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