KAFKA-20772 (1/n): Add DLQ system tests for single-partition share group scenarios#22786
KAFKA-20772 (1/n): Add DLQ system tests for single-partition share group scenarios#22786sjhajharia wants to merge 5 commits into
Conversation
smjn
left a comment
There was a problem hiding this comment.
Please add combined_kraft as well in the matrix
There was a problem hiding this comment.
Pull request overview
This PR adds end-to-end ducktape system test coverage for share group dead-letter queues (DLQ, KIP-1191) in a single-partition scenario, along with the supporting test harness/tooling needed to drive explicit per-record share acknowledgements and to bootstrap clusters with share.version=2.
Changes:
- Extend
VerifiableShareConsumerwith an--ack-patternflag for per-record explicit ack cycling and optionalackTypeCountsreporting inoffsets_acknowledgedevents. - Enhance ducktape’s
verifiable_share_consumer.pyservice to passack_patternthrough and expose per-ack-type counters. - Add
KafkaServicehelpers to configure share group DLQ settings and to bootstrapshare.version, plus new DLQ-focused system tests.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| tools/src/main/java/org/apache/kafka/tools/VerifiableShareConsumer.java | Adds --ack-pattern explicit-ack behavior and optional ack-type breakdown in emitted events. |
| tests/kafkatest/services/verifiable_share_consumer.py | Plumbs ack_pattern into the CLI and aggregates ackTypeCounts into helper counters. |
| tests/kafkatest/services/kafka/kafka.py | Adds share-version bootstrapping and new helpers to configure share group DLQ + delivery-count-limit. |
| tests/kafkatest/tests/client/share_consumer_dlq_test.py | New ducktape system tests validating DLQ topic contents for reject/release/mixed patterns. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| List<AcknowledgeType> ackPattern = parseAckPattern(res.getString("ackPattern")); | ||
| if (!ackPattern.isEmpty()) { | ||
| if (acknowledgementMode == AcknowledgementMode.AUTO) { | ||
| throw new ArgumentParserException( | ||
| "--ack-pattern requires --acknowledgement-mode to be 'sync' or 'async', not 'auto'", parser); | ||
| } | ||
| } |
|
Mostly good, one AI comment seems relevant and could result in flakiness. Please look into it. |
smjn
left a comment
There was a problem hiding this comment.
AI comment regarding unchecked map creation overriding previous values could result in flakiness. Please address
chia7712
left a comment
There was a problem hiding this comment.
@sjhajharia thanks for this patch!
| partitionOffsets.add(record.offset()); | ||
|
|
||
| if (!ackPattern.isEmpty()) { | ||
| AcknowledgeType type = ackPattern.get((int) (record.offset() % ackPattern.size())); |
There was a problem hiding this comment.
What happens if ackPattern contains RENEW?
There was a problem hiding this comment.
Thanks for the review. I have added the support for RENEW as well.
| .metavar("ACKNOWLEDGEMENT-MODE") | ||
| .help("Acknowledgement mode for the share consumers (must be either 'auto', 'sync' or 'async')"); | ||
|
|
||
| parser.addArgument("--ack-pattern") |
There was a problem hiding this comment.
Should we add those new options to KIP-1191? Or is it fine since this is a test class?
There was a problem hiding this comment.
I think given its an internal class which we use only for our system tests and do not expose it to customers, we shall be good to go ahead in this state. Still, I am open to the other way round too if you think necessary.
This adds the first system-test coverage for share group dead-letter
queues (KIP-1191, part of KAFKA-19469), plus the client-side tooling
changes needed to drive it — there was previously no way for any
ducktape test client to explicitly REJECT or RELEASE a share-consumed
record; VerifiableShareConsumer only ever implicitly accepted.
VerifiableShareConsumer.java--ack-patternCLI flag: a comma-separated cycle ofaccept|release|reject|renew, applied per record via(offset % pattern.length)— keyed off the immutable record offset so theassignment is stable across redeliveries.
share.acknowledgement.mode=explicitand requires--acknowledgement-mode sync|async(rejects auto at arg-parse time,since explicit per-record acks still need a commit to ship).
offsets_acknowledgedevents now optionally include anackTypeCountsbreakdown({"ACCEPT": n, "RELEASE": n, ...}), omittedentirely when
--ack-patternisn't used — no change to the existingJSON schema for any current caller.
verifiable_share_consumer.py(ducktape service)ack_patternthrough to the CLI, and addstotal_accepted()/total_released()/total_rejected()/total_renewed()accessors backed by the new
ackTypeCountsdata.kafka.pyset_share_group_dlq_config(group, topic_name, copy_record_enable)—sets the GroupConfig DLQ configs via kafka-configs.sh.
set_share_group_delivery_count_limit(group, limit)— setsshare.delivery.count.limit(the per-group override).--feature share.version=<n>. Since DLQ (share.version=2) is aboveShareVersion.LATEST_PRODUCTION, this also flips onunstable.feature.versions.enablein the broker properties.New:
tests/kafkatest/tests/client/share_consumer_dlq_test.pyThree tests on a real 3-broker isolated-KRaft cluster, verifying actual
DLQ topic content (not just consumer-side counters):
test_single_partition_dlq_reject— every record REJECTed, DLQ'dexactly once, values null (copy-record disabled, the default).
test_single_partition_dlq_release— every record RELEASEdrepeatedly; once delivery count exceeds a lowered
share.delivery.count.limit, it lands in the DLQ.
test_single_partition_dlq_mixed— records cycledreject/release/accept by offset % 3, copy-record enabled; asserts the
DLQ'd record set and values exactly match the subset of produced values
that should have been rejected/released (cross-checked against
VerifiableProducer.acked_values, not just "value is non-null").
All three verified passing end-to-end against a live ducker cluster
(tests/docker/run_tests.sh).
Reviewers: Sushant Mahajan smahajan@confluent.io, Chia-Ping Tsai
chia7712@gmail.com