15
15
@testable import AsyncHTTPClient
16
16
import Logging
17
17
import NIOConcurrencyHelpers
18
+ #if swift(>=5.6)
19
+ @preconcurrency import NIOCore
20
+ #else
18
21
import NIOCore
22
+ #endif
19
23
import NIOEmbedded
20
24
import NIOHTTP1
21
25
import NIOPosix
@@ -41,23 +45,23 @@ final class TransactionTests: XCTestCase {
41
45
guard let preparedRequest = maybePreparedRequest else {
42
46
return XCTFail ( " Expected to have a request here. " )
43
47
}
44
- let ( transaction, responseTask) = Transaction . makeWithResultTask (
48
+
49
+ let queuer = MockTaskQueuer ( )
50
+
51
+ await XCTAssertThrowsError ( try await Transaction . awaitResponseWithTransaction (
45
52
request: preparedRequest,
46
53
preferredEventLoop: embeddedEventLoop
47
- )
54
+ ) { transaction in
55
+ transaction. requestWasQueued ( queuer)
48
56
49
- let queuer = MockTaskQueuer ( )
50
- transaction. requestWasQueued ( queuer)
57
+ Task . detached {
58
+ try await Task . sleep ( nanoseconds: 5 * 1000 * 1000 )
59
+ transaction. cancel ( )
60
+ }
51
61
52
- Task . detached {
53
- try await Task . sleep ( nanoseconds: 5 * 1000 * 1000 )
54
- transaction. cancel ( )
55
- }
62
+ XCTAssertEqual ( queuer. hitCancelCount, 0 )
63
+ } )
56
64
57
- XCTAssertEqual ( queuer. hitCancelCount, 0 )
58
- await XCTAssertThrowsError ( try await responseTask. value) {
59
- XCTAssertEqual ( $0 as? HTTPClientError , . cancelled)
60
- }
61
65
XCTAssertEqual ( queuer. hitCancelCount, 1 )
62
66
}
63
67
#endif
@@ -78,50 +82,54 @@ final class TransactionTests: XCTestCase {
78
82
guard let preparedRequest = maybePreparedRequest else {
79
83
return
80
84
}
81
- let ( transaction, responseTask) = Transaction . makeWithResultTask (
82
- request: preparedRequest,
83
- preferredEventLoop: embeddedEventLoop
84
- )
85
85
86
86
let executor = MockRequestExecutor (
87
87
pauseRequestBodyPartStreamAfterASingleWrite: true ,
88
88
eventLoop: embeddedEventLoop
89
89
)
90
90
91
- transaction. willExecuteRequest ( executor)
92
- transaction. requestHeadSent ( )
91
+ let response = try await Transaction . awaitResponseWithTransaction (
92
+ request: preparedRequest,
93
+ preferredEventLoop: embeddedEventLoop
94
+ ) { transaction in
93
95
94
- let responseHead = HTTPResponseHead ( version: . http1_1, status: . ok, headers: [ " foo " : " bar " ] )
95
- XCTAssertFalse ( executor. signalledDemandForResponseBody)
96
- transaction. receiveResponseHead ( responseHead)
96
+ transaction. willExecuteRequest ( executor)
97
+ transaction. requestHeadSent ( )
97
98
98
- let response = try await responseTask. value
99
- XCTAssertEqual ( response. status, responseHead. status)
100
- XCTAssertEqual ( response. headers, responseHead. headers)
101
- XCTAssertEqual ( response. version, responseHead. version)
99
+ let responseHead = HTTPResponseHead ( version: . http1_1, status: . ok, headers: [ " foo " : " bar " ] )
100
+ XCTAssertFalse ( executor. signalledDemandForResponseBody)
101
+ transaction. receiveResponseHead ( responseHead)
102
102
103
- let iterator = SharedIterator ( response. body. filter { $0. readableBytes > 0 } . makeAsyncIterator ( ) )
103
+ for i in 0 ..< 100 {
104
+ XCTAssertFalse ( executor. signalledDemandForResponseBody, " Demand was not signalled yet. " )
104
105
105
- for i in 0 ..< 100 {
106
- XCTAssertFalse ( executor . signalledDemandForResponseBody , " Demand was not signalled yet. " )
107
-
108
- async let part = iterator . next ( )
106
+ XCTAssertNoThrow ( try executor . receiveResponseDemand ( ) )
107
+ executor . resetResponseStreamDemandSignal ( )
108
+ transaction . receiveResponseBodyParts ( [ ByteBuffer ( integer : i ) ] )
109
+ }
109
110
111
+ XCTAssertFalse ( executor. signalledDemandForResponseBody, " Demand was not signalled yet. " )
110
112
XCTAssertNoThrow ( try executor. receiveResponseDemand ( ) )
111
113
executor. resetResponseStreamDemandSignal ( )
112
- transaction. receiveResponseBodyParts ( [ ByteBuffer ( integer: i) ] )
114
+ transaction. succeedRequest ( [ ] )
115
+ }
113
116
114
- let result = try await part
117
+ let expectedResponse = HTTPResponseHead ( version: . http1_1, status: . ok, headers: [ " foo " : " bar " ] )
118
+
119
+ XCTAssertEqual ( response. status, expectedResponse. status)
120
+ XCTAssertEqual ( response. headers, expectedResponse. headers)
121
+ XCTAssertEqual ( response. version, expectedResponse. version)
122
+
123
+ var iterator = response. body. filter { $0. readableBytes > 0 } . makeAsyncIterator ( )
124
+
125
+ for i in 0 ..< 100 {
126
+ let result = try await iterator. next ( )
115
127
XCTAssertEqual ( result, ByteBuffer ( integer: i) )
116
128
}
117
129
118
- XCTAssertFalse ( executor. signalledDemandForResponseBody, " Demand was not signalled yet. " )
119
- async let part = iterator. next ( )
120
- XCTAssertNoThrow ( try executor. receiveResponseDemand ( ) )
121
- executor. resetResponseStreamDemandSignal ( )
122
- transaction. succeedRequest ( [ ] )
123
- let result = try await part
124
- XCTAssertNil ( result)
130
+ let final = try await iterator. next ( )
131
+ XCTAssertNil ( final)
132
+
125
133
}
126
134
#endif
127
135
}
@@ -581,5 +589,34 @@ extension Transaction {
581
589
582
590
return ( transaction, result)
583
591
}
592
+
593
+ fileprivate static func awaitResponseWithTransaction(
594
+ request: PreparedRequest ,
595
+ requestOptions: RequestOptions = . forTests( ) ,
596
+ logger: Logger = Logger ( label: " test " ) ,
597
+ connectionDeadline: NIODeadline = . distantFuture,
598
+ preferredEventLoop: EventLoop ,
599
+ _ closure: @Sendable @escaping ( Transaction) async throws -> ( )
600
+ ) async throws -> HTTPClientResponse {
601
+
602
+ try await withCheckedThrowingContinuation { ( continuation: CheckedContinuation < HTTPClientResponse , Error > ) in
603
+ let transaction = Transaction (
604
+ request: request,
605
+ requestOptions: requestOptions,
606
+ logger: logger,
607
+ connectionDeadline: connectionDeadline,
608
+ preferredEventLoop: preferredEventLoop,
609
+ responseContinuation: continuation
610
+ )
611
+
612
+ Task {
613
+ do {
614
+ try await closure ( transaction)
615
+ } catch {
616
+ XCTFail ( )
617
+ }
618
+ }
619
+ }
620
+ }
584
621
}
585
622
#endif
0 commit comments