test_kotlin_smoke.py (3609B)
1 from __future__ import annotations 2 3 import os 4 import sys 5 import tempfile 6 import unittest 7 import xml.etree.ElementTree as ET 8 from pathlib import Path 9 from unittest.mock import patch 10 11 SCRIPTS = Path(__file__).resolve().parent 12 if str(SCRIPTS) not in sys.path: 13 sys.path.insert(0, str(SCRIPTS)) 14 15 import ffi_source as source # noqa: E402 16 import kotlin_smoke as smoke # noqa: E402 17 18 19 class KotlinSmokeTests(unittest.TestCase): 20 def setUp(self) -> None: 21 temporary = tempfile.TemporaryDirectory() 22 self.addCleanup(temporary.cleanup) 23 self.root = Path(temporary.name).resolve() 24 self.path = self.root / "TEST-smoke.xml" 25 self.suite = ET.Element( 26 "testsuite", tests="18", failures="0", errors="0", skipped="0" 27 ) 28 for identity in sorted(smoke.EXPECTED_CASES): 29 name, case = identity.split("/") 30 ET.SubElement(self.suite, "testcase", classname=name, name=case) 31 32 def write(self) -> None: 33 self.path.write_bytes(ET.tostring(self.suite)) 34 35 def test_only_complete_executed_inventory_is_green(self) -> None: 36 self.write() 37 result = smoke.test_results(self.root) 38 self.assertEqual(result["passed"], 18) 39 self.assertEqual((result["failed"], result["skipped"]), (0, 0)) 40 41 def test_empty_and_missing_results_cannot_pass(self) -> None: 42 with self.assertRaises(source.ProvenanceError): 43 smoke.test_results(self.root) 44 self.suite.clear() 45 self.suite.attrib.update(tests="0", failures="0", errors="0", skipped="0") 46 self.write() 47 with self.assertRaises(source.ProvenanceError): 48 smoke.test_results(self.root) 49 50 def test_failed_skipped_or_error_results_cannot_pass(self) -> None: 51 for key in ("failures", "errors", "skipped"): 52 with self.subTest(key=key): 53 self.suite.set(key, "1") 54 self.write() 55 with self.assertRaises(source.ProvenanceError): 56 smoke.test_results(self.root) 57 self.suite.set(key, "0") 58 59 def test_case_failures_cannot_hide_behind_zero_suite_totals(self) -> None: 60 ET.SubElement(self.suite.find("testcase"), "failure") 61 self.write() 62 with self.assertRaises(source.ProvenanceError): 63 smoke.test_results(self.root) 64 65 def test_renamed_duplicate_or_missing_cases_cannot_pass(self) -> None: 66 cases = self.suite.findall("testcase") 67 cases[-1].attrib = cases[0].attrib.copy() 68 self.write() 69 with self.assertRaises(source.ProvenanceError): 70 smoke.test_results(self.root) 71 self.suite.remove(cases[-1]) 72 self.suite.set("tests", "15") 73 self.write() 74 with self.assertRaises(source.ProvenanceError): 75 smoke.test_results(self.root) 76 77 def test_result_symlinks_are_rejected(self) -> None: 78 self.write() 79 alias = self.root / "TEST-alias.xml" 80 alias.symlink_to(self.path) 81 with self.assertRaises(source.ProvenanceError): 82 smoke.test_results(self.root) 83 84 def test_output_requires_extbuild_and_cannot_enter_source(self) -> None: 85 with patch.dict(os.environ, {}, clear=True): 86 with self.assertRaises(source.ProvenanceError): 87 smoke.output_root(self.root) 88 with patch.dict( 89 os.environ, 90 {"EXT_BUILD_RUN_ACTIVE": "1", "EXT_BUILD_PROJECT_DIR": str(self.root)}, 91 ): 92 with self.assertRaises(source.ProvenanceError): 93 smoke.output_root(self.root) 94 95 96 if __name__ == "__main__": 97 unittest.main()