mirror of
https://github.com/norandom/OpenUltraSAST.git
synced 2026-10-16 03:49:26 +00:00
pre-push(17.2): name every skipped check in plain words
One terminal line per distinct coverage reason (push/explain.py): hex-encoded paths decoded, per-question sha256 tokens dropped and counted, unknown reasons still printed; the JSON artifact keeps the raw values. A changed language with no engine frontend and no quick rules is recorded and printed as "language not covered: <lang> (...)", in pre-push and in `ousast scan`. The scan report renders the eight degradations cli.py recorded but never showed, and any reason without a sentence. The hook forwards OUSAST_COMPARISON_BASE. Requirement 9.2. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01EmM1j46qgKMh3zqD1QMwEo
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
bf07cd4d1d
commit
f555dee640
@@ -654,3 +654,46 @@ def test_a_clean_scan_states_no_coverage_gaps(tmp_path) -> None: # type: ignore
|
||||
degradations=[],
|
||||
)
|
||||
assert "### What could not be analysed" not in path.read_text()
|
||||
|
||||
|
||||
def test_every_recorded_scan_degradation_is_rendered(tmp_path) -> None: # type: ignore[no-untyped-def]
|
||||
"""pre-push 17.2 / Req 9.2: the eight degradations cli.py records and the report used to drop."""
|
||||
from openultrasast.reports import write_markdown_report
|
||||
|
||||
reasons = [
|
||||
{"stage": "model", "reason": "learning_endpoint_unavailable"},
|
||||
{"stage": "model", "reason": "cpg_unavailable"},
|
||||
{"stage": "overlay", "reason": "facts_unavailable", "detail": "missing table"},
|
||||
{"stage": "obligations", "reason": "facts_unavailable"},
|
||||
{"stage": "obligations", "reason": "policy_invalid", "detail": "bad toml"},
|
||||
{"stage": "model", "reason": "model_withheld_execution_budget"},
|
||||
{"stage": "budget", "reason": "max_findings_exceeded", "requested": 5, "actual": 9},
|
||||
{"stage": "map", "reason": "hunter_model_unavailable"},
|
||||
{"stage": "regress", "reason": "sandbox_unavailable"},
|
||||
{"stage": "x", "reason": "not_yet_described"},
|
||||
]
|
||||
path = tmp_path / "report.md"
|
||||
write_markdown_report([], path, [], degradations=reasons)
|
||||
text = path.read_text()
|
||||
for needle in (
|
||||
"No model endpoint is configured",
|
||||
"Joern engine is not installed",
|
||||
"fact tables for the `overlay` stage",
|
||||
"fact tables for the `obligations` stage",
|
||||
"`obligations` policy could not be loaded",
|
||||
"time budget leaves no room",
|
||||
"first 5 of 9 findings",
|
||||
"needs a model and none is available",
|
||||
"Docker is not available",
|
||||
"`not_yet_described`",
|
||||
):
|
||||
assert needle in text, needle
|
||||
|
||||
|
||||
def test_quick_scan_names_a_language_nothing_covers(tmp_path, capsys) -> None: # type: ignore[no-untyped-def]
|
||||
"""pre-push 17.2 / Req 9.2: a Go-only tree is not a silent zero."""
|
||||
(tmp_path / "run.go").write_text('package main\n\nimport "os/exec"\n\nfunc run(c string) { exec.Command("sh", "-c", c).Run() }\n')
|
||||
assert main(["scan", str(tmp_path), "--mode", "quick"]) == 0
|
||||
assert "notice: language not covered: go (1 files)" in capsys.readouterr().out
|
||||
report = next((tmp_path / ".openultrasast" / "runs").iterdir()) / "report.md"
|
||||
assert "Not a clean result for go (1 files)" in report.read_text()
|
||||
|
||||
Reference in New Issue
Block a user