Coverage Report

Created: 2023-11-12 09:30

/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/extensions/transport_sockets/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
2.64k
  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
9.05k
  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
  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 = "");
189
190
  template <class T>
191
  void
192
  sendDiscoveryResponse(const std::string& type_url, const std::vector<T>& state_of_the_world,
193
                        const std::vector<T>& added_or_updated,
194
                        const std::vector<std::string>& removed, const std::string& version,
195
172
                        const absl::flat_hash_map<std::string, ProtobufWkt::Any>& metadata = {}) {
196
172
    if (sotw_or_delta_ == Grpc::SotwOrDelta::Sotw ||
197
172
        sotw_or_delta_ == Grpc::SotwOrDelta::UnifiedSotw) {
198
134
      sendSotwDiscoveryResponse(type_url, state_of_the_world, version, nullptr, metadata);
199
134
    } else {
200
38
      sendDeltaDiscoveryResponse(type_url, added_or_updated, removed, version, metadata);
201
38
    }
202
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::flat_hash_map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::Any, absl::container_internal::StringHash, absl::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
195
98
                        const absl::flat_hash_map<std::string, ProtobufWkt::Any>& metadata = {}) {
196
98
    if (sotw_or_delta_ == Grpc::SotwOrDelta::Sotw ||
197
98
        sotw_or_delta_ == Grpc::SotwOrDelta::UnifiedSotw) {
198
74
      sendSotwDiscoveryResponse(type_url, state_of_the_world, version, nullptr, metadata);
199
74
    } else {
200
24
      sendDeltaDiscoveryResponse(type_url, added_or_updated, removed, version, metadata);
201
24
    }
202
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::flat_hash_map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::Any, absl::container_internal::StringHash, absl::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
195
46
                        const absl::flat_hash_map<std::string, ProtobufWkt::Any>& metadata = {}) {
196
46
    if (sotw_or_delta_ == Grpc::SotwOrDelta::Sotw ||
197
46
        sotw_or_delta_ == Grpc::SotwOrDelta::UnifiedSotw) {
198
40
      sendSotwDiscoveryResponse(type_url, state_of_the_world, version, nullptr, metadata);
199
40
    } else {
200
6
      sendDeltaDiscoveryResponse(type_url, added_or_updated, removed, version, metadata);
201
6
    }
202
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::flat_hash_map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::Any, absl::container_internal::StringHash, absl::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
195
14
                        const absl::flat_hash_map<std::string, ProtobufWkt::Any>& metadata = {}) {
196
14
    if (sotw_or_delta_ == Grpc::SotwOrDelta::Sotw ||
197
14
        sotw_or_delta_ == Grpc::SotwOrDelta::UnifiedSotw) {
198
10
      sendSotwDiscoveryResponse(type_url, state_of_the_world, version, nullptr, metadata);
199
10
    } else {
200
4
      sendDeltaDiscoveryResponse(type_url, added_or_updated, removed, version, metadata);
201
4
    }
202
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::flat_hash_map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::Any, absl::container_internal::StringHash, absl::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
195
14
                        const absl::flat_hash_map<std::string, ProtobufWkt::Any>& metadata = {}) {
196
14
    if (sotw_or_delta_ == Grpc::SotwOrDelta::Sotw ||
197
14
        sotw_or_delta_ == Grpc::SotwOrDelta::UnifiedSotw) {
198
10
      sendSotwDiscoveryResponse(type_url, state_of_the_world, version, nullptr, metadata);
199
10
    } else {
200
4
      sendDeltaDiscoveryResponse(type_url, added_or_updated, removed, version, metadata);
201
4
    }
202
14
  }
203
204
  AssertionResult compareDeltaDiscoveryRequest(
205
      const std::string& expected_type_url,
206
      const std::vector<std::string>& expected_resource_subscriptions,
207
      const std::vector<std::string>& expected_resource_unsubscriptions,
208
      const Protobuf::int32 expected_error_code = Grpc::Status::WellKnownGrpcStatus::Ok,
209
8
      const std::string& expected_error_message = "", bool expect_node = true) {
210
8
    return compareDeltaDiscoveryRequest(expected_type_url, expected_resource_subscriptions,
211
8
                                        expected_resource_unsubscriptions, xds_stream_,
212
8
                                        expected_error_code, expected_error_message, expect_node);
213
8
  }
214
215
  AssertionResult compareDeltaDiscoveryRequest(
216
      const std::string& expected_type_url,
217
      const std::vector<std::string>& expected_resource_subscriptions,
218
      const std::vector<std::string>& expected_resource_unsubscriptions, FakeStreamPtr& stream,
219
      const Protobuf::int32 expected_error_code = Grpc::Status::WellKnownGrpcStatus::Ok,
220
      const std::string& expected_error_message = "", bool expect_node = true);
