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