test: caller-driven replica-lag + idempotency guards (stacked on #4284)#4285
Conversation
|
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
WalkthroughAdds extensive Vitest integration coverage for replica-lag behavior across webapp routes, presenters, realtime services, run-engine operations, and run-store views. Tests simulate missing or stale replica rows, verify primary read fallbacks and primary-only mutation reads, validate tolerated null/empty responses, and cover cross-database global idempotency and waitpoint ownership behavior. 🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
b9faca3 to
69fe2db
Compare
e7b4143 to
1abf430
Compare
There was a problem hiding this comment.
Actionable comments posted: 9
🧹 Nitpick comments (3)
apps/webapp/test/metadataRouteReplicaLag.guard.test.ts (1)
95-124: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winUse the shared
laggingReplicaprimitive.This local proxy duplicates the canonical test harness and can drift from its Prisma routing semantics. Import
laggingReplicafrom@internal/testcontainers, configuretaskRunwithmode: "missing", and update the hit assertion towasHit("taskRun").internal-packages/run-store/src/runOpsStore.bulkActionReadView.replicaLag.test.ts (1)
24-55: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winUse the shared
laggingReplicahelper instead of maintaining five proxy copies.The exported helper already supports the same
taskRunmissing mode used here. Reusing it keeps lag simulation consistent across the suite and matches the PR objective.
internal-packages/run-store/src/runOpsStore.bulkActionReadView.replicaLag.test.ts#L24-L55: importlaggingReplicaand configuretaskRunwithmode: "missing".internal-packages/run-store/src/runOpsStore.cancelRunReadAfterWrite.replicaLag.test.ts#L30-L64: replace the local proxy with the shared helper.internal-packages/run-store/src/runOpsStore.dashboardAgentReadView.replicaLag.test.ts#L34-L66: replace the local proxy with the shared helper.internal-packages/run-store/src/runOpsStore.idempotencyResetReadView.replicaLag.test.ts#L24-L58: replace the local proxy with the shared helper.internal-packages/run-store/src/runOpsStore.modelRuntimeEnvReadView.replicaLag.test.ts#L43-L79: replace the copied proxy with the shared helper.internal-packages/run-store/src/runOpsStore.sessionMetadataRouteReadView.replicaLag.test.ts (1)
39-67: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winUse the shared
laggingReplicatestcontainer primitive.Both local Prisma proxies duplicate and can drift from the shared replica simulation required by this PR.
internal-packages/run-store/src/runOpsStore.sessionMetadataRouteReadView.replicaLag.test.ts#L39-L67: importlaggingReplicafrom@internal/testcontainers, remove the local proxy, and use model-keyedwasHit.internal-packages/run-store/src/runOpsStore.sessionRunProbeReadAfterWrite.test.ts#L26-L54: make the same replacement for both legacy and dedicated replica cases.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: 17b844da-e700-4b47-8cde-0f1d2b331439
📒 Files selected for processing (55)
apps/webapp/test/batchServices.replicaLag.test.tsapps/webapp/test/bulkActionV2.replicaLag.test.tsapps/webapp/test/cancelRouteReplicaLag.guard.test.tsapps/webapp/test/engineReplicaReads.replicaLag.guard.test.tsapps/webapp/test/findEnvironmentFromRunReplicaLag.guard.test.tsapps/webapp/test/idempotencyGlobalScopeCrossDbConcurrent.test.tsapps/webapp/test/idempotencyResetRouteReplicaLag.guard.test.tsapps/webapp/test/metadataRouteReplicaLag.guard.test.tsapps/webapp/test/presentersSessionBatchReplicaLag.guard.test.tsapps/webapp/test/readRunForEvent.replicaLag.test.tsapps/webapp/test/realtimeServices.replicaLag.test.tsapps/webapp/test/realtimeSessionsIoRoute.replicaLag.guard.test.tsapps/webapp/test/realtimeStreamRoutes.replicaLag.test.tsapps/webapp/test/replayRouteReplicaLag.guard.test.tsapps/webapp/test/routesBatchGetReplicaLag.guard.test.tsapps/webapp/test/runGetRoutes.replicaLag.guard.test.tsapps/webapp/test/runPresenters.replicaLag.test.tsapps/webapp/test/runsRepositoryConvert.replicaLag.test.tsapps/webapp/test/sessionWaitpointRoutes.replicaLag.guard.test.tsapps/webapp/test/spanTraceRoutes.replicaLag.test.tsapps/webapp/test/waitpointCallbackRouteReplicaLag.guard.test.tsapps/webapp/test/waitpointCompleteRouteReplicaLag.guard.test.tsapps/webapp/test/waitpointPresenters.replicaLag.guard.test.tsinternal-packages/run-engine/src/engine/retryDecisionReadAfterWrite.replicaLag.test.tsinternal-packages/run-engine/src/engine/systems/ttlSystemExpireReplicaLag.guard.test.tsinternal-packages/run-engine/src/engine/tests/concurrencySweeperCallbackReplicaLag.guard.test.tsinternal-packages/run-engine/src/engine/tests/runAttemptSystemReplicaLag.guard.test.tsinternal-packages/run-store/src/runOpsStore.batchDependentAttemptReadView.replicaLag.test.tsinternal-packages/run-store/src/runOpsStore.batchIdempotencyDedupReadAfterWrite.test.tsinternal-packages/run-store/src/runOpsStore.bulkActionReadView.replicaLag.test.tsinternal-packages/run-store/src/runOpsStore.cancelRunReadAfterWrite.replicaLag.test.tsinternal-packages/run-store/src/runOpsStore.dashboardAgentReadView.replicaLag.test.tsinternal-packages/run-store/src/runOpsStore.engineReadViews.replicaLag.test.tsinternal-packages/run-store/src/runOpsStore.idempotencyGlobalScopeCrossDb.test.tsinternal-packages/run-store/src/runOpsStore.idempotencyResetReadView.replicaLag.test.tsinternal-packages/run-store/src/runOpsStore.modelRuntimeEnvReadView.replicaLag.test.tsinternal-packages/run-store/src/runOpsStore.presentersRunReadView.replicaLag.test.tsinternal-packages/run-store/src/runOpsStore.presentersSessionBatchReadView.replicaLag.test.tsinternal-packages/run-store/src/runOpsStore.presentersWaitpointReadView.replicaLag.test.tsinternal-packages/run-store/src/runOpsStore.realtimeServicesReadView.replicaLag.test.tsinternal-packages/run-store/src/runOpsStore.replayReadAfterWrite.replicaLag.test.tsinternal-packages/run-store/src/runOpsStore.resolveRunForMutationReplicaLag.test.tsinternal-packages/run-store/src/runOpsStore.routesBatchGetReadView.replicaLag.test.tsinternal-packages/run-store/src/runOpsStore.routesRealtimeStreamReadView.replicaLag.test.tsinternal-packages/run-store/src/runOpsStore.routesRunGetReadView.replicaLag.test.tsinternal-packages/run-store/src/runOpsStore.routesSpanTraceReadView.replicaLag.test.tsinternal-packages/run-store/src/runOpsStore.serviceBatchFamilyReadView.replicaLag.test.tsinternal-packages/run-store/src/runOpsStore.sessionMetadataRouteReadView.replicaLag.test.tsinternal-packages/run-store/src/runOpsStore.sessionRunProbeReadAfterWrite.test.tsinternal-packages/run-store/src/runOpsStore.storeReceiverReadView.replicaLag.test.tsinternal-packages/run-store/src/runOpsStore.ttlExpireOrphanReplicaLag.test.tsinternal-packages/run-store/src/runOpsStore.usageCostUndercountReadAfterWrite.test.tsinternal-packages/run-store/src/runOpsStore.waitpointCompleteRouteAndReplayLoaderReadView.replicaLag.test.tsinternal-packages/run-store/src/runOpsStore.waitpointCompleteTokenReadAfterWrite.test.tsinternal-packages/run-store/src/runOpsStore.waitpointDedupReadAfterWrite.test.ts
c0b053f to
eac4192
Compare
|
Follow-up on the shared- Rather than leave it for a later PR, I'm sweeping the remaining replica-lag test files in this PR that still carry a local lag-proxy onto the shared Scope: ~18 remaining files across Exceptions that will stay on a local proxy (with an inline note), because the shared primitive intercepts only configured Prisma model reads and can't express them:
Each migrated file is verified green individually; pushing as an amend to the tests commit shortly. |
eac4192 to
47a6984
Compare
|
Shared- Migrated onto the shared
Each now calls Kept on a local proxy — the shared primitive can't express these (with reason):
No change needed: |
1a6af28 to
7102b75
Compare
|
@coderabbitai full review |
✅ Action performedFull review finished. |
There was a problem hiding this comment.
Actionable comments posted: 5
🧹 Nitpick comments (2)
apps/webapp/test/findEnvironmentFromRunReplicaLag.guard.test.ts (1)
29-30: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winUse static
Prismaimports in both database mock factories.Neither import performs conditional loading or resolves a circular dependency.
apps/webapp/test/findEnvironmentFromRunReplicaLag.guard.test.ts#L29-L30: statically importPrismaand make the mock factory synchronous.apps/webapp/test/routesBatchGetReplicaLag.guard.test.ts#L51-L53: apply the same change to this mock factory.As per coding guidelines, prefer static imports unless dynamic loading is required for a documented exception.
Source: Coding guidelines
apps/webapp/test/waitpointPresenters.replicaLag.guard.test.ts (1)
91-135: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick winUse the shared
laggingReplicafor supported model freezes.This local proxy changes all Prisma read semantics and can let these guard tests diverge from the rest of the replica-lag suite. Use the shared primitive for
waitpoint,taskRun, andwaitpointTag; retain a narrow local wrapper only for the unsupported raw-query case.The PR objective reserves local proxies for unsupported behaviors such as raw queries or select-specific snapshots.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: e0204b38-b5dd-4392-903a-21214f9bbd70
📒 Files selected for processing (56)
apps/webapp/test/batchServices.replicaLag.test.tsapps/webapp/test/bulkActionV2.replicaLag.test.tsapps/webapp/test/cancelRouteReplicaLag.guard.test.tsapps/webapp/test/engineReplicaReads.replicaLag.guard.test.tsapps/webapp/test/findEnvironmentFromRunReplicaLag.guard.test.tsapps/webapp/test/idempotencyGlobalScopeCrossDbConcurrent.test.tsapps/webapp/test/idempotencyResetRouteReplicaLag.guard.test.tsapps/webapp/test/metadataRouteReplicaLag.guard.test.tsapps/webapp/test/presentersSessionBatchReplicaLag.guard.test.tsapps/webapp/test/readRunForEvent.replicaLag.test.tsapps/webapp/test/realtimeServices.replicaLag.test.tsapps/webapp/test/realtimeSessionsIoRoute.replicaLag.guard.test.tsapps/webapp/test/realtimeStreamRoutes.replicaLag.test.tsapps/webapp/test/replayRouteReplicaLag.guard.test.tsapps/webapp/test/routesBatchGetReplicaLag.guard.test.tsapps/webapp/test/runGetRoutes.replicaLag.guard.test.tsapps/webapp/test/runPresenters.replicaLag.test.tsapps/webapp/test/runsRepositoryConvert.replicaLag.test.tsapps/webapp/test/sessionWaitpointRoutes.replicaLag.guard.test.tsapps/webapp/test/spanTraceRoutes.replicaLag.test.tsapps/webapp/test/waitpointCallbackRouteReplicaLag.guard.test.tsapps/webapp/test/waitpointCompleteRouteReplicaLag.guard.test.tsapps/webapp/test/waitpointPresenters.replicaLag.guard.test.tsinternal-packages/run-engine/src/engine/retryDecisionReadAfterWrite.replicaLag.test.tsinternal-packages/run-engine/src/engine/systems/ttlSystemExpireReplicaLag.guard.test.tsinternal-packages/run-engine/src/engine/tests/concurrencySweeperCallbackReplicaLag.guard.test.tsinternal-packages/run-engine/src/engine/tests/runAttemptSystemReplicaLag.guard.test.tsinternal-packages/run-store/src/runOpsStore.batchDependentAttemptReadView.replicaLag.test.tsinternal-packages/run-store/src/runOpsStore.batchIdempotencyDedupReadAfterWrite.test.tsinternal-packages/run-store/src/runOpsStore.bulkActionReadView.replicaLag.test.tsinternal-packages/run-store/src/runOpsStore.cancelRunReadAfterWrite.replicaLag.test.tsinternal-packages/run-store/src/runOpsStore.dashboardAgentReadView.replicaLag.test.tsinternal-packages/run-store/src/runOpsStore.engineReadViews.replicaLag.test.tsinternal-packages/run-store/src/runOpsStore.idempotencyGlobalScopeCrossDb.test.tsinternal-packages/run-store/src/runOpsStore.idempotencyResetReadView.replicaLag.test.tsinternal-packages/run-store/src/runOpsStore.modelRuntimeEnvReadView.replicaLag.test.tsinternal-packages/run-store/src/runOpsStore.presentersRunReadView.replicaLag.test.tsinternal-packages/run-store/src/runOpsStore.presentersSessionBatchReadView.replicaLag.test.tsinternal-packages/run-store/src/runOpsStore.presentersWaitpointReadView.replicaLag.test.tsinternal-packages/run-store/src/runOpsStore.realtimeServicesReadView.replicaLag.test.tsinternal-packages/run-store/src/runOpsStore.replayReadAfterWrite.replicaLag.test.tsinternal-packages/run-store/src/runOpsStore.resolveRunForMutationReplicaLag.test.tsinternal-packages/run-store/src/runOpsStore.routesBatchGetReadView.replicaLag.test.tsinternal-packages/run-store/src/runOpsStore.routesRealtimeStreamReadView.replicaLag.test.tsinternal-packages/run-store/src/runOpsStore.routesRunGetReadView.replicaLag.test.tsinternal-packages/run-store/src/runOpsStore.routesSpanTraceReadView.replicaLag.test.tsinternal-packages/run-store/src/runOpsStore.serviceBatchFamilyReadView.replicaLag.test.tsinternal-packages/run-store/src/runOpsStore.sessionMetadataRouteReadView.replicaLag.test.tsinternal-packages/run-store/src/runOpsStore.sessionRunProbeReadAfterWrite.test.tsinternal-packages/run-store/src/runOpsStore.storeReceiverReadView.replicaLag.test.tsinternal-packages/run-store/src/runOpsStore.test.tsinternal-packages/run-store/src/runOpsStore.ttlExpireOrphanReplicaLag.test.tsinternal-packages/run-store/src/runOpsStore.usageCostUndercountReadAfterWrite.test.tsinternal-packages/run-store/src/runOpsStore.waitpointCompleteRouteAndReplayLoaderReadView.replicaLag.test.tsinternal-packages/run-store/src/runOpsStore.waitpointCompleteTokenReadAfterWrite.test.tsinternal-packages/run-store/src/runOpsStore.waitpointDedupReadAfterWrite.test.ts
…tency guards Guards for the production fixes in the base PR. Each fixed site has a caller-driven test that drives the real exported route/presenter/service/engine caller against a real Postgres with the owning replica frozen (shared laggingReplica primitive), and goes RED when the fix is reverted; tolerated read-view sites carry a caller-driven GREEN proof of self-healing. The global-scope idempotency guard drives the real dedup + claim path through a real MollifierBuffer over a Redis testcontainer, incl. the cross-DB andWait and the expired/failed clear-and-recreate reacquire cases.
7102b75 to
551354a
Compare
|
The suite genuinely guards the regression — caller-driven RED-on-revert across every fix category, and the global-idempotency race is exercised for real over Redis + a two-DB store with a live
|
Stacked on #4284 — tests only
This PR contains only the tests that guard the production fixes in #4284 (its base). Review #4284 first; this branch adds no production code.
What
Caller-driven replica-lag and idempotency guards for every fixed site:
.call(), service, or engine method) against a real Postgres with the owning replica frozen via the sharedlaggingReplicatestcontainer primitive — never a store-seam reimplementation.MollifierBufferover a Redis testcontainer (real SETNX/poll/publish), and covers the cross-DB andWait waitpoint wiring and the expired/failed clear-and-recreate reacquire cases.Run with
vitest --no-file-parallelism(testcontainers). Verified GREEN, and revert→RED verified per fixed site.