Repository navigation
test: finish test-suite cleanup WP-3..WP-12 and promote shipped designs - #1349
Conversation
|
Important Review skippedToo many files! This PR contains 168 files, which is 68 over the limit of 100. To get a review, reduce the PR to 100 files or fewer by splitting it into smaller PRs or changing its base branch. Upgrade to a paid plan to raise the limit. This review couldn't start because sufficient usage credits or metered capacity aren't available. Add credits or update usage-based reviews in the billing tab, then retry.
|
TLA+ spec divergence review (auto-triggered)This PR touches files that the TLA+ safety spec has an anchor on (per Anchored files changed in this PR head (5e320c4):
What to check, by subsystem:
If the change is correct but requires a spec update, edit @claude review please verify TLA+ spec divergence per the checklist above. @codex review please verify TLA+ spec divergence per the checklist above. |
TLA+ spec divergence review (auto-triggered)This PR touches files that the TLA+ safety spec has an anchor on (per Anchored files changed in this PR head (2851afd):
What to check, by subsystem:
If the change is correct but requires a spec update, edit @claude review please verify TLA+ spec divergence per the checklist above. @codex review please verify TLA+ spec divergence per the checklist above. |
|
CI status on this branch:
Generated by Claude Code |
TLA+ spec divergence review (auto-triggered)This PR touches files that the TLA+ safety spec has an anchor on (per Anchored files changed in this PR head (8e7ef73):
What to check, by subsystem:
If the change is correct but requires a spec update, edit @claude review please verify TLA+ spec divergence per the checklist above. @codex review please verify TLA+ spec divergence per the checklist above. |
TLA+ spec divergence review (auto-triggered)This PR touches files that the TLA+ safety spec has an anchor on (per Anchored files changed in this PR head (944b6ef):
What to check, by subsystem:
If the change is correct but requires a spec update, edit @claude review please verify TLA+ spec divergence per the checklist above. @codex review please verify TLA+ spec divergence per the checklist above. |
TLA+ spec divergence review (auto-triggered)This PR touches files that the TLA+ safety spec has an anchor on (per Anchored files changed in this PR head (3c50453):
What to check, by subsystem:
If the change is correct but requires a spec update, edit @claude review please verify TLA+ spec divergence per the checklist above. @codex review please verify TLA+ spec divergence per the checklist above. |
|
Please review the current head (3c50453). The design spec is Generated by Claude Code |
|
Claude finished @bootjp's task in 26s —— View job Review of 3c50453: no blocking findingsI reviewed the full diff against What I checked
Non-blocking notes
TLA+ divergence checklist: the only anchored files touched are I found nothing blocking. |
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
Delete TestMaxAppliedIndexStartsFromSnapshotIndex (subsumed by TestOpenInitializesAppliedIndexFromPersistedSnapshot), replace the run-time AppliedIndexWriter check with a compile-time assertion, and drop TestHeaderAADBytes_Layout (same bytes as the Append variant). Point the three persistConfigSnapshot tests at persistConfigState, the function production calls, and delete the orphaned persistConfigSnapshot. Give the over-cap bootstrap batch test all 16385 registration rows so only the cap can reject it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Fm5mogKjCk6edosPUsnMWZ Signed-off-by: bootjp <noreply@anthropic.com>
…WP-7) TestServer_WriteRejectsMissingCSRF accepted any of 401/403/405 and still passed with CSRF removed; TestServer_DynamoCreateTable_MissingCSRFRejected covers the chain. TestKeyVizFanoutRunPeerOverlargeBody never exceeded the cap; its PR #686 reference moves onto TestKeyVizFanoutRunPeerExceedsBodyLimit. TestCatalogWatcherLoggerOption and TestAllLabelConstantsInAllLabels only read back what they set. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Fm5mogKjCk6edosPUsnMWZ Signed-off-by: bootjp <noreply@anthropic.com>
Delete tests that duplicate a survivor or cannot fail: the Phase-0 registration gate (its §2.3 note moves onto the table row), the buildLeaderForwarder happy path, the pebbleOptions pair, the EncryptionObserver and capability-fanout non-nil checks, the encryptionAdminWiringForGroup tests together with that uncalled function, the loadToken copies, the racy fanout dedup twin, the proxy map-only pubsub tests, and a duplicate encode-info helper. Retarget the KEK unwrap timing test onto loadKEKAndRunStartupGuards for a fresh node, drive the orphan branch of installOrAttach directly, and point the S3 and registry tests at newS3Server and registryLastSeen. Delete the uncalled startPprofServer, startMetricsServer, startS3Server, prepareS3Server and readWriterRegistryLastSeen wrappers; serverwiring already tests the live prepare functions. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Fm5mogKjCk6edosPUsnMWZ Signed-off-by: bootjp <noreply@anthropic.com>
Delete ten tests that a named survivor already covers or that cannot fail, plus the GSI-path duplicate of TestDynamoDB_QueryLeaseFallbackFencesAllGroups. Move the SigV4 signature table onto the live extractSigV4Signature and delete the uncalled extractS3Signature. Drive the SQS throttle tests through the production reset sequence (beginQueueReset before commit, invalidateQueueBuckets after) and delete invalidateQueue and bumpQueueEpoch; the lock-ordering comment moves onto invalidateQueueBuckets. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Fm5mogKjCk6edosPUsnMWZ Signed-off-by: bootjp <noreply@anthropic.com>
Delete seven redundant Redis tests and redis_server_setup_test.go, which only checked the store type the test harness itself injects. Retarget the tests that guarded dead twins onto the live paths and delete the twins: HDEL through hdelTxn (persistHashTxn), EXPIRE through the *ReadTimestamp dispatchers (dispatchExpireForType, dispatchCollectionExpire, dispatchHLLExpire, dispatchStringExpire), and the EXEC read fence through commandReadFenceTargets, queuedCommandReadFenceGroupTargets and redisReadFencedTimestampForTargets (the key-only fence chain and the discarded nil-server branch). Replace three tests that never reached the code they named: the invalid UTF-8 unsupported-command test now goes through Run() over raw RESP, the dual-encoding guard is seeded directly in the store and checked on HGET, HEXISTS and SISMEMBER, and the EXEC DEL timeout test asserts that the stream-deletion scan runs on a deadline-bounded context. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Fm5mogKjCk6edosPUsnMWZ Signed-off-by: bootjp <noreply@anthropic.com>
WP-0 through WP-8 have landed; WP-9 to WP-12 (migrations onto the shared test-support packages) remain. Record the three places where the implementation departed from the plan and the dead DynamoDB lease branch follow-up. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Fm5mogKjCk6edosPUsnMWZ Signed-off-by: bootjp <noreply@anthropic.com>
SIGTERM leadership transfer (#1291), DCO sign-off (#1306), the filesystem and SQLite Jepsen history budgets (#1321, #1333), Jepsen artifact archives, and the review approval label series (#1328, #1332, #1336, #1340) are all on main; their remaining live-verification milestones are met by successful runs on main. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Fm5mogKjCk6edosPUsnMWZ Signed-off-by: bootjp <noreply@anthropic.com>
…(cleanup WP-9..12) Replace the hand-rolled legacyListMetaDeltaKey copies in adapter, kv and distribution with store.LegacyListMetaDeltaKey, keeping each package's existing sequence number (adapter 0, kv 1), and derive the delta-looking user keys from the same helper. The internal/backup mirror stays independent on purpose. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Fm5mogKjCk6edosPUsnMWZ Signed-off-by: bootjp <noreply@anthropic.com>
Replace 154 receive-or-fail select blocks with testutil.Recv, NoRecv or Closed, keeping each block's timeout and failure message. A bare receive becomes Closed only when the file closes that channel and Recv only when it sends on it. Blocks were left alone when the choice was ambiguous, the case body uses break or goto, the failure is non-fatal (t.Error), or hoisting a case variable could shadow another name in the function (123 blocks). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Fm5mogKjCk6edosPUsnMWZ Signed-off-by: bootjp <noreply@anthropic.com>
Delete store/encryption_test_helpers.go, which exported a test-only CounterNonceFactory from production store; its byte layout matches encryption.NewDeterministicNonceFactory, which the callers now use. Replace the random-DEK keystore+cipher boilerplate with encryptiontest.NewCipher (fixed-byte DEKs are kept), and the temp-dir sidecar writers, including the byte-identical writeSidecarFixture and writeStatusFixture, with encryptiontest.WriteSidecar. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Fm5mogKjCk6edosPUsnMWZ Signed-off-by: bootjp <noreply@anthropic.com>
…cleanup WP-9..12) kv: replace stubLeaderEngine and noopEngine with one newStubLeaderEngine built on raftenginetest.StubEngine, stubFollowerEngine with newStubFollowerEngine, and the admin/internal LeaderView fakes with raftenginetest.StaticLeaderView. Fakes whose behaviour is the subject of the test (toggling leader, blocking reads, lease, call recording, panicking VerifyLeader) stay local. The etcd engine tests alias raftenginetest.TestStateMachine instead of carrying a copy. Fourteen kv loopback gRPC servers move onto grpctest.Serve and so pick up the production server options; servers whose tests assert the Serve error or need the listener address before construction are left as they are. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Fm5mogKjCk6edosPUsnMWZ Signed-off-by: bootjp <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Fm5mogKjCk6edosPUsnMWZ Signed-off-by: bootjp <noreply@anthropic.com>
…..12) localAdapterCoordinator and occAdapterCoordinator now dispatch through kvtest.LocalCoordinator (standalone DEL_PREFIX applied; OCC with read-key validation for the OCC variant) while keeping stubAdapterCoordinator's configurable leadership surface; LocalOptions gains a Clock so the wrapper and the dispatcher share one HLC. fstest.MemoryDispatcher and the filesystem-internal testCoordinator, which were byte-for-byte the same policy, now both use LocalCoordinator with store-increment timestamps, AdvanceCommitTS, OCC on every group and commit-timestamp patching. The near-identical HELLO and INFO coordinator fakes fold into stubAdapterCoordinator (which gains raftLeader), testCoordinatorWrapper embeds kv.Coordinator instead of forwarding eight methods by hand, and the panicking kv fakeGroupRoutableCoordinator embeds a nil Coordinator. Behaviour notes: LocalCoordinator serializes dispatches, copies elements, checks ctx before applying, reports CommitTS/CommitIndex in the response, and returns ErrUnknownOp for unknown ops; an invalid commit-timestamp patch now surfaces kv's validation error instead of filesystem.ErrInvalid. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Fm5mogKjCk6edosPUsnMWZ Signed-off-by: bootjp <noreply@anthropic.com>
…p WP-9..12) phaseDGateCoordinator embeds an interface of exactly the methods it forwarded, retryOnceCoordinator fails once and then delegates to localAdapterCoordinator, and distributionLeaderView becomes a raftenginetest.StaticLeaderView. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Fm5mogKjCk6edosPUsnMWZ Signed-off-by: bootjp <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Fm5mogKjCk6edosPUsnMWZ Signed-off-by: bootjp <noreply@anthropic.com>
3c50453 to
2134e7b
Compare
TLA+ spec divergence review (auto-triggered)This PR touches files that the TLA+ safety spec has an anchor on (per Anchored files changed in this PR head (2134e7b):
What to check, by subsystem:
If the change is correct but requires a spec update, edit @claude review please verify TLA+ spec divergence per the checklist above. @codex review please verify TLA+ spec divergence per the checklist above. |
…query prefix path (#1354) Design: docs/design/2026_10_16_partial_test_suite_cleanup.md ## Summary Follow-up to #1349: remove the dead `keySchema.HashKey != schema.PrimaryKey.HashKey` branches from the DynamoDB Query prefix path (WP-5 deviation 1 and its follow-up). 1. **`queryLeasePrefix`** (`adapter/dynamodb_lease.go`). It is only reached from `queryLeaseKey` for a Query without an `IndexName`, so `keySchemaForQuery` always returns the primary key and the `→ queryLeaseAllGroups` branch could never run. 2. **`queryScanPrefix`** (`adapter/dynamodb_query_scan.go`), both the legacy and the ordered-encoding twin. Every caller (`queryLeasePrefix`, `resolveQueryReadBounds`, `queryItemsByKeyCondition`, `queryItemsByGSI`) gets its key schema from `keySchemaForQuery(in.IndexName)` on the same input. Without an `IndexName` that is the primary key. With one, the GSI prefix is returned before the comparison. The migration path passes `migrationSourceSchema()`, which copies the target's `PrimaryKey`, so the comparison holds there too. The branches, the `keySchema` parameter they were the only use of, and the parameter that removal left unused in `queryItemsByKeyCondition` are gone. The PR originally also widened the `TestMigrationQuorumPartitionAcceptance` snapshot wait to fix `main` ([run 40825629367](https://github.com/bootjp/elastickv/actions/runs/40825629367/job/123287896346)). #1347 fixed the same wait on `main` by bounding it with the phase budget, so the merge of `main` takes its version and this PR no longer touches that test. ## Behaviour change - Production: none at run time; every removed branch was unreachable. - Tests: two new table tests. ## Test evidence - `TestQueryLeasePrefix_BaseTableClassification`: a pinned hash key resolves to its single-group prefix; a non-key or malformed condition is a validation skip. Its expected prefix is now built from `attributeValueAsKeySegment` + `dynamoItemHashPrefixForTable` rather than from `queryScanPrefix` itself (CodeRabbit nit). - `TestQueryScanPrefix_SelectsHashPrefixPerEncoding`: base-table and GSI prefixes for both the ordered and the legacy key encoding, never the whole-table prefix. - Mutations (via `go test -overlay`): - ordered base table returns `dynamoItemPrefixForTable` → both tests FAIL; - legacy base table returns `dynamoItemPrefixForTable` → `TestQueryScanPrefix_SelectsHashPrefixPerEncoding` FAILS; - `queryLeasePrefix` returns `queryLeaseAllGroups` → `TestQueryLeasePrefix_BaseTableClassification` FAILS. - `go test -race -run 'QueryScanPrefix|QueryLeasePrefix|DynamoDB|Query' ./adapter/`: pass. - `golangci-lint v2.15.0 --new-from-rev=origin/main`: 0 issues. - Jepsen: not run; no reachable behaviour changes. ## Self-review (five lenses) 1. **Data loss:** no write or persistence path is touched. 2. **Concurrency / distributed failures:** no concurrency change. 3. **Performance:** no hot-path change beyond one fewer comparison. 4. **Data consistency:** every Query still reads the same prefix (hash-key item prefix for base tables, index hash prefix for GSIs), and the base-table lease plan still resolves to a single group; both are now pinned by tests. GSI queries still take `gsiQueryLeasePlan` and fence all groups. 5. **Test coverage:** two table tests and three mutation checks; the design doc records the removal and drops the follow-up. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01Fm5mogKjCk6edosPUsnMWZ <!-- This is an auto-generated comment: release notes by coderabbit.ai --> <!-- coderabbit-ai-generated:v1 --> ## Summary by CodeRabbit * **バグ修正** * ベーステーブルへのクエリで有効なハッシュキー条件を指定すると、該当する単一グループのリース判定が行われるようになりました。 * キー条件に該当しない属性や不正な条件式では、リース判定をスキップします。 * ベーステーブルおよびセカンダリインデックスへのクエリで、適切な項目プレフィックスが選択されるようになりました。 <!-- end of auto-generated comment: release notes by coderabbit.ai -->
Design: docs/design/2026_10_16_partial_test_suite_cleanup.md
Summary
A survey of every
proposed/partialdesign doc found two kinds of unfinished work:mainbut still namedproposed. They are promoted toimplementedin a dedicated commit: SIGTERM leadership transfer (main: transfer Raft leadership before shutdown #1291), DCO sign-off (ci: enforce sign-offs with the Probot DCO app #1306), the filesystem/SQLite Jepsen history budgets (Bound scheduled filesystem Jepsen rename histories #1321, Bound scheduled SQLite Jepsen histories #1333), Jepsen artifact archives, and the review-approval-label series (ci: label current HEAD after a zero-finding code review #1328, ci: grant permission to label pull requests #1332, ci: revoke approval for findings mapped to current HEAD #1336, ci: distinguish resolved findings from earlier revisions #1340). Their last "verify live" milestones are met by successful runs onmain(Jepsen Test 40657220651, review label updater 40666978702).partial.The doc asks for one PR per WP. They are bundled here as one commit per WP (
raftengine,encryption:,adapter:×2,main,cmd,proxy:,test:), so each can be reviewed or split out separately.The larger proposed designs (serializable isolation audit, typed error boundaries, migration ownership partitions, apply-time readiness evidence, scaling/positioning roadmaps) touch replication, OCC and routing. This PR does not attempt them.
WP-9 to WP-12 migrations
All four directory sets were migrated together, one commit per pattern. The before/after counts and every intentional exception are recorded in the design doc under "WP-9 to WP-12 results":
selectblocks: 276 candidates; 154 replaced bytestutil.Recv/NoRecv/Closed. A bare receive becomesClosedonly when the file closes the channel andRecvonly when it sends on it. 122 remain, where the choice was ambiguous, the body usesbreak/goto, the failure is non-fatal, or hoisting a variable could shadow another name.store.LegacyListMetaDeltaKey, keeping each package's sequence number).store/encryption_test_helpers.go; 37encryptiontestcall sites.grpctest.Serve, so they now use the production server options.raftenginetest/kvtest. The in-memory apply coordinators, includingfstest.MemoryDispatcher, now dispatch throughkvtest.LocalCoordinator, which gains aClockoption so a wrapper can share its HLC. Fakes whose behaviour is the subject of the test stay local (rule 4).Intentional behaviour changes from the
LocalCoordinatormove:ctxis checked before applying;CommitTS/CommitIndex;ErrUnknownOp;filesystem.ErrInvalid.Behaviour change
None in production code. Production edits only delete functions that the retargets leave without callers, and fix comments that named them:
persistConfigSnapshot,encryptionAdminWiringForGroup,startPprofServer,startMetricsServer,startS3Server,prepareS3Server,readWriterRegistryLastSeen,extractS3Signature,bucketStore.invalidateQueue/bumpQueueEpoch,persistHashTxn,dispatchExpireForType,dispatchCollectionExpire,dispatchHLLExpire,dispatchStringExpire, and the key-only Redis read-fence chain plus its discarded nil-server branch. A repository-wide grep confirms none of them has a remaining caller.Deviations from the plan (also recorded in the doc)
queryLeasePrefixis only reached with an emptyIndexName, so the hash-key-mismatch branch is unreachable. I deleted the duplicate test and added removing the dead branch as a follow-up (it is a production change).internal/serverwiring, which already tests them, so I deleted the root wrappers and their tests instead of retargeting them.redisDispatchTimeoutis a 30 s constant. Instead of blocking, the test records the stream-deletion scan's deadline. The doc's mutation (context.Background()for the EXEC dispatch) survives becausetxnContext.dispatchContextbounds the context a second time. Breaking that second bound fails the test.Mutation table
Each mutation was applied only through
go test -overlayto a temporary copy.persistConfigStateTestPersistConfigStateSkipsSerializationWhenNewerSnapshotExistscount > maxBootstrapBatchCountTestBootstrap_RejectsOverCapBatchCountTestTimedKEKUnwrapperCoversStartupPreflightUnwrapsinstallOrAttachTestFanoutClientForOrphanedDialClosednewS3ServerTestNewS3ServerRejectsVirtualHostedStyleConfigregistryLastSeenreturns 0TestRegistryLastSeenlistenMonitoringTestPrepareMonitoringServers=delimiter infindSigV4ParamTestExtractSigV4SignaturebeginQueueResetExpireAtinpersistHashReadTimestampTxnTestRedisHDelLegacyRewritePreservesLegacyTTLdispatchCollectionExpireReadTimestampTestRedisCollectionExpire*TestRedisDispatchHLLExpireWritesInlineAnchorAndScanIndexredisLegacyBareReadFenceAllowedalways trueTestRedisExecReadFenceUsesRedisStorageKeysTestRedisMetricsUnsupportedCommandRawInvalidUTF8ByteshasHigherPriorityStringEncodingreturns falseTestRedis_FastPathGuardDualEncodingReportsWrongTypetxnContext.dispatchContextreturns an unbounded contextTestRedis_StreamMultiExecDelHonoursDispatchTimeout(both modes)context.Background()for the EXEC dispatch (plan's mutation)dispatchContext(deviation 3)kvtest.NewLocalCoordinatorignoresLocalOptions.ClockTestLocalCoordinatorSharesInjectedClockTest evidence
go test -race ./internal/raftengine/... ./internal/encryption/...: pass, exceptTestFinalizeAsFSMFile_RenameFailureCleansUpSpool. It fails identically on a clean checkout because the container runs as root, sochmod 0o500doesn't block writes. It is unrelated to this PR.go test -race . ./cmd/... ./proxy/... ./internal/serverwiring/...: pass.go test -race ./internal/admin/... ./distribution/... ./keyviz/...: pass.go test -race ./adapter/... .: root passes. The adapter package passes exceptTestMigrationQuorumPartitionAcceptance, which also fails on a cleanorigin/maincheckout in this container and failed once in CI on this branch (see the PR comment).TestMigrationQuorumCommitFollowsForcedLeadershipTransferfails intermittently under load and passed 3/3 in isolation. Neither test touches a file changed here.go test -race ./adapter/... ./kv/... ./store/... ./internal/filesystem/... ./internal/raftengine/... ./internal/admin/... .pass, apart from the pre-existing failures above.TestKernelMountReaddirPagesLargeDirectoryfailed once in a five-package parallel run and then passed 3 full-package runs, 2 more parallel runs and 20 targeted repetitions under load.golangci-lint v2.15.0 --new-from-rev=origin/main(the CI configuration): 0 issues.Self-review (five lenses)
persistConfigStateordering).Run(), recorder mutex), and the throttle tests use the production reset sequence. TheLocalCoordinatormove serializes test dispatches, asfstest.MemoryDispatcheralready did.ReadTimestamppaths. The bare-key!sqs|exclusion is mutation-checked. The migrated coordinators keep their timestamp policies (store+1 / StartTS+1 clamp for filesystem; HLC for adapter), and the adapter wrapper shares one HLC with the dispatcher.🤖 Generated with Claude Code
https://claude.ai/code/session_01Fm5mogKjCk6edosPUsnMWZ