Skip to content

Commit cfc2c3e

Browse files
authored
test: adding original dst tests. (#23645)
Part of #22583 Signed-off-by: Alyssa Wilk <[email protected]>
1 parent c0189d0 commit cfc2c3e

File tree

6 files changed

+183
-7
lines changed

6 files changed

+183
-7
lines changed

test/extensions/filters/listener/original_dst/BUILD

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
load(
22
"//bazel:envoy_build_system.bzl",
33
"envoy_cc_fuzz_test",
4+
"envoy_cc_test",
45
"envoy_package",
56
)
67

@@ -17,3 +18,22 @@ envoy_cc_fuzz_test(
1718
"//test/extensions/filters/listener/common/fuzz:listener_filter_fuzzer_lib",
1819
],
1920
)
21+
22+
envoy_cc_test(
23+
name = "original_dst_integration_test",
24+
srcs = [
25+
"original_dst_integration_test.cc",
26+
],
27+
deps = [
28+
"//source/common/http:header_map_lib",
29+
"//source/extensions/filters/http/buffer:config",
30+
"//source/extensions/filters/listener/original_dst:config",
31+
"//source/extensions/filters/network/tcp_proxy:config",
32+
"//test/integration:http_protocol_integration_lib",
33+
"//test/test_common:logging_lib",
34+
"//test/test_common:utility_lib",
35+
"@envoy_api//envoy/config/bootstrap/v3:pkg_cc_proto",
36+
"@envoy_api//envoy/extensions/filters/listener/original_dst/v3:pkg_cc_proto",
37+
"@envoy_api//envoy/extensions/filters/network/http_connection_manager/v3:pkg_cc_proto",
38+
],
39+
)
Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
#include "envoy/config/bootstrap/v3/bootstrap.pb.h"
2+
#include "envoy/event/dispatcher.h"
3+
#include "envoy/extensions/filters/listener/original_dst/v3/original_dst.pb.h"
4+
#include "envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.pb.h"
5+
#include "envoy/http/header_map.h"
6+
7+
#include "source/common/http/headers.h"
8+
#include "source/common/network/utility.h"
9+
10+
#include "test/common/upstream/utility.h"
11+
#include "test/integration/http_integration.h"
12+
#include "test/integration/http_protocol_integration.h"
13+
#include "test/integration/utility.h"
14+
15+
#include "gtest/gtest.h"
16+
17+
namespace Envoy {
18+
19+
using OriginalDstIntegrationTest = HttpProtocolIntegrationTest;
20+
21+
ConfigHelper::ConfigModifierFunction setOriginalDstCluster(int port) {
22+
return [port](envoy::config::bootstrap::v3::Bootstrap& bootstrap) {
23+
RELEASE_ASSERT(bootstrap.mutable_static_resources()->clusters_size() == 1, "");
24+
auto& cluster = *bootstrap.mutable_static_resources()->mutable_clusters(0);
25+
cluster.set_type(envoy::config::cluster::v3::Cluster::ORIGINAL_DST);
26+
cluster.set_lb_policy(envoy::config::cluster::v3::Cluster::CLUSTER_PROVIDED);
27+
cluster.mutable_original_dst_lb_config()->mutable_upstream_port_override()->set_value(port);
28+
cluster.clear_load_assignment();
29+
30+
auto* listener = bootstrap.mutable_static_resources()->mutable_listeners(0);
31+
listener->mutable_address()->mutable_socket_address()->set_address("0.0.0.0");
32+
listener->set_traffic_direction(envoy::config::core::v3::INBOUND);
33+
34+
auto* listener_filter = listener->add_listener_filters();
35+
listener_filter->set_name("envoy.filters.listener.original_dst");
36+
envoy::extensions::filters::listener::original_dst::v3::OriginalDst original_dst;
37+
listener_filter->mutable_typed_config()->PackFrom(original_dst);
38+
};
39+
}
40+
41+
INSTANTIATE_TEST_SUITE_P(Protocols, OriginalDstIntegrationTest,
42+
testing::ValuesIn(HttpProtocolIntegrationTest::getProtocolTestParams(
43+
{Http::CodecType::HTTP1}, {Http::CodecType::HTTP1})),
44+
HttpProtocolIntegrationTest::protocolTestParamsToString);
45+
46+
TEST_P(OriginalDstIntegrationTest, OriginalDstHttpManyConnections) {
47+
// Windows apparently have this loopback property.
48+
DISABLE_UNDER_WINDOWS;
49+
// Only do this for IPv4 as we can have many 127.0.0.x addresses listening on 0.0.0.0
50+
if (version_ != Network::Address::IpVersion::v4) {
51+
return;
52+
}
53+
ASSERT(!upstream_tls_);
54+
auto address = Network::Test::getAnyAddress(Network::Address::IpVersion::v4);
55+
fake_upstreams_.emplace_back(
56+
std::make_unique<FakeUpstream>(Network::Test::createRawBufferDownstreamSocketFactory(),
57+
address, configWithType(upstreamProtocol())));
58+
59+
config_helper_.addConfigModifier(
60+
setOriginalDstCluster(fake_upstreams_[0]->localAddress()->ip()->port()));
61+
initialize();
62+
63+
const int32_t kMaxConnections = 10;
64+
for (int i = 0; i < kMaxConnections; ++i) {
65+
std::string address_str = fmt::format("127.0.0.{}", i + 1);
66+
Network::ClientConnectionPtr connection(dispatcher_->createClientConnection(
67+
Network::Utility::resolveUrl(fmt::format("tcp://{}:{}", address_str, lookupPort("http"))),
68+
Network::Address::InstanceConstSharedPtr(), Network::Test::createRawBufferSocket(), nullptr,
69+
nullptr));
70+
71+
connection->enableHalfClose(enableHalfClose());
72+
73+
codec_client_ = makeHttpConnection(std::move(connection));
74+
auto response =
75+
sendRequestAndWaitForResponse(default_request_headers_, 0, default_response_headers_, 0);
76+
EXPECT_EQ(address_str, fake_upstream_connection_->connection()
77+
.connectionInfoProvider()
78+
.localAddress()
79+
->ip()
80+
->addressAsString());
81+
ASSERT_TRUE(fake_upstream_connection_->close());
82+
fake_upstream_connection_.reset();
83+
codec_client_->close();
84+
}
85+
}
86+
87+
class OriginalDstTcpProxyIntegrationTest
88+
: public testing::TestWithParam<Network::Address::IpVersion>,
89+
public BaseIntegrationTest {
90+
public:
91+
OriginalDstTcpProxyIntegrationTest()
92+
: BaseIntegrationTest(GetParam(), ConfigHelper::tcpProxyConfig()) {
93+
enableHalfClose(true);
94+
}
95+
};
96+
97+
TEST_P(OriginalDstTcpProxyIntegrationTest, TestManyConnections) {
98+
// Windows apparently have this loopback property.
99+
DISABLE_UNDER_WINDOWS;
100+
if (version_ != Network::Address::IpVersion::v4) {
101+
return;
102+
}
103+
104+
// Create an upstream on 0.0.0.0
105+
auto address = Network::Test::getAnyAddress(Network::Address::IpVersion::v4);
106+
ASSERT(!upstream_tls_);
107+
fake_upstreams_.emplace_back(
108+
std::make_unique<FakeUpstream>(Network::Test::createRawBufferDownstreamSocketFactory(),
109+
address, configWithType(upstreamProtocol())));
110+
111+
config_helper_.addConfigModifier(
112+
setOriginalDstCluster(fake_upstreams_[0]->localAddress()->ip()->port()));
113+
initialize();
114+
115+
const int32_t kMaxConnections = 10;
116+
for (int i = 0; i < kMaxConnections; ++i) {
117+
// Set up the connection
118+
std::string address_str = fmt::format("127.0.0.{}", i + 1);
119+
IntegrationTcpClientPtr tcp_client =
120+
makeTcpConnection(lookupPort("listener_0"), nullptr, nullptr, address_str);
121+
FakeRawConnectionPtr fake_upstream_connection;
122+
ASSERT_TRUE(fake_upstreams_[0]->waitForRawConnection(fake_upstream_connection));
123+
EXPECT_EQ(address_str, fake_upstream_connection->connection()
124+
.connectionInfoProvider()
125+
.localAddress()
126+
->ip()
127+
->addressAsString());
128+
129+
// Write bidirectional data.
130+
ASSERT_TRUE(fake_upstream_connection->write("hello"));
131+
tcp_client->waitForData("hello");
132+
ASSERT_TRUE(tcp_client->write("hello"));
133+
ASSERT_TRUE(fake_upstream_connection->waitForData(5));
134+
135+
// Close down the connection.
136+
ASSERT_TRUE(fake_upstream_connection->write("", true));
137+
tcp_client->waitForHalfClose();
138+
ASSERT_TRUE(tcp_client->write("", true));
139+
ASSERT_TRUE(fake_upstream_connection->waitForHalfClose());
140+
ASSERT_TRUE(fake_upstream_connection->waitForDisconnect());
141+
}
142+
test_server_->waitForCounterGe("cluster_manager.cluster_updated", kMaxConnections);
143+
}
144+
145+
INSTANTIATE_TEST_SUITE_P(IpVersions, OriginalDstTcpProxyIntegrationTest,
146+
testing::ValuesIn(TestEnvironment::getIpVersionsForTest()),
147+
TestUtility::ipTestParamsToString);
148+
149+
} // namespace Envoy

