Skip to content

raftengine: test live config persistence and bootstrap guards - #1346

Merged
bootjp merged 2 commits into
design/validation-lint-baselinefrom
design/test-suite-cleanup-wp3
Oct 28, 2026
Merged

bootjp merged 2 commits into
design/validation-lint-baselinefrom
design/test-suite-cleanup-wp3

Conversation

@bootjp

@bootjp bootjp commented Oct 28, 2026 •

Copy link
Copy Markdown
Owner

Design: docs/design/2026_10_16_proposed_test_suite_cleanup.md

Scope

Implement WP-3: retarget Raft/encryption tests to live code and remove only the resulting unused wrapper and redundant tests. No production behavior, wire format, or persistence format changes.

  • Move the three configuration-snapshot regressions to persistConfigState, using actual temporary data directories and explicit voter metadata.
  • Preserve newer-snapshot serialization avoidance, no-log-compaction, and the SaveSnap before Release/completed-publication assertions. Also verify durable peer metadata and the cached config index, so skipping the whole operation cannot satisfy the test.
  • Remove persistConfigSnapshot, which had only those test callers; retain the live payload helper.
  • Replace the runtime fake-interface test with a compile-time AppliedIndexWriter assertion.
  • Remove the self-restating applied-index test and duplicated AAD-layout test; keep the real Open snapshot-index regression and append/layout/allocation regression.
  • Give the over-cap bootstrap fixture all 16,385 registration records' wire bytes, and require the explicit cap error. The huge-count fixture also verifies cap-error precedence without allocating gigabytes.

This is WP-3 only, not completion of the whole test-cleanup design or #1330. It is independent of WP-1 (#1345).

Depends on #1347 (base: design/validation-lint-baseline). The signed merge 0904faefd257b247ef4bed3b3032efce2cfc0a0d incorporates its lint-baseline and snapshot-wait fixes without rewriting existing commits. The diff against that dependency stays limited to the five WP-3 files. After #1347 merges, retarget this PR to main and recheck CI before merging.

Verification

  • Targeted live configuration-state / persisted snapshot-index race tests: PASS (2.367s).
  • Targeted AAD/bootstrap tests and full fsmwire race suite: PASS. A diagnostic 90-second encryption run timed out in the unchanged TestKeystore_Concurrent; that failure and interrupted attempts are not passing evidence. The final full run below includes that test without skipping it and passed.
  • Raft/encryption package lint, unfiltered: PASS, zero issues (golangci-lint v2.15.0 run ./internal/raftengine/... ./internal/encryption/... --timeout=10m).
  • Full race command PASS (exit 0): GOMAXPROCS=4 go test -p 2 -race ./internal/raftengine/... ./internal/encryption/... . -count=1 -timeout=15m. Raft etcd 64.204s, transportsoak 3.357s, raftenginetest 1.982s, encryption 379.242s, encryptiontest 1.450s, fsmwire 1.133s, kek 1.457s, root 171.892s. No explicit short/skip filters were used; TestKeystore_Concurrent was included. Linux kernel-FUSE acceptance is remote-only.
  • Whole-repository CI-equivalent differential lint: PASS (zero new issues), golangci-lint v2.15.0 run ./... --new-from-rev=64fc9e62 --timeout=10m.
  • Integrated head 0904faef: unfiltered whole-repository lint PASS, zero issues (GOMAXPROCS=4 golangci-lint run ./... --timeout=10m, exit 0). Dependency validation: restore unfiltered lint and snapshot phase checks #1347 resolves the eight earlier baseline findings. No differential filter or new exclusions were used.
  • git diff --check: PASS.
  • Historical code and security reviews both completed with zero findings on 01ec486846db3d38dbb70e13aa69adc6c928a56d (code receipt, security receipt). Remote Jepsen encryption off/on passed. Full Go CI failed in unchanged TestMigrationQuorumPartitionAcceptance: the five-second wait for all four persisted native snapshots did not complete. Three isolated two-CPU race repetitions passed (90.317s), which does not erase the CI failure or establish its physical cause. The validation: restore unfiltered lint and snapshot phase checks #1347 fix is now incorporated in the signed merge head above: polling uses the existing 60-second write/snapshot phase context, still requiring actual persisted native snapshots on every voter and learner plus the original restored-byte and resolution-evidence assertions. Timeout diagnostics report the target and last observed snapshot indexes. The updated HEAD's passing review/CI receipts are recorded below; the older reviews/CI are historical only.

