Coverage Report

Created: 2024-09-19 09:45

/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