Skip to content

KAFKA-19535: add integration tests for DescribeProducersOptions#brokerId#8

Draft
apalan60 wants to merge 6 commits into
trunkfrom
KAFKA-19535
Draft

KAFKA-19535: add integration tests for DescribeProducersOptions#brokerId#8
apalan60 wants to merge 6 commits into
trunkfrom
KAFKA-19535

Conversation

@apalan60

Copy link
Copy Markdown
Owner

No description provided.

@apalan60

Copy link
Copy Markdown
Owner Author

/review
auto_approve
--pr_reviewer.extra_instructions="
In the possible issues section, emphasize the following:

  • Is the code logic efficient?

"
--pr_reviewer.inline_code_comments=true
-i
--pr_reviewer.require_score_review=true
--pr_reviewer.require_can_be_split_review=true
--pr_reviewer.require_soc2_ticket=true
--pr_reviewer.num_code_suggestions="5"

@qodo-code-review

Copy link
Copy Markdown

Manual-approval option for PR-Agent is disabled. You can enable it via a configuration file

@apalan60

Copy link
Copy Markdown
Owner Author

/gemini review

@apalan60

Copy link
Copy Markdown
Owner Author

/improve
--pr_code_suggestions.extra_instructions="
Emphasize the following:

  • Does the code logic cover relevant edge cases?
  • Is the code logic clear and easy to understand?
  • Is the code logic efficient?

"
--pr_code_suggestions.num_code_suggestions_per_chunk="4"
--pr_code_suggestions.commitable_code_suggestions=true
--pr_code_suggestions.suggestions_score_threshold="0"

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request adds integration tests for the brokerId option in DescribeProducersOptions, which is a valuable addition. The tests cover the main scenarios, including routing to leaders, followers, and invalid brokers. I've identified a couple of areas where the tests can be improved for better type safety and more robust assertions. My feedback includes specific suggestions to address these points.

this.clusterInstance = clusterInstance;
}

private static void sendTestRecords(Producer<Object, Object> producer) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The producer is configured with StringSerializer for both key and value, so its type is Producer<String, String>. Using Producer<Object, Object> in the method signature is not type-safe. It's better to use the specific types to leverage Java's type system and prevent potential runtime errors.

