Skip to content

✅ test: teach the dist_* gates to tell code from comments - #328

Merged
konih merged 4 commits into
mainfrom
lane/gate-comment-01-r2
Aug 23, 2026
Merged

✅ test: teach the dist_* gates to tell code from comments#328
konih merged 4 commits into
mainfrom
lane/gate-comment-01-r2

Conversation

@konih

@konih konih commented Aug 23, 2026

Copy link
Copy Markdown
Collaborator

Problem

The two dist_* gates could not tell code from comments, so the states they exist to prevent were reachable while both stayed green:

  • Commenting out the operator-sdk install body in ci.yaml left the wiring gate green.
  • Commenting out the bash "${script}" line inside the dist_* glob step left it green — the glob would expand and match scripts that were then never run.
  • Two OperatorHub checks were satisfied by comments alone (release.yaml:478,481,499).
  • The wiring gate's own self-test counted any nonzero exit as "the gate rejected this mutant", so an empty file, an unparseable file and a nonexistent path all "passed" the self-test. The self-test was measuring nothing.

Change

Ten mutation shapes are now permanent, built-in self-test assertions:

gate assertions before after
hack/test/dist_ci_wiring_test.sh 5 16
hack/test/dist_operatorhub_pr_test.sh 0 5

mutant_rejected now refuses to count an empty file, an unparseable file, a nonexistent path, or an unmutated copy of the real workflow as a rejection — closing the tautology in the self-test itself.

Note on the prescribed remedy

The reviewer-prescribed remedy in the story turned out to be insufficient. Comment-stripping alone does not close the bash "${script}" shape, because the glob step's stripped body still carries the matching literal on its scripts=(…) assignment. The author caught this and added a separate invocation assertion rather than relying on the strip.

Scope

Two files, zero Go. No workflow file is modified at any point in this branch's history.

konih added 4 commits August 23, 2026 18:55
`mutant_rejected()` counted ANY nonzero exit as "the gate rejected this mutation",
so the self-test proved nothing about the gate: an empty file, an unparseable file
and a nonexistent path all exit nonzero and each printed `ok - self-test: gate
rejects ...`. A self-test that passes on garbage is not evidence.

Each mutant must now be non-empty and byte-different from the real workflow, and
the rejection has to carry the message of the assertion the mutation was built to
trip -- `cmp` alone only rules out no-op mutations, it says nothing about WHICH
check fired, so the expected-message substring is the load-bearing half.

Adds `self_test_guard_holds()`, which re-runs the four degenerate "rejections"
(empty, unparseable, nonexistent, unmutated copy) through `mutant_rejected` every
CI run and fails if any of them is still accepted as proof.

Refs: GATE-COMMENT-01 (F-4)
The step anchors ran `contains()` over the RAW `run:` body, which cannot
distinguish a command from a comment. Two mutations exploited that and left the
gate fully green while producing exactly the end state it exists to prevent:

  - `run: "# bash hack/install-operator-sdk.sh ./bin"` still satisfied the
    install anchor, so `lint` ran the dist_* glob with no operator-sdk;
  - commenting out `bash "${script}"` inside the glob step's body still matched,
    because the surrounding `scripts=(hack/test/dist_*_test.sh)` line carries the
    literal -- the step expanded the glob and executed nothing.

Every anchor now matches a comment-stripped view of the body (`RUN_CODE`), which
closes the first shape. The second needs more than stripping, since the pattern
appears on lines other than the invocation, so the glob step must additionally be
shown to contain the `bash "${script}"` call; the failure names the exact line to
restore.

Both shapes are added to the built-in yq self-test, so they stay closed.

Refs: GATE-COMMENT-01 (F-1)
The gate asserted step ORDERING but never that the ordered steps are reachable
and enforcing. Four mutations satisfied every existing assertion while making the
dist_* meta-tests incapable of failing anything: `continue-on-error: true` or
`if: "false"` on the glob step, and the same two on `.jobs.lint` itself.

Adds those four assertions with distinct failure messages, and the matching
mutants to the built-in self-test. yq's `//` alternative operator cannot be used
for the defaulting here -- it treats a literal `false` as absent, which is exactly
the value being guarded against -- so the raw `yq eval` output is compared instead.

`continue-on-error` on the operator-sdk install step is deliberately NOT asserted:
that is a different class. A soft-failed install still reds the build, because the
glob step it feeds is not soft-failed and dies without the binary.

Refs: GATE-COMMENT-01 (F-5)
The workflow reference checks grepped the raw release.yaml, on a committed
rationale that the file inverts. Measured with a strip-every-executable-line
sweep against release.yaml:

  - OPERATORHUB_PAT        vacuous — comments at :478 and :481 kept it GREEN
  - hack/operatorhub-pr.sh vacuous — the comment at :499 kept it GREEN
  - operatorhub-pr:, continue-on-error: true, hack/install-operator-sdk.sh
                           already redded; no comment carries those literals

The old comment claimed the opposite: that install-operator-sdk was the risky
one, and that a raw grep for it "would keep passing if the `run:` line were ever
commented out or deleted". The deletion half was false. That comment is corrected
here rather than left to mislead the next reader.

All five checks now run over a comment-stripped view, and a built-in self-test
re-measures the property every CI run: for each literal it rebuilds release.yaml
with the executable occurrences removed and asserts the check reds. A `cmp` guard
fails loudly if a literal has no executable occurrence at all, so an assertion
that comments alone satisfy can no longer hide as a passing check.

Refs: GATE-COMMENT-01 (F-2, F-3)
@codecov

codecov Bot commented Aug 23, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@sonarqubecloud

Copy link
Copy Markdown

@konih
konih merged commit a231291 into main Aug 23, 2026
32 checks passed
@konih
konih deleted the lane/gate-comment-01-r2 branch August 23, 2026 17:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant