Repository navigation
test(backend): add comprehensive integration and stress test suite for Idempotency Key Manager - #1608
Open
Abidoyesimze wants to merge 2 commits into
Conversation
…r Idempotency Key Manager
Replaces the check-then-set idempotency flow (GET followed by a
fire-and-forget SET) with a distributed lock built on an atomic
SET NX PX acquisition keyed per merchant+key:
- Concurrent duplicates now receive 409 while the original request is
still in flight instead of both executing (the previous race let every
duplicate through).
- Completion is written with two Lua compare-and-swap scripts so a
worker that lost its lock (TTL expiry or crash) can never clobber the
state of the request that re-acquired the key; orphaned completions
are counted and logged instead.
- Non-2xx responses release the lock immediately so clients can retry,
and connections that close before a response release it too.
- Replays now return the original status code (legacy 201 fallback) and
set Idempotency-Replayed; legacy {"hash","response"} records are still
honoured so the change is backwards compatible.
- Redis failures still fail open but are now logged and counted.
Adds Prometheus instrumentation (idempotency_requests_total,
idempotency_lock_duration_seconds, idempotency_orphaned_completions_total)
and unit coverage for the race, lock TTL self-healing, payload mismatch,
legacy replay, fail-open and lock cleanup paths.
…r Idempotency Key Manager Adds integration/bench-style tests for the distributed idempotency lock under contention: multi-way duplication across many keys, 100-parallel hammering of the same key, multi-instance sharing of a single Redis store, time-budget checks, racey payload mismatch against an in-flight request, lock self-healing after simulated crash (TTL expiry), TTL persistence of completed records, and a skippable real-Redis Lua CAS smoke test. Also adds a reusable in-memory FakeRedis double that mirrors the script semantics for isolated/fast runs.
|
@Abidoyesimze is attempting to deploy a commit to the Emmanuel's projects Team on Vercel. A member of the Team first needs to authorize it. |
|
@Abidoyesimze Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits. You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀 |
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Closes #1466
Adds the integration and stress suite for the Idempotency Key Manager, which had none: the middleware's correctness properties (exactly-once execution, replay identity, conflict semantics, lock expiry, TTL behaviour) were previously only argued about, never executed.
New shared test double
src/lib/__testing__/fake-redis.js— an in-memory Redis with the exact command surface the middleware uses (SETwithNX/PX,GET,DEL,EVALSHA/Lua script semantics, TTL expiry with an injectable clock), so tests are deterministic and run without a Redis container. The existing unit tests were refactored to import this same double instead of defining their own.New suite
src/lib/idempotency.integration.test.js:Idempotency-Replayedheader, handler not re-executed. Mutated body → mismatch rejection. Missing/changed key material → not treated as a replay.REDIS_URLis set; skipped by default (describe.skipIf) so CI without Redis stays green.Test plan
(the 1 skip is the real-Redis suite, gated on
REDIS_URL)Full backend suite: no new failures vs.
origin/main(identical pre-existing failure count).Security notes
src/lib/__testing__/and is only imported by tests; nothing in the runtime import graph pulls it in.REDIS_URLfrom the environment like the application does.