From 905dddc76f51555153718e0f1572eb5cd4c24afd Mon Sep 17 00:00:00 2001 From: Gus Cairo Date: Tue, 16 Jul 2024 11:07:57 +0100 Subject: [PATCH] Turn tests into variants instead of duplicating them --- .../test_client_server_request_response.swift | 67 +++++++- ...ponse_no_promise_on_channel_creation.swift | 158 ------------------ docker/docker-compose.2204.510.yaml | 8 +- docker/docker-compose.2204.58.yaml | 8 +- docker/docker-compose.2204.59.yaml | 8 +- docker/docker-compose.2204.main.yaml | 8 +- 6 files changed, 77 insertions(+), 180 deletions(-) delete mode 100644 IntegrationTests/tests_01_allocation_counters/test_01_resources/test_client_server_request_response_no_promise_on_channel_creation.swift diff --git a/IntegrationTests/tests_01_allocation_counters/test_01_resources/test_client_server_request_response.swift b/IntegrationTests/tests_01_allocation_counters/test_01_resources/test_client_server_request_response.swift index 25bdeb7b..b4082f7d 100644 --- a/IntegrationTests/tests_01_allocation_counters/test_01_resources/test_client_server_request_response.swift +++ b/IntegrationTests/tests_01_allocation_counters/test_01_resources/test_client_server_request_response.swift @@ -89,6 +89,16 @@ func run(identifier: String) { }.wait() } + testRun(identifier: identifier + "_no_promise_based_API", usePromiseBasedAPI: false) { clientChannel in + return try! clientChannel.configureHTTP2Pipeline(mode: .client) { channel in + return channel.eventLoop.makeSucceededVoidFuture() + }.wait() + } serverPipelineConfigurator: { serverChannel in + _ = try! serverChannel.configureHTTP2Pipeline(mode: .server) { channel in + return channel.pipeline.addHandler(ServerHandler()) + }.wait() + } + testRun(identifier: identifier + "_many", dataBlockCount: 100, dataBlockLengthBytes: 1000) { clientChannel in return try! clientChannel.configureHTTP2Pipeline(mode: .client) { channel in return channel.eventLoop.makeSucceededVoidFuture() @@ -99,7 +109,16 @@ func run(identifier: String) { }.wait() } - // + testRun(identifier: identifier + "_many_no_promise_based_API", dataBlockCount: 100, dataBlockLengthBytes: 1000, usePromiseBasedAPI: false) { clientChannel in + return try! clientChannel.configureHTTP2Pipeline(mode: .client) { channel in + return channel.eventLoop.makeSucceededVoidFuture() + }.wait() + } serverPipelineConfigurator: { serverChannel in + _ = try! serverChannel.configureHTTP2Pipeline(mode: .server) { channel in + return channel.pipeline.addHandler(ServerHandler()) + }.wait() + } + // MARK: - Inline HTTP2 multiplexer tests testRun(identifier: identifier + "_inline") { clientChannel in return try! clientChannel.configureHTTP2Pipeline(mode: .client, connectionConfiguration: .init(), streamConfiguration: .init()) { channel in @@ -111,6 +130,16 @@ func run(identifier: String) { }.wait() } + testRun(identifier: identifier + "_inline_no_promise_based_API", usePromiseBasedAPI: false) { clientChannel in + return try! clientChannel.configureHTTP2Pipeline(mode: .client, connectionConfiguration: .init(), streamConfiguration: .init()) { channel in + return channel.eventLoop.makeSucceededVoidFuture() + }.wait() + } serverPipelineConfigurator: { serverChannel in + _ = try! serverChannel.configureHTTP2Pipeline(mode: .server, connectionConfiguration: .init(), streamConfiguration: .init()) { channel in + return channel.pipeline.addHandler(ServerHandler()) + }.wait() + } + testRun(identifier: identifier + "_many_inline", dataBlockCount: 100, dataBlockLengthBytes: 1000) { clientChannel in return try! clientChannel.configureHTTP2Pipeline(mode: .client, connectionConfiguration: .init(), streamConfiguration: .init()) { channel in return channel.eventLoop.makeSucceededVoidFuture() @@ -120,9 +149,26 @@ func run(identifier: String) { return channel.pipeline.addHandler(ServerHandler()) }.wait() } + + testRun(identifier: identifier + "_many_inline_no_promise_based_API", dataBlockCount: 100, dataBlockLengthBytes: 1000, usePromiseBasedAPI: false) { clientChannel in + return try! clientChannel.configureHTTP2Pipeline(mode: .client, connectionConfiguration: .init(), streamConfiguration: .init()) { channel in + return channel.eventLoop.makeSucceededVoidFuture() + }.wait() + } serverPipelineConfigurator: { serverChannel in + _ = try! serverChannel.configureHTTP2Pipeline(mode: .server, connectionConfiguration: .init(), streamConfiguration: .init()) { channel in + return channel.pipeline.addHandler(ServerHandler()) + }.wait() + } } -private func testRun(identifier: String, dataBlockCount: Int = 0, dataBlockLengthBytes: Int = 0, clientPipelineConfigurator: (Channel) throws -> MultiplexerChannelCreator, serverPipelineConfigurator: (Channel) throws -> ()) { +private func testRun( + identifier: String, + dataBlockCount: Int = 0, + dataBlockLengthBytes: Int = 0, + usePromiseBasedAPI: Bool = true, + clientPipelineConfigurator: (Channel) throws -> MultiplexerChannelCreator, + serverPipelineConfigurator: (Channel) throws -> () +) { let loop = EmbeddedEventLoop() measure(identifier: identifier) { @@ -137,12 +183,21 @@ private func testRun(identifier: String, dataBlockCount: Int = 0, dataBlockLengt try! clientChannel.connect(to: SocketAddress(ipAddress: "1.2.3.4", port: 5678)).wait() try! serverChannel.connect(to: SocketAddress(ipAddress: "1.2.3.4", port: 5678)).wait() - let promise = clientChannel.eventLoop.makePromise(of: Channel.self) - clientMultiplexer.createStreamChannel(promise: promise) { channel in - return channel.pipeline.addHandler(ClientHandler(dataBlockCount: dataBlockCount, dataBlockLengthBytes: dataBlockLengthBytes)) + let channelFuture: EventLoopFuture + if usePromiseBasedAPI { + let promise = clientChannel.eventLoop.makePromise(of: Channel.self) + clientMultiplexer.createStreamChannel(promise: promise) { channel in + return channel.pipeline.addHandler(ClientHandler(dataBlockCount: dataBlockCount, dataBlockLengthBytes: dataBlockLengthBytes)) + } + channelFuture = promise.futureResult + } else { + channelFuture = clientMultiplexer.createStreamChannel { channel in + return channel.pipeline.addHandler(ClientHandler(dataBlockCount: dataBlockCount, dataBlockLengthBytes: dataBlockLengthBytes)) + } } + clientChannel.embeddedEventLoop.run() - let child = try! promise.futureResult.wait() + let child = try! channelFuture.wait() let streamID = try! Int(child.getOption(HTTP2StreamChannelOptions.streamID).wait()) sumOfStreamIDs += streamID diff --git a/IntegrationTests/tests_01_allocation_counters/test_01_resources/test_client_server_request_response_no_promise_on_channel_creation.swift b/IntegrationTests/tests_01_allocation_counters/test_01_resources/test_client_server_request_response_no_promise_on_channel_creation.swift deleted file mode 100644 index 6ea4724e..00000000 --- a/IntegrationTests/tests_01_allocation_counters/test_01_resources/test_client_server_request_response_no_promise_on_channel_creation.swift +++ /dev/null @@ -1,158 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the SwiftNIO open source project -// -// Copyright (c) 2019-2023 Apple Inc. and the SwiftNIO project authors -// Licensed under Apache License v2.0 -// -// See LICENSE.txt for license information -// See CONTRIBUTORS.txt for the list of SwiftNIO project authors -// -// SPDX-License-Identifier: Apache-2.0 -// -//===----------------------------------------------------------------------===// - -import NIOCore -import NIOEmbedded -import NIOHPACK -import NIOHTTP1 -import NIOHTTP2 - -final class ServerHandler: ChannelInboundHandler { - typealias InboundIn = HTTP2Frame.FramePayload - typealias OutboundOut = HTTP2Frame.FramePayload - - func channelRead(context: ChannelHandlerContext, data: NIOAny) { - let payload = self.unwrapInboundIn(data) - switch payload { - case .headers(let headers) where headers.endStream: - break - case .data(let data) where data.endStream: - break - default: - // Ignore this frame - return - } - - // We got END_STREAM. Let's send a response. - let headers = HPACKHeaders([(":status", "200")]) - let responseFramePayload = HTTP2Frame.FramePayload.headers(.init(headers: headers, endStream: true)) - context.writeAndFlush(self.wrapOutboundOut(responseFramePayload), promise: nil) - } -} - - -final class ClientHandler: ChannelInboundHandler { - typealias InboundIn = HTTP2Frame.FramePayload - typealias OutboundOut = HTTP2Frame.FramePayload - - let dataBlockCount: Int - let dataBlockLengthBytes: Int - - init(dataBlockCount: Int, dataBlockLengthBytes: Int) { - self.dataBlockCount = dataBlockCount - self.dataBlockLengthBytes = dataBlockLengthBytes - } - - func channelActive(context: ChannelHandlerContext) { - // Send a request. - let headers = HPACKHeaders([(":path", "/"), - (":authority", "localhost"), - (":method", "GET"), - (":scheme", "https")]) - - if self.dataBlockCount > 0 { - let requestFramePayload = HTTP2Frame.FramePayload.headers(.init(headers: headers, endStream: false)) - context.write(self.wrapOutboundOut(requestFramePayload), promise: nil) - - let buffer = ByteBuffer(repeating: 0, count: self.dataBlockLengthBytes) - - for _ in 0 ..< self.dataBlockCount-1 { - context.write(self.wrapOutboundOut(HTTP2Frame.FramePayload.data(.init(data: .byteBuffer(buffer), endStream: false))), promise: nil) - } - context.writeAndFlush(self.wrapOutboundOut(HTTP2Frame.FramePayload.data(.init(data: .byteBuffer(buffer), endStream: true))), promise: nil) - } else { - let requestFramePayload = HTTP2Frame.FramePayload.headers(.init(headers: headers, endStream: true)) - context.writeAndFlush(self.wrapOutboundOut(requestFramePayload), promise: nil) - } - } -} - -func run(identifier: String) { - testRun(identifier: identifier) { clientChannel in - return try! clientChannel.configureHTTP2Pipeline(mode: .client) { channel in - return channel.eventLoop.makeSucceededVoidFuture() - }.wait() - } serverPipelineConfigurator: { serverChannel in - _ = try! serverChannel.configureHTTP2Pipeline(mode: .server) { channel in - return channel.pipeline.addHandler(ServerHandler()) - }.wait() - } - - testRun(identifier: identifier + "_many", dataBlockCount: 100, dataBlockLengthBytes: 1000) { clientChannel in - return try! clientChannel.configureHTTP2Pipeline(mode: .client) { channel in - return channel.eventLoop.makeSucceededVoidFuture() - }.wait() - } serverPipelineConfigurator: { serverChannel in - _ = try! serverChannel.configureHTTP2Pipeline(mode: .server) { channel in - return channel.pipeline.addHandler(ServerHandler()) - }.wait() - } - - // - // MARK: - Inline HTTP2 multiplexer tests - testRun(identifier: identifier + "_inline") { clientChannel in - return try! clientChannel.configureHTTP2Pipeline(mode: .client, connectionConfiguration: .init(), streamConfiguration: .init()) { channel in - return channel.eventLoop.makeSucceededVoidFuture() - }.wait() - } serverPipelineConfigurator: { serverChannel in - _ = try! serverChannel.configureHTTP2Pipeline(mode: .server, connectionConfiguration: .init(), streamConfiguration: .init()) { channel in - return channel.pipeline.addHandler(ServerHandler()) - }.wait() - } - - testRun(identifier: identifier + "_many_inline", dataBlockCount: 100, dataBlockLengthBytes: 1000) { clientChannel in - return try! clientChannel.configureHTTP2Pipeline(mode: .client, connectionConfiguration: .init(), streamConfiguration: .init()) { channel in - return channel.eventLoop.makeSucceededVoidFuture() - }.wait() - } serverPipelineConfigurator: { serverChannel in - _ = try! serverChannel.configureHTTP2Pipeline(mode: .server, connectionConfiguration: .init(), streamConfiguration: .init()) { channel in - return channel.pipeline.addHandler(ServerHandler()) - }.wait() - } -} - -private func testRun(identifier: String, dataBlockCount: Int = 0, dataBlockLengthBytes: Int = 0, clientPipelineConfigurator: (Channel) throws -> MultiplexerChannelCreator, serverPipelineConfigurator: (Channel) throws -> ()) { - let loop = EmbeddedEventLoop() - - measure(identifier: identifier) { - var sumOfStreamIDs = 0 - - for _ in 0..<1000 { - let clientChannel = EmbeddedChannel(loop: loop) - let serverChannel = EmbeddedChannel(loop: loop) - - let clientMultiplexer = try! clientPipelineConfigurator(clientChannel) - try! serverPipelineConfigurator(serverChannel) - try! clientChannel.connect(to: SocketAddress(ipAddress: "1.2.3.4", port: 5678)).wait() - try! serverChannel.connect(to: SocketAddress(ipAddress: "1.2.3.4", port: 5678)).wait() - - let channelFuture = clientMultiplexer.createStreamChannel { channel in - return channel.pipeline.addHandler(ClientHandler(dataBlockCount: dataBlockCount, dataBlockLengthBytes: dataBlockLengthBytes)) - } - clientChannel.embeddedEventLoop.run() - let child = try! channelFuture.wait() - let streamID = try! Int(child.getOption(HTTP2StreamChannelOptions.streamID).wait()) - - sumOfStreamIDs += streamID - try! interactInMemory(clientChannel, serverChannel) - try! child.closeFuture.wait() - - try! clientChannel.close().wait() - try! serverChannel.close().wait() - } - - return sumOfStreamIDs - } -} - diff --git a/docker/docker-compose.2204.510.yaml b/docker/docker-compose.2204.510.yaml index c70e6109..29d01423 100644 --- a/docker/docker-compose.2204.510.yaml +++ b/docker/docker-compose.2204.510.yaml @@ -36,12 +36,12 @@ services: - MAX_ALLOCS_ALLOWED_client_server_h1_request_response_inline=269050 - MAX_ALLOCS_ALLOWED_client_server_request_response=253050 - MAX_ALLOCS_ALLOWED_client_server_request_response_inline=244050 + - MAX_ALLOCS_ALLOWED_client_server_request_response_inline_no_promise_based_API=251050 - MAX_ALLOCS_ALLOWED_client_server_request_response_many=1198050 - MAX_ALLOCS_ALLOWED_client_server_request_response_many_inline=889050 - - MAX_ALLOCS_ALLOWED_client_server_request_response_no_promise_on_channel_creation=253050 - - MAX_ALLOCS_ALLOWED_client_server_request_response_no_promise_on_channel_creation_inline=251050 - - MAX_ALLOCS_ALLOWED_client_server_request_response_no_promise_on_channel_creation_many=1198050 - - MAX_ALLOCS_ALLOWED_client_server_request_response_no_promise_on_channel_creation_many_inline=896050 + - MAX_ALLOCS_ALLOWED_client_server_request_response_many_inline_no_promise_based_API=896050 + - MAX_ALLOCS_ALLOWED_client_server_request_response_many_no_promise_based_API=1198050 + - MAX_ALLOCS_ALLOWED_client_server_request_response_no_promise_based_API=253050 - MAX_ALLOCS_ALLOWED_create_client_stream_channel=37050 - MAX_ALLOCS_ALLOWED_create_client_stream_channel_inline=37050 - MAX_ALLOCS_ALLOWED_get_100000_headers_canonical_form=200050 diff --git a/docker/docker-compose.2204.58.yaml b/docker/docker-compose.2204.58.yaml index d6781f80..9af342bf 100644 --- a/docker/docker-compose.2204.58.yaml +++ b/docker/docker-compose.2204.58.yaml @@ -36,12 +36,12 @@ services: - MAX_ALLOCS_ALLOWED_client_server_h1_request_response_inline=269050 - MAX_ALLOCS_ALLOWED_client_server_request_response=253050 - MAX_ALLOCS_ALLOWED_client_server_request_response_inline=244050 + - MAX_ALLOCS_ALLOWED_client_server_request_response_inline_no_promise_based_API=251050 - MAX_ALLOCS_ALLOWED_client_server_request_response_many=1198050 - MAX_ALLOCS_ALLOWED_client_server_request_response_many_inline=889050 - - MAX_ALLOCS_ALLOWED_client_server_request_response_no_promise_on_channel_creation=253050 - - MAX_ALLOCS_ALLOWED_client_server_request_response_no_promise_on_channel_creation_inline=251050 - - MAX_ALLOCS_ALLOWED_client_server_request_response_no_promise_on_channel_creation_many=1198050 - - MAX_ALLOCS_ALLOWED_client_server_request_response_no_promise_on_channel_creation_many_inline=896050 + - MAX_ALLOCS_ALLOWED_client_server_request_response_many_inline_no_promise_based_API=896050 + - MAX_ALLOCS_ALLOWED_client_server_request_response_many_no_promise_based_API=1198050 + - MAX_ALLOCS_ALLOWED_client_server_request_response_no_promise_based_API=253050 - MAX_ALLOCS_ALLOWED_create_client_stream_channel=37050 - MAX_ALLOCS_ALLOWED_create_client_stream_channel_inline=37050 - MAX_ALLOCS_ALLOWED_get_100000_headers_canonical_form=200050 diff --git a/docker/docker-compose.2204.59.yaml b/docker/docker-compose.2204.59.yaml index a6086879..ec23c40a 100644 --- a/docker/docker-compose.2204.59.yaml +++ b/docker/docker-compose.2204.59.yaml @@ -36,12 +36,12 @@ services: - MAX_ALLOCS_ALLOWED_client_server_h1_request_response_inline=269050 - MAX_ALLOCS_ALLOWED_client_server_request_response=253050 - MAX_ALLOCS_ALLOWED_client_server_request_response_inline=244050 + - MAX_ALLOCS_ALLOWED_client_server_request_response_inline_no_promise_based_API=251050 - MAX_ALLOCS_ALLOWED_client_server_request_response_many=1198050 - MAX_ALLOCS_ALLOWED_client_server_request_response_many_inline=889050 - - MAX_ALLOCS_ALLOWED_client_server_request_response_no_promise_on_channel_creation=253050 - - MAX_ALLOCS_ALLOWED_client_server_request_response_no_promise_on_channel_creation_inline=251050 - - MAX_ALLOCS_ALLOWED_client_server_request_response_no_promise_on_channel_creation_many=1198050 - - MAX_ALLOCS_ALLOWED_client_server_request_response_no_promise_on_channel_creation_many_inline=896050 + - MAX_ALLOCS_ALLOWED_client_server_request_response_many_inline_no_promise_based_API=896050 + - MAX_ALLOCS_ALLOWED_client_server_request_response_many_no_promise_based_API=1198050 + - MAX_ALLOCS_ALLOWED_client_server_request_response_no_promise_based_API=253050 - MAX_ALLOCS_ALLOWED_create_client_stream_channel=37050 - MAX_ALLOCS_ALLOWED_create_client_stream_channel_inline=37050 - MAX_ALLOCS_ALLOWED_get_100000_headers_canonical_form=200050 diff --git a/docker/docker-compose.2204.main.yaml b/docker/docker-compose.2204.main.yaml index 00df2b62..4a57522a 100644 --- a/docker/docker-compose.2204.main.yaml +++ b/docker/docker-compose.2204.main.yaml @@ -35,12 +35,12 @@ services: - MAX_ALLOCS_ALLOWED_client_server_h1_request_response_inline=269050 - MAX_ALLOCS_ALLOWED_client_server_request_response=253050 - MAX_ALLOCS_ALLOWED_client_server_request_response_inline=244050 + - MAX_ALLOCS_ALLOWED_client_server_request_response_inline_no_promise_based_API=251050 - MAX_ALLOCS_ALLOWED_client_server_request_response_many=1198050 - MAX_ALLOCS_ALLOWED_client_server_request_response_many_inline=889050 - - MAX_ALLOCS_ALLOWED_client_server_request_response_no_promise_on_channel_creation=253050 - - MAX_ALLOCS_ALLOWED_client_server_request_response_no_promise_on_channel_creation_inline=251050 - - MAX_ALLOCS_ALLOWED_client_server_request_response_no_promise_on_channel_creation_many=1198050 - - MAX_ALLOCS_ALLOWED_client_server_request_response_no_promise_on_channel_creation_many_inline=896050 + - MAX_ALLOCS_ALLOWED_client_server_request_response_many_inline_no_promise_based_API=896050 + - MAX_ALLOCS_ALLOWED_client_server_request_response_many_no_promise_based_API=1198050 + - MAX_ALLOCS_ALLOWED_client_server_request_response_no_promise_based_API=253050 - MAX_ALLOCS_ALLOWED_create_client_stream_channel=37050 - MAX_ALLOCS_ALLOWED_create_client_stream_channel_inline=37050 - MAX_ALLOCS_ALLOWED_get_100000_headers_canonical_form=200050