From 1bedfc619cb617736ca76a52b842bd7683e55c03 Mon Sep 17 00:00:00 2001 From: Kamil Krzywannski Date: Sun, 12 Jul 2026 11:00:03 +0200 Subject: [PATCH 1/2] Fix flaky preferCallConnectionOverDeferredConnection test Stall IPv6 by destination address in Socket.connect() instead of the first createSocket() call, which raced under concurrent connects. Fixes #9369 --- .../kotlin/okhttp3/FastFallbackTest.kt | 25 ++++++++++++------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/okhttp/src/jvmTest/kotlin/okhttp3/FastFallbackTest.kt b/okhttp/src/jvmTest/kotlin/okhttp3/FastFallbackTest.kt index b74743868ce6..3db4f5cbcc9d 100644 --- a/okhttp/src/jvmTest/kotlin/okhttp3/FastFallbackTest.kt +++ b/okhttp/src/jvmTest/kotlin/okhttp3/FastFallbackTest.kt @@ -23,7 +23,9 @@ import java.io.IOException import java.net.Inet4Address import java.net.Inet6Address import java.net.InetAddress +import java.net.InetSocketAddress import java.net.Socket +import java.net.SocketAddress import java.util.concurrent.CountDownLatch import java.util.concurrent.TimeUnit import javax.net.SocketFactory @@ -280,18 +282,23 @@ class FastFallbackTest { serverIpv4.protocols = listOf(Protocol.H2_PRIOR_KNOWLEDGE) serverIpv6.protocols = listOf(Protocol.H2_PRIOR_KNOWLEDGE) - // Yield the first IP address so the second IP address completes first. - val firstConnectLatch = CountDownLatch(1) + // Stall IPv6 so the IPv4 address completes first. + val ipv6ConnectLatch = CountDownLatch(1) val socketFactory = object : DelegatingSocketFactory(SocketFactory.getDefault()) { - var first = true - override fun createSocket(): Socket { - if (first) { - first = false - firstConnectLatch.await() + return object : Socket() { + override fun connect( + endpoint: SocketAddress, + timeout: Int, + ) { + val address = (endpoint as? InetSocketAddress)?.address + if (address == localhostIpv6) { + ipv6ConnectLatch.await() + } + super.connect(endpoint, timeout) + } } - return super.createSocket() } } @@ -305,7 +312,7 @@ class FastFallbackTest { try { chain.proceed(chain.request()) } finally { - firstConnectLatch.countDown() + ipv6ConnectLatch.countDown() } }, ).build() From 6bd8d262c4f042129f976e843b4390456183b3cf Mon Sep 17 00:00:00 2001 From: Kamil Krzywanski Date: Sat, 18 Jul 2026 12:13:09 +0200 Subject: [PATCH 2/2] Apply Spotless formatting to FastFallbackTest CI failed on :okhttp:spotlessKotlinCheck because createSocket() should use expression-body form. --- okhttp/src/jvmTest/kotlin/okhttp3/FastFallbackTest.kt | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/okhttp/src/jvmTest/kotlin/okhttp3/FastFallbackTest.kt b/okhttp/src/jvmTest/kotlin/okhttp3/FastFallbackTest.kt index 3db4f5cbcc9d..9e71dfd00677 100644 --- a/okhttp/src/jvmTest/kotlin/okhttp3/FastFallbackTest.kt +++ b/okhttp/src/jvmTest/kotlin/okhttp3/FastFallbackTest.kt @@ -286,8 +286,8 @@ class FastFallbackTest { val ipv6ConnectLatch = CountDownLatch(1) val socketFactory = object : DelegatingSocketFactory(SocketFactory.getDefault()) { - override fun createSocket(): Socket { - return object : Socket() { + override fun createSocket(): Socket = + object : Socket() { override fun connect( endpoint: SocketAddress, timeout: Int, @@ -299,7 +299,6 @@ class FastFallbackTest { super.connect(endpoint, timeout) } } - } } client =