xref: /aosp_15_r20/external/grpc-grpc/test/core/end2end/cq_verifier.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_CQ_VERIFIER_H
20 #define GRPC_TEST_CORE_END2END_CQ_VERIFIER_H
21 
22 #include <stdint.h>
23 
24 #include <functional>
25 #include <string>
26 #include <vector>
27 
28 #include "absl/container/flat_hash_map.h"
29 #include "absl/functional/any_invocable.h"
30 #include "absl/types/variant.h"
31 
32 #include <grpc/event_engine/event_engine.h>
33 #include <grpc/grpc.h>
34 #include <grpc/slice.h>
35 #include <grpc/support/time.h>
36 
37 #include "src/core/lib/gprpp/debug_location.h"
38 #include "src/core/lib/gprpp/time.h"
39 
40 namespace grpc_core {
41 
42 // A CqVerifier can verify that expected events arrive in a timely fashion
43 // on a single completion queue
44 class CqVerifier {
45  public:
46   // ExpectedResult - if the tag is received, set *seen to true (if seen is
47   // non-null).
48   struct Maybe {
49     bool* seen = nullptr;
50   };
51   // ExpectedResult - expect the tag, but its result may be true or false.
52   // Store the result in result (if result is non-null).
53   struct AnyStatus {
54     bool* result = nullptr;
55   };
56   // PerformAction - expect the tag, and run a function based on the result
57   struct PerformAction {
58     std::function<void(bool success)> action;
59   };
60   // MaybePerformAction - run a function if a tag is seen
61   struct MaybePerformAction {
62     std::function<void(bool success)> action;
63   };
64 
65   using ExpectedResult =
66       absl::variant<bool, Maybe, AnyStatus, PerformAction, MaybePerformAction>;
67 
68   // Captures information about one failure
69   struct Failure {
70     SourceLocation location;
71     std::string message;
72     std::vector<std::string> expected;
73     std::vector<std::string> message_details;
74   };
75 
76   // Produces a string upon the successful (but unexpected) completion of an
77   // expectation.
78   class SuccessfulStateString {
79    public:
80     virtual std::string GetSuccessfulStateString() = 0;
81 
82    protected:
83     ~SuccessfulStateString() = default;
84   };
85 
86   static void FailUsingGprCrash(const Failure& failure);
87   static void FailUsingGprCrashWithStdio(const Failure& failure);
88   static void FailUsingGtestFail(const Failure& failure);
89 
90   // Allow customizing the failure handler
91   // For legacy tests we should use FailUsingGprCrash (the default)
92   // For gtest based tests we should start migrating to FailUsingGtestFail which
93   // will produce nicer failure messages.
94   explicit CqVerifier(
95       grpc_completion_queue* cq,
96       absl::AnyInvocable<void(Failure) const> fail = FailUsingGprCrash,
97       absl::AnyInvocable<
98           void(grpc_event_engine::experimental::EventEngine::Duration) const>
99           step_fn = nullptr);
100   ~CqVerifier();
101 
102   CqVerifier(const CqVerifier&) = delete;
103   CqVerifier& operator=(const CqVerifier&) = delete;
104 
105   // Ensure all expected events (and only those events) are present on the
106   // bound completion queue within \a timeout.
107   void Verify(Duration timeout = Duration::Seconds(10),
108               SourceLocation location = SourceLocation());
109 
110   // Ensure that the completion queue is empty, waiting up to \a timeout.
111   void VerifyEmpty(Duration timeout = Duration::Seconds(1),
112                    SourceLocation location = SourceLocation());
113 
114   void ClearSuccessfulStateStrings(void* tag);
115   void AddSuccessfulStateString(void* tag,
116                                 SuccessfulStateString* successful_state_string);
117 
118   // Match an expectation about a status.
119   // location must be DEBUG_LOCATION.
120   // result can be any of the types in ExpectedResult - a plain bool means
121   // 'expect success to be true/false'.
122   void Expect(void* tag, ExpectedResult result,
123               SourceLocation location = SourceLocation());
124 
125   std::string ToString() const;
126   std::vector<std::string> ToStrings() const;
127   std::string ToShortString() const;
128   std::vector<std::string> ToShortStrings() const;
129 
130   // Logging verifications helps debug CI problems a lot.
131   // Only disable if the logging prevents a stress test like scenario from
132   // passing.
SetLogVerifications(bool log_verifications)133   void SetLogVerifications(bool log_verifications) {
134     log_verifications_ = log_verifications;
135   }
136 
tag(intptr_t t)137   static void* tag(intptr_t t) { return reinterpret_cast<void*>(t); }
138 
139  private:
140   struct Expectation {
141     SourceLocation location;
142     void* tag;
143     ExpectedResult result;
144 
145     std::string ToString() const;
146     std::string ToShortString() const;
147   };
148 
149   void FailNoEventReceived(const SourceLocation& location) const;
150   void FailUnexpectedEvent(grpc_event* ev,
151                            const SourceLocation& location) const;
152   bool AllMaybes() const;
153   grpc_event Step(gpr_timespec deadline);
154 
155   grpc_completion_queue* const cq_;
156   std::vector<Expectation> expectations_;
157   absl::AnyInvocable<void(Failure) const> fail_;
158   absl::AnyInvocable<void(
159       grpc_event_engine::experimental::EventEngine::Duration) const>
160       step_fn_;
161   absl::flat_hash_map<void*, std::vector<SuccessfulStateString*>>
162       successful_state_strings_;
163   bool log_verifications_ = true;
164   bool added_expectations_ = false;
165 };
166 
167 }  // namespace grpc_core
168 
169 int byte_buffer_eq_slice(grpc_byte_buffer* bb, grpc_slice b);
170 int byte_buffer_eq_string(grpc_byte_buffer* bb, const char* str);
171 int contains_metadata(grpc_metadata_array* array, const char* key,
172                       const char* value);
173 int contains_metadata_slices(grpc_metadata_array* array, grpc_slice key,
174                              grpc_slice value);
175 
176 #endif  // GRPC_TEST_CORE_END2END_CQ_VERIFIER_H
177