221
222
  AssertionResult compareSotwDiscoveryRequest(
223
      const std::string& expected_type_url, const std::string& expected_version,
224
      const std::vector<std::string>& expected_resource_names, bool expect_node = false,
225
      const Protobuf::int32 expected_error_code = Grpc::Status::WellKnownGrpcStatus::Ok,
226
      const std::string& expected_error_message = "", FakeStream* stream = nullptr);
227
228
  template <class T>
229
  void sendSotwDiscoveryResponse(const std::string& type_url, const std::vector<T>& messages,
230
                                 const std::string& version, FakeStream* stream = nullptr) {
231
    sendSotwDiscoveryResponse(type_url, messages, version, stream, {});
232
  }
233
  template <class T>
234
  void
235
  sendSotwDiscoveryResponse(const std::string& type_url, const std::vector<T>& messages,
236
                            const std::string& version, FakeStream* stream,
237
134
                            const absl::flat_hash_map<std::string, ProtobufWkt::Any>& metadata) {
238
134
    if (stream == nullptr) {
239
134
      stream = xds_stream_.get();
240
134
    }
241
134
    envoy::service::discovery::v3::DiscoveryResponse discovery_response;
242
134
    discovery_response.set_version_info(version);
243
134
    discovery_response.set_type_url(type_url);
244
238
    for (const auto& message : messages) {
245
238
      if (!metadata.empty()) {
246
0
        envoy::service::discovery::v3::Resource resource;
247
0
        resource.mutable_resource()->PackFrom(message);
248
0
        resource.set_name(intResourceName(message));
249
0
        resource.set_version(version);
250
0
        for (const auto& kvp : metadata) {
251
0
          auto* map = resource.mutable_metadata()->mutable_typed_filter_metadata();
252
0
          (*map)[std::string(kvp.first)] = kvp.second;
253
0
        }
254
0
        discovery_response.add_resources()->PackFrom(resource);
255
238
      } else {
256
238
        discovery_response.add_resources()->PackFrom(message);
257
238
      }
258
238
    }
259
134
    static int next_nonce_counter = 0;
260
134
    discovery_response.set_nonce(absl::StrCat("nonce", next_nonce_counter++));
261
134
    stream->sendGrpcMessage(discovery_response);
262
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::flat_hash_map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::Any, absl::container_internal::StringHash, absl::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
237
74
                            const absl::flat_hash_map<std::string, ProtobufWkt::Any>& metadata) {
238
74
    if (stream == nullptr) {
239
74
      stream = xds_stream_.get();
240
74
    }
241
74
    envoy::service::discovery::v3::DiscoveryResponse discovery_response;
242
74
    discovery_response.set_version_info(version);
243
74
    discovery_response.set_type_url(type_url);
244
144
    for (const auto& message : messages) {
245
144
      if (!metadata.empty()) {
246
0
        envoy::service::discovery::v3::Resource resource;
247
0
        resource.mutable_resource()->PackFrom(message);
248
0
        resource.set_name(intResourceName(message));
249
0
        resource.set_version(version);
250
0
        for (const auto& kvp : metadata) {
251
0
          auto* map = resource.mutable_metadata()->mutable_typed_filter_metadata();
252
0
          (*map)[std::string(kvp.first)] = kvp.second;
253
0
        }
254
0
        discovery_response.add_resources()->PackFrom(resource);
255
144
      } else {
256
144
        discovery_response.add_resources()->PackFrom(message);
257
144
      }
258
144
    }
259
74
    static int next_nonce_counter = 0;
260
74
    discovery_response.set_nonce(absl::StrCat("nonce", next_nonce_counter++));
261
74
    stream->sendGrpcMessage(discovery_response);
262
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::flat_hash_map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::Any, absl::container_internal::StringHash, absl::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
237
40
                            const absl::flat_hash_map<std::string, ProtobufWkt::Any>& metadata) {
238
40
    if (stream == nullptr) {
239
40
      stream = xds_stream_.get();
240
40
    }
241
40
    envoy::service::discovery::v3::DiscoveryResponse discovery_response;
242
40
    discovery_response.set_version_info(version);
243
40
    discovery_response.set_type_url(type_url);
244
74
    for (const auto& message : messages) {
245
74
      if (!metadata.empty()) {
246
0
        envoy::service::discovery::v3::Resource resource;
247
0
        resource.mutable_resource()->PackFrom(message);
248
0
        resource.set_name(intResourceName(message));
249
0
        resource.set_version(version);
250
0
        for (const auto& kvp : metadata) {
251
0
          auto* map = resource.mutable_metadata()->mutable_typed_filter_metadata();
252
0
          (*map)[std::string(kvp.first)] = kvp.second;
253
0
        }
254
0
        discovery_response.add_resources()->PackFrom(resource);
255
74
      } else {
256
74
        discovery_response.add_resources()->PackFrom(message);
257
74
      }
258
74
    }
259
40
    static int next_nonce_counter = 0;
260
40
    discovery_response.set_nonce(absl::StrCat("nonce", next_nonce_counter++));
261
40
    stream->sendGrpcMessage(discovery_response);
262
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::flat_hash_map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::Any, absl::container_internal::StringHash, absl::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
237
10
                            const absl::flat_hash_map<std::string, ProtobufWkt::Any>& metadata) {
238
10
    if (stream == nullptr) {
239
10
      stream = xds_stream_.get();
240
10
    }
241
10
    envoy::service::discovery::v3::DiscoveryResponse discovery_response;
242
10
    discovery_response.set_version_info(version);
243
10
    discovery_response.set_type_url(type_url);
244
10
    for (const auto& message : messages) {
245
10
      if (!metadata.empty()) {
246
0
        envoy::service::discovery::v3::Resource resource;
247
0
        resource.mutable_resource()->PackFrom(message);
248
0
        resource.set_name(intResourceName(message));
249
0
        resource.set_version(version);
250
0
        for (const auto& kvp : metadata) {
251
0
          auto* map = resource.mutable_metadata()->mutable_typed_filter_metadata();
252
0
          (*map)[std::string(kvp.first)] = kvp.second;
253
0
        }
254
0
        discovery_response.add_resources()->PackFrom(resource);
255
10
      } else {
256
10
        discovery_response.add_resources()->PackFrom(message);
257
10
      }
258
10
    }
259
10
    static int next_nonce_counter = 0;
260
10
    discovery_response.set_nonce(absl::StrCat("nonce", next_nonce_counter++));
261
10
    stream->sendGrpcMessage(discovery_response);
262
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::flat_hash_map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::Any, absl::container_internal::StringHash, absl::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
237
10
                            const absl::flat_hash_map<std::string, ProtobufWkt::Any>& metadata) {
238
10
    if (stream == nullptr) {
239
10
      stream = xds_stream_.get();
240
10
    }
241
10
    envoy::service::discovery::v3::DiscoveryResponse discovery_response;
242
10
    discovery_response.set_version_info(version);
243
10
    discovery_response.set_type_url(type_url);
244
10
    for (const auto& message : messages) {
245
10
      if (!metadata.empty()) {
246
0
        envoy::service::discovery::v3::Resource resource;
247
0
        resource.mutable_resource()->PackFrom(message);
248
0
        resource.set_name(intResourceName(message));
249
0
        resource.set_version(version);
250
0
        for (const auto& kvp : metadata) {
251
0
          auto* map = resource.mutable_metadata()->mutable_typed_filter_metadata();
252
0
          (*map)[std::string(kvp.first)] = kvp.second;
253
0
        }
254
0
        discovery_response.add_resources()->PackFrom(resource);
255
10
      } else {
256
10
        discovery_response.add_resources()->PackFrom(message);
257
10
      }
258
10
    }
259
10
    static int next_nonce_counter = 0;
260
10
    discovery_response.set_nonce(absl::StrCat("nonce", next_nonce_counter++));
261
10
    stream->sendGrpcMessage(discovery_response);
262
10
  }
