/proc/self/cwd/test/integration/base_integration_test.h
Line | Count | Source (jump to first uncovered line) |
1 | | #pragma once |
2 | | |
3 | | #include <cstdint> |
4 | | #include <functional> |
5 | | #include <string> |
6 | | #include <vector> |
7 | | |
8 | | #include "envoy/config/endpoint/v3/endpoint_components.pb.h" |
9 | | #include "envoy/server/process_context.h" |
10 | | #include "envoy/service/discovery/v3/discovery.pb.h" |
11 | | |
12 | | #include "source/common/tls/context_manager_impl.h" |
13 | | |
14 | | #include "test/common/grpc/grpc_client_integration.h" |
15 | | #include "test/config/utility.h" |
16 | | #include "test/integration/autonomous_upstream.h" |
17 | | #include "test/integration/fake_upstream.h" |
18 | | #include "test/integration/integration_tcp_client.h" |
19 | | #include "test/integration/server.h" |
20 | | #include "test/integration/utility.h" |
21 | | #include "test/mocks/buffer/mocks.h" |
22 | | #include "test/mocks/server/transport_socket_factory_context.h" |
23 | | #include "test/test_common/environment.h" |
24 | | #include "test/test_common/test_time.h" |
25 | | #include "test/test_common/utility.h" |
26 | | |
27 | | #include "absl/strings/str_format.h" |
28 | | #include "absl/types/optional.h" |
29 | | |
30 | | #if defined(ENVOY_CONFIG_COVERAGE) |
31 | | #define DISABLE_UNDER_COVERAGE return |
32 | | #else |
33 | | #define DISABLE_UNDER_COVERAGE \ |
34 | | do { \ |
35 | | } while (0) |
36 | | #endif |
37 | | |
38 | | #ifndef ENVOY_ADMIN_FUNCTIONALITY |
39 | | #define DISABLE_IF_ADMIN_DISABLED return |
40 | | #else |
41 | | #define DISABLE_IF_ADMIN_DISABLED \ |
42 | | do { \ |
43 | | } while (0) |
44 | | #endif |
45 | | |
46 | | namespace Envoy { |
47 | | |
48 | | struct ApiFilesystemConfig { |
49 | | std::string bootstrap_path_; |
50 | | std::string cds_path_; |
51 | | std::string eds_path_; |
52 | | std::string lds_path_; |
53 | | std::string rds_path_; |
54 | | }; |
55 | | |
56 | | /** |
57 | | * Test fixture for all integration tests. |
58 | | */ |
59 | | class BaseIntegrationTest : protected Logger::Loggable<Logger::Id::testing> { |
60 | | public: |
61 | | using InstanceConstSharedPtrFn = std::function<Network::Address::InstanceConstSharedPtr(int)>; |
62 | | static const InstanceConstSharedPtrFn defaultAddressFunction(Network::Address::IpVersion version); |
63 | | |
64 | | BaseIntegrationTest(const InstanceConstSharedPtrFn& upstream_address_fn, |
65 | | Network::Address::IpVersion version, |
66 | | const envoy::config::bootstrap::v3::Bootstrap& bootstrap); |
67 | | // Creates a test fixture with an upstream bound to INADDR_ANY on an unspecified port using the |
68 | | // provided IP |version|. |
69 | | BaseIntegrationTest(Network::Address::IpVersion version, |
70 | | const std::string& config = ConfigHelper::httpProxyConfig()); |
71 | | // Creates a test fixture with a specified |upstream_address| function that provides the IP and |
72 | | // port to use. |
73 | | BaseIntegrationTest(const InstanceConstSharedPtrFn& upstream_address_fn, |
74 | | Network::Address::IpVersion version, |
75 | | const std::string& config = ConfigHelper::httpProxyConfig()); |
76 | 1.97k | virtual ~BaseIntegrationTest() = default; |
77 | | |
78 | | // Initialize the basic proto configuration, create fake upstreams, and start Envoy. |
79 | | virtual void initialize(); |
80 | | // Set up the fake upstream connections. This is called by initialize() and |
81 | | // is virtual to allow subclass overrides. |
82 | | virtual void createUpstreams(); |
83 | | // Create a single upstream, based on the supplied config. |
84 | | void createUpstream(Network::Address::InstanceConstSharedPtr endpoint, |
85 | | FakeUpstreamConfig& config); |
86 | | // Finalize the config and spin up an Envoy instance. |
87 | | virtual void createEnvoy(); |
88 | | // Sets upstream_protocol_ and alters the upstream protocol in the config_helper_ |
89 | | void setUpstreamProtocol(Http::CodecType protocol); |
90 | | // Sets fake_upstreams_count_ |
91 | 0 | void setUpstreamCount(uint32_t count) { fake_upstreams_count_ = count; } |
92 | | // Skip validation that ensures that all upstream ports are referenced by the |
93 | | // configuration generated in ConfigHelper::finalize. |
94 | 0 | void skipPortUsageValidation() { config_helper_.skipPortUsageValidation(); } |
95 | | // Make test more deterministic by using a fixed RNG value. |
96 | 0 | void setDeterministicValue(uint64_t value = 0) { deterministic_value_ = value; } |
97 | | // Get socket option for a specific listener's socket. |
98 | | bool getSocketOption(const std::string& listener_name, int level, int optname, void* optval, |
99 | | socklen_t* optlen, int address_index = 0); |
100 | | |
101 | 0 | Http::CodecType upstreamProtocol() const { return upstream_config_.upstream_protocol_; } |
102 | | |
103 | | absl::optional<uint64_t> waitForNextRawUpstreamConnection( |
104 | | const std::vector<uint64_t>& upstream_indices, FakeRawConnectionPtr& fake_upstream_connection, |
105 | | std::chrono::milliseconds connection_wait_timeout = TestUtility::DefaultTimeout); |
106 | | |
107 | | IntegrationTcpClientPtr |
108 | | makeTcpConnection(uint32_t port, |
109 | | const Network::ConnectionSocket::OptionsSharedPtr& options = nullptr, |
110 | | Network::Address::InstanceConstSharedPtr source_address = |
111 | | Network::Address::InstanceConstSharedPtr(), |
112 | | absl::string_view destination_address = ""); |
113 | | |
114 | | // Test-wide port map. |
115 | | void registerPort(const std::string& key, uint32_t port); |
116 | | uint32_t lookupPort(const std::string& key); |
117 | | |
118 | | // Set the endpoint's socket address to point at upstream at given index. |
119 | | void setUpstreamAddress(uint32_t upstream_index, |
120 | | envoy::config::endpoint::v3::LbEndpoint& endpoint) const; |
121 | | |
122 | | Network::ClientConnectionPtr makeClientConnection(uint32_t port); |
123 | | virtual Network::ClientConnectionPtr |
124 | | makeClientConnectionWithOptions(uint32_t port, |
125 | | const Network::ConnectionSocket::OptionsSharedPtr& options); |
126 | | |
127 | 0 | void registerTestServerPorts(const std::vector<std::string>& port_names) { |
128 | 0 | registerTestServerPorts(port_names, test_server_); |
129 | 0 | } |
130 | | void registerTestServerPorts(const std::vector<std::string>& port_names, |
131 | | IntegrationTestServerPtr& test_server); |
132 | | void createGeneratedApiTestServer(const std::string& bootstrap_path, |
133 | | const std::vector<std::string>& port_names, |
134 | | Server::FieldValidationConfig validator_config, |
135 | | bool allow_lds_rejection); |
136 | | void createApiTestServer(const ApiFilesystemConfig& api_filesystem_config, |
137 | | const std::vector<std::string>& port_names, |
138 | | Server::FieldValidationConfig validator_config, |
139 | | bool allow_lds_rejection); |
140 | | |
141 | | void createGeneratedApiTestServer(const std::string& bootstrap_path, |
142 | | const std::vector<std::string>& port_names, |
143 | | Server::FieldValidationConfig validator_config, |
144 | | bool allow_lds_rejection, |
145 | | IntegrationTestServerPtr& test_server); |
146 | | |
147 | 4.76k | Event::TestTimeSystem& timeSystem() { return time_system_; } |
148 | | |
149 | | Stats::IsolatedStoreImpl stats_store_; |
150 | | Stats::Scope& stats_scope_{*stats_store_.rootScope()}; |
151 | | Api::ApiPtr api_; |
152 | | Api::ApiPtr api_for_server_stat_store_; |
153 | | MockBufferFactory* mock_buffer_factory_; // Will point to the dispatcher's factory. |
154 | | |
155 | | // Enable the listener access log |
156 | | void useListenerAccessLog(absl::string_view format = ""); |
157 | | // Returns all log entries after the nth access log entry, defaulting to log entry 0. |
158 | | // By default will trigger an expect failure if more than one entry is returned. |
159 | | // If client_connection is provided, flush pending acks to enable deferred logging. |
160 | | std::string waitForAccessLog(const std::string& filename, uint32_t entry = 0, |
161 | | bool allow_excess_entries = false, |
162 | | Network::ClientConnection* client_connection = nullptr); |
163 | | |
164 | | std::string listener_access_log_name_; |
165 | | |
166 | | // Last node received on an xDS stream from the server. |
167 | | envoy::config::core::v3::Node last_node_; |
168 | | |
169 | | // Functions for testing reloadable config (xDS) |
170 | | virtual void createXdsUpstream(); |
171 | | void createXdsConnection(); |
172 | | void cleanUpXdsConnection(); |
173 | | |
174 | | // See if a port can be successfully bound within the given timeout. |
175 | | ABSL_MUST_USE_RESULT AssertionResult waitForPortAvailable( |
176 | | uint32_t port, std::chrono::milliseconds timeout = TestUtility::DefaultTimeout); |
177 | | |
178 | | // Helpers for setting up expectations and making the internal gears turn for xDS request/response |
179 | | // sending/receiving to/from the (imaginary) xDS server. You should almost always use |
180 | | // compareDiscoveryRequest() and sendDiscoveryResponse(), but the SotW/delta-specific versions are |
181 | | // available if you're writing a SotW/delta-specific test. |
182 | | AssertionResult compareDiscoveryRequest( |
183 | | const std::string& expected_type_url, const std::string& expected_version, |
184 | | const std::vector<std::string>& expected_resource_names, |
185 | | const std::vector<std::string>& expected_resource_names_added, |
186 | | const std::vector<std::string>& expected_resource_names_removed, bool expect_node = false, |
187 | | const Protobuf::int32 expected_error_code = Grpc::Status::WellKnownGrpcStatus::Ok, |
188 | | const std::string& expected_error_message = "", FakeStream* stream = nullptr, |
189 | | OptRef<const absl::flat_hash_map<std::string, std::string>> initial_resource_versions = |
190 | | absl::nullopt); |
191 | | |
192 | | template <class T> |
193 | | void |
194 | | sendDiscoveryResponse(const std::string& type_url, const std::vector<T>& state_of_the_world, |
195 | | const std::vector<T>& added_or_updated, |
196 | | const std::vector<std::string>& removed, const std::string& version, |
197 | | const absl::flat_hash_map<std::string, ProtobufWkt::Any>& metadata = {}, |
198 | 172 | FakeStream* stream = nullptr) { |
199 | 172 | if (sotw_or_delta_ == Grpc::SotwOrDelta::Sotw || |
200 | 172 | sotw_or_delta_ == Grpc::SotwOrDelta::UnifiedSotw) { |
201 | 134 | sendSotwDiscoveryResponse(type_url, state_of_the_world, version, stream, metadata); |
202 | 134 | } else { |
203 | 38 | sendDeltaDiscoveryResponse(type_url, added_or_updated, removed, version, stream, {}, |
204 | 38 | metadata); |
205 | 38 | } |
206 | 172 | } void Envoy::BaseIntegrationTest::sendDiscoveryResponse<envoy::config::listener::v3::Listener>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::vector<envoy::config::listener::v3::Listener, std::__1::allocator<envoy::config::listener::v3::Listener> > const&, std::__1::vector<envoy::config::listener::v3::Listener, std::__1::allocator<envoy::config::listener::v3::Listener> > const&, std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, absl::lts_20230802::flat_hash_map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::Any, absl::lts_20230802::container_internal::StringHash, absl::lts_20230802::container_internal::StringEq, std::__1::allocator<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const, google::protobuf::Any> > > const&, Envoy::FakeStream*) Line | Count | Source | 198 | 98 | FakeStream* stream = nullptr) { | 199 | 98 | if (sotw_or_delta_ == Grpc::SotwOrDelta::Sotw || | 200 | 98 | sotw_or_delta_ == Grpc::SotwOrDelta::UnifiedSotw) { | 201 | 74 | sendSotwDiscoveryResponse(type_url, state_of_the_world, version, stream, metadata); | 202 | 74 | } else { | 203 | 24 | sendDeltaDiscoveryResponse(type_url, added_or_updated, removed, version, stream, {}, | 204 | 24 | metadata); | 205 | 24 | } | 206 | 98 | } |
void Envoy::BaseIntegrationTest::sendDiscoveryResponse<envoy::config::route::v3::RouteConfiguration>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::vector<envoy::config::route::v3::RouteConfiguration, std::__1::allocator<envoy::config::route::v3::RouteConfiguration> > const&, std::__1::vector<envoy::config::route::v3::RouteConfiguration, std::__1::allocator<envoy::config::route::v3::RouteConfiguration> > const&, std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, absl::lts_20230802::flat_hash_map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::Any, absl::lts_20230802::container_internal::StringHash, absl::lts_20230802::container_internal::StringEq, std::__1::allocator<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const, google::protobuf::Any> > > const&, Envoy::FakeStream*) Line | Count | Source | 198 | 46 | FakeStream* stream = nullptr) { | 199 | 46 | if (sotw_or_delta_ == Grpc::SotwOrDelta::Sotw || | 200 | 46 | sotw_or_delta_ == Grpc::SotwOrDelta::UnifiedSotw) { | 201 | 40 | sendSotwDiscoveryResponse(type_url, state_of_the_world, version, stream, metadata); | 202 | 40 | } else { | 203 | 6 | sendDeltaDiscoveryResponse(type_url, added_or_updated, removed, version, stream, {}, | 204 | 6 | metadata); | 205 | 6 | } | 206 | 46 | } |
void Envoy::BaseIntegrationTest::sendDiscoveryResponse<envoy::config::cluster::v3::Cluster>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::vector<envoy::config::cluster::v3::Cluster, std::__1::allocator<envoy::config::cluster::v3::Cluster> > const&, std::__1::vector<envoy::config::cluster::v3::Cluster, std::__1::allocator<envoy::config::cluster::v3::Cluster> > const&, std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, absl::lts_20230802::flat_hash_map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::Any, absl::lts_20230802::container_internal::StringHash, absl::lts_20230802::container_internal::StringEq, std::__1::allocator<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const, google::protobuf::Any> > > const&, Envoy::FakeStream*) Line | Count | Source | 198 | 14 | FakeStream* stream = nullptr) { | 199 | 14 | if (sotw_or_delta_ == Grpc::SotwOrDelta::Sotw || | 200 | 14 | sotw_or_delta_ == Grpc::SotwOrDelta::UnifiedSotw) { | 201 | 10 | sendSotwDiscoveryResponse(type_url, state_of_the_world, version, stream, metadata); | 202 | 10 | } else { | 203 | 4 | sendDeltaDiscoveryResponse(type_url, added_or_updated, removed, version, stream, {}, | 204 | 4 | metadata); | 205 | 4 | } | 206 | 14 | } |
void Envoy::BaseIntegrationTest::sendDiscoveryResponse<envoy::config::endpoint::v3::ClusterLoadAssignment>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::vector<envoy::config::endpoint::v3::ClusterLoadAssignment, std::__1::allocator<envoy::config::endpoint::v3::ClusterLoadAssignment> > const&, std::__1::vector<envoy::config::endpoint::v3::ClusterLoadAssignment, std::__1::allocator<envoy::config::endpoint::v3::ClusterLoadAssignment> > const&, std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, absl::lts_20230802::flat_hash_map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::Any, absl::lts_20230802::container_internal::StringHash, absl::lts_20230802::container_internal::StringEq, std::__1::allocator<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const, google::protobuf::Any> > > const&, Envoy::FakeStream*) Line | Count | Source | 198 | 14 | FakeStream* stream = nullptr) { | 199 | 14 | if (sotw_or_delta_ == Grpc::SotwOrDelta::Sotw || | 200 | 14 | sotw_or_delta_ == Grpc::SotwOrDelta::UnifiedSotw) { | 201 | 10 | sendSotwDiscoveryResponse(type_url, state_of_the_world, version, stream, metadata); | 202 | 10 | } else { | 203 | 4 | sendDeltaDiscoveryResponse(type_url, added_or_updated, removed, version, stream, {}, | 204 | 4 | metadata); | 205 | 4 | } | 206 | 14 | } |
|
207 | | |
208 | | AssertionResult compareDeltaDiscoveryRequest( |
209 | | const std::string& expected_type_url, |
210 | | const std::vector<std::string>& expected_resource_subscriptions, |
211 | | const std::vector<std::string>& expected_resource_unsubscriptions, |
212 | | const Protobuf::int32 expected_error_code = Grpc::Status::WellKnownGrpcStatus::Ok, |
213 | 0 | const std::string& expected_error_message = "", bool expect_node = true) { |
214 | 0 | return compareDeltaDiscoveryRequest(expected_type_url, expected_resource_subscriptions, |
215 | 0 | expected_resource_unsubscriptions, xds_stream_.get(), |
216 | 0 | expected_error_code, expected_error_message, expect_node); |
217 | 0 | } |
218 | | |
219 | | AssertionResult compareDeltaDiscoveryRequest( |
220 | | const std::string& expected_type_url, |
221 | | const std::vector<std::string>& expected_resource_subscriptions, |
222 | | const std::vector<std::string>& expected_resource_unsubscriptions, FakeStream* stream, |
223 | | const Protobuf::int32 expected_error_code = Grpc::Status::WellKnownGrpcStatus::Ok, |
224 | | const std::string& expected_error_message = "", bool expect_node = true, |
225 | | OptRef<const absl::flat_hash_map<std::string, std::string>> initial_resource_versions = |
226 | | absl::nullopt); |
227 | | |
228 | | AssertionResult compareSotwDiscoveryRequest( |
229 | | const std::string& expected_type_url, const std::string& expected_version, |
230 | | const std::vector<std::string>& expected_resource_names, bool expect_node = false, |
231 | | const Protobuf::int32 expected_error_code = Grpc::Status::WellKnownGrpcStatus::Ok, |
232 | | const std::string& expected_error_message = "", FakeStream* stream = nullptr); |
233 | | |
234 | | template <class T> |
235 | | void sendSotwDiscoveryResponse(const std::string& type_url, const std::vector<T>& messages, |
236 | | const std::string& version, FakeStream* stream = nullptr) { |
237 | | sendSotwDiscoveryResponse(type_url, messages, version, stream, {}); |
238 | | } |
239 | | template <class T> |
240 | | void |
241 | | sendSotwDiscoveryResponse(const std::string& type_url, const std::vector<T>& messages, |
242 | | const std::string& version, FakeStream* stream, |
243 | 134 | const absl::flat_hash_map<std::string, ProtobufWkt::Any>& metadata) { |
244 | 134 | if (stream == nullptr) { |
245 | 134 | stream = xds_stream_.get(); |
246 | 134 | } |
247 | 134 | envoy::service::discovery::v3::DiscoveryResponse discovery_response; |
248 | 134 | discovery_response.set_version_info(version); |
249 | 134 | discovery_response.set_type_url(type_url); |
250 | 238 | for (const auto& message : messages) { |
251 | 238 | if (!metadata.empty()) { |
252 | 0 | envoy::service::discovery::v3::Resource resource; |
253 | 0 | resource.mutable_resource()->PackFrom(message); |
254 | 0 | resource.set_name(intResourceName(message)); |
255 | 0 | resource.set_version(version); |
256 | 0 | for (const auto& kvp : metadata) { |
257 | 0 | auto* map = resource.mutable_metadata()->mutable_typed_filter_metadata(); |
258 | 0 | (*map)[std::string(kvp.first)] = kvp.second; |
259 | 0 | } |
260 | 0 | discovery_response.add_resources()->PackFrom(resource); |
261 | 238 | } else { |
262 | 238 | discovery_response.add_resources()->PackFrom(message); |
263 | 238 | } |
264 | 238 | } |
265 | 134 | static int next_nonce_counter = 0; |
266 | 134 | discovery_response.set_nonce(absl::StrCat("nonce", next_nonce_counter++)); |
267 | 134 | stream->sendGrpcMessage(discovery_response); |
268 | 134 | } void Envoy::BaseIntegrationTest::sendSotwDiscoveryResponse<envoy::config::listener::v3::Listener>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::vector<envoy::config::listener::v3::Listener, std::__1::allocator<envoy::config::listener::v3::Listener> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, Envoy::FakeStream*, absl::lts_20230802::flat_hash_map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::Any, absl::lts_20230802::container_internal::StringHash, absl::lts_20230802::container_internal::StringEq, std::__1::allocator<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const, google::protobuf::Any> > > const&) Line | Count | Source | 243 | 74 | const absl::flat_hash_map<std::string, ProtobufWkt::Any>& metadata) { | 244 | 74 | if (stream == nullptr) { | 245 | 74 | stream = xds_stream_.get(); | 246 | 74 | } | 247 | 74 | envoy::service::discovery::v3::DiscoveryResponse discovery_response; | 248 | 74 | discovery_response.set_version_info(version); | 249 | 74 | discovery_response.set_type_url(type_url); | 250 | 144 | for (const auto& message : messages) { | 251 | 144 | if (!metadata.empty()) { | 252 | 0 | envoy::service::discovery::v3::Resource resource; | 253 | 0 | resource.mutable_resource()->PackFrom(message); | 254 | 0 | resource.set_name(intResourceName(message)); | 255 | 0 | resource.set_version(version); | 256 | 0 | for (const auto& kvp : metadata) { | 257 | 0 | auto* map = resource.mutable_metadata()->mutable_typed_filter_metadata(); | 258 | 0 | (*map)[std::string(kvp.first)] = kvp.second; | 259 | 0 | } | 260 | 0 | discovery_response.add_resources()->PackFrom(resource); | 261 | 144 | } else { | 262 | 144 | discovery_response.add_resources()->PackFrom(message); | 263 | 144 | } | 264 | 144 | } | 265 | 74 | static int next_nonce_counter = 0; | 266 | 74 | discovery_response.set_nonce(absl::StrCat("nonce", next_nonce_counter++)); | 267 | 74 | stream->sendGrpcMessage(discovery_response); | 268 | 74 | } |
void Envoy::BaseIntegrationTest::sendSotwDiscoveryResponse<envoy::config::route::v3::RouteConfiguration>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::vector<envoy::config::route::v3::RouteConfiguration, std::__1::allocator<envoy::config::route::v3::RouteConfiguration> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, Envoy::FakeStream*, absl::lts_20230802::flat_hash_map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::Any, absl::lts_20230802::container_internal::StringHash, absl::lts_20230802::container_internal::StringEq, std::__1::allocator<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const, google::protobuf::Any> > > const&) Line | Count | Source | 243 | 40 | const absl::flat_hash_map<std::string, ProtobufWkt::Any>& metadata) { | 244 | 40 | if (stream == nullptr) { | 245 | 40 | stream = xds_stream_.get(); | 246 | 40 | } | 247 | 40 | envoy::service::discovery::v3::DiscoveryResponse discovery_response; | 248 | 40 | discovery_response.set_version_info(version); | 249 | 40 | discovery_response.set_type_url(type_url); | 250 | 74 | for (const auto& message : messages) { | 251 | 74 | if (!metadata.empty()) { | 252 | 0 | envoy::service::discovery::v3::Resource resource; | 253 | 0 | resource.mutable_resource()->PackFrom(message); | 254 | 0 | resource.set_name(intResourceName(message)); | 255 | 0 | resource.set_version(version); | 256 | 0 | for (const auto& kvp : metadata) { | 257 | 0 | auto* map = resource.mutable_metadata()->mutable_typed_filter_metadata(); | 258 | 0 | (*map)[std::string(kvp.first)] = kvp.second; | 259 | 0 | } | 260 | 0 | discovery_response.add_resources()->PackFrom(resource); | 261 | 74 | } else { | 262 | 74 | discovery_response.add_resources()->PackFrom(message); | 263 | 74 | } | 264 | 74 | } | 265 | 40 | static int next_nonce_counter = 0; | 266 | 40 | discovery_response.set_nonce(absl::StrCat("nonce", next_nonce_counter++)); | 267 | 40 | stream->sendGrpcMessage(discovery_response); | 268 | 40 | } |
void Envoy::BaseIntegrationTest::sendSotwDiscoveryResponse<envoy::config::cluster::v3::Cluster>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::vector<envoy::config::cluster::v3::Cluster, std::__1::allocator<envoy::config::cluster::v3::Cluster> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, Envoy::FakeStream*, absl::lts_20230802::flat_hash_map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::Any, absl::lts_20230802::container_internal::StringHash, absl::lts_20230802::container_internal::StringEq, std::__1::allocator<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const, google::protobuf::Any> > > const&) Line | Count | Source | 243 | 10 | const absl::flat_hash_map<std::string, ProtobufWkt::Any>& metadata) { | 244 | 10 | if (stream == nullptr) { | 245 | 10 | stream = xds_stream_.get(); | 246 | 10 | } | 247 | 10 | envoy::service::discovery::v3::DiscoveryResponse discovery_response; | 248 | 10 | discovery_response.set_version_info(version); | 249 | 10 | discovery_response.set_type_url(type_url); | 250 | 10 | for (const auto& message : messages) { | 251 | 10 | if (!metadata.empty()) { | 252 | 0 | envoy::service::discovery::v3::Resource resource; | 253 | 0 | resource.mutable_resource()->PackFrom(message); | 254 | 0 | resource.set_name(intResourceName(message)); | 255 | 0 | resource.set_version(version); | 256 | 0 | for (const auto& kvp : metadata) { | 257 | 0 | auto* map = resource.mutable_metadata()->mutable_typed_filter_metadata(); | 258 | 0 | (*map)[std::string(kvp.first)] = kvp.second; | 259 | 0 | } | 260 | 0 | discovery_response.add_resources()->PackFrom(resource); | 261 | 10 | } else { | 262 | 10 | discovery_response.add_resources()->PackFrom(message); | 263 | 10 | } | 264 | 10 | } | 265 | 10 | static int next_nonce_counter = 0; | 266 | 10 | discovery_response.set_nonce(absl::StrCat("nonce", next_nonce_counter++)); | 267 | 10 | stream->sendGrpcMessage(discovery_response); | 268 | 10 | } |
void Envoy::BaseIntegrationTest::sendSotwDiscoveryResponse<envoy::config::endpoint::v3::ClusterLoadAssignment>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::vector<envoy::config::endpoint::v3::ClusterLoadAssignment, std::__1::allocator<envoy::config::endpoint::v3::ClusterLoadAssignment> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, Envoy::FakeStream*, absl::lts_20230802::flat_hash_map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::Any, absl::lts_20230802::container_internal::StringHash, absl::lts_20230802::container_internal::StringEq, std::__1::allocator<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const, google::protobuf::Any> > > const&) Line | Count | Source | 243 | 10 | const absl::flat_hash_map<std::string, ProtobufWkt::Any>& metadata) { | 244 | 10 | if (stream == nullptr) { | 245 | 10 | stream = xds_stream_.get(); | 246 | 10 | } | 247 | 10 | envoy::service::discovery::v3::DiscoveryResponse discovery_response; | 248 | 10 | discovery_response.set_version_info(version); | 249 | 10 | discovery_response.set_type_url(type_url); | 250 | 10 | for (const auto& message : messages) { | 251 | 10 | if (!metadata.empty()) { | 252 | 0 | envoy::service::discovery::v3::Resource resource; | 253 | 0 | resource.mutable_resource()->PackFrom(message); | 254 | 0 | resource.set_name(intResourceName(message)); | 255 | 0 | resource.set_version(version); | 256 | 0 | for (const auto& kvp : metadata) { | 257 | 0 | auto* map = resource.mutable_metadata()->mutable_typed_filter_metadata(); | 258 | 0 | (*map)[std::string(kvp.first)] = kvp.second; | 259 | 0 | } | 260 | 0 | discovery_response.add_resources()->PackFrom(resource); | 261 | 10 | } else { | 262 | 10 | discovery_response.add_resources()->PackFrom(message); | 263 | 10 | } | 264 | 10 | } | 265 | 10 | static int next_nonce_counter = 0; | 266 | 10 | discovery_response.set_nonce(absl::StrCat("nonce", next_nonce_counter++)); | 267 | 10 | stream->sendGrpcMessage(discovery_response); | 268 | 10 | } |
|
269 | | |
270 | | template <class T> |
271 | | void |
272 | | sendDeltaDiscoveryResponse(const std::string& type_url, const std::vector<T>& added_or_updated, |
273 | | const std::vector<std::string>& removed, const std::string& version) { |
274 | | sendDeltaDiscoveryResponse(type_url, added_or_updated, removed, version, xds_stream_.get(), {}, |
275 | | {}); |
276 | | } |
277 | | |
278 | | template <class T> |
279 | | void |
280 | | sendDeltaDiscoveryResponse(const std::string& type_url, const std::vector<T>& added_or_updated, |
281 | | const std::vector<std::string>& removed, const std::string& version, |
282 | | FakeStream* stream, const std::vector<std::string>& aliases = {}) { |
283 | | sendDeltaDiscoveryResponse(type_url, added_or_updated, removed, version, stream, aliases, {}); |
284 | | } |
285 | | |
286 | | template <class T> |
287 | | void |
288 | | sendDeltaDiscoveryResponse(const std::string& type_url, const std::vector<T>& added_or_updated, |
289 | | const std::vector<std::string>& removed, const std::string& version, |
290 | | const absl::flat_hash_map<std::string, ProtobufWkt::Any>& metadata) { |
291 | | sendDeltaDiscoveryResponse(type_url, added_or_updated, removed, version, xds_stream_, {}, |
292 | | metadata); |
293 | | } |
294 | | |
295 | | template <class T> |
296 | | void |
297 | | sendDeltaDiscoveryResponse(const std::string& type_url, const std::vector<T>& added_or_updated, |
298 | | const std::vector<std::string>& removed, const std::string& version, |
299 | | FakeStream* stream, const std::vector<std::string>& aliases, |
300 | 38 | const absl::flat_hash_map<std::string, ProtobufWkt::Any>& metadata) { |
301 | 38 | auto response = createDeltaDiscoveryResponse<T>(type_url, added_or_updated, removed, version, |
302 | 38 | aliases, metadata); |
303 | 38 | if (stream == nullptr) { |
304 | 38 | stream = xds_stream_.get(); |
305 | 38 | } |
306 | 38 | stream->sendGrpcMessage(response); |
307 | 38 | } void Envoy::BaseIntegrationTest::sendDeltaDiscoveryResponse<envoy::config::listener::v3::Listener>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::vector<envoy::config::listener::v3::Listener, std::__1::allocator<envoy::config::listener::v3::Listener> > const&, std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, Envoy::FakeStream*, std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&, absl::lts_20230802::flat_hash_map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::Any, absl::lts_20230802::container_internal::StringHash, absl::lts_20230802::container_internal::StringEq, std::__1::allocator<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const, google::protobuf::Any> > > const&) Line | Count | Source | 300 | 24 | const absl::flat_hash_map<std::string, ProtobufWkt::Any>& metadata) { | 301 | 24 | auto response = createDeltaDiscoveryResponse<T>(type_url, added_or_updated, removed, version, | 302 | 24 | aliases, metadata); | 303 | 24 | if (stream == nullptr) { | 304 | 24 | stream = xds_stream_.get(); | 305 | 24 | } | 306 | 24 | stream->sendGrpcMessage(response); | 307 | 24 | } |
void Envoy::BaseIntegrationTest::sendDeltaDiscoveryResponse<envoy::config::route::v3::RouteConfiguration>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::vector<envoy::config::route::v3::RouteConfiguration, std::__1::allocator<envoy::config::route::v3::RouteConfiguration> > const&, std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, Envoy::FakeStream*, std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&, absl::lts_20230802::flat_hash_map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::Any, absl::lts_20230802::container_internal::StringHash, absl::lts_20230802::container_internal::StringEq, std::__1::allocator<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const, google::protobuf::Any> > > const&) Line | Count | Source | 300 | 6 | const absl::flat_hash_map<std::string, ProtobufWkt::Any>& metadata) { | 301 | 6 | auto response = createDeltaDiscoveryResponse<T>(type_url, added_or_updated, removed, version, | 302 | 6 | aliases, metadata); | 303 | 6 | if (stream == nullptr) { | 304 | 6 | stream = xds_stream_.get(); | 305 | 6 | } | 306 | 6 | stream->sendGrpcMessage(response); | 307 | 6 | } |
void Envoy::BaseIntegrationTest::sendDeltaDiscoveryResponse<envoy::config::cluster::v3::Cluster>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::vector<envoy::config::cluster::v3::Cluster, std::__1::allocator<envoy::config::cluster::v3::Cluster> > const&, std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, Envoy::FakeStream*, std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&, absl::lts_20230802::flat_hash_map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::Any, absl::lts_20230802::container_internal::StringHash, absl::lts_20230802::container_internal::StringEq, std::__1::allocator<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const, google::protobuf::Any> > > const&) Line | Count | Source | 300 | 4 | const absl::flat_hash_map<std::string, ProtobufWkt::Any>& metadata) { | 301 | 4 | auto response = createDeltaDiscoveryResponse<T>(type_url, added_or_updated, removed, version, | 302 | 4 | aliases, metadata); | 303 | 4 | if (stream == nullptr) { | 304 | 4 | stream = xds_stream_.get(); | 305 | 4 | } | 306 | 4 | stream->sendGrpcMessage(response); | 307 | 4 | } |
void Envoy::BaseIntegrationTest::sendDeltaDiscoveryResponse<envoy::config::endpoint::v3::ClusterLoadAssignment>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::vector<envoy::config::endpoint::v3::ClusterLoadAssignment, std::__1::allocator<envoy::config::endpoint::v3::ClusterLoadAssignment> > const&, std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, Envoy::FakeStream*, std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&, absl::lts_20230802::flat_hash_map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::Any, absl::lts_20230802::container_internal::StringHash, absl::lts_20230802::container_internal::StringEq, std::__1::allocator<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const, google::protobuf::Any> > > const&) Line | Count | Source | 300 | 4 | const absl::flat_hash_map<std::string, ProtobufWkt::Any>& metadata) { | 301 | 4 | auto response = createDeltaDiscoveryResponse<T>(type_url, added_or_updated, removed, version, | 302 | 4 | aliases, metadata); | 303 | 4 | if (stream == nullptr) { | 304 | 4 | stream = xds_stream_.get(); | 305 | 4 | } | 306 | 4 | stream->sendGrpcMessage(response); | 307 | 4 | } |
|
308 | | |
309 | | // Sends a DeltaDiscoveryResponse with a given list of added resources. |
310 | | // Note that the resources are expected to be of the same type, and match type_url. |
311 | | void sendExplicitResourcesDeltaDiscoveryResponse( |
312 | | const std::string& type_url, |
313 | | const std::vector<envoy::service::discovery::v3::Resource>& added_or_updated, |
314 | 0 | const std::vector<std::string>& removed) { |
315 | 0 | xds_stream_->sendGrpcMessage( |
316 | 0 | createExplicitResourcesDeltaDiscoveryResponse(type_url, added_or_updated, removed)); |
317 | 0 | } |
318 | | |
319 | | envoy::service::discovery::v3::DeltaDiscoveryResponse |
320 | | createExplicitResourcesDeltaDiscoveryResponse( |
321 | | const std::string& type_url, |
322 | | const std::vector<envoy::service::discovery::v3::Resource>& added_or_updated, |
323 | | const std::vector<std::string>& removed); |
324 | | |
325 | | template <class T> |
326 | | envoy::service::discovery::v3::DeltaDiscoveryResponse |
327 | | createDeltaDiscoveryResponse(const std::string& type_url, const std::vector<T>& added_or_updated, |
328 | | const std::vector<std::string>& removed, const std::string& version, |
329 | | const std::vector<std::string>& aliases, |
330 | 38 | const absl::flat_hash_map<std::string, ProtobufWkt::Any>& metadata) { |
331 | 38 | std::vector<envoy::service::discovery::v3::Resource> resources; |
332 | 38 | for (const auto& message : added_or_updated) { |
333 | 38 | envoy::service::discovery::v3::Resource resource; |
334 | 38 | resource.mutable_resource()->PackFrom(message); |
335 | 38 | resource.set_name(intResourceName(message)); |
336 | 38 | resource.set_version(version); |
337 | 38 | for (const auto& alias : aliases) { |
338 | 0 | resource.add_aliases(alias); |
339 | 0 | } |
340 | 38 | for (const auto& kvp : metadata) { |
341 | 0 | auto* map = resource.mutable_metadata()->mutable_typed_filter_metadata(); |
342 | 0 | (*map)[std::string(kvp.first)] = kvp.second; |
343 | 0 | } |
344 | 38 | resources.emplace_back(resource); |
345 | 38 | } |
346 | 38 | return createExplicitResourcesDeltaDiscoveryResponse(type_url, resources, removed); |
347 | 38 | } envoy::service::discovery::v3::DeltaDiscoveryResponse Envoy::BaseIntegrationTest::createDeltaDiscoveryResponse<envoy::config::listener::v3::Listener>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::vector<envoy::config::listener::v3::Listener, std::__1::allocator<envoy::config::listener::v3::Listener> > const&, std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&, absl::lts_20230802::flat_hash_map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::Any, absl::lts_20230802::container_internal::StringHash, absl::lts_20230802::container_internal::StringEq, std::__1::allocator<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const, google::protobuf::Any> > > const&) Line | Count | Source | 330 | 24 | const absl::flat_hash_map<std::string, ProtobufWkt::Any>& metadata) { | 331 | 24 | std::vector<envoy::service::discovery::v3::Resource> resources; | 332 | 24 | for (const auto& message : added_or_updated) { | 333 | 24 | envoy::service::discovery::v3::Resource resource; | 334 | 24 | resource.mutable_resource()->PackFrom(message); | 335 | 24 | resource.set_name(intResourceName(message)); | 336 | 24 | resource.set_version(version); | 337 | 24 | for (const auto& alias : aliases) { | 338 | 0 | resource.add_aliases(alias); | 339 | 0 | } | 340 | 24 | for (const auto& kvp : metadata) { | 341 | 0 | auto* map = resource.mutable_metadata()->mutable_typed_filter_metadata(); | 342 | 0 | (*map)[std::string(kvp.first)] = kvp.second; | 343 | 0 | } | 344 | 24 | resources.emplace_back(resource); | 345 | 24 | } | 346 | 24 | return createExplicitResourcesDeltaDiscoveryResponse(type_url, resources, removed); | 347 | 24 | } |
envoy::service::discovery::v3::DeltaDiscoveryResponse Envoy::BaseIntegrationTest::createDeltaDiscoveryResponse<envoy::config::route::v3::RouteConfiguration>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::vector<envoy::config::route::v3::RouteConfiguration, std::__1::allocator<envoy::config::route::v3::RouteConfiguration> > const&, std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&, absl::lts_20230802::flat_hash_map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::Any, absl::lts_20230802::container_internal::StringHash, absl::lts_20230802::container_internal::StringEq, std::__1::allocator<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const, google::protobuf::Any> > > const&) Line | Count | Source | 330 | 6 | const absl::flat_hash_map<std::string, ProtobufWkt::Any>& metadata) { | 331 | 6 | std::vector<envoy::service::discovery::v3::Resource> resources; | 332 | 6 | for (const auto& message : added_or_updated) { | 333 | 6 | envoy::service::discovery::v3::Resource resource; | 334 | 6 | resource.mutable_resource()->PackFrom(message); | 335 | 6 | resource.set_name(intResourceName(message)); | 336 | 6 | resource.set_version(version); | 337 | 6 | for (const auto& alias : aliases) { | 338 | 0 | resource.add_aliases(alias); | 339 | 0 | } | 340 | 6 | for (const auto& kvp : metadata) { | 341 | 0 | auto* map = resource.mutable_metadata()->mutable_typed_filter_metadata(); | 342 | 0 | (*map)[std::string(kvp.first)] = kvp.second; | 343 | 0 | } | 344 | 6 | resources.emplace_back(resource); | 345 | 6 | } | 346 | 6 | return createExplicitResourcesDeltaDiscoveryResponse(type_url, resources, removed); | 347 | 6 | } |
envoy::service::discovery::v3::DeltaDiscoveryResponse Envoy::BaseIntegrationTest::createDeltaDiscoveryResponse<envoy::config::cluster::v3::Cluster>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::vector<envoy::config::cluster::v3::Cluster, std::__1::allocator<envoy::config::cluster::v3::Cluster> > const&, std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&, absl::lts_20230802::flat_hash_map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::Any, absl::lts_20230802::container_internal::StringHash, absl::lts_20230802::container_internal::StringEq, std::__1::allocator<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const, google::protobuf::Any> > > const&) Line | Count | Source | 330 | 4 | const absl::flat_hash_map<std::string, ProtobufWkt::Any>& metadata) { | 331 | 4 | std::vector<envoy::service::discovery::v3::Resource> resources; | 332 | 4 | for (const auto& message : added_or_updated) { | 333 | 4 | envoy::service::discovery::v3::Resource resource; | 334 | 4 | resource.mutable_resource()->PackFrom(message); | 335 | 4 | resource.set_name(intResourceName(message)); | 336 | 4 | resource.set_version(version); | 337 | 4 | for (const auto& alias : aliases) { | 338 | 0 | resource.add_aliases(alias); | 339 | 0 | } | 340 | 4 | for (const auto& kvp : metadata) { | 341 | 0 | auto* map = resource.mutable_metadata()->mutable_typed_filter_metadata(); | 342 | 0 | (*map)[std::string(kvp.first)] = kvp.second; | 343 | 0 | } | 344 | 4 | resources.emplace_back(resource); | 345 | 4 | } | 346 | 4 | return createExplicitResourcesDeltaDiscoveryResponse(type_url, resources, removed); | 347 | 4 | } |
envoy::service::discovery::v3::DeltaDiscoveryResponse Envoy::BaseIntegrationTest::createDeltaDiscoveryResponse<envoy::config::endpoint::v3::ClusterLoadAssignment>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::vector<envoy::config::endpoint::v3::ClusterLoadAssignment, std::__1::allocator<envoy::config::endpoint::v3::ClusterLoadAssignment> > const&, std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&, absl::lts_20230802::flat_hash_map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::Any, absl::lts_20230802::container_internal::StringHash, absl::lts_20230802::container_internal::StringEq, std::__1::allocator<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const, google::protobuf::Any> > > const&) Line | Count | Source | 330 | 4 | const absl::flat_hash_map<std::string, ProtobufWkt::Any>& metadata) { | 331 | 4 | std::vector<envoy::service::discovery::v3::Resource> resources; | 332 | 4 | for (const auto& message : added_or_updated) { | 333 | 4 | envoy::service::discovery::v3::Resource resource; | 334 | 4 | resource.mutable_resource()->PackFrom(message); | 335 | 4 | resource.set_name(intResourceName(message)); | 336 | 4 | resource.set_version(version); | 337 | 4 | for (const auto& alias : aliases) { | 338 | 0 | resource.add_aliases(alias); | 339 | 0 | } | 340 | 4 | for (const auto& kvp : metadata) { | 341 | 0 | auto* map = resource.mutable_metadata()->mutable_typed_filter_metadata(); | 342 | 0 | (*map)[std::string(kvp.first)] = kvp.second; | 343 | 0 | } | 344 | 4 | resources.emplace_back(resource); | 345 | 4 | } | 346 | 4 | return createExplicitResourcesDeltaDiscoveryResponse(type_url, resources, removed); | 347 | 4 | } |
|
348 | | |
349 | | private: |
350 | 38 | template <class T> std::string intResourceName(const T& m) { |
351 | | // gcc doesn't allow inline template function to be specialized, using a constexpr if to |
352 | | // workaround. |
353 | 38 | if constexpr (std::is_same_v<T, envoy::config::endpoint::v3::ClusterLoadAssignment>) { |
354 | 34 | return m.cluster_name(); |
355 | 34 | } else { |
356 | 34 | return m.name(); |
357 | 34 | } |
358 | 38 | } std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > Envoy::BaseIntegrationTest::intResourceName<envoy::config::listener::v3::Listener>(envoy::config::listener::v3::Listener const&) Line | Count | Source | 350 | 24 | template <class T> std::string intResourceName(const T& m) { | 351 | | // gcc doesn't allow inline template function to be specialized, using a constexpr if to | 352 | | // workaround. | 353 | 24 | if constexpr (std::is_same_v<T, envoy::config::endpoint::v3::ClusterLoadAssignment>) { | 354 | 24 | return m.cluster_name(); | 355 | 24 | } else { | 356 | 24 | return m.name(); | 357 | 24 | } | 358 | 24 | } |
std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > Envoy::BaseIntegrationTest::intResourceName<envoy::config::route::v3::RouteConfiguration>(envoy::config::route::v3::RouteConfiguration const&) Line | Count | Source | 350 | 6 | template <class T> std::string intResourceName(const T& m) { | 351 | | // gcc doesn't allow inline template function to be specialized, using a constexpr if to | 352 | | // workaround. | 353 | 6 | if constexpr (std::is_same_v<T, envoy::config::endpoint::v3::ClusterLoadAssignment>) { | 354 | 6 | return m.cluster_name(); | 355 | 6 | } else { | 356 | 6 | return m.name(); | 357 | 6 | } | 358 | 6 | } |
std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > Envoy::BaseIntegrationTest::intResourceName<envoy::config::cluster::v3::Cluster>(envoy::config::cluster::v3::Cluster const&) Line | Count | Source | 350 | 4 | template <class T> std::string intResourceName(const T& m) { | 351 | | // gcc doesn't allow inline template function to be specialized, using a constexpr if to | 352 | | // workaround. | 353 | 4 | if constexpr (std::is_same_v<T, envoy::config::endpoint::v3::ClusterLoadAssignment>) { | 354 | 4 | return m.cluster_name(); | 355 | 4 | } else { | 356 | 4 | return m.name(); | 357 | 4 | } | 358 | 4 | } |
std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > Envoy::BaseIntegrationTest::intResourceName<envoy::config::endpoint::v3::ClusterLoadAssignment>(envoy::config::endpoint::v3::ClusterLoadAssignment const&) Line | Count | Source | 350 | 4 | template <class T> std::string intResourceName(const T& m) { | 351 | | // gcc doesn't allow inline template function to be specialized, using a constexpr if to | 352 | | // workaround. | 353 | 4 | if constexpr (std::is_same_v<T, envoy::config::endpoint::v3::ClusterLoadAssignment>) { | 354 | 4 | return m.cluster_name(); | 355 | 4 | } else { | 356 | 4 | return m.name(); | 357 | 4 | } | 358 | 4 | } |
|
359 | | |
360 | | Event::GlobalTimeSystem time_system_; |
361 | | |
362 | | public: |
363 | | Event::DispatcherPtr dispatcher_; |
364 | | |
365 | | /** |
366 | | * Open a connection to Envoy, send a series of bytes, and return the |
367 | | * response. This function will continue reading response bytes until Envoy |
368 | | * closes the connection (as a part of error handling) or (if configured true) |
369 | | * the complete headers are read. |
370 | | * |
371 | | * @param port the port to connect to. |
372 | | * @param raw_http the data to send. |
373 | | * @param response the response data will be sent here. |
374 | | * @param disconnect_after_headers_complete if the connection should be terminated once "\r\n\r\n" |
375 | | * has been read. |
376 | | * @param transport_socket the transport socket of the created client connection. |
377 | | **/ |
378 | | void sendRawHttpAndWaitForResponse(int port, const char* raw_http, std::string* response, |
379 | | bool disconnect_after_headers_complete = false, |
380 | | Network::TransportSocketPtr transport_socket = nullptr); |
381 | | |
382 | | /** |
383 | | * Helper to create ConnectionDriver. |
384 | | * |
385 | | * @param port the port to connect to. |
386 | | * @param initial_data the data to send. |
387 | | * @param data_callback the callback on the received data. |
388 | | **/ |
389 | | std::unique_ptr<RawConnectionDriver> createConnectionDriver( |
390 | | uint32_t port, const std::string& initial_data, |
391 | | std::function<void(Network::ClientConnection&, const Buffer::Instance&)>&& data_callback, |
392 | 0 | Network::TransportSocketPtr transport_socket = nullptr) { |
393 | 0 | Buffer::OwnedImpl buffer(initial_data); |
394 | 0 | return std::make_unique<RawConnectionDriver>(port, buffer, data_callback, version_, |
395 | 0 | *dispatcher_, std::move(transport_socket)); |
396 | 0 | } |
397 | | |
398 | | /** |
399 | | * Helper to create ConnectionDriver. |
400 | | * |
401 | | * @param port the port to connect to. |
402 | | * @param write_request_cb callback used to send data. |
403 | | * @param data_callback the callback on the received data. |
404 | | * @param transport_socket transport socket to use for the client connection |
405 | | **/ |
406 | | std::unique_ptr<RawConnectionDriver> createConnectionDriver( |
407 | | uint32_t port, RawConnectionDriver::DoWriteCallback write_request_cb, |
408 | | std::function<void(Network::ClientConnection&, const Buffer::Instance&)>&& data_callback, |
409 | 0 | Network::TransportSocketPtr transport_socket = nullptr) { |
410 | 0 | return std::make_unique<RawConnectionDriver>(port, write_request_cb, data_callback, version_, |
411 | 0 | *dispatcher_, std::move(transport_socket)); |
412 | 0 | } |
413 | | |
414 | 14 | FakeUpstreamConfig configWithType(Http::CodecType type) const { |
415 | 14 | FakeUpstreamConfig config = upstream_config_; |
416 | 14 | config.upstream_protocol_ = type; |
417 | 14 | if (type != Http::CodecType::HTTP3) { |
418 | 14 | config.udp_fake_upstream_ = absl::nullopt; |
419 | 14 | } |
420 | 14 | return config; |
421 | 14 | } |
422 | | |
423 | 14 | FakeUpstream& addFakeUpstream(Http::CodecType type) { |
424 | 14 | auto config = configWithType(type); |
425 | 14 | fake_upstreams_.emplace_back(std::make_unique<FakeUpstream>(0, version_, config)); |
426 | 14 | return *fake_upstreams_.back(); |
427 | 14 | } |
428 | | |
429 | | // Adds a fake upstream to the integration test setup. If `autonomous_upstream` is true, then a |
430 | | // AutonomousUpstream instance will be created instead of a FakeUpstream instance. If |
431 | | // `autonomous_upstream` is true, then `autonomous_allow_incomplete_streams` determines whether |
432 | | // an end-of-stream is required on connections between the Envoy and the fake upstream. If |
433 | | // `autonomous_upstream` is false, then `autonomous_allow_incomplete_streams` is ignored. |
434 | | FakeUpstream& |
435 | | addFakeUpstream(Network::DownstreamTransportSocketFactoryPtr&& transport_socket_factory, |
436 | | Http::CodecType type, bool autonomous_upstream, |
437 | 0 | bool autonomous_allow_incomplete_streams = false) { |
438 | 0 | auto config = configWithType(type); |
439 | 0 | if (autonomous_upstream) { |
440 | 0 | fake_upstreams_.emplace_back( |
441 | 0 | std::make_unique<AutonomousUpstream>(std::move(transport_socket_factory), 0, version_, |
442 | 0 | config, autonomous_allow_incomplete_streams)); |
443 | 0 | } else { |
444 | 0 | fake_upstreams_.emplace_back( |
445 | 0 | std::make_unique<FakeUpstream>(std::move(transport_socket_factory), 0, version_, config)); |
446 | 0 | } |
447 | 0 | return *fake_upstreams_.back(); |
448 | 0 | } |
449 | | |
450 | 0 | void setDrainTime(std::chrono::seconds drain_time) { drain_time_ = drain_time; } |
451 | | |
452 | | protected: |
453 | | static std::string finalizeConfigWithPorts(ConfigHelper& helper, std::vector<uint32_t>& ports, |
454 | | bool use_lds); |
455 | | |
456 | 0 | void setUdpFakeUpstream(absl::optional<FakeUpstreamConfig::UdpConfig> config) { |
457 | 0 | upstream_config_.udp_fake_upstream_ = config; |
458 | 0 | } |
459 | 0 | bool initialized() const { return initialized_; } |
460 | | |
461 | | // Right now half-close is set globally, not separately for upstream and |
462 | | // downstream. |
463 | 0 | void enableHalfClose(bool value) { upstream_config_.enable_half_close_ = value; } |
464 | | |
465 | 2.92k | bool enableHalfClose() { return upstream_config_.enable_half_close_; } |
466 | | |
467 | 1.97k | FakeUpstreamConfig& upstreamConfig() { return upstream_config_; } |
468 | 0 | void setMaxRequestHeadersKb(uint32_t value) { upstream_config_.max_request_headers_kb_ = value; } |
469 | 0 | void setMaxRequestHeadersCount(uint32_t value) { |
470 | 0 | upstream_config_.max_request_headers_count_ = value; |
471 | 0 | } |
472 | | |
473 | 0 | void setServerBufferFactory(Buffer::WatermarkFactorySharedPtr proxy_buffer_factory) { |
474 | 0 | ASSERT(!test_server_, "Proxy buffer factory must be set before test server creation"); |
475 | 0 | proxy_buffer_factory_ = proxy_buffer_factory; |
476 | 0 | } |
477 | | |
478 | 0 | void mergeOptions(envoy::config::core::v3::Http2ProtocolOptions& options) { |
479 | 0 | upstream_config_.http2_options_.MergeFrom(options); |
480 | 0 | } |
481 | 0 | void mergeOptions(envoy::config::listener::v3::QuicProtocolOptions& options) { |
482 | 0 | upstream_config_.quic_options_.MergeFrom(options); |
483 | 0 | } |
484 | | |
485 | | void checkForMissingTagExtractionRules(); |
486 | | |
487 | | // Sets the timeout to wait for listeners to be created before invoking |
488 | | // registerTestServerPorts(), as that needs to know about the bound listener ports. |
489 | | // Needs to be called before invoking createEnvoy() (invoked during initialize()). |
490 | 0 | void setListenersBoundTimeout(const std::chrono::milliseconds& duration) { |
491 | 0 | listeners_bound_timeout_ms_ = duration; |
492 | 0 | } |
493 | | |
494 | | std::unique_ptr<Stats::Store> upstream_stats_store_; |
495 | | |
496 | | // Make sure the test server will be torn down after any fake client. |
497 | | // The test server owns the runtime, which is often accessed by client and |
498 | | // fake upstream codecs and must outlast them. |
499 | | IntegrationTestServerPtr test_server_; |
500 | | |
501 | | // The IpVersion (IPv4, IPv6) to use. |
502 | | Network::Address::IpVersion version_; |
503 | | // IP Address to use when binding sockets on upstreams. |
504 | | InstanceConstSharedPtrFn upstream_address_fn_; |
505 | | // The config for envoy start-up. |
506 | | ConfigHelper config_helper_; |
507 | | // The ProcessObject to use when constructing the envoy server. |
508 | | ProcessObjectOptRef process_object_{absl::nullopt}; |
509 | | |
510 | | // Steps that should be done before the envoy server starting. |
511 | | std::function<void(IntegrationTestServer&)> on_server_ready_function_; |
512 | | |
513 | | // Steps that should be done in parallel with the envoy server starting. E.g., xDS |
514 | | // pre-init, control plane synchronization needed for server start. |
515 | | std::function<void()> on_server_init_function_; |
516 | | |
517 | | // A map of keys to port names. Generally the names are pulled from the v2 listener name |
518 | | // but if a listener is created via ADS, it will be from whatever key is used with registerPort. |
519 | | TestEnvironment::PortMap port_map_; |
520 | | |
521 | | // The DrainStrategy that dictates the behaviour of |
522 | | // DrainManagerImpl::drainClose(). |
523 | | Server::DrainStrategy drain_strategy_{Server::DrainStrategy::Gradual}; |
524 | | |
525 | | // Member variables for xDS testing. |
526 | | FakeUpstream* xds_upstream_{}; |
527 | | FakeHttpConnectionPtr xds_connection_; |
528 | | FakeStreamPtr xds_stream_; |
529 | | bool create_xds_upstream_{false}; |
530 | | bool tls_xds_upstream_{false}; |
531 | | bool use_lds_{true}; // Use the integration framework's LDS set up. |
532 | | bool upstream_tls_{false}; |
533 | | |
534 | | Network::DownstreamTransportSocketFactoryPtr |
535 | | createUpstreamTlsContext(const FakeUpstreamConfig& upstream_config); |
536 | | testing::NiceMock<ThreadLocal::MockInstance> thread_local_; |
537 | | testing::NiceMock<Server::Configuration::MockTransportSocketFactoryContext> factory_context_; |
538 | | testing::NiceMock<Server::Configuration::MockServerFactoryContext> server_factory_context_; |
539 | | Extensions::TransportSockets::Tls::ContextManagerImpl context_manager_{server_factory_context_}; |
540 | | |
541 | | // The fake upstreams_ are created using the context_manager, so make sure |
542 | | // they are destroyed before it is. |
543 | | std::vector<std::unique_ptr<FakeUpstream>> fake_upstreams_; |
544 | | |
545 | | Grpc::SotwOrDelta sotw_or_delta_{Grpc::SotwOrDelta::Sotw}; |
546 | | |
547 | | spdlog::level::level_enum default_log_level_; |
548 | | |
549 | | // Timeout to wait for listeners to be created before invoking |
550 | | // registerTestServerPorts(), as that needs to know about the bound listener ports. |
551 | | // Using 2x default timeout to cover for slow TLS implementations (no inline asm) on slow |
552 | | // computers (e.g., Raspberry Pi) that sometimes time out on TLS listeners, or when |
553 | | // the number of listeners in a test is large. |
554 | | std::chrono::milliseconds listeners_bound_timeout_ms_{2 * TestUtility::DefaultTimeout}; |
555 | | |
556 | | // Target number of upstreams. |
557 | | uint32_t fake_upstreams_count_{1}; |
558 | | |
559 | | // The duration of the drain manager graceful drain period. |
560 | | std::chrono::seconds drain_time_{1}; |
561 | | |
562 | | // The number of worker threads that the test server uses. |
563 | | uint32_t concurrency_{1}; |
564 | | |
565 | | // If true, use AutonomousUpstream for fake upstreams. |
566 | | bool autonomous_upstream_{false}; |
567 | | |
568 | | // If true, allow incomplete streams in AutonomousUpstream |
569 | | // This does nothing if autonomous_upstream_ is false |
570 | | bool autonomous_allow_incomplete_streams_{false}; |
571 | | |
572 | | // If this member is not empty, the test will use a fixed RNG value specified |
573 | | // by it. |
574 | | absl::optional<uint64_t> deterministic_value_{}; |
575 | | |
576 | | // Set true when your test will itself take care of ensuring listeners are up, and registering |
577 | | // them in the port_map_. |
578 | | bool defer_listener_finalization_{false}; |
579 | | |
580 | | // By default the test server will use custom stats to notify on increment. |
581 | | // This override exists for tests measuring stats memory. |
582 | | bool use_real_stats_{}; |
583 | | |
584 | | // If true, skip checking stats for missing tag-extraction rules. |
585 | | bool skip_tag_extraction_rule_check_{true}; |
586 | | |
587 | | // By default, node metadata (node name, cluster name, locality) for the test server gets set to |
588 | | // hard-coded values in the OptionsImpl ("node_name", "cluster_name", etc.). Set to true if your |
589 | | // test specifies the node metadata in the Bootstrap configuration and that's what you want to use |
590 | | // for node info in Envoy. |
591 | | bool use_bootstrap_node_metadata_{false}; |
592 | | |
593 | | private: |
594 | | // Configuration for the fake upstream. |
595 | | FakeUpstreamConfig upstream_config_{time_system_}; |
596 | | // True if initialize() has been called. |
597 | | bool initialized_{}; |
598 | | // Optional factory that the proxy-under-test should use to create watermark buffers. If nullptr, |
599 | | // the proxy uses the default watermark buffer factory to create buffers. |
600 | | Buffer::WatermarkFactorySharedPtr proxy_buffer_factory_; |
601 | | }; |
602 | | |
603 | | } // namespace Envoy |