Skip to content

Commit

Permalink
mobile: Enable integration tests to run both a HTTP and a proxy server (
Browse files Browse the repository at this point in the history
#36454)

This will be used by a subsequent change to test the Apple PAC proxy
resolver.

Signed-off-by: Ali Beyad <[email protected]>
  • Loading branch information
abeyad authored Oct 7, 2024
1 parent 78f832d commit 5fb93b9
Show file tree
Hide file tree
Showing 20 changed files with 166 additions and 83 deletions.
86 changes: 69 additions & 17 deletions mobile/test/common/integration/test_server_interface.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2,39 +2,91 @@

// NOLINT(namespace-envoy)

static std::shared_ptr<Envoy::TestServer> strong_test_server_;
static std::weak_ptr<Envoy::TestServer> weak_test_server_;
static std::shared_ptr<Envoy::TestServer> strong_test_http_server_;
static std::weak_ptr<Envoy::TestServer> weak_test_http_server_;
static std::shared_ptr<Envoy::TestServer> strong_test_proxy_server_;
static std::weak_ptr<Envoy::TestServer> weak_test_proxy_server_;

static std::shared_ptr<Envoy::TestServer> test_server() { return weak_test_server_.lock(); }
static std::shared_ptr<Envoy::TestServer> test_http_server() {
if (strong_test_http_server_ == nullptr) {
return nullptr;
}
return weak_test_http_server_.lock();
}

static std::shared_ptr<Envoy::TestServer> test_proxy_server() {
if (strong_test_proxy_server_ == nullptr) {
return nullptr;
}
return weak_test_proxy_server_.lock();
}

void start_server(Envoy::TestServerType test_server_type) {
strong_test_server_ = std::make_shared<Envoy::TestServer>();
weak_test_server_ = strong_test_server_;
void start_http_server(Envoy::TestServerType test_server_type) {
strong_test_http_server_ = std::make_shared<Envoy::TestServer>();
weak_test_http_server_ = strong_test_http_server_;

if (auto server = test_server()) {
ASSERT(test_server_type == Envoy::TestServerType::HTTP1_WITHOUT_TLS ||
test_server_type == Envoy::TestServerType::HTTP1_WITH_TLS ||
test_server_type == Envoy::TestServerType::HTTP2_WITH_TLS ||
test_server_type == Envoy::TestServerType::HTTP3,
"Cannot start a proxy server with start_http_server. Use start_proxy_server instead.");
if (auto server = test_http_server()) {
server->start(test_server_type, 0);
}
}

void shutdown_server() {
// Reset the primary handle to the test_server,
void start_proxy_server(Envoy::TestServerType test_server_type) {
strong_test_proxy_server_ = std::make_shared<Envoy::TestServer>();
weak_test_proxy_server_ = strong_test_proxy_server_;

ASSERT(test_server_type == Envoy::TestServerType::HTTP_PROXY ||
test_server_type == Envoy::TestServerType::HTTPS_PROXY,
"Cannot start a HTTP server with start_proxy_server. Use start_http_server instead.");
if (auto server = test_proxy_server()) {
server->start(test_server_type, 0);
}
}

void shutdown_http_server() {
if (strong_test_http_server_ == nullptr) {
return;
}
// Reset the primary handle to the test_http_server,
// but retain it long enough to synchronously shutdown.
auto server = strong_test_server_;
strong_test_server_.reset();
auto server = strong_test_http_server_;
strong_test_http_server_.reset();
server->shutdown();
}

int get_server_port() {
if (auto server = test_server()) {
void shutdown_proxy_server() {
if (strong_test_proxy_server_ == nullptr) {
return;
}
// Reset the primary handle to the test_proxy_server,
// but retain it long enough to synchronously shutdown.
auto server = strong_test_proxy_server_;
strong_test_proxy_server_.reset();
server->shutdown();
}

int get_http_server_port() {
if (auto server = test_http_server()) {
return server->getPort();
}
return -1; // failure
}

int get_proxy_server_port() {
if (auto server = test_proxy_server()) {
return server->getPort();
}
return -1; // failure
}

void set_headers_and_data(absl::string_view header_key, absl::string_view header_value,
absl::string_view response_body) {
if (auto server = test_server()) {
// start_server() must be called before headers and data can be added.
void set_http_headers_and_data(absl::string_view header_key, absl::string_view header_value,
absl::string_view response_body) {
if (auto server = test_http_server()) {
// start_http_server() must be called before headers and data can be added.
ASSERT(server);
server->setHeadersAndData(header_key, header_value, response_body);
}
Expand Down
43 changes: 31 additions & 12 deletions mobile/test/common/integration/test_server_interface.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,28 +9,47 @@ extern "C" { // functions
#endif

/**
* Starts the server. Can only have one server active per JVM. This is blocking until the port can
* start accepting requests.
* Starts the HTTP server. Can only have one HTTP server active per process. This is blocking
* until the port can start accepting requests.
*/
void start_server(Envoy::TestServerType test_server_type);
void start_http_server(Envoy::TestServerType test_server_type);

/**
* Shutdowns the server. Can be restarted later. This is blocking until the server has freed all
* resources.
* Starts the Proxy server. Can only have one proxy server active per process. This is blocking
* until the port can start accepting requests.
*/
void shutdown_server();
void start_proxy_server(Envoy::TestServerType test_server_type);

/**
* Returns the port that got attributed. Can only be called once the server has been started.
* Shuts down the HTTP server. Can be restarted later. This is blocking until the server has freed
* all resources.
*/
int get_server_port();
void shutdown_http_server();

/**
* Set response data for server to return for any URL. Can only be called once the server has been
* started.
* Shuts down the proxy server. Can be restarted later. This is blocking until the server has freed
* all resources.
*/
void set_headers_and_data(absl::string_view header_key, absl::string_view header_value,
absl::string_view response_body);
void shutdown_proxy_server();

/**
* Returns the port that got attributed to the HTTP server. Can only be called once the server has
* been started.
*/
int get_http_server_port();

/**
* Returns the port that got attributed to the proxy server. Can only be called once the server has
* been started.
*/
int get_proxy_server_port();

/**
* Set response data for the HTTP server to return for any URL. Can only be called once the server
* has been started.
*/
void set_http_headers_and_data(absl::string_view header_key, absl::string_view header_value,
absl::string_view response_body);

#ifdef __cplusplus
} // functions
Expand Down
14 changes: 9 additions & 5 deletions mobile/test/objective-c/EnvoyTestServer.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,21 @@
// (https://docs.engflow.com/re/client/platform-options-reference.html#sandboxallowed).
@interface EnvoyTestServer : NSObject

// Get the port of the upstream server.
+ (NSInteger)getEnvoyPort;
// Get the port of the upstream HTTP server.
+ (NSInteger)getHttpPort;
// Get the port of the upstream proxy server.
+ (NSInteger)getProxyPort;
// Starts a server with HTTP1 and no TLS.
+ (void)startHttp1PlaintextServer;
// Starts a server as a HTTP proxy.
+ (void)startHttpProxyServer;
// Starts a server as a HTTPS proxy.
+ (void)startHttpsProxyServer;
// Shut down and clean up server.
+ (void)shutdownTestServer;
// Add response data to the upstream.
// Shut down and clean up the HTTP server.
+ (void)shutdownTestHttpServer;
// Shut down and clean up the Proxy server.
+ (void)shutdownTestProxyServer;
// Add response data to the HTTP server.
+ (void)setHeadersAndData:(NSString *)header_key
header_value:(NSString *)header_value
response_body:(NSString *)response_body;
Expand Down
26 changes: 17 additions & 9 deletions mobile/test/objective-c/EnvoyTestServer.mm
Original file line number Diff line number Diff line change
Expand Up @@ -3,31 +3,39 @@

@implementation EnvoyTestServer

+ (NSInteger)getEnvoyPort {
return get_server_port();
+ (NSInteger)getHttpPort {
return get_http_server_port();
}

+ (NSInteger)getProxyPort {
return get_proxy_server_port();
}

+ (void)startHttp1PlaintextServer {
start_server(Envoy::TestServerType::HTTP1_WITHOUT_TLS);
start_http_server(Envoy::TestServerType::HTTP1_WITHOUT_TLS);
}

+ (void)startHttpProxyServer {
start_server(Envoy::TestServerType::HTTP_PROXY);
start_proxy_server(Envoy::TestServerType::HTTP_PROXY);
}

+ (void)startHttpsProxyServer {
start_server(Envoy::TestServerType::HTTPS_PROXY);
start_proxy_server(Envoy::TestServerType::HTTPS_PROXY);
}

+ (void)shutdownTestHttpServer {
shutdown_http_server();
}

+ (void)shutdownTestServer {
shutdown_server();
+ (void)shutdownTestProxyServer {
shutdown_proxy_server();
}

+ (void)setHeadersAndData:(NSString *)header_key
header_value:(NSString *)header_value
response_body:(NSString *)response_body {
set_headers_and_data([header_key UTF8String], [header_value UTF8String],
[response_body UTF8String]);
set_http_headers_and_data([header_key UTF8String], [header_value UTF8String],
[response_body UTF8String]);
}

@end
4 changes: 2 additions & 2 deletions mobile/test/swift/integration/CancelGRPCStreamTest.swift
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ final class CancelGRPCStreamTests: XCTestCase {

let requestHeaders = GRPCRequestHeadersBuilder(
scheme: "http",
authority: "localhost:" + String(EnvoyTestServer.getEnvoyPort()),
authority: "localhost:" + String(EnvoyTestServer.getHttpPort()),
path: "/")
.build()

Expand All @@ -87,6 +87,6 @@ final class CancelGRPCStreamTests: XCTestCase {
XCTAssertEqual(XCTWaiter.wait(for: expectations, timeout: 10), .completed)

engine.terminate()
EnvoyTestServer.shutdownTestServer()
EnvoyTestServer.shutdownTestHttpServer()
}
}
4 changes: 2 additions & 2 deletions mobile/test/swift/integration/CancelStreamTest.swift
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ final class CancelStreamTests: XCTestCase {

let client = engine.streamClient()

let port = String(EnvoyTestServer.getEnvoyPort())
let port = String(EnvoyTestServer.getHttpPort())
let requestHeaders = RequestHeadersBuilder(method: .get, scheme: "http",
authority: "localhost:" + port, path: "/")
.build()
Expand All @@ -86,6 +86,6 @@ final class CancelStreamTests: XCTestCase {
XCTAssertEqual(XCTWaiter.wait(for: expectations, timeout: 10), .completed)

engine.terminate()
EnvoyTestServer.shutdownTestServer()
EnvoyTestServer.shutdownTestHttpServer()
}
}
4 changes: 2 additions & 2 deletions mobile/test/swift/integration/EndToEndNetworkingTest.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ final class EndToEndNetworkingTest: XCTestCase {
"x-response-foo", header_value: "aaa", response_body: "hello world")
let headersExpectation = self.expectation(description: "Response headers received")
let dataExpectation = self.expectation(description: "Response data received")
let port = String(EnvoyTestServer.getEnvoyPort())
let port = String(EnvoyTestServer.getHttpPort())
let requestHeaders = RequestHeadersBuilder(
method: .get, scheme: "http", authority: "localhost:" + port, path: "/"
)
Expand Down Expand Up @@ -60,6 +60,6 @@ final class EndToEndNetworkingTest: XCTestCase {
XCTAssertEqual(.completed, XCTWaiter().wait(for: expectations, timeout: 10, enforceOrder: true))

engine.terminate()
EnvoyTestServer.shutdownTestServer()
EnvoyTestServer.shutdownTestHttpServer()
}
}
4 changes: 2 additions & 2 deletions mobile/test/swift/integration/FilterResetIdleTest.swift
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ final class FilterResetIdleTests: XCTestCase {
cancelExpectation.isInverted = true

EnvoyTestServer.startHttp1PlaintextServer()
let port = String(EnvoyTestServer.getEnvoyPort())
let port = String(EnvoyTestServer.getHttpPort())

let engine = EngineBuilder()
.setLogLevel(.debug)
Expand Down Expand Up @@ -166,6 +166,6 @@ final class FilterResetIdleTests: XCTestCase {
)

engine.terminate()
EnvoyTestServer.shutdownTestServer()
EnvoyTestServer.shutdownTestHttpServer()
}
}
4 changes: 2 additions & 2 deletions mobile/test/swift/integration/GRPCReceiveErrorTest.swift
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ final class GRPCReceiveErrorTests: XCTestCase {

let requestHeaders = GRPCRequestHeadersBuilder(
scheme: "http",
authority: "localhost:" + String(EnvoyTestServer.getEnvoyPort()),
authority: "localhost:" + String(EnvoyTestServer.getHttpPort()),
path: "/pb.api.v1.Foo/GetBar")
.build()
let message = Data([1, 2, 3, 4, 5])
Expand Down Expand Up @@ -114,6 +114,6 @@ final class GRPCReceiveErrorTests: XCTestCase {
XCTAssertEqual(XCTWaiter.wait(for: expectations, timeout: 10), .completed)

engine.terminate()
EnvoyTestServer.shutdownTestServer()
EnvoyTestServer.shutdownTestHttpServer()
}
}
4 changes: 2 additions & 2 deletions mobile/test/swift/integration/IdleTimeoutTest.swift
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ final class IdleTimeoutTests: XCTestCase {

let client = engine.streamClient()

let port = String(EnvoyTestServer.getEnvoyPort())
let port = String(EnvoyTestServer.getHttpPort())
let requestHeaders = RequestHeadersBuilder(
method: .get, scheme: "http", authority: "localhost:" + port, path: "/"
)
Expand All @@ -119,6 +119,6 @@ final class IdleTimeoutTests: XCTestCase {
)

engine.terminate()
EnvoyTestServer.shutdownTestServer()
EnvoyTestServer.shutdownTestHttpServer()
}
}
4 changes: 2 additions & 2 deletions mobile/test/swift/integration/KeyValueStoreTest.swift
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ final class KeyValueStoreTests: XCTestCase {

let requestHeaders = RequestHeadersBuilder(
method: .get, scheme: "http",
authority: "localhost:" + String(EnvoyTestServer.getEnvoyPort()), path: "/simple.txt"
authority: "localhost:" + String(EnvoyTestServer.getHttpPort()), path: "/simple.txt"
)
.build()

Expand All @@ -84,6 +84,6 @@ final class KeyValueStoreTests: XCTestCase {
)

engine.terminate()
EnvoyTestServer.shutdownTestServer()
EnvoyTestServer.shutdownTestHttpServer()
}
}
4 changes: 2 additions & 2 deletions mobile/test/swift/integration/ReceiveDataTest.swift
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ final class ReceiveDataTests: XCTestCase {

let client = engine.streamClient()

let port = String(EnvoyTestServer.getEnvoyPort())
let port = String(EnvoyTestServer.getHttpPort())
let requestHeaders = RequestHeadersBuilder(method: .get, scheme: "http",
authority: "localhost:" + port, path: "/simple.txt")
.build()
Expand Down Expand Up @@ -67,6 +67,6 @@ final class ReceiveDataTests: XCTestCase {
XCTAssertEqual(actualResponseBody, directResponseBody)

engine.terminate()
EnvoyTestServer.shutdownTestServer()
EnvoyTestServer.shutdownTestHttpServer()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ final class ResetConnectivityStateTest: XCTestCase {

let client = engine.streamClient()

let port = String(EnvoyTestServer.getEnvoyPort())
let port = String(EnvoyTestServer.getHttpPort())
let requestHeaders = RequestHeadersBuilder(method: .get, scheme: "http",
authority: "localhost:" + port, path: "/simple.txt")
.build()
Expand Down Expand Up @@ -98,6 +98,6 @@ final class ResetConnectivityStateTest: XCTestCase {
XCTAssertTrue(resultEndStream2)

engine.terminate()
EnvoyTestServer.shutdownTestServer()
EnvoyTestServer.shutdownTestHttpServer()
}
}
Loading

0 comments on commit 5fb93b9

Please sign in to comment.