263
264
  template <class T>
265
  void
266
  sendDeltaDiscoveryResponse(const std::string& type_url, const std::vector<T>& added_or_updated,
267
                             const std::vector<std::string>& removed, const std::string& version) {
268
    sendDeltaDiscoveryResponse(type_url, added_or_updated, removed, version, xds_stream_, {}, {});
269
  }
270
271
  template <class T>
272
  void
273
  sendDeltaDiscoveryResponse(const std::string& type_url, const std::vector<T>& added_or_updated,
274
                             const std::vector<std::string>& removed, const std::string& version,
275
                             FakeStreamPtr& stream, const std::vector<std::string>& aliases = {}) {
276
    sendDeltaDiscoveryResponse(type_url, added_or_updated, removed, version, stream, aliases, {});
277
  }
278
279
  template <class T>
280
  void
281
  sendDeltaDiscoveryResponse(const std::string& type_url, const std::vector<T>& added_or_updated,
282
                             const std::vector<std::string>& removed, const std::string& version,
283
38
                             const absl::flat_hash_map<std::string, ProtobufWkt::Any>& metadata) {
284
38
    sendDeltaDiscoveryResponse(type_url, added_or_updated, removed, version, xds_stream_, {},
285
38
                               metadata);
286
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&, absl::flat_hash_map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::Any, absl::container_internal::StringHash, absl::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
283
24
                             const absl::flat_hash_map<std::string, ProtobufWkt::Any>& metadata) {
284
24
    sendDeltaDiscoveryResponse(type_url, added_or_updated, removed, version, xds_stream_, {},
285
24
                               metadata);
286
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&, absl::flat_hash_map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::Any, absl::container_internal::StringHash, absl::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
283
6
                             const absl::flat_hash_map<std::string, ProtobufWkt::Any>& metadata) {
284
6
    sendDeltaDiscoveryResponse(type_url, added_or_updated, removed, version, xds_stream_, {},
285
6
                               metadata);
286
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&, absl::flat_hash_map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::Any, absl::container_internal::StringHash, absl::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
283
4
                             const absl::flat_hash_map<std::string, ProtobufWkt::Any>& metadata) {
284
4
    sendDeltaDiscoveryResponse(type_url, added_or_updated, removed, version, xds_stream_, {},
285
4
                               metadata);
286
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&, absl::flat_hash_map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::Any, absl::container_internal::StringHash, absl::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
283
4
                             const absl::flat_hash_map<std::string, ProtobufWkt::Any>& metadata) {
284
4
    sendDeltaDiscoveryResponse(type_url, added_or_updated, removed, version, xds_stream_, {},
285
4
                               metadata);
286
4
  }
