Как правильно делать @DirtiesConfig при использовании @EmbeddedKafka - PullRequest
0 голосов
/ 01 октября 2019

У нас есть «маленькая» проблема в нашем проекте: «Не удалось установить соединение с узлом 0. Брокер может быть недоступен». Тесты выполняются очень и очень долго, и это сообщение регистрируется как минимум раз в секунду. Но я узнал, как от этого избавиться. Читать дальше. Если что-то не так в настройках / аннотациях, пожалуйста, дайте мне знать.

Первые версии:

<springframework.boot.version>2.1.8.RELEASE</springframework.boot.version>

, что автоматически приводит к

<spring-kafka.version>2.2.8.RELEASE</spring-kafka.version>

Теперь мы рассмотрим этот интеграционный тест с комментариями:

@RunWith(SpringRunner.class)
@Import(/*some our configuration, irrelevant*/ )
@ActiveProfiles(/*some our profiles, irrelevant*/)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@EmbeddedKafka(controlledShutdown = true)
@Transactional

Итогда у нас есть несколько тестов, таких как:

@Test
@DirtiesContext

public void testPostWhatever() throws JSONException, IOException {

Этот тест просто создает некоторые данные запроса, вызывает post, который, в свою очередь, сохраняет данные в БД. Затем мы будем использовать GET, чтобы выяснить, сможем ли мы найти эти данные. Trivial. Немного странным для меня является обработка транзакций здесь. Тестовый класс аннотируется @Transactional, но в соответствии с журналом транзакция открывается только по методу Controller, который в этом примере (обязательно должен быть на службе) точно такой же аннотацией @Transactional. Оба с TxType.REQUIRED распространения. Это приведет к тому, что откат, инициированный тестом, фактически ничего не откатит, так как транзакция уже зафиксирована. Если вы знаете, почему это так, пожалуйста, сообщите. Но это не суть этого вопроса. Пока что мы просто поместили @DirtiesContext в этот метод, который должен просто повторно инициализировать контекст. Это решает проблему с необкатанными данными при высокой стоимости повторной инициализации контекста. Но в журнале начинают появляться следующие сообщения:

2019-10-01 13:49:07.336 org.apache.kafka.clients.NetworkClient   : [Producer clientId=producer-2] Connection to node 0 could not be established. Broker may not be available.
2019-10-01 13:49:07.699 org.apache.kafka.clients.NetworkClient   : [Producer clientId=producer-1] Connection to node 0 could not be established. Broker may not be available.
2019-10-01 13:49:08.191 org.apache.kafka.clients.NetworkClient   : [Producer clientId=producer-2] Connection to node 0 could not be established. Broker may not be available.
2019-10-01 13:49:08.603 org.apache.kafka.clients.NetworkClient   : [Producer clientId=producer-1] Connection to node 0 could not be established. Broker may not be available.
2019-10-01 13:49:08.927 o.a.c.loader.WebappClassLoaderBase       : The web application [ofs] appears to have started a thread named [kafka-producer-network-thread | producer-2] but has failed to stop it. This is very likely to create a memory leak. Stack trace of thread:
 sun.nio.ch.EPollArrayWrapper.epollWait(Native Method)
 sun.nio.ch.EPollArrayWrapper.poll(EPollArrayWrapper.java:269)
 sun.nio.ch.EPollSelectorImpl.doSelect(EPollSelectorImpl.java:93)
 sun.nio.ch.SelectorImpl.lockAndDoSelect(SelectorImpl.java:86)
 sun.nio.ch.SelectorImpl.select(SelectorImpl.java:97)
 org.apache.kafka.common.network.Selector.select(Selector.java:691)
 org.apache.kafka.common.network.Selector.poll(Selector.java:411)
 org.apache.kafka.clients.NetworkClient.poll(NetworkClient.java:510)
 org.apache.kafka.clients.producer.internals.Sender.run(Sender.java:239)
 org.apache.kafka.clients.producer.internals.Sender.run(Sender.java:163)
 java.lang.Thread.run(Thread.java:748)

Удаление этого @DirtiesContext и размещение его на уровне класса, например

@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)

, ведут себя аналогично (за исключением нелепых дополнительных накладных расходов). Но если я удаляю все @DirtiesContext, очищаю db вручную и фиксирую изменения, чтобы после каждого теста изменения были отменены, все работало просто отлично, без предупреждений или ошибок.

Так что я думаю, что есть 2 вещи. Моя проблема вызвана неправильной обработкой tx (пожалуйста, помогите), но @DirtiesContext также может быть возможно использовать с spring-kafka, и что кажется не работает. Либо это невозможно в принципе (или это так?), Либо у меня что-то неправильно настроено (пожалуйста, помогите), или это может быть ошибка?

1 Ответ

0 голосов
/ 01 октября 2019

Если вы используете JUnit4, вы можете использовать EmbeddedKafkaRule в качестве @ClassRule вместо @EmbeddedKafka, и посредник не будет добавлен в контекст.

К сожалению, аналога нетJUnitt5 - но вы все равно можете добавить статический EmbeddedKafkaBroker и уничтожить его самостоятельно @AfterAll методом.

...