diff --git a/Tests/AsyncHTTPClientTests/HTTPClientInternalTests+XCTest.swift b/Tests/AsyncHTTPClientTests/HTTPClientInternalTests+XCTest.swift index 06f9b4228..a66cfcbf2 100644 --- a/Tests/AsyncHTTPClientTests/HTTPClientInternalTests+XCTest.swift +++ b/Tests/AsyncHTTPClientTests/HTTPClientInternalTests+XCTest.swift @@ -35,6 +35,7 @@ extension HTTPClientInternalTests { ("testChannelAndDelegateOnDifferentEventLoops", testChannelAndDelegateOnDifferentEventLoops), ("testResponseConnectionCloseGet", testResponseConnectionCloseGet), ("testWeNoticeRemoteClosuresEvenWhenConnectionIsIdleInPool", testWeNoticeRemoteClosuresEvenWhenConnectionIsIdleInPool), + ("testWeTolerateConnectionsGoingAwayWhilstPoolIsShuttingDown", testWeTolerateConnectionsGoingAwayWhilstPoolIsShuttingDown), ] } } diff --git a/Tests/AsyncHTTPClientTests/HTTPClientInternalTests.swift b/Tests/AsyncHTTPClientTests/HTTPClientInternalTests.swift index d2124171e..b36207245 100644 --- a/Tests/AsyncHTTPClientTests/HTTPClientInternalTests.swift +++ b/Tests/AsyncHTTPClientTests/HTTPClientInternalTests.swift @@ -581,4 +581,43 @@ class HTTPClientInternalTests: XCTestCase { XCTAssertEqual(2, sharedStateServerHandler.connectionNumber.load()) XCTAssertEqual(2, sharedStateServerHandler.requestNumber.load()) } + + func testWeTolerateConnectionsGoingAwayWhilstPoolIsShuttingDown() { + struct NoChannelError: Error {} + + let client = HTTPClient(eventLoopGroupProvider: .createNew) + var maybeServersAndChannels: [(HTTPBin, Channel)]? + XCTAssertNoThrow(maybeServersAndChannels = try (0..<10).map { _ in + let web = HTTPBin() + + let req = try! HTTPClient.Request(url: "http://localhost:\(web.serverChannel.localAddress!.port!)/get", + method: .GET, + body: nil) + var maybeConnection: ConnectionPool.Connection? + XCTAssertNoThrow(try maybeConnection = client.pool.getConnection(for: req, + preference: .indifferent, + on: client.eventLoopGroup.next(), + deadline: nil).wait()) + guard let connection = maybeConnection else { + XCTFail("couldn't make connection") + throw NoChannelError() + } + + let channel = connection.channel + client.pool.release(connection) + return (web, channel) + }) + + guard let serversAndChannels = maybeServersAndChannels else { + XCTFail("couldn't open servers") + return + } + + DispatchQueue.global().async { + serversAndChannels.forEach { serverAndChannel in + serverAndChannel.1.close(promise: nil) + } + } + XCTAssertNoThrow(try client.syncShutdown()) + } }