Mutation Evidence

Mutations use temporary go test -overlay copies only; no broken production code is committed.

Retarget Mutation Detecting Test Result
Config state Remove the newer-snapshot fast path from live persistConfigState TestPersistConfigStateSkipsSerializationWhenNewerSnapshotExists FAIL: cached config index stays 0 instead of 7
Bootstrap cap Remove count > maxBootstrapBatchCount TestBootstrap_RejectsOverCapBatchCount / TestBootstrap_RejectsHugeBatchCount Both FAIL: complete over-cap input accepted; huge input returns underflow instead of cap error

The initial config mutation also encountered a fixture mismatch between an unspecified suffrage and its persisted voter normalization. That is not counted as valid evidence. After fixing the fixture, the unmodified test passes and mutation fails on the actual config-index assertion. snapshotPayloadLocked retains a second serialization guard; the test does not falsely claim that serialization now occurs under this mutation.

CI Follow-up

The original failure was a five-second snapshot wait at line 700, not a failure of the retargeted configuration-state assertions. The CI log does not identify why a particular runner missed that window; no production Raft or storage defect is asserted from this timeout alone.

The dependency includes a red/green regression where final-member coverage arrives after 5.25 seconds within its phase deadline. With the old sub-budget it fails at five seconds; with phase-bounded waiting it passes. It also tests cancellation, expiry, partial and empty coverage. No member, payload, snapshot or restore requirement is removed.

Integrated head 0904faef: GOMAXPROCS=4 go test -p 2 -race ./adapter -run '^TestQuorumAcceptanceSnapshotWait|^TestMigrationQuorumPartitionAcceptance$' -count=2 -timeout=5m PASS (57.339s, exit 0). This includes two actual four-member snapshot/restart acceptance runs, not only the synthetic timing regression. Independent standards/spec reviews found no new issues.

Remote latest-HEAD verification on 0904faefd257b247ef4bed3b3032efce2cfc0a0d: all reported CI checks passed. Ubuntu full Go/race/gRPC CI, Jepsen encryption off/on, CodeQL, lint, build, TLA+ and DCO all succeeded. Post-push SHA-bound code and security review completed with no findings or unresolved findings. This supersedes the old 01ec4868 failure/reviews without erasing them. #1347 remains the base dependency; after it merges and this PR retargets main, recheck CI before merging.

Risk and Self-review

  1. Data loss: live snapshot/publication code is unchanged. The retargeted test preserves SaveSnap/Release order and completion checks.
  2. Concurrency / distributed failures: the blocking snapshot fixture retains bounded waits, cleanup release, and actual disk-backed metadata. Race results are reported above.
  3. Performance: no new production hot-path work. The test removes unnecessary serialization only by detecting regressions, not changing runtime behavior.
  4. Data consistency: peer identities, voter suffrage, configuration indexes and no-compaction behavior remain explicit assertions.
  5. Test coverage: every deleted test has its spec-named survivor or compile-time replacement. Cap tests no longer pass merely because their input is truncated; mutation evidence distinguishes that case.

Author: bootjp

Signed-off-by: bootjp <contact@bootjp.me>
@coderabbitai

coderabbitai Bot commented Oct 28, 2026 •

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 2a10ffed-c8e6-4ef7-bc7e-7008647a9105

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@bootjp
bootjp marked this pull request as ready for review October 28, 2026 06:30
@bootjp

bootjp commented Oct 28, 2026

Copy link
Copy Markdown
Owner Author

@codex review

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 28, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-28T10:15:49.051369Z 0904fae Manual request
🔒 Security Review ✅ Completed 2026-10-28T10:17:07.244506Z 0904fae Manual request
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Breezy!

Reviewed commit: 01ec486846

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@chatgpt-codex-connector

Copy link
Copy Markdown

🛡️ Codex Security Review · Automatically triggered

Security review completed. No security issues were found in this pull request.

Reviewed commit: 01ec486846

View security finding report

Only the user who started this review can view the report in Codex.

ℹ️ About Codex security reviews in GitHub

