Camel JUnit-Tests: неверные результаты при параллельном выполнении

Я использую camel.version 2.18.1 и spring-boot 1.5.1.RELEASE.
У меня есть несколько более или менее сложных маршрутов Camel, где сообщения из тем MQ будут потребляться, фильтроваться, преобразовываться и, наконец, маршрутизироваться в разные темы MQ.

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

Для каждого маршрута существует более 40 различных сценариев. Поэтому у меня есть около 50 JUnit-тестов для каждого маршрута, в общей сложности у меня есть около 400 JUnit-тестов, которые я запускаю с подключаемым модулем maven-surefire для достижения параллельного выполнения тестов.

<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>

Проблема в том, что когда JUnit-тесты выполняются параллельно, это приведет к несогласованности в конечных точках производителя (EDIT: для тестирования я использую конечные точки Mock от Camel). Параллельные тесты повлияли на другие тесты, и ожидаемое количество сообщений в целевых конечных точках неверно.

Тест: 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");
    }

    ...
} 

Мой вопрос, возможно ли вообще запускать маршруты JUnit-Tests of Camel параллельно?

Я пытался добавить @DirtiesContext о методах тестирования, чтобы заставить Spring Testing автоматически перезагружать CamelContext после каждого метода тестирования: http://camel.apache.org/testing.html
Что, конечно, не работает при параллельном выполнении теста, потому что результат все еще случайный и ожидаемое количество сообщений неверно.

Я закончил, чтобы установить эти тесты, которые будут проверять маршруты Camel в @NotThreadSafe для обеспечения выполнения одного потока. Только эти JUnit-тесты, которые будут тестировать другие функциональные возможности, кроме маршрутизации Camel, выполняются параллельно.

Но это не является удовлетворительным решением относительно суммы около 400 JUnit-тестов.
Нет ли какой-либо конфигурации или настройки для параллельного тестирования маршрутов Camel, которые будут работать правильно?

1 ответ

Ваши MQ темы с состоянием и, следовательно, "не потокобезопасны". Как только несколько тестов выполняются параллельно, количество сообщений в темах не предвидится.

Чтобы решить эту проблему, вы должны изолировать часть ваших тестов с сохранением состояния, то есть темы MQ. Вам нужно будет генерировать уникальные имена тем MQ для каждого теста, чтобы у каждого теста были свои собственные темы MQ. В этом случае размер сообщения четко определяется как при однопоточном выполнении.

В качестве альтернативы изоляции в теме можно использовать селекторы сообщений JMS, чтобы изолировать сообщения в теме для различных тестов. В этом случае каждый тест должен установить заголовок сообщения с уникальным значением и использовать только сообщения с этим значением.

Другие вопросы по тегам