test/integration/base_integration_test.cc

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -305,9 +305,11 @@ absl::optional<uint64_t> BaseIntegrationTest::waitForNextRawUpstreamConnection(
305305
IntegrationTcpClientPtr
306306
BaseIntegrationTest::makeTcpConnection(uint32_t port,
307307
const Network::ConnectionSocket::OptionsSharedPtr& options,
308-
Network::Address::InstanceConstSharedPtr source_address) {
308+
Network::Address::InstanceConstSharedPtr source_address,
309+
absl::string_view destination_address) {
309310
return std::make_unique<IntegrationTcpClient>(*dispatcher_, *mock_buffer_factory_, port, version_,
310-
enableHalfClose(), options, source_address);
311+
enableHalfClose(), options, source_address,
312+
destination_address);
311313
}
312314

313315
void BaseIntegrationTest::registerPort(const std::string& key, uint32_t port) {

test/integration/base_integration_test.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,8 @@ class BaseIntegrationTest : protected Logger::Loggable<Logger::Id::testing> {
9999
makeTcpConnection(uint32_t port,
100100
const Network::ConnectionSocket::OptionsSharedPtr& options = nullptr,
101101
Network::Address::InstanceConstSharedPtr source_address =
102-
Network::Address::InstanceConstSharedPtr());
102+
Network::Address::InstanceConstSharedPtr(),
103+
absl::string_view destination_address = "");
103104

104105
// Test-wide port map.
105106
void registerPort(const std::string& key, uint32_t port);

test/integration/integration_tcp_client.cc

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ IntegrationTcpClient::IntegrationTcpClient(
3838
Event::Dispatcher& dispatcher, MockBufferFactory& factory, uint32_t port,
3939
Network::Address::IpVersion version, bool enable_half_close,
4040
const Network::ConnectionSocket::OptionsSharedPtr& options,
41-
Network::Address::InstanceConstSharedPtr source_address)
41+
Network::Address::InstanceConstSharedPtr source_address, absl::string_view destination_address)
4242
: payload_reader_(new WaitForPayloadReader(dispatcher)),
4343
callbacks_(new ConnectionCallbacks(*this)) {
4444
EXPECT_CALL(factory, createBuffer_(_, _, _))
@@ -55,8 +55,11 @@ IntegrationTcpClient::IntegrationTcpClient(
5555
}));
5656

5757
connection_ = dispatcher.createClientConnection(
58-
Network::Utility::resolveUrl(
59-
fmt::format("tcp://{}:{}", Network::Test::getLoopbackAddressUrlString(version), port)),
58+
Network::Utility::resolveUrl(fmt::format(
59+
"tcp://{}:{}",
60+
destination_address.empty() ? Network::Test::getLoopbackAddressUrlString(version)
61+
: destination_address,
62+
port)),
6063
source_address, Network::Test::createRawBufferSocket(), options, nullptr);
6164

6265
ON_CALL(*client_write_buffer_, drain(_))

test/integration/integration_tcp_client.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,8 @@ class IntegrationTcpClient {
2929
IntegrationTcpClient(Event::Dispatcher& dispatcher, MockBufferFactory& factory, uint32_t port,
3030
Network::Address::IpVersion version, bool enable_half_close,
3131
const Network::ConnectionSocket::OptionsSharedPtr& options,
32-
Network::Address::InstanceConstSharedPtr source_address = nullptr);
32+
Network::Address::InstanceConstSharedPtr source_address = nullptr,
33+
absl::string_view destination_address = "");
3334

3435
void close();
3536
void waitForData(const std::string& data, bool exact_match = true);

0 commit comments

Comments
 (0)