287
288
  template <class T>
289
  void
290
  sendDeltaDiscoveryResponse(const std::string& type_url, const std::vector<T>& added_or_updated,
291
                             const std::vector<std::string>& removed, const std::string& version,
292
                             FakeStreamPtr& stream, const std::vector<std::string>& aliases,
293
38
                             const absl::flat_hash_map<std::string, ProtobufWkt::Any>& metadata) {
294
38
    auto response = createDeltaDiscoveryResponse<T>(type_url, added_or_updated, removed, version,
295
38
                                                    aliases, metadata);
296
38
    stream->sendGrpcMessage(response);
297
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&, std::__1::unique_ptr<Envoy::FakeStream, std::__1::default_delete<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::flat_hash_map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::Any, absl::container_internal::StringHash, absl::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
293
24
                             const absl::flat_hash_map<std::string, ProtobufWkt::Any>& metadata) {
294
24
    auto response = createDeltaDiscoveryResponse<T>(type_url, added_or_updated, removed, version,
295
24
                                                    aliases, metadata);
296
24
    stream->sendGrpcMessage(response);
297
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&, std::__1::unique_ptr<Envoy::FakeStream, std::__1::default_delete<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::flat_hash_map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::Any, absl::container_internal::StringHash, absl::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
293
6
                             const absl::flat_hash_map<std::string, ProtobufWkt::Any>& metadata) {
294
6
    auto response = createDeltaDiscoveryResponse<T>(type_url, added_or_updated, removed, version,
295
6
                                                    aliases, metadata);
296
6
    stream->sendGrpcMessage(response);
297
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&, std::__1::unique_ptr<Envoy::FakeStream, std::__1::default_delete<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::flat_hash_map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::Any, absl::container_internal::StringHash, absl::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
293
4
                             const absl::flat_hash_map<std::string, ProtobufWkt::Any>& metadata) {
294
4
    auto response = createDeltaDiscoveryResponse<T>(type_url, added_or_updated, removed, version,
295
4
                                                    aliases, metadata);
296
4
    stream->sendGrpcMessage(response);
297
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&, std::__1::unique_ptr<Envoy::FakeStream, std::__1::default_delete<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::flat_hash_map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::Any, absl::container_internal::StringHash, absl::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
293
4
                             const absl::flat_hash_map<std::string, ProtobufWkt::Any>& metadata) {
294
4
    auto response = createDeltaDiscoveryResponse<T>(type_url, added_or_updated, removed, version,
295
4
                                                    aliases, metadata);
296
4
    stream->sendGrpcMessage(response);
297
4
  }
298
299
  // Sends a DeltaDiscoveryResponse with a given list of added resources.
300
  // Note that the resources are expected to be of the same type, and match type_url.
301
  void sendExplicitResourcesDeltaDiscoveryResponse(
302
      const std::string& type_url,
303
      const std::vector<envoy::service::discovery::v3::Resource>& added_or_updated,
304
0
      const std::vector<std::string>& removed) {
305
0
    xds_stream_->sendGrpcMessage(
306
0
        createExplicitResourcesDeltaDiscoveryResponse(type_url, added_or_updated, removed));
307
0
  }
308
309
  envoy::service::discovery::v3::DeltaDiscoveryResponse
310
  createExplicitResourcesDeltaDiscoveryResponse(
311
      const std::string& type_url,
312
      const std::vector<envoy::service::discovery::v3::Resource>& added_or_updated,
313
      const std::vector<std::string>& removed);
314
315
  template <class T>
316
  envoy::service::discovery::v3::DeltaDiscoveryResponse
