Skip to content

Commit b4e5e0f

Browse files
author
Andy Chambers
committed
Add test-machine intro post
1 parent 3c4ac30 commit b4e5e0f

File tree

3 files changed

+183
-10
lines changed

3 files changed

+183
-10
lines changed

_posts/2014-3-3-Hello-World.md

Lines changed: 0 additions & 10 deletions
This file was deleted.
Lines changed: 183 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
1+
---
2+
layout: post
3+
title: A Test Environment for Kafka Applications
4+
---
5+
6+
In [Testing Event Driven Systems](https://www.confluent.io/blog/testing-event-driven-systems),
7+
I introduced the test-machine and included a simple example for
8+
demonstration purposes. I made the claim that however your system is
9+
implemented, as long as its input and output can be represented in
10+
Kafka, the test-machine would be an effective tool for testing it. Now
11+
we’ve had some time to put that claim to the...ahem test, I thought
12+
it might be interesting to explore some actual use-cases in a bit more
13+
detail.
14+
15+
Having spent a year or so of using the test-machine, I can now say
16+
with increased confidence that it is an effective tool for
17+
testing a variety of Kafka based systems. However with the benefit of
18+
experience, I'd add that you might want to define your own domain
19+
specific layer of helper functions on top so that your tests may bear
20+
some resemblance to the discussion that happens in your sprint
21+
planning meetings. The raw events represent a layer beneath what we
22+
typically discuss with product owners.
23+
24+
Hopefully the use-cases described in this forthcoming mini-series
25+
will help clarify this concept and get you thinking about
26+
how you might be able to apply the test-machine to solve your own
27+
testing problems.
28+
29+
Before getting into the actual use-cases though, let’s get a test environment
30+
setup so we can quickly run experiments locally without having to deploy
31+
our code to a shared testing environment.
32+
33+
## Service Composition
34+
35+
For each of these tests, we’ll be using docker-compose to setup the
36+
test environment. There are other ways of providing a test-environment
37+
but the nice thing about docker-compose is that when things go awry
38+
you can blow away all test state and start again with a clean
39+
environment. This makes the process of acquiring a test-environment
40+
*repeatable*, and at least after the first time you do it, pretty
41+
fast. On my machine, `docker-compose down && docker-compose up -d`
42+
doesn’t usually take more than 5-10 seconds or so. If you have not
43+
used the confluent images before, it might take a while to download
44+
the images if you're not on the end of a fat internet pipe.
45+
46+
Ideally you should be able to run your tests against a
47+
test-environment with existing data. Your tests should create all the
48+
data they need themselves and ignore any data that has been already
49+
entered so acquiring a fresh test environment is not something you
50+
should be doing for each test-run. Sometimes while developing a test,
51+
it can help avoid confusing behavior to have a completely clean environment
52+
but I wouldn't consider the test to be complete until it can be run
53+
against a test environment with old data.
54+
55+
Below is a base docker-compose file containing the core services from
56+
Confluent that will be required to run these tests. Depending on what’s being
57+
tested, we will need additional services to fully exercise the system
58+
under test. The configuration choices are made with a view to minimizing
59+
the memory required by the collection of services. This is tailored
60+
for the use-case of running small tests on a local laptop that
61+
typically has zoom, firefox and chrome all clamoring for their share
62+
of RAM. It is not intended for production workloads.
63+
64+
{% highlight yaml %}
65+
version: '3'
66+
services:
67+
zookeeper:
68+
image: confluentinc/cp-zookeeper:5.1.0
69+
expose:
70+
- "2181"
71+
ports:
72+
- "2181:2181"
73+
environment:
74+
KAFKA_OPTS: '-Xms256m -Xmx256m'
75+
ZOOKEEPER_CLIENT_PORT: 2181
76+
ZOOKEEPER_TICK_TIME: 2000
77+
78+
broker:
79+
image: confluentinc/cp-kafka:5.1.0
80+
depends_on:
81+
- zookeeper
82+
expose:
83+
- "9092"
84+
ports:
85+
- "9092:9092"
86+
- "19092:19092"
87+
environment:
88+
KAFKA_BROKER_ID: 1
89+
KAFKA_ZOOKEEPER_CONNECT: 'zookeeper:2181'
90+
KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: PLAINTEXT:PLAINTEXT,PLAINTEXT_HOST:PLAINTEXT
91+
KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://broker:9092,PLAINTEXT_HOST://localhost:19092
92+
KAFKA_ADVERTISED_HOST_NAME: localhost
93+
KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1
94+
KAFKA_GROUP_INITIAL_REBALANCE_DELAY_MS: 0
95+
KAFKA_TRANSACTION_STATE_LOG_REPLICATION_FACTOR: 1
96+
KAFKA_AUTO_CREATE_TOPICS_ENABLE: "false"
97+
KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1
98+
KAFKA_OFFSETS_TOPIC_NUM_PARTITIONS: 1
99+
KAFKA_OPTS: '-Xms256m -Xmx256m'
100+
KAFKA_TRANSACTION_STATE_LOG_REPLICATION_FACTOR: 1
101+
KAFKA_TRANSACTION_STATE_LOG_MIN_ISR: 1
102+
KAFKA_AUTO_OFFSET_RESET: "latest"
103+
KAFKA_ENABLE_AUTO_COMMIT: "false"
104+
105+
schema-registry:
106+
image: confluentinc/cp-schema-registry:5.1.0
107+
depends_on:
108+
- zookeeper
109+
- broker
110+
expose:
111+
- "8081"
112+
ports:
113+
- "8081:8081"
114+
environment:
115+
KAFKA_OPTS: '-Xms256m -Xmx256m'
116+
SCHEMA_REGISTRY_HOST_NAME: schema-registry
117+
SCHEMA_REGISTRY_KAFKASTORE_CONNECTION_URL: 'zookeeper:2181'
118+
{% endhighlight %}
119+
120+
## Test Environment Healthchecks
121+
122+
It’s always a good idea to make sure the composition of services is
123+
behaving as expected before trying to write tests against
124+
them. Otherwise you might spend hours scratching your head wondering
125+
why your system isn’t working when the problem is actually
126+
mis-configuration of the test environment.
127+
128+
The most basic health-check you can do is to run `docker-compose ps`. This
129+
will show at least that the services came up without exiting
130+
immediately due to mis-configuration. In the happy case, the state of
131+
all services should be “Up”. This command also shows which ports are
132+
exposed by each service which will be important information when it comes
133+
to configuring the system under test.
134+
135+
![docker-compose ps]({{ site.baseurl }}/images/docker-compose-ps.png)
136+
137+
### Accessing the logs
138+
139+
When something goes wrong there is often a clue in the logs although it
140+
will take a bit of experience with them before you'll know what to look
141+
for. Familiarizing yourself with them will payoff eventually though
142+
both in “dev mode” when you’re trying to figure out why the code you’re
143+
writing doesn’t work, and also in “ops mode” when you’re trying to
144+
figure out what’s gone wrong in a deployed system. Getting access to
145+
them in the test environment described here is the same as any other
146+
docker-compose based system. The snippets below demonstrate a few of
147+
the common use-cases and the full documentation is available
148+
at [docs.docker.com](https://docs.docker.com/compose/reference/logs/)
149+
150+
{% highlight sh%}
151+
152+
# get all the logs
153+
$ docker-compose logs
154+
155+
# get just the broker logs
156+
$ docker-compose logs broker
157+
158+
# get the schema-registry logs and print more as they appear
159+
$ docker-compose logs -f schema-registry
160+
161+
{% endhighlight%}
162+
163+
### Testing Connectivity
164+
165+
Another diagnostic tool that helps when debugging connectivity
166+
issues is telnet. Experienced engineers will probably know this already
167+
but for example, to ensure that you can reach kafka from your system under
168+
test (assuming the system you're testing runs on the host OS), you can try
169+
to reach the port exposed by the docker-compose configuration.
170+
171+
{% highlight sh%}
172+
173+
telnet localhost 19092
174+
175+
{% endhighlight %}
176+
177+
If the problem is more gnarly than basic connectivity issues, then Julia Evans'
178+
[debugging zine](https://jvns.ca/debugging-zine.pdf) contains very useful advice
179+
about debugging *any* problem you have with Linux based systems.
180+
181+
That's all for now. In the next article, I'll use this test environment
182+
together with the [test-machine](https://github.com/FundingCircle/jackdaw/blob/master/doc/test-machine.md)
183+
library to build a helper function for testing Kafka Connect JDBC Sinks.

images/docker-compose-ps.png

61.3 KB
Loading

0 commit comments

Comments
 (0)