This is an automated email from the ASF dual-hosted git repository.

gnodet pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git


The following commit(s) were added to refs/heads/main by this push:
     new 5eb8451c0458 CAMEL-23885: Fix flaky camel-mllp surefire tests (#24394)
5eb8451c0458 is described below

commit 5eb8451c04588f099a597b857b421a6fed044350
Author: Guillaume Nodet <[email protected]>
AuthorDate: Fri Jul 3 12:41:07 2026 +0200

    CAMEL-23885: Fix flaky camel-mllp surefire tests (#24394)
    
    Fix two flaky tests in the camel-mllp module:
    
    1. MllpTcpClientProducerConnectionErrorTest
       .testConnectionResetAndServerShutdownBeforeSendingHL7Message:
       When a connection reset is followed by a server shutdown, the
       error can manifest as either a MllpWriteException or a
       MllpAcknowledgementException depending on timing. The test
       previously hard-coded expectations for writeEx=1 and
       acknowledgementEx=0, but now follows the same pattern as the
       sibling tests (testServerShutdownBeforeSendingHL7Message and
       testConnectionCloseAndServerShutdownBeforeSendingHL7Message)
       by checking that the sum of both is 1.
    
    2. MllpMutualTlsConnectionAndHeaderRequiresClientAuthenticationTest
       
.testSendingTlsWithNoClientCertificateToMllpConsumerWhichRequiresClientAuthentication:
       When a TLS client connects without a certificate to a server
       that requires client authentication, the root cause exception
       can be either SSLHandshakeException (clean TLS rejection) or
       SocketException (connection reset before the handshake error
       propagates), depending on JDK-level timing. The test now
       accepts both exception types.
    
    Co-authored-by: Claude Opus 4.6 <[email protected]>
---
 ...ectionAndHeaderRequiresClientAuthenticationTest.java | 17 ++++++++++++++++-
 .../mllp/MllpTcpClientProducerConnectionErrorTest.java  |  6 ++++--
 2 files changed, 20 insertions(+), 3 deletions(-)

diff --git 
a/components/camel-mllp/src/test/java/org/apache/camel/component/mllp/MllpMutualTlsConnectionAndHeaderRequiresClientAuthenticationTest.java
 
b/components/camel-mllp/src/test/java/org/apache/camel/component/mllp/MllpMutualTlsConnectionAndHeaderRequiresClientAuthenticationTest.java
index de0890a22cee..a9f4feca4e37 100644
--- 
a/components/camel-mllp/src/test/java/org/apache/camel/component/mllp/MllpMutualTlsConnectionAndHeaderRequiresClientAuthenticationTest.java
+++ 
b/components/camel-mllp/src/test/java/org/apache/camel/component/mllp/MllpMutualTlsConnectionAndHeaderRequiresClientAuthenticationTest.java
@@ -16,6 +16,8 @@
  */
 package org.apache.camel.component.mllp;
 
+import java.net.SocketException;
+
 import javax.net.ssl.SSLHandshakeException;
 
 import org.apache.camel.CamelExecutionException;
@@ -34,13 +36,26 @@ class 
MllpMutualTlsConnectionAndHeaderRequiresClientAuthenticationTest extends M
      * This test does TLS connection without a client sending its certificate, 
i.e., no mTLS. As the server is
      * configured to require client authentication, this should fail.
      *
+     * The cause chain may contain either an SSLHandshakeException (clean TLS 
rejection) or a SocketException
+     * (connection reset before the handshake error propagates), depending on 
JDK-level timing.
      */
     @Test
     void 
testSendingTlsWithNoClientCertificateToMllpConsumerWhichRequiresClientAuthentication()
 {
         CamelExecutionException e = 
Assertions.assertThrows(CamelExecutionException.class, () -> {
             template.sendBody(assembleEndpointUri(WITH_ONLY_TRUSTSTORE), 
TEST_PAYLOAD);
         });
-        Assertions.assertInstanceOf(SSLHandshakeException.class, 
e.getCause().getCause().getCause());
+        Throwable rootCause = findRootCause(e);
+        Assertions.assertTrue(
+                rootCause instanceof SSLHandshakeException || rootCause 
instanceof SocketException,
+                "Expected SSLHandshakeException or SocketException but was: " 
+ rootCause.getClass().getName());
+    }
+
+    private static Throwable findRootCause(Throwable t) {
+        Throwable cause = t;
+        while (cause.getCause() != null && cause.getCause() != cause) {
+            cause = cause.getCause();
+        }
+        return cause;
     }
 
     /**
diff --git 
a/components/camel-mllp/src/test/java/org/apache/camel/component/mllp/MllpTcpClientProducerConnectionErrorTest.java
 
b/components/camel-mllp/src/test/java/org/apache/camel/component/mllp/MllpTcpClientProducerConnectionErrorTest.java
index aa5ed2da1209..00aa6d0e9273 100644
--- 
a/components/camel-mllp/src/test/java/org/apache/camel/component/mllp/MllpTcpClientProducerConnectionErrorTest.java
+++ 
b/components/camel-mllp/src/test/java/org/apache/camel/component/mllp/MllpTcpClientProducerConnectionErrorTest.java
@@ -255,8 +255,6 @@ public class MllpTcpClientProducerConnectionErrorTest 
extends CamelTestSupport {
         target.expectedMessageCount(1);
         complete.expectedMessageCount(2);
         connectEx.expectedMessageCount(0);
-        writeEx.expectedMessageCount(1);
-        acknowledgementEx.expectedMessageCount(0);
 
         NotifyBuilder done = new 
NotifyBuilder(context).whenCompleted(2).create();
 
@@ -271,6 +269,10 @@ public class MllpTcpClientProducerConnectionErrorTest 
extends CamelTestSupport {
         assertTrue(done.matches(10, TimeUnit.SECONDS), "Should have completed 
an exchange");
 
         MockEndpoint.assertIsSatisfied(context, 10, TimeUnit.SECONDS);
+
+        // Depending on the timing, either a write or a receive exception will 
be thrown
+        assertEquals(1, writeEx.getExchanges().size() + 
acknowledgementEx.getExchanges().size(),
+                "Either a write or a receive exception should have been be 
thrown");
     }
 
 }

Reply via email to