xref: /aosp_15_r20/external/grpc-grpc/test/core/end2end/fuzzers/fuzzing_common.h (revision cc02d7e222339f7a4f6ba5f422e6413f4bd931f2)
1 //
2 //
3 // Copyright 2023 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_FUZZERS_FUZZING_COMMON_H
20 #define GRPC_TEST_CORE_END2END_FUZZERS_FUZZING_COMMON_H
21 
22 #include <stddef.h>
23 #include <stdint.h>
24 
25 #include <algorithm>
26 #include <functional>
27 #include <memory>
28 #include <utility>
29 #include <vector>
30 
31 #include "absl/types/span.h"
32 
33 #include <grpc/grpc.h>
34 #include <grpc/support/log.h>
35 
36 #include "src/core/lib/gprpp/ref_counted_ptr.h"
37 #include "src/core/lib/gprpp/time.h"
38 #include "src/core/lib/resource_quota/resource_quota.h"
39 #include "test/core/end2end/fuzzers/api_fuzzer.pb.h"
40 #include "test/core/event_engine/fuzzing_event_engine/fuzzing_event_engine.h"
41 #include "test/core/event_engine/fuzzing_event_engine/fuzzing_event_engine.pb.h"
42 
43 namespace grpc_core {
44 namespace testing {
45 
46 class Validator {
47  public:
Validator(std::function<void (bool)> impl)48   explicit Validator(std::function<void(bool)> impl) : impl_(std::move(impl)) {}
49 
~Validator()50   virtual ~Validator() {}
Run(bool success)51   void Run(bool success) {
52     impl_(success);
53     delete this;
54   }
55 
56  private:
57   std::function<void(bool)> impl_;
58 };
59 
MakeValidator(std::function<void (bool)> impl)60 inline Validator* MakeValidator(std::function<void(bool)> impl) {
61   return new Validator(std::move(impl));
62 }
63 
AssertSuccessAndDecrement(int * counter)64 inline Validator* AssertSuccessAndDecrement(int* counter) {
65   return MakeValidator([counter](bool success) {
66     GPR_ASSERT(success);
67     --*counter;
68   });
69 }
70 
Decrement(int * counter)71 inline Validator* Decrement(int* counter) {
72   return MakeValidator([counter](bool) { --*counter; });
73 }
74 
75 class Call;
76 
77 class BasicFuzzer {
78  public:
79   explicit BasicFuzzer(const fuzzing_event_engine::Actions& actions);
80 
81   enum Result { kPending = 0, kComplete = 1, kFailed = 2, kNotSupported = 3 };
82   virtual Result ExecuteAction(const api_fuzzer::Action& action);
83   Call* ActiveCall();
84 
85   bool Continue();
86   virtual void Tick();
87 
88   void Run(absl::Span<const api_fuzzer::Action* const> actions);
89 
90  protected:
91   ~BasicFuzzer();
92 
server_finished_shutting_down()93   bool server_finished_shutting_down() {
94     return server() != nullptr && server_shutdown_ &&
95            pending_server_shutdowns_ == 0;
96   }
server_shutdown_called()97   bool server_shutdown_called() { return server_shutdown_; }
98 
99   void ShutdownCalls();
ResetServerState()100   void ResetServerState() {
101     server_shutdown_ = false;
102     GPR_ASSERT(pending_server_shutdowns_ == 0);
103   }
104 
105   // Poll any created completion queue to drive the RPC forward.
106   Result PollCq();
107 
108   // Shutdown the active server.
109   Result ShutdownServer();
110 
resource_quota()111   RefCountedPtr<ResourceQuota> resource_quota() { return resource_quota_; }
112 
engine()113   grpc_event_engine::experimental::FuzzingEventEngine* engine() {
114     return engine_.get();
115   }
116 
cq()117   grpc_completion_queue* cq() { return cq_; }
118 
UpdateMinimumRunTime(Duration minimum_run_time)119   void UpdateMinimumRunTime(Duration minimum_run_time) {
120     minimum_run_time_ = std::max(minimum_run_time, minimum_run_time_);
121   }
122 
123  private:
124   // Channel specific actions.
125   // Create an active channel with the specified parameters.
126   virtual Result CreateChannel(
127       const api_fuzzer::CreateChannel& create_channel) = 0;
128 
129   // Close the active channel.
130   Result CloseChannel();
131   // Check whether the channel is connected and optionally try to connect if it
132   // is not connected.
133   Result CheckConnectivity(bool try_to_connect);
134   // Watch whether the channel connects within the specified duration.
135   Result WatchConnectivity(uint32_t duration_us);
136   // Verify that the channel target can be reliably queried.
137   Result ValidateChannelTarget();
138 
139   // Server specific actions
140   // Create an active server.
141   virtual Result CreateServer(
142       const api_fuzzer::CreateServer& create_server) = 0;
143   // Destroy the active server.
144   Result DestroyServerIfReady();
145 
146   // Request to be notified of a new RPC on the active server.
147   Result ServerRequestCall();
148   // Cancel all server calls.
149   Result CancelAllCallsIfShutdown();
150 
151   // Call specific actions.
152   // Create a call on the active channel with the specified parameters. Also add
153   // it the list of managed calls.
154   Result CreateCall(const api_fuzzer::CreateCall& create_call);
155   // Choose a different active call from the list of managed calls.
156   Result ChangeActiveCall();
157   // Queue a batch of operations to be executed on the active call.
158   Result QueueBatchForActiveCall(const api_fuzzer::Batch& queue_batch);
159   // Cancel the active call.
160   Result CancelActiveCall();
161   // Validate that the peer can be reliably queried for the active call.
162   Result ValidatePeerForActiveCall();
163   // Cancel and destroy the active call.
164   Result DestroyActiveCall();
165   // Pause the run loop for some time
166   Result Pause(Duration duration);
167 
168   // Other actions.
169   // Change the resource quota limits.
170   Result ResizeResourceQuota(uint32_t resize_resource_quota);
171 
172   void TryShutdown();
173 
174   virtual grpc_server* server() = 0;
175   virtual grpc_channel* channel() = 0;
176   virtual void DestroyServer() = 0;
177   virtual void DestroyChannel() = 0;
178 
179   std::shared_ptr<grpc_event_engine::experimental::FuzzingEventEngine> engine_;
180   grpc_completion_queue* cq_;
181   bool server_shutdown_ = false;
182   int pending_server_shutdowns_ = 0;
183   int pending_channel_watches_ = 0;
184   int paused_ = 0;
185   std::vector<std::shared_ptr<Call>> calls_;
186   RefCountedPtr<ResourceQuota> resource_quota_;
187   size_t active_call_ = 0;
188   Duration minimum_run_time_ = Duration::Zero();
189 };
190 
191 }  // namespace testing
192 }  // namespace grpc_core
193 
194 #endif  // GRPC_TEST_CORE_END2END_FUZZERS_FUZZING_COMMON_H
195