Testing stream topologies in Kafka - Time & Space Complexity
When testing stream topologies, we want to know how the time to run tests changes as the data size grows.
We ask: How does the test execution time grow when we add more input records?
Analyze the time complexity of the following Kafka Streams test code snippet.
TopologyTestDriver testDriver = new TopologyTestDriver(topology, props);
TestInputTopic<String, String> inputTopic = testDriver.createInputTopic("input", stringSerializer, stringSerializer);
TestOutputTopic<String, String> outputTopic = testDriver.createOutputTopic("output", stringDeserializer, stringDeserializer);
for (int i = 0; i < n; i++) {
inputTopic.pipeInput("key" + i, "value" + i);
}
List<KeyValue<String, String>> results = outputTopic.readKeyValuesToList();
This code feeds n records into the input topic and reads all output records after processing.
Look for repeated actions that take time.
- Primary operation: Loop feeding n input records one by one.
- How many times: Exactly n times, once per input record.
- Secondary operation: Reading all output records after processing, which depends on n.
As you add more input records, the test runs longer because each record is processed.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 10 input operations + reading outputs |
| 100 | About 100 input operations + reading outputs |
| 1000 | About 1000 input operations + reading outputs |
Pattern observation: The time grows roughly in direct proportion to the number of input records.
Time Complexity: O(n)
This means the test time increases linearly as you add more input records.
[X] Wrong: "The test time stays the same no matter how many records I add."
[OK] Correct: Each input record triggers processing, so more records mean more work and longer test time.
Understanding how test time grows helps you write efficient tests and reason about system behavior under load.
"What if we batch input records instead of sending them one by one? How would the time complexity change?"
Practice
TopologyTestDriver in Kafka Streams testing?Solution
Step 1: Understand the role of TopologyTestDriver
It runs the Kafka Streams topology in memory for testing purposes.Step 2: Compare with other options
Options A, B, and C relate to topic creation, deployment, or monitoring, which are not testing functions.Final Answer:
To simulate the stream processing logic without a real Kafka cluster -> Option AQuick Check:
TopologyTestDriver = simulate streams [OK]
- Confusing testing with deployment
- Thinking it manages Kafka topics
- Assuming it monitors Kafka cluster health
TopologyTestDriver instance in Java?Solution
Step 1: Recall the constructor signature
The constructor takes the topology first, then the properties.Step 2: Check each option
new TopologyTestDriver(topology, properties); matches the correct constructor call. Options B and C use non-existent static methods. new TopologyTestDriver(properties, topology); reverses the argument order.Final Answer:
new TopologyTestDriver(topology, properties); -> Option BQuick Check:
Constructor = topology, properties [OK]
- Using static methods instead of constructor
- Swapping argument order
- Calling non-existent start or create methods
TopologyTestDriver:
var driver = new TopologyTestDriver(topology, props);
var inputTopic = driver.createInputTopic("input", Serdes.String().serializer(), Serdes.String().serializer());
var outputTopic = driver.createOutputTopic("output", Serdes.String().deserializer(), Serdes.String().deserializer());
inputTopic.pipeInput("key1", "value1");
var result = outputTopic.readKeyValue();
System.out.println(result.key + ":" + result.value);
What will be printed if the topology simply forwards input to output unchanged?Solution
Step 1: Understand the topology behavior
The topology forwards input key-value pairs unchanged to the output topic.Step 2: Trace the test driver code
Input "key1" and "value1" is piped in; outputTopic reads the same key-value pair.Final Answer:
key1:value1 -> Option AQuick Check:
Forwarded key-value = key1:value1 [OK]
- Mixing key and value order
- Expecting null output without input
- Assuming exceptions without errors
TopologyTestDriver:
var driver = new TopologyTestDriver(topology, props);
var inputTopic = driver.createInputTopic("input", Serdes.String().deserializer(), Serdes.String().serializer());
inputTopic.pipeInput("key", "value");Solution
Step 1: Check serializer/deserializer usage
Input topic requires serializers for key and value, not deserializers.Step 2: Identify the swapped serializers
Code uses deserializer for key and serializer for value, which is incorrect.Final Answer:
Input topic serializers and deserializers are swapped -> Option CQuick Check:
Input topic needs serializers [OK]
- Using deserializers for input topic
- Ignoring proper resource closing
- Confusing constructor argument order
TopologyTestDriver?Solution
Step 1: Prepare test input with null and non-null values
This tests the filter logic by including both cases.Step 2: Verify output topic contents
Assert that only records with non-null values appear in the output topic.Final Answer:
Send records with null and non-null values to input topic, then assert output topic only has non-null values -> Option DQuick Check:
Filter test = input mixed, output filtered [OK]
- Expecting null values to appear in output
- Not reading output topic to verify results
- Assuming exceptions occur on null values
Ready to prove it?
Pass the test and this pattern moves unknown
