xref: /aosp_15_r20/external/cronet/net/base/test_completion_callback.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright 2012 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef NET_BASE_TEST_COMPLETION_CALLBACK_H_
6 #define NET_BASE_TEST_COMPLETION_CALLBACK_H_
7 
8 #include <stdint.h>
9 
10 #include <memory>
11 #include <optional>
12 #include <utility>
13 
14 #include "base/compiler_specific.h"
15 #include "base/functional/callback.h"
16 #include "base/memory/raw_ptr.h"
17 #include "net/base/completion_once_callback.h"
18 #include "net/base/net_errors.h"
19 
20 //-----------------------------------------------------------------------------
21 // completion callback helper
22 
23 // A helper class for completion callbacks, designed to make it easy to run
24 // tests involving asynchronous operations.  Just call WaitForResult to wait
25 // for the asynchronous operation to complete.  Uses a RunLoop to spin the
26 // current MessageLoop while waiting.  The callback must be invoked on the same
27 // thread WaitForResult is called on.
28 //
29 // NOTE: Since this runs a message loop to wait for the completion callback,
30 // there could be other side-effects resulting from WaitForResult.  For this
31 // reason, this class is probably not ideal for a general application.
32 //
33 namespace base {
34 class RunLoop;
35 }
36 
37 namespace net {
38 
39 class IOBuffer;
40 
41 namespace internal {
42 
43 class TestCompletionCallbackBaseInternal {
44  public:
45   TestCompletionCallbackBaseInternal(
46       const TestCompletionCallbackBaseInternal&) = delete;
47   TestCompletionCallbackBaseInternal& operator=(
48       const TestCompletionCallbackBaseInternal&) = delete;
have_result()49   bool have_result() const { return have_result_; }
50 
51  protected:
52   TestCompletionCallbackBaseInternal();
53   virtual ~TestCompletionCallbackBaseInternal();
54 
55   void DidSetResult();
56   void WaitForResult();
57 
58  private:
59   // RunLoop.  Only non-NULL during the call to WaitForResult, so the class is
60   // reusable.
61   std::unique_ptr<base::RunLoop> run_loop_;
62   bool have_result_ = false;
63 };
64 
65 template <typename R>
66 struct NetErrorIsPendingHelper {
operatorNetErrorIsPendingHelper67   bool operator()(R status) const { return status == ERR_IO_PENDING; }
68 };
69 
70 template <typename R, typename IsPendingHelper = NetErrorIsPendingHelper<R>>
71 class TestCompletionCallbackTemplate
72     : public TestCompletionCallbackBaseInternal {
73  public:
74   TestCompletionCallbackTemplate(const TestCompletionCallbackTemplate&) =
75       delete;
76   TestCompletionCallbackTemplate& operator=(
77       const TestCompletionCallbackTemplate&) = delete;
78   ~TestCompletionCallbackTemplate() override = default;
79 
WaitForResult()80   R WaitForResult() {
81     TestCompletionCallbackBaseInternal::WaitForResult();
82     return std::move(result_);
83   }
84 
GetResult(R result)85   R GetResult(R result) {
86     IsPendingHelper check_pending;
87     if (!check_pending(result))
88       return std::move(result);
89     return WaitForResult();
90   }
91 
92  protected:
TestCompletionCallbackTemplate()93   TestCompletionCallbackTemplate() : result_(R()) {}
94 
95   // Override this method to gain control as the callback is running.
SetResult(R result)96   virtual void SetResult(R result) {
97     result_ = std::move(result);
98     DidSetResult();
99   }
100 
101  private:
102   R result_;
103 };
104 
105 }  // namespace internal
106 
107 class TestClosure : public internal::TestCompletionCallbackBaseInternal {
108  public:
109   using internal::TestCompletionCallbackBaseInternal::WaitForResult;
110 
111   TestClosure() = default;
112   TestClosure(const TestClosure&) = delete;
113   TestClosure& operator=(const TestClosure&) = delete;
114   ~TestClosure() override;
115 
closure()116   base::OnceClosure closure() {
117     return base::BindOnce(&TestClosure::DidSetResult, base::Unretained(this));
118   }
119 };
120 
121 // Base class overridden by custom implementations of TestCompletionCallback.
122 typedef internal::TestCompletionCallbackTemplate<int>
123     TestCompletionCallbackBase;
124 
125 typedef internal::TestCompletionCallbackTemplate<int64_t>
126     TestInt64CompletionCallbackBase;
127 
128 class TestCompletionCallback : public TestCompletionCallbackBase {
129  public:
130   TestCompletionCallback() = default;
131   TestCompletionCallback(const TestCompletionCallback&) = delete;
132   TestCompletionCallback& operator=(const TestCompletionCallback&) = delete;
133   ~TestCompletionCallback() override;
134 
callback()135   CompletionOnceCallback callback() {
136     return base::BindOnce(&TestCompletionCallback::SetResult,
137                           base::Unretained(this));
138   }
139 };
140 
141 class TestInt64CompletionCallback : public TestInt64CompletionCallbackBase {
142  public:
143   TestInt64CompletionCallback() = default;
144   TestInt64CompletionCallback(const TestInt64CompletionCallback&) = delete;
145   TestInt64CompletionCallback& operator=(const TestInt64CompletionCallback&) =
146       delete;
147   ~TestInt64CompletionCallback() override;
148 
callback()149   Int64CompletionOnceCallback callback() {
150     return base::BindOnce(&TestInt64CompletionCallback::SetResult,
151                           base::Unretained(this));
152   }
153 };
154 
155 // Makes sure that the buffer is not referenced when the callback runs.
156 class ReleaseBufferCompletionCallback: public TestCompletionCallback {
157  public:
158   explicit ReleaseBufferCompletionCallback(IOBuffer* buffer);
159   ReleaseBufferCompletionCallback(const ReleaseBufferCompletionCallback&) =
160       delete;
161   ReleaseBufferCompletionCallback& operator=(
162       const ReleaseBufferCompletionCallback&) = delete;
163   ~ReleaseBufferCompletionCallback() override;
164 
165  private:
166   void SetResult(int result) override;
167 
168   raw_ptr<IOBuffer> buffer_;
169 };
170 
171 }  // namespace net
172 
173 #endif  // NET_BASE_TEST_COMPLETION_CALLBACK_H_
174