Fix for flaky tests (#5869)

* possible logging tests fix

* fix for flaky tests

* use timelimit for max test time

* pr suggestions

* remove comment
This commit is contained in:
Mauro
2026-07-14 18:01:36 +02:00
committed by GitHub
parent 85f28d017d
commit 39bd882a27
14 changed files with 231 additions and 132 deletions
+47 -32
View File
@@ -11,6 +11,8 @@ import Clocks
import PushKit
import Testing
// The TestClock advances by yielding to background tasks which can be starved on a busy CI runner.
@Suite(.timeLimit(.minutes(2)))
@MainActor
final class ElementCallServiceTests {
private var callProvider: CXProviderMock!
@@ -111,27 +113,28 @@ final class ElementCallServiceTests {
}
@Test
func lifetimeIsCapped() async {
await confirmation { confirmation in
callProvider.reportCallWithEndedAtReasonClosure = { _, _, reason in
if reason == .unanswered {
confirmation()
} else {
Issue.record("Call should have ended as unanswered")
}
}
#expect(!callProvider.reportNewIncomingCallWithUpdateCompletionCalled)
let pushPayload = PKPushPayloadMock().updatingExpiration(currentDate, lifetime: 300)
service.pushRegistry(pushRegistry,
didReceiveIncomingPushWith: pushPayload,
for: .voIP) { }
// Advance past the max timeout but below the 300
await testClock.advance(by: .seconds(100))
func lifetimeIsCapped() async throws {
#expect(!callProvider.reportNewIncomingCallWithUpdateCompletionCalled)
let (endedCalls, endedCallsContinuation) = AsyncStream<CXCallEndedReason>.makeStream()
callProvider.reportCallWithEndedAtReasonClosure = { _, _, reason in
endedCallsContinuation.yield(reason)
}
let deferredEndedCall = deferFulfillment(endedCalls, timeout: .seconds(30)) { _ in true }
let pushPayload = PKPushPayloadMock().updatingExpiration(currentDate, lifetime: 300)
service.pushRegistry(pushRegistry,
didReceiveIncomingPushWith: pushPayload,
for: .voIP) { }
await waitForScheduledSleep()
// Advance past the max timeout but below the 300
await testClock.advance(by: .seconds(100))
let reason = try await deferredEndedCall.fulfill()
#expect(reason == .unanswered, "Call should have ended as unanswered")
}
@Test
@@ -142,20 +145,20 @@ final class ElementCallServiceTests {
}
@Test
func timeoutClearsIncomingCallStateBeforeNextPush() async {
func timeoutClearsIncomingCallStateBeforeNextPush() async throws {
// Drive push #1 to its 60s unanswered timeout
await confirmation { confirmation in
callProvider.reportCallWithEndedAtReasonClosure = { _, _, reason in
if reason == .unanswered {
confirmation()
}
}
let firstPayload = PKPushPayloadMock().updatingExpiration(currentDate, lifetime: 60)
service.pushRegistry(pushRegistry, didReceiveIncomingPushWith: firstPayload, for: .voIP) { }
await testClock.advance(by: .seconds(70))
let (endedCalls, endedCallsContinuation) = AsyncStream<CXCallEndedReason>.makeStream()
callProvider.reportCallWithEndedAtReasonClosure = { _, _, reason in
endedCallsContinuation.yield(reason)
}
let deferredEndedCall = deferFulfillment(endedCalls, timeout: .seconds(30)) { $0 == .unanswered }
let firstPayload = PKPushPayloadMock().updatingExpiration(currentDate, lifetime: 60)
service.pushRegistry(pushRegistry, didReceiveIncomingPushWith: firstPayload, for: .voIP) { }
await waitForScheduledSleep()
await testClock.advance(by: .seconds(70))
try await deferredEndedCall.fulfill()
callProvider.reportCallWithEndedAtReasonClosure = nil
let firstCallUUID = callProvider.reportNewIncomingCallWithUpdateCompletionReceivedArguments?.uuid
@@ -189,6 +192,9 @@ final class ElementCallServiceTests {
}
}
// Make sure the cancellation below exercises a scheduled timer rather than one that never started.
await waitForScheduledSleep()
// Simulate the answer flow handing off to setupCallSession, which must cancel
// the pending endUnansweredCallTask as part of clearing the incoming state.
await service.setupCallSession(roomID: "!room:example.com", roomDisplayName: "welcome")
@@ -235,6 +241,15 @@ final class ElementCallServiceTests {
#expect(service.ongoingCallRoomIDPublisher.value == "!room:example.com")
}
/// Waits until the unanswered-call timer is sleeping on the test clock — it runs in an
/// unstructured task, so advancing the clock before that would never wake it.
/// Note: `checkSuspension()` throws when a sleep is scheduled, which is the state we want.
private func waitForScheduledSleep() async {
while await (try? testClock.checkSuspension()) != nil {
await Task.yield()
}
}
private func expectImmediatelyEndedCallReported(forPayload payload: PKPushPayloadMock,
expectedReason: CXCallEndedReason) async {
let baselineNewIncomingCount = callProvider.reportNewIncomingCallWithUpdateCompletionCallsCount