Camel JUnit-Tests: wrong results with parallel execution
I use camel.version 2.18.1 and spring-boot 1.5.1.RELEASE.
I have some more or less complex Camel routes, where messages from MQ Topics will be consumed, filtered, transformed and finally routed to different MQ Topics.
from("{{sourceEP}}").to("{{archiveEP}}")
.process(new MyProcessor())
.to("{{archiveEP}}").to("{{resultEP}}");
application.properties
sourceEP=jms:topic:SOURCE
archiveEP=jms:topic:ARCHIVE
resultEP=jms:topic:TARGET
For each route there exists more then 40 different scenarios. Therefore I have nearly 50 JUnit-Tests for each route, in total I have nearly 400 JUnit-Tests which I run with the maven-surefire-plugin to achieve parallel test execution.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.19.1</version>
<configuration>
<parallel>classes</parallel>
<threadCount>4</threadCount>
</configuration>
</plugin>
The problem is when the JUnit-Tests run in parallel, this will result in inconsistences in the producer endpoints (EDIT: for testing I use the Mock endpoints from Camel). The parallel tests affected the other tests and the expected number of messages in the target endpoints are incorrect.
Test: application.properties
sourceEP=direct:start
archiveEP=mock:archive
resultEP=mock:result
RouteTest.java
@RunWith(CamelSpringBootRunner.class)
@SpringBootTest(classes = MyApplication.class)
public class RouteTest {
@Autowired
private CamelContext context;
@EndpointInject(uri = "{{archiveEP}}")
protected MockEndpoint archiveEndpoint;
@EndpointInject(uri = "{{resultEP}}")
protected MockEndpoint resultEndpoint;
@Produce(uri = "{{sourceEP}}")
protected ProducerTemplate sourceEndpoint;
@Before
public void setup() {
sourceEndpoint.cleanUp();
archiveEndpoint.reset();
resultEndpoint.reset();
}
@Test
public void test1() throws Exception {
sourceEndpoint.sendBody("some text");
archiveEndpoint.expectedMessageCount(2);
archiveEndpoint.assertIsSatisfied();
resultEndpoint.expectedMessageCount(1);
resultEndpoint.assertIsSatisfied();
resultEndpoint.expectedBodiesReceived("expected output");
}
@Test
public void test2() throws Exception {
sourceEndpoint.sendBody("another text");
archiveEndpoint.expectedMessageCount(2);
archiveEndpoint.assertIsSatisfied();
resultEndpoint.expectedMessageCount(1);
resultEndpoint.assertIsSatisfied();
resultEndpoint.expectedBodiesReceived("another output");
}
...
}
My question, is it possible at all to run the JUnit-Tests of Camel routes in parallel?
I tried to add @DirtiesContext
on the test methods to force Spring Testing to automatically reload the CamelContext after each test method: http://camel.apache.org/testing.html
Which of course is not working at parallel test execution, because the result is still random and the expected number of messages is incorrect.
I ended up to set these tests which will test the Camel routes to @NotThreadSafe
to enforce a single thread execution. Only these JUnit-Tests which will test other functionality than the Camel routing are executed in parallel.
But this is not a satisfied solution concerning the amount of nearly 400 JUnit-Tests.
Isn't there any configuration or setting to test Camel routes in parallel which will work correct?
spring-boot junit apache-camel parallel-testing
add a comment |
I use camel.version 2.18.1 and spring-boot 1.5.1.RELEASE.
I have some more or less complex Camel routes, where messages from MQ Topics will be consumed, filtered, transformed and finally routed to different MQ Topics.
from("{{sourceEP}}").to("{{archiveEP}}")
.process(new MyProcessor())
.to("{{archiveEP}}").to("{{resultEP}}");
application.properties
sourceEP=jms:topic:SOURCE
archiveEP=jms:topic:ARCHIVE
resultEP=jms:topic:TARGET
For each route there exists more then 40 different scenarios. Therefore I have nearly 50 JUnit-Tests for each route, in total I have nearly 400 JUnit-Tests which I run with the maven-surefire-plugin to achieve parallel test execution.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.19.1</version>
<configuration>
<parallel>classes</parallel>
<threadCount>4</threadCount>
</configuration>
</plugin>
The problem is when the JUnit-Tests run in parallel, this will result in inconsistences in the producer endpoints (EDIT: for testing I use the Mock endpoints from Camel). The parallel tests affected the other tests and the expected number of messages in the target endpoints are incorrect.
Test: application.properties
sourceEP=direct:start
archiveEP=mock:archive
resultEP=mock:result
RouteTest.java
@RunWith(CamelSpringBootRunner.class)
@SpringBootTest(classes = MyApplication.class)
public class RouteTest {
@Autowired
private CamelContext context;
@EndpointInject(uri = "{{archiveEP}}")
protected MockEndpoint archiveEndpoint;
@EndpointInject(uri = "{{resultEP}}")
protected MockEndpoint resultEndpoint;
@Produce(uri = "{{sourceEP}}")
protected ProducerTemplate sourceEndpoint;
@Before
public void setup() {
sourceEndpoint.cleanUp();
archiveEndpoint.reset();
resultEndpoint.reset();
}
@Test
public void test1() throws Exception {
sourceEndpoint.sendBody("some text");
archiveEndpoint.expectedMessageCount(2);
archiveEndpoint.assertIsSatisfied();
resultEndpoint.expectedMessageCount(1);
resultEndpoint.assertIsSatisfied();
resultEndpoint.expectedBodiesReceived("expected output");
}
@Test
public void test2() throws Exception {
sourceEndpoint.sendBody("another text");
archiveEndpoint.expectedMessageCount(2);
archiveEndpoint.assertIsSatisfied();
resultEndpoint.expectedMessageCount(1);
resultEndpoint.assertIsSatisfied();
resultEndpoint.expectedBodiesReceived("another output");
}
...
}
My question, is it possible at all to run the JUnit-Tests of Camel routes in parallel?
I tried to add @DirtiesContext
on the test methods to force Spring Testing to automatically reload the CamelContext after each test method: http://camel.apache.org/testing.html
Which of course is not working at parallel test execution, because the result is still random and the expected number of messages is incorrect.
I ended up to set these tests which will test the Camel routes to @NotThreadSafe
to enforce a single thread execution. Only these JUnit-Tests which will test other functionality than the Camel routing are executed in parallel.
But this is not a satisfied solution concerning the amount of nearly 400 JUnit-Tests.
Isn't there any configuration or setting to test Camel routes in parallel which will work correct?
spring-boot junit apache-camel parallel-testing
add a comment |
I use camel.version 2.18.1 and spring-boot 1.5.1.RELEASE.
I have some more or less complex Camel routes, where messages from MQ Topics will be consumed, filtered, transformed and finally routed to different MQ Topics.
from("{{sourceEP}}").to("{{archiveEP}}")
.process(new MyProcessor())
.to("{{archiveEP}}").to("{{resultEP}}");
application.properties
sourceEP=jms:topic:SOURCE
archiveEP=jms:topic:ARCHIVE
resultEP=jms:topic:TARGET
For each route there exists more then 40 different scenarios. Therefore I have nearly 50 JUnit-Tests for each route, in total I have nearly 400 JUnit-Tests which I run with the maven-surefire-plugin to achieve parallel test execution.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.19.1</version>
<configuration>
<parallel>classes</parallel>
<threadCount>4</threadCount>
</configuration>
</plugin>
The problem is when the JUnit-Tests run in parallel, this will result in inconsistences in the producer endpoints (EDIT: for testing I use the Mock endpoints from Camel). The parallel tests affected the other tests and the expected number of messages in the target endpoints are incorrect.
Test: application.properties
sourceEP=direct:start
archiveEP=mock:archive
resultEP=mock:result
RouteTest.java
@RunWith(CamelSpringBootRunner.class)
@SpringBootTest(classes = MyApplication.class)
public class RouteTest {
@Autowired
private CamelContext context;
@EndpointInject(uri = "{{archiveEP}}")
protected MockEndpoint archiveEndpoint;
@EndpointInject(uri = "{{resultEP}}")
protected MockEndpoint resultEndpoint;
@Produce(uri = "{{sourceEP}}")
protected ProducerTemplate sourceEndpoint;
@Before
public void setup() {
sourceEndpoint.cleanUp();
archiveEndpoint.reset();
resultEndpoint.reset();
}
@Test
public void test1() throws Exception {
sourceEndpoint.sendBody("some text");
archiveEndpoint.expectedMessageCount(2);
archiveEndpoint.assertIsSatisfied();
resultEndpoint.expectedMessageCount(1);
resultEndpoint.assertIsSatisfied();
resultEndpoint.expectedBodiesReceived("expected output");
}
@Test
public void test2() throws Exception {
sourceEndpoint.sendBody("another text");
archiveEndpoint.expectedMessageCount(2);
archiveEndpoint.assertIsSatisfied();
resultEndpoint.expectedMessageCount(1);
resultEndpoint.assertIsSatisfied();
resultEndpoint.expectedBodiesReceived("another output");
}
...
}
My question, is it possible at all to run the JUnit-Tests of Camel routes in parallel?
I tried to add @DirtiesContext
on the test methods to force Spring Testing to automatically reload the CamelContext after each test method: http://camel.apache.org/testing.html
Which of course is not working at parallel test execution, because the result is still random and the expected number of messages is incorrect.
I ended up to set these tests which will test the Camel routes to @NotThreadSafe
to enforce a single thread execution. Only these JUnit-Tests which will test other functionality than the Camel routing are executed in parallel.
But this is not a satisfied solution concerning the amount of nearly 400 JUnit-Tests.
Isn't there any configuration or setting to test Camel routes in parallel which will work correct?
spring-boot junit apache-camel parallel-testing
I use camel.version 2.18.1 and spring-boot 1.5.1.RELEASE.
I have some more or less complex Camel routes, where messages from MQ Topics will be consumed, filtered, transformed and finally routed to different MQ Topics.
from("{{sourceEP}}").to("{{archiveEP}}")
.process(new MyProcessor())
.to("{{archiveEP}}").to("{{resultEP}}");
application.properties
sourceEP=jms:topic:SOURCE
archiveEP=jms:topic:ARCHIVE
resultEP=jms:topic:TARGET
For each route there exists more then 40 different scenarios. Therefore I have nearly 50 JUnit-Tests for each route, in total I have nearly 400 JUnit-Tests which I run with the maven-surefire-plugin to achieve parallel test execution.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.19.1</version>
<configuration>
<parallel>classes</parallel>
<threadCount>4</threadCount>
</configuration>
</plugin>
The problem is when the JUnit-Tests run in parallel, this will result in inconsistences in the producer endpoints (EDIT: for testing I use the Mock endpoints from Camel). The parallel tests affected the other tests and the expected number of messages in the target endpoints are incorrect.
Test: application.properties
sourceEP=direct:start
archiveEP=mock:archive
resultEP=mock:result
RouteTest.java
@RunWith(CamelSpringBootRunner.class)
@SpringBootTest(classes = MyApplication.class)
public class RouteTest {
@Autowired
private CamelContext context;
@EndpointInject(uri = "{{archiveEP}}")
protected MockEndpoint archiveEndpoint;
@EndpointInject(uri = "{{resultEP}}")
protected MockEndpoint resultEndpoint;
@Produce(uri = "{{sourceEP}}")
protected ProducerTemplate sourceEndpoint;
@Before
public void setup() {
sourceEndpoint.cleanUp();
archiveEndpoint.reset();
resultEndpoint.reset();
}
@Test
public void test1() throws Exception {
sourceEndpoint.sendBody("some text");
archiveEndpoint.expectedMessageCount(2);
archiveEndpoint.assertIsSatisfied();
resultEndpoint.expectedMessageCount(1);
resultEndpoint.assertIsSatisfied();
resultEndpoint.expectedBodiesReceived("expected output");
}
@Test
public void test2() throws Exception {
sourceEndpoint.sendBody("another text");
archiveEndpoint.expectedMessageCount(2);
archiveEndpoint.assertIsSatisfied();
resultEndpoint.expectedMessageCount(1);
resultEndpoint.assertIsSatisfied();
resultEndpoint.expectedBodiesReceived("another output");
}
...
}
My question, is it possible at all to run the JUnit-Tests of Camel routes in parallel?
I tried to add @DirtiesContext
on the test methods to force Spring Testing to automatically reload the CamelContext after each test method: http://camel.apache.org/testing.html
Which of course is not working at parallel test execution, because the result is still random and the expected number of messages is incorrect.
I ended up to set these tests which will test the Camel routes to @NotThreadSafe
to enforce a single thread execution. Only these JUnit-Tests which will test other functionality than the Camel routing are executed in parallel.
But this is not a satisfied solution concerning the amount of nearly 400 JUnit-Tests.
Isn't there any configuration or setting to test Camel routes in parallel which will work correct?
spring-boot junit apache-camel parallel-testing
spring-boot junit apache-camel parallel-testing
edited Nov 22 '18 at 10:45
Ani
asked Nov 22 '18 at 8:02
AniAni
365
365
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
Your MQ Topics are stateful and therefore "not threadsafe". As soon as multiple tests run in parallel, the number of messages in the topics is not foreseeable.
To solve this problem you have to isolate the stateful part of your tests, i.e. your MQ Topics. You would have to generate unique MQ topic names per test, so that each test has its own MQ topics. If this is the case, the message size is well defined as in a single-thread execution.
Or as an in-topic-isolation alternative, you could use JMS message selectors to isolate the messages in a topic for the different tests. In this case each test must set a message header with a unique value and consumes only messages with this value.
Thanks for your answer. For testing I use the Mock endpoints from Camel which cause incorrect and random results. Maybe I will try to set an individual mock name for each test.
– Ani
Nov 22 '18 at 10:22
1
Oh sorry, didn't notice that. Yes, in that case you have to make sure that each test has its own MockEndpoint instances
– burki
Nov 22 '18 at 10:32
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53426306%2fcamel-junit-tests-wrong-results-with-parallel-execution%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
Your MQ Topics are stateful and therefore "not threadsafe". As soon as multiple tests run in parallel, the number of messages in the topics is not foreseeable.
To solve this problem you have to isolate the stateful part of your tests, i.e. your MQ Topics. You would have to generate unique MQ topic names per test, so that each test has its own MQ topics. If this is the case, the message size is well defined as in a single-thread execution.
Or as an in-topic-isolation alternative, you could use JMS message selectors to isolate the messages in a topic for the different tests. In this case each test must set a message header with a unique value and consumes only messages with this value.
Thanks for your answer. For testing I use the Mock endpoints from Camel which cause incorrect and random results. Maybe I will try to set an individual mock name for each test.
– Ani
Nov 22 '18 at 10:22
1
Oh sorry, didn't notice that. Yes, in that case you have to make sure that each test has its own MockEndpoint instances
– burki
Nov 22 '18 at 10:32
add a comment |
Your MQ Topics are stateful and therefore "not threadsafe". As soon as multiple tests run in parallel, the number of messages in the topics is not foreseeable.
To solve this problem you have to isolate the stateful part of your tests, i.e. your MQ Topics. You would have to generate unique MQ topic names per test, so that each test has its own MQ topics. If this is the case, the message size is well defined as in a single-thread execution.
Or as an in-topic-isolation alternative, you could use JMS message selectors to isolate the messages in a topic for the different tests. In this case each test must set a message header with a unique value and consumes only messages with this value.
Thanks for your answer. For testing I use the Mock endpoints from Camel which cause incorrect and random results. Maybe I will try to set an individual mock name for each test.
– Ani
Nov 22 '18 at 10:22
1
Oh sorry, didn't notice that. Yes, in that case you have to make sure that each test has its own MockEndpoint instances
– burki
Nov 22 '18 at 10:32
add a comment |
Your MQ Topics are stateful and therefore "not threadsafe". As soon as multiple tests run in parallel, the number of messages in the topics is not foreseeable.
To solve this problem you have to isolate the stateful part of your tests, i.e. your MQ Topics. You would have to generate unique MQ topic names per test, so that each test has its own MQ topics. If this is the case, the message size is well defined as in a single-thread execution.
Or as an in-topic-isolation alternative, you could use JMS message selectors to isolate the messages in a topic for the different tests. In this case each test must set a message header with a unique value and consumes only messages with this value.
Your MQ Topics are stateful and therefore "not threadsafe". As soon as multiple tests run in parallel, the number of messages in the topics is not foreseeable.
To solve this problem you have to isolate the stateful part of your tests, i.e. your MQ Topics. You would have to generate unique MQ topic names per test, so that each test has its own MQ topics. If this is the case, the message size is well defined as in a single-thread execution.
Or as an in-topic-isolation alternative, you could use JMS message selectors to isolate the messages in a topic for the different tests. In this case each test must set a message header with a unique value and consumes only messages with this value.
answered Nov 22 '18 at 9:41
burkiburki
1,9351415
1,9351415
Thanks for your answer. For testing I use the Mock endpoints from Camel which cause incorrect and random results. Maybe I will try to set an individual mock name for each test.
– Ani
Nov 22 '18 at 10:22
1
Oh sorry, didn't notice that. Yes, in that case you have to make sure that each test has its own MockEndpoint instances
– burki
Nov 22 '18 at 10:32
add a comment |
Thanks for your answer. For testing I use the Mock endpoints from Camel which cause incorrect and random results. Maybe I will try to set an individual mock name for each test.
– Ani
Nov 22 '18 at 10:22
1
Oh sorry, didn't notice that. Yes, in that case you have to make sure that each test has its own MockEndpoint instances
– burki
Nov 22 '18 at 10:32
Thanks for your answer. For testing I use the Mock endpoints from Camel which cause incorrect and random results. Maybe I will try to set an individual mock name for each test.
– Ani
Nov 22 '18 at 10:22
Thanks for your answer. For testing I use the Mock endpoints from Camel which cause incorrect and random results. Maybe I will try to set an individual mock name for each test.
– Ani
Nov 22 '18 at 10:22
1
1
Oh sorry, didn't notice that. Yes, in that case you have to make sure that each test has its own MockEndpoint instances
– burki
Nov 22 '18 at 10:32
Oh sorry, didn't notice that. Yes, in that case you have to make sure that each test has its own MockEndpoint instances
– burki
Nov 22 '18 at 10:32
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53426306%2fcamel-junit-tests-wrong-results-with-parallel-execution%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown