xfstestsdb/tests/xunit/test_read.py
Anna Schumaker 3366c1eb0c xfstestsdb: Add testcases from the xunit file to the database
I use the testcases table to store testcase information, and store
messages, system out, and system error logs in the messages table.

The testcases_view is used to link testcases with their source xunits,
messages, system out, and system error logs. This view has an INSTEAD
OF INSERT trigger to allow insertions that properly set up message ids
in the testcases table.

Signed-off-by: Anna Schumaker <anna@nowheycreamery.com>
2023-02-16 16:15:55 -05:00

199 lines
10 KiB
Python

# Copyright 2023 (c) Anna Schumaker.
"""Tests the `xfstestsdb xunit read` command."""
import errno
import io
import unittest
import unittest.mock
import xfstestsdb.xunit.read
import tests.xunit
class TestXunitRead(unittest.TestCase):
"""Tests the `xfstestsdb xunit read` command."""
def setUp(self):
"""Set up common variables."""
self.xfstestsdb = xfstestsdb.Command()
self.xunit = self.xfstestsdb.commands["xunit"]
self.read = self.xunit.commands["read"]
def test_init(self):
"""Check that the xunit read command was set up properly."""
self.assertIsInstance(self.read, xfstestsdb.commands.Command)
self.assertIsInstance(self.read, xfstestsdb.xunit.read.Command)
self.assertEqual(self.xunit.subparser.choices["read"],
self.read.parser)
@unittest.mock.patch("sys.stdout", new_callable=io.StringIO)
def test_read_file(self, mock_stdout: io.StringIO):
"""Test reading a file into the xfstestsdb_xunit database."""
self.xfstestsdb.run(["new", "/dev/vda1"])
self.xfstestsdb.run(["xunit", "read", "1", str(tests.xunit.XUNIT_1)])
self.assertRegex(mock_stdout.getvalue(),
"added 'test-1' with 10 testcases to run #1")
row = self.xfstestsdb.sql("SELECT * FROM xunits_view").fetchone()
self.assertEqual(row["runid"], 1)
self.assertEqual(row["name"], "test-1")
self.assertEqual(row["hostname"], "myhost")
self.assertEqual(row["timestamp"], "2023-01-31 14:14:14")
self.assertEqual(row["tests"], 10)
self.assertEqual(row["failed"], 1)
self.assertEqual(row["skipped"], 3)
self.assertEqual(row["passed"], 6)
self.assertEqual(row["time"], 43)
@unittest.mock.patch("sys.stdout", new_callable=io.StringIO)
def test_read_file_properties(self, mock_stdout: io.StringIO):
"""Test reading a file's properties into the database."""
self.xfstestsdb.run(["new", "/dev/vda1"])
self.xfstestsdb.run(["xunit", "read", "1", str(tests.xunit.XUNIT_1)])
cur = self.xfstestsdb.sql("SELECT key, value FROM xunit_properties")
properties = {row["key"]: row["value"] for row in cur.fetchall()}
self.assertDictEqual(properties,
{"SECTION": "-no-sections-",
"FSTYP": "myfs",
"PLATFORM": "Linux/x86_64 myhost 6.1.8-arch1",
"MOUNT_OPTIONS": "-o mountopt1,mountopt2",
"HOST_OPTIONS": "local.config",
"CHECK_OPTIONS": "-r -R xunit -g quick",
"TIME_FACTOR": "1",
"LOAD_FACTOR": "1",
"TEST_DIR": "/mnt/test",
"TEST_DEV": "/dev/vdb1",
"SCRATCH_DEV": "/dev/vdb2",
"SCRATCH_MNT": "/mnt/scratch",
"OVL_UPPER": "ovl-upper",
"OVL_LOWER": "ovl-lower",
"OVL_WORK": "ovl-work"})
@unittest.mock.patch("sys.stdout", new_callable=io.StringIO)
def test_read_file_property_view(self, mock_stdout: io.StringIO):
"""Test reading a file's properties into the database."""
self.xfstestsdb.run(["new", "/dev/vda1"])
self.xfstestsdb.run(["xunit", "read", "1", str(tests.xunit.XUNIT_1)])
cur = self.xfstestsdb.sql("SELECT xunitid, key, value "
"FROM xunit_properties_view")
rows = cur.fetchall()
for row in rows:
self.assertEqual(row["xunitid"], 1)
self.assertDictEqual({row["key"]: row["value"] for row in rows},
{"SECTION": "-no-sections-",
"FSTYP": "myfs",
"PLATFORM": "Linux/x86_64 myhost 6.1.8-arch1",
"MOUNT_OPTIONS": "-o mountopt1,mountopt2",
"HOST_OPTIONS": "local.config",
"CHECK_OPTIONS": "-r -R xunit -g quick",
"TIME_FACTOR": "1",
"LOAD_FACTOR": "1",
"TEST_DIR": "/mnt/test",
"TEST_DEV": "/dev/vdb1",
"SCRATCH_DEV": "/dev/vdb2",
"SCRATCH_MNT": "/mnt/scratch",
"OVL_UPPER": "ovl-upper",
"OVL_LOWER": "ovl-lower",
"OVL_WORK": "ovl-work"})
@unittest.mock.patch("sys.stdout", new_callable=io.StringIO)
def test_read_file_testcases(self, mock_stdout: io.StringIO):
"""Test reading a file's testcases into the database."""
self.xfstestsdb.run(["new", "/dev/vda1"])
self.xfstestsdb.run(["xunit", "read", "1", str(tests.xunit.XUNIT_1)])
cur = self.xfstestsdb.sql("SELECT * FROM testcases ORDER BY testcase")
self.assertListEqual([[c for c in row] for row in cur.fetchall()],
[[1, "test/01", "passed", 1, None, None, None],
[1, "test/02", "skipped", 0, 1, None, None],
[1, "test/03", "skipped", 0, 2, None, None],
[1, "test/04", "passed", 4, None, None, None],
[1, "test/05", "passed", 5, None, None, None],
[1, "test/06", "passed", 6, None, None, None],
[1, "test/07", "skipped", 0, 3, None, None],
[1, "test/08", "passed", 8, None, None, None],
[1, "test/09", "failure", 9, 4, 5, 6],
[1, "test/10", "passed", 10, None, None, None]])
@unittest.mock.patch("sys.stdout", new_callable=io.StringIO)
def test_read_file_testcases_view(self, mock_stdout: io.StringIO):
"""Test reading a file's testcases into the database."""
self.xfstestsdb.run(["new", "/dev/vda1"])
self.xfstestsdb.run(["xunit", "read", "1", str(tests.xunit.XUNIT_1)])
rows = self.xfstestsdb.sql("""SELECT * FROM testcases_view
ORDER BY testcase""").fetchall()
for row in rows:
self.assertTupleEqual(row[:4], (1, 1, "/dev/vda1", "test-1"))
self.assertListEqual([row[4:] for row in rows],
[("test/01", "passed", 1, None, None, None),
("test/02", "skipped", 0,
"skipped on $TEST_DEV", None, None),
("test/03", "skipped", 0,
"skipped on $TEST_DIR too", None, None),
("test/04", "passed", 4, None, None, None),
("test/05", "passed", 5, None, None, None),
("test/06", "passed", 6, None, None, None),
("test/07", "skipped", 0,
"fstype \"myfs\" gets skipped", None, None),
("test/08", "passed", 8, None, None, None),
("test/09", "failure", 9,
"- output mismatch (see somefile)",
"there was a problem with '$SCRATCH_DEV'",
"--- test/09.out\n" +
"+++ results/test/09.out.bad\n" +
"there was a problem with '$SCRATCH_MNT'"),
("test/10", "passed", 10, None, None, None)])
@unittest.mock.patch("sys.stdout", new_callable=io.StringIO)
def test_read_file_named(self, mock_stdout: io.StringIO):
"""Test reading a file with the --name= option."""
self.xfstestsdb.run(["new", "/dev/vda1"])
self.xfstestsdb.run(["xunit", "read", "--name", "testname",
"1", str(tests.xunit.XUNIT_1)])
self.assertRegex(mock_stdout.getvalue(),
"added 'testname' with 10 testcases to run #1")
@unittest.mock.patch("sys.stdout", new_callable=io.StringIO)
@unittest.mock.patch("sys.stderr", new_callable=io.StringIO)
def test_read_duplicate_file(self, mock_stdout: io.StringIO,
mock_stderr: io.StringIO):
"""Test reading a duplicate file into the xfstestsdb_xunit database."""
self.xfstestsdb.run(["new", "/dev/vda1"])
self.xfstestsdb.run(["xunit", "read", "1", str(tests.xunit.XUNIT_1)])
with self.assertRaises(SystemExit) as sys_exit:
self.xfstestsdb.run(["xunit", "read", "1",
str(tests.xunit.XUNIT_1)])
self.assertEqual(sys_exit.exception.code, errno.EEXIST)
self.assertRegex(mock_stderr.getvalue(),
"error: run #1 already has xunit file 'test-1'")
@unittest.mock.patch("sys.stderr", new_callable=io.StringIO)
def test_read_error(self, mock_stderr: io.StringIO):
"""Test the `xfstestsdb xunit read` command with invalid input."""
with self.assertRaises(SystemExit):
self.xfstestsdb.run(["xunit", "read"])
self.assertRegex(mock_stderr.getvalue(),
"error: the following arguments are required: runid")
with self.assertRaises(SystemExit):
self.xfstestsdb.run(["xunit", "read", "1"])
self.assertRegex(mock_stderr.getvalue(),
"error: the following arguments are required: file")
@unittest.mock.patch("sys.stderr", new_callable=io.StringIO)
def test_read_enoent(self, mock_stderr: io.StringIO):
"""Test the `xfstestsdb xunit read` command with an invalid runid."""
with self.assertRaises(SystemExit) as sys_exit:
self.xfstestsdb.run(["xunit", "read", "2",
str(tests.xunit.XUNIT_1)])
self.assertEqual(sys_exit.exception.code, errno.ENOENT)
self.assertRegex(mock_stderr.getvalue(),
"error: run #2 does not exist")