• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2021 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 #include "base/test/test_future.h"
6 
7 #include <tuple>
8 
9 #include "base/functional/callback.h"
10 #include "base/run_loop.h"
11 #include "base/task/sequenced_task_runner.h"
12 #include "base/task/thread_pool.h"
13 #include "base/test/bind.h"
14 #include "base/test/gtest_util.h"
15 #include "base/test/mock_callback.h"
16 #include "base/test/scoped_run_loop_timeout.h"
17 #include "base/test/task_environment.h"
18 #include "testing/gtest/include/gtest/gtest-spi.h"
19 #include "testing/gtest/include/gtest/gtest.h"
20 
21 namespace base::test {
22 
23 namespace {
24 
25 using AnyType = int;
26 constexpr int kAnyValue = 5;
27 constexpr int kOtherValue = 10;
28 
29 struct MoveOnlyValue {
30  public:
31   MoveOnlyValue() = default;
MoveOnlyValuebase::test::__anon0a11accd0111::MoveOnlyValue32   explicit MoveOnlyValue(int data) : data(data) {}
33   MoveOnlyValue(MoveOnlyValue&&) = default;
34   MoveOnlyValue& operator=(MoveOnlyValue&&) = default;
35   ~MoveOnlyValue() = default;
36 
37   int data;
38 };
39 
40 }  // namespace
41 
42 class TestFutureTest : public ::testing::Test {
43  public:
44   TestFutureTest() = default;
45   TestFutureTest(const TestFutureTest&) = delete;
46   TestFutureTest& operator=(const TestFutureTest&) = delete;
47   ~TestFutureTest() override = default;
48 
49   template <typename Lambda>
RunLater(Lambda lambda,scoped_refptr<SequencedTaskRunner> task_runner=SequencedTaskRunner::GetCurrentDefault ())50   void RunLater(Lambda lambda,
51                 scoped_refptr<SequencedTaskRunner> task_runner =
52                     SequencedTaskRunner::GetCurrentDefault()) {
53     task_runner->PostTask(FROM_HERE, BindLambdaForTesting(lambda));
54   }
55 
RunLater(OnceClosure callable,scoped_refptr<SequencedTaskRunner> task_runner=SequencedTaskRunner::GetCurrentDefault ())56   void RunLater(OnceClosure callable,
57                 scoped_refptr<SequencedTaskRunner> task_runner =
58                     SequencedTaskRunner::GetCurrentDefault()) {
59     task_runner->PostTask(FROM_HERE, std::move(callable));
60   }
61 
RunLater(RepeatingClosure callable,scoped_refptr<SequencedTaskRunner> task_runner=SequencedTaskRunner::GetCurrentDefault ())62   void RunLater(RepeatingClosure callable,
63                 scoped_refptr<SequencedTaskRunner> task_runner =
64                     SequencedTaskRunner::GetCurrentDefault()) {
65     task_runner->PostTask(FROM_HERE, std::move(callable));
66   }
67 
PostDelayedTask(OnceClosure callable,base::TimeDelta delay,scoped_refptr<SequencedTaskRunner> task_runner=SequencedTaskRunner::GetCurrentDefault ())68   void PostDelayedTask(OnceClosure callable,
69                        base::TimeDelta delay,
70                        scoped_refptr<SequencedTaskRunner> task_runner =
71                            SequencedTaskRunner::GetCurrentDefault()) {
72     task_runner->PostDelayedTask(FROM_HERE, std::move(callable), delay);
73   }
74 
75  private:
76   TaskEnvironment environment_{TaskEnvironment::TimeSource::MOCK_TIME};
77 };
78 
79 using TestFutureDeathTest = TestFutureTest;
80 
TEST_F(TestFutureTest,WaitShouldBlockUntilValueArrives)81 TEST_F(TestFutureTest, WaitShouldBlockUntilValueArrives) {
82   const int expected_value = 42;
83   TestFuture<int> future;
84 
85   PostDelayedTask(BindOnce(future.GetCallback(), expected_value),
86                   Milliseconds(1));
87 
88   std::ignore = future.Wait();
89 
90   EXPECT_EQ(expected_value, future.Get());
91 }
92 
TEST_F(TestFutureTest,WaitShouldBlockUntilValueArrivesOnOtherSequence)93 TEST_F(TestFutureTest, WaitShouldBlockUntilValueArrivesOnOtherSequence) {
94   const int expected_value = 42;
95   TestFuture<int> future;
96 
97   PostDelayedTask(BindOnce(future.GetSequenceBoundCallback(), expected_value),
98                   Milliseconds(1), ThreadPool::CreateSequencedTaskRunner({}));
99 
100   std::ignore = future.Wait();
101 
102   EXPECT_EQ(expected_value, future.Get());
103 }
104 
TEST_F(TestFutureTest,WaitShouldReturnTrueWhenValueArrives)105 TEST_F(TestFutureTest, WaitShouldReturnTrueWhenValueArrives) {
106   TestFuture<int> future;
107 
108   PostDelayedTask(BindOnce(future.GetCallback(), kAnyValue), Milliseconds(1));
109 
110   bool success = future.Wait();
111   EXPECT_TRUE(success);
112 }
113 
TEST_F(TestFutureTest,WaitShouldReturnTrueWhenValueArrivesOnOtherSequence)114 TEST_F(TestFutureTest, WaitShouldReturnTrueWhenValueArrivesOnOtherSequence) {
115   TestFuture<int> future;
116 
117   PostDelayedTask(BindOnce(future.GetSequenceBoundCallback(), kAnyValue),
118                   Milliseconds(1), ThreadPool::CreateSequencedTaskRunner({}));
119 
120   bool success = future.Wait();
121   EXPECT_TRUE(success);
122 }
123 
TEST_F(TestFutureTest,WaitShouldReturnFalseIfTimeoutHappens)124 TEST_F(TestFutureTest, WaitShouldReturnFalseIfTimeoutHappens) {
125   ScopedRunLoopTimeout timeout(FROM_HERE, Milliseconds(1));
126 
127   // `ScopedRunLoopTimeout` will automatically fail the test when a timeout
128   // happens, so we use EXPECT_FATAL_FAILURE to handle this failure.
129   // EXPECT_FATAL_FAILURE only works on static objects.
130   static bool success;
131   static TestFuture<AnyType> future;
132 
133   EXPECT_NONFATAL_FAILURE({ success = future.Wait(); }, "timed out");
134 
135   EXPECT_FALSE(success);
136 }
137 
TEST_F(TestFutureTest,GetShouldBlockUntilValueArrives)138 TEST_F(TestFutureTest, GetShouldBlockUntilValueArrives) {
139   const int expected_value = 42;
140   TestFuture<int> future;
141 
142   PostDelayedTask(BindOnce(future.GetCallback(), expected_value),
143                   Milliseconds(1));
144 
145   int actual_value = future.Get();
146 
147   EXPECT_EQ(expected_value, actual_value);
148 }
149 
TEST_F(TestFutureTest,GetShouldBlockUntilValueArrivesOnOtherSequence)150 TEST_F(TestFutureTest, GetShouldBlockUntilValueArrivesOnOtherSequence) {
151   const int expected_value = 42;
152   TestFuture<int> future;
153 
154   PostDelayedTask(BindOnce(future.GetSequenceBoundCallback(), expected_value),
155                   Milliseconds(1), ThreadPool::CreateSequencedTaskRunner({}));
156 
157   int actual_value = future.Get();
158 
159   EXPECT_EQ(expected_value, actual_value);
160 }
161 
TEST_F(TestFutureDeathTest,GetShouldCheckIfTimeoutHappens)162 TEST_F(TestFutureDeathTest, GetShouldCheckIfTimeoutHappens) {
163   ScopedRunLoopTimeout timeout(FROM_HERE, Milliseconds(1));
164 
165   TestFuture<AnyType> future;
166 
167   EXPECT_CHECK_DEATH_WITH(std::ignore = future.Get(), "timed out");
168 }
169 
TEST_F(TestFutureTest,TakeShouldWorkWithMoveOnlyValue)170 TEST_F(TestFutureTest, TakeShouldWorkWithMoveOnlyValue) {
171   const int expected_data = 99;
172   TestFuture<MoveOnlyValue> future;
173 
174   RunLater(BindOnce(future.GetCallback(), MoveOnlyValue(expected_data)));
175 
176   MoveOnlyValue actual_value = future.Take();
177 
178   EXPECT_EQ(expected_data, actual_value.data);
179 }
180 
TEST_F(TestFutureTest,TakeShouldWorkWithMoveOnlyValueOnOtherSequence)181 TEST_F(TestFutureTest, TakeShouldWorkWithMoveOnlyValueOnOtherSequence) {
182   const int expected_data = 99;
183   TestFuture<MoveOnlyValue> future;
184 
185   RunLater(
186       BindOnce(future.GetSequenceBoundCallback(), MoveOnlyValue(expected_data)),
187       ThreadPool::CreateSequencedTaskRunner({}));
188 
189   MoveOnlyValue actual_value = future.Take();
190 
191   EXPECT_EQ(expected_data, actual_value.data);
192 }
193 
TEST_F(TestFutureDeathTest,TakeShouldCheckIfTimeoutHappens)194 TEST_F(TestFutureDeathTest, TakeShouldCheckIfTimeoutHappens) {
195   ScopedRunLoopTimeout timeout(FROM_HERE, Milliseconds(1));
196 
197   TestFuture<AnyType> future;
198 
199   EXPECT_CHECK_DEATH_WITH(std::ignore = future.Take(), "timed out");
200 }
201 
TEST_F(TestFutureTest,IsReadyShouldBeTrueWhenValueIsSet)202 TEST_F(TestFutureTest, IsReadyShouldBeTrueWhenValueIsSet) {
203   TestFuture<AnyType> future;
204 
205   EXPECT_FALSE(future.IsReady());
206 
207   future.SetValue(kAnyValue);
208 
209   EXPECT_TRUE(future.IsReady());
210 }
211 
TEST_F(TestFutureTest,ClearShouldRemoveStoredValue)212 TEST_F(TestFutureTest, ClearShouldRemoveStoredValue) {
213   TestFuture<AnyType> future;
214 
215   future.SetValue(kAnyValue);
216 
217   future.Clear();
218 
219   EXPECT_FALSE(future.IsReady());
220 }
221 
TEST_F(TestFutureTest,ShouldNotAllowOverwritingStoredValue)222 TEST_F(TestFutureTest, ShouldNotAllowOverwritingStoredValue) {
223   TestFuture<AnyType> future;
224 
225   future.SetValue(kAnyValue);
226 
227   EXPECT_NONFATAL_FAILURE(future.SetValue(kOtherValue), "Received new value");
228 }
229 
TEST_F(TestFutureTest,ShouldAllowReuseIfPreviousValueIsFirstConsumed)230 TEST_F(TestFutureTest, ShouldAllowReuseIfPreviousValueIsFirstConsumed) {
231   TestFuture<std::string> future;
232 
233   RunLater([&] { future.SetValue("first value"); });
234   EXPECT_EQ(future.Take(), "first value");
235 
236   ASSERT_FALSE(future.IsReady());
237 
238   RunLater([&] { future.SetValue("second value"); });
239   EXPECT_EQ(future.Take(), "second value");
240 }
241 
TEST_F(TestFutureTest,ShouldAllowReusingCallback)242 TEST_F(TestFutureTest, ShouldAllowReusingCallback) {
243   TestFuture<std::string> future;
244 
245   RepeatingCallback<void(std::string)> callback = future.GetRepeatingCallback();
246 
247   RunLater(BindOnce(callback, "first value"));
248   EXPECT_EQ(future.Take(), "first value");
249 
250   RunLater(BindOnce(callback, "second value"));
251   EXPECT_EQ(future.Take(), "second value");
252 
253   RepeatingCallback<void(std::string)> sequence_bound_callback =
254       future.GetSequenceBoundRepeatingCallback();
255   auto other_task_runner = ThreadPool::CreateSequencedTaskRunner({});
256 
257   RunLater(BindOnce(sequence_bound_callback, "third value"), other_task_runner);
258   EXPECT_EQ(future.Take(), "third value");
259 
260   RunLater(BindOnce(sequence_bound_callback, "fourth value"),
261            other_task_runner);
262   EXPECT_EQ(future.Take(), "fourth value");
263 }
264 
TEST_F(TestFutureTest,WaitShouldWorkAfterTake)265 TEST_F(TestFutureTest, WaitShouldWorkAfterTake) {
266   TestFuture<std::string> future;
267 
268   future.SetValue("first value");
269   std::ignore = future.Take();
270 
271   RunLater([&] { future.SetValue("second value"); });
272 
273   EXPECT_TRUE(future.Wait());
274   EXPECT_EQ(future.Get(), "second value");
275 }
276 
TEST_F(TestFutureTest,ShouldSignalWhenSetValueIsInvoked)277 TEST_F(TestFutureTest, ShouldSignalWhenSetValueIsInvoked) {
278   const int expected_value = 111;
279   TestFuture<int> future;
280 
281   RunLater([&future] { future.SetValue(expected_value); });
282 
283   int actual_value = future.Get();
284 
285   EXPECT_EQ(expected_value, actual_value);
286 }
287 
TEST_F(TestFutureTest,ShouldAllowReferenceArgumentsForCallback)288 TEST_F(TestFutureTest, ShouldAllowReferenceArgumentsForCallback) {
289   const int expected_value = 222;
290   TestFuture<int> future;
291 
292   OnceCallback<void(const int&)> callback = future.GetCallback<const int&>();
293   RunLater(BindOnce(std::move(callback), expected_value));
294 
295   int actual_value = future.Get();
296 
297   EXPECT_EQ(expected_value, actual_value);
298 }
299 
TEST_F(TestFutureTest,ShouldAllowReferenceArgumentsForCallbackOnOtherSequence)300 TEST_F(TestFutureTest,
301        ShouldAllowReferenceArgumentsForCallbackOnOtherSequence) {
302   const int expected_value = 222;
303   TestFuture<int> future;
304 
305   OnceCallback<void(const int&)> callback =
306       future.GetSequenceBoundCallback<const int&>();
307   RunLater(BindOnce(std::move(callback), expected_value),
308            ThreadPool::CreateSequencedTaskRunner({}));
309 
310   int actual_value = future.Get();
311 
312   EXPECT_EQ(expected_value, actual_value);
313 }
314 
TEST_F(TestFutureTest,ShouldAllowInvokingCallbackAfterFutureIsDestroyed)315 TEST_F(TestFutureTest, ShouldAllowInvokingCallbackAfterFutureIsDestroyed) {
316   OnceCallback<void(int)> callback;
317 
318   {
319     TestFuture<int> future;
320     callback = future.GetCallback();
321   }
322 
323   std::move(callback).Run(1);
324 }
325 
TEST_F(TestFutureTest,ShouldAllowInvokingCallbackOnOtherSequenceAfterFutureIsDestroyed)326 TEST_F(TestFutureTest,
327        ShouldAllowInvokingCallbackOnOtherSequenceAfterFutureIsDestroyed) {
328   OnceCallback<void(int)> callback;
329 
330   {
331     TestFuture<int> future;
332     callback = future.GetSequenceBoundCallback();
333   }
334 
335   base::RunLoop run_loop;
336   ThreadPool::PostTask(
337       FROM_HERE, BindOnce(std::move(callback), 1).Then(run_loop.QuitClosure()));
338   run_loop.Run();
339 }
340 
TEST_F(TestFutureTest,ShouldReturnTupleValue)341 TEST_F(TestFutureTest, ShouldReturnTupleValue) {
342   const int expected_int_value = 5;
343   const std::string expected_string_value = "value";
344 
345   TestFuture<int, std::string> future;
346 
347   RunLater(BindOnce(future.GetCallback(), expected_int_value,
348                     expected_string_value));
349 
350   const std::tuple<int, std::string>& actual = future.Get();
351 
352   EXPECT_EQ(expected_int_value, std::get<0>(actual));
353   EXPECT_EQ(expected_string_value, std::get<1>(actual));
354 }
355 
TEST_F(TestFutureTest,ShouldReturnTupleValueOnOtherSequence)356 TEST_F(TestFutureTest, ShouldReturnTupleValueOnOtherSequence) {
357   const int expected_int_value = 5;
358   const std::string expected_string_value = "value";
359 
360   TestFuture<int, std::string> future;
361 
362   RunLater(BindOnce(future.GetSequenceBoundCallback(), expected_int_value,
363                     expected_string_value),
364            ThreadPool::CreateSequencedTaskRunner({}));
365 
366   const std::tuple<int, std::string>& actual = future.Get();
367 
368   EXPECT_EQ(expected_int_value, std::get<0>(actual));
369   EXPECT_EQ(expected_string_value, std::get<1>(actual));
370 }
371 
TEST_F(TestFutureTest,ShouldAllowAccessingTupleValueUsingGetWithIndex)372 TEST_F(TestFutureTest, ShouldAllowAccessingTupleValueUsingGetWithIndex) {
373   const int expected_int_value = 5;
374   const std::string expected_string_value = "value";
375 
376   TestFuture<int, std::string> future;
377 
378   RunLater(BindOnce(future.GetCallback(), expected_int_value,
379                     expected_string_value));
380 
381   std::ignore = future.Get();
382 
383   EXPECT_EQ(expected_int_value, future.Get<0>());
384   EXPECT_EQ(expected_string_value, future.Get<1>());
385 }
386 
TEST_F(TestFutureTest,ShouldAllowAccessingTupleValueUsingGetWithType)387 TEST_F(TestFutureTest, ShouldAllowAccessingTupleValueUsingGetWithType) {
388   const int expected_int_value = 5;
389   const std::string expected_string_value = "value";
390 
391   TestFuture<int, std::string> future;
392 
393   RunLater(BindOnce(future.GetCallback(), expected_int_value,
394                     expected_string_value));
395 
396   std::ignore = future.Get();
397 
398   EXPECT_EQ(expected_int_value, future.Get<int>());
399   EXPECT_EQ(expected_string_value, future.Get<std::string>());
400 }
401 
TEST_F(TestFutureTest,ShouldAllowReferenceArgumentsForMultiArgumentCallback)402 TEST_F(TestFutureTest, ShouldAllowReferenceArgumentsForMultiArgumentCallback) {
403   const int expected_int_value = 5;
404   const std::string expected_string_value = "value";
405 
406   TestFuture<int, std::string> future;
407 
408   OnceCallback<void(int, const std::string&)> callback =
409       future.GetCallback<int, const std::string&>();
410   RunLater(
411       BindOnce(std::move(callback), expected_int_value, expected_string_value));
412 
413   std::tuple<int, std::string> actual = future.Get();
414 
415   EXPECT_EQ(expected_int_value, std::get<0>(actual));
416   EXPECT_EQ(expected_string_value, std::get<1>(actual));
417 }
418 
TEST_F(TestFutureTest,ShouldAllowReferenceArgumentsForMultiArgumentCallbackOnOtherSequence)419 TEST_F(TestFutureTest,
420        ShouldAllowReferenceArgumentsForMultiArgumentCallbackOnOtherSequence) {
421   const int expected_int_value = 5;
422   const std::string expected_string_value = "value";
423 
424   TestFuture<int, std::string> future;
425 
426   OnceCallback<void(int, const std::string&)> callback =
427       future.GetSequenceBoundCallback<int, const std::string&>();
428   RunLater(
429       BindOnce(std::move(callback), expected_int_value, expected_string_value),
430       ThreadPool::CreateSequencedTaskRunner({}));
431 
432   std::tuple<int, std::string> actual = future.Get();
433 
434   EXPECT_EQ(expected_int_value, std::get<0>(actual));
435   EXPECT_EQ(expected_string_value, std::get<1>(actual));
436 }
437 
TEST_F(TestFutureTest,SetValueShouldAllowMultipleArguments)438 TEST_F(TestFutureTest, SetValueShouldAllowMultipleArguments) {
439   const int expected_int_value = 5;
440   const std::string expected_string_value = "value";
441 
442   TestFuture<int, std::string> future;
443 
444   RunLater([&future, expected_string_value]() {
445     future.SetValue(expected_int_value, expected_string_value);
446   });
447 
448   const std::tuple<int, std::string>& actual = future.Get();
449 
450   EXPECT_EQ(expected_int_value, std::get<0>(actual));
451   EXPECT_EQ(expected_string_value, std::get<1>(actual));
452 }
453 
TEST_F(TestFutureTest,ShouldSupportCvRefType)454 TEST_F(TestFutureTest, ShouldSupportCvRefType) {
455   std::string expected_value = "value";
456   TestFuture<const std::string&> future;
457 
458   OnceCallback<void(const std::string&)> callback = future.GetCallback();
459   std::move(callback).Run(expected_value);
460 
461   // both get and take should compile, and take should return the decayed value.
462   const std::string& get_result = future.Get();
463   EXPECT_EQ(expected_value, get_result);
464 
465   std::string take_result = future.Take();
466   EXPECT_EQ(expected_value, take_result);
467 }
468 
TEST_F(TestFutureTest,ShouldSupportMultipleCvRefTypes)469 TEST_F(TestFutureTest, ShouldSupportMultipleCvRefTypes) {
470   const int expected_first_value = 5;
471   std::string expected_second_value = "value";
472   const long expected_third_value = 10;
473   TestFuture<const int, std::string&, const long&> future;
474 
475   OnceCallback<void(const int, std::string&, const long&)> callback =
476       future.GetCallback();
477   std::move(callback).Run(expected_first_value, expected_second_value,
478                           expected_third_value);
479 
480   // both get and take should compile, and return the decayed value.
481   const std::tuple<int, std::string, long>& get_result = future.Get();
482   EXPECT_EQ(expected_first_value, std::get<0>(get_result));
483   EXPECT_EQ(expected_second_value, std::get<1>(get_result));
484   EXPECT_EQ(expected_third_value, std::get<2>(get_result));
485 
486   // Get<i> should also work
487   EXPECT_EQ(expected_first_value, future.Get<0>());
488   EXPECT_EQ(expected_second_value, future.Get<1>());
489   EXPECT_EQ(expected_third_value, future.Get<2>());
490 
491   std::tuple<int, std::string, long> take_result = future.Take();
492   EXPECT_EQ(expected_first_value, std::get<0>(take_result));
493   EXPECT_EQ(expected_second_value, std::get<1>(take_result));
494   EXPECT_EQ(expected_third_value, std::get<2>(take_result));
495 }
496 
TEST_F(TestFutureTest,ShouldAllowReuseIfPreviousTupleValueIsFirstConsumed)497 TEST_F(TestFutureTest, ShouldAllowReuseIfPreviousTupleValueIsFirstConsumed) {
498   TestFuture<std::string, int> future;
499 
500   future.SetValue("first value", 1);
501   std::ignore = future.Take();
502 
503   ASSERT_FALSE(future.IsReady());
504 
505   future.SetValue("second value", 2);
506   EXPECT_EQ(future.Take(), std::make_tuple("second value", 2));
507 }
508 
TEST_F(TestFutureTest,ShouldPrintCurrentValueIfItIsOverwritten)509 TEST_F(TestFutureTest, ShouldPrintCurrentValueIfItIsOverwritten) {
510   using UnprintableValue = MoveOnlyValue;
511 
512   TestFuture<const char*, int, UnprintableValue> future;
513 
514   future.SetValue("first-value", 1111, UnprintableValue());
515 
516   EXPECT_NONFATAL_FAILURE(
517       future.SetValue("second-value", 2222, UnprintableValue()),
518       "old value <first-value, 1111, [4-byte object at 0x");
519 }
520 
TEST_F(TestFutureTest,ShouldPrintNewValueIfItOverwritesOldValue)521 TEST_F(TestFutureTest, ShouldPrintNewValueIfItOverwritesOldValue) {
522   using UnprintableValue = MoveOnlyValue;
523 
524   TestFuture<const char*, int, UnprintableValue> future;
525 
526   future.SetValue("first-value", 1111, UnprintableValue());
527 
528   EXPECT_NONFATAL_FAILURE(
529       future.SetValue("second-value", 2222, UnprintableValue()),
530       "new value <second-value, 2222, [4-byte object at 0x");
531 }
532 
TEST_F(TestFutureTest,InvokeFutureSingleValue)533 TEST_F(TestFutureTest, InvokeFutureSingleValue) {
534   TestFuture<int> future;
535 
536   MockCallback<OnceCallback<void(int)>> cb;
537 
538   EXPECT_CALL(cb, Run).WillOnce(InvokeFuture(future));
539 
540   RunLater(BindOnce(cb.Get(), 7));
541 
542   EXPECT_EQ(7, future.Take());
543 }
544 
TEST_F(TestFutureTest,InvokeFutureMoveOnlyValue)545 TEST_F(TestFutureTest, InvokeFutureMoveOnlyValue) {
546   TestFuture<MoveOnlyValue> future;
547 
548   MockCallback<OnceCallback<void(MoveOnlyValue)>> cb;
549 
550   EXPECT_CALL(cb, Run).WillOnce(InvokeFuture(future));
551 
552   RunLater(BindOnce(cb.Get(), MoveOnlyValue(10)));
553 
554   EXPECT_EQ(10, future.Take().data);
555 }
556 
TEST_F(TestFutureTest,InvokeFutureMultipleValues)557 TEST_F(TestFutureTest, InvokeFutureMultipleValues) {
558   TestFuture<int, std::string> future;
559 
560   MockCallback<OnceCallback<void(int, std::string)>> cb;
561 
562   EXPECT_CALL(cb, Run).WillOnce(InvokeFuture(future));
563 
564   RunLater(BindOnce(cb.Get(), 19, "Nineteen"));
565 
566   EXPECT_THAT(future.Take(), std::tuple(19, "Nineteen"));
567 }
568 
TEST_F(TestFutureTest,InvokeFutureMultipleTimes)569 TEST_F(TestFutureTest, InvokeFutureMultipleTimes) {
570   TestFuture<std::string> future;
571 
572   MockCallback<RepeatingCallback<void(std::string)>> cb;
573 
574   EXPECT_CALL(cb, Run).WillRepeatedly(InvokeFuture(future));
575 
576   cb.Get().Run("first time");
577   EXPECT_EQ("first time", future.Take());
578 
579   cb.Get().Run("second time");
580   EXPECT_EQ("second time", future.Take());
581 }
582 
TEST_F(TestFutureTest,InvokeFutureDestroyedFuture)583 TEST_F(TestFutureTest, InvokeFutureDestroyedFuture) {
584   std::optional<TestFuture<int>> maybe_future;
585   maybe_future.emplace();
586 
587   MockCallback<OnceCallback<void(int)>> cb;
588 
589   EXPECT_CALL(cb, Run).WillOnce(InvokeFuture(*maybe_future));
590 
591   maybe_future = std::nullopt;
592 
593   // If this doesn't crash it worked.
594   cb.Get().Run(42);
595 }
596 
TEST_F(TestFutureDeathTest,CallbackShouldDcheckOnOtherSequence)597 TEST_F(TestFutureDeathTest, CallbackShouldDcheckOnOtherSequence) {
598   TestFuture<int> future;
599 
600   // Sequence-bound callback may run any time between RunLater() and Wait(),
601   // should succeed.
602   auto other_task_runner = ThreadPool::CreateSequencedTaskRunner({});
603   RunLater(BindOnce(future.GetSequenceBoundCallback(), 1), other_task_runner);
604   EXPECT_TRUE(future.Wait());
605 
606   future.Clear();
607 
608   // Callback may run any time between RunLater() and Wait(), should DCHECK.
609   EXPECT_DCHECK_DEATH_WITH(
610       {
611         RunLater(BindOnce(future.GetCallback(), 2), other_task_runner);
612         EXPECT_TRUE(future.Wait());
613       },
614       "CalledOnValidSequence");
615 }
616 
617 using TestFutureWithoutValuesTest = TestFutureTest;
618 
TEST_F(TestFutureWithoutValuesTest,IsReadyShouldBeTrueWhenSetValueIsInvoked)619 TEST_F(TestFutureWithoutValuesTest, IsReadyShouldBeTrueWhenSetValueIsInvoked) {
620   TestFuture<void> future;
621 
622   EXPECT_FALSE(future.IsReady());
623 
624   future.SetValue();
625 
626   EXPECT_TRUE(future.IsReady());
627 }
628 
TEST_F(TestFutureWithoutValuesTest,WaitShouldUnblockWhenSetValueIsInvoked)629 TEST_F(TestFutureWithoutValuesTest, WaitShouldUnblockWhenSetValueIsInvoked) {
630   TestFuture<void> future;
631 
632   RunLater([&future] { future.SetValue(); });
633 
634   ASSERT_FALSE(future.IsReady());
635   std::ignore = future.Wait();
636   EXPECT_TRUE(future.IsReady());
637 }
638 
TEST_F(TestFutureWithoutValuesTest,WaitShouldUnblockWhenCallbackIsInvoked)639 TEST_F(TestFutureWithoutValuesTest, WaitShouldUnblockWhenCallbackIsInvoked) {
640   TestFuture<void> future;
641 
642   RunLater(future.GetCallback());
643 
644   ASSERT_FALSE(future.IsReady());
645   std::ignore = future.Wait();
646   EXPECT_TRUE(future.IsReady());
647 }
648 
TEST_F(TestFutureWithoutValuesTest,WaitShouldUnblockWhenCallbackIsInvokedOnOtherSequence)649 TEST_F(TestFutureWithoutValuesTest,
650        WaitShouldUnblockWhenCallbackIsInvokedOnOtherSequence) {
651   TestFuture<void> future;
652 
653   RunLater(future.GetSequenceBoundCallback(),
654            ThreadPool::CreateSequencedTaskRunner({}));
655 
656   ASSERT_FALSE(future.IsReady());
657   std::ignore = future.Wait();
658   EXPECT_TRUE(future.IsReady());
659 }
660 
TEST_F(TestFutureWithoutValuesTest,WaitAndClearShouldAllowFutureReusing)661 TEST_F(TestFutureWithoutValuesTest, WaitAndClearShouldAllowFutureReusing) {
662   TestFuture<void> future;
663 
664   RunLater(future.GetCallback());
665   EXPECT_TRUE(future.WaitAndClear());
666 
667   ASSERT_FALSE(future.IsReady());
668 
669   RunLater(future.GetCallback());
670   EXPECT_TRUE(future.Wait());
671 
672   auto other_task_runner = ThreadPool::CreateSequencedTaskRunner({});
673   RunLater(future.GetSequenceBoundCallback(), other_task_runner);
674   EXPECT_TRUE(future.WaitAndClear());
675 
676   ASSERT_FALSE(future.IsReady());
677 
678   RunLater(future.GetSequenceBoundCallback(), other_task_runner);
679   EXPECT_TRUE(future.Wait());
680 }
681 
TEST_F(TestFutureWithoutValuesTest,GetShouldUnblockWhenCallbackIsInvoked)682 TEST_F(TestFutureWithoutValuesTest, GetShouldUnblockWhenCallbackIsInvoked) {
683   TestFuture<void> future;
684 
685   RunLater(future.GetCallback());
686 
687   ASSERT_FALSE(future.IsReady());
688   future.Get();
689   EXPECT_TRUE(future.IsReady());
690 }
691 
TEST_F(TestFutureWithoutValuesTest,GetShouldUnblockWhenCallbackIsInvokedOnOtherSequence)692 TEST_F(TestFutureWithoutValuesTest,
693        GetShouldUnblockWhenCallbackIsInvokedOnOtherSequence) {
694   TestFuture<void> future;
695 
696   RunLater(future.GetSequenceBoundCallback(),
697            ThreadPool::CreateSequencedTaskRunner({}));
698 
699   ASSERT_FALSE(future.IsReady());
700   future.Get();
701   EXPECT_TRUE(future.IsReady());
702 }
703 
TEST(TestFutureWithoutTaskEnvironmentTest,CanCreateTestFutureBeforeTaskEnvironment)704 TEST(TestFutureWithoutTaskEnvironmentTest,
705      CanCreateTestFutureBeforeTaskEnvironment) {
706   TestFuture<AnyType> future;
707 
708   // If we come here the test passes, since it means we can create a
709   // `TestFuture` without having a `TaskEnvironment`.
710 }
711 
TEST(TestFutureWithoutTaskEnvironmentDeathTest,WaitShouldDcheckWithoutTaskEnvironment)712 TEST(TestFutureWithoutTaskEnvironmentDeathTest,
713      WaitShouldDcheckWithoutTaskEnvironment) {
714   TestFuture<AnyType> future;
715 
716   EXPECT_CHECK_DEATH_WITH((void)future.Wait(),
717                           "requires a single-threaded context");
718 }
719 
TEST_F(TestFutureWithoutValuesTest,InvokeFuture)720 TEST_F(TestFutureWithoutValuesTest, InvokeFuture) {
721   TestFuture<void> future;
722 
723   MockCallback<OnceClosure> cb;
724 
725   EXPECT_CALL(cb, Run).WillOnce(InvokeFuture(future));
726 
727   RunLater(cb.Get());
728 
729   EXPECT_TRUE(future.Wait());
730 }
731 
732 }  // namespace base::test
733