xref: /aosp_15_r20/external/grpc-grpc/test/core/end2end/end2end_tests.h (revision cc02d7e222339f7a4f6ba5f422e6413f4bd931f2)
1 //
2 //
3 // Copyright 2015 gRPC authors.
4 //
5 // Licensed under the Apache License, Version 2.0 (the "License");
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 //     http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 //
17 //
18 
19 #ifndef GRPC_TEST_CORE_END2END_END2END_TESTS_H
20 #define GRPC_TEST_CORE_END2END_END2END_TESTS_H
21 
22 #include <stdint.h>
23 #include <stdio.h>
24 
25 #include <algorithm>
26 #include <functional>
27 #include <initializer_list>
28 #include <map>
29 #include <memory>
30 #include <string>
31 #include <utility>
32 #include <vector>
33 
34 #include "absl/functional/any_invocable.h"
35 #include "absl/memory/memory.h"
36 #include "absl/meta/type_traits.h"
37 #include "absl/strings/str_cat.h"
38 #include "absl/strings/string_view.h"
39 #include "absl/types/optional.h"
40 #include "absl/types/variant.h"
41 #include "gtest/gtest.h"
42 
43 #include <grpc/byte_buffer.h>
44 #include <grpc/compression.h>
45 #include <grpc/event_engine/event_engine.h>
46 #include <grpc/grpc.h>
47 #include <grpc/grpc_security.h>
48 #include <grpc/impl/propagation_bits.h>
49 #include <grpc/status.h>
50 #include <grpc/support/alloc.h>
51 #include <grpc/support/log.h>
52 #include <grpc/support/time.h>
53 
54 #include "src/core/lib/channel/channel_args.h"
55 #include "src/core/lib/gprpp/bitset.h"
56 #include "src/core/lib/gprpp/debug_location.h"
57 #include "src/core/lib/gprpp/time.h"
58 #include "src/core/lib/slice/slice.h"
59 #include "src/core/lib/slice/slice_internal.h"
60 #include "src/core/lib/surface/call_test_only.h"
61 #include "src/core/lib/surface/channel.h"
62 #include "test/core/end2end/cq_verifier.h"
63 #include "test/core/event_engine/event_engine_test_utils.h"
64 #include "test/core/util/test_config.h"
65 
66 // Test feature flags.
67 #define FEATURE_MASK_DOES_NOT_SUPPORT_RETRY (1 << 0)
68 #define FEATURE_MASK_SUPPORTS_HOSTNAME_VERIFICATION (1 << 1)
69 // Feature mask supports call credentials with a minimum security level of
70 // GRPC_PRIVACY_AND_INTEGRITY.
71 #define FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS (1 << 2)
72 // Feature mask supports call credentials with a minimum security level of
73 // GRPC_SECURTITY_NONE.
74 #define FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS_LEVEL_INSECURE (1 << 3)
75 #define FEATURE_MASK_SUPPORTS_REQUEST_PROXYING (1 << 4)
76 #define FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL (1 << 5)
77 #define FEATURE_MASK_IS_HTTP2 (1 << 6)
78 #define FEATURE_MASK_ENABLES_TRACES (1 << 7)
79 #define FEATURE_MASK_1BYTE_AT_A_TIME (1 << 8)
80 #define FEATURE_MASK_DOES_NOT_SUPPORT_WRITE_BUFFERING (1 << 9)
81 #define FEATURE_MASK_DOES_NOT_SUPPORT_CLIENT_HANDSHAKE_COMPLETE_FIRST (1 << 10)
82 #define FEATURE_MASK_IS_MINSTACK (1 << 11)
83 #define FEATURE_MASK_IS_SECURE (1 << 12)
84 #define FEATURE_MASK_DO_NOT_FUZZ (1 << 13)
85 // Exclude this fixture from experiment runs
86 #define FEATURE_MASK_EXCLUDE_FROM_EXPERIMENT_RUNS (1 << 14)
87 
88 #define FAIL_AUTH_CHECK_SERVER_ARG_NAME "fail_auth_check"
89 
90 namespace grpc_core {
91 
92 extern bool g_is_fuzzing_core_e2e_tests;
93 
94 class CoreTestFixture {
95  public:
96   virtual ~CoreTestFixture() = default;
97 
98   virtual grpc_server* MakeServer(
99       const ChannelArgs& args, grpc_completion_queue* cq,
100       absl::AnyInvocable<void(grpc_server*)>& pre_server_start) = 0;
101   virtual grpc_channel* MakeClient(const ChannelArgs& args,
102                                    grpc_completion_queue* cq) = 0;
103 };
104 
105 Slice RandomSlice(size_t length);
106 Slice RandomBinarySlice(size_t length);
107 using ByteBufferUniquePtr =
108     std::unique_ptr<grpc_byte_buffer, void (*)(grpc_byte_buffer*)>;
109 ByteBufferUniquePtr ByteBufferFromSlice(Slice slice);
110 
111 struct CoreTestConfiguration {
112   // A descriptive name for this test fixture.
113   const char* name;
114 
115   // Which features are supported by this fixture. See feature flags above.
116   uint32_t feature_mask;
117 
118   // If the call host is setup by the fixture (for example, via the
119   // GRPC_SSL_TARGET_NAME_OVERRIDE_ARG channel arg), which value should the
120   // test expect to find in call_details.host
121   const char* overridden_call_host;
122 
123   std::function<std::unique_ptr<CoreTestFixture>(
124       const ChannelArgs& client_args, const ChannelArgs& server_args)>
125       create_fixture;
126 };
127 
128 // Base class for e2e tests.
129 //
130 // Initialization:
131 //
132 // At the start of a test, nothing is initialized. CoreConfiguration is reset,
133 // and there's certainly no server nor client.
134 // A test can then register whatever builders it wants into the
135 // CoreConfiguration and have them picked up. If it does not, it will get the
136 // default CoreConfiguration.
137 //
138 // The test may choose to then create a client and server with InitClient() and
139 // InitServer(). It does not matter which order they are called, nor whether one
140 // or both are called. It's necessary to call these if the test demands that
141 // non-empty channel args should be passed to either the client or server.
142 //
143 // If a test does not call InitClient() or InitServer(), then upon the first
144 // call to either NewClientCall() or NewServerCall(), the client and server will
145 // be instantiated - this saves substantial boilerplate in the most common case
146 // for our tests.
147 //
148 // Notes:
149 // - older compilers fail matching absl::string_view with some gmock matchers on
150 //   older compilers, and it's tremendously convenient to be able to do so. So
151 //   we use std::string for return types here - performance isn't particularly
152 //   important, so an extra copy is fine.
153 class CoreEnd2endTest : public ::testing::Test {
154  public:
TestInfrastructureSetParam(const CoreTestConfiguration * param)155   void TestInfrastructureSetParam(const CoreTestConfiguration* param) {
156     param_ = param;
157   }
GetParam()158   const CoreTestConfiguration* GetParam() { return param_; }
159 
160   void SetUp() override;
161   void TearDown() override;
162   virtual void RunTest() = 0;
163 
SetCqVerifierStepFn(absl::AnyInvocable<void (grpc_event_engine::experimental::EventEngine::Duration)const> step_fn)164   void SetCqVerifierStepFn(
165       absl::AnyInvocable<
166           void(grpc_event_engine::experimental::EventEngine::Duration) const>
167           step_fn) {
168     step_fn_ = std::move(step_fn);
169   }
SetQuiesceEventEngine(absl::AnyInvocable<void (std::shared_ptr<grpc_event_engine::experimental::EventEngine> &&)> quiesce_event_engine)170   void SetQuiesceEventEngine(
171       absl::AnyInvocable<
172           void(std::shared_ptr<grpc_event_engine::experimental::EventEngine>&&)>
173           quiesce_event_engine) {
174     quiesce_event_engine_ = std::move(quiesce_event_engine);
175   }
176 
177   class Call;
178   struct RegisteredCall {
179     void* p;
180   };
181 
182   // CallBuilder - results in a call to either grpc_channel_create_call or
183   // grpc_channel_create_registered_call.
184   // Affords a fluent interface to specify optional arguments.
185   class ClientCallBuilder {
186    public:
ClientCallBuilder(CoreEnd2endTest & test,std::string method)187     ClientCallBuilder(CoreEnd2endTest& test, std::string method)
188         : test_(test),
189           call_selector_(UnregisteredCall{std::move(method), absl::nullopt}) {}
ClientCallBuilder(CoreEnd2endTest & test,RegisteredCall registered_call)190     ClientCallBuilder(CoreEnd2endTest& test, RegisteredCall registered_call)
191         : test_(test), call_selector_(registered_call.p) {}
192 
193     // Specify the host (otherwise nullptr is passed)
Host(std::string host)194     ClientCallBuilder& Host(std::string host) {
195       absl::get<UnregisteredCall>(call_selector_).host = std::move(host);
196       return *this;
197     }
198     // Specify the timeout (otherwise gpr_inf_future is passed) - this time is
199     // scaled according to the test environment.
Timeout(Duration timeout)200     ClientCallBuilder& Timeout(Duration timeout) {
201       if (timeout == Duration::Infinity()) {
202         deadline_ = gpr_inf_future(GPR_CLOCK_REALTIME);
203         return *this;
204       }
205       deadline_ = grpc_timeout_milliseconds_to_deadline(timeout.millis());
206       return *this;
207     }
208     // Finally create the call.
209     Call Create();
210 
211    private:
212     CoreEnd2endTest& test_;
213     struct UnregisteredCall {
214       std::string method;
215       absl::optional<std::string> host;
216     };
217     absl::variant<void*, UnregisteredCall> call_selector_;
218     grpc_call* parent_call_ = nullptr;
219     uint32_t propagation_mask_ = GRPC_PROPAGATE_DEFAULTS;
220     gpr_timespec deadline_ = gpr_inf_future(GPR_CLOCK_REALTIME);
221   };
222 
223   // Receiving container for incoming metadata.
224   class IncomingMetadata final : public CqVerifier::SuccessfulStateString {
225    public:
226     IncomingMetadata() = default;
~IncomingMetadata()227     ~IncomingMetadata() {
228       if (metadata_ != nullptr) grpc_metadata_array_destroy(metadata_.get());
229     }
230 
231     // Lookup a metadata value by key.
232     absl::optional<std::string> Get(absl::string_view key) const;
233 
234     // Make a GRPC_RECV_INITIAL_METADATA op - intended for the framework, not
235     // for tests.
236     grpc_op MakeOp();
237 
238     std::string GetSuccessfulStateString() override;
239 
240    private:
241     std::unique_ptr<grpc_metadata_array> metadata_ =
242         std::make_unique<grpc_metadata_array>(
243             grpc_metadata_array{0, 0, nullptr});
244   };
245 
246   class IncomingCall;
247 
248   // Receiving container for one incoming message.
249   class IncomingMessage final : public CqVerifier::SuccessfulStateString {
250    public:
251     IncomingMessage() = default;
252     IncomingMessage(const IncomingMessage&) = delete;
253     IncomingMessage& operator=(const IncomingMessage&) = delete;
~IncomingMessage()254     ~IncomingMessage() {
255       if (payload_ != nullptr) grpc_byte_buffer_destroy(payload_);
256     }
257 
258     // Get the payload of the message - concatenated together into a string for
259     // easy verification.
260     std::string payload() const;
261     // Check if the message is the end of the stream.
is_end_of_stream()262     bool is_end_of_stream() const { return payload_ == nullptr; }
263     // Get the type of the message.
byte_buffer_type()264     grpc_byte_buffer_type byte_buffer_type() const { return payload_->type; }
265     // Get the compression algorithm used for the message.
compression()266     grpc_compression_algorithm compression() const {
267       return payload_->data.raw.compression;
268     }
269     std::string GetSuccessfulStateString() override;
270 
271     // Make a GRPC_OP_RECV_MESSAGE op - intended for the framework, not for
272     // tests.
273     grpc_op MakeOp();
274 
275    private:
276     friend class IncomingCall;
277     grpc_byte_buffer* payload_ = nullptr;
278   };
279 
280   // Receiving container for incoming status on the client from the server.
281   class IncomingStatusOnClient final
282       : public CqVerifier::SuccessfulStateString {
283    public:
284     IncomingStatusOnClient() = default;
285     IncomingStatusOnClient(const IncomingStatusOnClient&) = delete;
286     IncomingStatusOnClient& operator=(const IncomingStatusOnClient&) = delete;
287     IncomingStatusOnClient(IncomingStatusOnClient&& other) noexcept = default;
288     IncomingStatusOnClient& operator=(IncomingStatusOnClient&& other) noexcept =
289         default;
~IncomingStatusOnClient()290     ~IncomingStatusOnClient() {
291       if (data_ != nullptr) {
292         grpc_metadata_array_destroy(&data_->trailing_metadata);
293         gpr_free(const_cast<char*>(data_->error_string));
294       }
295     }
296 
297     // Get the status code.
status()298     grpc_status_code status() const { return data_->status; }
299     // Get the status details.
message()300     std::string message() const {
301       return std::string(data_->status_details.as_string_view());
302     }
303     // Get the error string.
error_string()304     std::string error_string() const {
305       return data_->error_string == nullptr ? "" : data_->error_string;
306     }
307     // Get a trailing metadata value by key.
308     absl::optional<std::string> GetTrailingMetadata(
309         absl::string_view key) const;
310 
311     std::string GetSuccessfulStateString() override;
312 
313     // Make a GRPC_OP_RECV_STATUS_ON_CLIENT op - intended for the framework, not
314     // for tests.
315     grpc_op MakeOp();
316 
317    private:
318     struct Data {
319       grpc_metadata_array trailing_metadata{0, 0, nullptr};
320       grpc_status_code status;
321       Slice status_details;
322       const char* error_string = nullptr;
323     };
324     std::unique_ptr<Data> data_ = std::make_unique<Data>();
325   };
326 
327   // Receiving container for incoming status on the server from the client.
328   class IncomingCloseOnServer final : public CqVerifier::SuccessfulStateString {
329    public:
330     IncomingCloseOnServer() = default;
331     IncomingCloseOnServer(const IncomingCloseOnServer&) = delete;
332     IncomingCloseOnServer& operator=(const IncomingCloseOnServer&) = delete;
333 
334     // Get the cancellation bit.
was_cancelled()335     bool was_cancelled() const { return cancelled_ != 0; }
336 
337     // Make a GRPC_OP_RECV_CLOSE_ON_SERVER op - intended for the framework, not
338     // for tests.
339     grpc_op MakeOp();
340 
GetSuccessfulStateString()341     std::string GetSuccessfulStateString() override {
342       return absl::StrCat("close_on_server: cancelled=", cancelled_);
343     }
344 
345    private:
346     int cancelled_;
347   };
348 
349   // Build one batch. Returned from NewBatch (use that to instantiate this!)
350   // Upon destruction of the BatchBuilder, the batch will be executed with any
351   // added batches.
352   class BatchBuilder {
353    public:
BatchBuilder(grpc_call * call,CoreEnd2endTest * test,int tag)354     BatchBuilder(grpc_call* call, CoreEnd2endTest* test, int tag)
355         : call_(call), tag_(tag), cq_verifier_(&test->cq_verifier()) {
356       cq_verifier_->ClearSuccessfulStateStrings(CqVerifier::tag(tag_));
357     }
358     ~BatchBuilder();
359 
360     BatchBuilder(const BatchBuilder&) = delete;
361     BatchBuilder& operator=(const BatchBuilder&) = delete;
362     BatchBuilder(BatchBuilder&&) noexcept = default;
363 
364     // Add a GRPC_OP_SEND_INITIAL_METADATA op.
365     // Optionally specify flags, compression level.
366     BatchBuilder& SendInitialMetadata(
367         std::initializer_list<std::pair<absl::string_view, absl::string_view>>
368             md,
369         uint32_t flags = 0,
370         absl::optional<grpc_compression_level> compression_level =
371             absl::nullopt);
372 
373     // Add a GRPC_OP_SEND_MESSAGE op.
374     BatchBuilder& SendMessage(Slice payload, uint32_t flags = 0);
375     BatchBuilder& SendMessage(absl::string_view payload, uint32_t flags = 0) {
376       return SendMessage(Slice::FromCopiedString(payload), flags);
377     }
378 
379     // Add a GRPC_OP_SEND_CLOSE_FROM_CLIENT op.
380     BatchBuilder& SendCloseFromClient();
381 
382     // Add a GRPC_OP_SEND_STATUS_FROM_SERVER op.
383     BatchBuilder& SendStatusFromServer(
384         grpc_status_code status, absl::string_view message,
385         std::initializer_list<std::pair<absl::string_view, absl::string_view>>
386             md);
387 
388     // Add a GRPC_OP_RECV_INITIAL_METADATA op.
RecvInitialMetadata(IncomingMetadata & md)389     BatchBuilder& RecvInitialMetadata(IncomingMetadata& md) {
390       cq_verifier_->AddSuccessfulStateString(CqVerifier::tag(tag_), &md);
391       ops_.emplace_back(md.MakeOp());
392       return *this;
393     }
394 
395     // Add a GRPC_OP_RECV_MESSAGE op.
RecvMessage(IncomingMessage & msg)396     BatchBuilder& RecvMessage(IncomingMessage& msg) {
397       cq_verifier_->AddSuccessfulStateString(CqVerifier::tag(tag_), &msg);
398       ops_.emplace_back(msg.MakeOp());
399       return *this;
400     }
401 
402     // Add a GRPC_OP_RECV_STATUS_ON_CLIENT op.
RecvStatusOnClient(IncomingStatusOnClient & status)403     BatchBuilder& RecvStatusOnClient(IncomingStatusOnClient& status) {
404       cq_verifier_->AddSuccessfulStateString(CqVerifier::tag(tag_), &status);
405       ops_.emplace_back(status.MakeOp());
406       return *this;
407     }
408 
409     // Add a GRPC_OP_RECV_CLOSE_ON_SERVER op.
RecvCloseOnServer(IncomingCloseOnServer & close)410     BatchBuilder& RecvCloseOnServer(IncomingCloseOnServer& close) {
411       cq_verifier_->AddSuccessfulStateString(CqVerifier::tag(tag_), &close);
412       ops_.emplace_back(close.MakeOp());
413       return *this;
414     }
415 
416    private:
417     // We need to track little bits of memory up until the batch is executed.
418     // One Thing is one such block of memory.
419     // We specialize it with SpecificThing to track a specific type of memory.
420     // These get placed on things_ and deleted when the batch is executed.
421     class Thing {
422      public:
423       virtual ~Thing() = default;
424     };
425     template <typename T>
426     class SpecificThing final : public Thing {
427      public:
428       template <typename... Args>
SpecificThing(Args &&...args)429       explicit SpecificThing(Args&&... args)
430           : t_(std::forward<Args>(args)...) {}
431       SpecificThing() = default;
432 
get()433       T& get() { return t_; }
434 
435      private:
436       T t_;
437     };
438 
439     // Make a thing of type T, and return a reference to it.
440     template <typename T, typename... Args>
Make(Args &&...args)441     T& Make(Args&&... args) {
442       things_.emplace_back(new SpecificThing<T>(std::forward<Args>(args)...));
443       return static_cast<SpecificThing<T>*>(things_.back().get())->get();
444     }
445 
446     grpc_call* call_;
447     const int tag_;
448     std::vector<grpc_op> ops_;
449     std::vector<std::unique_ptr<Thing>> things_;
450     CqVerifier* const cq_verifier_;
451   };
452 
453   // Wrapper around a grpc_call.
454   // Instantiated by ClientCallBuilder via NewClientCall for client calls.
455   // Wrapped by IncomingCall for server calls.
456   class Call {
457    public:
Call(grpc_call * call,CoreEnd2endTest * test)458     Call(grpc_call* call, CoreEnd2endTest* test) : call_(call), test_(test) {}
459     Call(const Call&) = delete;
460     Call& operator=(const Call&) = delete;
Call(Call && other)461     Call(Call&& other) noexcept
462         : call_(std::exchange(other.call_, nullptr)),
463           test_(std::exchange(other.test_, nullptr)) {}
~Call()464     ~Call() {
465       if (call_ != nullptr) grpc_call_unref(call_);
466     }
467     // Construct a batch with a tag - upon destruction of the BatchBuilder the
468     // operation will occur.
NewBatch(int tag)469     BatchBuilder NewBatch(int tag) { return BatchBuilder(call_, test_, tag); }
470     // Cancel the call
Cancel()471     void Cancel() { grpc_call_cancel(call_, nullptr); }
CancelWithStatus(grpc_status_code status,const char * message)472     void CancelWithStatus(grpc_status_code status, const char* message) {
473       grpc_call_cancel_with_status(call_, status, message, nullptr);
474     }
475     // Access the peer structure (returns a string that can be matched, etc) -
476     // or nullopt if grpc_call_get_peer returns nullptr.
GetPeer()477     absl::optional<std::string> GetPeer() {
478       char* peer = grpc_call_get_peer(call_);
479       if (peer == nullptr) return absl::nullopt;
480       std::string result(peer);
481       gpr_free(peer);
482       return result;
483     }
484 
485     // Set call credentials.
486     // Takes ownership of creds.
SetCredentials(grpc_call_credentials * creds)487     void SetCredentials(grpc_call_credentials* creds) {
488       EXPECT_EQ(grpc_call_set_credentials(call_, creds), GRPC_CALL_OK);
489       grpc_call_credentials_release(creds);
490     }
491 
492     // Retrieve the auth context.
493     std::unique_ptr<grpc_auth_context, void (*)(grpc_auth_context*)>
GetAuthContext()494     GetAuthContext() {
495       return std::unique_ptr<grpc_auth_context, void (*)(grpc_auth_context*)>(
496           grpc_call_auth_context(call_), grpc_auth_context_release);
497     }
498 
call_ptr()499     grpc_call** call_ptr() { return &call_; }
c_call()500     grpc_call* c_call() const { return call_; }
501 
502    private:
503     grpc_call* call_ = nullptr;
504     CoreEnd2endTest* test_;
505   };
506 
507   // Wrapper around a server call.
508   class IncomingCall {
509    public:
510     IncomingCall(CoreEnd2endTest& test, int tag);
511     IncomingCall(CoreEnd2endTest& test, void* method, IncomingMessage* message,
512                  int tag);
513     IncomingCall(const IncomingCall&) = delete;
514     IncomingCall& operator=(const IncomingCall&) = delete;
515     IncomingCall(IncomingCall&&) noexcept = default;
516 
517     // Construct a batch with a tag - upon destruction of the BatchBuilder the
518     // operation will occur. Must have received the call first!
NewBatch(int tag)519     BatchBuilder NewBatch(int tag) { return impl_->call.NewBatch(tag); }
Cancel()520     void Cancel() { impl_->call.Cancel(); }
521 
522     // Return the method being called.
method()523     std::string method() const {
524       return std::string(StringViewFromSlice(impl_->call_details.method));
525     }
526 
527     // Return the host being called.
host()528     std::string host() const {
529       return std::string(StringViewFromSlice(impl_->call_details.host));
530     }
531 
532     // Return some initial metadata.
533     absl::optional<std::string> GetInitialMetadata(absl::string_view key) const;
534 
535     // Return the peer address.
GetPeer()536     absl::optional<std::string> GetPeer() { return impl_->call.GetPeer(); }
537 
538     // Return the auth context.
539     std::unique_ptr<grpc_auth_context, void (*)(grpc_auth_context*)>
GetAuthContext()540     GetAuthContext() {
541       return impl_->call.GetAuthContext();
542     }
543 
544     // Return the underlying C call object
c_call()545     grpc_call* c_call() { return impl_->call.c_call(); }
546 
547     // Return the encodings accepted by the peer.
GetEncodingsAcceptedByPeer()548     BitSet<GRPC_COMPRESS_ALGORITHMS_COUNT> GetEncodingsAcceptedByPeer() {
549       return BitSet<GRPC_COMPRESS_ALGORITHMS_COUNT>::FromInt(
550           grpc_call_test_only_get_encodings_accepted_by_peer(c_call()));
551     }
552 
553    private:
554     struct Impl {
ImplImpl555       explicit Impl(CoreEnd2endTest* test) : call(nullptr, test) {
556         grpc_call_details_init(&call_details);
557         grpc_metadata_array_init(&request_metadata);
558       }
~ImplImpl559       ~Impl() {
560         grpc_call_details_destroy(&call_details);
561         grpc_metadata_array_destroy(&request_metadata);
562       }
563       Call call;
564       grpc_call_details call_details;
565       grpc_metadata_array request_metadata;
566     };
567     std::unique_ptr<Impl> impl_;
568   };
569 
570   class ServerRegisteredMethod {
571    public:
572     ServerRegisteredMethod(
573         CoreEnd2endTest* test, absl::string_view name,
574         grpc_server_register_method_payload_handling payload_handling);
575 
handle()576     void* handle() { return *handle_; }
577 
578    private:
579     std::shared_ptr<void*> handle_ = std::make_shared<void*>(nullptr);
580   };
581 
RegisterServerMethod(absl::string_view name,grpc_server_register_method_payload_handling payload_handling)582   ServerRegisteredMethod RegisterServerMethod(
583       absl::string_view name,
584       grpc_server_register_method_payload_handling payload_handling) {
585     return ServerRegisteredMethod(this, name, payload_handling);
586   }
587 
588   // Begin construction of a client call.
NewClientCall(std::string method)589   ClientCallBuilder NewClientCall(std::string method) {
590     return ClientCallBuilder(*this, std::move(method));
591   }
NewClientCall(RegisteredCall registered_method)592   ClientCallBuilder NewClientCall(RegisteredCall registered_method) {
593     return ClientCallBuilder(*this, registered_method);
594   }
595   // Request a call on the server - notifies `tag` when complete.
RequestCall(int tag)596   IncomingCall RequestCall(int tag) { return IncomingCall(*this, tag); }
597   // Request a call on the server - notifies `tag` when complete.
RequestRegisteredCall(ServerRegisteredMethod method,int tag)598   IncomingCall RequestRegisteredCall(ServerRegisteredMethod method, int tag) {
599     return IncomingCall(*this, method.handle(), nullptr, tag);
600   }
RequestRegisteredCall(ServerRegisteredMethod method,IncomingMessage * message,int tag)601   IncomingCall RequestRegisteredCall(ServerRegisteredMethod method,
602                                      IncomingMessage* message, int tag) {
603     return IncomingCall(*this, method.handle(), message, tag);
604   }
605 
606   // Pull in CqVerifier types for ergonomics
607   // TODO(ctiller): evaluate just dropping CqVerifier and folding it in here.
608   using ExpectedResult = CqVerifier::ExpectedResult;
609   using Maybe = CqVerifier::Maybe;
610   using PerformAction = CqVerifier::PerformAction;
611   using MaybePerformAction = CqVerifier::MaybePerformAction;
612   using AnyStatus = CqVerifier::AnyStatus;
613   // Expect a tag with some result.
614   void Expect(int tag, ExpectedResult result, SourceLocation whence = {}) {
615     expectations_++;
616     cq_verifier().Expect(CqVerifier::tag(tag), std::move(result), whence);
617   }
618   // Step the system until expectations are met or until timeout is reached.
619   // If there are no expectations logged, then step for 1 second and verify that
620   // no events occur.
621   void Step(absl::optional<Duration> timeout = absl::nullopt,
622             SourceLocation whence = {}) {
623     if (expectations_ == 0) {
624       cq_verifier().VerifyEmpty(timeout.value_or(Duration::Seconds(1)), whence);
625       return;
626     }
627     expectations_ = 0;
628     cq_verifier().Verify(
629         timeout.value_or(g_is_fuzzing_core_e2e_tests ? Duration::Minutes(10)
630                                                      : Duration::Seconds(10)),
631         whence);
632   }
633 
634   // Initialize the client.
635   // If called, then InitServer must be called to create a server (otherwise one
636   // will be provided).
InitClient(const ChannelArgs & args)637   void InitClient(const ChannelArgs& args) {
638     initialized_ = true;
639     if (client_ != nullptr) ShutdownAndDestroyClient();
640     auto& f = fixture();
641     client_ = f.MakeClient(args, cq_);
642     GPR_ASSERT(client_ != nullptr);
643   }
644   // Initialize the server.
645   // If called, then InitClient must be called to create a client (otherwise one
646   // will be provided).
InitServer(const ChannelArgs & args)647   void InitServer(const ChannelArgs& args) {
648     initialized_ = true;
649     if (server_ != nullptr) ShutdownAndDestroyServer();
650     auto& f = fixture();
651     server_ = f.MakeServer(args, cq_, pre_server_start_);
652     GPR_ASSERT(server_ != nullptr);
653   }
654   // Remove the client.
ShutdownAndDestroyClient()655   void ShutdownAndDestroyClient() {
656     if (client_ == nullptr) return;
657     grpc_channel_destroy(client_);
658     client_ = nullptr;
659   }
660   // Shutdown the server; notify tag on completion.
ShutdownServerAndNotify(int tag)661   void ShutdownServerAndNotify(int tag) {
662     grpc_server_shutdown_and_notify(server_, cq_, CqVerifier::tag(tag));
663   }
664   // Destroy the server.
DestroyServer()665   void DestroyServer() {
666     if (server_ == nullptr) return;
667     grpc_server_destroy(server_);
668     server_ = nullptr;
669   }
670   // Shutdown then destroy the server.
ShutdownAndDestroyServer()671   void ShutdownAndDestroyServer() {
672     if (server_ == nullptr) return;
673     ShutdownServerAndNotify(-1);
674     Expect(-1, AnyStatus{});
675     Step();
676     DestroyServer();
677   }
678   // Cancel any calls on the server.
CancelAllCallsOnServer()679   void CancelAllCallsOnServer() { grpc_server_cancel_all_calls(server_); }
680   // Ping the server from the client
PingServerFromClient(int tag)681   void PingServerFromClient(int tag) {
682     grpc_channel_ping(client_, cq_, CqVerifier::tag(tag), nullptr);
683   }
684   // Register a call on the client, return its handle.
RegisterCallOnClient(const char * method,const char * host)685   RegisteredCall RegisterCallOnClient(const char* method, const char* host) {
686     ForceInitialized();
687     return RegisteredCall{
688         grpc_channel_register_call(client_, method, host, nullptr)};
689   }
690 
691   // Return the current connectivity state of the client.
CheckConnectivityState(bool try_to_connect)692   grpc_connectivity_state CheckConnectivityState(bool try_to_connect) {
693     return grpc_channel_check_connectivity_state(client_, try_to_connect);
694   }
695 
696   // Watch the connectivity state of the client.
WatchConnectivityState(grpc_connectivity_state last_observed_state,Duration deadline,int tag)697   void WatchConnectivityState(grpc_connectivity_state last_observed_state,
698                               Duration deadline, int tag) {
699     grpc_channel_watch_connectivity_state(
700         client_, last_observed_state,
701         grpc_timeout_milliseconds_to_deadline(deadline.millis()), cq_,
702         CqVerifier::tag(tag));
703   }
704 
705   // Return the client channel.
client()706   grpc_channel* client() {
707     ForceInitialized();
708     return client_;
709   }
710 
711   // Return the server channel.
server()712   grpc_server* server() {
713     ForceInitialized();
714     return server_;
715   }
716 
cq()717   grpc_completion_queue* cq() {
718     ForceInitialized();
719     return cq_;
720   }
721 
722   // Given a duration, return a timestamp that is that duration in the future -
723   // with dilation according to test environment (eg sanitizers)
TimestampAfterDuration(Duration duration)724   Timestamp TimestampAfterDuration(Duration duration) {
725     return Timestamp::FromTimespecRoundUp(
726         grpc_timeout_milliseconds_to_deadline(duration.millis()));
727   }
728 
SetPostGrpcInitFunc(absl::AnyInvocable<void ()> fn)729   void SetPostGrpcInitFunc(absl::AnyInvocable<void()> fn) {
730     GPR_ASSERT(fixture_ == nullptr);
731     post_grpc_init_func_ = std::move(fn);
732   }
733 
734  private:
735   void ForceInitialized();
736 
fixture()737   CoreTestFixture& fixture() {
738     if (fixture_ == nullptr) {
739       grpc_init();
740       post_grpc_init_func_();
741       cq_ = grpc_completion_queue_create_for_next(nullptr);
742       fixture_ = GetParam()->create_fixture(ChannelArgs(), ChannelArgs());
743     }
744     return *fixture_;
745   }
746 
cq_verifier()747   CqVerifier& cq_verifier() {
748     if (cq_verifier_ == nullptr) {
749       fixture();  // ensure cq_ present
750       cq_verifier_ = absl::make_unique<CqVerifier>(
751           cq_,
752           g_is_fuzzing_core_e2e_tests ? CqVerifier::FailUsingGprCrashWithStdio
753                                       : CqVerifier::FailUsingGprCrash,
754           std::move(step_fn_));
755     }
756     return *cq_verifier_;
757   }
758 
759   const CoreTestConfiguration* param_ = nullptr;
760   std::unique_ptr<CoreTestFixture> fixture_;
761   grpc_completion_queue* cq_ = nullptr;
762   grpc_server* server_ = nullptr;
763   grpc_channel* client_ = nullptr;
764   std::unique_ptr<CqVerifier> cq_verifier_;
765   absl::AnyInvocable<void(grpc_server*)> pre_server_start_ = [](grpc_server*) {
766   };
767   int expectations_ = 0;
768   bool initialized_ = false;
769   absl::AnyInvocable<void()> post_grpc_init_func_ = []() {};
770   absl::AnyInvocable<void(
771       grpc_event_engine::experimental::EventEngine::Duration) const>
772       step_fn_ = nullptr;
773   absl::AnyInvocable<void(
774       std::shared_ptr<grpc_event_engine::experimental::EventEngine>&&)>
775       quiesce_event_engine_ =
776           grpc_event_engine::experimental::WaitForSingleOwner;
777 };
778 
779 // Define names for additional test suites.
780 // These make no changes to the actual class, but define new names to register
781 // tests against. Each new name gets a differing set of configurations in
782 // end2end_test_main.cc to customize the set of fixtures the tests run against.
783 
784 // Test suite for tests that rely on a secure transport
785 class SecureEnd2endTest : public CoreEnd2endTest {};
786 // Test suite for tests that send rather large messages/metadata
787 class CoreLargeSendTest : public CoreEnd2endTest {};
788 // Test suite for tests that need a client channel
789 class CoreClientChannelTest : public CoreEnd2endTest {};
790 // Test suite for tests that require deadline handling
791 class CoreDeadlineTest : public CoreEnd2endTest {};
792 // Test suite for tests that require deadline handling
793 class CoreDeadlineSingleHopTest : public CoreEnd2endTest {};
794 // Test suite for http2 tests that only work over a single hop (unproxyable)
795 class Http2SingleHopTest : public CoreEnd2endTest {};
796 // Test suite for fullstack single hop http2 tests (require client channel)
797 class Http2FullstackSingleHopTest : public CoreEnd2endTest {};
798 // Test suite for tests that require retry features
799 class RetryTest : public CoreEnd2endTest {};
800 // Test suite for write buffering
801 class WriteBufferingTest : public CoreEnd2endTest {};
802 // Test suite for http2 tests
803 class Http2Test : public CoreEnd2endTest {};
804 // Test suite for http2 tests that require retry features
805 class RetryHttp2Test : public CoreEnd2endTest {};
806 // Test suite for tests that require resource quota
807 class ResourceQuotaTest : public CoreEnd2endTest {};
808 // Test suite for tests that require a transport that supports secure call
809 // credentials
810 class PerCallCredsTest : public CoreEnd2endTest {};
811 // Test suite for tests that require a transport that supports insecure call
812 // credentials
813 class PerCallCredsOnInsecureTest : public CoreEnd2endTest {};
814 // Test suite for tests that verify lack of logging in particular situations
815 class NoLoggingTest : public CoreEnd2endTest {};
816 // Test suite for tests that verify proxy authentication
817 class ProxyAuthTest : public CoreEnd2endTest {};
818 
819 using MakeTestFn = absl::AnyInvocable<CoreEnd2endTest*(
820     const CoreTestConfiguration* config) const>;
821 
822 class CoreEnd2endTestRegistry {
823  public:
824   CoreEnd2endTestRegistry(const CoreEnd2endTestRegistry&) = delete;
825   CoreEnd2endTestRegistry& operator=(const CoreEnd2endTestRegistry&) = delete;
826 
Get()827   static CoreEnd2endTestRegistry& Get() {
828     static CoreEnd2endTestRegistry* singleton = new CoreEnd2endTestRegistry;
829     return *singleton;
830   }
831 
832   struct Test {
833     absl::string_view suite;
834     absl::string_view name;
835     const CoreTestConfiguration* config;
836     const MakeTestFn& make_test;
837   };
838 
839   void RegisterTest(absl::string_view suite, absl::string_view name,
840                     MakeTestFn make_test, SourceLocation where = {});
841 
842   void RegisterSuite(absl::string_view suite,
843                      std::vector<const CoreTestConfiguration*> configs,
844                      SourceLocation where);
845 
846   std::vector<Test> AllTests();
847 
848   // Enforce passing a type so that we can check it exists (saves typos)
849   template <typename T>
850   absl::void_t<T> RegisterSuiteT(
851       absl::string_view suite,
852       std::vector<const CoreTestConfiguration*> configs,
853       SourceLocation where = {}) {
854     return RegisterSuite(suite, std::move(configs), where);
855   }
856 
857  private:
858   CoreEnd2endTestRegistry() = default;
859 
860   std::map<absl::string_view, std::vector<const CoreTestConfiguration*>>
861       suites_;
862   std::map<absl::string_view, std::map<absl::string_view, MakeTestFn>>
863       tests_by_suite_;
864 };
865 
866 }  // namespace grpc_core
867 
868 // If this test fixture is being run under minstack, skip the test.
869 #define SKIP_IF_MINSTACK()                                 \
870   if (GetParam()->feature_mask & FEATURE_MASK_IS_MINSTACK) \
871   GTEST_SKIP() << "Skipping test for minstack"
872 
873 #define SKIP_IF_FUZZING() \
874   if (g_is_fuzzing_core_e2e_tests) GTEST_SKIP() << "Skipping test for fuzzing"
875 
876 #define SKIP_IF_CHAOTIC_GOOD()                                   \
877   if (IsChaoticGoodEnabled()) {                                  \
878     GTEST_SKIP() << "Disabled for initial chaotic good testing"; \
879   }
880 
881 #define CORE_END2END_TEST(suite, name)                                       \
882   class CoreEnd2endTest_##suite##_##name : public grpc_core::suite {         \
883    public:                                                                   \
884     CoreEnd2endTest_##suite##_##name() {}                                    \
885     void TestBody() override { RunTest(); }                                  \
886     void RunTest() override;                                                 \
887                                                                              \
888    private:                                                                  \
889     static grpc_core::CoreEnd2endTest* Run(                                  \
890         const grpc_core::CoreTestConfiguration* config) {                    \
891       auto* test = new CoreEnd2endTest_##suite##_##name;                     \
892       test->TestInfrastructureSetParam(config);                              \
893       return test;                                                           \
894     }                                                                        \
895     static int registered_;                                                  \
896   };                                                                         \
897   int CoreEnd2endTest_##suite##_##name::registered_ =                        \
898       (grpc_core::CoreEnd2endTestRegistry::Get().RegisterTest(#suite, #name, \
899                                                               &Run),         \
900        0);                                                                   \
901   void CoreEnd2endTest_##suite##_##name::RunTest()
902 
903 #define CORE_END2END_TEST_SUITE(suite, configs)              \
904   static int registered_##suite =                            \
905       (grpc_core::CoreEnd2endTestRegistry::Get()             \
906            .template RegisterSuiteT<suite>(#suite, configs), \
907        0)
908 
909 #endif  // GRPC_TEST_CORE_END2END_END2END_TESTS_H
910