Repository navigation
test(app): pin the lock-error sink of redisStores, the deadline cap of redisLocks and the hundred-per-page lister - #681
Conversation
…f redisLocks and the hundred-per-page lister
A Stryker pass over src/adapters/app/*.ts, src/server/{node,main}.ts and
src/platform/index.ts (580 mutants, 96.55 %) left three survivors that
change what the App does rather than what it logs, and no test noticed:
- src/server/node.ts:48 `redisLocks(client, { sink })` -> `{}`: a renewal
or release that fails would be swallowed instead of logged. stores.test.ts
now drives a failing EVAL through storesFromEnv and expects the line.
- src/adapters/app/redis.ts:83 `deadline - Date.now()` -> `+`: the last
wait would no longer be cut to the deadline, so withLock could sleep up to
a second past waitMs. The default-wait test now expects the clock to end
exactly on the deadline rather than at or after it.
- src/adapters/app/cron.ts:37/47 `{ per_page: 100 }` -> `{}`: the lister
would page thirty at a time, several times the requests of #641's intent.
The paging test now records the per_page of every request.
The other survivors are equivalent at their span (Response's default status,
a falsy default, platform() falling back to the same value, log text, the
token prefix slice, the private-key trim the JWT signer repeats) or need the
real-Redis describe that CI runs with REDIS_TEST_URL (the Lua literals).
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 |
There was a problem hiding this comment.
Read the three pinned source spans at head b6ce2ac, not just the diff. All three assertions are grounded and deterministic:
src/server/node.ts:48passes{ sink }toredisLocks; the newstores.test.tscase fails if that option is dropped, sinceredisLocksdefaults the sink to a no-op (src/adapters/app/redis.ts:70) and the release-failurereportatredis.ts:99would then go nowhere.- The exact-equality pin
expect(now).toBe(1_000_000 + lockWaitMs)is safe despite the unmocked jitter: the sleep insrc/adapters/app/redis.ts:84isMath.min(round(backoff * jitter), deadline - Date.now()), and the test's sleep mock advancesnowby exactly that amount, so the final wait always lands on the deadline — equality holds for any jitter value, and thedeadline + Date.now()mutant overshoots and fails it. src/adapters/app/cron.ts:37and:47both paginate withper_page: 100; the recordedpageSizesorder (installations fully, then repositories per installation token) matches howrepositories()drives the two listers.
Tests-only, no src/ or config change, CI green. Looks correct to me — a maintainer can take this on the strength of the pins.
— hive: agent=reviewer backend=copilot model=claude-fable-5
|
/kind cleanup 🐝 Hive Agent: — hive: agent=quality backend=copilot model=claude-fable-5.1 |
Description
Three tests-only pins from a Stryker pass over
src/adapters/app/*.ts,src/server/{node,main}.tsandsrc/platform/index.tsatmain9aa12b8 — the GitHub App adapter and server, which have changed in #614, #615, #623, #640, #641, #648, #649, #652 and #654 since they were last probed, and which sit outside the nightlymutationset (stryker.nightly.config.mjs). 580 mutants, 555 killed, 5 timed out, 20 survived (96.55 %). Of the 20, three change what the App does rather than what it logs, and no test noticed:src/server/node.ts:48redisLocks(client, { sink })→redisLocks(client, {})redisLocksdefaults the sink to a no-op)__tests__/server/stores.test.ts:storesFromEnv({ REDIS_URL }), a rejectingEVAL, expectredis lock o/r#1: release failed: offlineon the sinksrc/adapters/app/redis.ts:83deadline - Date.now()→deadline + Date.now()withLocksleeps up to a second (maxRetryMs) pastwaitMs__tests__/adapters/app/redis.test.tsdefault-wait test: the mocked clock must end exactly on1_000_000 + lockWaitMs, not at or after itsrc/adapters/app/cron.ts:37and:47{ per_page: 100 }→{}appInstallationListerpages thirty at a time — several times the requests #641 set out to avoid for an App on many installations or repositories__tests__/adapters/app/cron.test.tspaging test recordsper_pageof everyGET /app/installationsandGET /installation/repositoriesEach assertion was run against its mutant applied by hand: 1 failed / rest passed in each file; 39 passed with
src/restored.The remaining 17 survivors are left, read at their exact span:
webhook.ts:59/:68{ status: 200 }→{}(aResponse's default status);node.ts:122() => false→() => undefined(only ever tested for truthiness);platform/index.ts:26get: () => current→() => undefined(platform()readsscope.get() ?? current, the same value);redis.ts:75.slice(2)of the lock token (the0.prefix changes nothing);settings.ts:40.trim()of the private key (universal-github-app-jwttrims the PEM again before signing);platform.ts:108value === ''→true(onlyoctokit.tspassesrequired: true, forgithub-token, which returns before that line);cron.ts:107theschedule-…delivery id and:132'schedule'event tag of log lines,node.ts:203the'info'level of the drain line;lock.ts:34-36thetailsmap cleanup ofmemoryLocks(a private map; dropping it only grows memory);redis.ts:59/:61the release and renew Lua literals — theagainst a redis serverdescribe, which build-test runs withREDIS_TEST_URL, fails on a wrong script (the ttl test would seestolen; the exclusion test would wait on a never-released lock), so they are 0-test survivors locally and killed in CI.No issue is opened: these files sit outside the nightly set the maintainers bounded, and the Stryker-survivor class is held under the gate proposal in #594; as with #660, the pins ship directly. No
src/,dist/or threshold change.Testing
npx vitest run __tests__/adapters/app/cron.test.ts __tests__/adapters/app/redis.test.ts __tests__/server/stores.test.ts: 39 passed, 4 skipped (the real-Redis describe, noREDIS_TEST_URLhere)src/fails exactly its new assertionnpx eslinton the three files,npm run typecheck,git diff --checknpm run test:coverageat 9aa12b8: 100 / 99.89 / 100 / 100 (1911/1913 branches, the two documentedawaitartefacts)Checklist
dist/, dependency or source change, sonpm run packis not applicableFiled by quality agent (hold-gated mode). Human review required.
— hive: agent=quality backend=copilot model=claude-fable-5.1