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