Suggested change
private static void sendTestRecords(Producer<Object, Object> producer) {
private static void sendTestRecords(Producer<String, String> producer) {

Comment on lines +127 to +129
var followerProducerId = followerState.activeProducers().iterator().next().producerId();
var leaderProducerId = leaderState.activeProducers().iterator().next().producerId();
assertEquals(leaderProducerId, followerProducerId);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The current assertion only compares the producer ID of the first active producer. A more robust test would compare the entire list of active producers between the leader and the follower, similar to what is done in testDescribeProducersDefaultRoutesToLeader. This ensures that all producer states are correctly replicated to the follower.

Suggested change
var followerProducerId = followerState.activeProducers().iterator().next().producerId();
var leaderProducerId = leaderState.activeProducers().iterator().next().producerId();
assertEquals(leaderProducerId, followerProducerId);
assertEquals(leaderState.activeProducers(), followerState.activeProducers());

Comment on lines +86 to +84
var stateWithDefaultRouting = admin.describeProducers(List.of(topicPartition))
.partitionResult(topicPartition).get();

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: Await leader election and metadata stabilization before asserting producer state to avoid flakiness. Add a wait/retry until the partition has a known leader and at least one active producer is observed, with a reasonable timeout. [general, importance: 6]

Suggested change
var stateWithDefaultRouting = admin.describeProducers(List.of(topicPartition))
.partitionResult(topicPartition).get();
TestUtils.waitForCondition(() -> {
try {
var state = admin.describeProducers(List.of(topicPartition))
.partitionResult(topicPartition).get();
return state != null && !state.activeProducers().isEmpty();
} catch (Exception e) {
return false;
}
}, 10_000L, "Timed out waiting for active producers on leader");
var stateWithDefaultRouting = admin.describeProducers(List.of(topicPartition))
.partitionResult(topicPartition).get();

Comment on lines +118 to +129
var followerState = admin.describeProducers(List.of(topicPartition),
new DescribeProducersOptions().brokerId(followerBrokerId))
.partitionResult(topicPartition).get();
var leaderState = admin.describeProducers(List.of(topicPartition))
.partitionResult(topicPartition).get();

assertNotNull(followerState);
assertFalse(followerState.activeProducers().isEmpty());

var followerProducerId = followerState.activeProducers().iterator().next().producerId();
var leaderProducerId = leaderState.activeProducers().iterator().next().producerId();
assertEquals(leaderProducerId, followerProducerId);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: Guard against the case where leader has no active producers yet to prevent NoSuchElementException. Add waits ensuring both leader and follower responses have at least one active producer before comparing IDs. [general, importance: 7]

Suggested change
var followerState = admin.describeProducers(List.of(topicPartition),
new DescribeProducersOptions().brokerId(followerBrokerId))
.partitionResult(topicPartition).get();
var leaderState = admin.describeProducers(List.of(topicPartition))
.partitionResult(topicPartition).get();
assertNotNull(followerState);
assertFalse(followerState.activeProducers().isEmpty());
var followerProducerId = followerState.activeProducers().iterator().next().producerId();
var leaderProducerId = leaderState.activeProducers().iterator().next().producerId();
assertEquals(leaderProducerId, followerProducerId);
TestUtils.waitForCondition(() -> {
try {
var ls = admin.describeProducers(List.of(topicPartition)).partitionResult(topicPartition).get();
var fs = admin.describeProducers(List.of(topicPartition), new DescribeProducersOptions().brokerId(followerBrokerId))
.partitionResult(topicPartition).get();
return ls != null && fs != null && !ls.activeProducers().isEmpty() && !fs.activeProducers().isEmpty();
} catch (Exception e) {
return false;
}
}, 10_000L, "Timed out waiting for active producers on leader and follower");
var followerState = admin.describeProducers(List.of(topicPartition),
new DescribeProducersOptions().brokerId(followerBrokerId))
.partitionResult(topicPartition).get();
var leaderState = admin.describeProducers(List.of(topicPartition))
.partitionResult(topicPartition).get();
assertNotNull(followerState);
assertFalse(followerState.activeProducers().isEmpty());
assertFalse(leaderState.activeProducers().isEmpty());
var followerProducerId = followerState.activeProducers().iterator().next().producerId();
var leaderProducerId = leaderState.activeProducers().iterator().next().producerId();
assertEquals(leaderProducerId, followerProducerId);

Comment on lines +113 to +116
var followerBrokerId = replicaBrokerIds.stream()
.filter(id -> !id.equals(leaderBrokerId))
.findFirst()
.orElseThrow(() -> new IllegalStateException("No follower found"));

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: Ensure a true follower is selected when multiple replicas exist by excluding the leader and, if available, preferring an in-sync replica that is not leader. This avoids accidental selection of the leader after a leadership change. [general, importance: 1]

Suggested change
var followerBrokerId = replicaBrokerIds.stream()
.filter(id -> !id.equals(leaderBrokerId))
.findFirst()
.orElseThrow(() -> new IllegalStateException("No follower found"));
var followerBrokerId = replicaBrokerIds.stream()
.filter(id -> !id.equals(leaderBrokerId))
.findFirst()
.orElseThrow(() -> new IllegalStateException("No follower found for partition " + topicPartition));

Comment on lines +155 to +140
TestUtils.assertFutureThrows(NotLeaderOrFollowerException.class,
admin.describeProducers(List.of(topicPartition),
new DescribeProducersOptions().brokerId(nonReplicaBrokerId))
.partitionResult(topicPartition));

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: Wrap the future supplier to retry until metadata reflects the chosen non-replica to avoid transient leader movements causing different exceptions. Add a bounded wait ensuring the broker remains a non-replica before asserting the failure. [general, importance: 6]

Suggested change
TestUtils.assertFutureThrows(NotLeaderOrFollowerException.class,
admin.describeProducers(List.of(topicPartition),
new DescribeProducersOptions().brokerId(nonReplicaBrokerId))
.partitionResult(topicPartition));
// Ensure the selected broker is not a replica before asserting
TestUtils.waitForCondition(() -> {
try {
var desc = admin.describeTopics(List.of(TOPIC_NAME)).allTopicNames().get().get(TOPIC_NAME);
var currentReplicaIds = desc.partitions().get(0).replicas().stream().map(Node::id).toList();
return !currentReplicaIds.contains(nonReplicaBrokerId);
} catch (Exception e) {
return false;
}
}, 10_000L, "Timed out ensuring broker is non-replica");
TestUtils.assertFutureThrows(NotLeaderOrFollowerException.class,
admin.describeProducers(List.of(topicPartition),
new DescribeProducersOptions().brokerId(nonReplicaBrokerId))
.partitionResult(topicPartition));

@apalan60

Copy link
Copy Markdown
Owner Author

/review
--pr_reviewer.extra_instructions="
In the possible issues section, emphasize the following:

  • Is the code logic efficient?

"
--pr_reviewer.inline_code_comments=true
-i
--pr_reviewer.require_score_review=true
--pr_reviewer.require_can_be_split_review=true
--pr_reviewer.require_soc2_ticket=false
--pr_reviewer.num_code_suggestions="5"

@qodo-code-review

qodo-code-review Bot commented Aug 27, 2025

Copy link
Copy Markdown

PR Reviewer Guide 🔍

(Review updated until commit 956c3aa)

Here are some key observations to aid the review process:

⏱️ Estimated effort to review: 2 🔵🔵⚪⚪⚪
🧪 PR contains tests
🔒 No security concerns identified
🔀 No multiple PR themes
⚡ Recommended focus areas for review

Efficiency

The tests repeatedly describe topics and materialize full topic descriptions to derive replica IDs; consider caching the partition description or querying only once per test to reduce admin calls and speed up integration tests.

        var topicDescription = admin.describeTopics(List.of(TOPIC_NAME)).allTopicNames().get().get(TOPIC_NAME);
        var replicaBrokerIds = topicDescription.partitions().get(0).replicas().stream()
                .map(Node::id)
                .toList();

        var leaderBrokerId = clusterInstance.getLeaderBrokerId(topicPartition);
        var followerBrokerId = replicaBrokerIds.stream()
                .filter(id -> id != leaderBrokerId)
                .findFirst()
                .orElseThrow(() -> new IllegalStateException("No follower found for partition " + topicPartition));

        var followerState = admin.describeProducers(List.of(topicPartition), 
                new DescribeProducersOptions().brokerId(followerBrokerId))
                .partitionResult(topicPartition).get();
        var leaderState = admin.describeProducers(List.of(topicPartition))
                .partitionResult(topicPartition).get();

        assertNotNull(followerState);
        assertFalse(followerState.activeProducers().isEmpty());
        assertEquals(leaderState.activeProducers(), followerState.activeProducers());
    }
}

