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

Reply via email to