This is an experimental Codex feature. Security reviews are triggered when:

  • You comment "@codex security review"
  • A regular code review gets triggered (for example, "@codex review" or when a PR is opened), and you’re opted in so security review runs alongside code review

Once complete, Codex will leave suggestions, or a comment if no findings are found.

@github-actions github-actions Bot added the agent-review-approved Current HEAD has a completed code review with zero findings label Oct 28, 2026
Signed-off-by: bootjp <contact@bootjp.me>
@github-actions github-actions Bot removed the agent-review-approved Current HEAD has a completed code review with zero findings label Oct 28, 2026
@bootjp
bootjp changed the base branch from main to design/validation-lint-baseline October 28, 2026 10:14
@github-actions

Copy link
Copy Markdown
Contributor

TLA+ spec divergence review (auto-triggered)

This PR touches files that the TLA+ safety spec has an anchor on (per
docs/design/2026_05_28_implemented_tla_safety_spec.md §3),
so an AI review is requested below to verify the implementation has not drifted
from the model.

Anchored files changed in this PR head (0904fae):

  • kv/fsm.go

What to check, by subsystem:

  • kv/hlc*.go — Next() must respect the HLC-4 preconditions (i)/(ii)/(iii) from the design doc: bounded skew, logical-counter handoff on leader change (strategy (c) Observe(MaxAppliedHLC)), and the commit-time ceiling fence (fail-closed when wall_now >= physicalCeiling). Any change to the bit layout (48/16), the CAS loop, or the ceiling getter/setter is in scope.
  • kv/coordinator.go, kv/sharded_coordinator.go — RunHLCLeaseRenewal, hlcRenewalInterval, hlcPhysicalWindowMs constants, and the new-term detection that calls Observe(fsm.MaxAppliedHLC()) (strategy (c)). Any change to renewal cadence, group selection, or fail-closed behaviour is in scope.
  • kv/transaction.go, kv/lock_resolver.go — OCC commit-ts assignment, lock-map encoding (key, lock_ts) -> start_ts, and the LockResolver action OCC-3 depends on. (M2 spec will land OCC-1..OCC-5; until then the spec doc §5.2 is the contract.)
  • kv/fsm.go — FSM apply of HLC lease entries (SetPhysicalCeiling), and any future MaxAppliedHLC() accessor that strategy (c) needs.
  • store/mvcc_store.go — version visibility, snapshot install, and the MVCC-1..MVCC-4 invariants (M3 scope).
  • distribution/** — route catalog versioning, SplitRange atomicity, and CatalogWatcher async fan-out (M4 scope).

If the change is correct but requires a spec update, edit tla/hlc/HLC.tla (or the corresponding M2..M5 module once landed) and the design doc in the same PR. The tla-check workflow runs the TLC model check on the same paths.


@claude review please verify TLA+ spec divergence per the checklist above.

@codex review please verify TLA+ spec divergence per the checklist above.

@bootjp

bootjp commented Oct 28, 2026

Copy link
Copy Markdown
Owner Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. 🚀

Reviewed commit: 0904faefd2

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@chatgpt-codex-connector

Copy link
Copy Markdown

🛡️ Codex Security Review · Automatically triggered

Security review completed. No security issues were found in this pull request.

Reviewed commit: 0904faefd2

View security finding report

Only the user who started this review can view the report in Codex.

ℹ️ About Codex security reviews in GitHub

This is an experimental Codex feature. Security reviews are triggered when:

  • You comment "@codex security review"
  • A regular code review gets triggered (for example, "@codex review" or when a PR is opened), and you’re opted in so security review runs alongside code review

Once complete, Codex will leave suggestions, or a comment if no findings are found.

@github-actions github-actions Bot added the agent-review-approved Current HEAD has a completed code review with zero findings label Oct 28, 2026
@bootjp

bootjp commented Oct 28, 2026

Copy link
Copy Markdown
Owner Author

CI follow-up complete on 0904fae. The existing #1347 snapshot-phase fix is incorporated through a signed merge. The original failed Ubuntu job is superseded by passing run https://github.com/bootjp/elastickv/actions/runs/40670552848; encryption off/on Jepsen, CodeQL, lint, build, TLA+ and DCO also passed. The post-push review and security review both completed with no findings on this exact HEAD. No member, snapshot/restore requirement, payload or workload was removed. #1347 remains the dependency; CI must be checked again after retargeting to main.

@bootjp
bootjp merged commit 30fd929 into design/validation-lint-baseline Oct 28, 2026
14 checks passed
@bootjp
bootjp deleted the design/test-suite-cleanup-wp3 branch October 28, 2026 10:32
@github-actions github-actions Bot removed the agent-review-approved Current HEAD has a completed code review with zero findings label Oct 28, 2026
bootjp added a commit that referenced this pull request Oct 29, 2026
Design: docs/design/2026_10_28_proposed_validation_lint_baseline.md

## Purpose

Restore the **unfiltered** repository lint baseline required by the
test-cleanup design, and make one native-snapshot acceptance wait honor
its existing phase deadline. This is a separate validation prerequisite,
not a claim that #1330 or all unfinished designs are complete.

The design was committed before implementation and independently
reviewed. It covers all eight findings on main `64fc9e62`: four
complexity reports, two duplicate bodies, one unused-parameter report,
and one nested-test complexity report. Removing the first unused
argument revealed a second always-nil wrapper argument; all five callers
were audited before removing both. General routed publication still
accepts real effect/read-key arguments.

## Changes

- Preserve main's migration of the memory dispatcher to
`kvtest.LocalCoordinator`; keep the added timestamp-boundary, copy,
unsupported-operation and OCC regressions on that shared path. The
obsolete local helpers are not restored.
- Extract journaled FUSE writes and share unlink/rmdir lifecycle
handling. Operation-specific capabilities remain independent;
session/capability checks precede operation-ID allocation. Admission,
refresh, empty writes, receipts, unknown-outcome classification, and
logging retain their order and errno behavior.
- Share the existing zero-or-mismatched attempt predicate in journal
planning/publication/rejection. Publication and duplicate-resolution
ordering is unchanged.
- Split the raw verdict predicate into protocol categories with the
exact prior sentinel set/evaluation order and readiness exclusion
priority.
- Preserve all 24 migration-control protection cases and every assertion
while extracting their case body.
- Replace the separate five-second snapshot wait with a poll bounded by
the **existing 60-second write/snapshot phase**. All actual members,
including the learner, still need persisted native snapshots covering
the ACKed write before restart; restored bytes and PREPARE evidence
assertions are unchanged.

No production wire/on-disk format, timestamp issuance, Raft settings,
authorization, retry policy, or default flags change. No suppression,
new exclusion, shorter workload, or test skip is added. PR #1344's
accounting trace and workflow changes are not duplicated or
incorporated; its changes affect different journal bodies from this
refactor.

## Verification

- **Unfiltered golangci-lint v2.15.0: PASS, 0 issues** with
`GOMAXPROCS=4 golangci-lint run ./... --timeout=10m`. No
`--new-from-rev` filter. The same command failed with the eight findings
before implementation.
- Focused new parity tests passed before and after their refactors: FUSE
partial capabilities/admission/session/unknown-outcome behavior;
dispatcher copy/boundary/OCC behavior; attempt identity; raw verdict
allowlist/exclusion. The extracted migration case set retains all 24
names/assertions.
- `GOMAXPROCS=4 go test -p 2 -race ./adapter -run
'^TestQuorumAcceptanceSnapshotWait|^TestMigrationQuorumPartitionAcceptance$'
-count=2 -timeout=5m`: PASS (74.843s), including actual native snapshot,
restart, restored bytes, and resolution-evidence requirements.
- Full filesystem/KV/root race: PASS (exit 0), `GOMAXPROCS=4 go test -p
2 -race ./internal/filesystem/... ./kv/... . -count=1 -timeout=20m`.
Filesystem 103.569s, fstest 1.822s, fuseadapter 11.005s, KV 69.721s,
kvtest 1.781s, root 104.345s. No short/skip flags are used. Kernel FUSE
checks require Linux CI rather than macOS local execution.
- An earlier worker full filesystem attempt failed in
`TestHandleContentionIsTerminalAndReplayable` with
deadline/unknown-outcome errors. Its cause was not established; a later
parent full filesystem run passed. The earlier failure is not counted as
passing evidence.
- `git diff --check`: PASS.

### Snapshot Regression Evidence

PR #1346's Go CI failed `TestMigrationQuorumPartitionAcceptance` at the
five-second wait for all four persisted native snapshots. Three isolated
two-CPU race repetitions of that unchanged test passed (90.317s). That
does not establish a production regression or identify the physical
cause of the CI delay.

The new focused regression makes the final member's snapshot coverage
arrive after 5.25 seconds, within its phase context. With the old
five-second sub-budget it **failed at 5.00s**, showing target 22 and
snapshots `[22 22 22 21]`. It passes when the helper uses the caller's
existing phase deadline. Separate cases reject partial/empty coverage,
canceled phases, and deadline expiration. This changes neither the real
acceptance phase's 60-second budget nor its payload, member count,
snapshot threshold, or restored-data assertions.

The helper reports target and last observed snapshot indexes on failure.
The test remains red if actual native snapshots do not cover the write
within the phase. It does not substitute applied indexes or a stub for
the real four-member acceptance case.

## Conflict Resolution Against Current Main

Merged main `75daeeb800ee9b661e5dfd3d9b91fb656928c145` without rewriting
existing history. Final HEAD: `3d2d0b436c8d953031713460bf2d1e229c149eae`
(bootjp author/committer, `contact@bootjp.me`, signature Verified and
DCO sign-off).

- Resolve four conflicted files: preserve main's shared coordinator
migration and exact-size bootstrap fixture, retain this PR's explicit
cap-error and durable peer-metadata assertions, and keep exactly one
compile-time applied-index interface assertion.
- Adapt the new memory-dispatcher regressions to main's existing
invalid-request sentinel, prefix validation order, nested error wrapping
and empty-slice copy semantics. No production decision/error contract is
changed by this resolution; all dispatcher/service callers were checked.
- Include only mechanical lint fixes for shared-helper result
declarations and import grouping exposed by the main merge. No workload,
timeout, assertion or exclusion was removed.
- Independent read-only conflict/FUSE integration review: no findings.
- Targeted conflict-area race tests: PASS (fstest, kvtest, fsmwire, live
Raft config persistence).
- Full filesystem/KV/Raft/fsmwire/root race command: PASS, exit 0
(`GOMAXPROCS=4 go test -p 2 -race ./internal/filesystem/... ./kv/...
./internal/raftengine/... ./internal/encryption/fsmwire . -count=1
-timeout=20m`). Filesystem 101.625s, fuseadapter 10.540s, KV 72.379s,
etcd 54.961s, root 108.109s. No explicit short/skip filters; kernel-FUSE
checks require Linux CI.
- Affected DynamoDB/S3 helper-binding tests plus the real four-member
snapshot/restart acceptance and snapshot-wait regressions: race PASS,
exit 0 (34.184s).
- Initial unfiltered lint on the main merge found four new reports;
mechanical fixes were applied. Final unfiltered lint, without auto-fix
or a differential filter: PASS, 0 issues (`GOMAXPROCS=4 golangci-lint
run ./... --timeout=10m`, exit 0). A subsequent commit hook also passed
with no remaining edits.
- `git diff --check`: PASS. GitHub reports MERGEABLE. Fresh post-push
review and CI are pending; old-head reviews/CI are historical only.

## Risk and Self-review

1. Data loss: journal effect/OCC ordering, receipt handling, and raw
error classification are unchanged; native snapshot and restored-byte
checks are retained.
2. Concurrency / distributed failures: dispatcher serialization and FUSE
mutation-ticket lifetime are preserved. The snapshot poll uses the
original phase cancellation/deadline and verifies every member. Full
race results and their limits are above.
3. Performance: helpers share existing work rather than add
network/consensus operations or new per-key scans. The polling
allocation is test-only.
4. Data consistency: all prior verdict sentinels and exclusion
precedence, attempt identity checks, mutation copies, timestamp patch
bounds, and all migration-control combinations are explicitly pinned.
5. Test coverage: behavior parity was exercised before and after
refactoring; the wait regression was observed red before the fix.
Unfiltered full lint is distinguished from differential CI. Linux kernel
acceptance and remote CI are not claimed complete yet.

Related: #1330, #1345, #1346. Earlier PR heads do not retroactively gain
this clean baseline; they need to incorporate it and re-run latest-HEAD
review/CI.

Author: bootjp


<!-- 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 -->
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