feat(server): Add integration test for message deduplicatpr#2879
feat(server): Add integration test for message deduplicatpr#2879tomighita wants to merge 3 commits intoapache:masterfrom
Conversation
| if batch.count() == 0 { | ||
| return Ok(()); | ||
| } | ||
|
|
There was a problem hiding this comment.
[note] This was causing a bug when all the messages were with duplicate IDs because the batch was empty and we unwraped on first
| let message_deduplicator = create_message_deduplicator(&self.config.system).map(Arc::new); | ||
|
|
||
| let partition = LocalPartition::with_log( | ||
| loaded_log, | ||
| stats, | ||
| std::sync::Arc::new(std::sync::atomic::AtomicU64::new(current_offset)), | ||
| consumer_offsets, | ||
| consumer_group_offsets, | ||
| None, | ||
| message_deduplicator, |
There was a problem hiding this comment.
[note] I've added this here since the message_deduplicator was always None
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #2879 +/- ##
============================================
+ Coverage 68.33% 68.42% +0.09%
Complexity 739 739
============================================
Files 1052 1052
Lines 84745 84749 +4
Branches 61281 61293 +12
============================================
+ Hits 57910 57992 +82
+ Misses 24463 24376 -87
- Partials 2372 2381 +9
Flags with carried forward coverage won't be shown. Click here to find out more.
🚀 New features to boost your workflow:
|
atharvalade
left a comment
There was a problem hiding this comment.
I found no critical issues in this PR
There was a problem hiding this comment.
you never test id 0 (auto-generated ids). the server replaces 0 with a uuid before the dedup check (messages_batch_mut.rs:164-166), so sending multiple messages with id 0 should all pass through. without this, you could silently break the default send path and never know. after that, please also poll the messages to check whether they have unique message id.
| if batch.count() == 0 { | ||
| return Ok(()); | ||
| } |
There was a problem hiding this comment.
i get that it's a fix, but you didn't test it. nothing in this test actually exercises it. you'd need a step that sends a batch where every message is a duplicate (e.g. resend ids 1-10 a third time without any new ids mixed in) and verify the server doesn't blow up and the message count stays the same.
There was a problem hiding this comment.
Isn’t this exactly what the step does where all ids are overlapping?
| let polled = poll_all(&client, MESSAGES_PER_BATCH * 4).await; | ||
| assert_eq!( | ||
| polled.messages.len() as u32, | ||
| total_after_step3, | ||
| "Only new IDs from the mixed batch should have been accepted" | ||
| ); |
There was a problem hiding this comment.
steps 3 and 4 only check message counts but never verify payloads. step 1 does this correctly (checks for "original" prefix), but step 3 doesn't verify the 5 surviving messages are actually the new ones (ids 21-25 with "mixed" payload) andnot some other combination. same for step 4 -- should check "after-ttl" payloads. count-only assertions can pass even if the wrong messages are kept.
| let polled = poll_all(&client, MESSAGES_PER_BATCH * 2).await; | ||
| assert_eq!( | ||
| polled.messages.len() as u32, | ||
| MESSAGES_PER_BATCH, | ||
| "Duplicate messages should have been dropped" | ||
| ); |
There was a problem hiding this comment.
after dedup removes messages mid-batch, offsets and indexes get rebuilt via remove_messages(). you never verify that the polled messages actually have correct, contiguous offsets. a bug in the offset recalculation would be a silent data corruption issue and this test wouldn't catch it.
| let overlap_id_start = 16; | ||
| let total_after_step3 = MESSAGES_PER_BATCH + overlap_id_start - 1; | ||
| // Ensure the `overlap_id_start` is between two batches. | ||
| assert!(overlap_id_start > MESSAGES_PER_BATCH && overlap_id_start < 2 * MESSAGES_PER_BATCH); |
There was a problem hiding this comment.
overlap_id_start = 16 is a magic number and the formula total_after_step3 = MESSAGES_PER_BATCH + overlap_id_start - 1 only works because ids happen to be contiguous from 1. consider deriving it from the actual unique id range, e.g. let new_ids_in_mixed = (overlap_id_start + MESSAGES_PER_BATCH) - (2 * MESSAGES_PER_BATCH + 1) or just computing the set difference explicitly. also build_messages uses 0-based i in the payload instead of the actual message id, which makes correlating payloads to ids harder than it needs to be.
Which issue does this PR close?
Closes #2872
Rationale
As stated in the issue description, the message deduplicator was lacking integration tests. This change adds one based on existing test harness.
What changed?
The message deduplicator is only tested through unit tests, which means it lacks end to end verification. This PR adds one integration test, covering common scenarios like:
This change also fixed two minor bugs where sending a batch with all ids duplicated panicked and one where the deduplicator was not instantiated and
Nonewas always set.Local Execution
AI Usage