# Copyright 2023 (c) Anna Schumaker. """The `xfstestsdb testcase show` command.""" import argparse import errno import sys from . import colors from . import commands from . import sqlite from . import table class TestCaseTable(table.Table): """A custom Table for coloring cells based on status.""" def do_format_cell(self, rownum: int, text: str, color: str, **kwargs) -> str: """Set cell text color based on testcase status.""" match text.strip(): case "passed": color = "fg-passed" case "skipped": color = "fg-skipped" case "failure": color = "fg-failure" case _: color = "fg-testcase" return super().do_format_cell(rownum, text, color, **kwargs) class Command(commands.Command): """The `xfstestsdb testcase show` command.""" def __init__(self, subparser: argparse.Action, sql: sqlite.Connection) -> None: """Set up the testcase show command.""" super().__init__(subparser, sql, "show", help="show an xfstests run") self.parser.add_argument("runid", metavar="runid", nargs=1, help="runid of the testcase to show") self.parser.add_argument("--color", metavar="color", nargs="?", choices=["light", "dark", "none"], const=colors.get_default_colors(), default=colors.get_default_colors(), help="show with color output " f"[default={colors.get_default_colors()}]") self.parser.add_argument("--failure", dest="status", action="append_const", const="failure", help="show failing testcases") self.parser.add_argument("--passed", dest="status", action="append_const", const="passed", help="show passing testcases") self.parser.add_argument("--skipped", dest="status", action="append_const", const="skipped", help="show skipped testcases") self.parser.add_argument("--testcase", metavar="testcase", nargs=1, help="show testcases matching " "the given pattern") def do_command(self, args: argparse.Namespace) -> None: """Create a new row in the xfstestsdb_runs table.""" rows = self.sql("""SELECT name FROM xunits_view WHERE runid=? ORDER BY name""", args.runid[0]).fetchall() if len(rows) == 0: print(f"error: run #{args.runid[0]} does not exist", file=sys.stderr) sys.exit(errno.ENOENT) xunits = [row["name"] for row in rows] tbl = TestCaseTable(["testcase"] + xunits, ["r"] + ["l"] * len(rows), args.color) select = [f"xunit{i}.status as xunit{i}" for i in range(len(xunits))] query = [(f"SELECT testcase, {','.join(select)} FROM")] query.append("(SELECT DISTINCT runid, testcase FROM testcases_view " "WHERE runid=:runid) ") sql_args = {"runid": args.runid[0]} where = [] for i, xunit in enumerate(xunits): xunit_select = "SELECT testcase, status FROM testcases_view " + \ f"WHERE runid=:runid AND xunit=:xunit{i}" query.append(f"FULL JOIN ({xunit_select}) AS xunit{i} " "USING (testcase)") sql_args[f"xunit{i}"] = xunit if args.status: xunit_list = ",".join([f"xunit{i}" for i in range(len(xunits))]) for status in args.status: where.append(f":{status} IN ({xunit_list})") sql_args[status] = status if args.testcase: where.append("testcase GLOB :testcase") sql_args["testcase"] = args.testcase[0] if len(where) > 0: query.append(f"WHERE {' AND '.join(where)}") query.append("ORDER BY testcase") cur = self.sql("\n".join(query), **sql_args) for row in cur.fetchall(): tbl.add_row(*row) if len(tbl.rows) > 0: print(tbl)