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