This is an automated email from the ASF dual-hosted git repository.
exceptionfactory pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/nifi.git
The following commit(s) were added to refs/heads/main by this push:
new 9d80b4a02d9 NIFI-16528 Fixed flaky MongoDB integration tests with
container status checks (#11871)
9d80b4a02d9 is described below
commit 9d80b4a02d9c03793a4818cb7b397f05550b000a
Author: Pierre Villard <[email protected]>
AuthorDate: Thu Oct 29 20:52:00 2026 +0100
NIFI-16528 Fixed flaky MongoDB integration tests with container status
checks (#11871)
Signed-off-by: David Handermann <[email protected]>
---
.../nifi/processors/mongodb/AbstractMongoIT.java | 58 +++++++++++++++++++++-
.../org/apache/nifi/mongodb/AbstractMongoIT.java | 56 ++++++++++++++++++++-
.../nifi/mongodb/MongoDBLookupServiceIT.java | 7 ++-
3 files changed, 115 insertions(+), 6 deletions(-)
diff --git
a/nifi-extension-bundles/nifi-mongodb-bundle/nifi-mongodb-processors/src/test/java/org/apache/nifi/processors/mongodb/AbstractMongoIT.java
b/nifi-extension-bundles/nifi-mongodb-bundle/nifi-mongodb-processors/src/test/java/org/apache/nifi/processors/mongodb/AbstractMongoIT.java
index 07e992fe3ac..76678fe925d 100644
---
a/nifi-extension-bundles/nifi-mongodb-bundle/nifi-mongodb-processors/src/test/java/org/apache/nifi/processors/mongodb/AbstractMongoIT.java
+++
b/nifi-extension-bundles/nifi-mongodb-bundle/nifi-mongodb-processors/src/test/java/org/apache/nifi/processors/mongodb/AbstractMongoIT.java
@@ -19,22 +19,76 @@
package org.apache.nifi.processors.mongodb;
+import com.github.dockerjava.api.command.InspectContainerResponse;
+import com.mongodb.ConnectionString;
+import com.mongodb.MongoClientSettings;
+import com.mongodb.client.MongoClient;
+import com.mongodb.client.MongoClients;
+import org.bson.Document;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testcontainers.containers.output.Slf4jLogConsumer;
+import org.testcontainers.containers.wait.strategy.Wait;
import org.testcontainers.mongodb.MongoDBContainer;
import org.testcontainers.utility.DockerImageName;
+import java.time.Duration;
+import java.util.concurrent.TimeUnit;
+
public class AbstractMongoIT {
+
+ private static final Logger LOGGER =
LoggerFactory.getLogger(AbstractMongoIT.class);
private static final String DOCKER_IMAGE =
System.getProperty("mongo.docker.image", "mongo:8");
- protected static final MongoDBContainer MONGO_CONTAINER = new
MongoDBContainer(DockerImageName.parse(DOCKER_IMAGE));
+ private static final Duration STARTUP_TIMEOUT = Duration.ofMinutes(2);
+ private static final long PING_TIMEOUT_SECONDS = 30;
+ protected static final MongoDBContainer MONGO_CONTAINER = new
MongoDBContainer(DockerImageName.parse(DOCKER_IMAGE))
+ // Let glibc own rseq so TCMalloc does not use incompatible
per-CPU caches on newer kernels.
+ .withEnv("GLIBC_TUNABLES", "glibc.pthread.rseq=1")
+ .withLogConsumer(new Slf4jLogConsumer(LOGGER))
+ .waitingFor(Wait.forLogMessage("(?i).*waiting for connections.*",
1).withStartupTimeout(STARTUP_TIMEOUT));
@BeforeAll
public static void start() {
- MONGO_CONTAINER.start();
+ try {
+ MONGO_CONTAINER.start();
+
+ final MongoClientSettings settings = MongoClientSettings.builder()
+ .applyConnectionString(new
ConnectionString(MONGO_CONTAINER.getConnectionString()))
+ .applyToClusterSettings(builder ->
builder.serverSelectionTimeout(PING_TIMEOUT_SECONDS, TimeUnit.SECONDS))
+ .applyToSocketSettings(builder -> builder
+ .connectTimeout(PING_TIMEOUT_SECONDS,
TimeUnit.SECONDS)
+ .readTimeout(PING_TIMEOUT_SECONDS,
TimeUnit.SECONDS))
+ .build();
+ try (final MongoClient client = MongoClients.create(settings)) {
+ client.getDatabase("admin").runCommand(new Document("ping",
1));
+ }
+ } catch (final RuntimeException e) {
+ logContainerDiagnostics(e);
+ throw e;
+ }
}
@AfterAll
public static void stop() {
MONGO_CONTAINER.stop();
}
+
+ private static void logContainerDiagnostics(final RuntimeException
startupException) {
+ final String containerId = MONGO_CONTAINER.getContainerId();
+ if (containerId == null) {
+ LOGGER.error("MongoDB container [{}] is unavailable for inspection
after startup failure", DOCKER_IMAGE);
+ return;
+ }
+
+ try {
+ final InspectContainerResponse.ContainerState state =
MONGO_CONTAINER.getDockerClient().inspectContainerCmd(containerId).exec().getState();
+ LOGGER.error("MongoDB container [{}] failed to become ready:
status [{}] exit code [{}] OOM killed [{}] error [{}]",
+ containerId, state.getStatus(), state.getExitCodeLong(),
state.getOOMKilled(), state.getError());
+ LOGGER.error("MongoDB container [{}] logs:\n{}", containerId,
MONGO_CONTAINER.getLogs());
+ } catch (final RuntimeException diagnosticsException) {
+ startupException.addSuppressed(diagnosticsException);
+ }
+ }
}
diff --git
a/nifi-extension-bundles/nifi-mongodb-bundle/nifi-mongodb-services/src/test/java/org/apache/nifi/mongodb/AbstractMongoIT.java
b/nifi-extension-bundles/nifi-mongodb-bundle/nifi-mongodb-services/src/test/java/org/apache/nifi/mongodb/AbstractMongoIT.java
index 272fb7f6bde..b25869e65d9 100644
---
a/nifi-extension-bundles/nifi-mongodb-bundle/nifi-mongodb-services/src/test/java/org/apache/nifi/mongodb/AbstractMongoIT.java
+++
b/nifi-extension-bundles/nifi-mongodb-bundle/nifi-mongodb-services/src/test/java/org/apache/nifi/mongodb/AbstractMongoIT.java
@@ -19,19 +19,55 @@
package org.apache.nifi.mongodb;
+import com.github.dockerjava.api.command.InspectContainerResponse;
+import com.mongodb.ConnectionString;
+import com.mongodb.MongoClientSettings;
+import com.mongodb.client.MongoClient;
+import com.mongodb.client.MongoClients;
+import org.bson.Document;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testcontainers.containers.output.Slf4jLogConsumer;
+import org.testcontainers.containers.wait.strategy.Wait;
import org.testcontainers.mongodb.MongoDBContainer;
import org.testcontainers.utility.DockerImageName;
+import java.time.Duration;
+import java.util.concurrent.TimeUnit;
+
public class AbstractMongoIT {
+ private static final Logger LOGGER =
LoggerFactory.getLogger(AbstractMongoIT.class);
private static final String DOCKER_IMAGE =
System.getProperty("mongo.docker.image", "mongo:8");
- protected static final MongoDBContainer MONGO_CONTAINER = new
MongoDBContainer(DockerImageName.parse(DOCKER_IMAGE));
+ private static final Duration STARTUP_TIMEOUT = Duration.ofMinutes(2);
+ private static final long PING_TIMEOUT_SECONDS = 30;
+ protected static final MongoDBContainer MONGO_CONTAINER = new
MongoDBContainer(DockerImageName.parse(DOCKER_IMAGE))
+ // Let glibc own rseq so TCMalloc does not use incompatible
per-CPU caches on newer kernels.
+ .withEnv("GLIBC_TUNABLES", "glibc.pthread.rseq=1")
+ .withLogConsumer(new Slf4jLogConsumer(LOGGER))
+ .waitingFor(Wait.forLogMessage("(?i).*waiting for connections.*",
1).withStartupTimeout(STARTUP_TIMEOUT));
@BeforeAll
public static void start() {
- MONGO_CONTAINER.start();
+ try {
+ MONGO_CONTAINER.start();
+
+ final MongoClientSettings settings = MongoClientSettings.builder()
+ .applyConnectionString(new
ConnectionString(MONGO_CONTAINER.getConnectionString()))
+ .applyToClusterSettings(builder ->
builder.serverSelectionTimeout(PING_TIMEOUT_SECONDS, TimeUnit.SECONDS))
+ .applyToSocketSettings(builder -> builder
+ .connectTimeout(PING_TIMEOUT_SECONDS,
TimeUnit.SECONDS)
+ .readTimeout(PING_TIMEOUT_SECONDS,
TimeUnit.SECONDS))
+ .build();
+ try (final MongoClient client = MongoClients.create(settings)) {
+ client.getDatabase("admin").runCommand(new Document("ping",
1));
+ }
+ } catch (final RuntimeException e) {
+ logContainerDiagnostics(e);
+ throw e;
+ }
}
@AfterAll
@@ -39,4 +75,20 @@ public class AbstractMongoIT {
MONGO_CONTAINER.stop();
}
+ private static void logContainerDiagnostics(final RuntimeException
startupException) {
+ final String containerId = MONGO_CONTAINER.getContainerId();
+ if (containerId == null) {
+ LOGGER.error("MongoDB container [{}] is unavailable for inspection
after startup failure", DOCKER_IMAGE);
+ return;
+ }
+
+ try {
+ final InspectContainerResponse.ContainerState state =
MONGO_CONTAINER.getDockerClient().inspectContainerCmd(containerId).exec().getState();
+ LOGGER.error("MongoDB container [{}] failed to become ready:
status [{}] exit code [{}] OOM killed [{}] error [{}]",
+ containerId, state.getStatus(), state.getExitCodeLong(),
state.getOOMKilled(), state.getError());
+ LOGGER.error("MongoDB container [{}] logs:\n{}", containerId,
MONGO_CONTAINER.getLogs());
+ } catch (final RuntimeException diagnosticsException) {
+ startupException.addSuppressed(diagnosticsException);
+ }
+ }
}
diff --git
a/nifi-extension-bundles/nifi-mongodb-bundle/nifi-mongodb-services/src/test/java/org/apache/nifi/mongodb/MongoDBLookupServiceIT.java
b/nifi-extension-bundles/nifi-mongodb-bundle/nifi-mongodb-services/src/test/java/org/apache/nifi/mongodb/MongoDBLookupServiceIT.java
index 9eb47af8036..76130c2d46b 100644
---
a/nifi-extension-bundles/nifi-mongodb-bundle/nifi-mongodb-services/src/test/java/org/apache/nifi/mongodb/MongoDBLookupServiceIT.java
+++
b/nifi-extension-bundles/nifi-mongodb-bundle/nifi-mongodb-services/src/test/java/org/apache/nifi/mongodb/MongoDBLookupServiceIT.java
@@ -89,8 +89,11 @@ public class MongoDBLookupServiceIT extends AbstractMongoIT {
@AfterEach
public void after() {
- db.drop();
- controllerService.onDisable();
+ try {
+ db.drop();
+ } finally {
+ controllerService.onDisable();
+ }
}
@Test