Add replay idempotency tests for duplicate and out-of-order contract events - #1392
Merged
Conversation
…order contract events Adds 30 unit tests covering the cross-path invariant that re-ingesting the same event is a no-op, out-of-order events are accepted and stored, and no duplicate business event is emitted. Test coverage areas: - Duplicate delivery: single event, batch, repeated delivery, corrected event - Out-of-order events: reverse ledger, interleaved contracts, same-ledger - Mixed batches: duplicates + new events in a single insertMany call - Gap and retry: partial batch re-delivery, out-of-order retry - Cursor advancement: pagination stability after duplicate ingestion - Postgres store dedup: mock-based contract verification for ON CONFLICT - No duplicate business events: eventId identity key, first-writer-wins - Concurrent delivery: overlapping parallel inserts, rapid re-delivery Closes Fluxora-Org#1257
|
@Fury03 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! 🚀 |
1 task
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.
Linked Issue
Closes #1257
Problem Statement (The Bug)
The backend has replay integrity, event-id, ingested-at, and stale-cursor tests, but lacked cross-path tests verifying the idempotency invariant for duplicate and out-of-order contract event delivery. Without these tests, there is no regression guard against:
This is not something that can be fixed with a local patch because the invariant spans multiple layers (store, ingestion service, metrics, cursor). Only dedicated regression tests can lock it down.
Solution Comparison and Decision (Why tests, not code changes)
InMemoryContractEventStore(Map-based eventId key) andPostgresContractEventStore(ON CONFLICT DO NOTHING viacontract_event_dedup). The code works; it needs test coverage.streamEventService.dedup.test.tswith property-based testing. The issue asks for store-level cross-path tests.insertManythrough database state, cursor advancement, and metrics reporting.The Change (Code modifications)
A single new test file
tests/indexer-store.replay-idempotency.test.tswith 30 unit tests across 8 describe blocks:Compatibility Note (On INTERFACE_VERSION)
INTERFACE_VERSION is not modified. This PR adds only test files -- no production code changes, no API contract changes, no schema migrations. There is no risk to breaking live critical paths because no production code is touched.
Incidental Fixes
None. The scope is strictly limited to the new test file. No existing tests were modified or weakened.
Testing (Proving it works)
New test cases:
tests/indexer-store.replay-idempotency.test.ts-- 30 tests, all passingVerification command from the issue:
Results:
tests/streamEventService.eventId.test.ts-- 4 tests, all passingtests/indexer-store.ledger-hash.test.ts-- 10 tests, all passingtests/indexer-store.ingested-at.test.ts-- 1 pre-existing failure (unrelated to this change;InMemoryContractEventStore.getEvents()silently backfills missingingestedAtwith current time instead of throwingRowMappingError)Additional Notes
ingested-at.test.tsline 200 --store.getEvents()resolves instead of rejecting wheningestedAtis deleted from a record. This is becauseInMemoryContractEventStore.getEvents()usesr.ingestedAt ?? new Date().toISOString()fallback. This is a known issue tracked separately and is NOT introduced by this PR.tests/indexer-store.replay-idempotency.test.tsis added. No production modules, configuration files, or existing tests are touched.