mirror of
https://github.com/liquidraver/ZephCore.git
synced 2026-10-15 08:20:11 +00:00
- tests/ (114 host cases over production sources), the CI workflow (ASan/UBSan on PRs and master pushes) and REGRESSION_TEST_PLAN.md are tracked - .gitignore grouped and deduplicated (173 -> 96 lines, same ignored set)
79 lines
3.4 KiB
Python
79 lines
3.4 KiB
Python
import json
|
|
from pathlib import Path
|
|
import sys
|
|
import tempfile
|
|
import unittest
|
|
from unittest.mock import patch
|
|
import xml.etree.ElementTree as ET
|
|
|
|
sys.path.insert(0, str(Path(__file__).resolve().parents[1]))
|
|
import run
|
|
|
|
|
|
class RunnerTests(unittest.TestCase):
|
|
CASE = {"id": "ONE", "name": "Example", "source": "unit/example.cpp"}
|
|
|
|
def test_empty_collection(self):
|
|
with self.assertRaises(ValueError):
|
|
run.select_cases([], None)
|
|
|
|
def test_unknown_case(self):
|
|
with self.assertRaises(ValueError):
|
|
run.select_cases([self.CASE], "MISSING")
|
|
|
|
def test_catalog_duplicate_ids(self):
|
|
with tempfile.TemporaryDirectory() as directory:
|
|
path = Path(directory) / "catalog.json"
|
|
path.write_text(json.dumps({"schema_version": 1, "cases": [self.CASE, self.CASE]}))
|
|
with self.assertRaises(ValueError):
|
|
run.load_catalog(path)
|
|
|
|
def test_executable_catalog_agreement(self):
|
|
run.validate_listing("ONE\tExample\n", [self.CASE])
|
|
for output in ("", "ONE\tExample\nONE\tExample\n", "TWO\tExample\n", "ONE\tWrong\n", "garbage"):
|
|
with self.assertRaises(ValueError):
|
|
run.validate_listing(output, [self.CASE])
|
|
|
|
def test_child_failure_retains_output(self):
|
|
result = run.command([sys.executable, "-c", "import sys; print('evidence'); sys.exit(7)"])
|
|
self.assertEqual(result["status"], "FAIL")
|
|
self.assertEqual(result["returncode"], 7)
|
|
self.assertIn("evidence", result["stdout"])
|
|
|
|
def test_child_timeout(self):
|
|
result = run.command([sys.executable, "-c", "import time; print('started', flush=True); time.sleep(30)"], timeout=1)
|
|
self.assertEqual(result["status"], "ERROR")
|
|
self.assertIn("Timeout", result["stderr"])
|
|
|
|
def test_missing_executable(self):
|
|
with tempfile.TemporaryDirectory() as directory:
|
|
result = run.command([str(Path(directory) / "missing")])
|
|
self.assertEqual(result["status"], "ERROR")
|
|
|
|
def test_success_requires_matching_marker(self):
|
|
for output in ("", "PASS OLD", "PASS ONE\nextra"):
|
|
with patch.object(run, "command", return_value={"status": "PASS", "stdout": output, "stderr": ""}):
|
|
self.assertEqual(run.execute_case("unused", self.CASE)["status"], "ERROR")
|
|
|
|
def test_failure_not_overridden_by_success_text(self):
|
|
with patch.object(run, "command", return_value={"status": "FAIL", "stdout": "PASS ONE", "stderr": "crash"}):
|
|
self.assertEqual(run.execute_case("unused", self.CASE)["status"], "FAIL")
|
|
|
|
def test_report_counts_and_xml_escaping(self):
|
|
results = [{"id": str(i), "name": "<&>", "status": status, "stderr": "a < b & c"}
|
|
for i, status in enumerate(("PASS", "FAIL", "ERROR", "BLOCKED"))]
|
|
report = {"results": results}
|
|
with tempfile.TemporaryDirectory() as directory:
|
|
run.write_reports(Path(directory), report)
|
|
xml = ET.parse(Path(directory) / "junit.xml").getroot()
|
|
self.assertEqual(xml.attrib["tests"], "4")
|
|
self.assertEqual(xml.attrib["failures"], "1")
|
|
self.assertEqual(xml.attrib["errors"], "2")
|
|
self.assertEqual(len(xml.findall("testcase")), 4)
|
|
self.assertEqual(json.loads((Path(directory) / "results.json").read_text())["counts"],
|
|
{"PASS": 1, "FAIL": 1, "ERROR": 1, "BLOCKED": 1})
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|