@@ -96,7 +96,7 @@ class HTTPConnectionPool_HTTP2StateMachineTests: XCTestCase {
96
96
XCTAssertEqual ( action. request, . none)
97
97
XCTAssertEqual ( action. connection, . none)
98
98
}
99
-
99
+
100
100
/// 4 streams are available and therefore request should be executed immediately
101
101
for _ in 0 ..< 4 {
102
102
let mockRequest = MockHTTPRequest ( eventLoop: el1, requiresEventLoopForChannel: true )
@@ -106,7 +106,7 @@ class HTTPConnectionPool_HTTP2StateMachineTests: XCTestCase {
106
106
XCTAssertEqual ( action. connection, . none)
107
107
XCTAssertEqual ( action. request, . executeRequest( request, conn, cancelTimeout: false ) )
108
108
}
109
-
109
+
110
110
/// closing streams without any queued requests shouldn't do anything if it's *not* the last stream
111
111
for _ in 0 ..< 4 {
112
112
let action = state. http2ConnectionStreamClosed ( connID)
@@ -341,11 +341,11 @@ class HTTPConnectionPool_HTTP2StateMachineTests: XCTestCase {
341
341
XCTAssertEqual ( releaseAction. request, . none)
342
342
XCTAssertEqual ( releaseAction. connection, . closeConnection( conn1, isShutdown: . yes( unclean: true ) ) )
343
343
}
344
-
344
+
345
345
func testSchedulingAndCancelingOfIdleTimeout( ) {
346
346
let elg = EmbeddedEventLoopGroup ( loops: 1 )
347
347
let el1 = elg. next ( )
348
-
348
+
349
349
// establish one idle http2 connection
350
350
let idGenerator = HTTPConnectionPool . Connection. ID. Generator ( )
351
351
var http1Conns = HTTPConnectionPool . HTTP1Connections ( maximumConcurrentConnections: 8 , generator: idGenerator)
@@ -360,36 +360,36 @@ class HTTPConnectionPool_HTTP2StateMachineTests: XCTestCase {
360
360
let connectAction = state. newHTTP2ConnectionEstablished ( conn1, maxConcurrentStreams: 100 )
361
361
XCTAssertEqual ( connectAction. request, . none)
362
362
XCTAssertEqual ( connectAction. connection, . scheduleTimeoutTimer( conn1ID, on: el1) )
363
-
363
+
364
364
// execute request on idle connection
365
365
let mockRequest1 = MockHTTPRequest ( eventLoop: el1)
366
366
let request1 = HTTPConnectionPool . Request ( mockRequest1)
367
367
let request1Action = state. executeRequest ( request1)
368
368
XCTAssertEqual ( request1Action. request, . executeRequest( request1, conn1, cancelTimeout: false ) )
369
369
XCTAssertEqual ( request1Action. connection, . cancelTimeoutTimer( conn1ID) )
370
-
370
+
371
371
// close stream
372
372
let closeStream1Action = state. http2ConnectionStreamClosed ( conn1ID)
373
373
XCTAssertEqual ( closeStream1Action. request, . none)
374
374
XCTAssertEqual ( closeStream1Action. connection, . scheduleTimeoutTimer( conn1ID, on: el1) )
375
-
375
+
376
376
// execute request on idle connection with required event loop
377
377
let mockRequest2 = MockHTTPRequest ( eventLoop: el1, requiresEventLoopForChannel: true )
378
378
let request2 = HTTPConnectionPool . Request ( mockRequest2)
379
379
let request2Action = state. executeRequest ( request2)
380
380
XCTAssertEqual ( request2Action. request, . executeRequest( request2, conn1, cancelTimeout: false ) )
381
381
XCTAssertEqual ( request2Action. connection, . cancelTimeoutTimer( conn1ID) )
382
-
382
+
383
383
// close stream
384
384
let closeStream2Action = state. http2ConnectionStreamClosed ( conn1ID)
385
385
XCTAssertEqual ( closeStream2Action. request, . none)
386
386
XCTAssertEqual ( closeStream2Action. connection, . scheduleTimeoutTimer( conn1ID, on: el1) )
387
387
}
388
-
388
+
389
389
func testConnectionTimeout( ) {
390
390
let elg = EmbeddedEventLoopGroup ( loops: 1 )
391
391
let el1 = elg. next ( )
392
-
392
+
393
393
// establish one idle http2 connection
394
394
let idGenerator = HTTPConnectionPool . Connection. ID. Generator ( )
395
395
var http1Conns = HTTPConnectionPool . HTTP1Connections ( maximumConcurrentConnections: 8 , generator: idGenerator)
@@ -404,20 +404,19 @@ class HTTPConnectionPool_HTTP2StateMachineTests: XCTestCase {
404
404
let connectAction = state. newHTTP2ConnectionEstablished ( conn1, maxConcurrentStreams: 100 )
405
405
XCTAssertEqual ( connectAction. request, . none)
406
406
XCTAssertEqual ( connectAction. connection, . scheduleTimeoutTimer( conn1ID, on: el1) )
407
-
408
-
407
+
409
408
// let the connection timeout
410
409
let timeoutAction = state. connectionIdleTimeout ( conn1ID)
411
410
XCTAssertEqual ( timeoutAction. request, . none)
412
411
XCTAssertEqual ( timeoutAction. connection, . closeConnection( conn1, isShutdown: . no) )
413
412
}
414
-
413
+
415
414
func testConnectionEstablishmentFailure( ) {
416
415
struct SomeError : Error , Equatable { }
417
-
416
+
418
417
let elg = EmbeddedEventLoopGroup ( loops: 1 )
419
418
let el1 = elg. next ( )
420
-
419
+
421
420
// establish one idle http2 connection
422
421
let idGenerator = HTTPConnectionPool . Connection. ID. Generator ( )
423
422
var http1Conns = HTTPConnectionPool . HTTP1Connections ( maximumConcurrentConnections: 8 , generator: idGenerator)
@@ -428,12 +427,48 @@ class HTTPConnectionPool_HTTP2StateMachineTests: XCTestCase {
428
427
requests: HTTPConnectionPool . RequestQueue ( )
429
428
)
430
429
XCTAssertEqual ( migrationAction, . none)
431
-
430
+
432
431
let action = state. failedToCreateNewConnection ( SomeError ( ) , connectionID: conn1ID)
433
432
XCTAssertEqual ( action. request, . none)
434
433
guard case . scheduleBackoffTimer( conn1ID, _, let eventLoop) = action. connection else {
435
434
return XCTFail ( " unexpected connection action \( action. connection) " )
436
435
}
437
436
XCTAssertEqual ( eventLoop. id, el1. id)
438
437
}
438
+
439
+ func testGoAway( ) {
440
+ let elg = EmbeddedEventLoopGroup ( loops: 1 )
441
+ let el1 = elg. next ( )
442
+
443
+ // establish one idle http2 connection
444
+ let idGenerator = HTTPConnectionPool . Connection. ID. Generator ( )
445
+ var http1Conns = HTTPConnectionPool . HTTP1Connections ( maximumConcurrentConnections: 8 , generator: idGenerator)
446
+ let conn1ID = http1Conns. createNewConnection ( on: el1)
447
+ var state = HTTPConnectionPool . HTTP2StateMachine ( idGenerator: idGenerator)
448
+ let migrationAction = state. migrateConnectionsFromHTTP1 (
449
+ connections: http1Conns,
450
+ requests: HTTPConnectionPool . RequestQueue ( )
451
+ )
452
+ XCTAssertEqual ( migrationAction, . none)
453
+ let conn1 = HTTPConnectionPool . Connection. __testOnly_connection ( id: conn1ID, eventLoop: el1)
454
+ let connectAction = state. newHTTP2ConnectionEstablished ( conn1, maxConcurrentStreams: 100 )
455
+ XCTAssertEqual ( connectAction. request, . none)
456
+ XCTAssertEqual ( connectAction. connection, . scheduleTimeoutTimer( conn1ID, on: el1) )
457
+
458
+ // execute request on idle connection
459
+ let mockRequest1 = MockHTTPRequest ( eventLoop: el1)
460
+ let request1 = HTTPConnectionPool . Request ( mockRequest1)
461
+ let request1Action = state. executeRequest ( request1)
462
+ XCTAssertEqual ( request1Action. request, . executeRequest( request1, conn1, cancelTimeout: false ) )
463
+ XCTAssertEqual ( request1Action. connection, . cancelTimeoutTimer( conn1ID) )
464
+
465
+ let goAwayAction = state. http2ConnectionGoAwayReceived ( conn1ID)
466
+ XCTAssertEqual ( goAwayAction. request, . none)
467
+ XCTAssertEqual ( goAwayAction. connection, . none)
468
+
469
+ // close stream
470
+ let closeStream1Action = state. http2ConnectionStreamClosed ( conn1ID)
471
+ XCTAssertEqual ( closeStream1Action. request, . none)
472
+ XCTAssertEqual ( closeStream1Action. connection, . closeConnection( conn1, isShutdown: . no) )
473
+ }
439
474
}
0 commit comments