Skip to content

Commit 0f21b44

Browse files
authored
Use a local TCP server that doesn’t accept connections on macOS for testConnectTimeout() (#592)
* Use a local TCP server that doesn’t accept connections on macOS for `testConnectTimeout()` * fix linting
1 parent 2483e08 commit 0f21b44

File tree

1 file changed

+31
-4
lines changed

1 file changed

+31
-4
lines changed

Tests/AsyncHTTPClientTests/HTTPClientTests.swift

+31-4
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)