@@ -254,8 +254,8 @@ func TestE2E_EpochTransition(t *testing.T) {
254254 require .Contains (t , epochs , uint32 (146 ))
255255}
256256
257- // TestE2E_Deduplication tests that duplicate events are not stored twice
258- func TestE2E_Deduplication (t * testing.T ) {
257+ // TestE2E_EventOverwrite tests that resent events are overwritten in storage (no dedup)
258+ func TestE2E_EventOverwrite (t * testing.T ) {
259259 mockBob := NewMockBobServer (145 , 22000000 )
260260 defer mockBob .Close ()
261261
@@ -301,7 +301,7 @@ func TestE2E_Deduplication(t *testing.T) {
301301 return exists
302302 }, "first event should be stored" )
303303
304- // Send duplicate
304+ // Resend the same event (bob resends on reconnect — no dedup, overwrites in storage)
305305 err = mockBob .SendTickStreamResult (bob.TickStreamResult {
306306 Epoch : 145 ,
307307 Tick : 22000001 ,
@@ -312,13 +312,13 @@ func TestE2E_Deduplication(t *testing.T) {
312312 require .NoError (t , err )
313313 mockBob .SendCatchUpComplete ()
314314
315- // Give some time for the duplicate to be processed
315+ // Give some time for the resent event to be processed
316316 time .Sleep (100 * time .Millisecond )
317317
318- // Verify only one event is stored
318+ // Verify still one event stored (overwritten with same data)
319319 _ , events , err := storageMgr .GetEventsForTick (22000001 )
320320 require .NoError (t , err )
321- require .Len (t , events , 1 , "Duplicate event should not be stored " )
321+ require .Len (t , events , 1 , "Resent event should overwrite, not duplicate " )
322322}
323323
324324// TestE2E_StatePersistence tests that state (lastTick/lastLogID/currentEpoch) is persisted
@@ -789,7 +789,8 @@ func TestE2E_IndexInTickResetsAcrossTicks(t *testing.T) {
789789 require .True (t , indicesB [2 ], "Expected IndexInTick 2 for tick B" )
790790}
791791
792- // TestE2E_CrashRecoveryIndexInTick tests that IndexInTick is correctly recovered after crash
792+ // TestE2E_CrashRecoveryIndexInTick tests IndexInTick behavior after crash recovery.
793+ // Without dedup, resent events are re-processed with indexes continuing from the recovered count.
793794func TestE2E_CrashRecoveryIndexInTick (t * testing.T ) {
794795 tempDir := t .TempDir ()
795796 tick := uint32 (22000050 )
@@ -839,7 +840,9 @@ func TestE2E_CrashRecoveryIndexInTick(t *testing.T) {
839840 _ = storageMgr .Close ()
840841 }()
841842
842- // Phase 2: Restart, send 2 duplicates + 1 new event, verify new event gets index 2
843+ // Phase 2: Restart, resend 2 events + 1 new event.
844+ // Without dedup, all 3 are processed. Index resumes from recovered count (2).
845+ // Resent events get indexes 2, 3 (overwritten in storage), new event gets index 4.
843846 mockBob2 := NewMockBobServer (145 , 22000000 )
844847 defer mockBob2 .Close ()
845848
@@ -860,7 +863,7 @@ func TestE2E_CrashRecoveryIndexInTick(t *testing.T) {
860863 _ , err = mockBob2 .WaitForSubscription (5 * time .Second )
861864 require .NoError (t , err )
862865
863- // Resend the 2 duplicate events + 1 new event in one tickStream message
866+ // Resend the 2 events + 1 new event in one tickStream message
864867 var logs []bob.LogPayload
865868 for i := uint64 (1 ); i <= 2 ; i ++ {
866869 logs = append (logs , CreateLogPayload (145 , tick , i , 0 , map [string ]any {
@@ -890,16 +893,17 @@ func TestE2E_CrashRecoveryIndexInTick(t *testing.T) {
890893 return len (events ) >= 3
891894 }, "3 events should be stored after recovery" )
892895
893- // Verify the new event has IndexInTick=2
896+ // Verify all 3 events are stored
894897 service := grpc .NewEventsBridgeService (storageMgr2 , zap .NewNop ())
895898 resp , err := service .GetEventsForTick (ctx , & eventsbridge.GetEventsForTickRequest {Tick : tick })
896899 require .NoError (t , err )
897900 require .Len (t , resp .Events , 3 )
898901
899- // Find the event with logID=3 (the new one) and check its index
902+ // Without dedup, resent events continue from recovered index (2).
903+ // New event (logID=3) gets IndexInTick=4.
900904 for _ , event := range resp .Events {
901905 if event .LogId == 3 {
902- require .Equal (t , uint32 (2 ), event .IndexInTick , "New event after crash recovery should have IndexInTick=2 " )
906+ require .Equal (t , uint32 (4 ), event .IndexInTick , "New event after crash recovery should have IndexInTick=4 (resumed from recovered count) " )
903907 }
904908 }
905909}
@@ -1474,9 +1478,9 @@ func TestE2E_KafkaPublishFailure(t *testing.T) {
14741478 assert .Equal (t , uint64 (1 ), msgs [0 ].LogID )
14751479}
14761480
1477- // TestE2E_IndexResetAfterDeduplication tests that IndexInTick resets to 0 for a new tick
1478- // even when all events from the previous tick were deduplicated (pendingBatch is nil ).
1479- func TestE2E_IndexResetAfterDeduplication (t * testing.T ) {
1481+ // TestE2E_IndexResetAfterResend tests that IndexInTick resets to 0 for a new tick
1482+ // even when events from the previous tick were resent (overwritten, no dedup ).
1483+ func TestE2E_IndexResetAfterResend (t * testing.T ) {
14801484 tempDir := t .TempDir ()
14811485 tickOld := uint32 (22000050 ) // Previous tick
14821486 tickNew := uint32 (22000051 ) // New tick
@@ -1534,8 +1538,8 @@ func TestE2E_IndexResetAfterDeduplication(t *testing.T) {
15341538 _ = storageMgr .Close ()
15351539 }()
15361540
1537- // Phase 2: Restart, resend tickOld events (will be deduplicated ), then send tickNew events.
1538- // The tickNew events should start with index 0, not index 3 .
1541+ // Phase 2: Restart, resend tickOld events (now re-processed and published ), then send tickNew events.
1542+ // The tickNew events should start with index 0.
15391543 mockBob2 := NewMockBobServer (145 , 22000000 )
15401544 defer mockBob2 .Close ()
15411545
@@ -1557,7 +1561,7 @@ func TestE2E_IndexResetAfterDeduplication(t *testing.T) {
15571561 _ , err = mockBob2 .WaitForSubscription (5 * time .Second )
15581562 require .NoError (t , err )
15591563
1560- // Resend the 3 events for tickOld (these will be deduplicated - already in storage)
1564+ // Resend the 3 events for tickOld (no dedup — re-processed and overwritten in storage)
15611565 var logsOld []bob.LogPayload
15621566 for i := uint64 (1 ); i <= 3 ; i ++ {
15631567 logsOld = append (logsOld , CreateLogPayloadWithTimestamp (145 , tickOld , i , 0 , map [string ]any {
@@ -1575,7 +1579,7 @@ func TestE2E_IndexResetAfterDeduplication(t *testing.T) {
15751579 })
15761580 require .NoError (t , err )
15771581
1578- // Now send 2 events for tickNew (these should get index 0, 1 - NOT 3, 4 )
1582+ // Now send 2 events for tickNew (these should get index 0, 1)
15791583 var logsNew []bob.LogPayload
15801584 for i := uint64 (4 ); i <= 5 ; i ++ {
15811585 logsNew = append (logsNew , CreateLogPayloadWithTimestamp (145 , tickNew , i , 0 , map [string ]any {
@@ -1600,14 +1604,20 @@ func TestE2E_IndexResetAfterDeduplication(t *testing.T) {
16001604 return len (events ) >= 2
16011605 }, "2 events should be stored for tickNew" )
16021606
1603- // Verify that tickNew events have indexes 0 and 1 in Kafka (NOT 3 and 4)
1607+ // Resent tickOld events (3) + tickNew events (2) = 5 total Kafka messages
16041608 msgs := mockKafka2 .Messages ()
1605- require .Len (t , msgs , 2 , "Only 2 new events should be published to Kafka (tickOld events were deduplicated) " )
1609+ require .Len (t , msgs , 5 , "3 resent + 2 new events should be published to Kafka" )
16061610
1607- // The events should have index 0 and 1 for tickNew
1608- for i , msg := range msgs {
1609- require .Equal (t , uint64 (i ), msg .Index , "tickNew event %d should have index %d, not %d" , i , i , msg .Index )
1610- require .Equal (t , tickNew , msg .TickNumber , "Event should be for tickNew" )
1611+ // tickNew events should have index 0 and 1 (tick boundary resets the index)
1612+ tickNewMsgs := make ([]* kafka.EventMessage , 0 )
1613+ for _ , msg := range msgs {
1614+ if msg .TickNumber == tickNew {
1615+ tickNewMsgs = append (tickNewMsgs , msg )
1616+ }
1617+ }
1618+ require .Len (t , tickNewMsgs , 2 )
1619+ for i , msg := range tickNewMsgs {
1620+ require .Equal (t , uint64 (i ), msg .Index , "tickNew event %d should have index %d" , i , i )
16111621 }
16121622
16131623 // Also verify storage IndexInTick values
@@ -1704,8 +1714,8 @@ func TestE2E_NotificationsBeforeSubscribeResponse(t *testing.T) {
17041714 require .Equal (t , uint64 (2 ), resp2 .Events [0 ].LogId )
17051715}
17061716
1707- // TestE2E_KafkaDeduplication tests that deduplicated events are NOT published to Kafka
1708- func TestE2E_KafkaDeduplication (t * testing.T ) {
1717+ // TestE2E_KafkaResend tests that resent events ARE published to Kafka (no dedup)
1718+ func TestE2E_KafkaResend (t * testing.T ) {
17091719 tempDir := t .TempDir ()
17101720 tick := uint32 (22000001 )
17111721
@@ -1754,7 +1764,7 @@ func TestE2E_KafkaDeduplication(t *testing.T) {
17541764 _ = storageMgr .Close ()
17551765 }()
17561766
1757- // Phase 2: Restart and resend the same event — should be deduplicated
1767+ // Phase 2: Restart and resend the same event — now re-published to Kafka
17581768 mockBob2 := NewMockBobServer (145 , 22000000 )
17591769 defer mockBob2 .Close ()
17601770
@@ -1776,7 +1786,7 @@ func TestE2E_KafkaDeduplication(t *testing.T) {
17761786 _ , err = mockBob2 .WaitForSubscription (5 * time .Second )
17771787 require .NoError (t , err )
17781788
1779- // Resend the same event (bob resends on reconnect)
1789+ // Resend the same event (bob resends on reconnect — no dedup )
17801790 payload := CreateLogPayloadWithTimestamp (145 , tick , 1 , 0 , map [string ]any {
17811791 "from" : "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" ,
17821792 "to" : "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" ,
@@ -1813,8 +1823,9 @@ func TestE2E_KafkaDeduplication(t *testing.T) {
18131823 return exists
18141824 }, "new event should be stored" )
18151825
1816- // Verify only the new event was published to Kafka (duplicate was skipped )
1826+ // Both resent and new events should be published to Kafka (no dedup )
18171827 msgs := mockKafka2 .Messages ()
1818- require .Len (t , msgs , 1 , "Only non-duplicate event should be published to Kafka" )
1819- assert .Equal (t , uint64 (2 ), msgs [0 ].LogID , "Only the new event should be published" )
1828+ require .Len (t , msgs , 2 , "Both resent and new events should be published to Kafka" )
1829+ assert .Equal (t , uint64 (1 ), msgs [0 ].LogID , "Resent event should be published" )
1830+ assert .Equal (t , uint64 (2 ), msgs [1 ].LogID , "New event should be published" )
18201831}
0 commit comments