Skip to content
Merged
Changes from 13 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@
*/
package org.apache.kafka.clients.consumer;

import static org.junit.jupiter.api.Assertions.assertEquals;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
Expand All @@ -31,32 +31,155 @@
import org.apache.kafka.common.record.TimestampType;
import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;

public class ConsumerRecordsTest {

@Test
public void iterator() throws Exception {
public void testIterator() throws Exception {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Exception is unused.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Oops, I will remove it

String topic = "topic";
int recordSize = 10;
int partitionSize = 15;
int emptyPartitionIndex = 3;
ConsumerRecords<Integer, String> records = buildTopicTestRecords(recordSize, partitionSize, emptyPartitionIndex, Collections.singleton(topic));
Iterator<ConsumerRecord<Integer, String>> iterator = records.iterator();

Map<TopicPartition, List<ConsumerRecord<Integer, String>>> records = new LinkedHashMap<>();
int recordCount = 0;
int partitionCount = 0;
int currentPartition = -1;

String topic = "topic";
records.put(new TopicPartition(topic, 0), new ArrayList<>());
ConsumerRecord<Integer, String> record1 = new ConsumerRecord<>(topic, 1, 0, 0L, TimestampType.CREATE_TIME,
0, 0, 1, "value1", new RecordHeaders(), Optional.empty());
ConsumerRecord<Integer, String> record2 = new ConsumerRecord<>(topic, 1, 1, 0L, TimestampType.CREATE_TIME,
0, 0, 2, "value2", new RecordHeaders(), Optional.empty());
records.put(new TopicPartition(topic, 1), Arrays.asList(record1, record2));
records.put(new TopicPartition(topic, 2), new ArrayList<>());

ConsumerRecords<Integer, String> consumerRecords = new ConsumerRecords<>(records);
Iterator<ConsumerRecord<Integer, String>> iter = consumerRecords.iterator();

int c = 0;
for (; iter.hasNext(); c++) {
ConsumerRecord<Integer, String> record = iter.next();
assertEquals(1, record.partition());
assertEquals(topic, record.topic());
assertEquals(c, record.offset());
while (iterator.hasNext()) {
ConsumerRecord<Integer, String> record = iterator.next();
validateEmptyPartition(record, emptyPartitionIndex);

// Check if we have moved to a new partition
if (currentPartition != record.partition()) {
// Increment the partition count as we have encountered a new partition
partitionCount++;
// Update the current partition to the new partition
currentPartition = record.partition();
}

validateRecordPayload(topic, record, currentPartition, recordCount, recordSize);
recordCount++;
}

// Including empty partition
assertEquals(partitionSize, partitionCount + 1);
}

@Test
public void testRecordsByPartition() {
List<String> topics = Arrays.asList("topic1", "topic2");
int recordSize = 3;
int partitionSize = 5;
int emptyPartitionIndex = 2;

ConsumerRecords<Integer, String> consumerRecords = buildTopicTestRecords(recordSize, partitionSize, emptyPartitionIndex, topics);

for (String topic : topics) {
for (int partition = 0; partition < partitionSize; partition++) {
TopicPartition topicPartition = new TopicPartition(topic, partition);
List<ConsumerRecord<Integer, String>> records = consumerRecords.records(topicPartition);

if (partition == emptyPartitionIndex) {
assertTrue(records.isEmpty());
} else {
assertEquals(recordSize, records.size());
for (int i = 0; i < records.size(); i++) {
ConsumerRecord<Integer, String> record = records.get(i);
validateRecordPayload(topic, record, partition, i, recordSize);
}
}
}
}
assertEquals(2, c);
}

@Test
public void testRecordsByNullTopic() {
String nullTopic = null;
ConsumerRecords<Integer, String> consumerRecords = ConsumerRecords.empty();
IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> consumerRecords.records(nullTopic));
assertEquals("Topic must be non-null.", exception.getMessage());
}


@Test
public void testRecordsByTopic() {
List<String> topics = Arrays.asList("topic1", "topic2", "topic3", "topic4");
int recordSize = 3;
int partitionSize = 10;
int emptyPartitionIndex = 6;
int expectedTotalRecordSizeOfEachTopic = recordSize * (partitionSize - 1);

ConsumerRecords<Integer, String> consumerRecords = buildTopicTestRecords(recordSize, partitionSize, emptyPartitionIndex, topics);

for (String topic : topics) {
Iterable<ConsumerRecord<Integer, String>> records = consumerRecords.records(topic);
Iterator<ConsumerRecord<Integer, String>> iterator = records.iterator();
int recordCount = 0;
int partitionCount = 0;
int currentPartition = -1;

while (iterator.hasNext()) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Maybe we can loop records? for (ConsumerRecord<Integer, String> record : records) {

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Indeed, it will be more easy to read than using iterator.

ConsumerRecord<Integer, String> record = iterator.next();
validateEmptyPartition(record, emptyPartitionIndex);

// Check if we have moved to a new partition
if (currentPartition != record.partition()) {
// Increment the partition count as we have encountered a new partition
partitionCount++;
// Update the current partition to the new partition
currentPartition = record.partition();
}

validateRecordPayload(topic, record, currentPartition, recordCount, recordSize);
recordCount++;
}

// Including empty partition
assertEquals(partitionSize, partitionCount + 1);
assertEquals(expectedTotalRecordSizeOfEachTopic, recordCount);
}
}

private ConsumerRecords<Integer, String> buildTopicTestRecords(int recordSize,
int partitionSize,
int emptyPartitionIndex,
Collection<String> topics) {
Map<TopicPartition, List<ConsumerRecord<Integer, String>>> partitionToRecords = new LinkedHashMap<>();
for (String topic : topics) {
for (int i = 0; i < partitionSize; i++) {
List<ConsumerRecord<Integer, String>> records = new ArrayList<>(recordSize);
if (i != emptyPartitionIndex) {
for (int j = 0; j < recordSize; j++) {
records.add(
new ConsumerRecord<>(topic, i, j, 0L, TimestampType.CREATE_TIME,
0, 0, j, String.valueOf(j), new RecordHeaders(), Optional.empty())
);
}
}
partitionToRecords.put(new TopicPartition(topic, i), records);
}
}

return new ConsumerRecords<>(partitionToRecords);
}

private void validateEmptyPartition(ConsumerRecord<Integer, String> record, int emptyPartitionIndex) {
if (record.partition() == emptyPartitionIndex) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

It can be assertNotEquals(emptyPartitionIndex, record.partition(), "Partition " + record.partition() + " is not empty");, right?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yes, in this way it could be more straightforward

fail("Partition " + emptyPartitionIndex + " is not empty");
}
}

private void validateRecordPayload(String topic, ConsumerRecord<Integer, String> record, int currentPartition, int recordCount, int recordSize) {
assertEquals(topic, record.topic());
assertEquals(currentPartition, record.partition());
assertEquals(recordCount % recordSize, record.offset());
assertEquals(recordCount % recordSize, record.key());
assertEquals(String.valueOf(recordCount % recordSize), record.value());
}
}