317
  createDeltaDiscoveryResponse(const std::string& type_url, const std::vector<T>& added_or_updated,
318
                               const std::vector<std::string>& removed, const std::string& version,
319
                               const std::vector<std::string>& aliases,
320
38
                               const absl::flat_hash_map<std::string, ProtobufWkt::Any>& metadata) {
321
38
    std::vector<envoy::service::discovery::v3::Resource> resources;
322
38
    for (const auto& message : added_or_updated) {
323
38
      envoy::service::discovery::v3::Resource resource;
324
38
      resource.mutable_resource()->PackFrom(message);
325
38
      resource.set_name(intResourceName(message));
326
38
      resource.set_version(version);
327
38
      for (const auto& alias : aliases) {
328
0
        resource.add_aliases(alias);
329
0
      }
330
38
      for (const auto& kvp : metadata) {
331
0
        auto* map = resource.mutable_metadata()->mutable_typed_filter_metadata();
332
0
        (*map)[std::string(kvp.first)] = kvp.second;
333
0
      }
334
38
      resources.emplace_back(resource);
335
38
    }
336
38
    return createExplicitResourcesDeltaDiscoveryResponse(type_url, resources, removed);
337
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::flat_hash_map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::Any, absl::container_internal::StringHash, absl::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
320
24
                               const absl::flat_hash_map<std::string, ProtobufWkt::Any>& metadata) {
321
24
    std::vector<envoy::service::discovery::v3::Resource> resources;
322
24
    for (const auto& message : added_or_updated) {
323
24
      envoy::service::discovery::v3::Resource resource;
324
24
      resource.mutable_resource()->PackFrom(message);
325
24
      resource.set_name(intResourceName(message));
326
24
      resource.set_version(version);
327
24
      for (const auto& alias : aliases) {
328
0
        resource.add_aliases(alias);
329
0
      }
330
24
      for (const auto& kvp : metadata) {
331
0
        auto* map = resource.mutable_metadata()->mutable_typed_filter_metadata();
332
0
        (*map)[std::string(kvp.first)] = kvp.second;
333
0
      }
334
24
      resources.emplace_back(resource);
335
24
    }
336
24
    return createExplicitResourcesDeltaDiscoveryResponse(type_url, resources, removed);
337
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::flat_hash_map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::Any, absl::container_internal::StringHash, absl::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
320
6
                               const absl::flat_hash_map<std::string, ProtobufWkt::Any>& metadata) {
321
6
    std::vector<envoy::service::discovery::v3::Resource> resources;
322
6
    for (const auto& message : added_or_updated) {
323
6
      envoy::service::discovery::v3::Resource resource;
324
6
      resource.mutable_resource()->PackFrom(message);
325
6
      resource.set_name(intResourceName(message));
326
6
      resource.set_version(version);
327
6
      for (const auto& alias : aliases) {
328
0
        resource.add_aliases(alias);
329
0
      }
330
6
      for (const auto& kvp : metadata) {
331
0
        auto* map = resource.mutable_metadata()->mutable_typed_filter_metadata();
332
0
        (*map)[std::string(kvp.first)] = kvp.second;
333
0
      }
334
6
      resources.emplace_back(resource);
335
6
    }
336
6
    return createExplicitResourcesDeltaDiscoveryResponse(type_url, resources, removed);
337
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::flat_hash_map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::Any, absl::container_internal::StringHash, absl::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
320
4
                               const absl::flat_hash_map<std::string, ProtobufWkt::Any>& metadata) {
321
4
    std::vector<envoy::service::discovery::v3::Resource> resources;
322
4
    for (const auto& message : added_or_updated) {
323
4
      envoy::service::discovery::v3::Resource resource;
324
4
      resource.mutable_resource()->PackFrom(message);
325
4
      resource.set_name(intResourceName(message));
326
4
      resource.set_version(version);
327
4
      for (const auto& alias : aliases) {
328
0
        resource.add_aliases(alias);
329
0
      }
330
4
      for (const auto& kvp : metadata) {
331
0
        auto* map = resource.mutable_metadata()->mutable_typed_filter_metadata();
332
0
        (*map)[std::string(kvp.first)] = kvp.second;
333
0
      }
334
4
      resources.emplace_back(resource);
335
4
    }
336
4
    return createExplicitResourcesDeltaDiscoveryResponse(type_url, resources, removed);
337
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::flat_hash_map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::Any, absl::container_internal::StringHash, absl::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
320
4
                               const absl::flat_hash_map<std::string, ProtobufWkt::Any>& metadata) {
321
4
    std::vector<envoy::service::discovery::v3::Resource> resources;
322
4
    for (const auto& message : added_or_updated) {
323
4
      envoy::service::discovery::v3::Resource resource;
324
4
      resource.mutable_resource()->PackFrom(message);
325
4
      resource.set_name(intResourceName(message));
326
4
      resource.set_version(version);
327
4
      for (const auto& alias : aliases) {
328
0
        resource.add_aliases(alias);
329
0
      }
330
4
      for (const auto& kvp : metadata) {
331
0
        auto* map = resource.mutable_metadata()->mutable_typed_filter_metadata();
332
0
        (*map)[std::string(kvp.first)] = kvp.second;
333
0
      }
334
4
      resources.emplace_back(resource);
335
4
    }
336
4
    return createExplicitResourcesDeltaDiscoveryResponse(type_url, resources, removed);
337
4
  }
