mirror of
https://github.com/elder-plinius/OBLITERATUS.git
synced 2026-08-17 16:37:30 +02:00
119 lines
4.3 KiB
Python
119 lines
4.3 KiB
Python
"""Unit tests for quality-depth gate helpers."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import json
|
|
from types import SimpleNamespace
|
|
|
|
from scripts import check_mutation_score
|
|
from scripts import run_repeat_gate
|
|
|
|
|
|
def test_mutation_score_accepts_exact_floor_and_rejects_regression():
|
|
stats = {"killed": 70, "total": 100, "check_was_interrupted_by_user": 0}
|
|
assert check_mutation_score.validate_mutation_stats(stats, minimum=70) == []
|
|
assert check_mutation_score.validate_mutation_stats(stats, minimum=70.01) == [
|
|
"mutation score 70.00% (70/100) is below the 70.01% floor",
|
|
]
|
|
|
|
|
|
def test_mutation_score_rejects_malformed_and_interrupted_runs():
|
|
assert check_mutation_score.validate_mutation_stats(
|
|
{"killed": True, "total": 1}, minimum=70,
|
|
) == ["mutation statistics require a non-negative integer 'killed'"]
|
|
assert check_mutation_score.validate_mutation_stats(
|
|
{"killed": 1, "total": 1, "check_was_interrupted_by_user": 1}, minimum=70,
|
|
) == ["mutation run was interrupted"]
|
|
|
|
|
|
def test_repeat_orders_are_distinct_and_deterministic():
|
|
paths = ["a", "b", "c", "d"]
|
|
assert run_repeat_gate.test_orders(paths) == [
|
|
["a", "b", "c", "d"],
|
|
["d", "c", "b", "a"],
|
|
["a", "c", "b", "d"],
|
|
]
|
|
|
|
|
|
def test_repeat_gate_records_each_pass(monkeypatch, tmp_path):
|
|
calls = []
|
|
|
|
def fake_run(command, **kwargs):
|
|
calls.append((command, kwargs["env"]["PYTHONHASHSEED"]))
|
|
return SimpleNamespace(returncode=0, stdout="2 passed\n", stderr="")
|
|
|
|
monkeypatch.setattr(run_repeat_gate.subprocess, "run", fake_run)
|
|
monkeypatch.setattr(
|
|
run_repeat_gate,
|
|
"junit_snapshot",
|
|
lambda _path: {"tests": 2, "failed_nodeids": [], "skipped_nodeids": []},
|
|
)
|
|
output = tmp_path / "repeat.json"
|
|
assert run_repeat_gate.run_repeat_gate(
|
|
["first.py", "second.py"], output=output, python="python-fixture",
|
|
) == 0
|
|
evidence = json.loads(output.read_text())
|
|
assert evidence["status"] == "passed"
|
|
assert [entry["python_hash_seed"] for entry in evidence["passes"]] == [
|
|
"0", "1", "8675309",
|
|
]
|
|
assert calls[0][0] == [
|
|
"python-fixture",
|
|
"-m",
|
|
"pytest",
|
|
"--no-cov",
|
|
"-q",
|
|
f"--junitxml={tmp_path / 'repeat-pass-1.xml'}",
|
|
"first.py",
|
|
"second.py",
|
|
]
|
|
|
|
|
|
def test_repeat_gate_completes_all_passes_and_preserves_failure_output(monkeypatch, tmp_path):
|
|
def fake_run(*_args, **_kwargs):
|
|
return SimpleNamespace(returncode=3, stdout="failed output", stderr="failure detail")
|
|
|
|
monkeypatch.setattr(run_repeat_gate.subprocess, "run", fake_run)
|
|
monkeypatch.setattr(
|
|
run_repeat_gate,
|
|
"junit_snapshot",
|
|
lambda _path: {
|
|
"tests": 1,
|
|
"failed_nodeids": ["tests.test_example::test_failure"],
|
|
"skipped_nodeids": [],
|
|
},
|
|
)
|
|
output = tmp_path / "repeat.json"
|
|
assert run_repeat_gate.run_repeat_gate(["test.py"], output=output) == 3
|
|
evidence = json.loads(output.read_text())
|
|
assert evidence["status"] == "failed"
|
|
assert len(evidence["passes"]) == 3
|
|
assert evidence["passes"][0]["stderr"] == "failure detail"
|
|
assert evidence["consistent_failures"] == [{
|
|
"nodeid": "tests.test_example::test_failure",
|
|
"occurrences": 3,
|
|
}]
|
|
|
|
|
|
def test_repeat_gate_identifies_intermittent_failures(monkeypatch, tmp_path):
|
|
results = iter([
|
|
SimpleNamespace(returncode=1, stdout="failed", stderr=""),
|
|
SimpleNamespace(returncode=0, stdout="passed", stderr=""),
|
|
SimpleNamespace(returncode=1, stdout="failed", stderr=""),
|
|
])
|
|
snapshots = iter([
|
|
{"tests": 1, "failed_nodeids": ["tests.test_example::test_flake"], "skipped_nodeids": []},
|
|
{"tests": 1, "failed_nodeids": [], "skipped_nodeids": []},
|
|
{"tests": 1, "failed_nodeids": ["tests.test_example::test_flake"], "skipped_nodeids": []},
|
|
])
|
|
monkeypatch.setattr(run_repeat_gate.subprocess, "run", lambda *_args, **_kwargs: next(results))
|
|
monkeypatch.setattr(run_repeat_gate, "junit_snapshot", lambda _path: next(snapshots))
|
|
|
|
output = tmp_path / "repeat.json"
|
|
assert run_repeat_gate.run_repeat_gate(["test.py"], output=output) == 1
|
|
evidence = json.loads(output.read_text())
|
|
assert evidence["flake_candidates"] == [{
|
|
"nodeid": "tests.test_example::test_flake",
|
|
"occurrences": 2,
|
|
}]
|