You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Permission-bridge app-claim-first test races the server leg and times out on Windows #762
LocalPermissionBridgeInteractiveTests.App_claim_first_answers_the_hook_cancels_the_server_await_responds_to_the_server_and_logs_app (test/Capacitor.Cli.Daemon.Tests.Unit/Services/LocalPermissionBridgeInteractiveTests.cs) fails intermittently on the windows-latest leg with a 30 s TimeoutException from awaitCts.Task.WaitAsync(TimeSpan.FromSeconds(30)): the fake server's AwaitScript is never invoked.
The test settles from the app as soon as the broker shows the pending request, then waits for the server await to be cancelled. But LocalPermissionBridge.RunServerLegAsync checks settlement.IsCompleted right after BeginPermissionRequestAsync returns and, when the settlement already landed, relays it and returns without ever calling AwaitPermissionDecisionAsync. That is deliberate product behaviour. On a loaded runner the app claim wins that window, so the await the test is waiting to see cancelled never starts, and the test hangs until its own 30 s bound.
The premise in the name, "app claim first while the server await is in flight", is therefore not guaranteed by the test as written: it only holds when the server leg happens to reach AwaitPermissionDecisionAsync before the test's 10 ms pending-poll plus TrySettle.
Proposed fix
Make the premise explicit: have the test await awaitCts.Task (the AwaitScript invocation) before calling Broker.TrySettle, so the app claim provably lands while the server await is in flight. The rest of the assertions then hold deterministically. The sibling scenario, app claim landing before the server leg reaches the await, is covered by the settlement.IsCompleted relay path and could get its own test if it has none.
Already fixed in the tree. LocalPermissionBridgeInteractiveTests.cs:75 awaits awaitCts.Task and only then calls TrySettle on line 76, which is the proposed fix verbatim — the app claim provably lands while the server await is in flight, so the premise in the test's name is now guaranteed rather than hoped for.
It arrived as a drive-by in 84df292 (#812) rather than under this issue, which is why the issue stayed open.
The sibling scenario the issue mentions — an app claim landing before the server leg reaches the await — is covered by App_claim_before_the_server_leg_awaits_is_relayed_without_an_await, so the settlement.IsCompleted relay path has a test of its own.
Correction to the last paragraph above: I named a sibling test that does not exist. The scenario the issue anticipated — an app claim landing before the server leg reaches AwaitPermissionDecisionAsync, taking the settlement.IsCompleted relay path — has no test of its own in LocalPermissionBridgeInteractiveTests.
That gap is what the issue predicted, so it is worth its own issue rather than reopening this one: the fix here was making the in-flight premise deterministic, and that is done.
Activity
linear-code commentedon Sep 3, 2026
AI-2481
Inok commentedon Sep 14, 2026
Already fixed in the tree.
LocalPermissionBridgeInteractiveTests.cs:75awaitsawaitCts.Taskand only then callsTrySettleon line 76, which is the proposed fix verbatim — the app claim provably lands while the server await is in flight, so the premise in the test's name is now guaranteed rather than hoped for.It arrived as a drive-by in 84df292 (#812) rather than under this issue, which is why the issue stayed open.
The sibling scenario the issue mentions — an app claim landing before the server leg reaches the await — is covered by
App_claim_before_the_server_leg_awaits_is_relayed_without_an_await, so thesettlement.IsCompletedrelay path has a test of its own.Inok commentedon Sep 14, 2026
Correction to the last paragraph above: I named a sibling test that does not exist. The scenario the issue anticipated — an app claim landing before the server leg reaches
AwaitPermissionDecisionAsync, taking thesettlement.IsCompletedrelay path — has no test of its own inLocalPermissionBridgeInteractiveTests.That gap is what the issue predicted, so it is worth its own issue rather than reopening this one: the fix here was making the in-flight premise deterministic, and that is done.