@@ -4326,28 +4326,54 @@ final class HTTPClientTests: XCTestCaseHTTPClientTestsBaseClass {
43264326 config. tlsConfiguration? . certificateVerification = . none
43274327 }
43284328
4329- let client = HTTPClient (
4329+ let higherConnectTimeout = CountingDebugInitializerUtil . duration + . milliseconds( 100 )
4330+ var configWithHigherTimeout = config
4331+ configWithHigherTimeout. timeout = . init( connect: higherConnectTimeout)
4332+
4333+ let clientWithHigherTimeout = HTTPClient (
43304334 eventLoopGroupProvider: . singleton,
4331- configuration: config ,
4335+ configuration: configWithHigherTimeout ,
43324336 backgroundActivityLogger: Logger (
43334337 label: " HTTPClient " ,
43344338 factory: StreamLogHandler . standardOutput ( label: )
43354339 )
43364340 )
4337- defer { XCTAssertNoThrow ( client . shutdown ( ) ) }
4341+ defer { XCTAssertNoThrow ( try clientWithHigherTimeout . syncShutdown ( ) ) }
43384342
43394343 let bin = HTTPBin ( . http1_1( ssl: ssl, compress: false ) )
43404344 defer { XCTAssertNoThrow ( try bin. shutdown ( ) ) }
43414345
43424346 let scheme = ssl ? " https " : " http "
43434347
43444348 for _ in 0 ..< 3 {
4345- XCTAssertNoThrow ( try client. get ( url: " \( scheme) ://localhost: \( bin. port) /get " ) . wait ( ) )
4349+ XCTAssertNoThrow (
4350+ try clientWithHigherTimeout. get ( url: " \( scheme) ://localhost: \( bin. port) /get " ) . wait ( )
4351+ )
43464352 }
43474353
43484354 // Even though multiple requests were made, the connection debug initializer must be called
43494355 // only once.
43504356 XCTAssertEqual ( connectionDebugInitializerUtil. executionCount, 1 )
4357+
4358+ let lowerConnectTimeout = CountingDebugInitializerUtil . duration - . milliseconds( 100 )
4359+ var configWithLowerTimeout = config
4360+ configWithLowerTimeout. timeout = . init( connect: lowerConnectTimeout)
4361+
4362+ let clientWithLowerTimeout = HTTPClient (
4363+ eventLoopGroupProvider: . singleton,
4364+ configuration: configWithLowerTimeout,
4365+ backgroundActivityLogger: Logger (
4366+ label: " HTTPClient " ,
4367+ factory: StreamLogHandler . standardOutput ( label: )
4368+ )
4369+ )
4370+ defer { XCTAssertNoThrow ( try clientWithLowerTimeout. syncShutdown ( ) ) }
4371+
4372+ XCTAssertThrowsError (
4373+ try clientWithLowerTimeout. get ( url: " \( scheme) ://localhost: \( bin. port) /get " ) . wait ( )
4374+ ) {
4375+ XCTAssertEqual ( $0 as? HTTPClientError , . connectTimeout)
4376+ }
43514377 }
43524378
43534379 func testHTTP1PlainTextConnectionDebugInitializer( ) {
@@ -4378,23 +4404,29 @@ final class HTTPClientTests: XCTestCaseHTTPClientTestsBaseClass {
43784404 config. tlsConfiguration? . certificateVerification = . none
43794405 config. httpVersion = . automatic
43804406
4381- let client = HTTPClient (
4407+ let higherConnectTimeout = CountingDebugInitializerUtil . duration + . milliseconds( 100 )
4408+ var configWithHigherTimeout = config
4409+ configWithHigherTimeout. timeout = . init( connect: higherConnectTimeout)
4410+
4411+ let clientWithHigherTimeout = HTTPClient (
43824412 eventLoopGroupProvider: . singleton,
4383- configuration: config ,
4413+ configuration: configWithHigherTimeout ,
43844414 backgroundActivityLogger: Logger (
43854415 label: " HTTPClient " ,
43864416 factory: StreamLogHandler . standardOutput ( label: )
43874417 )
43884418 )
4389- defer { XCTAssertNoThrow ( client . shutdown ( ) ) }
4419+ defer { XCTAssertNoThrow ( try clientWithHigherTimeout . syncShutdown ( ) ) }
43904420
43914421 let bin = HTTPBin ( . http2( compress: false ) )
43924422 defer { XCTAssertNoThrow ( try bin. shutdown ( ) ) }
43934423
43944424 let numberOfRequests = 3
43954425
43964426 for _ in 0 ..< numberOfRequests {
4397- XCTAssertNoThrow ( try client. get ( url: " https://localhost: \( bin. port) /get " ) . wait ( ) )
4427+ XCTAssertNoThrow (
4428+ try clientWithHigherTimeout. get ( url: " https://localhost: \( bin. port) /get " ) . wait ( )
4429+ )
43984430 }
43994431
44004432 // Even though multiple requests were made, the connection debug initializer must be called
@@ -4404,21 +4436,44 @@ final class HTTPClientTests: XCTestCaseHTTPClientTestsBaseClass {
44044436 // The stream channel debug initializer must be called only as much as the number of
44054437 // requests made.
44064438 XCTAssertEqual ( streamChannelDebugInitializerUtil. executionCount, numberOfRequests)
4439+
4440+ let lowerConnectTimeout = CountingDebugInitializerUtil . duration - . milliseconds( 100 )
4441+ var configWithLowerTimeout = config
4442+ configWithLowerTimeout. timeout = . init( connect: lowerConnectTimeout)
4443+
4444+ let clientWithLowerTimeout = HTTPClient (
4445+ eventLoopGroupProvider: . singleton,
4446+ configuration: configWithLowerTimeout,
4447+ backgroundActivityLogger: Logger (
4448+ label: " HTTPClient " ,
4449+ factory: StreamLogHandler . standardOutput ( label: )
4450+ )
4451+ )
4452+ defer { XCTAssertNoThrow ( try clientWithLowerTimeout. syncShutdown ( ) ) }
4453+
4454+ XCTAssertThrowsError (
4455+ try clientWithLowerTimeout. get ( url: " https://localhost: \( bin. port) /get " ) . wait ( )
4456+ ) {
4457+ XCTAssertEqual ( $0 as? HTTPClientError , . connectTimeout)
4458+ }
44074459 }
44084460}
44094461
44104462final class CountingDebugInitializerUtil : Sendable {
4411- private let _executionCount : NIOLockedValueBox < Int >
4463+ private let _executionCount = NIOLockedValueBox < Int > ( 0 )
44124464 var executionCount : Int { self . _executionCount. withLockedValue { $0 } }
44134465
4466+ /// The minimum time to spend running the debug initializer.
4467+ static let duration : TimeAmount = . milliseconds( 300 )
4468+
44144469 /// The actual debug initializer.
44154470 func initialize( channel: Channel ) -> EventLoopFuture < Void > {
44164471 self . _executionCount. withLockedValue { $0 += 1 }
44174472
4418- return channel. eventLoop. makeSucceededVoidFuture ( )
4419- }
4473+ let someScheduledTask = channel. eventLoop. scheduleTask ( in: Self . duration) {
4474+ return channel. eventLoop. makeSucceededVoidFuture ( )
4475+ }
44204476
4421- init ( ) {
4422- self . _executionCount = . init( 0 )
4477+ return someScheduledTask. futureResult. flatMap { $0 }
44234478 }
44244479}
0 commit comments