# Copyright 2023 (c) Anna Schumaker. """Tests the `xfstestsdb list` command.""" import datetime import dateutil.tz import io import unittest import unittest.mock import xfstestsdb.list import tests.xunit class TestList(unittest.TestCase): """Tests the `xfstestsdb list` command.""" def setUp(self): """Set up common variables.""" self.xfstestsdb = xfstestsdb.Command() self.list = self.xfstestsdb.commands["list"] def setup_runs(self, mock_stdout: io.StringIO): """Set up runs in the database and clear stdout.""" timestamp = datetime.datetime(2023, 1, 1, 12, 59, 59) timestamp = timestamp.astimezone(tz=dateutil.tz.tzutc()) timestamp = timestamp.replace(tzinfo=None) self.xfstestsdb.run(["new", "/dev/vda1"]) self.xfstestsdb.run(["new", "/dev/vda2"]) self.xfstestsdb.run(["new", "/dev/vdb1"]) 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), (timestamp.replace(day=2), 2), (timestamp.replace(day=3), 3)) self.xfstestsdb.run(["xunit", "read", "1", str(tests.xunit.XUNIT_1)]) self.xfstestsdb.run(["xunit", "read", "1", str(tests.xunit.XUNIT_1), "--name", "test-2"]) self.xfstestsdb.run(["xunit", "read", "3", str(tests.xunit.XUNIT_1), "--name", "test-3"]) mock_stdout.seek(0) mock_stdout.truncate(0) def test_init(self): """Check that the list command was set up properly.""" self.assertIsInstance(self.list, xfstestsdb.commands.Command) self.assertIsInstance(self.list, xfstestsdb.list.Command) self.assertEqual(self.xfstestsdb.subparser.choices["list"], self.list.parser) @unittest.mock.patch("sys.stdout", new_callable=io.StringIO) def test_list_empty(self, mock_stdout: io.StringIO): """Test printing out an empty list.""" self.xfstestsdb.run(["list", "--color", "none"]) self.assertEqual(mock_stdout.getvalue(), "") @unittest.mock.patch("sys.stdout", new_callable=io.StringIO) def test_list_runs(self, mock_stdout: io.StringIO): """Test listing runs with default options.""" self.setup_runs(mock_stdout) print() self.xfstestsdb.run(["list", "--color", "none"]) self.assertEqual(mock_stdout.getvalue(), """ +-----+---------------------+-----------+ | run | timestamp | device | +-----+---------------------+-----------+ | 1 | 2023-01-01 12:59:59 | /dev/vda1 | | 2 | 2023-01-02 12:59:59 | /dev/vda2 | | 3 | 2023-01-03 12:59:59 | /dev/vdb1 | +-----+---------------------+-----------+ """) @unittest.mock.patch("sys.stdout", new_callable=io.StringIO) def test_list_filter_device(self, mock_stdout: io.StringIO): """Test listing runs with a specific device pattern.""" self.setup_runs(mock_stdout) print() self.xfstestsdb.run(["list", "--device", "/dev/vd*1", "--color", "none"]) self.assertEqual(mock_stdout.getvalue(), """ +-----+---------------------+-----------+ | run | timestamp | device | +-----+---------------------+-----------+ | 1 | 2023-01-01 12:59:59 | /dev/vda1 | | 3 | 2023-01-03 12:59:59 | /dev/vdb1 | +-----+---------------------+-----------+ """) @unittest.mock.patch("sys.stdout", new_callable=io.StringIO) def test_list_filter_timestamp(self, mock_stdout: io.StringIO): """Test listing runs with a specific timestamp pattern.""" self.setup_runs(mock_stdout) print() self.xfstestsdb.run(["list", "--timestamp", "*-03 12:*", "--color", "none"]) self.assertEqual(mock_stdout.getvalue(), """ +-----+---------------------+-----------+ | run | timestamp | device | +-----+---------------------+-----------+ | 3 | 2023-01-03 12:59:59 | /dev/vdb1 | +-----+---------------------+-----------+ """) @unittest.mock.patch("sys.stdout", new_callable=io.StringIO) def test_list_print_tags(self, mock_stdout: io.StringIO): """Test listing runs with the Tags column added.""" self.setup_runs(mock_stdout) print() 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 | | 3 | 2023-01-03 12:59:59 | /dev/vdb1 | mytag3,othertag | +-----+---------------------+-----------+-----------------+ """) @unittest.mock.patch("sys.stdout", new_callable=io.StringIO) def test_list_filter_tags(self, mock_stdout: io.StringIO): """Test listing runs with a specific tag pattern.""" self.setup_runs(mock_stdout) print() self.xfstestsdb.run(["list", "--tags", "mytag*", "--color", "none"]) self.assertEqual(mock_stdout.getvalue(), """ +-----+---------------------+-----------+---------------+ | run | timestamp | device | tags | +-----+---------------------+-----------+---------------+ | 1 | 2023-01-01 12:59:59 | /dev/vda1 | mytag1,mytag2 | | 3 | 2023-01-03 12:59:59 | /dev/vdb1 | mytag3 | +-----+---------------------+-----------+---------------+ """) @unittest.mock.patch("sys.stdout", new_callable=io.StringIO) def test_list_filter_tags_device(self, mock_stdout: io.StringIO): """Test listing runs with miltiple filter patterns.""" self.setup_runs(mock_stdout) print() self.xfstestsdb.run(["list", "--tags", "mytag*", "--device", "/dev/vda*", "--color", "none"]) self.assertEqual(mock_stdout.getvalue(), """ +-----+---------------------+-----------+---------------+ | run | timestamp | device | tags | +-----+---------------------+-----------+---------------+ | 1 | 2023-01-01 12:59:59 | /dev/vda1 | mytag1,mytag2 | +-----+---------------------+-----------+---------------+ """) @unittest.mock.patch("sys.stdout", new_callable=io.StringIO) def test_list_print_xunits(self, mock_stdout: io.StringIO): """Test listing runs with the Xunits column added.""" self.setup_runs(mock_stdout) print() self.xfstestsdb.run(["list", "--color", "none", "--xunits"]) self.assertEqual(mock_stdout.getvalue(), """ +-----+---------------------+-----------+---------------+ | run | timestamp | device | xunits | +-----+---------------------+-----------+---------------+ | 1 | 2023-01-01 12:59:59 | /dev/vda1 | test-1,test-2 | | 3 | 2023-01-03 12:59:59 | /dev/vdb1 | test-3 | +-----+---------------------+-----------+---------------+ """)