Skip to content
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
43 changes: 38 additions & 5 deletions test/common/integration/BUILD
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
load("@envoy//bazel:envoy_build_system.bzl", "envoy_cc_test", "envoy_cc_test_library", "envoy_package")
load(
"@envoy//bazel:envoy_build_system.bzl",
"envoy_cc_test",
"envoy_cc_test_library",
"envoy_package",
)

licenses(["notice"]) # Apache 2

Expand All @@ -12,19 +17,47 @@ envoy_cc_test(
"sandboxNetwork": "standard",
},
repository = "@envoy",
deps = [
":base_client_integration_test_lib",
],
)

envoy_cc_test(
name = "rtds_integration_test",
srcs = ["rtds_integration_test.cc"],
exec_properties = {
# TODO(willengflow): Remove this once the sandboxNetwork=off works for ipv4 localhost addresses.
"sandboxNetwork": "standard",
},
repository = "@envoy",
deps = [
":base_client_integration_test_lib",
"@envoy//test/common/grpc:grpc_client_integration_lib",
"@envoy//test/server:utility_lib",
"@envoy_api//envoy/config/bootstrap/v3:pkg_cc_proto",
"@envoy_api//envoy/config/cluster/v3:pkg_cc_proto",
"@envoy_api//envoy/service/runtime/v3:pkg_cc_proto",
],
)

envoy_cc_test_library(
name = "base_client_integration_test_lib",
srcs = [
"base_client_integration_test.cc",
],
hdrs = [
"base_client_integration_test.h",
],
repository = "@envoy",
deps = [
"//library/cc:engine_builder_lib",
"//library/common/extensions/filters/http/local_error:config",
"//library/common/extensions/filters/http/local_error:filter_cc_proto",
"//library/common/http:client_lib",
"//library/common/http:header_utility_lib",
"//library/common/types:c_types_lib",
"@envoy//source/extensions/http/header_formatters/preserve_case:config",
"@envoy//source/extensions/http/header_formatters/preserve_case:preserve_case_formatter",
"@envoy//test/common/http:common_lib",
"@envoy//test/integration:http_integration_lib",
"@envoy//test/server:utility_lib",
"@envoy//test/test_common:environment_lib",
],
)

Expand Down
119 changes: 119 additions & 0 deletions test/common/integration/base_client_integration_test.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
#include "test/common/integration/base_client_integration_test.h"

#include "source/extensions/http/header_formatters/preserve_case/config.h"
#include "source/extensions/http/header_formatters/preserve_case/preserve_case_formatter.h"

#include "test/common/http/common.h"

#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "library/cc/engine_builder.h"
#include "library/common/config/internal.h"
#include "library/common/http/header_utility.h"

