1 // Copyright 2023 gRPC authors.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include <grpc/compression.h>
16 #include <grpc/credentials.h>
17 #include <grpc/grpc.h>
18 #include <grpc/grpc_posix.h>
19 #include <grpc/grpc_security.h>
20 #include <grpc/grpc_security_constants.h>
21 #include <grpc/impl/channel_arg_names.h>
22 #include <grpc/slice.h>
23 #include <grpc/status.h>
24 #include <grpc/support/time.h>
25 #include <inttypes.h>
26 #include <string.h>
27
28 #include <algorithm>
29 #include <atomic>
30 #include <functional>
31 #include <memory>
32 #include <regex>
33 #include <string>
34 #include <utility>
35 #include <vector>
36
37 #include "absl/base/thread_annotations.h"
38 #include "absl/functional/any_invocable.h"
39 #include "absl/log/check.h"
40 #include "absl/meta/type_traits.h"
41 #include "absl/random/random.h"
42 #include "absl/status/status.h"
43 #include "absl/strings/str_format.h"
44 #include "absl/types/optional.h"
45 #include "gtest/gtest.h"
46 #include "src/core/ext/transport/chaotic_good/client/chaotic_good_connector.h"
47 #include "src/core/ext/transport/chaotic_good/server/chaotic_good_server.h"
48 #include "src/core/lib/channel/channel_args.h"
49 #include "src/core/lib/debug/trace.h"
50 #include "src/core/lib/iomgr/error.h"
51 #include "src/core/lib/iomgr/exec_ctx.h"
52 #include "src/core/lib/iomgr/port.h"
53 #include "src/core/lib/security/credentials/fake/fake_credentials.h"
54 #include "src/core/util/env.h"
55 #include "src/core/util/host_port.h"
56 #include "src/core/util/no_destruct.h"
57 #include "src/core/util/sync.h"
58 #include "test/core/end2end/end2end_tests.h"
59 #include "test/core/end2end/fixtures/h2_oauth2_common.h"
60 #include "test/core/end2end/fixtures/h2_ssl_cred_reload_fixture.h"
61 #include "test/core/end2end/fixtures/h2_ssl_tls_common.h"
62 #include "test/core/end2end/fixtures/h2_tls_common.h"
63 #include "test/core/end2end/fixtures/http_proxy_fixture.h"
64 #include "test/core/end2end/fixtures/inproc_fixture.h"
65 #include "test/core/end2end/fixtures/local_util.h"
66 #include "test/core/end2end/fixtures/proxy.h"
67 #include "test/core/end2end/fixtures/secure_fixture.h"
68 #include "test/core/end2end/fixtures/sockpair_fixture.h"
69 #include "test/core/test_util/port.h"
70 #include "test/core/test_util/test_config.h"
71 #include "test/core/test_util/tls_utils.h"
72
73 // IWYU pragma: no_include <unistd.h>
74
75 #ifdef GRPC_POSIX_SOCKET
76 #include <fcntl.h>
77
78 #include "src/core/lib/iomgr/socket_utils_posix.h"
79 #include "src/core/lib/iomgr/unix_sockets_posix.h"
80 #endif
81
82 #ifdef GRPC_POSIX_WAKEUP_FD
83 #include "src/core/lib/iomgr/wakeup_fd_posix.h"
84 #endif
85
86 #define CA_CERT_PATH "src/core/tsi/test_creds/ca.pem"
87 #define SERVER_CERT_PATH "src/core/tsi/test_creds/server1.pem"
88 #define SERVER_KEY_PATH "src/core/tsi/test_creds/server1.key"
89
90 namespace grpc_core {
91
92 namespace {
93
Rand()94 uint64_t Rand() {
95 struct State {
96 Mutex mu;
97 absl::BitGen gen ABSL_GUARDED_BY(mu);
98 };
99 static State* const state = new State;
100 MutexLock lock(&state->mu);
101 return absl::Uniform<uint64_t>(state->gen);
102 }
103
104 std::atomic<uint64_t> unique{Rand()};
105
ProcessAuthFailure(void * state,grpc_auth_context *,const grpc_metadata *,size_t,grpc_process_auth_metadata_done_cb cb,void * user_data)106 void ProcessAuthFailure(void* state, grpc_auth_context* /*ctx*/,
107 const grpc_metadata* /*md*/, size_t /*md_count*/,
108 grpc_process_auth_metadata_done_cb cb,
109 void* user_data) {
110 CHECK_EQ(state, nullptr);
111 cb(user_data, nullptr, 0, nullptr, 0, GRPC_STATUS_UNAUTHENTICATED, nullptr);
112 }
113
AddFailAuthCheckIfNeeded(const ChannelArgs & args,grpc_server_credentials * creds)114 void AddFailAuthCheckIfNeeded(const ChannelArgs& args,
115 grpc_server_credentials* creds) {
116 if (args.Contains(FAIL_AUTH_CHECK_SERVER_ARG_NAME)) {
117 grpc_auth_metadata_processor processor = {ProcessAuthFailure, nullptr,
118 nullptr};
119 grpc_server_credentials_set_auth_metadata_processor(creds, processor);
120 }
121 }
122
123 } // namespace
124
125 class CensusFixture : public CoreTestFixture {
126 private:
MakeServer(const ChannelArgs & args,grpc_completion_queue * cq,absl::AnyInvocable<void (grpc_server *)> & pre_server_start)127 grpc_server* MakeServer(
128 const ChannelArgs& args, grpc_completion_queue* cq,
129 absl::AnyInvocable<void(grpc_server*)>& pre_server_start) override {
130 grpc_server_credentials* server_creds =
131 grpc_insecure_server_credentials_create();
132 auto* server = grpc_server_create(
133 args.Set(GRPC_ARG_ENABLE_CENSUS, true).ToC().get(), nullptr);
134 grpc_server_register_completion_queue(server, cq, nullptr);
135 CHECK(grpc_server_add_http2_port(server, localaddr_.c_str(), server_creds));
136 grpc_server_credentials_release(server_creds);
137 pre_server_start(server);
138 grpc_server_start(server);
139 return server;
140 }
MakeClient(const ChannelArgs & args,grpc_completion_queue *)141 grpc_channel* MakeClient(const ChannelArgs& args,
142 grpc_completion_queue*) override {
143 auto* creds = grpc_insecure_credentials_create();
144 auto* client =
145 grpc_channel_create(localaddr_.c_str(), creds,
146 args.Set(GRPC_ARG_ENABLE_CENSUS, true).ToC().get());
147 grpc_channel_credentials_release(creds);
148 return client;
149 }
150 const std::string localaddr_ =
151 JoinHostPort("localhost", grpc_pick_unused_port_or_die());
152 };
153
154 class CompressionFixture : public CoreTestFixture {
155 private:
MakeServer(const ChannelArgs & args,grpc_completion_queue * cq,absl::AnyInvocable<void (grpc_server *)> & pre_server_start)156 grpc_server* MakeServer(
157 const ChannelArgs& args, grpc_completion_queue* cq,
158 absl::AnyInvocable<void(grpc_server*)>& pre_server_start) override {
159 auto* server = grpc_server_create(
160 args.SetIfUnset(GRPC_COMPRESSION_CHANNEL_DEFAULT_ALGORITHM,
161 GRPC_COMPRESS_GZIP)
162 .ToC()
163 .get(),
164 nullptr);
165 grpc_server_register_completion_queue(server, cq, nullptr);
166 grpc_server_credentials* server_creds =
167 grpc_insecure_server_credentials_create();
168 CHECK(grpc_server_add_http2_port(server, localaddr_.c_str(), server_creds));
169 grpc_server_credentials_release(server_creds);
170 pre_server_start(server);
171 grpc_server_start(server);
172 return server;
173 }
MakeClient(const ChannelArgs & args,grpc_completion_queue *)174 grpc_channel* MakeClient(const ChannelArgs& args,
175 grpc_completion_queue*) override {
176 grpc_channel_credentials* creds = grpc_insecure_credentials_create();
177 auto* client = grpc_channel_create(
178 localaddr_.c_str(), creds,
179 args.SetIfUnset(GRPC_COMPRESSION_CHANNEL_DEFAULT_ALGORITHM,
180 GRPC_COMPRESS_GZIP)
181 .ToC()
182 .get());
183 grpc_channel_credentials_release(creds);
184 return client;
185 }
186
187 std::string localaddr_ =
188 JoinHostPort("localhost", grpc_pick_unused_port_or_die());
189 };
190
191 class FakesecFixture : public SecureFixture {
192 private:
MakeClientCreds(const ChannelArgs &)193 grpc_channel_credentials* MakeClientCreds(const ChannelArgs&) override {
194 return grpc_fake_transport_security_credentials_create();
195 }
MakeServerCreds(const ChannelArgs & args)196 grpc_server_credentials* MakeServerCreds(const ChannelArgs& args) override {
197 grpc_server_credentials* fake_ts_creds =
198 grpc_fake_transport_security_server_credentials_create();
199 AddFailAuthCheckIfNeeded(args, fake_ts_creds);
200 return fake_ts_creds;
201 }
202 };
203
204 class InsecureCredsFixture : public InsecureFixture {
205 private:
MakeServerCreds(const ChannelArgs & args)206 grpc_server_credentials* MakeServerCreds(const ChannelArgs& args) override {
207 auto* creds = grpc_insecure_server_credentials_create();
208 AddFailAuthCheckIfNeeded(args, creds);
209 return creds;
210 }
211 };
212
213 class SockpairWithMinstackFixture : public SockpairFixture {
214 public:
215 using SockpairFixture::SockpairFixture;
216
217 private:
MutateClientArgs(ChannelArgs args)218 ChannelArgs MutateClientArgs(ChannelArgs args) override {
219 return args.Set(GRPC_ARG_MINIMAL_STACK, true);
220 }
MutateServerArgs(ChannelArgs args)221 ChannelArgs MutateServerArgs(ChannelArgs args) override {
222 return args.Set(GRPC_ARG_MINIMAL_STACK, true);
223 }
224 };
225
226 class Sockpair1Byte : public SockpairFixture {
227 public:
Sockpair1Byte()228 Sockpair1Byte()
229 : SockpairFixture(ChannelArgs()
230 .Set(GRPC_ARG_TCP_READ_CHUNK_SIZE, 1)
231 .Set(GRPC_ARG_TCP_MIN_READ_CHUNK_SIZE, 1)
232 .Set(GRPC_ARG_TCP_MAX_READ_CHUNK_SIZE, 1)) {
233 g_fixture_slowdown_factor = 2;
234 }
~Sockpair1Byte()235 ~Sockpair1Byte() override { g_fixture_slowdown_factor = 1; }
236
237 private:
MutateClientArgs(ChannelArgs args)238 ChannelArgs MutateClientArgs(ChannelArgs args) override {
239 return args.Set(GRPC_ARG_MINIMAL_STACK, true);
240 }
MutateServerArgs(ChannelArgs args)241 ChannelArgs MutateServerArgs(ChannelArgs args) override {
242 return args.Set(GRPC_ARG_MINIMAL_STACK, true);
243 }
244 };
245
246 #ifdef GRPC_POSIX_SOCKET
247
248 class FdFixture : public CoreTestFixture {
249 public:
FdFixture()250 FdFixture() { create_sockets(fd_pair_); }
251
252 private:
MakeServer(const ChannelArgs & args,grpc_completion_queue * cq,absl::AnyInvocable<void (grpc_server *)> & pre_server_start)253 grpc_server* MakeServer(
254 const ChannelArgs& args, grpc_completion_queue* cq,
255 absl::AnyInvocable<void(grpc_server*)>& pre_server_start) override {
256 ExecCtx exec_ctx;
257 auto* server = grpc_server_create(args.ToC().get(), nullptr);
258 grpc_server_register_completion_queue(server, cq, nullptr);
259 pre_server_start(server);
260 grpc_server_start(server);
261 grpc_server_credentials* creds = grpc_insecure_server_credentials_create();
262 grpc_server_add_channel_from_fd(server, fd_pair_[1], creds);
263 grpc_server_credentials_release(creds);
264 return server;
265 }
MakeClient(const ChannelArgs & args,grpc_completion_queue *)266 grpc_channel* MakeClient(const ChannelArgs& args,
267 grpc_completion_queue*) override {
268 ExecCtx exec_ctx;
269 grpc_channel_credentials* creds = grpc_insecure_credentials_create();
270 auto* client = grpc_channel_create_from_fd("fixture_client", fd_pair_[0],
271 creds, args.ToC().get());
272 grpc_channel_credentials_release(creds);
273 return client;
274 }
275
create_sockets(int sv[2])276 static void create_sockets(int sv[2]) {
277 int flags;
278 grpc_create_socketpair_if_unix(sv);
279 flags = fcntl(sv[0], F_GETFL, 0);
280 CHECK_EQ(fcntl(sv[0], F_SETFL, flags | O_NONBLOCK), 0);
281 flags = fcntl(sv[1], F_GETFL, 0);
282 CHECK_EQ(fcntl(sv[1], F_SETFL, flags | O_NONBLOCK), 0);
283 CHECK(grpc_set_socket_no_sigpipe_if_possible(sv[0]) == absl::OkStatus());
284 CHECK(grpc_set_socket_no_sigpipe_if_possible(sv[1]) == absl::OkStatus());
285 }
286
287 int fd_pair_[2];
288 };
289 #endif
290
291 class NoRetryFixture : public InsecureFixture {
292 private:
MutateClientArgs(ChannelArgs args)293 ChannelArgs MutateClientArgs(ChannelArgs args) override {
294 return args.Set(GRPC_ARG_ENABLE_RETRIES, false);
295 }
296 };
297
298 class HttpProxyFilter : public CoreTestFixture {
299 public:
HttpProxyFilter(const ChannelArgs & client_args)300 explicit HttpProxyFilter(const ChannelArgs& client_args)
301 : proxy_(grpc_end2end_http_proxy_create(client_args.ToC().get())) {}
~HttpProxyFilter()302 ~HttpProxyFilter() override { grpc_end2end_http_proxy_destroy(proxy_); }
303
304 private:
MakeServer(const ChannelArgs & args,grpc_completion_queue * cq,absl::AnyInvocable<void (grpc_server *)> & pre_server_start)305 grpc_server* MakeServer(
306 const ChannelArgs& args, grpc_completion_queue* cq,
307 absl::AnyInvocable<void(grpc_server*)>& pre_server_start) override {
308 auto* server = grpc_server_create(args.ToC().get(), nullptr);
309 grpc_server_register_completion_queue(server, cq, nullptr);
310 grpc_server_credentials* server_creds =
311 grpc_insecure_server_credentials_create();
312 CHECK(
313 grpc_server_add_http2_port(server, server_addr_.c_str(), server_creds));
314 grpc_server_credentials_release(server_creds);
315 pre_server_start(server);
316 grpc_server_start(server);
317 return server;
318 }
319
MakeClient(const ChannelArgs & args,grpc_completion_queue *)320 grpc_channel* MakeClient(const ChannelArgs& args,
321 grpc_completion_queue*) override {
322 // If testing for proxy auth, add credentials to proxy uri
323 absl::optional<std::string> proxy_auth_str =
324 args.GetOwnedString(GRPC_ARG_HTTP_PROXY_AUTH_CREDS);
325 std::string proxy_uri;
326 if (!proxy_auth_str.has_value()) {
327 proxy_uri = absl::StrFormat(
328 "http://%s", grpc_end2end_http_proxy_get_proxy_name(proxy_));
329 } else {
330 proxy_uri =
331 absl::StrFormat("http://%s@%s", proxy_auth_str->c_str(),
332 grpc_end2end_http_proxy_get_proxy_name(proxy_));
333 }
334 grpc_channel_credentials* creds = grpc_insecure_credentials_create();
335 auto* client = grpc_channel_create(
336 server_addr_.c_str(), creds,
337 args.Set(GRPC_ARG_HTTP_PROXY, proxy_uri).ToC().get());
338 grpc_channel_credentials_release(creds);
339 CHECK(client);
340 return client;
341 }
342
343 std::string server_addr_ =
344 JoinHostPort("localhost", grpc_pick_unused_port_or_die());
345 grpc_end2end_http_proxy* proxy_;
346 };
347
348 class ProxyFixture : public CoreTestFixture {
349 public:
ProxyFixture(const ChannelArgs & client_args,const ChannelArgs & server_args)350 ProxyFixture(const ChannelArgs& client_args, const ChannelArgs& server_args)
351 : proxy_(grpc_end2end_proxy_create(&proxy_def_, client_args.ToC().get(),
352 server_args.ToC().get())) {}
~ProxyFixture()353 ~ProxyFixture() override { grpc_end2end_proxy_destroy(proxy_); }
354
355 private:
CreateProxyServer(const char * port,const grpc_channel_args * server_args)356 static grpc_server* CreateProxyServer(const char* port,
357 const grpc_channel_args* server_args) {
358 grpc_server* s = grpc_server_create(server_args, nullptr);
359 grpc_server_credentials* server_creds =
360 grpc_insecure_server_credentials_create();
361 CHECK(grpc_server_add_http2_port(s, port, server_creds));
362 grpc_server_credentials_release(server_creds);
363 return s;
364 }
365
CreateProxyClient(const char * target,const grpc_channel_args * client_args)366 static grpc_channel* CreateProxyClient(const char* target,
367 const grpc_channel_args* client_args) {
368 grpc_channel_credentials* creds = grpc_insecure_credentials_create();
369 grpc_channel* channel = grpc_channel_create(target, creds, client_args);
370 grpc_channel_credentials_release(creds);
371 return channel;
372 }
373
MakeServer(const ChannelArgs & args,grpc_completion_queue * cq,absl::AnyInvocable<void (grpc_server *)> & pre_server_start)374 grpc_server* MakeServer(
375 const ChannelArgs& args, grpc_completion_queue* cq,
376 absl::AnyInvocable<void(grpc_server*)>& pre_server_start) override {
377 auto* server = grpc_server_create(args.ToC().get(), nullptr);
378 grpc_server_register_completion_queue(server, cq, nullptr);
379 grpc_server_credentials* server_creds =
380 grpc_insecure_server_credentials_create();
381 CHECK(grpc_server_add_http2_port(
382 server, grpc_end2end_proxy_get_server_port(proxy_), server_creds));
383 grpc_server_credentials_release(server_creds);
384 pre_server_start(server);
385 grpc_server_start(server);
386 return server;
387 }
388
MakeClient(const ChannelArgs & args,grpc_completion_queue *)389 grpc_channel* MakeClient(const ChannelArgs& args,
390 grpc_completion_queue*) override {
391 grpc_channel_credentials* creds = grpc_insecure_credentials_create();
392 auto* client = grpc_channel_create(
393 grpc_end2end_proxy_get_client_target(proxy_), creds, args.ToC().get());
394 grpc_channel_credentials_release(creds);
395 CHECK(client);
396 return client;
397 }
398 const grpc_end2end_proxy_def proxy_def_ = {CreateProxyServer,
399 CreateProxyClient};
400 grpc_end2end_proxy* proxy_;
401 };
402
403 class SslProxyFixture : public CoreTestFixture {
404 public:
SslProxyFixture(const ChannelArgs & client_args,const ChannelArgs & server_args)405 SslProxyFixture(const ChannelArgs& client_args,
406 const ChannelArgs& server_args)
407 : proxy_(grpc_end2end_proxy_create(&proxy_def_, client_args.ToC().get(),
408 server_args.ToC().get())) {}
~SslProxyFixture()409 ~SslProxyFixture() override { grpc_end2end_proxy_destroy(proxy_); }
410
411 private:
CreateProxyServer(const char * port,const grpc_channel_args * server_args)412 static grpc_server* CreateProxyServer(const char* port,
413 const grpc_channel_args* server_args) {
414 grpc_server* s = grpc_server_create(server_args, nullptr);
415 std::string server_cert = testing::GetFileContents(SERVER_CERT_PATH);
416 std::string server_key = testing::GetFileContents(SERVER_KEY_PATH);
417 grpc_ssl_pem_key_cert_pair pem_key_cert_pair = {server_key.c_str(),
418 server_cert.c_str()};
419 grpc_server_credentials* ssl_creds = grpc_ssl_server_credentials_create(
420 nullptr, &pem_key_cert_pair, 1, 0, nullptr);
421 CHECK(grpc_server_add_http2_port(s, port, ssl_creds));
422 grpc_server_credentials_release(ssl_creds);
423 return s;
424 }
425
CreateProxyClient(const char * target,const grpc_channel_args * client_args)426 static grpc_channel* CreateProxyClient(const char* target,
427 const grpc_channel_args* client_args) {
428 grpc_channel* channel;
429 grpc_channel_credentials* ssl_creds =
430 grpc_ssl_credentials_create(nullptr, nullptr, nullptr, nullptr);
431 grpc_arg ssl_name_override = {
432 GRPC_ARG_STRING,
433 const_cast<char*>(GRPC_SSL_TARGET_NAME_OVERRIDE_ARG),
434 {const_cast<char*>("foo.test.google.fr")}};
435 const grpc_channel_args* new_client_args =
436 grpc_channel_args_copy_and_add(client_args, &ssl_name_override, 1);
437 channel = grpc_channel_create(target, ssl_creds, new_client_args);
438 grpc_channel_credentials_release(ssl_creds);
439 {
440 ExecCtx exec_ctx;
441 grpc_channel_args_destroy(new_client_args);
442 }
443 return channel;
444 }
445
MakeServer(const ChannelArgs & args,grpc_completion_queue * cq,absl::AnyInvocable<void (grpc_server *)> & pre_server_start)446 grpc_server* MakeServer(
447 const ChannelArgs& args, grpc_completion_queue* cq,
448 absl::AnyInvocable<void(grpc_server*)>& pre_server_start) override {
449 std::string server_cert = testing::GetFileContents(SERVER_CERT_PATH);
450 std::string server_key = testing::GetFileContents(SERVER_KEY_PATH);
451 grpc_ssl_pem_key_cert_pair pem_key_cert_pair = {server_key.c_str(),
452 server_cert.c_str()};
453 grpc_server_credentials* ssl_creds = grpc_ssl_server_credentials_create(
454 nullptr, &pem_key_cert_pair, 1, 0, nullptr);
455 if (args.Contains(FAIL_AUTH_CHECK_SERVER_ARG_NAME)) {
456 grpc_auth_metadata_processor processor = {ProcessAuthFailure, nullptr,
457 nullptr};
458 grpc_server_credentials_set_auth_metadata_processor(ssl_creds, processor);
459 }
460
461 auto* server = grpc_server_create(args.ToC().get(), nullptr);
462 grpc_server_register_completion_queue(server, cq, nullptr);
463 CHECK(grpc_server_add_http2_port(
464 server, grpc_end2end_proxy_get_server_port(proxy_), ssl_creds));
465 grpc_server_credentials_release(ssl_creds);
466 pre_server_start(server);
467 grpc_server_start(server);
468 return server;
469 }
470
MakeClient(const ChannelArgs & args,grpc_completion_queue *)471 grpc_channel* MakeClient(const ChannelArgs& args,
472 grpc_completion_queue*) override {
473 grpc_channel_credentials* ssl_creds =
474 grpc_ssl_credentials_create(nullptr, nullptr, nullptr, nullptr);
475 auto* client = grpc_channel_create(
476 grpc_end2end_proxy_get_client_target(proxy_), ssl_creds,
477 args.Set(GRPC_SSL_TARGET_NAME_OVERRIDE_ARG, "foo.test.google.fr")
478 .ToC()
479 .get());
480 CHECK_NE(client, nullptr);
481 grpc_channel_credentials_release(ssl_creds);
482 return client;
483 }
484 const grpc_end2end_proxy_def proxy_def_ = {CreateProxyServer,
485 CreateProxyClient};
486 grpc_end2end_proxy* proxy_;
487 };
488
489 class FixtureWithTracing final : public CoreTestFixture {
490 public:
FixtureWithTracing(std::unique_ptr<CoreTestFixture> fixture)491 explicit FixtureWithTracing(std::unique_ptr<CoreTestFixture> fixture)
492 : fixture_(std::move(fixture)) {
493 // g_fixture_slowdown_factor = 10;
494 EXPECT_FALSE(grpc_tracer_set_enabled("doesnt-exist", 0));
495 EXPECT_TRUE(grpc_tracer_set_enabled("http", 1));
496 EXPECT_TRUE(grpc_tracer_set_enabled("all", 1));
497 }
~FixtureWithTracing()498 ~FixtureWithTracing() override {
499 saved_trace_flags_.Restore();
500 // g_fixture_slowdown_factor = 1;
501 }
502
MakeServer(const ChannelArgs & args,grpc_completion_queue * cq,absl::AnyInvocable<void (grpc_server *)> & pre_server_start)503 grpc_server* MakeServer(
504 const ChannelArgs& args, grpc_completion_queue* cq,
505 absl::AnyInvocable<void(grpc_server*)>& pre_server_start) override {
506 return fixture_->MakeServer(args, cq, pre_server_start);
507 }
508
MakeClient(const ChannelArgs & args,grpc_completion_queue * cq)509 grpc_channel* MakeClient(const ChannelArgs& args,
510 grpc_completion_queue* cq) override {
511 return fixture_->MakeClient(args, cq);
512 }
513
514 private:
515 SavedTraceFlags saved_trace_flags_;
516 std::unique_ptr<CoreTestFixture> fixture_;
517 };
518
519 class ChaoticGoodFixture : public CoreTestFixture {
520 public:
ChaoticGoodFixture(int data_connections=1,int chunk_size=0,std::string localaddr=JoinHostPort ("localhost",grpc_pick_unused_port_or_die ()))521 explicit ChaoticGoodFixture(int data_connections = 1, int chunk_size = 0,
522 std::string localaddr = JoinHostPort(
523 "localhost", grpc_pick_unused_port_or_die()))
524 : data_connections_(data_connections),
525 chunk_size_(chunk_size),
526 localaddr_(std::move(localaddr)) {}
527
528 protected:
localaddr() const529 const std::string& localaddr() const { return localaddr_; }
530
531 private:
MakeServer(const ChannelArgs & args,grpc_completion_queue * cq,absl::AnyInvocable<void (grpc_server *)> & pre_server_start)532 grpc_server* MakeServer(
533 const ChannelArgs& args, grpc_completion_queue* cq,
534 absl::AnyInvocable<void(grpc_server*)>& pre_server_start) override {
535 auto* server = grpc_server_create(
536 args.Set(GRPC_ARG_CHAOTIC_GOOD_DATA_CONNECTIONS, data_connections_)
537 .Set(GRPC_ARG_CHAOTIC_GOOD_MAX_RECV_CHUNK_SIZE, chunk_size_)
538 .Set(GRPC_ARG_CHAOTIC_GOOD_MAX_SEND_CHUNK_SIZE, chunk_size_)
539 .ToC()
540 .get(),
541 nullptr);
542 grpc_server_register_completion_queue(server, cq, nullptr);
543 CHECK(grpc_server_add_chaotic_good_port(server, localaddr_.c_str()));
544 pre_server_start(server);
545 grpc_server_start(server);
546 return server;
547 }
548
MakeClient(const ChannelArgs & args,grpc_completion_queue *)549 grpc_channel* MakeClient(const ChannelArgs& args,
550 grpc_completion_queue*) override {
551 auto* client = grpc_chaotic_good_channel_create(
552 localaddr_.c_str(),
553 args.Set(GRPC_ARG_CHAOTIC_GOOD_MAX_RECV_CHUNK_SIZE, chunk_size_)
554 .Set(GRPC_ARG_CHAOTIC_GOOD_MAX_SEND_CHUNK_SIZE, chunk_size_)
555 .SetIfUnset(GRPC_ARG_ENABLE_RETRIES, IsRetryInCallv3Enabled())
556 .ToC()
557 .get());
558 return client;
559 }
560
561 int data_connections_;
562 int chunk_size_;
563 std::string localaddr_;
564 };
565
566 class ChaoticGoodSingleConnectionFixture final : public ChaoticGoodFixture {
567 public:
ChaoticGoodSingleConnectionFixture()568 ChaoticGoodSingleConnectionFixture() : ChaoticGoodFixture(1) {}
569 };
570
571 class ChaoticGoodManyConnectionFixture final : public ChaoticGoodFixture {
572 public:
ChaoticGoodManyConnectionFixture()573 ChaoticGoodManyConnectionFixture() : ChaoticGoodFixture(16) {}
574 };
575
576 class ChaoticGoodOneByteChunkFixture final : public ChaoticGoodFixture {
577 public:
ChaoticGoodOneByteChunkFixture()578 ChaoticGoodOneByteChunkFixture() : ChaoticGoodFixture(1, 1) {}
579 };
580
581 #ifdef GRPC_POSIX_WAKEUP_FD
582 class InsecureFixtureWithPipeForWakeupFd : public InsecureFixture {
583 public:
InsecureFixtureWithPipeForWakeupFd()584 InsecureFixtureWithPipeForWakeupFd()
585 : old_value_(std::exchange(grpc_allow_specialized_wakeup_fd, 0)) {}
586
~InsecureFixtureWithPipeForWakeupFd()587 ~InsecureFixtureWithPipeForWakeupFd() override {
588 grpc_allow_specialized_wakeup_fd = old_value_;
589 }
590
591 private:
592 const int old_value_;
593 };
594 #endif
595
596 // Returns the temp directory to create uds in this test.
GetTempDir()597 std::string GetTempDir() {
598 #ifdef GPR_WINDOWS
599 // Windows temp dir usually exceeds uds max path length,
600 // so we create a short dir for this test.
601 // TODO: find a better solution.
602 std::string temp_dir = "C:/tmp/";
603 if (CreateDirectoryA(temp_dir.c_str(), NULL) == 0 &&
604 ERROR_ALREADY_EXISTS != GetLastError()) {
605 Crash(absl::StrCat("Could not create temp dir: ", temp_dir));
606 }
607 return temp_dir;
608 #else
609 return "/tmp/";
610 #endif // GPR_WINDOWS
611 }
612
613 const std::string temp_dir = GetTempDir();
614
DefaultConfigs()615 std::vector<CoreTestConfiguration> DefaultConfigs() {
616 return std::vector<CoreTestConfiguration>{
617 #ifdef GRPC_POSIX_SOCKET
618 CoreTestConfiguration{"Chttp2Fd",
619 FEATURE_MASK_IS_HTTP2 | FEATURE_MASK_DO_NOT_FUZZ |
620 FEATURE_MASK_EXCLUDE_FROM_EXPERIMENT_RUNS,
621 nullptr,
622 [](const ChannelArgs&, const ChannelArgs&) {
623 return std::make_unique<FdFixture>();
624 }},
625 #endif
626 CoreTestConfiguration{
627 "Chttp2FakeSecurityFullstack",
628 FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL |
629 FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS_LEVEL_INSECURE |
630 FEATURE_MASK_IS_HTTP2,
631 nullptr,
632 [](const ChannelArgs&, const ChannelArgs&) {
633 return std::make_unique<FakesecFixture>();
634 }},
635 CoreTestConfiguration{
636 "Chttp2Fullstack",
637 FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL | FEATURE_MASK_IS_HTTP2, nullptr,
638 [](const ChannelArgs& /*client_args*/,
639 const ChannelArgs& /*server_args*/) {
640 return std::make_unique<InsecureFixture>();
641 }},
642 CoreTestConfiguration{
643 "Chttp2FullstackCompression",
644 FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL | FEATURE_MASK_IS_HTTP2, nullptr,
645 [](const ChannelArgs&, const ChannelArgs&) {
646 return std::make_unique<CompressionFixture>();
647 }},
648 #ifdef GPR_LINUX
649 CoreTestConfiguration{
650 "Chttp2FullstackLocalAbstractUdsPercentEncoded",
651 FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL |
652 FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS |
653 FEATURE_MASK_IS_HTTP2 | FEATURE_MASK_DO_NOT_FUZZ |
654 FEATURE_MASK_EXCLUDE_FROM_EXPERIMENT_RUNS,
655 nullptr,
656 [](const ChannelArgs& /*client_args*/,
657 const ChannelArgs& /*server_args*/) {
658 gpr_timespec now = gpr_now(GPR_CLOCK_MONOTONIC);
659 return std::make_unique<LocalTestFixture>(
660 absl::StrFormat(
661 "unix-abstract:grpc_fullstack_test.%%00.%d.%" PRId64
662 ".%" PRId32 ".%" PRId64 ".%" PRId64,
663 getpid(), now.tv_sec, now.tv_nsec,
664 unique.fetch_add(1, std::memory_order_relaxed), Rand()),
665 UDS);
666 }},
667 #endif
668
669 CoreTestConfiguration{"Chttp2FullstackLocalIpv4",
670 FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL |
671 FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS |
672 FEATURE_MASK_IS_HTTP2 |
673 FEATURE_MASK_DO_NOT_FUZZ |
674 FEATURE_MASK_EXCLUDE_FROM_EXPERIMENT_RUNS |
675 FEATURE_MASK_IS_LOCAL_TCP_CREDS,
676 nullptr,
677 [](const ChannelArgs& /*client_args*/,
678 const ChannelArgs& /*server_args*/) {
679 int port = grpc_pick_unused_port_or_die();
680 return std::make_unique<LocalTestFixture>(
681 JoinHostPort("127.0.0.1", port), LOCAL_TCP);
682 }},
683 CoreTestConfiguration{"Chttp2FullstackLocalIpv6",
684 FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL |
685 FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS |
686 FEATURE_MASK_IS_HTTP2 |
687 FEATURE_MASK_DO_NOT_FUZZ |
688 FEATURE_MASK_EXCLUDE_FROM_EXPERIMENT_RUNS |
689 FEATURE_MASK_IS_LOCAL_TCP_CREDS,
690 nullptr,
691 [](const ChannelArgs& /*client_args*/,
692 const ChannelArgs& /*server_args*/) {
693 int port = grpc_pick_unused_port_or_die();
694 return std::make_unique<LocalTestFixture>(
695 JoinHostPort("[::1]", port), LOCAL_TCP);
696 }},
697 #ifdef GRPC_HAVE_UNIX_SOCKET
698 CoreTestConfiguration{
699 "Chttp2FullstackLocalUdsPercentEncoded",
700 FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL |
701 FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS |
702 FEATURE_MASK_IS_HTTP2 | FEATURE_MASK_DO_NOT_FUZZ |
703 FEATURE_MASK_EXCLUDE_FROM_EXPERIMENT_RUNS,
704 nullptr,
705 [](const ChannelArgs& /*client_args*/,
706 const ChannelArgs& /*server_args*/) {
707 gpr_timespec now = gpr_now(GPR_CLOCK_MONOTONIC);
708 return std::make_unique<LocalTestFixture>(
709 absl::StrFormat("unix:%s"
710 "grpc_fullstack_test.%%25.%d.%" PRId64
711 ".%" PRId32 ".%" PRId64 ".%" PRId64,
712 temp_dir, getpid(), now.tv_sec, now.tv_nsec,
713 unique.fetch_add(1, std::memory_order_relaxed),
714 Rand()),
715 UDS);
716 }},
717 CoreTestConfiguration{
718 "Chttp2FullstackLocalUds",
719 FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL |
720 FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS |
721 FEATURE_MASK_IS_HTTP2 | FEATURE_MASK_DO_NOT_FUZZ |
722 FEATURE_MASK_EXCLUDE_FROM_EXPERIMENT_RUNS,
723 nullptr,
724 [](const ChannelArgs& /*client_args*/,
725 const ChannelArgs& /*server_args*/) {
726 gpr_timespec now = gpr_now(GPR_CLOCK_REALTIME);
727 return std::make_unique<LocalTestFixture>(
728 absl::StrFormat("unix:%s"
729 "grpc_fullstack_test.%d.%" PRId64 ".%" PRId32
730 ".%" PRId64 ".%" PRId64,
731 temp_dir, getpid(), now.tv_sec, now.tv_nsec,
732 unique.fetch_add(1, std::memory_order_relaxed),
733 Rand()),
734 UDS);
735 }},
736 #endif
737 CoreTestConfiguration{"Chttp2FullstackNoRetry",
738 FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL |
739 FEATURE_MASK_IS_HTTP2 |
740 FEATURE_MASK_DOES_NOT_SUPPORT_RETRY,
741 nullptr,
742 [](const ChannelArgs& /*client_args*/,
743 const ChannelArgs& /*server_args*/) {
744 return std::make_unique<NoRetryFixture>();
745 }},
746 CoreTestConfiguration{
747 "Chttp2FullstackWithCensus",
748 FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL | FEATURE_MASK_IS_HTTP2, nullptr,
749 [](const ChannelArgs&, const ChannelArgs&) {
750 return std::make_unique<CensusFixture>();
751 }},
752 CoreTestConfiguration{
753 "Chttp2FullstackWithProxy",
754 FEATURE_MASK_SUPPORTS_REQUEST_PROXYING |
755 FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL | FEATURE_MASK_IS_HTTP2 |
756 FEATURE_MASK_DO_NOT_FUZZ,
757 nullptr,
758 [](const ChannelArgs& client_args, const ChannelArgs& server_args) {
759 return std::make_unique<ProxyFixture>(client_args, server_args);
760 }},
761 CoreTestConfiguration{
762 "Chttp2HttpProxy",
763 FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL | FEATURE_MASK_IS_HTTP2 |
764 FEATURE_MASK_DO_NOT_FUZZ,
765 nullptr,
766 [](const ChannelArgs& client_args, const ChannelArgs&) {
767 return std::make_unique<HttpProxyFilter>(client_args);
768 }},
769 CoreTestConfiguration{
770 "Chttp2SslProxy",
771 FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL | FEATURE_MASK_IS_SECURE |
772 FEATURE_MASK_SUPPORTS_REQUEST_PROXYING |
773 FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS |
774 FEATURE_MASK_IS_HTTP2 | FEATURE_MASK_DO_NOT_FUZZ,
775 "foo.test.google.fr",
776 [](const ChannelArgs& client_args, const ChannelArgs& server_args) {
777 return std::make_unique<SslProxyFixture>(client_args, server_args);
778 }},
779 CoreTestConfiguration{
780 "Chttp2InsecureCredentials",
781 FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL |
782 FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS_LEVEL_INSECURE |
783 FEATURE_MASK_IS_HTTP2 | FEATURE_MASK_EXCLUDE_FROM_EXPERIMENT_RUNS,
784 nullptr,
785 [](const ChannelArgs&, const ChannelArgs&) {
786 return std::make_unique<InsecureCredsFixture>();
787 },
788 },
789 CoreTestConfiguration{
790 "Chttp2SimpleSslWithOauth2FullstackTls12",
791 FEATURE_MASK_IS_SECURE | FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS |
792 FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL | FEATURE_MASK_IS_HTTP2 |
793 FEATURE_MASK_EXCLUDE_FROM_EXPERIMENT_RUNS,
794 "foo.test.google.fr",
795 [](const ChannelArgs&, const ChannelArgs&) {
796 return std::make_unique<Oauth2Fixture>(grpc_tls_version::TLS1_2);
797 }},
798 CoreTestConfiguration{
799 "Chttp2SimpleSslWithOauth2FullstackTls13",
800 FEATURE_MASK_IS_SECURE | FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS |
801 FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL | FEATURE_MASK_IS_HTTP2,
802 "foo.test.google.fr",
803 [](const ChannelArgs&, const ChannelArgs&) {
804 return std::make_unique<Oauth2Fixture>(grpc_tls_version::TLS1_3);
805 }},
806 CoreTestConfiguration{
807 "Chttp2SimplSslFullstackTls12",
808 FEATURE_MASK_IS_SECURE | FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS |
809 FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL | FEATURE_MASK_IS_HTTP2 |
810 FEATURE_MASK_EXCLUDE_FROM_EXPERIMENT_RUNS,
811 "foo.test.google.fr",
812 [](const ChannelArgs&, const ChannelArgs&) {
813 return std::make_unique<SslTlsFixture>(grpc_tls_version::TLS1_2);
814 }},
815 CoreTestConfiguration{
816 "Chttp2SimplSslFullstackTls13",
817 FEATURE_MASK_IS_SECURE | FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS |
818 FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL |
819 FEATURE_MASK_DOES_NOT_SUPPORT_CLIENT_HANDSHAKE_COMPLETE_FIRST |
820 FEATURE_MASK_IS_HTTP2,
821 "foo.test.google.fr",
822 [](const ChannelArgs&, const ChannelArgs&) {
823 return std::make_unique<SslTlsFixture>(grpc_tls_version::TLS1_3);
824 }},
825 CoreTestConfiguration{"Chttp2SocketPair",
826 FEATURE_MASK_IS_HTTP2 | FEATURE_MASK_DO_NOT_FUZZ |
827 FEATURE_MASK_EXCLUDE_FROM_EXPERIMENT_RUNS,
828 nullptr,
829 [](const ChannelArgs&, const ChannelArgs&) {
830 return std::make_unique<SockpairFixture>(
831 ChannelArgs());
832 }},
833 CoreTestConfiguration{
834 "Chttp2SocketPair1ByteAtATime",
835 FEATURE_MASK_IS_HTTP2 | FEATURE_MASK_1BYTE_AT_A_TIME |
836 FEATURE_MASK_DO_NOT_FUZZ |
837 FEATURE_MASK_EXCLUDE_FROM_EXPERIMENT_RUNS,
838 nullptr,
839 [](const ChannelArgs&, const ChannelArgs&) {
840 return std::make_unique<SockpairFixture>(
841 ChannelArgs()
842 .Set(GRPC_ARG_TCP_READ_CHUNK_SIZE, 1)
843 .Set(GRPC_ARG_TCP_MIN_READ_CHUNK_SIZE, 1)
844 .Set(GRPC_ARG_TCP_MAX_READ_CHUNK_SIZE, 1));
845 }},
846 CoreTestConfiguration{
847 "Chttp2SocketPairMinstack",
848 FEATURE_MASK_IS_HTTP2 | FEATURE_MASK_IS_MINSTACK |
849 FEATURE_MASK_DO_NOT_FUZZ,
850 nullptr,
851 [](const ChannelArgs&, const ChannelArgs&) {
852 return std::make_unique<SockpairWithMinstackFixture>(ChannelArgs());
853 }},
854 CoreTestConfiguration{
855 "Inproc",
856 FEATURE_MASK_DOES_NOT_SUPPORT_WRITE_BUFFERING,
857 nullptr,
858 [](const ChannelArgs&, const ChannelArgs&) {
859 return std::make_unique<InprocFixture>(false);
860 },
861 },
862 CoreTestConfiguration{
863 "InprocWithPromises",
864 FEATURE_MASK_DOES_NOT_SUPPORT_WRITE_BUFFERING |
865 FEATURE_MASK_IS_CALL_V3,
866 nullptr,
867 [](const ChannelArgs&, const ChannelArgs&) {
868 return std::make_unique<InprocFixture>(true);
869 },
870 },
871 CoreTestConfiguration{
872 "Chttp2SslCredReloadTls12",
873 FEATURE_MASK_IS_SECURE | FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS |
874 FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL | FEATURE_MASK_IS_HTTP2 |
875 FEATURE_MASK_EXCLUDE_FROM_EXPERIMENT_RUNS,
876 "foo.test.google.fr",
877 [](const ChannelArgs&, const ChannelArgs&) {
878 return std::make_unique<SslCredReloadFixture>(TLS1_2);
879 }},
880 CoreTestConfiguration{
881 "Chttp2SslCredReloadTls13",
882 FEATURE_MASK_IS_SECURE | FEATURE_MASK_IS_HTTP2 |
883 FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS |
884 FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL |
885 FEATURE_MASK_DOES_NOT_SUPPORT_CLIENT_HANDSHAKE_COMPLETE_FIRST,
886 "foo.test.google.fr",
887 [](const ChannelArgs&, const ChannelArgs&) {
888 return std::make_unique<SslCredReloadFixture>(TLS1_3);
889 }},
890 CoreTestConfiguration{
891 // client: certificate watcher provider + async external verifier
892 // server: certificate watcher provider + async external verifier
893 // extra: TLS 1.3
894 "Chttp2CertWatcherProviderAsyncVerifierTls13",
895 kH2TLSFeatureMask | FEATURE_MASK_DO_NOT_FUZZ |
896 FEATURE_MASK_EXCLUDE_FROM_EXPERIMENT_RUNS,
897 "foo.test.google.fr",
898 [](const ChannelArgs&, const ChannelArgs&) {
899 return std::make_unique<TlsFixture>(
900 SecurityPrimitives::TlsVersion::V_13,
901 SecurityPrimitives::ProviderType::FILE_PROVIDER,
902 SecurityPrimitives::VerifierType::EXTERNAL_ASYNC_VERIFIER);
903 },
904 },
905 CoreTestConfiguration{
906 // client: certificate watcher provider + hostname verifier
907 // server: certificate watcher provider + sync external verifier
908 // extra: TLS 1.2
909 "Chttp2CertWatcherProviderSyncVerifierTls12",
910 kH2TLSFeatureMask | FEATURE_MASK_DO_NOT_FUZZ |
911 FEATURE_MASK_EXCLUDE_FROM_EXPERIMENT_RUNS,
912 "foo.test.google.fr",
913 [](const ChannelArgs&, const ChannelArgs&) {
914 return std::make_unique<TlsFixture>(
915 SecurityPrimitives::TlsVersion::V_12,
916 SecurityPrimitives::ProviderType::FILE_PROVIDER,
917 SecurityPrimitives::VerifierType::HOSTNAME_VERIFIER);
918 },
919 },
920 CoreTestConfiguration{
921 // client: static data provider + sync external verifier
922 // server: static data provider + sync external verifier
923 // extra: TLS 1.2
924 "Chttp2SimpleSslFullstack",
925 kH2TLSFeatureMask,
926 "foo.test.google.fr",
927 [](const ChannelArgs&, const ChannelArgs&) {
928 return std::make_unique<TlsFixture>(
929 SecurityPrimitives::TlsVersion::V_12,
930 SecurityPrimitives::ProviderType::STATIC_PROVIDER,
931 SecurityPrimitives::VerifierType::EXTERNAL_SYNC_VERIFIER);
932 },
933 },
934 CoreTestConfiguration{
935 // client: static data provider + async external verifier
936 // server: static data provider + async external verifier
937 // extra: TLS 1.3
938 "Chttp2StaticProviderAsyncVerifierTls13",
939 kH2TLSFeatureMask | FEATURE_MASK_DO_NOT_FUZZ |
940 FEATURE_MASK_EXCLUDE_FROM_EXPERIMENT_RUNS,
941 "foo.test.google.fr",
942 [](const ChannelArgs&, const ChannelArgs&) {
943 return std::make_unique<TlsFixture>(
944 SecurityPrimitives::TlsVersion::V_13,
945 SecurityPrimitives::ProviderType::STATIC_PROVIDER,
946 SecurityPrimitives::VerifierType::EXTERNAL_ASYNC_VERIFIER);
947 },
948 },
949 #ifdef GPR_LINUX
950 CoreTestConfiguration{
951 "Chttp2FullstackUdsAbstractNamespace",
952 FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL | FEATURE_MASK_IS_HTTP2 |
953 FEATURE_MASK_DO_NOT_FUZZ |
954 FEATURE_MASK_EXCLUDE_FROM_EXPERIMENT_RUNS,
955 nullptr,
956 [](const ChannelArgs&, const ChannelArgs&) {
957 gpr_timespec now = gpr_now(GPR_CLOCK_REALTIME);
958 return std::make_unique<InsecureFixture>(absl::StrFormat(
959 "unix-abstract:grpc_fullstack_test.%d.%" PRId64 ".%" PRId32
960 ".%" PRId64,
961 getpid(), now.tv_sec, now.tv_nsec,
962 unique.fetch_add(1, std::memory_order_relaxed)));
963 }},
964 #endif
965 #ifdef GRPC_HAVE_UNIX_SOCKET
966 CoreTestConfiguration{
967 "Chttp2FullstackUds",
968 FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL | FEATURE_MASK_IS_HTTP2 |
969 FEATURE_MASK_DO_NOT_FUZZ,
970 nullptr,
971 [](const ChannelArgs&, const ChannelArgs&) {
972 gpr_timespec now = gpr_now(GPR_CLOCK_REALTIME);
973 return std::make_unique<InsecureFixture>(absl::StrFormat(
974 "unix:%s"
975 "grpc_fullstack_test.%d.%" PRId64 ".%" PRId32 ".%" PRId64
976 ".%" PRId64,
977 temp_dir, getpid(), now.tv_sec, now.tv_nsec,
978 unique.fetch_add(1, std::memory_order_relaxed), Rand()));
979 }},
980 #endif
981 // TODO(ctiller): these got inadvertently disabled when the project
982 // switched to Bazel in 2016, and have not been re-enabled since and are now
983 // quite broken. We should re-enable them however, as they provide defense in
984 // depth that enabling tracers is safe. When doing so, we'll need to re-enable
985 // the windows setvbuf statement in main().
986 #if 0
987 CoreTestConfiguration{
988 "Chttp2SocketPairWithTrace",
989 FEATURE_MASK_IS_HTTP2 | FEATURE_MASK_ENABLES_TRACES, nullptr,
990 [](const ChannelArgs&, const ChannelArgs&) {
991 return std::make_unique<FixtureWithTracing>(
992 std::make_unique<SockpairFixture>(ChannelArgs()));
993 }},
994 CoreTestConfiguration{"Chttp2FullstackWithTrace",
995 FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL |
996 FEATURE_MASK_IS_HTTP2 |
997 FEATURE_MASK_ENABLES_TRACES,
998 nullptr,
999 [](const ChannelArgs& /*client_args*/,
1000 const ChannelArgs& /*server_args*/) {
1001 return std::make_unique<FixtureWithTracing>(
1002 std::make_unique<InsecureFixture>());
1003 }},
1004 #endif
1005 #ifdef GRPC_POSIX_WAKEUP_FD
1006 CoreTestConfiguration{
1007 "Chttp2FullstackWithPipeWakeup",
1008 FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL | FEATURE_MASK_IS_HTTP2 |
1009 FEATURE_MASK_DO_NOT_FUZZ |
1010 FEATURE_MASK_EXCLUDE_FROM_EXPERIMENT_RUNS,
1011 nullptr,
1012 [](const ChannelArgs& /*client_args*/,
1013 const ChannelArgs& /*server_args*/) {
1014 return std::make_unique<InsecureFixtureWithPipeForWakeupFd>();
1015 }},
1016 #endif
1017 #ifndef GPR_WINDOWS
1018 CoreTestConfiguration{"ChaoticGoodFullStack",
1019 FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL |
1020 FEATURE_MASK_DOES_NOT_SUPPORT_WRITE_BUFFERING |
1021 FEATURE_MASK_IS_CALL_V3,
1022 nullptr,
1023 [](const ChannelArgs& /*client_args*/,
1024 const ChannelArgs& /*server_args*/) {
1025 return std::make_unique<ChaoticGoodFixture>();
1026 }},
1027 CoreTestConfiguration{
1028 "ChaoticGoodManyConnections",
1029 FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL |
1030 FEATURE_MASK_DOES_NOT_SUPPORT_RETRY |
1031 FEATURE_MASK_DOES_NOT_SUPPORT_WRITE_BUFFERING |
1032 FEATURE_MASK_IS_CALL_V3,
1033 nullptr,
1034 [](const ChannelArgs& /*client_args*/,
1035 const ChannelArgs& /*server_args*/) {
1036 return std::make_unique<ChaoticGoodManyConnectionFixture>();
1037 }},
1038 CoreTestConfiguration{
1039 "ChaoticGoodSingleConnection",
1040 FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL |
1041 FEATURE_MASK_DOES_NOT_SUPPORT_RETRY |
1042 FEATURE_MASK_DOES_NOT_SUPPORT_WRITE_BUFFERING |
1043 FEATURE_MASK_IS_CALL_V3,
1044 nullptr,
1045 [](const ChannelArgs& /*client_args*/,
1046 const ChannelArgs& /*server_args*/) {
1047 return std::make_unique<ChaoticGoodSingleConnectionFixture>();
1048 }},
1049 CoreTestConfiguration{
1050 "ChaoticGoodOneByteChunk",
1051 FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL | FEATURE_MASK_1BYTE_AT_A_TIME |
1052 FEATURE_MASK_DOES_NOT_SUPPORT_RETRY |
1053 FEATURE_MASK_DOES_NOT_SUPPORT_WRITE_BUFFERING |
1054 FEATURE_MASK_IS_CALL_V3,
1055 nullptr,
1056 [](const ChannelArgs& /*client_args*/,
1057 const ChannelArgs& /*server_args*/) {
1058 return std::make_unique<ChaoticGoodOneByteChunkFixture>();
1059 }},
1060 #endif // GPR_WINDOWS
1061 };
1062 }
1063
AllConfigs()1064 std::vector<CoreTestConfiguration> AllConfigs() {
1065 std::vector<CoreTestConfiguration> configs = DefaultConfigs();
1066 std::sort(configs.begin(), configs.end(),
1067 [](const CoreTestConfiguration& a, const CoreTestConfiguration& b) {
1068 return strcmp(a.name, b.name) < 0;
1069 });
1070 return configs;
1071 }
1072
1073 // A ConfigQuery queries a database a set of test configurations
1074 // that match some criteria.
1075 class ConfigQuery {
1076 public:
ConfigQuery()1077 ConfigQuery() {
1078 if (GetEnv("GRPC_CI_EXPERIMENTS").has_value()) {
1079 exclude_features_ |= FEATURE_MASK_EXCLUDE_FROM_EXPERIMENT_RUNS;
1080 }
1081 }
1082 ConfigQuery(const ConfigQuery&) = delete;
1083 ConfigQuery& operator=(const ConfigQuery&) = delete;
1084 // Enforce that the returned configurations have the given features.
EnforceFeatures(uint32_t features)1085 ConfigQuery& EnforceFeatures(uint32_t features) {
1086 enforce_features_ |= features;
1087 return *this;
1088 }
1089 // Enforce that the returned configurations do not have the given features.
ExcludeFeatures(uint32_t features)1090 ConfigQuery& ExcludeFeatures(uint32_t features) {
1091 exclude_features_ |= features;
1092 return *this;
1093 }
1094 // Enforce that the returned configurations have the given name (regex).
AllowName(const std::string & name)1095 ConfigQuery& AllowName(const std::string& name) {
1096 allowed_names_.emplace_back(
1097 std::regex(name, std::regex_constants::ECMAScript));
1098 return *this;
1099 }
1100 // Enforce that the returned configurations do not have the given name
1101 // (regex).
ExcludeName(const std::string & name)1102 ConfigQuery& ExcludeName(const std::string& name) {
1103 excluded_names_.emplace_back(
1104 std::regex(name, std::regex_constants::ECMAScript));
1105 return *this;
1106 }
1107
Run() const1108 auto Run() const {
1109 static NoDestruct<std::vector<CoreTestConfiguration>> kConfigs(
1110 AllConfigs());
1111 std::vector<const CoreTestConfiguration*> out;
1112 for (const CoreTestConfiguration& config : *kConfigs) {
1113 if ((config.feature_mask & enforce_features_) == enforce_features_ &&
1114 (config.feature_mask & exclude_features_) == 0) {
1115 bool allowed = allowed_names_.empty();
1116 for (const std::regex& re : allowed_names_) {
1117 if (std::regex_match(config.name, re)) {
1118 allowed = true;
1119 break;
1120 }
1121 }
1122 for (const std::regex& re : excluded_names_) {
1123 if (std::regex_match(config.name, re)) {
1124 allowed = false;
1125 break;
1126 }
1127 }
1128 if (allowed) {
1129 out.push_back(&config);
1130 }
1131 }
1132 }
1133 return out;
1134 }
1135
1136 private:
1137 uint32_t enforce_features_ = 0;
1138 uint32_t exclude_features_ = 0;
1139 std::vector<std::regex> allowed_names_;
1140 std::vector<std::regex> excluded_names_;
1141 };
1142
1143 CORE_END2END_TEST_SUITE(CoreEnd2endTest, ConfigQuery().Run());
1144
1145 CORE_END2END_TEST_SUITE(
1146 SecureEnd2endTest,
1147 ConfigQuery().EnforceFeatures(FEATURE_MASK_IS_SECURE).Run());
1148
1149 CORE_END2END_TEST_SUITE(CoreLargeSendTest,
1150 ConfigQuery()
1151 .ExcludeFeatures(FEATURE_MASK_1BYTE_AT_A_TIME |
1152 FEATURE_MASK_ENABLES_TRACES)
1153 .Run());
1154
1155 CORE_END2END_TEST_SUITE(
1156 CoreDeadlineTest,
1157 ConfigQuery().ExcludeFeatures(FEATURE_MASK_IS_MINSTACK).Run());
1158
1159 CORE_END2END_TEST_SUITE(
1160 CoreDeadlineSingleHopTest,
1161 ConfigQuery()
1162 .ExcludeFeatures(FEATURE_MASK_SUPPORTS_REQUEST_PROXYING |
1163 FEATURE_MASK_IS_MINSTACK)
1164 .Run());
1165
1166 CORE_END2END_TEST_SUITE(
1167 CoreClientChannelTest,
1168 ConfigQuery().EnforceFeatures(FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL).Run());
1169
1170 CORE_END2END_TEST_SUITE(
1171 Http2SingleHopTest,
1172 ConfigQuery()
1173 .EnforceFeatures(FEATURE_MASK_IS_HTTP2)
1174 .ExcludeFeatures(FEATURE_MASK_SUPPORTS_REQUEST_PROXYING |
1175 FEATURE_MASK_ENABLES_TRACES)
1176 .Run());
1177
1178 CORE_END2END_TEST_SUITE(
1179 Http2FullstackSingleHopTest,
1180 ConfigQuery()
1181 .EnforceFeatures(FEATURE_MASK_IS_HTTP2)
1182 .EnforceFeatures(FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL)
1183 .ExcludeFeatures(FEATURE_MASK_SUPPORTS_REQUEST_PROXYING)
1184 .Run());
1185
1186 CORE_END2END_TEST_SUITE(
1187 RetryTest, ConfigQuery()
1188 .EnforceFeatures(FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL)
1189 .ExcludeFeatures(FEATURE_MASK_DOES_NOT_SUPPORT_RETRY)
1190 .Run());
1191
1192 CORE_END2END_TEST_SUITE(
1193 WriteBufferingTest,
1194 ConfigQuery()
1195 .ExcludeFeatures(FEATURE_MASK_DOES_NOT_SUPPORT_WRITE_BUFFERING)
1196 .Run());
1197
1198 CORE_END2END_TEST_SUITE(
1199 Http2Test, ConfigQuery().EnforceFeatures(FEATURE_MASK_IS_HTTP2).Run());
1200
1201 CORE_END2END_TEST_SUITE(
1202 RetryHttp2Test, ConfigQuery()
1203 .EnforceFeatures(FEATURE_MASK_IS_HTTP2 |
1204 FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL)
1205 .ExcludeFeatures(FEATURE_MASK_DOES_NOT_SUPPORT_RETRY |
1206 FEATURE_MASK_SUPPORTS_REQUEST_PROXYING)
1207 .Run());
1208
1209 CORE_END2END_TEST_SUITE(
1210 ResourceQuotaTest,
1211 ConfigQuery()
1212 .ExcludeFeatures(FEATURE_MASK_SUPPORTS_REQUEST_PROXYING |
1213 FEATURE_MASK_1BYTE_AT_A_TIME)
1214 .ExcludeName("Chttp2.*Uds.*")
1215 .ExcludeName("Chttp2HttpProxy")
1216 .Run());
1217
1218 CORE_END2END_TEST_SUITE(
1219 PerCallCredsTest,
1220 ConfigQuery()
1221 .EnforceFeatures(FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS)
1222 .Run());
1223
1224 CORE_END2END_TEST_SUITE(
1225 PerCallCredsOnInsecureTest,
1226 ConfigQuery()
1227 .EnforceFeatures(
1228 FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS_LEVEL_INSECURE)
1229 .Run());
1230
1231 CORE_END2END_TEST_SUITE(
1232 NoLoggingTest,
1233 ConfigQuery().ExcludeFeatures(FEATURE_MASK_ENABLES_TRACES).Run());
1234
1235 CORE_END2END_TEST_SUITE(ProxyAuthTest,
1236 ConfigQuery().AllowName("Chttp2HttpProxy").Run());
1237
EnsureSuitesLinked()1238 void EnsureSuitesLinked() {}
1239
1240 } // namespace grpc_core
1241