core/tunnel/src/jvmTest/.../OAuthEndToEndTest.kt fails nondeterministically in CI with a socket timeout, and a re-run of the identical commit passes.
Evidence
Same commit 172dea6d, same job, no code change between runs:
run 1 test FAILED OAuthEndToEndTest > full OAuth authorization code flow
with PKCE through relay()[jvm] FAILED
java.net.SocketTimeoutException at OAuthEndToEndTest.kt:604
50 tests completed, 1 failed
run 2 test SUCCESS 22m58s (re-run of failed jobs, identical SHA)
Line 604 is IntegrationHttpSupport.exchange(input, output, sb.toString(), bodyBytes) — a real socket exchange against the locally spawned rouse-relay binary, so a timeout here is timing, not logic.
Why this is worth an issue rather than a shrug
A nondeterministic red is worse than a consistently red test, because it destroys the ability to tell a real regression from noise at exactly the moment that distinction matters.
Concretely, this cost a full diagnostic cycle: the failure landed on a PR whose diff was two files in app/src/foss/, a module with no dependency path to :core:tunnel (core/tunnel/build.gradle.kts depends on :core:testfixtures, :core:mcp, :core:bridge — not :app), and the failing test references nothing from com.rousecontext.app. The structural argument said "not mine"; the branch history said "previous head green, this head red, only your files changed." Those pointed opposite ways and neither settled it — only re-running the identical commit did.
That is a tax on every future PR that happens to land while this test is unlucky. The next person may not re-run; they may push a speculative fix, or worse, learn to disregard a red test job.
What would settle the cause
Not investigated here — this issue records the flake with evidence rather than guessing at it. Candidates worth checking:
- the timeout constant used by
IntegrationHttpSupport.exchange versus how long relay startup actually takes on a cold GitHub runner
- whether the test waits for the relay to be listening or merely for the process to have been spawned
- whether the OAuth flow's multi-leg exchange has a per-leg timeout that is tight relative to runner variance
Prior occurrence
android-ci.yml on main shows a failure on 2026-07-08 among otherwise-green runs. I have not confirmed that was this same test — the logs may have aged out — so treat it as a lead rather than a second data point.
core/tunnel/src/jvmTest/.../OAuthEndToEndTest.ktfails nondeterministically in CI with a socket timeout, and a re-run of the identical commit passes.Evidence
Same commit
172dea6d, same job, no code change between runs:Line 604 is
IntegrationHttpSupport.exchange(input, output, sb.toString(), bodyBytes)— a real socket exchange against the locally spawnedrouse-relaybinary, so a timeout here is timing, not logic.Why this is worth an issue rather than a shrug
A nondeterministic red is worse than a consistently red test, because it destroys the ability to tell a real regression from noise at exactly the moment that distinction matters.
Concretely, this cost a full diagnostic cycle: the failure landed on a PR whose diff was two files in
app/src/foss/, a module with no dependency path to:core:tunnel(core/tunnel/build.gradle.ktsdepends on:core:testfixtures,:core:mcp,:core:bridge— not:app), and the failing test references nothing fromcom.rousecontext.app. The structural argument said "not mine"; the branch history said "previous head green, this head red, only your files changed." Those pointed opposite ways and neither settled it — only re-running the identical commit did.That is a tax on every future PR that happens to land while this test is unlucky. The next person may not re-run; they may push a speculative fix, or worse, learn to disregard a red
testjob.What would settle the cause
Not investigated here — this issue records the flake with evidence rather than guessing at it. Candidates worth checking:
IntegrationHttpSupport.exchangeversus how long relay startup actually takes on a cold GitHub runnerPrior occurrence
android-ci.ymlonmainshows afailureon 2026-07-08 among otherwise-green runs. I have not confirmed that was this same test — the logs may have aged out — so treat it as a lead rather than a second data point.