xref: /aosp_15_r20/external/cronet/base/test/test_future.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1*6777b538SAndroid Build Coastguard Worker // Copyright 2021 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker 
5*6777b538SAndroid Build Coastguard Worker #ifndef BASE_TEST_TEST_FUTURE_H_
6*6777b538SAndroid Build Coastguard Worker #define BASE_TEST_TEST_FUTURE_H_
7*6777b538SAndroid Build Coastguard Worker 
8*6777b538SAndroid Build Coastguard Worker #include <memory>
9*6777b538SAndroid Build Coastguard Worker #include <optional>
10*6777b538SAndroid Build Coastguard Worker #include <tuple>
11*6777b538SAndroid Build Coastguard Worker 
12*6777b538SAndroid Build Coastguard Worker #include "base/auto_reset.h"
13*6777b538SAndroid Build Coastguard Worker #include "base/check.h"
14*6777b538SAndroid Build Coastguard Worker #include "base/functional/bind.h"
15*6777b538SAndroid Build Coastguard Worker #include "base/functional/callback_forward.h"
16*6777b538SAndroid Build Coastguard Worker #include "base/functional/callback_helpers.h"
17*6777b538SAndroid Build Coastguard Worker #include "base/memory/weak_ptr.h"
18*6777b538SAndroid Build Coastguard Worker #include "base/run_loop.h"
19*6777b538SAndroid Build Coastguard Worker #include "base/sequence_checker.h"
20*6777b538SAndroid Build Coastguard Worker #include "base/strings/to_string.h"
21*6777b538SAndroid Build Coastguard Worker #include "base/task/bind_post_task.h"
22*6777b538SAndroid Build Coastguard Worker #include "base/task/sequenced_task_runner.h"
23*6777b538SAndroid Build Coastguard Worker #include "base/test/test_future_internal.h"
24*6777b538SAndroid Build Coastguard Worker #include "base/thread_annotations.h"
25*6777b538SAndroid Build Coastguard Worker #include "testing/gtest/include/gtest/gtest.h"
26*6777b538SAndroid Build Coastguard Worker 
27*6777b538SAndroid Build Coastguard Worker namespace base::test {
28*6777b538SAndroid Build Coastguard Worker 
29*6777b538SAndroid Build Coastguard Worker // Helper class to test code that returns its result(s) asynchronously through a
30*6777b538SAndroid Build Coastguard Worker // callback:
31*6777b538SAndroid Build Coastguard Worker //
32*6777b538SAndroid Build Coastguard Worker //    - Pass the callback provided by `GetCallback()` to the code under test.
33*6777b538SAndroid Build Coastguard Worker //    - Wait for the callback to be invoked by calling `Wait(),` or `Get()` to
34*6777b538SAndroid Build Coastguard Worker //      access the value(s) passed to the callback.
35*6777b538SAndroid Build Coastguard Worker //
36*6777b538SAndroid Build Coastguard Worker //   Example usage:
37*6777b538SAndroid Build Coastguard Worker //
38*6777b538SAndroid Build Coastguard Worker //     TEST_F(MyTestFixture, MyTest) {
39*6777b538SAndroid Build Coastguard Worker //       TestFuture<ResultType> future;
40*6777b538SAndroid Build Coastguard Worker //
41*6777b538SAndroid Build Coastguard Worker //       object_under_test.DoSomethingAsync(future.GetCallback());
42*6777b538SAndroid Build Coastguard Worker //
43*6777b538SAndroid Build Coastguard Worker //       const ResultType& actual_result = future.Get();
44*6777b538SAndroid Build Coastguard Worker //
45*6777b538SAndroid Build Coastguard Worker //       // When you come here, DoSomethingAsync has finished and
46*6777b538SAndroid Build Coastguard Worker //       // `actual_result` contains the result passed to the callback.
47*6777b538SAndroid Build Coastguard Worker //     }
48*6777b538SAndroid Build Coastguard Worker //
49*6777b538SAndroid Build Coastguard Worker //   Example using `Wait()`:
50*6777b538SAndroid Build Coastguard Worker //
51*6777b538SAndroid Build Coastguard Worker //     TEST_F(MyTestFixture, MyWaitTest) {
52*6777b538SAndroid Build Coastguard Worker //       TestFuture<ResultType> future;
53*6777b538SAndroid Build Coastguard Worker //
54*6777b538SAndroid Build Coastguard Worker //       object_under_test.DoSomethingAsync(future.GetCallback());
55*6777b538SAndroid Build Coastguard Worker //
56*6777b538SAndroid Build Coastguard Worker //       // Optional. The Get() call below will also wait until the value
57*6777b538SAndroid Build Coastguard Worker //       // arrives, but this explicit call to Wait() can be useful if you want
58*6777b538SAndroid Build Coastguard Worker //       // to add extra information.
59*6777b538SAndroid Build Coastguard Worker //       ASSERT_TRUE(future.Wait()) << "Detailed error message";
60*6777b538SAndroid Build Coastguard Worker //
61*6777b538SAndroid Build Coastguard Worker //       const ResultType& actual_result = future.Get();
62*6777b538SAndroid Build Coastguard Worker //     }
63*6777b538SAndroid Build Coastguard Worker //
64*6777b538SAndroid Build Coastguard Worker // `TestFuture` supports both single- and multiple-argument callbacks.
65*6777b538SAndroid Build Coastguard Worker // `TestFuture` provides both index and type based accessors for multi-argument
66*6777b538SAndroid Build Coastguard Worker // callbacks. `Get()` and `Take()` return tuples for multi-argument callbacks.
67*6777b538SAndroid Build Coastguard Worker //
68*6777b538SAndroid Build Coastguard Worker //   TestFuture<int, std::string> future;
69*6777b538SAndroid Build Coastguard Worker //   future.Get<0>();   // Reads the first argument
70*6777b538SAndroid Build Coastguard Worker //   future.Get<int>(); // Also reads the first argument
71*6777b538SAndroid Build Coastguard Worker //   future.Get();      // Returns a `const std::tuple<int, std::string>&`
72*6777b538SAndroid Build Coastguard Worker //
73*6777b538SAndroid Build Coastguard Worker //   Example for a multi-argument callback:
74*6777b538SAndroid Build Coastguard Worker //
75*6777b538SAndroid Build Coastguard Worker //     TEST_F(MyTestFixture, MyTest) {
76*6777b538SAndroid Build Coastguard Worker //       TestFuture<int, std::string> future;
77*6777b538SAndroid Build Coastguard Worker //
78*6777b538SAndroid Build Coastguard Worker //       object_under_test.DoSomethingAsync(future.GetCallback());
79*6777b538SAndroid Build Coastguard Worker //
80*6777b538SAndroid Build Coastguard Worker //       // You can use type based accessors:
81*6777b538SAndroid Build Coastguard Worker //       int first_argument = future.Get<int>();
82*6777b538SAndroid Build Coastguard Worker //       const std::string& second_argument = future.Get<std::string>();
83*6777b538SAndroid Build Coastguard Worker //
84*6777b538SAndroid Build Coastguard Worker //       // or index based accessors:
85*6777b538SAndroid Build Coastguard Worker //       int first_argument = future.Get<0>();
86*6777b538SAndroid Build Coastguard Worker //       const std::string& second_argument = future.Get<1>();
87*6777b538SAndroid Build Coastguard Worker //     }
88*6777b538SAndroid Build Coastguard Worker //
89*6777b538SAndroid Build Coastguard Worker // You can also satisfy a `TestFuture` by calling `SetValue()` from the sequence
90*6777b538SAndroid Build Coastguard Worker // on which the `TestFuture` was created. This is mostly useful when
91*6777b538SAndroid Build Coastguard Worker // implementing an observer:
92*6777b538SAndroid Build Coastguard Worker //
93*6777b538SAndroid Build Coastguard Worker //     class MyTestObserver: public MyObserver {
94*6777b538SAndroid Build Coastguard Worker //       public:
95*6777b538SAndroid Build Coastguard Worker //         // `MyObserver` implementation:
96*6777b538SAndroid Build Coastguard Worker //         void ObserveAnInt(int value) override {
97*6777b538SAndroid Build Coastguard Worker //           future_.SetValue(value);
98*6777b538SAndroid Build Coastguard Worker //         }
99*6777b538SAndroid Build Coastguard Worker //
100*6777b538SAndroid Build Coastguard Worker //         int Wait() { return future_.Take(); }
101*6777b538SAndroid Build Coastguard Worker //
102*6777b538SAndroid Build Coastguard Worker //      private:
103*6777b538SAndroid Build Coastguard Worker //        TestFuture<int> future_;
104*6777b538SAndroid Build Coastguard Worker //     };
105*6777b538SAndroid Build Coastguard Worker //
106*6777b538SAndroid Build Coastguard Worker //     TEST_F(MyTestFixture, MyTest) {
107*6777b538SAndroid Build Coastguard Worker //       MyTestObserver observer;
108*6777b538SAndroid Build Coastguard Worker //
109*6777b538SAndroid Build Coastguard Worker //       object_under_test.DoSomethingAsync(observer);
110*6777b538SAndroid Build Coastguard Worker //
111*6777b538SAndroid Build Coastguard Worker //       int value_passed_to_observer = observer.Wait();
112*6777b538SAndroid Build Coastguard Worker //     };
113*6777b538SAndroid Build Coastguard Worker //
114*6777b538SAndroid Build Coastguard Worker // `GetRepeatingCallback()` allows you to use a single `TestFuture` in code
115*6777b538SAndroid Build Coastguard Worker // that invokes the callback multiple times.
116*6777b538SAndroid Build Coastguard Worker // Your test must take care to consume each value before the next value
117*6777b538SAndroid Build Coastguard Worker // arrives. You can consume the value by calling either `Take()` or `Clear()`.
118*6777b538SAndroid Build Coastguard Worker //
119*6777b538SAndroid Build Coastguard Worker //   Example for reusing a `TestFuture`:
120*6777b538SAndroid Build Coastguard Worker //
121*6777b538SAndroid Build Coastguard Worker //     TEST_F(MyTestFixture, MyReuseTest) {
122*6777b538SAndroid Build Coastguard Worker //       TestFuture<std::string> future;
123*6777b538SAndroid Build Coastguard Worker //
124*6777b538SAndroid Build Coastguard Worker //       object_under_test.InstallCallback(future.GetRepeatingCallback());
125*6777b538SAndroid Build Coastguard Worker //
126*6777b538SAndroid Build Coastguard Worker //       object_under_test.DoSomething();
127*6777b538SAndroid Build Coastguard Worker //       EXPECT_EQ(future.Take(), "expected-first-value");
128*6777b538SAndroid Build Coastguard Worker //       // Because we used `Take()` the test future is ready for reuse.
129*6777b538SAndroid Build Coastguard Worker //
130*6777b538SAndroid Build Coastguard Worker //       object_under_test.DoSomethingElse();
131*6777b538SAndroid Build Coastguard Worker //       EXPECT_EQ(future.Take(), "expected-second-value");
132*6777b538SAndroid Build Coastguard Worker //     }
133*6777b538SAndroid Build Coastguard Worker //
134*6777b538SAndroid Build Coastguard Worker //   Example for reusing  a `TestFuture` using `Get()` + `Clear()`:
135*6777b538SAndroid Build Coastguard Worker //
136*6777b538SAndroid Build Coastguard Worker //     TEST_F(MyTestFixture, MyReuseTest) {
137*6777b538SAndroid Build Coastguard Worker //       TestFuture<std::string, int> future;
138*6777b538SAndroid Build Coastguard Worker //
139*6777b538SAndroid Build Coastguard Worker //       object_under_test.InstallCallback(future.GetRepeatingCallback());
140*6777b538SAndroid Build Coastguard Worker //
141*6777b538SAndroid Build Coastguard Worker //       object_under_test.DoSomething();
142*6777b538SAndroid Build Coastguard Worker //
143*6777b538SAndroid Build Coastguard Worker //       EXPECT_EQ(future.Get<std::string>(), "expected-first-value");
144*6777b538SAndroid Build Coastguard Worker //       EXPECT_EQ(future.Get<int>(), 5);
145*6777b538SAndroid Build Coastguard Worker //       // Because we used `Get()`, the test future is not ready for reuse,
146*6777b538SAndroid Build Coastguard Worker //       //so we need an explicit `Clear()` call.
147*6777b538SAndroid Build Coastguard Worker //       future.Clear();
148*6777b538SAndroid Build Coastguard Worker //
149*6777b538SAndroid Build Coastguard Worker //       object_under_test.DoSomethingElse();
150*6777b538SAndroid Build Coastguard Worker //       EXPECT_EQ(future.Get<std::string>(), "expected-second-value");
151*6777b538SAndroid Build Coastguard Worker //       EXPECT_EQ(future.Get<int>(), 2);
152*6777b538SAndroid Build Coastguard Worker //     }
153*6777b538SAndroid Build Coastguard Worker //
154*6777b538SAndroid Build Coastguard Worker // Finally, `TestFuture` also supports no-args callbacks:
155*6777b538SAndroid Build Coastguard Worker //
156*6777b538SAndroid Build Coastguard Worker //   Example for no-args callbacks:
157*6777b538SAndroid Build Coastguard Worker //
158*6777b538SAndroid Build Coastguard Worker //     TEST_F(MyTestFixture, MyTest) {
159*6777b538SAndroid Build Coastguard Worker //       TestFuture<void> signal;
160*6777b538SAndroid Build Coastguard Worker //
161*6777b538SAndroid Build Coastguard Worker //       object_under_test.DoSomethingAsync(signal.GetCallback());
162*6777b538SAndroid Build Coastguard Worker //
163*6777b538SAndroid Build Coastguard Worker //       EXPECT_TRUE(signal.Wait());
164*6777b538SAndroid Build Coastguard Worker //       // When you come here you know the callback was invoked and the async
165*6777b538SAndroid Build Coastguard Worker //       // code is ready.
166*6777b538SAndroid Build Coastguard Worker //     }
167*6777b538SAndroid Build Coastguard Worker //
168*6777b538SAndroid Build Coastguard Worker // All access to this class and its callbacks must be made from the sequence on
169*6777b538SAndroid Build Coastguard Worker // which the `TestFuture` was constructed.
170*6777b538SAndroid Build Coastguard Worker //
171*6777b538SAndroid Build Coastguard Worker template <typename... Types>
172*6777b538SAndroid Build Coastguard Worker class TestFuture {
173*6777b538SAndroid Build Coastguard Worker  public:
174*6777b538SAndroid Build Coastguard Worker   using TupleType = std::tuple<std::decay_t<Types>...>;
175*6777b538SAndroid Build Coastguard Worker 
176*6777b538SAndroid Build Coastguard Worker   static_assert(std::tuple_size_v<TupleType> > 0,
177*6777b538SAndroid Build Coastguard Worker                 "Don't use TestFuture<> but use TestFuture<void> instead");
178*6777b538SAndroid Build Coastguard Worker 
179*6777b538SAndroid Build Coastguard Worker   TestFuture() = default;
180*6777b538SAndroid Build Coastguard Worker   TestFuture(const TestFuture&) = delete;
181*6777b538SAndroid Build Coastguard Worker   TestFuture& operator=(const TestFuture&) = delete;
182*6777b538SAndroid Build Coastguard Worker   ~TestFuture() = default;
183*6777b538SAndroid Build Coastguard Worker 
184*6777b538SAndroid Build Coastguard Worker   // Waits for the value to arrive.
185*6777b538SAndroid Build Coastguard Worker   //
186*6777b538SAndroid Build Coastguard Worker   // Returns true if the value arrived, or false if a timeout happens.
187*6777b538SAndroid Build Coastguard Worker   //
188*6777b538SAndroid Build Coastguard Worker   // Directly calling Wait() is not required as Get()/Take() will also wait for
189*6777b538SAndroid Build Coastguard Worker   // the value to arrive, however you can use a direct call to Wait() to
190*6777b538SAndroid Build Coastguard Worker   // improve the error reported:
191*6777b538SAndroid Build Coastguard Worker   //
192*6777b538SAndroid Build Coastguard Worker   //   ASSERT_TRUE(queue.Wait()) << "Detailed error message";
193*6777b538SAndroid Build Coastguard Worker   //
Wait()194*6777b538SAndroid Build Coastguard Worker   [[nodiscard]] bool Wait() {
195*6777b538SAndroid Build Coastguard Worker     DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
196*6777b538SAndroid Build Coastguard Worker 
197*6777b538SAndroid Build Coastguard Worker     if (values_) {
198*6777b538SAndroid Build Coastguard Worker       return true;
199*6777b538SAndroid Build Coastguard Worker     }
200*6777b538SAndroid Build Coastguard Worker 
201*6777b538SAndroid Build Coastguard Worker     // Wait for the value to arrive.
202*6777b538SAndroid Build Coastguard Worker     RunLoop loop;
203*6777b538SAndroid Build Coastguard Worker     AutoReset<RepeatingClosure> quit_loop(&ready_signal_, loop.QuitClosure());
204*6777b538SAndroid Build Coastguard Worker     loop.Run();
205*6777b538SAndroid Build Coastguard Worker 
206*6777b538SAndroid Build Coastguard Worker     return IsReady();
207*6777b538SAndroid Build Coastguard Worker   }
208*6777b538SAndroid Build Coastguard Worker 
209*6777b538SAndroid Build Coastguard Worker   // Returns true if the value has arrived.
IsReady()210*6777b538SAndroid Build Coastguard Worker   bool IsReady() const {
211*6777b538SAndroid Build Coastguard Worker     DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
212*6777b538SAndroid Build Coastguard Worker     return values_.has_value();
213*6777b538SAndroid Build Coastguard Worker   }
214*6777b538SAndroid Build Coastguard Worker 
215*6777b538SAndroid Build Coastguard Worker   // Waits for the value to arrive, and returns the I-th value.
216*6777b538SAndroid Build Coastguard Worker   //
217*6777b538SAndroid Build Coastguard Worker   // Will CHECK if a timeout happens.
218*6777b538SAndroid Build Coastguard Worker   //
219*6777b538SAndroid Build Coastguard Worker   // Example usage:
220*6777b538SAndroid Build Coastguard Worker   //
221*6777b538SAndroid Build Coastguard Worker   //   TestFuture<int, std::string> future;
222*6777b538SAndroid Build Coastguard Worker   //   int first = future.Get<0>();
223*6777b538SAndroid Build Coastguard Worker   //   std::string second = future.Get<1>();
224*6777b538SAndroid Build Coastguard Worker   //
225*6777b538SAndroid Build Coastguard Worker   template <std::size_t I,
226*6777b538SAndroid Build Coastguard Worker             typename T = TupleType,
227*6777b538SAndroid Build Coastguard Worker             internal::EnableIfOneOrMoreValues<T> = true>
Get()228*6777b538SAndroid Build Coastguard Worker   const auto& Get() {
229*6777b538SAndroid Build Coastguard Worker     return std::get<I>(GetTuple());
230*6777b538SAndroid Build Coastguard Worker   }
231*6777b538SAndroid Build Coastguard Worker 
232*6777b538SAndroid Build Coastguard Worker   // Waits for the value to arrive, and returns the value with the given type.
233*6777b538SAndroid Build Coastguard Worker   //
234*6777b538SAndroid Build Coastguard Worker   // Will CHECK if a timeout happens.
235*6777b538SAndroid Build Coastguard Worker   //
236*6777b538SAndroid Build Coastguard Worker   // Example usage:
237*6777b538SAndroid Build Coastguard Worker   //
238*6777b538SAndroid Build Coastguard Worker   //   TestFuture<int, std::string> future;
239*6777b538SAndroid Build Coastguard Worker   //   int first = future.Get<int>();
240*6777b538SAndroid Build Coastguard Worker   //   std::string second = future.Get<std::string>();
241*6777b538SAndroid Build Coastguard Worker   //
242*6777b538SAndroid Build Coastguard Worker   template <typename Type>
Get()243*6777b538SAndroid Build Coastguard Worker   const auto& Get() {
244*6777b538SAndroid Build Coastguard Worker     return std::get<Type>(GetTuple());
245*6777b538SAndroid Build Coastguard Worker   }
246*6777b538SAndroid Build Coastguard Worker 
247*6777b538SAndroid Build Coastguard Worker   // Returns a callback that when invoked will store all the argument values,
248*6777b538SAndroid Build Coastguard Worker   // and unblock any waiters. The callback must be invoked on the sequence the
249*6777b538SAndroid Build Coastguard Worker   // TestFuture was created on.
250*6777b538SAndroid Build Coastguard Worker   //
251*6777b538SAndroid Build Coastguard Worker   // Templated so you can specify how you need the arguments to be passed -
252*6777b538SAndroid Build Coastguard Worker   // const, reference, .... Defaults to simply `Types...`.
253*6777b538SAndroid Build Coastguard Worker   //
254*6777b538SAndroid Build Coastguard Worker   // Example usage:
255*6777b538SAndroid Build Coastguard Worker   //
256*6777b538SAndroid Build Coastguard Worker   //   TestFuture<int, std::string> future;
257*6777b538SAndroid Build Coastguard Worker   //
258*6777b538SAndroid Build Coastguard Worker   //   // Without specifying the callback argument types, this returns
259*6777b538SAndroid Build Coastguard Worker   //   // base::OnceCallback<void(int, std::string)>.
260*6777b538SAndroid Build Coastguard Worker   //   future.GetCallback();
261*6777b538SAndroid Build Coastguard Worker   //
262*6777b538SAndroid Build Coastguard Worker   //   // By explicitly specifying the callback argument types, this returns
263*6777b538SAndroid Build Coastguard Worker   //   // base::OnceCallback<void(int, const std::string&)>.
264*6777b538SAndroid Build Coastguard Worker   //   future.GetCallback<int, const std::string&>();
265*6777b538SAndroid Build Coastguard Worker   //
266*6777b538SAndroid Build Coastguard Worker   template <typename... CallbackArgumentsTypes>
GetCallback()267*6777b538SAndroid Build Coastguard Worker   OnceCallback<void(CallbackArgumentsTypes...)> GetCallback() {
268*6777b538SAndroid Build Coastguard Worker     return GetRepeatingCallback<CallbackArgumentsTypes...>();
269*6777b538SAndroid Build Coastguard Worker   }
270*6777b538SAndroid Build Coastguard Worker 
GetCallback()271*6777b538SAndroid Build Coastguard Worker   OnceCallback<void(Types...)> GetCallback() { return GetCallback<Types...>(); }
272*6777b538SAndroid Build Coastguard Worker 
273*6777b538SAndroid Build Coastguard Worker   // Returns a repeating callback that when invoked will store all the argument
274*6777b538SAndroid Build Coastguard Worker   // values, and unblock any waiters. The callback must be invoked on the
275*6777b538SAndroid Build Coastguard Worker   // sequence the TestFuture was created on.
276*6777b538SAndroid Build Coastguard Worker   //
277*6777b538SAndroid Build Coastguard Worker   // You must take care that the stored value is consumed before the callback
278*6777b538SAndroid Build Coastguard Worker   // is invoked a second time. You can consume the value by calling either
279*6777b538SAndroid Build Coastguard Worker   // `Take()` or `Clear()`.
280*6777b538SAndroid Build Coastguard Worker   //
281*6777b538SAndroid Build Coastguard Worker   // Example usage:
282*6777b538SAndroid Build Coastguard Worker   //
283*6777b538SAndroid Build Coastguard Worker   //   TestFuture<std::string> future;
284*6777b538SAndroid Build Coastguard Worker   //
285*6777b538SAndroid Build Coastguard Worker   //   object_under_test.InstallCallback(future.GetRepeatingCallback());
286*6777b538SAndroid Build Coastguard Worker   //
287*6777b538SAndroid Build Coastguard Worker   //   object_under_test.DoSomething();
288*6777b538SAndroid Build Coastguard Worker   //   EXPECT_EQ(future.Take(), "expected-first-value");
289*6777b538SAndroid Build Coastguard Worker   //   // Because we used `Take()` the test future is ready for reuse.
290*6777b538SAndroid Build Coastguard Worker   //
291*6777b538SAndroid Build Coastguard Worker   //   object_under_test.DoSomethingElse();
292*6777b538SAndroid Build Coastguard Worker   //   // We can also use `Get()` + `Clear()` to reuse the callback.
293*6777b538SAndroid Build Coastguard Worker   //   EXPECT_EQ(future.Get(), "expected-second-value");
294*6777b538SAndroid Build Coastguard Worker   //   future.Clear();
295*6777b538SAndroid Build Coastguard Worker   //
296*6777b538SAndroid Build Coastguard Worker   //   object_under_test.DoSomethingElse();
297*6777b538SAndroid Build Coastguard Worker   //   EXPECT_EQ(future.Take(), "expected-third-value");
298*6777b538SAndroid Build Coastguard Worker   //
299*6777b538SAndroid Build Coastguard Worker   template <typename... CallbackArgumentsTypes>
GetRepeatingCallback()300*6777b538SAndroid Build Coastguard Worker   RepeatingCallback<void(CallbackArgumentsTypes...)> GetRepeatingCallback() {
301*6777b538SAndroid Build Coastguard Worker     DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
302*6777b538SAndroid Build Coastguard Worker     return BindRepeating(
303*6777b538SAndroid Build Coastguard Worker         [](WeakPtr<TestFuture<Types...>> future,
304*6777b538SAndroid Build Coastguard Worker            CallbackArgumentsTypes... values) {
305*6777b538SAndroid Build Coastguard Worker           if (future) {
306*6777b538SAndroid Build Coastguard Worker             future->SetValue(std::forward<CallbackArgumentsTypes>(values)...);
307*6777b538SAndroid Build Coastguard Worker           }
308*6777b538SAndroid Build Coastguard Worker         },
309*6777b538SAndroid Build Coastguard Worker         weak_ptr_factory_.GetWeakPtr());
310*6777b538SAndroid Build Coastguard Worker   }
311*6777b538SAndroid Build Coastguard Worker 
GetRepeatingCallback()312*6777b538SAndroid Build Coastguard Worker   RepeatingCallback<void(Types...)> GetRepeatingCallback() {
313*6777b538SAndroid Build Coastguard Worker     return GetRepeatingCallback<Types...>();
314*6777b538SAndroid Build Coastguard Worker   }
315*6777b538SAndroid Build Coastguard Worker 
316*6777b538SAndroid Build Coastguard Worker   // Returns a callback that can be invoked on any sequence. When invoked it
317*6777b538SAndroid Build Coastguard Worker   // will post a task to the sequence the TestFuture was created on, to store
318*6777b538SAndroid Build Coastguard Worker   // all the argument values, and unblock any waiters.
319*6777b538SAndroid Build Coastguard Worker   //
320*6777b538SAndroid Build Coastguard Worker   // Templated so you can specify how you need the arguments to be passed -
321*6777b538SAndroid Build Coastguard Worker   // const, reference, .... Defaults to simply `Types...`.
322*6777b538SAndroid Build Coastguard Worker   //
323*6777b538SAndroid Build Coastguard Worker   // Example usage:
324*6777b538SAndroid Build Coastguard Worker   //
325*6777b538SAndroid Build Coastguard Worker   //   TestFuture<int, std::string> future;
326*6777b538SAndroid Build Coastguard Worker   //
327*6777b538SAndroid Build Coastguard Worker   //   // Without specifying the callback argument types, this returns
328*6777b538SAndroid Build Coastguard Worker   //   // base::OnceCallback<void(int, std::string)>.
329*6777b538SAndroid Build Coastguard Worker   //   auto callback = future.GetSequenceBoundCallback();
330*6777b538SAndroid Build Coastguard Worker   //
331*6777b538SAndroid Build Coastguard Worker   //   // By explicitly specifying the callback argument types, this returns
332*6777b538SAndroid Build Coastguard Worker   //   // base::OnceCallback<void(int, const std::string&)>.
333*6777b538SAndroid Build Coastguard Worker   //   auto callback =
334*6777b538SAndroid Build Coastguard Worker   //       future.GetSequenceBoundCallback<int, const std::string&>();
335*6777b538SAndroid Build Coastguard Worker   //
336*6777b538SAndroid Build Coastguard Worker   //   // AsyncOperation invokes `callback` with a result.
337*6777b538SAndroid Build Coastguard Worker   //   other_task_runner->PostTask(FROM_HERE, base::BindOnce(&AsyncOperation,
338*6777b538SAndroid Build Coastguard Worker   //                                              std::move(callback));
339*6777b538SAndroid Build Coastguard Worker   //
340*6777b538SAndroid Build Coastguard Worker   //   future.Wait();
341*6777b538SAndroid Build Coastguard Worker   //
342*6777b538SAndroid Build Coastguard Worker   template <typename... CallbackArgumentsTypes>
GetSequenceBoundCallback()343*6777b538SAndroid Build Coastguard Worker   OnceCallback<void(CallbackArgumentsTypes...)> GetSequenceBoundCallback() {
344*6777b538SAndroid Build Coastguard Worker     return GetSequenceBoundRepeatingCallback<CallbackArgumentsTypes...>();
345*6777b538SAndroid Build Coastguard Worker   }
346*6777b538SAndroid Build Coastguard Worker 
GetSequenceBoundCallback()347*6777b538SAndroid Build Coastguard Worker   OnceCallback<void(Types...)> GetSequenceBoundCallback() {
348*6777b538SAndroid Build Coastguard Worker     return GetSequenceBoundCallback<Types...>();
349*6777b538SAndroid Build Coastguard Worker   }
350*6777b538SAndroid Build Coastguard Worker 
351*6777b538SAndroid Build Coastguard Worker   // Returns a repeating callback that can be invoked on any sequence. When
352*6777b538SAndroid Build Coastguard Worker   // invoked it will post a task to the sequence the TestFuture was created on,
353*6777b538SAndroid Build Coastguard Worker   // to store all the argument values, and unblock any waiters.
354*6777b538SAndroid Build Coastguard Worker   //
355*6777b538SAndroid Build Coastguard Worker   // You must take care that the stored value is consumed before the callback
356*6777b538SAndroid Build Coastguard Worker   // is invoked a second time. You can consume the value by calling either
357*6777b538SAndroid Build Coastguard Worker   // `Take()` or `Clear()`.
358*6777b538SAndroid Build Coastguard Worker   //
359*6777b538SAndroid Build Coastguard Worker   // Example usage:
360*6777b538SAndroid Build Coastguard Worker   //
361*6777b538SAndroid Build Coastguard Worker   //   base::SequenceBound<Object> object_under_test(other_task_runner);
362*6777b538SAndroid Build Coastguard Worker   //   TestFuture<std::string> future;
363*6777b538SAndroid Build Coastguard Worker   //
364*6777b538SAndroid Build Coastguard Worker   //   object_under_test.AsyncCall(&Object::InstallCallback,
365*6777b538SAndroid Build Coastguard Worker   //                               future.GetSequenceBoundRepeatingCallback());
366*6777b538SAndroid Build Coastguard Worker   //
367*6777b538SAndroid Build Coastguard Worker   //   object_under_test.AsyncCall(&DoSomething);
368*6777b538SAndroid Build Coastguard Worker   //   EXPECT_EQ(future.Take(), "expected-first-value");
369*6777b538SAndroid Build Coastguard Worker   //   // Because we used `Take()` the test future is ready for reuse.
370*6777b538SAndroid Build Coastguard Worker   //
371*6777b538SAndroid Build Coastguard Worker   //   object_under_test.AsyncCall(&DoSomethingElse);
372*6777b538SAndroid Build Coastguard Worker   //   // We can also use `Get()` + `Clear()` to reuse the callback.
373*6777b538SAndroid Build Coastguard Worker   //   EXPECT_EQ(future.Get(), "expected-second-value");
374*6777b538SAndroid Build Coastguard Worker   //   future.Clear();
375*6777b538SAndroid Build Coastguard Worker   //
376*6777b538SAndroid Build Coastguard Worker   //   object_under_test.AsyncCall(&DoSomethingElse);
377*6777b538SAndroid Build Coastguard Worker   //   EXPECT_EQ(future.Take(), "expected-third-value");
378*6777b538SAndroid Build Coastguard Worker   //
379*6777b538SAndroid Build Coastguard Worker   template <typename... CallbackArgumentsTypes>
380*6777b538SAndroid Build Coastguard Worker   RepeatingCallback<void(CallbackArgumentsTypes...)>
GetSequenceBoundRepeatingCallback()381*6777b538SAndroid Build Coastguard Worker   GetSequenceBoundRepeatingCallback() {
382*6777b538SAndroid Build Coastguard Worker     DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
383*6777b538SAndroid Build Coastguard Worker     return BindPostTask(base::SequencedTaskRunner::GetCurrentDefault(),
384*6777b538SAndroid Build Coastguard Worker                         GetRepeatingCallback<CallbackArgumentsTypes...>());
385*6777b538SAndroid Build Coastguard Worker   }
386*6777b538SAndroid Build Coastguard Worker 
GetSequenceBoundRepeatingCallback()387*6777b538SAndroid Build Coastguard Worker   RepeatingCallback<void(Types...)> GetSequenceBoundRepeatingCallback() {
388*6777b538SAndroid Build Coastguard Worker     return GetSequenceBoundRepeatingCallback<Types...>();
389*6777b538SAndroid Build Coastguard Worker   }
390*6777b538SAndroid Build Coastguard Worker 
391*6777b538SAndroid Build Coastguard Worker   // Sets the value of the future.
392*6777b538SAndroid Build Coastguard Worker   // This will unblock any pending Wait() or Get() call.
SetValue(Types...values)393*6777b538SAndroid Build Coastguard Worker   void SetValue(Types... values) {
394*6777b538SAndroid Build Coastguard Worker     DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
395*6777b538SAndroid Build Coastguard Worker 
396*6777b538SAndroid Build Coastguard Worker     auto new_values = std::make_tuple(std::forward<Types>(values)...);
397*6777b538SAndroid Build Coastguard Worker 
398*6777b538SAndroid Build Coastguard Worker     EXPECT_FALSE(values_.has_value())
399*6777b538SAndroid Build Coastguard Worker         << "Received new value " << ToString(new_values)  //
400*6777b538SAndroid Build Coastguard Worker         << " before old value " << ToString(GetTuple())
401*6777b538SAndroid Build Coastguard Worker         << " was consumed through Take() or Clear().";
402*6777b538SAndroid Build Coastguard Worker 
403*6777b538SAndroid Build Coastguard Worker     values_ = std::move(new_values);
404*6777b538SAndroid Build Coastguard Worker 
405*6777b538SAndroid Build Coastguard Worker     ready_signal_.Run();
406*6777b538SAndroid Build Coastguard Worker   }
407*6777b538SAndroid Build Coastguard Worker 
408*6777b538SAndroid Build Coastguard Worker   // Clears the future, allowing it to be reused and accept a new value.
409*6777b538SAndroid Build Coastguard Worker   //
410*6777b538SAndroid Build Coastguard Worker   // All outstanding callbacks issued through `GetCallback()` remain valid.
Clear()411*6777b538SAndroid Build Coastguard Worker   void Clear() {
412*6777b538SAndroid Build Coastguard Worker     if (IsReady()) {
413*6777b538SAndroid Build Coastguard Worker       std::ignore = Take();
414*6777b538SAndroid Build Coastguard Worker     }
415*6777b538SAndroid Build Coastguard Worker   }
416*6777b538SAndroid Build Coastguard Worker 
417*6777b538SAndroid Build Coastguard Worker   //////////////////////////////////////////////////////////////////////////////
418*6777b538SAndroid Build Coastguard Worker   //  Accessor methods only available if the future holds a single value.
419*6777b538SAndroid Build Coastguard Worker   //////////////////////////////////////////////////////////////////////////////
420*6777b538SAndroid Build Coastguard Worker 
421*6777b538SAndroid Build Coastguard Worker   // Waits for the value to arrive, and returns a reference to it.
422*6777b538SAndroid Build Coastguard Worker   //
423*6777b538SAndroid Build Coastguard Worker   // Will CHECK if a timeout happens.
424*6777b538SAndroid Build Coastguard Worker   template <typename T = TupleType, internal::EnableIfSingleValue<T> = true>
Get()425*6777b538SAndroid Build Coastguard Worker   [[nodiscard]] const auto& Get() {
426*6777b538SAndroid Build Coastguard Worker     return std::get<0>(GetTuple());
427*6777b538SAndroid Build Coastguard Worker   }
428*6777b538SAndroid Build Coastguard Worker 
429*6777b538SAndroid Build Coastguard Worker   // Waits for the value to arrive, and returns it.
430*6777b538SAndroid Build Coastguard Worker   //
431*6777b538SAndroid Build Coastguard Worker   // Will CHECK if a timeout happens.
432*6777b538SAndroid Build Coastguard Worker   template <typename T = TupleType, internal::EnableIfSingleValue<T> = true>
Take()433*6777b538SAndroid Build Coastguard Worker   [[nodiscard]] auto Take() {
434*6777b538SAndroid Build Coastguard Worker     return std::get<0>(TakeTuple());
435*6777b538SAndroid Build Coastguard Worker   }
436*6777b538SAndroid Build Coastguard Worker 
437*6777b538SAndroid Build Coastguard Worker   //////////////////////////////////////////////////////////////////////////////
438*6777b538SAndroid Build Coastguard Worker   //  Accessor methods only available if the future holds multiple values.
439*6777b538SAndroid Build Coastguard Worker   //////////////////////////////////////////////////////////////////////////////
440*6777b538SAndroid Build Coastguard Worker 
441*6777b538SAndroid Build Coastguard Worker   // Waits for the values to arrive, and returns a tuple with the values.
442*6777b538SAndroid Build Coastguard Worker   //
443*6777b538SAndroid Build Coastguard Worker   // Will CHECK if a timeout happens.
444*6777b538SAndroid Build Coastguard Worker   template <typename T = TupleType, internal::EnableIfMultiValue<T> = true>
Get()445*6777b538SAndroid Build Coastguard Worker   [[nodiscard]] const TupleType& Get() {
446*6777b538SAndroid Build Coastguard Worker     return GetTuple();
447*6777b538SAndroid Build Coastguard Worker   }
448*6777b538SAndroid Build Coastguard Worker 
449*6777b538SAndroid Build Coastguard Worker   // Waits for the values to arrive, and moves a tuple with the values out.
450*6777b538SAndroid Build Coastguard Worker   //
451*6777b538SAndroid Build Coastguard Worker   // Will CHECK if a timeout happens.
452*6777b538SAndroid Build Coastguard Worker   template <typename T = TupleType, internal::EnableIfMultiValue<T> = true>
Take()453*6777b538SAndroid Build Coastguard Worker   [[nodiscard]] TupleType Take() {
454*6777b538SAndroid Build Coastguard Worker     return TakeTuple();
455*6777b538SAndroid Build Coastguard Worker   }
456*6777b538SAndroid Build Coastguard Worker 
457*6777b538SAndroid Build Coastguard Worker  private:
GetTuple()458*6777b538SAndroid Build Coastguard Worker   [[nodiscard]] const TupleType& GetTuple() {
459*6777b538SAndroid Build Coastguard Worker     DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
460*6777b538SAndroid Build Coastguard Worker     bool success = Wait();
461*6777b538SAndroid Build Coastguard Worker     CHECK(success) << "Waiting for value timed out.";
462*6777b538SAndroid Build Coastguard Worker     return values_.value();
463*6777b538SAndroid Build Coastguard Worker   }
464*6777b538SAndroid Build Coastguard Worker 
TakeTuple()465*6777b538SAndroid Build Coastguard Worker   [[nodiscard]] TupleType TakeTuple() {
466*6777b538SAndroid Build Coastguard Worker     DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
467*6777b538SAndroid Build Coastguard Worker     bool success = Wait();
468*6777b538SAndroid Build Coastguard Worker     CHECK(success) << "Waiting for value timed out.";
469*6777b538SAndroid Build Coastguard Worker 
470*6777b538SAndroid Build Coastguard Worker     return std::exchange(values_, {}).value();
471*6777b538SAndroid Build Coastguard Worker   }
472*6777b538SAndroid Build Coastguard Worker 
473*6777b538SAndroid Build Coastguard Worker   SEQUENCE_CHECKER(sequence_checker_);
474*6777b538SAndroid Build Coastguard Worker 
475*6777b538SAndroid Build Coastguard Worker   base::RepeatingClosure ready_signal_ GUARDED_BY_CONTEXT(sequence_checker_) =
476*6777b538SAndroid Build Coastguard Worker       base::DoNothing();
477*6777b538SAndroid Build Coastguard Worker 
478*6777b538SAndroid Build Coastguard Worker   std::optional<TupleType> values_ GUARDED_BY_CONTEXT(sequence_checker_);
479*6777b538SAndroid Build Coastguard Worker 
480*6777b538SAndroid Build Coastguard Worker   WeakPtrFactory<TestFuture<Types...>> weak_ptr_factory_{this};
481*6777b538SAndroid Build Coastguard Worker };
482*6777b538SAndroid Build Coastguard Worker 
483*6777b538SAndroid Build Coastguard Worker // Specialization so you can use `TestFuture` to wait for a no-args callback.
484*6777b538SAndroid Build Coastguard Worker //
485*6777b538SAndroid Build Coastguard Worker // This specialization offers a subset of the methods provided on the base
486*6777b538SAndroid Build Coastguard Worker // `TestFuture`, as there is no value to be returned.
487*6777b538SAndroid Build Coastguard Worker template <>
488*6777b538SAndroid Build Coastguard Worker class TestFuture<void> {
489*6777b538SAndroid Build Coastguard Worker  public:
490*6777b538SAndroid Build Coastguard Worker   // Waits until the callback or `SetValue()` is invoked.
491*6777b538SAndroid Build Coastguard Worker   //
492*6777b538SAndroid Build Coastguard Worker   // Fails your test if a timeout happens, but you can check the return value
493*6777b538SAndroid Build Coastguard Worker   // to improve the error reported:
494*6777b538SAndroid Build Coastguard Worker   //
495*6777b538SAndroid Build Coastguard Worker   //   ASSERT_TRUE(future.Wait()) << "Detailed error message";
Wait()496*6777b538SAndroid Build Coastguard Worker   [[nodiscard]] bool Wait() { return implementation_.Wait(); }
497*6777b538SAndroid Build Coastguard Worker 
498*6777b538SAndroid Build Coastguard Worker   // Same as above, then clears the future, allowing it to be reused and accept
499*6777b538SAndroid Build Coastguard Worker   // a new value.
WaitAndClear()500*6777b538SAndroid Build Coastguard Worker   [[nodiscard]] bool WaitAndClear() {
501*6777b538SAndroid Build Coastguard Worker     auto result = Wait();
502*6777b538SAndroid Build Coastguard Worker     Clear();
503*6777b538SAndroid Build Coastguard Worker     return result;
504*6777b538SAndroid Build Coastguard Worker   }
505*6777b538SAndroid Build Coastguard Worker 
506*6777b538SAndroid Build Coastguard Worker   // Waits until the callback or `SetValue()` is invoked.
Get()507*6777b538SAndroid Build Coastguard Worker   void Get() { std::ignore = implementation_.Get(); }
508*6777b538SAndroid Build Coastguard Worker 
509*6777b538SAndroid Build Coastguard Worker   // Returns true if the callback or `SetValue()` was invoked.
IsReady()510*6777b538SAndroid Build Coastguard Worker   bool IsReady() const { return implementation_.IsReady(); }
511*6777b538SAndroid Build Coastguard Worker 
512*6777b538SAndroid Build Coastguard Worker   // Returns a callback that when invoked will unblock any waiters.
GetCallback()513*6777b538SAndroid Build Coastguard Worker   OnceClosure GetCallback() {
514*6777b538SAndroid Build Coastguard Worker     return BindOnce(implementation_.GetCallback(), true);
515*6777b538SAndroid Build Coastguard Worker   }
516*6777b538SAndroid Build Coastguard Worker 
517*6777b538SAndroid Build Coastguard Worker   // Returns a callback that when invoked will unblock any waiters.
GetRepeatingCallback()518*6777b538SAndroid Build Coastguard Worker   RepeatingClosure GetRepeatingCallback() {
519*6777b538SAndroid Build Coastguard Worker     return BindRepeating(implementation_.GetRepeatingCallback(), true);
520*6777b538SAndroid Build Coastguard Worker   }
521*6777b538SAndroid Build Coastguard Worker 
522*6777b538SAndroid Build Coastguard Worker   // Returns a callback that when invoked on any sequence will unblock any
523*6777b538SAndroid Build Coastguard Worker   // waiters.
GetSequenceBoundCallback()524*6777b538SAndroid Build Coastguard Worker   OnceClosure GetSequenceBoundCallback() {
525*6777b538SAndroid Build Coastguard Worker     return BindOnce(implementation_.GetSequenceBoundCallback(), true);
526*6777b538SAndroid Build Coastguard Worker   }
527*6777b538SAndroid Build Coastguard Worker 
528*6777b538SAndroid Build Coastguard Worker   // Returns a callback that when invoked on any sequence will unblock any
529*6777b538SAndroid Build Coastguard Worker   // waiters.
GetSequenceBoundRepeatingCallback()530*6777b538SAndroid Build Coastguard Worker   RepeatingClosure GetSequenceBoundRepeatingCallback() {
531*6777b538SAndroid Build Coastguard Worker     return BindRepeating(implementation_.GetSequenceBoundRepeatingCallback(),
532*6777b538SAndroid Build Coastguard Worker                          true);
533*6777b538SAndroid Build Coastguard Worker   }
534*6777b538SAndroid Build Coastguard Worker 
535*6777b538SAndroid Build Coastguard Worker   // Indicates this `TestFuture` is ready, and unblocks any waiters.
SetValue()536*6777b538SAndroid Build Coastguard Worker   void SetValue() { implementation_.SetValue(true); }
537*6777b538SAndroid Build Coastguard Worker 
538*6777b538SAndroid Build Coastguard Worker   // Clears the future, allowing it to be reused and accept a new value.
539*6777b538SAndroid Build Coastguard Worker   //
540*6777b538SAndroid Build Coastguard Worker   // All outstanding callbacks issued through `GetCallback()` remain valid.
Clear()541*6777b538SAndroid Build Coastguard Worker   void Clear() { implementation_.Clear(); }
542*6777b538SAndroid Build Coastguard Worker 
543*6777b538SAndroid Build Coastguard Worker  private:
544*6777b538SAndroid Build Coastguard Worker   TestFuture<bool> implementation_;
545*6777b538SAndroid Build Coastguard Worker };
546*6777b538SAndroid Build Coastguard Worker 
547*6777b538SAndroid Build Coastguard Worker }  // namespace base::test
548*6777b538SAndroid Build Coastguard Worker 
549*6777b538SAndroid Build Coastguard Worker #endif  // BASE_TEST_TEST_FUTURE_H_
550