diff --git a/docs/internal/testing-playbook.md b/docs/internal/testing-playbook.md index 4d75354b5ff..21edb803966 100644 --- a/docs/internal/testing-playbook.md +++ b/docs/internal/testing-playbook.md @@ -360,9 +360,12 @@ The merged Reborn LCOV report enforces three complementary ratchets: baseline (which supersedes the historical 80.81% floor); - critical production crates have percentage and covered-line floors in [`tests/integration/coverage-floor.toml`](../../tests/integration/coverage-floor.toml); -- added, instrumentable production lines and branch arms must be covered. The - denominator comes from the pull-request diff intersected with LLVM `DA` and - `BRDA` records, not from a hand-maintained file list. +- added, instrumentable production code must meet the original committed 90% + changed-line floor. Changed-branch coverage is still required in LCOV and + reported for review, but has no universal percentage floor. The denominator + comes from the pull-request diff intersected with LLVM `DA` and `BRDA` + records, not from a hand-maintained file list. Missing production coverage + and changed files with no measured instrumented lines remain hard failures. Changed-code exemptions live in [`tests/integration/changed-coverage-exemptions.toml`](../../tests/integration/changed-coverage-exemptions.toml). diff --git a/scripts/ci/test-reborn-changed-coverage.sh b/scripts/ci/test-reborn-changed-coverage.sh index f73e46589ab..b793f7ed1dc 100755 --- a/scripts/ci/test-reborn-changed-coverage.sh +++ b/scripts/ci/test-reborn-changed-coverage.sh @@ -123,6 +123,59 @@ check_text "line denominator is reported" "Changed line coverage: 100.00% (3/3)" check_text "branch denominator is reported" "Changed branch coverage: 100.00% (2/2)" check_report_text "machine report preserves the branch denominator" '"instrumented_branches": 2' +echo "▶ restored original changed-line floor" +cat >"${work}/policy.toml" <<'TOML' +[policy] +line_percent = 90.0 +branch_percent = 0.0 +TOML +threshold_lines=20 +: >"${case_root}/${source_path}" +: >"${work}/change.diff" +printf '%s\n' \ + "diff --git a/${source_path} b/${source_path}" \ + "--- /dev/null" \ + "+++ b/${source_path}" \ + "@@ -0,0 +1,${threshold_lines} @@" >>"${work}/change.diff" +for line in $(seq 1 "${threshold_lines}"); do + printf 'pub fn threshold_line_%s() {}\n' "${line}" >>"${case_root}/${source_path}" + printf '+pub fn threshold_line_%s() {}\n' "${line}" >>"${work}/change.diff" +done +write_threshold_lcov() { + local line_18_hits="$1" + printf 'SF:%s\n' "${case_root}/${source_path}" >"${work}/coverage.lcov" + for line in $(seq 1 17); do + printf 'DA:%s,1\n' "${line}" >>"${work}/coverage.lcov" + done + printf 'DA:18,%s\nDA:19,0\nDA:20,0\n' "${line_18_hits}" \ + >>"${work}/coverage.lcov" + for line in $(seq 1 20); do + printf 'BRDA:%s,0,0,0\n' "${line}" >>"${work}/coverage.lcov" + done + printf 'LF:20\nBRF:20\nend_of_record\n' >>"${work}/coverage.lcov" +} + +write_threshold_lcov 1 +run_gate +check_rc "90% changed lines pass at the original floor" 0 +check_text "line floor denominator is reported" "Changed line coverage: 90.00% (18/20)" +check_text "ungated branch coverage remains visible" "Changed branch coverage: 0.00% (0/20)" +check_text "uncovered branch detail remains visible" "${source_path}:1 branch 0/0" +check_report_text "machine report records the 90% line floor" '"threshold_percent": 90.0' +check_report_text "machine report records the zero branch floor" '"branch_threshold_percent": 0.0' + +write_threshold_lcov 0 +run_gate +check_rc "changed-line coverage below 90% fails" 1 +check_text "line-floor failure names the original threshold" "line coverage 85.00% is below 90.0%" + +printf '%s\n' 'pub fn classify(value: bool) -> bool {' ' value' '}' >"${case_root}/${source_path}" +cat >"${work}/policy.toml" <<'TOML' +[policy] +line_percent = 100.0 +branch_percent = 100.0 +TOML + echo "▶ diff markers inside hunk content are parsed by their first byte" cat >"${work}/change.diff" <<'DIFF' diff --git a/crates/ironclaw_demo/src/lib.rs b/crates/ironclaw_demo/src/lib.rs diff --git a/scripts/ci/test_reborn_changed_coverage.py b/scripts/ci/test_reborn_changed_coverage.py index 12e2f9e91d6..3d182102cb3 100755 --- a/scripts/ci/test_reborn_changed_coverage.py +++ b/scripts/ci/test_reborn_changed_coverage.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -"""Workflow-contract tests for strict changed-line and branch coverage.""" +"""Workflow-contract tests for thresholded changed-line and branch coverage.""" from __future__ import annotations @@ -7,6 +7,7 @@ import re import subprocess import tempfile +import tomllib import unittest from pathlib import Path @@ -16,7 +17,7 @@ class ChangedCoverageWorkflowTests(unittest.TestCase): - def test_strict_gate_sabotage_harness_passes(self): + def test_gate_sabotage_harness_passes(self): result = subprocess.run( ["bash", "scripts/ci/test-reborn-changed-coverage.sh"], cwd=ROOT, @@ -32,7 +33,16 @@ def test_strict_gate_sabotage_harness_passes(self): ) self.assertIsNotNone(success, result.stdout) - def test_reborn_workflow_runs_strict_gate_and_preserves_machine_report(self): + def test_committed_policy_restores_original_line_floor(self): + with (ROOT / "tests/integration/changed-coverage-exemptions.toml").open( + "rb" + ) as handle: + policy = tomllib.load(handle)["policy"] + + self.assertEqual(policy["line_percent"], 90.0) + self.assertEqual(policy["branch_percent"], 0.0) + + def test_reborn_workflow_runs_gate_and_preserves_machine_report(self): workflow = (ROOT / ".github/workflows/reborn-tests.yml").read_text( encoding="utf-8" ) @@ -53,7 +63,7 @@ def test_reborn_workflow_runs_strict_gate_and_preserves_machine_report(self): self.assertNotIn( "--threshold", gate_step, - "the strict line/branch gate has no threshold CLI and must gate every denominator", + "thresholds come from the reviewed manifest, not a workflow override", ) self.assertRegex( workflow, diff --git a/tests/integration/changed-coverage-exemptions.toml b/tests/integration/changed-coverage-exemptions.toml index 556aa88e839..06b53e51369 100644 --- a/tests/integration/changed-coverage-exemptions.toml +++ b/tests/integration/changed-coverage-exemptions.toml @@ -1,11 +1,14 @@ -# Changed-code coverage is intentionally strict: every LLVM-instrumentable -# production line and branch arm added by a PR must execute. An exemption is -# exact-line only and requires an owner, reason, tracking issue, and review -# date. Whole-file and glob exemptions are not supported. +# Changed-code coverage retains the original 90% changed-line floor. Branch +# coverage remains required in LCOV and reported for review, but it has no +# universal percentage floor: defensive async/backend arms made a blanket +# branch threshold incentive-incompatible with meaningful tests. Missing +# production coverage and changed files with an empty instrumented denominator +# still fail closed. Exemptions remain exact-line only; whole-file and glob +# exemptions are not supported. [policy] -line_percent = 100.0 -branch_percent = 100.0 +line_percent = 90.0 +branch_percent = 0.0 # Example (remove the comment markers only after reviewer approval): #