132 lines
5.5 KiB
Python
132 lines
5.5 KiB
Python
# Copyright 2023 (c) Anna Schumaker.
|
|
"""Tests the `xfstestsdb gc` command."""
|
|
import datetime
|
|
import io
|
|
import unittest
|
|
import unittest.mock
|
|
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."""
|
|
|
|
def setUp(self):
|
|
"""Set up common variables."""
|
|
self.xfstestsdb = xfstestsdb.Command()
|
|
self.xunit = self.xfstestsdb.commands["xunit"]
|
|
self.gc = self.xunit.commands["gc"]
|
|
|
|
def setup_runs(self, mock_stdout: io.StringIO):
|
|
"""Set up runs in the database and clear stdout."""
|
|
self.xfstestsdb.run(["new", "/dev/vda1"])
|
|
self.xfstestsdb.run(["new", "/dev/vda1"])
|
|
self.xfstestsdb.run(["new", "/dev/vda1"])
|
|
|
|
self.xfstestsdb.run(["xunit", "read", "1", str(tests.xunit.XUNIT_1)])
|
|
self.xfstestsdb.run(["xunit", "read", "3", str(tests.xunit.XUNIT_1)])
|
|
|
|
self.xfstestsdb.sql("DELETE FROM testcases WHERE xunitid=2")
|
|
|
|
mock_stdout.seek(0)
|
|
mock_stdout.truncate(0)
|
|
|
|
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)
|
|
|
|
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()
|
|
|
|
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)
|
|
|
|
cur = self.xfstestsdb.sql("SELECT runid FROM xfstests_gc_runs")
|
|
self.assertListEqual([row['runid'] for row in cur.fetchall()], [2, 3])
|
|
|
|
self.xfstestsdb.run(["gc"])
|
|
self.assertRegex(mock_stdout.getvalue(),
|
|
"run #2 has been deleted\nrun #3 has been deleted")
|
|
|
|
cur = self.xfstestsdb.sql("SELECT runid FROM xfstests_runs")
|
|
self.assertListEqual([row['runid'] for row in cur.fetchall()], [1])
|
|
mock_vacuum.assert_called()
|
|
|
|
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)])
|
|
|
|
utcnow = datetime.datetime.utcnow()
|
|
|
|
expired = utcnow - datetime.timedelta(days=180, seconds=1)
|
|
self.xfstestsdb.sql("""UPDATE xfstests_runs SET timestamp=?
|
|
WHERE runid=1""", expired)
|
|
|
|
not_expired = utcnow - datetime.timedelta(days=180, seconds=-1)
|
|
self.xfstestsdb.sql("""UPDATE xfstests_runs SET timestamp=?
|
|
WHERE runid=2""", not_expired)
|
|
|
|
cur = self.xfstestsdb.sql("SELECT runid FROM xfstests_gc_runs")
|
|
self.assertListEqual([row['runid'] for row in cur.fetchall()], [1, 3])
|
|
|
|
self.xfstestsdb.run(["gc"])
|
|
self.assertRegex(mock_stdout.getvalue(),
|
|
"run #1 has been deleted\nrun #3 has been deleted")
|
|
|
|
cur = self.xfstestsdb.sql("SELECT runid FROM xfstests_runs")
|
|
self.assertListEqual([row['runid'] for row in cur.fetchall()], [2])
|
|
mock_vacuum.assert_called()
|
|
|
|
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)])
|
|
self.xfstestsdb.run(["tag", "1", "my-tag"])
|
|
self.xfstestsdb.run(["tag", "3", "my-tag"])
|
|
|
|
utcnow = datetime.datetime.utcnow()
|
|
expired = utcnow - datetime.timedelta(days=181)
|
|
self.xfstestsdb.sql("UPDATE xfstests_runs SET timestamp=?", expired)
|
|
|
|
cur = self.xfstestsdb.sql("SELECT runid FROM xfstests_gc_runs")
|
|
self.assertListEqual([row['runid'] for row in cur.fetchall()], [2, 3])
|
|
|
|
self.xfstestsdb.run(["gc"])
|
|
self.assertRegex(mock_stdout.getvalue(),
|
|
"run #2 has been deleted\nrun #3 has been deleted")
|
|
|
|
cur = self.xfstestsdb.sql("SELECT runid FROM xfstests_runs")
|
|
self.assertListEqual([row['runid'] for row in cur.fetchall()], [1])
|
|
mock_vacuum.assert_called()
|
|
|
|
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"])
|
|
self.assertRegex(mock_stdout.getvalue(),
|
|
"run #2 would be deleted\nrun #3 would be deleted")
|
|
|
|
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()
|