@ClusterTest
void testDescribeProducersWithInvalidBrokerId() throws Exception {
    clusterInstance.createTopic(TOPIC_NAME, NUM_PARTITIONS, REPLICATION_FACTOR);

    try (Producer<byte[], byte[]> producer = clusterInstance.producer();
         var admin = clusterInstance.admin()) {
        sendTestRecords(producer);

        var topicDescription = admin.describeTopics(List.of(TOPIC_NAME)).allTopicNames().get().get(TOPIC_NAME);
        var replicaBrokerIds = topicDescription.partitions().get(0).replicas().stream()
                .map(Node::id)
                .toList();

        var nonReplicaBrokerId = clusterInstance.brokerIds().stream()
                .filter(id -> !replicaBrokerIds.contains(id))
                .findFirst()
                .orElseThrow(() -> new IllegalStateException("No non-replica broker found"));
Flakiness

After sending records, the tests immediately call describeProducers; consider waiting for metadata/leader election or using TestUtils utilities to ensure partition leaders and replication are ready to reduce timing-related flakes.

try (Producer<byte[], byte[]> producer = clusterInstance.producer();
     var admin = clusterInstance.admin()) {
    sendTestRecords(producer);

    var stateWithExplicitLeader = admin.describeProducers(List.of(topicPartition), 
            new DescribeProducersOptions().brokerId(clusterInstance.getLeaderBrokerId(topicPartition)))
            .partitionResult(topicPartition).get();

    var stateWithDefaultRouting = admin.describeProducers(List.of(topicPartition))
            .partitionResult(topicPartition).get();

    assertNotNull(stateWithDefaultRouting);
    assertFalse(stateWithDefaultRouting.activeProducers().isEmpty());
    assertEquals(stateWithExplicitLeader.activeProducers(), stateWithDefaultRouting.activeProducers());
}

@apalan60

Copy link
Copy Markdown
Owner Author

/gemini review

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request adds integration tests for the brokerId option in DescribeProducersOptions. The tests cover scenarios for routing to the leader, a follower, and an invalid broker that is not a replica. The test logic is sound and covers the intended functionality well. I've provided a couple of suggestions to improve the test structure by reducing code duplication, which will enhance maintainability.

Comment on lines +70 to +75
var admin = clusterInstance.admin()) {
sendTestRecords(producer);

var topicPartition = new TopicPartition(TOPIC_NAME, 0);
var leaderBrokerId = clusterInstance.getLeaderBrokerId(topicPartition);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

To reduce code duplication across the test methods, consider creating the topic, producer, and admin client in a @BeforeEach setup method and closing the clients in an @AfterEach teardown method. This would remove the need for clusterInstance.createTopic(...) and the try-with-resources block in each test, making the tests cleaner and more maintainable.

For example:

private Admin admin;
private Producer<Object, Object> producer;

@BeforeEach
void setup() throws Exception {
    admin = clusterInstance.admin();
    producer = clusterInstance.producer(Map.of(
        ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class,
        ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, StringSerializer.class));
    clusterInstance.createTopic(TOPIC_NAME, NUM_PARTITIONS, REPLICATION_FACTOR);
}

@AfterEach
void tearDown() {
    if (producer != null) {
        producer.close();
    }
    if (admin != null) {
        admin.close();
    }
}

Comment on lines +106 to +110
.findFirst()
.orElseThrow(() -> new IllegalStateException("No follower found for partition " + topicPartition));

var followerState = admin.describeProducers(List.of(topicPartition),
new DescribeProducersOptions().brokerId(followerBrokerId))

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This block of code to get replica broker IDs is duplicated in testDescribeProducersWithInvalidBrokerId. To improve maintainability and reduce duplication, consider extracting this logic into a private helper method. Additionally, new TopicPartition(TOPIC_NAME, 0) is used in all tests and could be defined as a static final constant for the class.

For example:

private static final TopicPartition TOPIC_PARTITION_0 = new TopicPartition(TOPIC_NAME, 0);

private List<Integer> getReplicaBrokerIds(Admin admin, TopicPartition topicPartition) throws Exception {
    TopicDescription topicDescription = admin.describeTopics(List.of(topicPartition.topic()))
        .allTopicNames().get().get(topicPartition.topic());
    return topicDescription.partitions().get(topicPartition.partition()).replicas().stream()
        .map(Node::id)
        .toList();
}

Then you could simplify this block to:

var replicaBrokerIds = getReplicaBrokerIds(admin, TOPIC_PARTITION_0);

@apalan60

Copy link
Copy Markdown
Owner Author

/gemini review

@apalan60

Copy link
Copy Markdown
Owner Author

/review
--pr_reviewer.extra_instructions="
In the possible issues section, emphasize the following:

  • Is the code logic efficient?

"
--pr_reviewer.inline_code_comments=true
-i
--pr_reviewer.require_score_review=false
--pr_reviewer.require_can_be_split_review=true
--pr_reviewer.num_code_suggestions="5"

@qodo-code-review

Copy link
Copy Markdown

Persistent review updated to latest commit 956c3aa

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request adds integration tests for DescribeProducersOptions#brokerId. The tests cover the main scenarios: default routing to leader, querying a follower, and querying an invalid broker. The test logic is sound. I've provided a few suggestions to improve code quality by using explicit charsets, removing hardcoded values, and reducing code duplication. These changes will make the new test class more robust and maintainable.


private static void sendTestRecords(Producer<byte[], byte[]> producer) {
for (int partition = 0; partition < NUM_PARTITIONS; partition++) {
producer.send(new ProducerRecord<>(TOPIC_NAME, partition, ("key-" + partition).getBytes(), ("value-" + partition).getBytes()));

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Using String.getBytes() without specifying a charset can lead to platform-dependent behavior, as it uses the system's default charset. It's a best practice to always specify a charset, like StandardCharsets.UTF_8, to ensure consistent behavior across different environments.

Suggested change
producer.send(new ProducerRecord<>(TOPIC_NAME, partition, ("key-" + partition).getBytes(), ("value-" + partition).getBytes()));
producer.send(new ProducerRecord<>(TOPIC_NAME, partition, ("key-" + partition).getBytes(java.nio.charset.StandardCharsets.UTF_8), ("value-" + partition).getBytes(java.nio.charset.StandardCharsets.UTF_8)));

Comment on lines +97 to +101
var topicDescription = admin.describeTopics(List.of(TOPIC_NAME)).allTopicNames().get().get(TOPIC_NAME);
var replicaBrokerIds = topicDescription.partitions().get(0).replicas().stream()
.map(Node::id)
.toList();

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This code block uses hardcoded values for the topic name (TOPIC_NAME) and partition index (0). It's better to use the topicPartition field to make the code more robust and readable.

Additionally, this logic is duplicated in testDescribeProducersWithInvalidBrokerId. Consider extracting it into a private helper method to improve maintainability.

Suggested change
var topicDescription = admin.describeTopics(List.of(TOPIC_NAME)).allTopicNames().get().get(TOPIC_NAME);
var replicaBrokerIds = topicDescription.partitions().get(0).replicas().stream()
.map(Node::id)
.toList();
var topicDescription = admin.describeTopics(List.of(topicPartition.topic())).allTopicNames().get().get(topicPartition.topic());
var replicaBrokerIds = topicDescription.partitions().get(topicPartition.partition()).replicas().stream()
.map(Node::id)
.toList();

Comment on lines +128 to +130
var topicDescription = admin.describeTopics(List.of(TOPIC_NAME)).allTopicNames().get().get(TOPIC_NAME);
var replicaBrokerIds = topicDescription.partitions().get(0).replicas().stream()
.map(Node::id)
.toList();

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This code block uses hardcoded values for the topic name (TOPIC_NAME) and partition index (0). It's better to use the topicPartition field to make the code more robust and readable.

This logic is also duplicated from testDescribeProducersFromFollower. Consider extracting it into a private helper method to improve maintainability.

Suggested change
var topicDescription = admin.describeTopics(List.of(TOPIC_NAME)).allTopicNames().get().get(TOPIC_NAME);
var replicaBrokerIds = topicDescription.partitions().get(0).replicas().stream()
.map(Node::id)
.toList();
var topicDescription = admin.describeTopics(List.of(topicPartition.topic())).allTopicNames().get().get(topicPartition.topic());
var replicaBrokerIds = topicDescription.partitions().get(topicPartition.partition()).replicas().stream()
.map(Node::id)
.toList();

@apalan60

Copy link
Copy Markdown
Owner Author

/describe
--pr_description.publish_labels=true
--pr_description.publish_description_as_comment=true
--pr_description.generate_ai_title=true
--pr_description.final_update_message=true

@qodo-code-review

Copy link
Copy Markdown

Title

Add integration tests for DescribeProducersOptions#brokerId


PR Type

Tests


Description

  • Add integration tests for DescribeProducersOptions#brokerId functionality

  • Test default routing to leader broker behavior

  • Test querying producer state from follower brokers

  • Test error handling for invalid broker IDs


Diagram Walkthrough

flowchart LR
  A["Test Setup"] --> B["Create Topic with Replicas"]
  B --> C["Send Test Records"]
  C --> D["Test Default Routing"]
  C --> E["Test Follower Query"]
  C --> F["Test Invalid Broker ID"]
  D --> G["Verify Leader Response"]
  E --> H["Verify Follower Response"]
  F --> I["Verify Exception Thrown"]
Loading

File Walkthrough

Relevant files
Tests
DescribeProducersWithBrokerIdTest.java
Integration tests for DescribeProducersOptions brokerId parameter

clients/clients-integration-tests/src/test/java/org/apache/kafka/clients/admin/DescribeProducersWithBrokerIdTest.java

  • New test class with 3 test methods for
    DescribeProducersOptions#brokerId
  • Tests default routing behavior to leader broker
  • Tests querying producer state from follower brokers
  • Tests error handling when using invalid broker IDs
+144/-0 

@apalan60

Copy link
Copy Markdown
Owner Author

./gemini review

@gemini-code-assist

Copy link
Copy Markdown

Hi @apalan60, I noticed you've re-triggered the /gemini review command. A review has already been provided and updated in previous comments (see comments #6 and #10).

Do you have any specific questions about the existing review, or have you pushed new changes that you'd like me to review again?

@apalan60

Copy link
Copy Markdown
Owner Author

@gemini-code-assist

Hi @apalan60, I noticed you've re-triggered the /gemini review command. A review has already been provided and updated in previous comments (see comments #6 and apache#10).

Do you have any specific questions about the existing review, or have you pushed new changes that you'd like me to review again?

I made some update, hope to continous reivew

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request adds integration tests for the brokerId option in DescribeProducersOptions. The tests cover routing to the leader by default, explicitly routing to a follower, and handling invalid broker IDs. The test logic is sound and covers the main scenarios. I've provided a couple of suggestions to improve code maintainability by reducing duplication and to make the test setup more efficient.

Comment on lines +64 to +66
for (int partition = 0; partition < NUM_PARTITIONS; partition++) {
producer.send(new ProducerRecord<>(TOPIC_NAME, partition, ("key-" + partition).getBytes(), ("value-" + partition).getBytes()));
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The tests in this class only use partition 0 (as defined by the topicPartition field). This loop sends records to all partitions, which is unnecessary for the test's purpose. To make the test setup more efficient, you can send a single record to partition 0.

        producer.send(new ProducerRecord<>(TOPIC_NAME, 0, "key-0".getBytes(), "value-0".getBytes()));

Comment on lines +129 to +130
var topicDescription = admin.describeTopics(List.of(topicPartition.topic())).allTopicNames().get().get(topicPartition.topic());
var replicaBrokerIds = topicDescription.partitions().get(topicPartition.partition()).replicas().stream()
.map(Node::id)
.toList();

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This block of code to retrieve replica broker IDs is duplicated from testDescribeProducersFromFollower (lines 100-103). To improve maintainability and reduce code duplication, consider extracting this logic into a private helper method.

For example:

private List<Integer> getReplicaBrokerIds(Admin admin) throws Exception {
    var topicDescription = admin.describeTopics(List.of(topicPartition.topic())).allTopicNames().get().get(topicPartition.topic());
    return topicDescription.partitions().get(topicPartition.partition()).replicas().stream()
            .map(Node::id)
            .toList();
}

You can then call this method in both testDescribeProducersFromFollower and testDescribeProducersWithInvalidBrokerId.

private List<Integer> getReplicaBrokerIds(Admin admin, TopicPartition topicPartition) throws Exception {
var topicDescription = admin.describeTopics(List.of(topicPartition.topic())).allTopicNames().get().get(topicPartition.topic());
return topicDescription.partitions().get(topicPartition.partition()).replicas().stream()
private List<Integer> getReplicaBrokerIds(Admin admin) throws Exception {

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

test review

@apalan60 apalan60 left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

test3

producer.flush();
}

@BeforeEach

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

test

@ClusterTestDefaults(
brokers = 3
)
class DescribeProducersWithBrokerIdTest {

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

t

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant