From 6be698abbb1ae26ddb630dac54989e9fff911674 Mon Sep 17 00:00:00 2001 From: David Nadoba Date: Thu, 9 Jun 2022 18:49:32 +0200 Subject: [PATCH 1/2] =?UTF-8?q?Use=20a=20local=20TCP=20server=20that=20doe?= =?UTF-8?q?sn=E2=80=99t=20accept=20connections=20on=20macOS=20for=20`testC?= =?UTF-8?q?onnectTimeout()`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../HTTPClientTests.swift | 35 ++++++++++++++++--- 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/Tests/AsyncHTTPClientTests/HTTPClientTests.swift b/Tests/AsyncHTTPClientTests/HTTPClientTests.swift index 0e5ccf63f..a29339d28 100644 --- a/Tests/AsyncHTTPClientTests/HTTPClientTests.swift +++ b/Tests/AsyncHTTPClientTests/HTTPClientTests.swift @@ -640,7 +640,35 @@ class HTTPClientTests: XCTestCase { } } - func testConnectTimeout() { + func testConnectTimeout() throws { + #if os(Linux) + // 198.51.100.254 is reserved for documentation only and therefore should not accept any TCP connection + let url = "http://198.51.100.254/get" + #else + // on macOS we can use the TCP backlog behaviour when the queue is full to simulate a non reachable server. + // this makes this test a bit more stable if `198.51.100.254` actually responds to connection attempt. + // The backlog behaviour on Linux can not be used to simulate a non-reachable server. + // Linux sends a `SYN/ACK` back even if the `backlog` queue is full as it has two queues. + // The second queue is not limit by `ChannelOptions.backlog` but by `/proc/sys/net/ipv4/tcp_max_syn_backlog`. + + let serverChannel = try ServerBootstrap(group: self.serverGroup) + .serverChannelOption(ChannelOptions.backlog, value: 1) + .serverChannelOption(ChannelOptions.autoRead, value: false) + .bind(host: "127.0.0.1", port: 0) + .wait() + defer { + XCTAssertNoThrow(try serverChannel.close().wait()) + } + let port = serverChannel.localAddress!.port! + let firstClientChannel = try ClientBootstrap(group: self.serverGroup) + .connect(host: "127.0.0.1", port: port) + .wait() + defer { + XCTAssertNoThrow(try firstClientChannel.close().wait()) + } + let url = "http://localhost:\(port)/get" + #endif + let httpClient = HTTPClient(eventLoopGroupProvider: .shared(self.clientGroup), configuration: .init(timeout: .init(connect: .milliseconds(100), read: .milliseconds(150)))) @@ -648,9 +676,8 @@ class HTTPClientTests: XCTestCase { XCTAssertNoThrow(try httpClient.syncShutdown()) } - // This must throw as 198.51.100.254 is reserved for documentation only - XCTAssertThrowsError(try httpClient.get(url: "http://198.51.100.254/get").wait()) { - XCTAssertEqual($0 as? HTTPClientError, .connectTimeout) + XCTAssertThrowsError(try httpClient.get(url: url).wait()) { + XCTAssertEqualTypeAndValue($0, HTTPClientError.connectTimeout) } } From f6748f28a2aaa00af31bf80105c908ddaebdf921 Mon Sep 17 00:00:00 2001 From: David Nadoba Date: Thu, 9 Jun 2022 18:56:37 +0200 Subject: [PATCH 2/2] fix linting --- Tests/AsyncHTTPClientTests/HTTPClientTests.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Tests/AsyncHTTPClientTests/HTTPClientTests.swift b/Tests/AsyncHTTPClientTests/HTTPClientTests.swift index a29339d28..726809415 100644 --- a/Tests/AsyncHTTPClientTests/HTTPClientTests.swift +++ b/Tests/AsyncHTTPClientTests/HTTPClientTests.swift @@ -650,7 +650,7 @@ class HTTPClientTests: XCTestCase { // The backlog behaviour on Linux can not be used to simulate a non-reachable server. // Linux sends a `SYN/ACK` back even if the `backlog` queue is full as it has two queues. // The second queue is not limit by `ChannelOptions.backlog` but by `/proc/sys/net/ipv4/tcp_max_syn_backlog`. - + let serverChannel = try ServerBootstrap(group: self.serverGroup) .serverChannelOption(ChannelOptions.backlog, value: 1) .serverChannelOption(ChannelOptions.autoRead, value: false) @@ -668,7 +668,7 @@ class HTTPClientTests: XCTestCase { } let url = "http://localhost:\(port)/get" #endif - + let httpClient = HTTPClient(eventLoopGroupProvider: .shared(self.clientGroup), configuration: .init(timeout: .init(connect: .milliseconds(100), read: .milliseconds(150))))