1 // Copyright 2015 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 #ifndef GRPC_TEST_CORE_END2END_END2END_TESTS_H 16 #define GRPC_TEST_CORE_END2END_END2END_TESTS_H 17 18 #include <grpc/byte_buffer.h> 19 #include <grpc/compression.h> 20 #include <grpc/credentials.h> 21 #include <grpc/event_engine/event_engine.h> 22 #include <grpc/grpc.h> 23 #include <grpc/grpc_security.h> 24 #include <grpc/impl/propagation_bits.h> 25 #include <grpc/status.h> 26 #include <grpc/support/alloc.h> 27 #include <grpc/support/time.h> 28 #include <stdint.h> 29 #include <stdio.h> 30 31 #include <algorithm> 32 #include <functional> 33 #include <initializer_list> 34 #include <map> 35 #include <memory> 36 #include <string> 37 #include <utility> 38 #include <vector> 39 40 #include "absl/functional/any_invocable.h" 41 #include "absl/log/check.h" 42 #include "absl/memory/memory.h" 43 #include "absl/meta/type_traits.h" 44 #include "absl/strings/str_cat.h" 45 #include "absl/strings/string_view.h" 46 #include "absl/types/optional.h" 47 #include "absl/types/variant.h" 48 #include "gtest/gtest.h" 49 #include "src/core/config/config_vars.h" 50 #include "src/core/lib/channel/channel_args.h" 51 #include "src/core/lib/slice/slice.h" 52 #include "src/core/lib/slice/slice_internal.h" 53 #include "src/core/lib/surface/call_test_only.h" 54 #include "src/core/lib/surface/channel.h" 55 #include "src/core/util/bitset.h" 56 #include "src/core/util/debug_location.h" 57 #include "src/core/util/time.h" 58 #include "test/core/call/batch_builder.h" 59 #include "test/core/end2end/cq_verifier.h" 60 #include "test/core/event_engine/event_engine_test_utils.h" 61 #include "test/core/test_util/test_config.h" 62 63 // Test feature flags. 64 #define FEATURE_MASK_DOES_NOT_SUPPORT_RETRY (1 << 0) 65 #define FEATURE_MASK_SUPPORTS_HOSTNAME_VERIFICATION (1 << 1) 66 // Feature mask supports call credentials with a minimum security level of 67 // GRPC_PRIVACY_AND_INTEGRITY. 68 #define FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS (1 << 2) 69 // Feature mask supports call credentials with a minimum security level of 70 // GRPC_SECURITY_NONE. 71 #define FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS_LEVEL_INSECURE (1 << 3) 72 #define FEATURE_MASK_SUPPORTS_REQUEST_PROXYING (1 << 4) 73 #define FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL (1 << 5) 74 #define FEATURE_MASK_IS_HTTP2 (1 << 6) 75 #define FEATURE_MASK_ENABLES_TRACES (1 << 7) 76 #define FEATURE_MASK_1BYTE_AT_A_TIME (1 << 8) 77 #define FEATURE_MASK_DOES_NOT_SUPPORT_WRITE_BUFFERING (1 << 9) 78 #define FEATURE_MASK_DOES_NOT_SUPPORT_CLIENT_HANDSHAKE_COMPLETE_FIRST (1 << 10) 79 #define FEATURE_MASK_IS_MINSTACK (1 << 11) 80 #define FEATURE_MASK_IS_SECURE (1 << 12) 81 #define FEATURE_MASK_DO_NOT_FUZZ (1 << 13) 82 // Exclude this fixture from experiment runs 83 #define FEATURE_MASK_EXCLUDE_FROM_EXPERIMENT_RUNS (1 << 14) 84 #define FEATURE_MASK_IS_CALL_V3 (1 << 15) 85 #define FEATURE_MASK_IS_LOCAL_TCP_CREDS (1 << 16) 86 87 #define FAIL_AUTH_CHECK_SERVER_ARG_NAME "fail_auth_check" 88 89 namespace grpc_core { 90 91 extern bool g_is_fuzzing_core_e2e_tests; 92 93 class CoreTestFixture { 94 public: 95 virtual ~CoreTestFixture() = default; 96 97 virtual grpc_server* MakeServer( 98 const ChannelArgs& args, grpc_completion_queue* cq, 99 absl::AnyInvocable<void(grpc_server*)>& pre_server_start) = 0; 100 virtual grpc_channel* MakeClient(const ChannelArgs& args, 101 grpc_completion_queue* cq) = 0; 102 }; 103 104 Slice RandomSlice(size_t length); 105 Slice RandomBinarySlice(size_t length); 106 107 struct CoreTestConfiguration { 108 // A descriptive name for this test fixture. 109 const char* name; 110 111 // Which features are supported by this fixture. See feature flags above. 112 uint32_t feature_mask; 113 114 // If the call host is setup by the fixture (for example, via the 115 // GRPC_SSL_TARGET_NAME_OVERRIDE_ARG channel arg), which value should the 116 // test expect to find in call_details.host 117 const char* overridden_call_host; 118 119 std::function<std::unique_ptr<CoreTestFixture>( 120 const ChannelArgs& client_args, const ChannelArgs& server_args)> 121 create_fixture; 122 }; 123 124 // Base class for e2e tests. 125 // 126 // Initialization: 127 // 128 // At the start of a test, nothing is initialized. CoreConfiguration is reset, 129 // and there's certainly no server nor client. 130 // A test can then register whatever builders it wants into the 131 // CoreConfiguration and have them picked up. If it does not, it will get the 132 // default CoreConfiguration. 133 // 134 // The test may choose to then create a client and server with InitClient() and 135 // InitServer(). It does not matter which order they are called, nor whether one 136 // or both are called. It's necessary to call these if the test demands that 137 // non-empty channel args should be passed to either the client or server. 138 // 139 // If a test does not call InitClient() or InitServer(), then upon the first 140 // call to either NewClientCall() or NewServerCall(), the client and server will 141 // be instantiated - this saves substantial boilerplate in the most common case 142 // for our tests. 143 // 144 // Notes: 145 // - older compilers fail matching absl::string_view with some gmock matchers on 146 // older compilers, and it's tremendously convenient to be able to do so. So 147 // we use std::string for return types here - performance isn't particularly 148 // important, so an extra copy is fine. 149 class CoreEnd2endTest : public ::testing::Test { 150 public: TestInfrastructureSetParam(const CoreTestConfiguration * param)151 void TestInfrastructureSetParam(const CoreTestConfiguration* param) { 152 param_ = param; 153 } GetParam()154 const CoreTestConfiguration* GetParam() { return param_; } 155 156 void SetUp() override; 157 void TearDown() override; 158 virtual void RunTest() = 0; 159 SetCqVerifierStepFn(absl::AnyInvocable<void (grpc_event_engine::experimental::EventEngine::Duration)const> step_fn)160 void SetCqVerifierStepFn( 161 absl::AnyInvocable< 162 void(grpc_event_engine::experimental::EventEngine::Duration) const> 163 step_fn) { 164 step_fn_ = std::move(step_fn); 165 } SetQuiesceEventEngine(absl::AnyInvocable<void (std::shared_ptr<grpc_event_engine::experimental::EventEngine> &&)> quiesce_event_engine)166 void SetQuiesceEventEngine( 167 absl::AnyInvocable< 168 void(std::shared_ptr<grpc_event_engine::experimental::EventEngine>&&)> 169 quiesce_event_engine) { 170 quiesce_event_engine_ = std::move(quiesce_event_engine); 171 } 172 173 class Call; 174 struct RegisteredCall { 175 void* p; 176 }; 177 178 // Safe notification to use for core e2e tests. 179 // Since when we're fuzzing we don't run background threads, the normal 180 // Notification type isn't safe to wait on (for some background timer to fire 181 // for instance...), consequently we need to use this. 182 class TestNotification { 183 public: TestNotification(CoreEnd2endTest * test)184 explicit TestNotification(CoreEnd2endTest* test) : test_(test) {} 185 WaitForNotificationWithTimeout(absl::Duration wait_time)186 void WaitForNotificationWithTimeout(absl::Duration wait_time) { 187 if (g_is_fuzzing_core_e2e_tests) { 188 Timestamp end = Timestamp::Now() + Duration::NanosecondsRoundUp( 189 ToInt64Nanoseconds(wait_time)); 190 while (true) { 191 if (base_.HasBeenNotified()) return; 192 auto now = Timestamp::Now(); 193 if (now >= end) return; 194 test_->step_fn_(now - end); 195 } 196 } else { 197 base_.WaitForNotificationWithTimeout(wait_time); 198 } 199 } 200 Notify()201 void Notify() { base_.Notify(); } 202 203 private: 204 Notification base_; 205 CoreEnd2endTest* const test_; 206 }; 207 208 // CallBuilder - results in a call to either grpc_channel_create_call or 209 // grpc_channel_create_registered_call. 210 // Affords a fluent interface to specify optional arguments. 211 class ClientCallBuilder { 212 public: ClientCallBuilder(CoreEnd2endTest & test,std::string method)213 ClientCallBuilder(CoreEnd2endTest& test, std::string method) 214 : test_(test), 215 call_selector_(UnregisteredCall{std::move(method), absl::nullopt}) {} ClientCallBuilder(CoreEnd2endTest & test,RegisteredCall registered_call)216 ClientCallBuilder(CoreEnd2endTest& test, RegisteredCall registered_call) 217 : test_(test), call_selector_(registered_call.p) {} 218 219 // Specify the host (otherwise nullptr is passed) Host(std::string host)220 ClientCallBuilder& Host(std::string host) { 221 absl::get<UnregisteredCall>(call_selector_).host = std::move(host); 222 return *this; 223 } 224 // Specify the timeout (otherwise gpr_inf_future is passed) - this time is 225 // scaled according to the test environment. Timeout(Duration timeout)226 ClientCallBuilder& Timeout(Duration timeout) { 227 if (timeout == Duration::Infinity()) { 228 deadline_ = gpr_inf_future(GPR_CLOCK_REALTIME); 229 return *this; 230 } 231 deadline_ = grpc_timeout_milliseconds_to_deadline(timeout.millis()); 232 return *this; 233 } 234 // Finally create the call. 235 Call Create(); 236 237 private: 238 CoreEnd2endTest& test_; 239 struct UnregisteredCall { 240 std::string method; 241 absl::optional<std::string> host; 242 }; 243 absl::variant<void*, UnregisteredCall> call_selector_; 244 grpc_call* parent_call_ = nullptr; 245 uint32_t propagation_mask_ = GRPC_PROPAGATE_DEFAULTS; 246 gpr_timespec deadline_ = gpr_inf_future(GPR_CLOCK_REALTIME); 247 }; 248 249 // Wrapper around a grpc_call. 250 // Instantiated by ClientCallBuilder via NewClientCall for client calls. 251 // Wrapped by IncomingCall for server calls. 252 class Call { 253 public: Call(grpc_call * call,CoreEnd2endTest * test)254 Call(grpc_call* call, CoreEnd2endTest* test) : call_(call), test_(test) {} 255 Call(const Call&) = delete; 256 Call& operator=(const Call&) = delete; Call(Call && other)257 Call(Call&& other) noexcept 258 : call_(std::exchange(other.call_, nullptr)), 259 test_(std::exchange(other.test_, nullptr)) {} ~Call()260 ~Call() { 261 if (call_ != nullptr) grpc_call_unref(call_); 262 } 263 // Construct a batch with a tag - upon destruction of the BatchBuilder the 264 // operation will occur. NewBatch(int tag)265 BatchBuilder NewBatch(int tag) { 266 return BatchBuilder(call_, &test_->cq_verifier(), tag); 267 } 268 // Cancel the call Cancel()269 void Cancel() { grpc_call_cancel(call_, nullptr); } CancelWithStatus(grpc_status_code status,const char * message)270 void CancelWithStatus(grpc_status_code status, const char* message) { 271 grpc_call_cancel_with_status(call_, status, message, nullptr); 272 } 273 // Access the peer structure (returns a string that can be matched, etc) - 274 // or nullopt if grpc_call_get_peer returns nullptr. GetPeer()275 absl::optional<std::string> GetPeer() { 276 char* peer = grpc_call_get_peer(call_); 277 if (peer == nullptr) return absl::nullopt; 278 std::string result(peer); 279 gpr_free(peer); 280 return result; 281 } 282 283 // Set call credentials. 284 // Takes ownership of creds. SetCredentials(grpc_call_credentials * creds)285 void SetCredentials(grpc_call_credentials* creds) { 286 EXPECT_EQ(grpc_call_set_credentials(call_, creds), GRPC_CALL_OK); 287 grpc_call_credentials_release(creds); 288 } 289 290 // Retrieve the auth context. 291 std::unique_ptr<grpc_auth_context, void (*)(grpc_auth_context*)> GetAuthContext()292 GetAuthContext() { 293 return std::unique_ptr<grpc_auth_context, void (*)(grpc_auth_context*)>( 294 grpc_call_auth_context(call_), grpc_auth_context_release); 295 } 296 call_ptr()297 grpc_call** call_ptr() { return &call_; } c_call()298 grpc_call* c_call() const { return call_; } 299 300 private: 301 grpc_call* call_ = nullptr; 302 CoreEnd2endTest* test_; 303 }; 304 305 // Wrapper around a server call. 306 class IncomingCall { 307 public: 308 IncomingCall(CoreEnd2endTest& test, int tag); 309 IncomingCall(CoreEnd2endTest& test, void* method, IncomingMessage* message, 310 int tag); 311 IncomingCall(const IncomingCall&) = delete; 312 IncomingCall& operator=(const IncomingCall&) = delete; 313 IncomingCall(IncomingCall&&) noexcept = default; 314 315 // Construct a batch with a tag - upon destruction of the BatchBuilder the 316 // operation will occur. Must have received the call first! NewBatch(int tag)317 BatchBuilder NewBatch(int tag) { return impl_->call.NewBatch(tag); } Cancel()318 void Cancel() { impl_->call.Cancel(); } 319 320 // Return the method being called. method()321 std::string method() const { 322 return std::string(StringViewFromSlice(impl_->call_details.method)); 323 } 324 325 // Return the host being called. host()326 std::string host() const { 327 return std::string(StringViewFromSlice(impl_->call_details.host)); 328 } 329 330 // Return some initial metadata. 331 absl::optional<std::string> GetInitialMetadata(absl::string_view key) const; 332 333 // Return the peer address. GetPeer()334 absl::optional<std::string> GetPeer() { return impl_->call.GetPeer(); } 335 336 // Return the auth context. 337 std::unique_ptr<grpc_auth_context, void (*)(grpc_auth_context*)> GetAuthContext()338 GetAuthContext() { 339 return impl_->call.GetAuthContext(); 340 } 341 342 // Return the underlying C call object c_call()343 grpc_call* c_call() { return impl_->call.c_call(); } 344 345 // Return the encodings accepted by the peer. GetEncodingsAcceptedByPeer()346 BitSet<GRPC_COMPRESS_ALGORITHMS_COUNT> GetEncodingsAcceptedByPeer() { 347 return BitSet<GRPC_COMPRESS_ALGORITHMS_COUNT>::FromInt( 348 grpc_call_test_only_get_encodings_accepted_by_peer(c_call())); 349 } 350 351 private: 352 struct Impl { ImplImpl353 explicit Impl(CoreEnd2endTest* test) : call(nullptr, test) { 354 grpc_call_details_init(&call_details); 355 grpc_metadata_array_init(&request_metadata); 356 } ~ImplImpl357 ~Impl() { 358 grpc_call_details_destroy(&call_details); 359 grpc_metadata_array_destroy(&request_metadata); 360 } 361 Call call; 362 grpc_call_details call_details; 363 grpc_metadata_array request_metadata; 364 }; 365 std::unique_ptr<Impl> impl_; 366 }; 367 368 class ServerRegisteredMethod { 369 public: 370 ServerRegisteredMethod( 371 CoreEnd2endTest* test, absl::string_view name, 372 grpc_server_register_method_payload_handling payload_handling); 373 handle()374 void* handle() { return *handle_; } 375 376 private: 377 std::shared_ptr<void*> handle_ = std::make_shared<void*>(nullptr); 378 }; 379 RegisterServerMethod(absl::string_view name,grpc_server_register_method_payload_handling payload_handling)380 ServerRegisteredMethod RegisterServerMethod( 381 absl::string_view name, 382 grpc_server_register_method_payload_handling payload_handling) { 383 return ServerRegisteredMethod(this, name, payload_handling); 384 } 385 386 // Begin construction of a client call. NewClientCall(std::string method)387 ClientCallBuilder NewClientCall(std::string method) { 388 return ClientCallBuilder(*this, std::move(method)); 389 } NewClientCall(RegisteredCall registered_method)390 ClientCallBuilder NewClientCall(RegisteredCall registered_method) { 391 return ClientCallBuilder(*this, registered_method); 392 } 393 // Request a call on the server - notifies `tag` when complete. RequestCall(int tag)394 IncomingCall RequestCall(int tag) { return IncomingCall(*this, tag); } 395 // Request a call on the server - notifies `tag` when complete. RequestRegisteredCall(ServerRegisteredMethod method,int tag)396 IncomingCall RequestRegisteredCall(ServerRegisteredMethod method, int tag) { 397 return IncomingCall(*this, method.handle(), nullptr, tag); 398 } RequestRegisteredCall(ServerRegisteredMethod method,IncomingMessage * message,int tag)399 IncomingCall RequestRegisteredCall(ServerRegisteredMethod method, 400 IncomingMessage* message, int tag) { 401 return IncomingCall(*this, method.handle(), message, tag); 402 } 403 404 // Pull in CqVerifier types for ergonomics 405 using ExpectedResult = CqVerifier::ExpectedResult; 406 using Maybe = CqVerifier::Maybe; 407 using PerformAction = CqVerifier::PerformAction; 408 using MaybePerformAction = CqVerifier::MaybePerformAction; 409 using AnyStatus = CqVerifier::AnyStatus; 410 // Expect a tag with some result. 411 void Expect(int tag, ExpectedResult result, SourceLocation whence = {}) { 412 expectations_++; 413 cq_verifier().Expect(CqVerifier::tag(tag), std::move(result), whence); 414 } 415 // Step the system until expectations are met or until timeout is reached. 416 // If there are no expectations logged, then step for 1 second and verify that 417 // no events occur. 418 void Step(absl::optional<Duration> timeout = absl::nullopt, 419 SourceLocation whence = {}) { 420 if (expectations_ == 0) { 421 cq_verifier().VerifyEmpty(timeout.value_or(Duration::Seconds(1)), whence); 422 return; 423 } 424 expectations_ = 0; 425 cq_verifier().Verify( 426 timeout.value_or(g_is_fuzzing_core_e2e_tests ? Duration::Minutes(10) 427 : Duration::Seconds(10)), 428 whence); 429 } 430 431 // Initialize the client. 432 // If called, then InitServer must be called to create a server (otherwise one 433 // will be provided). InitClient(const ChannelArgs & args)434 void InitClient(const ChannelArgs& args) { 435 initialized_ = true; 436 if (client_ != nullptr) ShutdownAndDestroyClient(); 437 auto& f = fixture(); 438 client_ = f.MakeClient(args, cq_); 439 CHECK_NE(client_, nullptr); 440 } 441 // Initialize the server. 442 // If called, then InitClient must be called to create a client (otherwise one 443 // will be provided). InitServer(const ChannelArgs & args)444 void InitServer(const ChannelArgs& args) { 445 initialized_ = true; 446 if (server_ != nullptr) ShutdownAndDestroyServer(); 447 auto& f = fixture(); 448 server_ = f.MakeServer(args, cq_, pre_server_start_); 449 CHECK_NE(server_, nullptr); 450 } 451 // Remove the client. ShutdownAndDestroyClient()452 void ShutdownAndDestroyClient() { 453 if (client_ == nullptr) return; 454 grpc_channel_destroy(client_); 455 client_ = nullptr; 456 } 457 // Shutdown the server; notify tag on completion. ShutdownServerAndNotify(int tag)458 void ShutdownServerAndNotify(int tag) { 459 grpc_server_shutdown_and_notify(server_, cq_, CqVerifier::tag(tag)); 460 } 461 // Destroy the server. DestroyServer()462 void DestroyServer() { 463 if (server_ == nullptr) return; 464 grpc_server_destroy(server_); 465 server_ = nullptr; 466 } 467 // Shutdown then destroy the server. ShutdownAndDestroyServer()468 void ShutdownAndDestroyServer() { 469 if (server_ == nullptr) return; 470 ShutdownServerAndNotify(-1); 471 Expect(-1, AnyStatus{}); 472 Step(); 473 DestroyServer(); 474 } 475 // Cancel any calls on the server. CancelAllCallsOnServer()476 void CancelAllCallsOnServer() { grpc_server_cancel_all_calls(server_); } 477 // Ping the server from the client PingServerFromClient(int tag)478 void PingServerFromClient(int tag) { 479 grpc_channel_ping(client_, cq_, CqVerifier::tag(tag), nullptr); 480 } 481 // Register a call on the client, return its handle. RegisterCallOnClient(const char * method,const char * host)482 RegisteredCall RegisterCallOnClient(const char* method, const char* host) { 483 ForceInitialized(); 484 return RegisteredCall{ 485 grpc_channel_register_call(client_, method, host, nullptr)}; 486 } 487 488 // Return the current connectivity state of the client. CheckConnectivityState(bool try_to_connect)489 grpc_connectivity_state CheckConnectivityState(bool try_to_connect) { 490 return grpc_channel_check_connectivity_state(client_, try_to_connect); 491 } 492 493 // Watch the connectivity state of the client. WatchConnectivityState(grpc_connectivity_state last_observed_state,Duration deadline,int tag)494 void WatchConnectivityState(grpc_connectivity_state last_observed_state, 495 Duration deadline, int tag) { 496 grpc_channel_watch_connectivity_state( 497 client_, last_observed_state, 498 grpc_timeout_milliseconds_to_deadline(deadline.millis()), cq_, 499 CqVerifier::tag(tag)); 500 } 501 502 // Return the client channel. client()503 grpc_channel* client() { 504 ForceInitialized(); 505 return client_; 506 } 507 508 // Return the server channel. server()509 grpc_server* server() { 510 ForceInitialized(); 511 return server_; 512 } 513 cq()514 grpc_completion_queue* cq() { 515 ForceInitialized(); 516 return cq_; 517 } 518 519 // Given a duration, return a timestamp that is that duration in the future - 520 // with dilation according to test environment (eg sanitizers) TimestampAfterDuration(Duration duration)521 Timestamp TimestampAfterDuration(Duration duration) { 522 return Timestamp::FromTimespecRoundUp( 523 grpc_timeout_milliseconds_to_deadline(duration.millis())); 524 } 525 SetPostGrpcInitFunc(absl::AnyInvocable<void ()> fn)526 void SetPostGrpcInitFunc(absl::AnyInvocable<void()> fn) { 527 CHECK(fixture_ == nullptr); 528 post_grpc_init_func_ = std::move(fn); 529 } 530 531 private: 532 void ForceInitialized(); 533 fixture()534 CoreTestFixture& fixture() { 535 if (fixture_ == nullptr) { 536 grpc_init(); 537 post_grpc_init_func_(); 538 cq_ = grpc_completion_queue_create_for_next(nullptr); 539 fixture_ = GetParam()->create_fixture(ChannelArgs(), ChannelArgs()); 540 } 541 return *fixture_; 542 } 543 cq_verifier()544 CqVerifier& cq_verifier() { 545 if (cq_verifier_ == nullptr) { 546 fixture(); // ensure cq_ present 547 cq_verifier_ = absl::make_unique<CqVerifier>( 548 cq_, 549 g_is_fuzzing_core_e2e_tests ? CqVerifier::FailUsingGprCrashWithStdio 550 : CqVerifier::FailUsingGprCrash, 551 step_fn_ == nullptr 552 ? nullptr 553 : absl::AnyInvocable<void( 554 grpc_event_engine::experimental::EventEngine::Duration) 555 const>( 556 [this]( 557 grpc_event_engine::experimental::EventEngine::Duration 558 d) { step_fn_(d); })); 559 } 560 return *cq_verifier_; 561 } 562 563 const CoreTestConfiguration* param_ = nullptr; 564 std::unique_ptr<CoreTestFixture> fixture_; 565 grpc_completion_queue* cq_ = nullptr; 566 grpc_server* server_ = nullptr; 567 grpc_channel* client_ = nullptr; 568 std::unique_ptr<CqVerifier> cq_verifier_; 569 absl::AnyInvocable<void(grpc_server*)> pre_server_start_ = [](grpc_server*) { 570 }; 571 int expectations_ = 0; 572 bool initialized_ = false; 573 absl::AnyInvocable<void()> post_grpc_init_func_ = []() {}; 574 absl::AnyInvocable<void( 575 grpc_event_engine::experimental::EventEngine::Duration) const> 576 step_fn_ = nullptr; 577 absl::AnyInvocable<void( 578 std::shared_ptr<grpc_event_engine::experimental::EventEngine>&&)> 579 quiesce_event_engine_ = 580 grpc_event_engine::experimental::WaitForSingleOwner; 581 }; 582 583 // Define names for additional test suites. 584 // These make no changes to the actual class, but define new names to register 585 // tests against. Each new name gets a differing set of configurations in 586 // end2end_test_main.cc to customize the set of fixtures the tests run against. 587 588 // Test suite for tests that rely on a secure transport 589 class SecureEnd2endTest : public CoreEnd2endTest {}; 590 // Test suite for tests that send rather large messages/metadata 591 class CoreLargeSendTest : public CoreEnd2endTest {}; 592 // Test suite for tests that need a client channel 593 class CoreClientChannelTest : public CoreEnd2endTest {}; 594 // Test suite for tests that require deadline handling 595 class CoreDeadlineTest : public CoreEnd2endTest {}; 596 // Test suite for tests that require deadline handling 597 class CoreDeadlineSingleHopTest : public CoreEnd2endTest {}; 598 // Test suite for http2 tests that only work over a single hop (unproxyable) 599 class Http2SingleHopTest : public CoreEnd2endTest {}; 600 // Test suite for fullstack single hop http2 tests (require client channel) 601 class Http2FullstackSingleHopTest : public CoreEnd2endTest {}; 602 // Test suite for tests that require retry features 603 class RetryTest : public CoreEnd2endTest {}; 604 // Test suite for write buffering 605 class WriteBufferingTest : public CoreEnd2endTest {}; 606 // Test suite for http2 tests 607 class Http2Test : public CoreEnd2endTest {}; 608 // Test suite for http2 tests that require retry features 609 class RetryHttp2Test : public CoreEnd2endTest {}; 610 // Test suite for tests that require resource quota 611 class ResourceQuotaTest : public CoreEnd2endTest {}; 612 // Test suite for tests that require a transport that supports secure call 613 // credentials 614 class PerCallCredsTest : public CoreEnd2endTest {}; 615 // Test suite for tests that require a transport that supports insecure call 616 // credentials 617 class PerCallCredsOnInsecureTest : public CoreEnd2endTest {}; 618 // Test suite for tests that verify lack of logging in particular situations 619 class NoLoggingTest : public CoreEnd2endTest {}; 620 // Test suite for tests that verify proxy authentication 621 class ProxyAuthTest : public CoreEnd2endTest {}; 622 623 using MakeTestFn = absl::AnyInvocable<CoreEnd2endTest*( 624 const CoreTestConfiguration* config) const>; 625 626 class CoreEnd2endTestRegistry { 627 public: 628 CoreEnd2endTestRegistry(const CoreEnd2endTestRegistry&) = delete; 629 CoreEnd2endTestRegistry& operator=(const CoreEnd2endTestRegistry&) = delete; 630 Get()631 static CoreEnd2endTestRegistry& Get() { 632 static CoreEnd2endTestRegistry* singleton = new CoreEnd2endTestRegistry; 633 return *singleton; 634 } 635 636 struct Test { 637 absl::string_view suite; 638 absl::string_view name; 639 const CoreTestConfiguration* config; 640 const MakeTestFn& make_test; 641 }; 642 643 void RegisterTest(absl::string_view suite, absl::string_view name, 644 MakeTestFn make_test, SourceLocation where = {}); 645 646 void RegisterSuite(absl::string_view suite, 647 std::vector<const CoreTestConfiguration*> configs, 648 SourceLocation where); 649 650 std::vector<Test> AllTests(); 651 652 // Enforce passing a type so that we can check it exists (saves typos) 653 template <typename T> 654 absl::void_t<T> RegisterSuiteT( 655 absl::string_view suite, 656 std::vector<const CoreTestConfiguration*> configs, 657 SourceLocation where = {}) { 658 return RegisterSuite(suite, std::move(configs), where); 659 } 660 661 private: 662 CoreEnd2endTestRegistry() = default; 663 664 std::map<absl::string_view, std::vector<const CoreTestConfiguration*>> 665 suites_; 666 std::map<absl::string_view, std::map<absl::string_view, MakeTestFn>> 667 tests_by_suite_; 668 }; 669 670 } // namespace grpc_core 671 672 // If this test fixture is being run under minstack, skip the test. 673 #define SKIP_IF_MINSTACK() \ 674 if (GetParam()->feature_mask & FEATURE_MASK_IS_MINSTACK) \ 675 GTEST_SKIP() << "Skipping test for minstack" 676 677 #define SKIP_IF_FUZZING() \ 678 if (g_is_fuzzing_core_e2e_tests) GTEST_SKIP() << "Skipping test for fuzzing" 679 680 #define SKIP_IF_V3() \ 681 if (GetParam()->feature_mask & FEATURE_MASK_IS_CALL_V3) { \ 682 GTEST_SKIP() << "Disabled for initial v3 testing"; \ 683 } 684 685 #define SKIP_IF_LOCAL_TCP_CREDS() \ 686 if (GetParam()->feature_mask & FEATURE_MASK_IS_LOCAL_TCP_CREDS) { \ 687 GTEST_SKIP() << "Disabled for Local TCP Connection"; \ 688 } 689 690 #define CORE_END2END_TEST(suite, name) \ 691 class CoreEnd2endTest_##suite##_##name : public grpc_core::suite { \ 692 public: \ 693 CoreEnd2endTest_##suite##_##name() {} \ 694 void TestBody() override { \ 695 if ((GetParam()->feature_mask & FEATURE_MASK_IS_CALL_V3) && \ 696 (grpc_core::ConfigVars::Get().PollStrategy() == "poll")) { \ 697 GTEST_SKIP() << "call-v3 not supported with poll poller"; \ 698 } \ 699 RunTest(); \ 700 } \ 701 void RunTest() override; \ 702 \ 703 private: \ 704 static grpc_core::CoreEnd2endTest* Run( \ 705 const grpc_core::CoreTestConfiguration* config) { \ 706 auto* test = new CoreEnd2endTest_##suite##_##name; \ 707 test->TestInfrastructureSetParam(config); \ 708 return test; \ 709 } \ 710 static int registered_; \ 711 }; \ 712 int CoreEnd2endTest_##suite##_##name::registered_ = \ 713 (grpc_core::CoreEnd2endTestRegistry::Get().RegisterTest(#suite, #name, \ 714 &Run), \ 715 0); \ 716 void CoreEnd2endTest_##suite##_##name::RunTest() 717 718 #define CORE_END2END_TEST_SUITE(suite, configs) \ 719 static int registered_##suite = \ 720 (grpc_core::CoreEnd2endTestRegistry::Get() \ 721 .template RegisterSuiteT<suite>(#suite, configs), \ 722 0) 723 724 #endif // GRPC_TEST_CORE_END2END_END2END_TESTS_H 725