@@ -640,17 +640,44 @@ class HTTPClientTests: XCTestCase {
640640 }
641641 }
642642
643- func testConnectTimeout( ) {
643+ func testConnectTimeout( ) throws {
644+ #if os(Linux)
645+ // 198.51.100.254 is reserved for documentation only and therefore should not accept any TCP connection
646+ let url = " http://198.51.100.254/get "
647+ #else
648+ // on macOS we can use the TCP backlog behaviour when the queue is full to simulate a non reachable server.
649+ // this makes this test a bit more stable if `198.51.100.254` actually responds to connection attempt.
650+ // The backlog behaviour on Linux can not be used to simulate a non-reachable server.
651+ // Linux sends a `SYN/ACK` back even if the `backlog` queue is full as it has two queues.
652+ // The second queue is not limit by `ChannelOptions.backlog` but by `/proc/sys/net/ipv4/tcp_max_syn_backlog`.
653+
654+ let serverChannel = try ServerBootstrap ( group: self . serverGroup)
655+ . serverChannelOption ( ChannelOptions . backlog, value: 1 )
656+ . serverChannelOption ( ChannelOptions . autoRead, value: false )
657+ . bind ( host: " 127.0.0.1 " , port: 0 )
658+ . wait ( )
659+ defer {
660+ XCTAssertNoThrow ( try serverChannel. close ( ) . wait ( ) )
661+ }
662+ let port = serverChannel. localAddress!. port!
663+ let firstClientChannel = try ClientBootstrap ( group: self . serverGroup)
664+ . connect ( host: " 127.0.0.1 " , port: port)
665+ . wait ( )
666+ defer {
667+ XCTAssertNoThrow ( try firstClientChannel. close ( ) . wait ( ) )
668+ }
669+ let url = " http://localhost: \( port) /get "
670+ #endif
671+
644672 let httpClient = HTTPClient ( eventLoopGroupProvider: . shared( self . clientGroup) ,
645673 configuration: . init( timeout: . init( connect: . milliseconds( 100 ) , read: . milliseconds( 150 ) ) ) )
646674
647675 defer {
648676 XCTAssertNoThrow ( try httpClient. syncShutdown ( ) )
649677 }
650678
651- // This must throw as 198.51.100.254 is reserved for documentation only
652- XCTAssertThrowsError ( try httpClient. get ( url: " http://198.51.100.254/get " ) . wait ( ) ) {
653- XCTAssertEqual ( $0 as? HTTPClientError , . connectTimeout)
679+ XCTAssertThrowsError ( try httpClient. get ( url: url) . wait ( ) ) {
680+ XCTAssertEqualTypeAndValue ( $0, HTTPClientError . connectTimeout)
654681 }
655682 }
656683
0 commit comments