xfstestsdb/xfstestsdb/show.py

104 lines
4.3 KiB
Python

# 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)