Compare commits
5 Commits
06d10cf883
...
4600258721
Author | SHA1 | Date |
---|---|---|
Anna Schumaker | 4600258721 | |
Anna Schumaker | 79fae64f37 | |
Anna Schumaker | 2e85870c87 | |
Anna Schumaker | 7e6f944cde | |
Anna Schumaker | dc6f5f54c3 |
|
@ -24,9 +24,15 @@ class TestCommand(unittest.TestCase):
|
|||
self.assertEqual(self.command.parser.description, "description")
|
||||
self.assertEqual(self.command.parser._defaults["function"],
|
||||
self.command.do_command)
|
||||
self.assertEqual(self.command.parser._defaults["done"],
|
||||
self.command.do_done)
|
||||
self.assertEqual(self.command.sql, self.sql)
|
||||
|
||||
def test_do_command(self):
|
||||
"""Test the do_command() function."""
|
||||
with self.assertRaises(NotImplementedError):
|
||||
self.command.do_command(argparse.Namespace())
|
||||
|
||||
def test_do_done(self):
|
||||
"""Test the do_done() function."""
|
||||
self.command.do_done(argparse.Namespace())
|
||||
|
|
|
@ -8,6 +8,8 @@ import xfstestsdb.xunit.gc
|
|||
import tests.xunit
|
||||
|
||||
|
||||
@unittest.mock.patch("xfstestsdb.sqlite.Connection.vacuum")
|
||||
@unittest.mock.patch("sys.stdout", new_callable=io.StringIO)
|
||||
class TestGC(unittest.TestCase):
|
||||
"""Tests the `xfstestsdb xunit gc` command."""
|
||||
|
||||
|
@ -31,24 +33,26 @@ class TestGC(unittest.TestCase):
|
|||
mock_stdout.seek(0)
|
||||
mock_stdout.truncate(0)
|
||||
|
||||
def test_init(self):
|
||||
def test_init(self, mock_stdout: io.StringIO,
|
||||
mock_vacuum: unittest.mock.Mock):
|
||||
"""Check that the gc command was set up properly."""
|
||||
self.assertIsInstance(self.gc, xfstestsdb.commands.Command)
|
||||
self.assertIsInstance(self.gc, xfstestsdb.xunit.gc.Command)
|
||||
self.assertEqual(self.xunit.subparser.choices["gc"],
|
||||
self.gc.parser)
|
||||
|
||||
@unittest.mock.patch("sys.stdout", new_callable=io.StringIO)
|
||||
def test_gc_empty(self, mock_stdout: io.StringIO):
|
||||
def test_gc_empty(self, mock_stdout: io.StringIO,
|
||||
mock_vacuum: unittest.mock.Mock):
|
||||
"""Test garbage collecting an empty database."""
|
||||
cur = self.xfstestsdb.sql("SELECT runid FROM xfstests_gc_runs")
|
||||
self.assertListEqual([row['runid'] for row in cur.fetchall()], [])
|
||||
|
||||
self.xfstestsdb.run(["gc"])
|
||||
self.assertEqual(mock_stdout.getvalue(), "")
|
||||
mock_vacuum.assert_not_called()
|
||||
|
||||
@unittest.mock.patch("sys.stdout", new_callable=io.StringIO)
|
||||
def test_gc_no_testcases(self, mock_stdout: io.StringIO):
|
||||
def test_gc_no_testcases(self, mock_stdout: io.StringIO,
|
||||
mock_vacuum: unittest.mock.Mock):
|
||||
"""Test garbage collecting runs with no testcases."""
|
||||
self.setup_runs(mock_stdout)
|
||||
|
||||
|
@ -61,9 +65,10 @@ class TestGC(unittest.TestCase):
|
|||
|
||||
cur = self.xfstestsdb.sql("SELECT runid FROM xfstests_runs")
|
||||
self.assertListEqual([row['runid'] for row in cur.fetchall()], [1])
|
||||
mock_vacuum.assert_called()
|
||||
|
||||
@unittest.mock.patch("sys.stdout", new_callable=io.StringIO)
|
||||
def test_gc_expired(self, mock_stdout: io.StringIO):
|
||||
def test_gc_expired(self, mock_stdout: io.StringIO,
|
||||
mock_vacuum: unittest.mock.Mock):
|
||||
"""Test garbage collecting old runs."""
|
||||
self.setup_runs(mock_stdout)
|
||||
self.xfstestsdb.run(["xunit", "read", "2", str(tests.xunit.XUNIT_1)])
|
||||
|
@ -87,9 +92,10 @@ class TestGC(unittest.TestCase):
|
|||
|
||||
cur = self.xfstestsdb.sql("SELECT runid FROM xfstests_runs")
|
||||
self.assertListEqual([row['runid'] for row in cur.fetchall()], [2])
|
||||
mock_vacuum.assert_called()
|
||||
|
||||
@unittest.mock.patch("sys.stdout", new_callable=io.StringIO)
|
||||
def test_gc_expired_tagged(self, mock_stdout: io.StringIO):
|
||||
def test_gc_expired_tagged(self, mock_stdout: io.StringIO,
|
||||
mock_vacuum: unittest.mock.Mock):
|
||||
"""Test that we don't garbage collect expired runs that are tagged."""
|
||||
self.setup_runs(mock_stdout)
|
||||
self.xfstestsdb.run(["xunit", "read", "2", str(tests.xunit.XUNIT_1)])
|
||||
|
@ -109,9 +115,10 @@ class TestGC(unittest.TestCase):
|
|||
|
||||
cur = self.xfstestsdb.sql("SELECT runid FROM xfstests_runs")
|
||||
self.assertListEqual([row['runid'] for row in cur.fetchall()], [1])
|
||||
mock_vacuum.assert_called()
|
||||
|
||||
@unittest.mock.patch("sys.stdout", new_callable=io.StringIO)
|
||||
def test_gc_dry_run(self, mock_stdout: io.StringIO):
|
||||
def test_gc_dry_run(self, mock_stdout: io.StringIO,
|
||||
mock_vacuum: unittest.mock.Mock):
|
||||
"""Test garbage collecting with the --dry-run option."""
|
||||
self.setup_runs(mock_stdout)
|
||||
self.xfstestsdb.run(["gc", "--dry-run"])
|
||||
|
@ -121,3 +128,4 @@ class TestGC(unittest.TestCase):
|
|||
cur = self.xfstestsdb.sql("SELECT runid FROM xfstests_runs")
|
||||
self.assertListEqual([row['runid'] for row in cur.fetchall()],
|
||||
[1, 2, 3])
|
||||
mock_vacuum.assert_not_called()
|
||||
|
|
|
@ -30,6 +30,7 @@ class TestList(unittest.TestCase):
|
|||
self.xfstestsdb.run(["tag", "1", "mytag1"])
|
||||
self.xfstestsdb.run(["tag", "1", "mytag2"])
|
||||
self.xfstestsdb.run(["tag", "3", "mytag3"])
|
||||
self.xfstestsdb.run(["tag", "3", "othertag"])
|
||||
|
||||
self.xfstestsdb.sql.executemany("""UPDATE xfstests_runs SET timestamp=?
|
||||
WHERE rowid=?""", (timestamp, 1),
|
||||
|
@ -116,13 +117,12 @@ class TestList(unittest.TestCase):
|
|||
self.xfstestsdb.run(["list", "--color", "none", "--tags"])
|
||||
self.assertEqual(mock_stdout.getvalue(),
|
||||
"""
|
||||
+-----+---------------------+-----------+---------------+
|
||||
+-----+---------------------+-----------+-----------------+
|
||||
| run | timestamp | device | tags |
|
||||
+-----+---------------------+-----------+---------------+
|
||||
+-----+---------------------+-----------+-----------------+
|
||||
| 1 | 2023-01-01 12:59:59 | /dev/vda1 | mytag1,mytag2 |
|
||||
| 2 | 2023-01-02 12:59:59 | /dev/vda2 | |
|
||||
| 3 | 2023-01-03 12:59:59 | /dev/vdb1 | mytag3 |
|
||||
+-----+---------------------+-----------+---------------+
|
||||
| 3 | 2023-01-03 12:59:59 | /dev/vdb1 | mytag3,othertag |
|
||||
+-----+---------------------+-----------+-----------------+
|
||||
""")
|
||||
|
||||
@unittest.mock.patch("sys.stdout", new_callable=io.StringIO)
|
||||
|
@ -170,7 +170,6 @@ class TestList(unittest.TestCase):
|
|||
| run | timestamp | device | xunits |
|
||||
+-----+---------------------+-----------+---------------+
|
||||
| 1 | 2023-01-01 12:59:59 | /dev/vda1 | test-1,test-2 |
|
||||
| 2 | 2023-01-02 12:59:59 | /dev/vda2 | |
|
||||
| 3 | 2023-01-03 12:59:59 | /dev/vdb1 | test-3 |
|
||||
+-----+---------------------+-----------+---------------+
|
||||
""")
|
||||
|
|
|
@ -29,6 +29,12 @@ class TestNew(unittest.TestCase):
|
|||
r"created run #1 with test device '/dev/vdb1' "
|
||||
r"\[[\d\-\: ]+\]\n")
|
||||
|
||||
@unittest.mock.patch("sys.stdout", new_callable=io.StringIO)
|
||||
def test_new_terse(self, mock_stdout: io.StringIO):
|
||||
"""Test running `xfstestsdb new --terse`."""
|
||||
self.xfstestsdb.run(["new", "--terse", "/dev/vdb1"])
|
||||
self.assertEqual(mock_stdout.getvalue(), "1\n")
|
||||
|
||||
@unittest.mock.patch("sys.stderr", new_callable=io.StringIO)
|
||||
def test_new_error(self, mock_stderr: io.StringIO):
|
||||
"""Test running the `xfstestsdb new` command with invalid input."""
|
||||
|
|
|
@ -114,6 +114,10 @@ class TestConnection(unittest.TestCase):
|
|||
with self.assertRaises(sqlite3.OperationalError):
|
||||
self.sql("SELECT COUNT(*) FROM other_table")
|
||||
|
||||
def test_vacuum(self):
|
||||
"""Test vacuuming the database."""
|
||||
self.assertIsInstance(self.sql.vacuum(), sqlite3.Cursor)
|
||||
|
||||
def test_close(self):
|
||||
"""Check closing the connection."""
|
||||
self.sql.close()
|
||||
|
|
|
@ -37,16 +37,18 @@ class TestXfstestsdb(unittest.TestCase):
|
|||
def test_run(self):
|
||||
"""Test running the xfstestsdb."""
|
||||
parser = self.xfstestsdb.subparser.add_parser("test-run", help="help")
|
||||
test_done = unittest.mock.Mock()
|
||||
test_passed = False
|
||||
|
||||
def test_func(args: argparse.Namespace) -> None:
|
||||
nonlocal test_passed
|
||||
self.assertTrue(self.xfstestsdb.sql.sql.in_transaction)
|
||||
test_passed = True
|
||||
parser.set_defaults(function=test_func)
|
||||
parser.set_defaults(function=test_func, done=test_done)
|
||||
|
||||
self.xfstestsdb.run(["test-run"])
|
||||
self.assertTrue(test_passed)
|
||||
test_done.assert_called()
|
||||
|
||||
@unittest.mock.patch("sys.stdout", new_callable=io.StringIO)
|
||||
def test_version(self, mock_stdout: io.StringIO):
|
||||
|
|
|
@ -24,7 +24,8 @@ class Command:
|
|||
def __init__(self) -> None:
|
||||
"""Initialize the xfstestsdb command."""
|
||||
self.parser = argparse.ArgumentParser()
|
||||
self.parser.set_defaults(function=lambda x: self.parser.print_usage())
|
||||
self.parser.set_defaults(function=lambda x: self.parser.print_usage(),
|
||||
done=lambda x: None)
|
||||
self.parser.add_argument("--version", action="store_true",
|
||||
help="show version number and exit")
|
||||
self.subparser = self.parser.add_subparsers(title="commands")
|
||||
|
@ -55,3 +56,4 @@ class Command:
|
|||
else:
|
||||
with self.sql:
|
||||
parsed.function(parsed)
|
||||
parsed.done(parsed)
|
||||
|
|
|
@ -12,8 +12,12 @@ class Command:
|
|||
"""Set up the Command."""
|
||||
self.parser = subparser.add_parser(name, help=help, **kwargs)
|
||||
self.parser.set_defaults(function=self.do_command)
|
||||
self.parser.set_defaults(done=self.do_done)
|
||||
self.sql = sql
|
||||
|
||||
def do_command(self, args: argparse.Namespace) -> None:
|
||||
"""Do something."""
|
||||
raise NotImplementedError
|
||||
|
||||
def do_done(self, args: argparse.Namespace) -> None:
|
||||
"""Run after the main command, outside of a transaction."""
|
||||
|
|
|
@ -25,3 +25,10 @@ class Command(commands.Command):
|
|||
if not args.dry_run:
|
||||
self.sql("DELETE FROM xfstests_runs WHERE runid=?", runid)
|
||||
print(f"run #{runid} {how} deleted")
|
||||
|
||||
args.need_vacuum = len(rows) > 0
|
||||
|
||||
def do_done(self, args: argparse.Namespace) -> None:
|
||||
"""Vacuum the database after deleting."""
|
||||
if args.need_vacuum and not args.dry_run:
|
||||
self.sql.vacuum()
|
||||
|
|
|
@ -100,17 +100,19 @@ class Command(commands.Command):
|
|||
|
||||
def do_command(self, args: argparse.Namespace) -> None:
|
||||
"""Run the Gtk UI."""
|
||||
app_args = []
|
||||
args.app_args = []
|
||||
|
||||
if args.runid is not None:
|
||||
if self.sql("SELECT 1 FROM xfstests_runs WHERE runid=?",
|
||||
args.runid).fetchone():
|
||||
app_args.append(f"runid={args.runid}")
|
||||
args.app_args.append(f"runid={args.runid}")
|
||||
else:
|
||||
print(f"error: run #{args.runid} does not exist",
|
||||
file=sys.stderr)
|
||||
sys.exit(errno.ENOENT)
|
||||
else:
|
||||
app_args.append("show-sidebar")
|
||||
args.app_args.append("show-sidebar")
|
||||
|
||||
Application(self.sql).run(app_args)
|
||||
def do_done(self, args: argparse.Namespace) -> None:
|
||||
"""Run the application outside of a transaction."""
|
||||
Application(self.sql).run(args.app_args)
|
||||
|
|
|
@ -52,6 +52,8 @@ class Command(commands.Command):
|
|||
if isinstance(args.tags, str):
|
||||
filter.append("tag GLOB ?")
|
||||
sql_args.append(args.tags)
|
||||
else:
|
||||
filter.append("tag IS NOT NULL")
|
||||
|
||||
if args.timestamp:
|
||||
filter.append("timestamp GLOB ?")
|
||||
|
@ -62,6 +64,8 @@ class Command(commands.Command):
|
|||
if isinstance(args.xunits, str):
|
||||
filter.append("xunit GLOB ?")
|
||||
sql_args.append(args.xunits)
|
||||
else:
|
||||
filter.append("xunit IS NOT NULL")
|
||||
|
||||
if len(filter) > 0:
|
||||
sql_where = " WHERE " + " AND ".join(filter) + " "
|
||||
|
|
|
@ -16,6 +16,8 @@ class Command(commands.Command):
|
|||
self.parser.add_argument("device", metavar="device", nargs=1,
|
||||
help="the test device used for"
|
||||
"this xfstests run")
|
||||
self.parser.add_argument("--terse", action="store_true",
|
||||
help="output only the new runid")
|
||||
|
||||
def do_command(self, args: argparse.Namespace) -> None:
|
||||
"""Create a new row in the xfstestsdb_runs table."""
|
||||
|
@ -24,6 +26,9 @@ class Command(commands.Command):
|
|||
datetime(timestamp, 'localtime') as timestamp""",
|
||||
args.device[0])
|
||||
row = cur.fetchone()
|
||||
if args.terse:
|
||||
print(row['runid'])
|
||||
else:
|
||||
print(f"created run #{row['runid']}", end=" ")
|
||||
print(f"with test device '{row['device']}'", end=" ")
|
||||
print(f"[{row['timestamp']}]")
|
||||
|
|
|
@ -76,3 +76,7 @@ class Connection:
|
|||
cur = self.sql.executescript(f.read())
|
||||
self.sql.commit()
|
||||
return cur
|
||||
|
||||
def vacuum(self) -> sqlite3.Cursor | None:
|
||||
"""Vacuum the database."""
|
||||
return self.sql.execute("VACUUM")
|
||||
|
|
Loading…
Reference in New Issue