namespace Envoy {
namespace {

// Use the Envoy mobile default config as much as possible in this test.
// There are some config modifiers below which do result in deltas.
std::string defaultConfig() {
Platform::EngineBuilder builder;
std::string config_str = absl::StrCat(config_header, builder.generateConfigStr());
return config_str;
}

} // namespace

Http::ResponseHeaderMapPtr toResponseHeaders(envoy_headers headers) {
std::unique_ptr<Http::ResponseHeaderMapImpl> transformed_headers =
Http::ResponseHeaderMapImpl::create();
transformed_headers->setFormatter(
std::make_unique<
Extensions::Http::HeaderFormatters::PreserveCase::PreserveCaseHeaderFormatter>(
false, envoy::extensions::http::header_formatters::preserve_case::v3::
PreserveCaseFormatterConfig::DEFAULT));
Http::Utility::toEnvoyHeaders(*transformed_headers, headers);
return transformed_headers;
}

BaseClientIntegrationTest::BaseClientIntegrationTest(Network::Address::IpVersion ip_version)
: BaseIntegrationTest(ip_version, defaultConfig()) {
use_lds_ = false;
autonomous_upstream_ = true;
defer_listener_finalization_ = true;

HttpTestUtility::addDefaultHeaders(default_request_headers_);

config_helper_.addConfigModifier([](envoy::config::bootstrap::v3::Bootstrap& bootstrap) {
// The default stats config has overenthusiastic filters.
bootstrap.clear_stats_config();
});
}

void BaseClientIntegrationTest::initialize() {
BaseIntegrationTest::initialize();

bridge_callbacks_.context = &cc_;
bridge_callbacks_.on_headers = [](envoy_headers c_headers, bool, envoy_stream_intel intel,
void* context) -> void* {
Http::ResponseHeaderMapPtr response_headers = toResponseHeaders(c_headers);
callbacks_called* cc_ = static_cast<callbacks_called*>(context);
cc_->on_headers_calls++;
cc_->status = response_headers->Status()->value().getStringView();
cc_->on_header_consumed_bytes_from_response = intel.consumed_bytes_from_response;
return nullptr;
};
bridge_callbacks_.on_data = [](envoy_data c_data, bool, envoy_stream_intel,
void* context) -> void* {
callbacks_called* cc_ = static_cast<callbacks_called*>(context);
cc_->on_data_calls++;
release_envoy_data(c_data);
return nullptr;
};
bridge_callbacks_.on_complete = [](envoy_stream_intel, envoy_final_stream_intel final_intel,
void* context) -> void* {
callbacks_called* cc_ = static_cast<callbacks_called*>(context);
cc_->final_intel = final_intel;
cc_->on_complete_received_byte_count = final_intel.received_byte_count;
cc_->on_complete_calls++;
cc_->terminal_callback->setReady();
return nullptr;
};
bridge_callbacks_.on_error = [](envoy_error error, envoy_stream_intel, envoy_final_stream_intel,
void* context) -> void* {
release_envoy_error(error);
callbacks_called* cc_ = static_cast<callbacks_called*>(context);
cc_->on_error_calls++;
cc_->terminal_callback->setReady();
return nullptr;
};
bridge_callbacks_.on_cancel = [](envoy_stream_intel, envoy_final_stream_intel final_intel,
void* context) -> void* {
EXPECT_NE(-1, final_intel.stream_start_ms);
callbacks_called* cc_ = static_cast<callbacks_called*>(context);
cc_->on_cancel_calls++;
cc_->terminal_callback->setReady();
return nullptr;
};

ConditionalInitializer server_started;
test_server_->server().dispatcher().post([this, &server_started]() -> void {
http_client_ = std::make_unique<Http::Client>(
test_server_->server().listenerManager().apiListener()->get().http()->get(), *dispatcher_,
test_server_->statStore(), test_server_->server().api().randomGenerator());
dispatcher_->drain(test_server_->server().dispatcher());
server_started.setReady();
});
server_started.waitReady();
default_request_headers_.setHost(fake_upstreams_[0]->localAddress()->asStringView());
}

void BaseClientIntegrationTest::cleanup() {
if (xds_connection_ != nullptr) {
cleanUpXdsConnection();
}
test_server_.reset();
fake_upstreams_.clear();
}

} // namespace Envoy
50 changes: 50 additions & 0 deletions test/common/integration/base_client_integration_test.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
#pragma once

#include "test/integration/integration.h"

#include "library/common/http/client.h"
#include "library/common/types/c_types.h"

namespace Envoy {

// Maintains statistics and status data obtained from the Http::Client callbacks.
typedef struct {
uint32_t on_headers_calls;
uint32_t on_data_calls;
uint32_t on_complete_calls;
uint32_t on_error_calls;
uint32_t on_cancel_calls;
uint64_t on_header_consumed_bytes_from_response;
uint64_t on_complete_received_byte_count;
std::string status;
ConditionalInitializer* terminal_callback;
envoy_final_stream_intel final_intel;
} callbacks_called;

// Based on Http::Utility::toRequestHeaders() but only used for these tests.
Http::ResponseHeaderMapPtr toResponseHeaders(envoy_headers headers);

// A base class for Envoy Mobile client integration tests which interact with Envoy through the
// Http::Client class.
//
// TODO(junr03): move this to derive from the ApiListenerIntegrationTest after moving that class
// into a test lib.
class BaseClientIntegrationTest : public BaseIntegrationTest {
public:
BaseClientIntegrationTest(Network::Address::IpVersion ip_version);
virtual ~BaseClientIntegrationTest() = default;

protected:
virtual void initialize() override;
virtual void cleanup();

Event::ProvisionalDispatcherPtr dispatcher_ = std::make_unique<Event::ProvisionalDispatcher>();
Http::ClientPtr http_client_{};
envoy_http_callbacks bridge_callbacks_;
ConditionalInitializer terminal_callback_;
callbacks_called cc_{0, 0, 0, 0, 0, 0, 0, "", &terminal_callback_, {}};
Http::TestRequestHeaderMapImpl default_request_headers_;
envoy_stream_t stream_{1};
};

} // namespace Envoy
Loading