Skip to content

Commit f9b040e

Browse files
committed
Add state machine tests and enable skipped test for http1
1 parent 856956d commit f9b040e

File tree

3 files changed

+94
-13
lines changed

3 files changed

+94
-13
lines changed

Tests/AsyncHTTPClientTests/AsyncAwaitEndToEndTests.swift

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -318,18 +318,16 @@ final class AsyncAwaitEndToEndTests: XCTestCase {
318318
#endif
319319
}
320320

321-
func testCanceling() throws {
322-
#if os(Linux)
323-
#else
324-
try XCTSkipIf(true, "test times out because of a swift concurrency bug on macOS: https://bugs.swift.org/browse/SR-15592")
325-
#endif
321+
func testCanceling() {
326322
#if compiler(>=5.5) && canImport(_Concurrency)
327323
guard #available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) else { return }
328324
XCTAsyncTest(timeout: 5) {
325+
let bin = HTTPBin()
326+
defer { XCTAssertNoThrow(try bin.shutdown()) }
329327
let client = makeDefaultHTTPClient()
330328
defer { XCTAssertNoThrow(try client.syncShutdown()) }
331329
let logger = Logger(label: "HTTPClient", factory: StreamLogHandler.standardOutput(label:))
332-
var request = HTTPClientRequest(url: "https://localhost:45678/offline")
330+
var request = HTTPClientRequest(url: "http://localhost:\(bin.port)/offline")
333331
request.method = .POST
334332
let streamWriter = AsyncSequenceWriter<ByteBuffer>()
335333
request.body = .stream(length: nil, streamWriter)
@@ -345,7 +343,7 @@ final class AsyncAwaitEndToEndTests: XCTestCase {
345343
#endif
346344
}
347345

348-
func testDeadline() throws {
346+
func testDeadline() {
349347
#if compiler(>=5.5) && canImport(_Concurrency)
350348
guard #available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) else { return }
351349
XCTAsyncTest(timeout: 5) {
@@ -366,18 +364,16 @@ final class AsyncAwaitEndToEndTests: XCTestCase {
366364
#endif
367365
}
368366

369-
func testImmediateDeadline() throws {
370-
// does not work on nether Linux nor Darwin
371-
try XCTSkipIf(true, "test times out because of a swift concurrency bug: https://bugs.swift.org/browse/SR-15592")
367+
func testImmediateDeadline() {
372368
#if compiler(>=5.5) && canImport(_Concurrency)
373369
guard #available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) else { return }
374370
XCTAsyncTest(timeout: 5) {
375-
let bin = HTTPBin(.http2(compress: false))
371+
let bin = HTTPBin()
376372
defer { XCTAssertNoThrow(try bin.shutdown()) }
377373
let client = makeDefaultHTTPClient()
378374
defer { XCTAssertNoThrow(try client.syncShutdown()) }
379375
let logger = Logger(label: "HTTPClient", factory: StreamLogHandler.standardOutput(label:))
380-
let request = HTTPClientRequest(url: "https://localhost:\(bin.port)/wait")
376+
let request = HTTPClientRequest(url: "http://localhost:\(bin.port)/wait")
381377

382378
let task = Task<HTTPClientResponse, Error> { [request] in
383379
try await client.execute(request, deadline: .now(), logger: logger)
@@ -409,7 +405,7 @@ final class AsyncAwaitEndToEndTests: XCTestCase {
409405

410406
#if compiler(>=5.5) && canImport(_Concurrency)
411407
extension AsyncSequence where Element == ByteBuffer {
412-
func collect() async throws -> ByteBuffer {
408+
func collect() async rethrows -> ByteBuffer {
413409
try await self.reduce(into: ByteBuffer()) { accumulatingBuffer, nextBuffer in
414410
var nextBuffer = nextBuffer
415411
accumulatingBuffer.writeBuffer(&nextBuffer)

Tests/AsyncHTTPClientTests/Transaction+StateMachineTests+XCTest.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@ extension Transaction_StateMachineTests {
2727
return [
2828
("testRequestWasQueuedAfterWillExecuteRequestWasCalled", testRequestWasQueuedAfterWillExecuteRequestWasCalled),
2929
("testRequestBodyStreamWasPaused", testRequestBodyStreamWasPaused),
30+
("testQueuedRequestGetsRemovedWhenDeadlineExceeded", testQueuedRequestGetsRemovedWhenDeadlineExceeded),
31+
("testScheduledRequestGetsRemovedWhenDeadlineExceeded", testScheduledRequestGetsRemovedWhenDeadlineExceeded),
32+
("testRequestWithHeadReceivedGetNotCancelledWhenDeadlineExceeded", testRequestWithHeadReceivedGetNotCancelledWhenDeadlineExceeded),
3033
]
3134
}
3235
}

Tests/AsyncHTTPClientTests/Transaction+StateMachineTests.swift

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
@testable import AsyncHTTPClient
1616
import NIOCore
1717
import NIOEmbedded
18+
import NIOHTTP1
1819
import XCTest
1920

2021
final class Transaction_StateMachineTests: XCTestCase {
@@ -70,6 +71,87 @@ final class Transaction_StateMachineTests: XCTestCase {
7071
}
7172
#endif
7273
}
74+
75+
func testQueuedRequestGetsRemovedWhenDeadlineExceeded() {
76+
#if compiler(>=5.5) && canImport(_Concurrency)
77+
guard #available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) else { return }
78+
XCTAsyncTest {
79+
func workaround(_ continuation: CheckedContinuation<HTTPClientResponse, Error>) {
80+
var state = Transaction.StateMachine(continuation)
81+
let queuer = MockTaskQueuer()
82+
83+
state.requestWasQueued(queuer)
84+
85+
let failAction = state.deadlineExceeded()
86+
guard case .cancel(let continuation, let scheduler, nil, nil) = failAction else {
87+
return XCTFail("Unexpected fail action: \(failAction)")
88+
}
89+
XCTAssertIdentical(scheduler as? MockTaskQueuer, queuer)
90+
91+
continuation.resume(throwing: HTTPClientError.deadlineExceeded)
92+
}
93+
94+
await XCTAssertThrowsError(try await withCheckedThrowingContinuation(workaround))
95+
}
96+
#endif
97+
}
98+
99+
func testScheduledRequestGetsRemovedWhenDeadlineExceeded() {
100+
#if compiler(>=5.5) && canImport(_Concurrency)
101+
guard #available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) else { return }
102+
let eventLoop = EmbeddedEventLoop()
103+
XCTAsyncTest {
104+
func workaround(_ continuation: CheckedContinuation<HTTPClientResponse, Error>) {
105+
var state = Transaction.StateMachine(continuation)
106+
let executor = MockRequestExecutor(eventLoop: eventLoop)
107+
let queuer = MockTaskQueuer()
108+
109+
XCTAssertEqual(state.willExecuteRequest(executor), .none)
110+
state.requestWasQueued(queuer)
111+
112+
let failAction = state.deadlineExceeded()
113+
guard case .cancel(let continuation, nil, let rexecutor, nil) = failAction else {
114+
return XCTFail("Unexpected fail action: \(failAction)")
115+
}
116+
XCTAssertIdentical(rexecutor as? MockRequestExecutor, executor)
117+
118+
continuation.resume(throwing: HTTPClientError.deadlineExceeded)
119+
}
120+
121+
await XCTAssertThrowsError(try await withCheckedThrowingContinuation(workaround))
122+
}
123+
#endif
124+
}
125+
126+
func testRequestWithHeadReceivedGetNotCancelledWhenDeadlineExceeded() {
127+
#if compiler(>=5.5) && canImport(_Concurrency)
128+
guard #available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) else { return }
129+
let eventLoop = EmbeddedEventLoop()
130+
XCTAsyncTest {
131+
func workaround(_ continuation: CheckedContinuation<HTTPClientResponse, Error>) {
132+
var state = Transaction.StateMachine(continuation)
133+
let executor = MockRequestExecutor(eventLoop: eventLoop)
134+
let queuer = MockTaskQueuer()
135+
136+
XCTAssertEqual(state.willExecuteRequest(executor), .none)
137+
state.requestWasQueued(queuer)
138+
let head = HTTPResponseHead(version: .http1_1, status: .ok)
139+
let receiveResponseHeadAction = state.receiveResponseHead(head)
140+
guard case .succeedResponseHead(head, let continuation) = receiveResponseHeadAction else {
141+
return XCTFail("Unexpected action: \(receiveResponseHeadAction)")
142+
}
143+
144+
let failAction = state.deadlineExceeded()
145+
guard case .none = failAction else {
146+
return XCTFail("Unexpected fail action: \(failAction)")
147+
}
148+
continuation.resume(throwing: HTTPClientError.deadlineExceeded)
149+
}
150+
151+
await XCTAssertThrowsError(try await withCheckedThrowingContinuation(workaround))
152+
}
153+
#endif
154+
}
73155
}
74156

75157
#if compiler(>=5.5) && canImport(_Concurrency)

0 commit comments

Comments
 (0)