Hi Ryan

The test still fails in some CI environments.

https://github.com/apache/httpcomponents-core/actions/runs/20535102490/job/58992266978

Any theory as to why it has started failing out of the sudden? The test was contributed in 2020 and I do not remember it causing any trouble.

Oleg


On 12/27/2025 06:48, [email protected] wrote:
This is an automated email from the ASF dual-hosted git repository.

rschmitt pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/httpcomponents-core.git


The following commit(s) were added to refs/heads/master by this push:
      new 9d954702b MonitoringResponseOutOfOrderStrategyIntegrationTest: Fix 
deadlock
9d954702b is described below

commit 9d954702b2527dc0eac5adf8ca9284b0150bb21e
Author: Ryan Schmitt <[email protected]>
AuthorDate: Sat Dec 27 00:16:39 2025 -0500

     MonitoringResponseOutOfOrderStrategyIntegrationTest: Fix deadlock
This test can deadlock: both the client and the server can fill up their
     respective output buffers and block indefinitely while simultaneously
     trying to write to each other.
It's clear why the client in this test sends a large request entity, but
     I'm not able to identify a reason why the test server is also sending a
     large response entity. To prevent the deadlock, I've changed the test
     server to send a small response instead, one that will trivially fit in
     the output buffer.
I've also added an assertion to verify that the client's request was
     truncated upon receipt of the server's response, since this seems to be
     the actual functionality we are testing. This new assertion fails if
     `MonitoringResponseOutOfOrderStrategy` is not provided.
---
  ...ringResponseOutOfOrderStrategyIntegrationTest.java | 19 ++++++++-----------
  1 file changed, 8 insertions(+), 11 deletions(-)

diff --git 
a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/classic/MonitoringResponseOutOfOrderStrategyIntegrationTest.java
 
b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/classic/MonitoringResponseOutOfOrderStrategyIntegrationTest.java
index 81ff0e804..dddd39696 100644
--- 
a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/classic/MonitoringResponseOutOfOrderStrategyIntegrationTest.java
+++ 
b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/classic/MonitoringResponseOutOfOrderStrategyIntegrationTest.java
@@ -47,6 +47,7 @@
  import org.apache.hc.core5.http.io.SocketConfig;
  import org.apache.hc.core5.http.io.entity.AbstractHttpEntity;
  import org.apache.hc.core5.http.io.entity.EntityUtils;
+import org.apache.hc.core5.http.io.entity.StringEntity;
  import org.apache.hc.core5.http.message.BasicClassicHttpRequest;
  import org.apache.hc.core5.http.protocol.HttpCoreContext;
  import org.apache.hc.core5.testing.SSLTestContexts;
@@ -55,12 +56,10 @@
  import org.apache.hc.core5.util.Timeout;
  import org.junit.jupiter.api.Assertions;
  import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.Timeout.ThreadMode;
  import org.junit.jupiter.api.extension.RegisterExtension;
abstract class MonitoringResponseOutOfOrderStrategyIntegrationTest {
-
-    // Use a 16k buffer for consistent results across systems
-    private static final int BUFFER_SIZE = 16 * 1024;
      private static final Timeout TIMEOUT = Timeout.ofSeconds(3);
private final URIScheme scheme;
@@ -78,14 +77,12 @@ public 
MonitoringResponseOutOfOrderStrategyIntegrationTest(final URIScheme schem
                  .setSslContext(scheme == URIScheme.HTTPS ? 
SSLTestContexts.createServerSSLContext() : null)
                  .setSocketConfig(SocketConfig.custom()
                          .setSoTimeout(TIMEOUT)
-                        .setSndBufSize(BUFFER_SIZE)
-                        .setRcvBufSize(BUFFER_SIZE)
                          .setSoKeepAlive(false)
                          .build())
                  .setRequestRouter(RequestRouter.<HttpRequestHandler>builder()
                          .addRoute(RequestRouter.LOCAL_AUTHORITY, "*", (request, 
response, context) -> {
                              response.setCode(400);
-                            response.setEntity(new AllOnesHttpEntity(200000));
+                            response.setEntity(new StringEntity("stop"));
                          })
                          
.resolveAuthority(RequestRouter.LOCAL_AUTHORITY_RESOLVER)
                          .build()));
@@ -95,8 +92,6 @@ public 
MonitoringResponseOutOfOrderStrategyIntegrationTest(final URIScheme schem
                  .setSslContext(SSLTestContexts.createClientSSLContext())
                  .setSocketConfig(SocketConfig.custom()
                          .setSoTimeout(TIMEOUT)
-                        .setRcvBufSize(BUFFER_SIZE)
-                        .setSndBufSize(BUFFER_SIZE)
                          .setSoKeepAlive(false)
                          .build())
                  
.setConnectionFactory(DefaultBHttpClientConnectionFactory.builder()
@@ -105,7 +100,7 @@ public 
MonitoringResponseOutOfOrderStrategyIntegrationTest(final URIScheme schem
      }
@Test
-    @org.junit.jupiter.api.Timeout(value = 1, unit = TimeUnit.MINUTES)// 
Failures may hang
+    @org.junit.jupiter.api.Timeout(value = 1, unit = TimeUnit.MINUTES, 
threadMode = ThreadMode.SEPARATE_THREAD)
      void testResponseOutOfOrderWithDefaultStrategy() throws Exception {
          final HttpServer server = serverResource.start();
          final HttpRequester requester = clientResource.start();
@@ -114,16 +109,18 @@ void testResponseOutOfOrderWithDefaultStrategy() throws 
Exception {
          final HttpHost host = new HttpHost(scheme.id, "localhost", 
server.getLocalPort());
final ClassicHttpRequest post = new BasicClassicHttpRequest(Method.POST, "/");
-        post.setEntity(new AllOnesHttpEntity(200000));
+        final AllOnesHttpEntity requestEntity = new AllOnesHttpEntity(20 * 
1024 * 1024);
+        post.setEntity(requestEntity);
try (final ClassicHttpResponse response = requester.execute(host, post, TIMEOUT, context)) {
              Assertions.assertEquals(400, response.getCode());
              EntityUtils.consumeQuietly(response.getEntity());
          }
+        Assertions.assertTrue(requestEntity.remaining > 0, "Client should have 
stopped sending data");
      }
private static final class AllOnesHttpEntity extends AbstractHttpEntity {
-        private long remaining;
+        long remaining;
protected AllOnesHttpEntity(final long length) {
              super(ContentType.APPLICATION_OCTET_STREAM, null, true);



---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to