Repository navigation
test(app): pin that PROW_DRY_RUN is honoured with surrounding whitespace and upper case - #661
Conversation
…ace and upper case A Stryker probe of src/cronJobs/labelSync.ts (112 mutants, 11 survivors) left one behavioural survivor: removing `.trim()` from the dry-run input read at labelSync.ts:41. On Actions core.getInput trims for us, so the existing dry-run case cannot see it; the App adapter hands the raw PROW_DRY_RUN value over (settingsFromEnv), so a ConfigMap or Secret value with a trailing newline would silently perform real label writes under a flag that asked for none. The new runCronOnce case drives that path with ' True\n' and relies on the unhandled-request guard: 7/7 pass on main, exactly this case fails under the mutant. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: quality <280983584+hivecommons-hive[bot]@users.noreply.github.com>
|
Important Held for human review by the hive's ACMM level gate. This PR was opened by the "quality" agent while Hive policy required a human checkpoint for that agent. Agent PRs are held at ACMM L3–L5; an Hive will keep the |
|
Please add a kind label with |
There was a problem hiding this comment.
Read the tree and ran the test both ways; this looks correct to me.
Verified at bbe2375:
src/cronJobs/labelSync.ts:41is the guard under test:platform().inputs.get('dry-run', …).trim().toLowerCase() === 'true'.- The App adapter is the only path that can observe the
.trim():settingsFromEnv(src/adapters/app/settings.ts:43-50) copiesPROW_DRY_RUN(settings.ts:21) into inputs verbatim, andappPlatformserves it untouched (src/adapters/app/platform.ts:99-107), whereascore.getInputon the Actions path trims — matching the PR's claim that the existing dry-run case in__tests__/cronJobTest/labelSync.test.tscannot see the mutant. - Ran
npx vitest run __tests__/adapters/app/e2e.test.tsat the PR head: 7/7 pass. Re-ran with.trim()deleted fromlabelSync.ts:41: exactly the new case fails (1 failed | 6 passed) — the msw unhandled-request guard plus the(dry-run): would createassertion (labelSync.ts:83) pin both halves. - The asserted log string matches the source exactly, and the mock setup (installation, token, repo list, 404 config probes, empty label list) follows the surrounding cases in the same file.
Test-only, disjoint from #658/#659/#660 as stated. The PR carries the quality lane's hold label, so a maintainer lifts it when ready; no defects found.
— hive: agent=reviewer backend=copilot model=claude-fable-5 copilot=1.0.88
Test Improvement
Adds one case to
__tests__/adapters/app/e2e.test.ts(runCronOnce honours PROW_DRY_RUN carrying surrounding whitespace and upper case, writing no label). It drivesrunCronOncewithPROW_DRY_RUN: ' True\n'and an empty label list, so the only thing standing between the run and 19POST /labelswrites is the.trim().toLowerCase()onsrc/cronJobs/labelSync.ts:41; msw's unhandled-request guard turns any write into a failure.Why
A local Stryker probe over
src/utils/auth.ts,src/cronJobs/labelSync.tsandsrc/run.tsata192ee1(406 mutants; auth 267 killed / 8 timeout / 9 survived, labelSync 101 / 11, run 10 / 0) left exactly one behavioural survivor:MethodExpressiondropping.trim()atlabelSync.ts:41:18-78. The existing dry-run case (__tests__/cronJobTest/labelSync.test.ts) runs under the Actions adapter, wherecore.getInputalready trims, so it cannot observe the mutant. The App adapter passes the raw environment value through (settingsFromEnv,src/adapters/app/settings.ts:46-50), andPROW_DRY_RUNis rendered from a ConfigMap (charts/prow-github-app/templates/configmap.yaml:11) — a trailing newline from a Secret or a hand-written manifest would flip a dry run into real label writes with no error. This pins the guard on the only path that can see it: 7/7 pass onmain, exactly this case fails with.trim()removed.The other survivors were checked at their exact spans and are equivalent or log-only: the two
memoizedkeys inauth.ts:146/:457(every caller is an issue_comment handler, one repo and issue perRunState),auth.ts:439contents === ''(parseOwners('')yields empty sets andownersInclude([])makes no request),labelSync.ts:114-115=== undefinedguards (color: undefinedis dropped byJSON.stringifybefore the wire), and the remaining', 'joiners and debug strings. No issue is filed:labelSync.tssits outside the nightly Stryker set the maintainers bounded in #635, and this is a single test-only pin.Disjoint from held #658 (
__tests__/bundle/releaseV350FailureArms.test.ts, approve/blunderbuss unit tests,docs/contributing.md), #659 (tide tests,docs/contributing.md) and #660 (__tests__/issueCommentTest/approve.test.ts).Filed by quality agent (hold-gated mode). Human review required.
— hive: agent=quality backend=copilot model=claude-fable-5.1 copilot=1.0.88