Skip to content

Commit 4c07d3b

Browse files
authored
Fix flaky test TransactionTests.testCancelAsyncRequest (#707)
* Fix flaky test `TransactionTests.testCancelAsyncRequest` Resolves #706. The continuation is resumed with the cancelation error before we cancel the scheduled request. https://github.com/swift-server/async-http-client/blob/62c06d47c8d21c91335e9f8998589e4ce31411e6/Sources/AsyncHTTPClient/AsyncAwait/Transaction.swift#L290C10-L294 Therefore this test is inherently flaky. The fix waits up to one second for the scheduled request to be canceled. * self.fulfillment(of:) is not available on Linux * Fix formatting * Fix 5.6
1 parent de7c84a commit 4c07d3b

File tree

2 files changed

+20
-6
lines changed

2 files changed

+20
-6
lines changed

Tests/AsyncHTTPClientTests/RequestBagTests.swift

+8-3
Original file line numberDiff line numberDiff line change
@@ -961,13 +961,18 @@ class UploadCountingDelegate: HTTPClientResponseDelegate {
961961
}
962962
}
963963

964-
class MockTaskQueuer: HTTPRequestScheduler {
964+
final class MockTaskQueuer: HTTPRequestScheduler {
965965
private(set) var hitCancelCount = 0
966966

967-
init() {}
967+
let onCancelRequest: (@Sendable (HTTPSchedulableRequest) -> Void)?
968968

969-
func cancelRequest(_: HTTPSchedulableRequest) {
969+
init(onCancelRequest: (@Sendable (HTTPSchedulableRequest) -> Void)? = nil) {
970+
self.onCancelRequest = onCancelRequest
971+
}
972+
973+
func cancelRequest(_ request: HTTPSchedulableRequest) {
970974
self.hitCancelCount += 1
975+
self.onCancelRequest?(request)
971976
}
972977
}
973978

Tests/AsyncHTTPClientTests/TransactionTests.swift

+12-3
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@ typealias PreparedRequest = HTTPClientRequest.Prepared
2727
final class TransactionTests: XCTestCase {
2828
func testCancelAsyncRequest() {
2929
guard #available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *) else { return }
30+
// creating the `XCTestExpectation` off the main thread crashes on Linux with Swift 5.6
31+
// therefore we create it here as a workaround which works fine
32+
let scheduledRequestCanceled = self.expectation(description: "scheduled request canceled")
3033
XCTAsyncTest {
3134
let embeddedEventLoop = EmbeddedEventLoop()
3235
defer { XCTAssertNoThrow(try embeddedEventLoop.syncShutdownGracefully()) }
@@ -43,19 +46,25 @@ final class TransactionTests: XCTestCase {
4346
preferredEventLoop: embeddedEventLoop
4447
)
4548

46-
let queuer = MockTaskQueuer()
49+
let queuer = MockTaskQueuer { _ in
50+
scheduledRequestCanceled.fulfill()
51+
}
4752
transaction.requestWasQueued(queuer)
4853

54+
XCTAssertEqual(queuer.hitCancelCount, 0)
4955
Task.detached {
5056
try await Task.sleep(nanoseconds: 5 * 1000 * 1000)
5157
transaction.cancel()
5258
}
5359

54-
XCTAssertEqual(queuer.hitCancelCount, 0)
5560
await XCTAssertThrowsError(try await responseTask.value) { error in
5661
XCTAssertTrue(error is CancellationError, "unexpected error \(error)")
5762
}
58-
XCTAssertEqual(queuer.hitCancelCount, 1)
63+
64+
// self.fulfillment(of:) is not available on Linux
65+
_ = {
66+
self.wait(for: [scheduledRequestCanceled], timeout: 1)
67+
}()
5968
}
6069
}
6170

0 commit comments

Comments
 (0)