use of org.apache.flink.connector.testutils.source.reader.TestingReaderOutput in project flink by splunk.
the class HybridSourceReaderTest method testReader.
@Test
public void testReader() throws Exception {
TestingReaderContext readerContext = new TestingReaderContext();
TestingReaderOutput<Integer> readerOutput = new TestingReaderOutput<>();
MockBaseSource source = new MockBaseSource(1, 1, Boundedness.BOUNDED);
// 2 underlying readers to exercise switch
SourceReader<Integer, MockSourceSplit> mockSplitReader1 = source.createReader(readerContext);
SourceReader<Integer, MockSourceSplit> mockSplitReader2 = source.createReader(readerContext);
HybridSourceReader<Integer> reader = new HybridSourceReader<>(readerContext);
Assert.assertThat(readerContext.getSentEvents(), Matchers.emptyIterable());
reader.start();
assertAndClearSourceReaderFinishedEvent(readerContext, -1);
Assert.assertNull(currentReader(reader));
Assert.assertEquals(InputStatus.NOTHING_AVAILABLE, reader.pollNext(readerOutput));
Source source1 = new MockSource(null, 0) {
@Override
public SourceReader<Integer, MockSourceSplit> createReader(SourceReaderContext readerContext) {
return mockSplitReader1;
}
};
reader.handleSourceEvents(new SwitchSourceEvent(0, source1, false));
MockSourceSplit mockSplit = new MockSourceSplit(0, 0, 1);
mockSplit.addRecord(0);
SwitchedSources switchedSources = new SwitchedSources();
switchedSources.put(0, source);
HybridSourceSplit hybridSplit = HybridSourceSplit.wrapSplit(mockSplit, 0, switchedSources);
reader.addSplits(Collections.singletonList(hybridSplit));
// drain splits
InputStatus status = reader.pollNext(readerOutput);
while (readerOutput.getEmittedRecords().isEmpty() || status == InputStatus.MORE_AVAILABLE) {
status = reader.pollNext(readerOutput);
Thread.sleep(10);
}
Assert.assertThat(readerOutput.getEmittedRecords(), Matchers.contains(0));
reader.pollNext(readerOutput);
Assert.assertEquals("before notifyNoMoreSplits", InputStatus.NOTHING_AVAILABLE, reader.pollNext(readerOutput));
reader.notifyNoMoreSplits();
reader.pollNext(readerOutput);
assertAndClearSourceReaderFinishedEvent(readerContext, 0);
Assert.assertEquals("reader before switch source event", mockSplitReader1, currentReader(reader));
Source source2 = new MockSource(null, 0) {
@Override
public SourceReader<Integer, MockSourceSplit> createReader(SourceReaderContext readerContext) {
return mockSplitReader2;
}
};
reader.handleSourceEvents(new SwitchSourceEvent(1, source2, true));
Assert.assertEquals("reader after switch source event", mockSplitReader2, currentReader(reader));
reader.notifyNoMoreSplits();
Assert.assertEquals("reader 1 after notifyNoMoreSplits", InputStatus.END_OF_INPUT, reader.pollNext(readerOutput));
reader.close();
}
use of org.apache.flink.connector.testutils.source.reader.TestingReaderOutput in project flink by splunk.
the class HybridSourceReaderTest method testReaderRecovery.
@Test
public void testReaderRecovery() throws Exception {
TestingReaderContext readerContext = new TestingReaderContext();
TestingReaderOutput<Integer> readerOutput = new TestingReaderOutput<>();
MockBaseSource source = new MockBaseSource(1, 1, Boundedness.BOUNDED);
HybridSourceReader<Integer> reader = new HybridSourceReader<>(readerContext);
reader.start();
assertAndClearSourceReaderFinishedEvent(readerContext, -1);
reader.handleSourceEvents(new SwitchSourceEvent(0, source, false));
MockSourceSplit mockSplit = new MockSourceSplit(0, 0, 2147483647);
SwitchedSources switchedSources = new SwitchedSources();
switchedSources.put(0, source);
HybridSourceSplit hybridSplit = HybridSourceSplit.wrapSplit(mockSplit, 0, switchedSources);
reader.addSplits(Collections.singletonList(hybridSplit));
List<HybridSourceSplit> snapshot = reader.snapshotState(0);
Assert.assertThat(snapshot, Matchers.contains(hybridSplit));
// reader recovery
readerContext.clearSentEvents();
reader = new HybridSourceReader<>(readerContext);
reader.addSplits(snapshot);
Assert.assertNull(currentReader(reader));
reader.start();
Assert.assertNull(currentReader(reader));
assertAndClearSourceReaderFinishedEvent(readerContext, -1);
reader.handleSourceEvents(new SwitchSourceEvent(0, source, false));
Assert.assertNotNull(currentReader(reader));
Assert.assertThat(reader.snapshotState(1), Matchers.contains(hybridSplit));
reader.close();
}
use of org.apache.flink.connector.testutils.source.reader.TestingReaderOutput in project flink by splunk.
the class KafkaSourceReaderTest method testCommitOffsetsWithoutAliveFetchers.
// -----------------------------------------
@Test
void testCommitOffsetsWithoutAliveFetchers() throws Exception {
final String groupId = "testCommitOffsetsWithoutAliveFetchers";
try (KafkaSourceReader<Integer> reader = (KafkaSourceReader<Integer>) createReader(Boundedness.CONTINUOUS_UNBOUNDED, groupId)) {
KafkaPartitionSplit split = new KafkaPartitionSplit(new TopicPartition(TOPIC, 0), 0, NUM_RECORDS_PER_SPLIT);
reader.addSplits(Collections.singletonList(split));
reader.notifyNoMoreSplits();
ReaderOutput<Integer> output = new TestingReaderOutput<>();
InputStatus status;
do {
status = reader.pollNext(output);
} while (status != InputStatus.NOTHING_AVAILABLE);
pollUntil(reader, output, () -> reader.getNumAliveFetchers() == 0, "The split fetcher did not exit before timeout.");
reader.snapshotState(100L);
reader.notifyCheckpointComplete(100L);
// Due to a bug in KafkaConsumer, when the consumer closes, the offset commit callback
// won't be fired, so the offsetsToCommit map won't be cleaned. To make the test
// stable, we add a split whose starting offset is the log end offset, so the
// split fetcher won't become idle and exit after commitOffsetAsync is invoked from
// notifyCheckpointComplete().
reader.addSplits(Collections.singletonList(new KafkaPartitionSplit(new TopicPartition(TOPIC, 0), NUM_RECORDS_PER_SPLIT)));
pollUntil(reader, output, () -> reader.getOffsetsToCommit().isEmpty(), "The offset commit did not finish before timeout.");
}
// Verify the committed offsets.
try (AdminClient adminClient = KafkaSourceTestEnv.getAdminClient()) {
Map<TopicPartition, OffsetAndMetadata> committedOffsets = adminClient.listConsumerGroupOffsets(groupId).partitionsToOffsetAndMetadata().get();
assertThat(committedOffsets).hasSize(1);
assertThat(committedOffsets.values()).extracting(OffsetAndMetadata::offset).allMatch(offset -> offset == NUM_RECORDS_PER_SPLIT);
}
}
use of org.apache.flink.connector.testutils.source.reader.TestingReaderOutput in project flink-mirror by flink-ci.
the class HybridSourceReaderTest method testReaderRecovery.
@Test
public void testReaderRecovery() throws Exception {
TestingReaderContext readerContext = new TestingReaderContext();
TestingReaderOutput<Integer> readerOutput = new TestingReaderOutput<>();
MockBaseSource source = new MockBaseSource(1, 1, Boundedness.BOUNDED);
HybridSourceReader<Integer> reader = new HybridSourceReader<>(readerContext);
reader.start();
assertAndClearSourceReaderFinishedEvent(readerContext, -1);
reader.handleSourceEvents(new SwitchSourceEvent(0, source, false));
MockSourceSplit mockSplit = new MockSourceSplit(0, 0, 2147483647);
SwitchedSources switchedSources = new SwitchedSources();
switchedSources.put(0, source);
HybridSourceSplit hybridSplit = HybridSourceSplit.wrapSplit(mockSplit, 0, switchedSources);
reader.addSplits(Collections.singletonList(hybridSplit));
List<HybridSourceSplit> snapshot = reader.snapshotState(0);
Assert.assertThat(snapshot, Matchers.contains(hybridSplit));
// reader recovery
readerContext.clearSentEvents();
reader = new HybridSourceReader<>(readerContext);
reader.addSplits(snapshot);
Assert.assertNull(currentReader(reader));
reader.start();
Assert.assertNull(currentReader(reader));
assertAndClearSourceReaderFinishedEvent(readerContext, -1);
reader.handleSourceEvents(new SwitchSourceEvent(0, source, false));
Assert.assertNotNull(currentReader(reader));
Assert.assertThat(reader.snapshotState(1), Matchers.contains(hybridSplit));
reader.close();
}
use of org.apache.flink.connector.testutils.source.reader.TestingReaderOutput in project flink by apache.
the class KafkaSourceReaderTest method testKafkaSourceMetrics.
@Test
void testKafkaSourceMetrics() throws Exception {
final MetricListener metricListener = new MetricListener();
final String groupId = "testKafkaSourceMetrics";
final TopicPartition tp0 = new TopicPartition(TOPIC, 0);
final TopicPartition tp1 = new TopicPartition(TOPIC, 1);
try (KafkaSourceReader<Integer> reader = (KafkaSourceReader<Integer>) createReader(Boundedness.CONTINUOUS_UNBOUNDED, groupId, metricListener.getMetricGroup())) {
KafkaPartitionSplit split0 = new KafkaPartitionSplit(tp0, KafkaPartitionSplit.EARLIEST_OFFSET);
KafkaPartitionSplit split1 = new KafkaPartitionSplit(tp1, KafkaPartitionSplit.EARLIEST_OFFSET);
reader.addSplits(Arrays.asList(split0, split1));
TestingReaderOutput<Integer> output = new TestingReaderOutput<>();
pollUntil(reader, output, () -> output.getEmittedRecords().size() == NUM_RECORDS_PER_SPLIT * 2, String.format("Failed to poll %d records until timeout", NUM_RECORDS_PER_SPLIT * 2));
// Metric "records-consumed-total" of KafkaConsumer should be NUM_RECORDS_PER_SPLIT
assertThat(getKafkaConsumerMetric("records-consumed-total", metricListener)).isEqualTo(NUM_RECORDS_PER_SPLIT * 2);
// Current consuming offset should be NUM_RECORD_PER_SPLIT - 1
assertThat(getCurrentOffsetMetric(tp0, metricListener)).isEqualTo(NUM_RECORDS_PER_SPLIT - 1);
assertThat(getCurrentOffsetMetric(tp1, metricListener)).isEqualTo(NUM_RECORDS_PER_SPLIT - 1);
// No offset is committed till now
assertThat(getCommittedOffsetMetric(tp0, metricListener)).isEqualTo(INITIAL_OFFSET);
assertThat(getCommittedOffsetMetric(tp1, metricListener)).isEqualTo(INITIAL_OFFSET);
// Trigger offset commit
final long checkpointId = 15213L;
reader.snapshotState(checkpointId);
waitUtil(() -> {
try {
reader.notifyCheckpointComplete(checkpointId);
} catch (Exception e) {
throw new RuntimeException("Failed to notify checkpoint complete to reader", e);
}
return reader.getOffsetsToCommit().isEmpty();
}, Duration.ofSeconds(60), Duration.ofSeconds(1), String.format("Offsets are not committed successfully. Dangling offsets: %s", reader.getOffsetsToCommit()));
// Metric "commit-total" of KafkaConsumer should be greater than 0
// It's hard to know the exactly number of commit because of the retry
MatcherAssert.assertThat(getKafkaConsumerMetric("commit-total", metricListener), Matchers.greaterThan(0L));
// Committed offset should be NUM_RECORD_PER_SPLIT
assertThat(getCommittedOffsetMetric(tp0, metricListener)).isEqualTo(NUM_RECORDS_PER_SPLIT);
assertThat(getCommittedOffsetMetric(tp1, metricListener)).isEqualTo(NUM_RECORDS_PER_SPLIT);
// Number of successful commits should be greater than 0
final Optional<Counter> commitsSucceeded = metricListener.getCounter(KAFKA_SOURCE_READER_METRIC_GROUP, COMMITS_SUCCEEDED_METRIC_COUNTER);
assertThat(commitsSucceeded).isPresent();
MatcherAssert.assertThat(commitsSucceeded.get().getCount(), Matchers.greaterThan(0L));
}
}
Aggregations