0

I wrote a Cucumber testcase with Citrus Framework where I wanted to test an HTTP Call which internally publishes a message to Kafka. I wrote a testcase to validate this behaviour using "Given, When, Then" syntax. The test case calls the HTTP endpoint as expected and validates the reception of Kafka message on first try but when I execute the same testcase multiple times, it always fails and passes only on first try. This is how my testcase is written:

@When("^I make a http call$")
public void when_scenario() {
    runner.when(http()
            .client("myHTTPClient")
            .send()
            .post("/api/endpoint")
            .message()
            .contentType(MediaType.APPLICATION_XML_VALUE)
            .header("X-B3-TraceId", "randomstring")
            .body("some XML payload"));
}

@Then("^a kafka message should be sent$")
public void then_scenario() {
    runner.then(receive()
            .endpoint("myKafkaEndpoint")
            .message()
            .timeout(5000)
            .header("ce_source", "mysourcev1"));
}

This is how the client endpoints are defined

@Bean
public HttpClient myHTTPClient() {
    return CitrusEndpoints
        .http()
            .client()
            .requestUrl("http://localhost:10000")
        .build();
}

@Bean
public KafkaEndpoint myKafkaEndpoint() {
    return CitrusEndpoints
        .kafka()
            .asynchronous()
            .server("localhost:9092")
            .topic("my-topic")
            .offsetReset("earliest")
        .build();
}

This is the error I received even though I can see that the kafka message is being received by the target topic:

org.citrusframework.exceptions.TestCaseFailedException: Action timeout after 5000 milliseconds. Failed to receive message on endpoint: 'my-topic'

What am I missing here?

1 Answer 1

0

Please consider to use fork=true option on the Http client send operation. This is because Http is a synchronous protocol and Citrus will block until a response message has been received.

The fork option makes Citrus continue with the rest of the test immediately and this will setup Kafka consumers immediately. Depending on the Kafka consumer and connection settings there may be racing conditions on when the Kafka consumer starts its subscription and the Kafka message has been sent.

Also when running the same test multiple times please make sure that the same KafkaEndpoint instance is reused in all tests run in the same suite. When the endpoint is reinitialized multiple times it may not receive messages according to the consumer group settings and other consumer options.

Setting the consumer group to a fixed value for the shared Kafka endpoint is also a good thing to do for your usecase.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.