338
339
private:
340
38
  template <class T> std::string intResourceName(const T& m) {
341
    // gcc doesn't allow inline template function to be specialized, using a constexpr if to
342
    // workaround.
343
38
    if constexpr (std::is_same_v<T, envoy::config::endpoint::v3::ClusterLoadAssignment>) {
344
34
      return m.cluster_name();
345
34
    } else {
346
34
      return m.name();
347
34
    }
348
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
340
24
  template <class T> std::string intResourceName(const T& m) {
341
    // gcc doesn't allow inline template function to be specialized, using a constexpr if to
342
    // workaround.
343
24
    if constexpr (std::is_same_v<T, envoy::config::endpoint::v3::ClusterLoadAssignment>) {
344
24
      return m.cluster_name();
345
24
    } else {
346
24
      return m.name();
347
24
    }
348
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
340
6
  template <class T> std::string intResourceName(const T& m) {
341
    // gcc doesn't allow inline template function to be specialized, using a constexpr if to
342
    // workaround.
343
6
    if constexpr (std::is_same_v<T, envoy::config::endpoint::v3::ClusterLoadAssignment>) {
344
6
      return m.cluster_name();
345
6
    } else {
346
6
      return m.name();
347
6
    }
348
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
340
4
  template <class T> std::string intResourceName(const T& m) {
341
    // gcc doesn't allow inline template function to be specialized, using a constexpr if to
342
    // workaround.
343
4
    if constexpr (std::is_same_v<T, envoy::config::endpoint::v3::ClusterLoadAssignment>) {
344
4
      return m.cluster_name();
345
4
    } else {
346
4
      return m.name();
347
4
    }
348
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
340
4
  template <class T> std::string intResourceName(const T& m) {
341
    // gcc doesn't allow inline template function to be specialized, using a constexpr if to
342
    // workaround.
343
4
    if constexpr (std::is_same_v<T, envoy::config::endpoint::v3::ClusterLoadAssignment>) {
344
4
      return m.cluster_name();
345
4
    } else {
346
4
      return m.name();
347
4
    }
348
4
  }
349
350
  Event::GlobalTimeSystem time_system_;
351
352
public:
353
  Event::DispatcherPtr dispatcher_;
354
355
  /**
356
   * Open a connection to Envoy, send a series of bytes, and return the
357
   * response. This function will continue reading response bytes until Envoy
358
   * closes the connection (as a part of error handling) or (if configured true)
359
   * the complete headers are read.
360
   *
361
   * @param port the port to connect to.
362
   * @param raw_http the data to send.
363
   * @param response the response data will be sent here.
364
   * @param disconnect_after_headers_complete if the connection should be terminated once "\r\n\r\n"
365
   *        has been read.
366
   * @param transport_socket the transport socket of the created client connection.
367
   **/
368
  void sendRawHttpAndWaitForResponse(int port, const char* raw_http, std::string* response,
369
                                     bool disconnect_after_headers_complete = false,
370
                                     Network::TransportSocketPtr transport_socket = nullptr);
371
372
  /**
373
   * Helper to create ConnectionDriver.
374
   *
375
   * @param port the port to connect to.
376
   * @param initial_data the data to send.
377
   * @param data_callback the callback on the received data.
378
   **/
379
  std::unique_ptr<RawConnectionDriver> createConnectionDriver(
380
      uint32_t port, const std::string& initial_data,
381
      std::function<void(Network::ClientConnection&, const Buffer::Instance&)>&& data_callback,
382
0
      Network::TransportSocketPtr transport_socket = nullptr) {
383
0
    Buffer::OwnedImpl buffer(initial_data);
384
0
    return std::make_unique<RawConnectionDriver>(port, buffer, data_callback, version_,
385
0
                                                 *dispatcher_, std::move(transport_socket));
386
0
  }
387
388
  /**
389
   * Helper to create ConnectionDriver.
390
   *
391
   * @param port the port to connect to.
392
   * @param write_request_cb callback used to send data.
393
   * @param data_callback the callback on the received data.
394
   * @param transport_socket transport socket to use for the client connection
395
   **/
396
  std::unique_ptr<RawConnectionDriver> createConnectionDriver(
397
      uint32_t port, RawConnectionDriver::DoWriteCallback write_request_cb,
398
      std::function<void(Network::ClientConnection&, const Buffer::Instance&)>&& data_callback,
399
0
      Network::TransportSocketPtr transport_socket = nullptr) {
400
0
    return std::make_unique<RawConnectionDriver>(port, write_request_cb, data_callback, version_,
401
0
                                                 *dispatcher_, std::move(transport_socket));
402
0
  }
403
404
14
  FakeUpstreamConfig configWithType(Http::CodecType type) const {
405
14
    FakeUpstreamConfig config = upstream_config_;
406
14
    config.upstream_protocol_ = type;
407
14
    if (type != Http::CodecType::HTTP3) {
408
14
      config.udp_fake_upstream_ = absl::nullopt;
409
14
    }
410
14
    return config;
411
14
  }
412
413
14
  FakeUpstream& addFakeUpstream(Http::CodecType type) {
414
14
    auto config = configWithType(type);
415
14
    fake_upstreams_.emplace_back(std::make_unique<FakeUpstream>(0, version_, config));
416
14
    return *fake_upstreams_.back();
417
14
  }
418
419
  // Adds a fake upstream to the integration test setup. If `autonomous_upstream` is true, then a
420
  // AutonomousUpstream instance will be created instead of a FakeUpstream instance. If
421
  // `autonomous_upstream` is true, then `autonomous_allow_incomplete_streams` determines whether
422
  // an end-of-stream is required on connections between the Envoy and the fake upstream. If
423
  // `autonomous_upstream` is false, then `autonomous_allow_incomplete_streams` is ignored.
424
  FakeUpstream&
425
  addFakeUpstream(Network::DownstreamTransportSocketFactoryPtr&& transport_socket_factory,
426
                  Http::CodecType type, bool autonomous_upstream,
427
0
                  bool autonomous_allow_incomplete_streams = false) {
428
0
    auto config = configWithType(type);
429
0
    if (autonomous_upstream) {
430
0
      fake_upstreams_.emplace_back(
431
0
          std::make_unique<AutonomousUpstream>(std::move(transport_socket_factory), 0, version_,
432
0
                                               config, autonomous_allow_incomplete_streams));
433
0
    } else {
434
0
      fake_upstreams_.emplace_back(
435
0
          std::make_unique<FakeUpstream>(std::move(transport_socket_factory), 0, version_, config));
436
0
    }
437
0
    return *fake_upstreams_.back();
438
0
  }
439
440
0
  void setDrainTime(std::chrono::seconds drain_time) { drain_time_ = drain_time; }
441
442
protected:
443
  static std::string finalizeConfigWithPorts(ConfigHelper& helper, std::vector<uint32_t>& ports,
444
                                             bool use_lds);
445
446
0
  void setUdpFakeUpstream(absl::optional<FakeUpstreamConfig::UdpConfig> config) {
447
0
    upstream_config_.udp_fake_upstream_ = config;
448
0
  }
449
0
  bool initialized() const { return initialized_; }
450
451
  // Right now half-close is set globally, not separately for upstream and
452
  // downstream.
453
0
  void enableHalfClose(bool value) { upstream_config_.enable_half_close_ = value; }
454
455
3.62k
  bool enableHalfClose() { return upstream_config_.enable_half_close_; }
456
457
2.64k
  FakeUpstreamConfig& upstreamConfig() { return upstream_config_; }
458
0
  void setMaxRequestHeadersKb(uint32_t value) { upstream_config_.max_request_headers_kb_ = value; }
459
0
  void setMaxRequestHeadersCount(uint32_t value) {
460
0
    upstream_config_.max_request_headers_count_ = value;
461
0
  }
462
463
0
  void setServerBufferFactory(Buffer::WatermarkFactorySharedPtr proxy_buffer_factory) {
464
0
    ASSERT(!test_server_, "Proxy buffer factory must be set before test server creation");
465
0
    proxy_buffer_factory_ = proxy_buffer_factory;
466
0
  }
467
468
0
  void mergeOptions(envoy::config::core::v3::Http2ProtocolOptions& options) {
469
0
    upstream_config_.http2_options_.MergeFrom(options);
470
0
  }
471
0
  void mergeOptions(envoy::config::listener::v3::QuicProtocolOptions& options) {
472
0
    upstream_config_.quic_options_.MergeFrom(options);
473
0
  }
474
475
  void checkForMissingTagExtractionRules();
476
477
  // Sets the timeout to wait for listeners to be created before invoking
478
  // registerTestServerPorts(), as that needs to know about the bound listener ports.
479
  // Needs to be called before invoking createEnvoy() (invoked during initialize()).
480
0
  void setListenersBoundTimeout(const std::chrono::milliseconds& duration) {
481
0
    listeners_bound_timeout_ms_ = duration;
482
0
  }
483
484
  std::unique_ptr<Stats::Store> upstream_stats_store_;
485
486
  // Make sure the test server will be torn down after any fake client.
487
  // The test server owns the runtime, which is often accessed by client and
488
  // fake upstream codecs and must outlast them.
489
  IntegrationTestServerPtr test_server_;
490
491
  // The IpVersion (IPv4, IPv6) to use.
492
  Network::Address::IpVersion version_;
493
  // IP Address to use when binding sockets on upstreams.
494
  InstanceConstSharedPtrFn upstream_address_fn_;
495
  // The config for envoy start-up.
496
  ConfigHelper config_helper_;
497
  // The ProcessObject to use when constructing the envoy server.
498
  ProcessObjectOptRef process_object_{absl::nullopt};
499
500
  // Steps that should be done before the envoy server starting.
501
  std::function<void(IntegrationTestServer&)> on_server_ready_function_;
502
503
  // Steps that should be done in parallel with the envoy server starting. E.g., xDS
504
  // pre-init, control plane synchronization needed for server start.
505
  std::function<void()> on_server_init_function_;
506
507
  // A map of keys to port names. Generally the names are pulled from the v2 listener name
508
  // but if a listener is created via ADS, it will be from whatever key is used with registerPort.
509
  TestEnvironment::PortMap port_map_;
510
511
  // The DrainStrategy that dictates the behaviour of
512
  // DrainManagerImpl::drainClose().
513
  Server::DrainStrategy drain_strategy_{Server::DrainStrategy::Gradual};
514
515
  // Member variables for xDS testing.
516
  FakeUpstream* xds_upstream_{};
517
  FakeHttpConnectionPtr xds_connection_;
518
  FakeStreamPtr xds_stream_;
519
  bool create_xds_upstream_{false};
520
  bool tls_xds_upstream_{false};
521
  bool use_lds_{true}; // Use the integration framework's LDS set up.
522
  bool upstream_tls_{false};
523
524
  Network::DownstreamTransportSocketFactoryPtr
525
  createUpstreamTlsContext(const FakeUpstreamConfig& upstream_config);
526
  testing::NiceMock<Server::Configuration::MockTransportSocketFactoryContext> factory_context_;
527
  Extensions::TransportSockets::Tls::ContextManagerImpl context_manager_{timeSystem()};
528
529
  // The fake upstreams_ are created using the context_manager, so make sure
530
  // they are destroyed before it is.
531
  std::vector<std::unique_ptr<FakeUpstream>> fake_upstreams_;
532
533
  Grpc::SotwOrDelta sotw_or_delta_{Grpc::SotwOrDelta::Sotw};
534
535
  spdlog::level::level_enum default_log_level_;
536
537
  // Timeout to wait for listeners to be created before invoking
538
  // registerTestServerPorts(), as that needs to know about the bound listener ports.
539
  // Using 2x default timeout to cover for slow TLS implementations (no inline asm) on slow
540
  // computers (e.g., Raspberry Pi) that sometimes time out on TLS listeners, or when
541
  // the number of listeners in a test is large.
542
  std::chrono::milliseconds listeners_bound_timeout_ms_{2 * TestUtility::DefaultTimeout};
543
544
  // Target number of upstreams.
545
  uint32_t fake_upstreams_count_{1};
546
547
  // The duration of the drain manager graceful drain period.
548
  std::chrono::seconds drain_time_{1};
549
550
  // The number of worker threads that the test server uses.
551
  uint32_t concurrency_{1};
552
553
  // If true, use AutonomousUpstream for fake upstreams.
554
  bool autonomous_upstream_{false};
555
556
  // If true, allow incomplete streams in AutonomousUpstream
557
  // This does nothing if autonomous_upstream_ is false
558
  bool autonomous_allow_incomplete_streams_{false};
559
560
  // If this member is not empty, the test will use a fixed RNG value specified
561
  // by it.
562
  absl::optional<uint64_t> deterministic_value_{};
563
564
  // Set true when your test will itself take care of ensuring listeners are up, and registering
565
  // them in the port_map_.
566
  bool defer_listener_finalization_{false};
567
568
  // By default the test server will use custom stats to notify on increment.
569
  // This override exists for tests measuring stats memory.
570
  bool use_real_stats_{};
571
572
  // If true, skip checking stats for missing tag-extraction rules.
573
  bool skip_tag_extraction_rule_check_{};
574
575
  // By default, node metadata (node name, cluster name, locality) for the test server gets set to
576
  // hard-coded values in the OptionsImpl ("node_name", "cluster_name", etc.). Set to true if your
577
  // test specifies the node metadata in the Bootstrap configuration and that's what you want to use
578
  // for node info in Envoy.
579
  bool use_bootstrap_node_metadata_{false};
580
581
private:
582
  // Configuration for the fake upstream.
583
  FakeUpstreamConfig upstream_config_{time_system_};
584
  // True if initialize() has been called.
585
  bool initialized_{};
586
  // Optional factory that the proxy-under-test should use to create watermark buffers. If nullptr,
587
  // the proxy uses the default watermark buffer factory to create buffers.
588
  Buffer::WatermarkFactorySharedPtr proxy_buffer_factory_;
589
};
590
591
} // namespace Envoy