Give the capacity gauges a liveness deadline, not a latency one
"a poll cancelled mid-hold gives its slot back" failed twice on this branch, both times on its FIRST expectation, the one that only wants the poll to have started. The branch changes markdown and leaf pages and cannot touch poll capacity. The test passes locally in 0.101 seconds. The 25-second budget was being spent on scheduling, not on work. These tests run on the machine that is the CI runner, shared with every other pipeline, and the thing being waited on is a Task that has to get a thread before it can register as held. Under load it does not, and a merge request touching no Swift at all goes red. The budget is now a named constant at 120 seconds, with the reason on it: these assert that a held connection is counted and that a cancelled one gives its slot back, never that either happens quickly. All five call sites take the default. The cost is that a genuinely broken build takes two minutes to fail here instead of twenty-five seconds. Falsified: with leave() made a no-op the test fails after 120.1 seconds, and passes in 0.101 with it restored. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
e75cdcbcfc
commit
0c94b84fad
@@ -258,9 +258,23 @@ extension EndToEndTests {
|
||||
signingPath: "/e2e/messages")
|
||||
}
|
||||
|
||||
/// How long a gauge is given to reach a value before the test calls it
|
||||
/// wrong.
|
||||
///
|
||||
/// A liveness deadline, not a latency assertion: these tests assert
|
||||
/// that a held connection is counted and that a cancelled one gives
|
||||
/// its slot back, never that either happens quickly. The machine
|
||||
/// running them is the CI runner itself, shared with every other
|
||||
/// pipeline, and the poll being waited on is a `Task` that has to be
|
||||
/// scheduled before it can register as held. At 25 seconds
|
||||
/// `cancelledPollDoesNotLeakTheGauge` failed twice on its first
|
||||
/// expectation, the one that only wants the poll to have started, on
|
||||
/// merge requests touching nothing but markdown.
|
||||
private static let settleBudget: Double = 120
|
||||
|
||||
/// Spins until `condition` holds or the deadline passes.
|
||||
private func settles(
|
||||
within seconds: Double,
|
||||
within seconds: Double = settleBudget,
|
||||
_ condition: @escaping @Sendable () -> Bool
|
||||
) async -> Bool {
|
||||
let deadline = Date().addingTimeInterval(seconds)
|
||||
@@ -287,7 +301,7 @@ extension EndToEndTests {
|
||||
}
|
||||
|
||||
#expect(
|
||||
await settles(within: 25) {
|
||||
await settles {
|
||||
RelayCapacity.shared.snapshot().heldNow == 1
|
||||
}, "the poll should have been counted as held")
|
||||
|
||||
@@ -295,7 +309,7 @@ extension EndToEndTests {
|
||||
_ = await poll.value
|
||||
|
||||
#expect(
|
||||
await settles(within: 25) {
|
||||
await settles {
|
||||
RelayCapacity.shared.snapshot().heldNow == 0
|
||||
}, "a cancelled poll must give its slot back")
|
||||
|
||||
@@ -319,7 +333,7 @@ extension EndToEndTests {
|
||||
}
|
||||
|
||||
#expect(
|
||||
await settles(within: 25) {
|
||||
await settles {
|
||||
RelayCapacity.shared.snapshot().heldNow == 1
|
||||
}, "the poll should have been counted as held")
|
||||
|
||||
@@ -352,7 +366,7 @@ extension EndToEndTests {
|
||||
}
|
||||
|
||||
#expect(
|
||||
await settles(within: 25) {
|
||||
await settles {
|
||||
RelayCapacity.shared.snapshot().heldNow == 1
|
||||
}, "the poll should have been counted as held")
|
||||
|
||||
@@ -361,7 +375,7 @@ extension EndToEndTests {
|
||||
|
||||
_ = try? await poll.value
|
||||
#expect(
|
||||
await settles(within: 25) {
|
||||
await settles {
|
||||
RelayCapacity.shared.snapshot().heldNow == 0
|
||||
}, "a poll that threw must still give its slot back")
|
||||
RelayCapacity.shared.reset()
|
||||
|
||||
Reference in New Issue
Block a user