19
19
#endif
20
20
import Logging
21
21
import NIOCore
22
+ import NIOHTTP1
22
23
import NIOPosix
23
24
import NIOSSL
24
25
import XCTest
@@ -229,29 +230,23 @@ class HTTP2ClientTests: XCTestCase {
229
230
case . success:
230
231
XCTFail ( " Shouldn't succeed " )
231
232
case . failure( let error) :
232
- if let clientError = error as? HTTPClientError , clientError == . cancelled {
233
- continue
234
- } else {
235
- XCTFail ( " Unexpected error: \( error) " )
236
- }
233
+ XCTAssertEqual ( error as? HTTPClientError , . cancelled)
237
234
}
238
235
}
239
236
}
240
237
241
238
func testCancelingRunningRequest( ) {
242
- let bin = HTTPBin ( . http2( compress: false ) )
239
+ let bin = HTTPBin ( . http2( compress: false ) ) { _ in SendHeaderAndWaitChannelHandler ( ) }
243
240
defer { XCTAssertNoThrow ( try bin. shutdown ( ) ) }
244
- let client = self . makeClientWithActiveHTTP2Connection ( to : bin )
241
+ let client = self . makeDefaultHTTPClient ( )
245
242
defer { XCTAssertNoThrow ( try client. syncShutdown ( ) ) }
246
243
247
244
var maybeRequest : HTTPClient . Request ?
248
- XCTAssertNoThrow ( maybeRequest = try HTTPClient . Request ( url: " https://localhost: \( bin. port) /sendheaderandwait " ) )
245
+ XCTAssertNoThrow ( maybeRequest = try HTTPClient . Request ( url: " https://localhost: \( bin. port) " ) )
249
246
guard let request = maybeRequest else { return }
250
247
251
- var task : HTTPClient . Task < TestHTTPDelegate . Response > !
252
- let delegate = TestHTTPDelegate ( )
253
- delegate. stateDidChangeCallback = { state in
254
- guard case . head = state else { return }
248
+ var task : HTTPClient . Task < Void > !
249
+ let delegate = HeadReceivedCallback { _ in
255
250
// request is definitely running because we just received a head from the server
256
251
task. cancel ( )
257
252
}
@@ -260,30 +255,26 @@ class HTTP2ClientTests: XCTestCase {
260
255
delegate: delegate
261
256
)
262
257
263
- XCTAssertThrowsError ( try task. futureResult. timeout ( after: . seconds( 2 ) ) . wait ( ) , " Should fail " ) { error in
264
- guard case let error = error as? HTTPClientError , error == . cancelled else {
265
- return XCTFail ( " Should fail with cancelled " )
266
- }
258
+ XCTAssertThrowsError ( try task. futureResult. timeout ( after: . seconds( 2 ) ) . wait ( ) ) {
259
+ XCTAssertEqual ( $0 as? HTTPClientError , . cancelled)
267
260
}
268
261
}
269
262
270
263
func testStressCancelingRunningRequestFromDifferentThreads( ) {
271
- let bin = HTTPBin ( . http2( compress: false ) )
264
+ let bin = HTTPBin ( . http2( compress: false ) ) { _ in SendHeaderAndWaitChannelHandler ( ) }
272
265
defer { XCTAssertNoThrow ( try bin. shutdown ( ) ) }
273
- let client = self . makeClientWithActiveHTTP2Connection ( to : bin )
266
+ let client = self . makeDefaultHTTPClient ( )
274
267
defer { XCTAssertNoThrow ( try client. syncShutdown ( ) ) }
275
268
let cancelPool = MultiThreadedEventLoopGroup ( numberOfThreads: 10 )
276
269
defer { XCTAssertNoThrow ( try cancelPool. syncShutdownGracefully ( ) ) }
277
270
278
271
var maybeRequest : HTTPClient . Request ?
279
- XCTAssertNoThrow ( maybeRequest = try HTTPClient . Request ( url: " https://localhost: \( bin. port) /sendheaderandwait " ) )
272
+ XCTAssertNoThrow ( maybeRequest = try HTTPClient . Request ( url: " https://localhost: \( bin. port) " ) )
280
273
guard let request = maybeRequest else { return }
281
274
282
275
let tasks = ( 0 ..< 100 ) . map { _ -> HTTPClient . Task < TestHTTPDelegate . Response > in
283
- var task : HTTPClient . Task < TestHTTPDelegate . Response > !
284
- let delegate = TestHTTPDelegate ( )
285
- delegate. stateDidChangeCallback = { state in
286
- guard case . head = state else { return }
276
+ var task : HTTPClient . Task < Void > !
277
+ let delegate = HeadReceivedCallback { _ in
287
278
// request is definitely running because we just received a head from the server
288
279
cancelPool. next ( ) . execute {
289
280
// canceling from a different thread
@@ -298,10 +289,8 @@ class HTTP2ClientTests: XCTestCase {
298
289
}
299
290
300
291
for task in tasks {
301
- XCTAssertThrowsError ( try task. futureResult. timeout ( after: . seconds( 2 ) ) . wait ( ) , " Should fail " ) { error in
302
- guard case let error = error as? HTTPClientError , error == . cancelled else {
303
- return XCTFail ( " Should fail with cancelled " )
304
- }
292
+ XCTAssertThrowsError ( try task. futureResult. timeout ( after: . seconds( 2 ) ) . wait ( ) ) {
293
+ XCTAssertEqual ( $0 as? HTTPClientError , . cancelled)
305
294
}
306
295
}
307
296
}
@@ -367,3 +356,32 @@ class HTTP2ClientTests: XCTestCase {
367
356
}
368
357
}
369
358
}
359
+
360
+ private final class HeadReceivedCallback : HTTPClientResponseDelegate {
361
+ typealias Response = Void
362
+ private let didReceiveHeadCallback : ( HTTPResponseHead ) -> Void
363
+ init ( didReceiveHead: @escaping ( HTTPResponseHead ) -> Void ) {
364
+ self . didReceiveHeadCallback = didReceiveHead
365
+ }
366
+
367
+ func didReceiveHead( task: HTTPClient . Task < Void > , _ head: HTTPResponseHead ) -> EventLoopFuture < Void > {
368
+ self . didReceiveHeadCallback ( head)
369
+ return task. eventLoop. makeSucceededVoidFuture ( )
370
+ }
371
+
372
+ func didFinishRequest( task: HTTPClient . Task < Void > ) throws { }
373
+ }
374
+
375
+ /// sends some headers and waits indefinitely afterwards
376
+ private final class SendHeaderAndWaitChannelHandler : ChannelInboundHandler {
377
+ typealias InboundIn = HTTPServerRequestPart
378
+ typealias OutboundOut = HTTPServerResponsePart
379
+
380
+ func channelRead( context: ChannelHandlerContext , data: NIOAny ) {
381
+ context. writeAndFlush ( wrapOutboundOut ( . head( HTTPResponseHead (
382
+ version: HTTPVersion ( major: 1 , minor: 1 ) ,
383
+ status: . ok
384
+ ) )
385
+ ) , promise: nil )
386
+ }
387
+ }
0 commit comments