Skip to content

Speedup tests #639

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Oct 11, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions Tests/AsyncHTTPClientTests/AsyncAwaitEndToEndTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -497,8 +497,9 @@ final class AsyncAwaitEndToEndTests: XCTestCase {
defer { XCTAssertNoThrow(try serverChannel.close().wait()) }
let port = serverChannel.localAddress!.port!

var config = HTTPClient.Configuration()
config.timeout.connect = .seconds(3)
let config = HTTPClient.Configuration()
.enableFastFailureModeForTesting()

let localClient = HTTPClient(eventLoopGroupProvider: .createNew, configuration: config)
defer { XCTAssertNoThrow(try localClient.syncShutdown()) }
let request = HTTPClientRequest(url: "https://localhost:\(port)")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
//===----------------------------------------------------------------------===//
//
// This source file is part of the AsyncHTTPClient open source project
//
// Copyright (c) 2018-2019 Apple Inc. and the AsyncHTTPClient project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
// See CONTRIBUTORS.txt for the list of AsyncHTTPClient project authors
//
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//
//
// ConnectionPoolSizeConfigValueIsRespectedTests+XCTest.swift
//
import XCTest

///
/// NOTE: This file was generated by generate_linux_tests.rb
///
/// Do NOT edit this file directly as it will be regenerated automatically when needed.
///

extension ConnectionPoolSizeConfigValueIsRespectedTests {
static var allTests: [(String, (ConnectionPoolSizeConfigValueIsRespectedTests) -> () throws -> Void)] {
return [
("testConnectionPoolSizeConfigValueIsRespected", testConnectionPoolSizeConfigValueIsRespected),
]
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
//===----------------------------------------------------------------------===//
//
// This source file is part of the AsyncHTTPClient open source project
//
// Copyright (c) 2022 Apple Inc. and the AsyncHTTPClient project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
// See CONTRIBUTORS.txt for the list of AsyncHTTPClient project authors
//
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//

import AsyncHTTPClient
import Atomics
#if canImport(Network)
import Network
#endif
import Logging
import NIOConcurrencyHelpers
import NIOCore
import NIOFoundationCompat
import NIOHTTP1
import NIOHTTPCompression
import NIOPosix
import NIOSSL
import NIOTestUtils
import NIOTransportServices
import XCTest

final class ConnectionPoolSizeConfigValueIsRespectedTests: XCTestCaseHTTPClientTestsBaseClass {
func testConnectionPoolSizeConfigValueIsRespected() {
let numberOfRequestsPerThread = 1000
let numberOfParallelWorkers = 16
let poolSize = 12

let httpBin = HTTPBin()
defer { XCTAssertNoThrow(try httpBin.shutdown()) }

let group = MultiThreadedEventLoopGroup(numberOfThreads: 4)
defer { XCTAssertNoThrow(try group.syncShutdownGracefully()) }

let configuration = HTTPClient.Configuration(
connectionPool: .init(
idleTimeout: .seconds(30),
concurrentHTTP1ConnectionsPerHostSoftLimit: poolSize
)
)
let client = HTTPClient(eventLoopGroupProvider: .shared(group), configuration: configuration)
defer { XCTAssertNoThrow(try client.syncShutdown()) }

let g = DispatchGroup()
for workerID in 0..<numberOfParallelWorkers {
DispatchQueue(label: "\(#file):\(#line):worker-\(workerID)").async(group: g) {
func makeRequest() {
let url = "http://127.0.0.1:\(httpBin.port)"
XCTAssertNoThrow(try client.get(url: url).wait())
}
for _ in 0..<numberOfRequestsPerThread {
makeRequest()
}
}
}
let timeout = DispatchTime.now() + .seconds(60)
switch g.wait(timeout: timeout) {
case .success:
break
case .timedOut:
XCTFail("Timed out")
}

XCTAssertEqual(httpBin.createdConnections, poolSize)
}
}
2 changes: 1 addition & 1 deletion Tests/AsyncHTTPClientTests/HTTP2ClientTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -287,7 +287,7 @@ class HTTP2ClientTests: XCTestCase {
)

XCTAssertThrowsError(try task.futureResult.timeout(after: .seconds(2)).wait()) {
XCTAssertEqual($0 as? HTTPClientError, .cancelled)
XCTAssertEqualTypeAndValue($0, HTTPClientError.cancelled)
}
}

Expand Down
20 changes: 11 additions & 9 deletions Tests/AsyncHTTPClientTests/HTTPClient+SOCKSTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,9 @@ class HTTPClientSOCKSTests: XCTestCase {
func testProxySOCKS() throws {
let socksBin = try MockSOCKSServer(expectedURL: "/socks/test", expectedResponse: "it works!")
let localClient = HTTPClient(eventLoopGroupProvider: .shared(self.clientGroup),
configuration: .init(proxy: .socksServer(host: "localhost", port: socksBin.port)))
configuration: .init(
proxy: .socksServer(host: "localhost", port: socksBin.port)
).enableFastFailureModeForTesting())

defer {
XCTAssertNoThrow(try localClient.syncShutdown())
Expand All @@ -90,8 +92,8 @@ class HTTPClientSOCKSTests: XCTestCase {
}

func testProxySOCKSBogusAddress() throws {
var config = HTTPClient.Configuration(proxy: .socksServer(host: "127.0.."))
config.networkFrameworkWaitForConnectivity = false
let config = HTTPClient.Configuration(proxy: .socksServer(host: "127.0.."))
.enableFastFailureModeForTesting()
let localClient = HTTPClient(eventLoopGroupProvider: .shared(self.clientGroup),
configuration: config)

Expand All @@ -104,8 +106,8 @@ class HTTPClientSOCKSTests: XCTestCase {
// there is no socks server, so we should fail
func testProxySOCKSFailureNoServer() throws {
let localHTTPBin = HTTPBin()
var config = HTTPClient.Configuration(proxy: .socksServer(host: "localhost", port: localHTTPBin.port))
config.networkFrameworkWaitForConnectivity = false
let config = HTTPClient.Configuration(proxy: .socksServer(host: "localhost", port: localHTTPBin.port))
.enableFastFailureModeForTesting()

let localClient = HTTPClient(eventLoopGroupProvider: .shared(self.clientGroup),
configuration: config)
Expand All @@ -118,8 +120,8 @@ class HTTPClientSOCKSTests: XCTestCase {

// speak to a server that doesn't speak SOCKS
func testProxySOCKSFailureInvalidServer() throws {
var config = HTTPClient.Configuration(proxy: .socksServer(host: "localhost"))
config.networkFrameworkWaitForConnectivity = false
let config = HTTPClient.Configuration(proxy: .socksServer(host: "localhost"))
.enableFastFailureModeForTesting()

let localClient = HTTPClient(eventLoopGroupProvider: .shared(self.clientGroup),
configuration: config)
Expand All @@ -132,8 +134,8 @@ class HTTPClientSOCKSTests: XCTestCase {
// test a handshake failure with a misbehaving server
func testProxySOCKSMisbehavingServer() throws {
let socksBin = try MockSOCKSServer(expectedURL: "/socks/test", expectedResponse: "it works!", misbehave: true)
var config = HTTPClient.Configuration(proxy: .socksServer(host: "localhost", port: socksBin.port))
config.networkFrameworkWaitForConnectivity = false
let config = HTTPClient.Configuration(proxy: .socksServer(host: "localhost", port: socksBin.port))
.enableFastFailureModeForTesting()

let localClient = HTTPClient(eventLoopGroupProvider: .shared(self.clientGroup),
configuration: config)
Expand Down
86 changes: 86 additions & 0 deletions Tests/AsyncHTTPClientTests/HTTPClientBase.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
//===----------------------------------------------------------------------===//
//
// This source file is part of the AsyncHTTPClient open source project
//
// Copyright (c) 2022 Apple Inc. and the AsyncHTTPClient project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
// See CONTRIBUTORS.txt for the list of AsyncHTTPClient project authors
//
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//

import AsyncHTTPClient
import Atomics
#if canImport(Network)
import Network
#endif
import Logging
import NIOConcurrencyHelpers
import NIOCore
import NIOFoundationCompat
import NIOHTTP1
import NIOHTTPCompression
import NIOPosix
import NIOSSL
import NIOTestUtils
import NIOTransportServices
import XCTest

class XCTestCaseHTTPClientTestsBaseClass: XCTestCase {
typealias Request = HTTPClient.Request

var clientGroup: EventLoopGroup!
var serverGroup: EventLoopGroup!
var defaultHTTPBin: HTTPBin<HTTPBinHandler>!
var defaultClient: HTTPClient!
var backgroundLogStore: CollectEverythingLogHandler.LogStore!

var defaultHTTPBinURLPrefix: String {
return "http://localhost:\(self.defaultHTTPBin.port)/"
}

override func setUp() {
XCTAssertNil(self.clientGroup)
XCTAssertNil(self.serverGroup)
XCTAssertNil(self.defaultHTTPBin)
XCTAssertNil(self.defaultClient)
XCTAssertNil(self.backgroundLogStore)

self.clientGroup = getDefaultEventLoopGroup(numberOfThreads: 1)
self.serverGroup = MultiThreadedEventLoopGroup(numberOfThreads: 1)
self.defaultHTTPBin = HTTPBin()
self.backgroundLogStore = CollectEverythingLogHandler.LogStore()
var backgroundLogger = Logger(label: "\(#function)", factory: { _ in
CollectEverythingLogHandler(logStore: self.backgroundLogStore!)
})
backgroundLogger.logLevel = .trace
self.defaultClient = HTTPClient(eventLoopGroupProvider: .shared(self.clientGroup),
configuration: HTTPClient.Configuration().enableFastFailureModeForTesting(),
backgroundActivityLogger: backgroundLogger)
}

override func tearDown() {
if let defaultClient = self.defaultClient {
XCTAssertNoThrow(try defaultClient.syncShutdown())
self.defaultClient = nil
}

XCTAssertNotNil(self.defaultHTTPBin)
XCTAssertNoThrow(try self.defaultHTTPBin.shutdown())
self.defaultHTTPBin = nil

XCTAssertNotNil(self.clientGroup)
XCTAssertNoThrow(try self.clientGroup.syncShutdownGracefully())
self.clientGroup = nil

XCTAssertNotNil(self.serverGroup)
XCTAssertNoThrow(try self.serverGroup.syncShutdownGracefully())
self.serverGroup = nil

XCTAssertNotNil(self.backgroundLogStore)
self.backgroundLogStore = nil
}
}
13 changes: 11 additions & 2 deletions Tests/AsyncHTTPClientTests/HTTPClientInternalTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -429,8 +429,8 @@ class HTTPClientInternalTests: XCTestCase {
let el2 = elg.next()

let httpBin = HTTPBin(.refuse)
var config = HTTPClient.Configuration()
config.networkFrameworkWaitForConnectivity = false
let config = HTTPClient.Configuration()
.enableFastFailureModeForTesting()
let client = HTTPClient(eventLoopGroupProvider: .shared(elg), configuration: config)

defer {
Expand Down Expand Up @@ -590,3 +590,12 @@ class HTTPClientInternalTests: XCTestCase {
XCTAssert(threadPools.dropFirst().allSatisfy { $0 === firstThreadPool })
}
}

extension HTTPClient.Configuration {
func enableFastFailureModeForTesting() -> Self {
var copy = self
copy.networkFrameworkWaitForConnectivity = false
copy.connectionPool.retryConnectionEstablishment = false
return copy
}
}
6 changes: 0 additions & 6 deletions Tests/AsyncHTTPClientTests/HTTPClientTests+XCTest.swift
Original file line number Diff line number Diff line change
Expand Up @@ -77,13 +77,10 @@ extension HTTPClientTests {
("testWorksWhenServerClosesConnectionAfterReceivingRequest", testWorksWhenServerClosesConnectionAfterReceivingRequest),
("testSubsequentRequestsWorkWithServerSendingConnectionClose", testSubsequentRequestsWorkWithServerSendingConnectionClose),
("testSubsequentRequestsWorkWithServerAlternatingBetweenKeepAliveAndClose", testSubsequentRequestsWorkWithServerAlternatingBetweenKeepAliveAndClose),
("testStressGetHttps", testStressGetHttps),
("testStressGetHttpsSSLError", testStressGetHttpsSSLError),
("testSelfSignedCertificateIsRejectedWithCorrectError", testSelfSignedCertificateIsRejectedWithCorrectError),
("testSelfSignedCertificateIsRejectedWithCorrectErrorIfRequestDeadlineIsExceeded", testSelfSignedCertificateIsRejectedWithCorrectErrorIfRequestDeadlineIsExceeded),
("testFailingConnectionIsReleased", testFailingConnectionIsReleased),
("testResponseDelayGet", testResponseDelayGet),
("testIdleTimeoutNoReuse", testIdleTimeoutNoReuse),
("testStressGetClose", testStressGetClose),
("testManyConcurrentRequestsWork", testManyConcurrentRequestsWork),
("testRepeatedRequestsWorkWhenServerAlwaysCloses", testRepeatedRequestsWorkWhenServerAlwaysCloses),
Expand All @@ -104,7 +101,6 @@ extension HTTPClientTests {
("testUseExistingConnectionOnDifferentEL", testUseExistingConnectionOnDifferentEL),
("testWeRecoverFromServerThatClosesTheConnectionOnUs", testWeRecoverFromServerThatClosesTheConnectionOnUs),
("testPoolClosesIdleConnections", testPoolClosesIdleConnections),
("testRacePoolIdleConnectionsAndGet", testRacePoolIdleConnectionsAndGet),
("testAvoidLeakingTLSHandshakeCompletionPromise", testAvoidLeakingTLSHandshakeCompletionPromise),
("testAsyncShutdown", testAsyncShutdown),
("testAsyncShutdownDefaultQueue", testAsyncShutdownDefaultQueue),
Expand All @@ -126,7 +122,6 @@ extension HTTPClientTests {
("testContentLengthTooLongFails", testContentLengthTooLongFails),
("testContentLengthTooShortFails", testContentLengthTooShortFails),
("testBodyUploadAfterEndFails", testBodyUploadAfterEndFails),
("testNoBytesSentOverBodyLimit", testNoBytesSentOverBodyLimit),
("testDoubleError", testDoubleError),
("testSSLHandshakeErrorPropagation", testSSLHandshakeErrorPropagation),
("testSSLHandshakeErrorPropagationDelayedClose", testSSLHandshakeErrorPropagationDelayedClose),
Expand All @@ -145,7 +140,6 @@ extension HTTPClientTests {
("testCloseWhileBackpressureIsExertedIsFine", testCloseWhileBackpressureIsExertedIsFine),
("testErrorAfterCloseWhileBackpressureExerted", testErrorAfterCloseWhileBackpressureExerted),
("testRequestSpecificTLS", testRequestSpecificTLS),
("testConnectionPoolSizeConfigValueIsRespected", testConnectionPoolSizeConfigValueIsRespected),
("testRequestWithHeaderTransferEncodingIdentityDoesNotFail", testRequestWithHeaderTransferEncodingIdentityDoesNotFail),
("testMassiveDownload", testMassiveDownload),
("testShutdownWithFutures", testShutdownWithFutures),
Expand Down
Loading