1 // Copyright 2017 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/task_environment.h"
6
7 #include <atomic>
8 #include <memory>
9
10 #include "base/atomicops.h"
11 #include "base/cancelable_callback.h"
12 #include "base/check.h"
13 #include "base/debug/debugger.h"
14 #include "base/functional/bind.h"
15 #include "base/functional/callback_forward.h"
16 #include "base/functional/callback_helpers.h"
17 #include "base/logging.h"
18 #include "base/run_loop.h"
19 #include "base/strings/string_number_conversions.h"
20 #include "base/synchronization/atomic_flag.h"
21 #include "base/synchronization/waitable_event.h"
22 #include "base/task/current_thread.h"
23 #include "base/task/sequence_manager/time_domain.h"
24 #include "base/task/sequenced_task_runner.h"
25 #include "base/task/single_thread_task_runner.h"
26 #include "base/task/thread_pool.h"
27 #include "base/task/thread_pool/thread_pool_instance.h"
28 #include "base/test/bind.h"
29 #include "base/test/gtest_util.h"
30 #include "base/test/mock_callback.h"
31 #include "base/test/mock_log.h"
32 #include "base/test/scoped_run_loop_timeout.h"
33 #include "base/test/test_timeouts.h"
34 #include "base/test/test_waitable_event.h"
35 #include "base/threading/platform_thread.h"
36 #include "base/threading/sequence_bound.h"
37 #include "base/threading/sequence_local_storage_slot.h"
38 #include "base/threading/thread.h"
39 #include "base/time/clock.h"
40 #include "base/time/default_clock.h"
41 #include "base/time/tick_clock.h"
42 #include "base/time/time.h"
43 #include "base/win/com_init_util.h"
44 #include "build/build_config.h"
45 #include "testing/gmock/include/gmock/gmock.h"
46 #include "testing/gtest/include/gtest/gtest-spi.h"
47 #include "testing/gtest/include/gtest/gtest.h"
48
49 #if BUILDFLAG(IS_POSIX)
50 #include <unistd.h>
51
52 #include "base/files/file_descriptor_watcher_posix.h"
53 #endif // BUILDFLAG(IS_POSIX)
54
55 #if BUILDFLAG(IS_WIN)
56 #include "base/win/scoped_com_initializer.h"
57 #endif
58
59 namespace base {
60 namespace test {
61
62 namespace {
63
64 using ::testing::_;
65 using ::testing::HasSubstr;
66 using ::testing::IsNull;
67 using ::testing::Not;
68 using ::testing::Return;
69
70 class TaskEnvironmentTest : public testing::Test {};
71
VerifyRunUntilIdleDidNotReturnAndSetFlag(AtomicFlag * run_until_idle_returned,AtomicFlag * task_ran)72 void VerifyRunUntilIdleDidNotReturnAndSetFlag(
73 AtomicFlag* run_until_idle_returned,
74 AtomicFlag* task_ran) {
75 EXPECT_FALSE(run_until_idle_returned->IsSet());
76 task_ran->Set();
77 }
78
RunUntilIdleTest(TaskEnvironment::ThreadPoolExecutionMode thread_pool_execution_mode)79 void RunUntilIdleTest(
80 TaskEnvironment::ThreadPoolExecutionMode thread_pool_execution_mode) {
81 AtomicFlag run_until_idle_returned;
82 TaskEnvironment task_environment(thread_pool_execution_mode);
83
84 AtomicFlag first_main_thread_task_ran;
85 SingleThreadTaskRunner::GetCurrentDefault()->PostTask(
86 FROM_HERE, BindOnce(&VerifyRunUntilIdleDidNotReturnAndSetFlag,
87 Unretained(&run_until_idle_returned),
88 Unretained(&first_main_thread_task_ran)));
89
90 AtomicFlag first_thread_pool_task_ran;
91 ThreadPool::PostTask(FROM_HERE,
92 BindOnce(&VerifyRunUntilIdleDidNotReturnAndSetFlag,
93 Unretained(&run_until_idle_returned),
94 Unretained(&first_thread_pool_task_ran)));
95
96 AtomicFlag second_thread_pool_task_ran;
97 AtomicFlag second_main_thread_task_ran;
98 ThreadPool::PostTaskAndReply(
99 FROM_HERE,
100 BindOnce(&VerifyRunUntilIdleDidNotReturnAndSetFlag,
101 Unretained(&run_until_idle_returned),
102 Unretained(&second_thread_pool_task_ran)),
103 BindOnce(&VerifyRunUntilIdleDidNotReturnAndSetFlag,
104 Unretained(&run_until_idle_returned),
105 Unretained(&second_main_thread_task_ran)));
106
107 task_environment.RunUntilIdle();
108 run_until_idle_returned.Set();
109
110 EXPECT_TRUE(first_main_thread_task_ran.IsSet());
111 EXPECT_TRUE(first_thread_pool_task_ran.IsSet());
112 EXPECT_TRUE(second_thread_pool_task_ran.IsSet());
113 EXPECT_TRUE(second_main_thread_task_ran.IsSet());
114 }
115
116 } // namespace
117
TEST_F(TaskEnvironmentTest,QueuedRunUntilIdle)118 TEST_F(TaskEnvironmentTest, QueuedRunUntilIdle) {
119 RunUntilIdleTest(TaskEnvironment::ThreadPoolExecutionMode::QUEUED);
120 }
121
TEST_F(TaskEnvironmentTest,AsyncRunUntilIdle)122 TEST_F(TaskEnvironmentTest, AsyncRunUntilIdle) {
123 RunUntilIdleTest(TaskEnvironment::ThreadPoolExecutionMode::ASYNC);
124 }
125
126 // Verify that tasks posted to an ThreadPoolExecutionMode::QUEUED
127 // TaskEnvironment do not run outside of RunUntilIdle().
TEST_F(TaskEnvironmentTest,QueuedTasksDoNotRunOutsideOfRunUntilIdle)128 TEST_F(TaskEnvironmentTest, QueuedTasksDoNotRunOutsideOfRunUntilIdle) {
129 TaskEnvironment task_environment(
130 TaskEnvironment::ThreadPoolExecutionMode::QUEUED);
131
132 AtomicFlag run_until_idle_called;
133 ThreadPool::PostTask(FROM_HERE,
134 BindOnce(
135 [](AtomicFlag* run_until_idle_called) {
136 EXPECT_TRUE(run_until_idle_called->IsSet());
137 },
138 Unretained(&run_until_idle_called)));
139 PlatformThread::Sleep(TestTimeouts::tiny_timeout());
140 run_until_idle_called.Set();
141 task_environment.RunUntilIdle();
142
143 AtomicFlag other_run_until_idle_called;
144 ThreadPool::PostTask(FROM_HERE,
145 BindOnce(
146 [](AtomicFlag* other_run_until_idle_called) {
147 EXPECT_TRUE(other_run_until_idle_called->IsSet());
148 },
149 Unretained(&other_run_until_idle_called)));
150 PlatformThread::Sleep(TestTimeouts::tiny_timeout());
151 other_run_until_idle_called.Set();
152 task_environment.RunUntilIdle();
153 }
154
155 // Verify that a task posted to an ThreadPoolExecutionMode::ASYNC
156 // TaskEnvironment can run without a call to RunUntilIdle().
TEST_F(TaskEnvironmentTest,AsyncTasksRunAsTheyArePosted)157 TEST_F(TaskEnvironmentTest, AsyncTasksRunAsTheyArePosted) {
158 TaskEnvironment task_environment(
159 TaskEnvironment::ThreadPoolExecutionMode::ASYNC);
160
161 WaitableEvent task_ran;
162 ThreadPool::PostTask(FROM_HERE,
163 BindOnce(&WaitableEvent::Signal, Unretained(&task_ran)));
164 task_ran.Wait();
165 }
166
167 // Verify that a task posted to an ThreadPoolExecutionMode::ASYNC
168 // TaskEnvironment after a call to RunUntilIdle() can run without another
169 // call to RunUntilIdle().
TEST_F(TaskEnvironmentTest,AsyncTasksRunAsTheyArePostedAfterRunUntilIdle)170 TEST_F(TaskEnvironmentTest, AsyncTasksRunAsTheyArePostedAfterRunUntilIdle) {
171 TaskEnvironment task_environment(
172 TaskEnvironment::ThreadPoolExecutionMode::ASYNC);
173
174 task_environment.RunUntilIdle();
175
176 WaitableEvent task_ran;
177 ThreadPool::PostTask(FROM_HERE,
178 BindOnce(&WaitableEvent::Signal, Unretained(&task_ran)));
179 task_ran.Wait();
180 }
181
DelayedTasksTest(TaskEnvironment::TimeSource time_source)182 void DelayedTasksTest(TaskEnvironment::TimeSource time_source) {
183 // Use a QUEUED execution-mode environment, so that no tasks are actually
184 // executed until RunUntilIdle()/FastForwardBy() are invoked.
185 TaskEnvironment task_environment(
186 time_source, TaskEnvironment::ThreadPoolExecutionMode::QUEUED);
187
188 subtle::Atomic32 counter = 0;
189
190 constexpr base::TimeDelta kShortTaskDelay = Days(1);
191 // Should run only in MOCK_TIME environment when time is fast-forwarded.
192 SingleThreadTaskRunner::GetCurrentDefault()->PostDelayedTask(
193 FROM_HERE,
194 BindOnce(
195 [](subtle::Atomic32* counter) {
196 subtle::NoBarrier_AtomicIncrement(counter, 4);
197 },
198 Unretained(&counter)),
199 kShortTaskDelay);
200 ThreadPool::PostDelayedTask(FROM_HERE,
201 BindOnce(
202 [](subtle::Atomic32* counter) {
203 subtle::NoBarrier_AtomicIncrement(counter,
204 128);
205 },
206 Unretained(&counter)),
207 kShortTaskDelay);
208
209 constexpr base::TimeDelta kLongTaskDelay = Days(7);
210 // Same as first task, longer delays to exercise
211 // FastForwardUntilNoTasksRemain().
212 SingleThreadTaskRunner::GetCurrentDefault()->PostDelayedTask(
213 FROM_HERE,
214 BindOnce(
215 [](subtle::Atomic32* counter) {
216 subtle::NoBarrier_AtomicIncrement(counter, 8);
217 },
218 Unretained(&counter)),
219 Days(5));
220 SingleThreadTaskRunner::GetCurrentDefault()->PostDelayedTask(
221 FROM_HERE,
222 BindOnce(
223 [](subtle::Atomic32* counter) {
224 subtle::NoBarrier_AtomicIncrement(counter, 16);
225 },
226 Unretained(&counter)),
227 kLongTaskDelay);
228 ThreadPool::PostDelayedTask(FROM_HERE,
229 BindOnce(
230 [](subtle::Atomic32* counter) {
231 subtle::NoBarrier_AtomicIncrement(counter,
232 256);
233 },
234 Unretained(&counter)),
235 kLongTaskDelay * 2);
236 SingleThreadTaskRunner::GetCurrentDefault()->PostDelayedTask(
237 FROM_HERE,
238 BindOnce(
239 [](subtle::Atomic32* counter) {
240 subtle::NoBarrier_AtomicIncrement(counter, 512);
241 },
242 Unretained(&counter)),
243 kLongTaskDelay * 3);
244 ThreadPool::PostDelayedTask(FROM_HERE,
245 BindOnce(
246 [](subtle::Atomic32* counter) {
247 subtle::NoBarrier_AtomicIncrement(counter,
248 1024);
249 },
250 Unretained(&counter)),
251 kLongTaskDelay * 4);
252
253 SingleThreadTaskRunner::GetCurrentDefault()->PostTask(
254 FROM_HERE, BindOnce(
255 [](subtle::Atomic32* counter) {
256 subtle::NoBarrier_AtomicIncrement(counter, 1);
257 },
258 Unretained(&counter)));
259 ThreadPool::PostTask(FROM_HERE, BindOnce(
260 [](subtle::Atomic32* counter) {
261 subtle::NoBarrier_AtomicIncrement(
262 counter, 2);
263 },
264 Unretained(&counter)));
265
266 // This expectation will fail flakily if the preceding PostTask() is executed
267 // asynchronously, indicating a problem with the QUEUED execution mode.
268 int expected_value = 0;
269 EXPECT_EQ(expected_value, counter);
270
271 // RunUntilIdle() should process non-delayed tasks only in all queues.
272 task_environment.RunUntilIdle();
273 expected_value += 1;
274 expected_value += 2;
275 EXPECT_EQ(expected_value, counter);
276
277 if (time_source == TaskEnvironment::TimeSource::MOCK_TIME) {
278 const TimeTicks start_time = task_environment.NowTicks();
279 const LiveTicks live_start_time = task_environment.NowLiveTicks();
280
281 // Delay inferior to the delay of the first posted task.
282 constexpr base::TimeDelta kInferiorTaskDelay = Seconds(1);
283 static_assert(kInferiorTaskDelay < kShortTaskDelay,
284 "|kInferiorTaskDelay| should be "
285 "set to a value inferior to the first posted task's delay.");
286 task_environment.FastForwardBy(kInferiorTaskDelay);
287 EXPECT_EQ(expected_value, counter);
288 // Time advances to cap even if there was no task at cap and live ticks
289 // advances by the same amount.
290 EXPECT_EQ(task_environment.NowTicks() - start_time, kInferiorTaskDelay);
291 EXPECT_EQ(task_environment.NowLiveTicks() - live_start_time,
292 kInferiorTaskDelay);
293
294 task_environment.FastForwardBy(kShortTaskDelay - kInferiorTaskDelay);
295 expected_value += 4;
296 expected_value += 128;
297 EXPECT_EQ(expected_value, counter);
298 EXPECT_EQ(task_environment.NowTicks() - start_time, kShortTaskDelay);
299 EXPECT_EQ(task_environment.NowLiveTicks() - live_start_time,
300 kShortTaskDelay);
301
302 task_environment.FastForwardUntilNoTasksRemain();
303 expected_value += 8;
304 expected_value += 16;
305 expected_value += 256;
306 expected_value += 512;
307 expected_value += 1024;
308 EXPECT_EQ(expected_value, counter);
309 EXPECT_EQ(task_environment.NowTicks() - start_time, kLongTaskDelay * 4);
310 EXPECT_EQ(task_environment.NowLiveTicks() - live_start_time,
311 kLongTaskDelay * 4);
312 }
313 }
314
TEST_F(TaskEnvironmentTest,DelayedTasksUnderSystemTime)315 TEST_F(TaskEnvironmentTest, DelayedTasksUnderSystemTime) {
316 DelayedTasksTest(TaskEnvironment::TimeSource::SYSTEM_TIME);
317 }
318
TEST_F(TaskEnvironmentTest,DelayedTasksUnderMockTime)319 TEST_F(TaskEnvironmentTest, DelayedTasksUnderMockTime) {
320 DelayedTasksTest(TaskEnvironment::TimeSource::MOCK_TIME);
321 }
322
323 // Regression test for https://crbug.com/824770.
SupportsSequenceLocalStorageOnMainThreadTest(TaskEnvironment::TimeSource time_source)324 void SupportsSequenceLocalStorageOnMainThreadTest(
325 TaskEnvironment::TimeSource time_source) {
326 TaskEnvironment task_environment(
327 time_source, TaskEnvironment::ThreadPoolExecutionMode::ASYNC);
328
329 SequenceLocalStorageSlot<int> sls_slot;
330 sls_slot.emplace(5);
331 EXPECT_EQ(5, *sls_slot);
332 }
333
TEST_F(TaskEnvironmentTest,SupportsSequenceLocalStorageOnMainThread)334 TEST_F(TaskEnvironmentTest, SupportsSequenceLocalStorageOnMainThread) {
335 SupportsSequenceLocalStorageOnMainThreadTest(
336 TaskEnvironment::TimeSource::SYSTEM_TIME);
337 }
338
TEST_F(TaskEnvironmentTest,SupportsSequenceLocalStorageOnMainThreadWithMockTime)339 TEST_F(TaskEnvironmentTest,
340 SupportsSequenceLocalStorageOnMainThreadWithMockTime) {
341 SupportsSequenceLocalStorageOnMainThreadTest(
342 TaskEnvironment::TimeSource::MOCK_TIME);
343 }
344
345 // Verify that the right MessagePump is instantiated under each MainThreadType.
346 // This avoids having to run all other TaskEnvironmentTests in every
347 // MainThreadType which is redundant (message loop and message pump tests
348 // otherwise cover the advanced functionality provided by UI/IO pumps).
TEST_F(TaskEnvironmentTest,MainThreadType)349 TEST_F(TaskEnvironmentTest, MainThreadType) {
350 // Uses CurrentThread as a convenience accessor but could be replaced by
351 // different accessors when we get rid of CurrentThread.
352 EXPECT_FALSE(CurrentThread::IsSet());
353 EXPECT_FALSE(CurrentUIThread::IsSet());
354 EXPECT_FALSE(CurrentIOThread::IsSet());
355 {
356 TaskEnvironment task_environment;
357 EXPECT_TRUE(CurrentThread::IsSet());
358 EXPECT_FALSE(CurrentUIThread::IsSet());
359 EXPECT_FALSE(CurrentIOThread::IsSet());
360 }
361 {
362 TaskEnvironment task_environment(TaskEnvironment::MainThreadType::UI);
363 EXPECT_TRUE(CurrentThread::IsSet());
364 EXPECT_TRUE(CurrentUIThread::IsSet());
365 EXPECT_FALSE(CurrentIOThread::IsSet());
366 }
367 {
368 TaskEnvironment task_environment(TaskEnvironment::MainThreadType::IO);
369 EXPECT_TRUE(CurrentThread::IsSet());
370 EXPECT_FALSE(CurrentUIThread::IsSet());
371 EXPECT_TRUE(CurrentIOThread::IsSet());
372 }
373 EXPECT_FALSE(CurrentThread::IsSet());
374 EXPECT_FALSE(CurrentUIThread::IsSet());
375 EXPECT_FALSE(CurrentIOThread::IsSet());
376 }
377
378 #if BUILDFLAG(IS_POSIX)
TEST_F(TaskEnvironmentTest,SupportsFileDescriptorWatcherOnIOMainThread)379 TEST_F(TaskEnvironmentTest, SupportsFileDescriptorWatcherOnIOMainThread) {
380 TaskEnvironment task_environment(TaskEnvironment::MainThreadType::IO);
381
382 int pipe_fds_[2];
383 ASSERT_EQ(0, pipe(pipe_fds_));
384
385 RunLoop run_loop;
386
387 // The write end of a newly created pipe is immediately writable.
388 auto controller = FileDescriptorWatcher::WatchWritable(
389 pipe_fds_[1], run_loop.QuitClosure());
390
391 // This will hang if the notification doesn't occur as expected.
392 run_loop.Run();
393 }
394
TEST_F(TaskEnvironmentTest,SupportsFileDescriptorWatcherOnIOMockTimeMainThread)395 TEST_F(TaskEnvironmentTest,
396 SupportsFileDescriptorWatcherOnIOMockTimeMainThread) {
397 TaskEnvironment task_environment(TaskEnvironment::MainThreadType::IO,
398 TaskEnvironment::TimeSource::MOCK_TIME);
399
400 int pipe_fds_[2];
401 ASSERT_EQ(0, pipe(pipe_fds_));
402
403 RunLoop run_loop;
404
405 SingleThreadTaskRunner::GetCurrentDefault()->PostDelayedTask(
406 FROM_HERE, BindLambdaForTesting([&]() {
407 int64_t x = 1;
408 auto ret = write(pipe_fds_[1], &x, sizeof(x));
409 ASSERT_EQ(static_cast<size_t>(ret), sizeof(x));
410 }),
411 Hours(1));
412
413 auto controller = FileDescriptorWatcher::WatchReadable(
414 pipe_fds_[0], run_loop.QuitClosure());
415
416 // This will hang if the notification doesn't occur as expected (Run() should
417 // fast-forward-time when idle).
418 run_loop.Run();
419 }
420 #endif // BUILDFLAG(IS_POSIX)
421
TEST_F(TaskEnvironmentTest,MockTimeStartsWithWholeMilliseconds)422 TEST_F(TaskEnvironmentTest, MockTimeStartsWithWholeMilliseconds) {
423 TaskEnvironment task_environment(TaskEnvironment::TimeSource::MOCK_TIME);
424 const TickClock* mock_tick_clock = task_environment.GetMockTickClock();
425 const Clock* mock_clock = task_environment.GetMockClock();
426 EXPECT_TRUE(
427 (mock_tick_clock->NowTicks().since_origin() % Milliseconds(1)).is_zero());
428 // The Windows epoch has no submillisecond components, so any submillisecond
429 // components in `Time::Now()` will appear in their difference.
430 EXPECT_TRUE((mock_clock->Now().since_origin() % Milliseconds(1)).is_zero());
431 EXPECT_TRUE((Time::Now().since_origin() % Milliseconds(1)).is_zero());
432 EXPECT_TRUE((TimeTicks::Now().since_origin() % Milliseconds(1)).is_zero());
433 }
434
435 // Verify that the TickClock returned by
436 // |TaskEnvironment::GetMockTickClock| gets updated when the
437 // FastForward(By|UntilNoTasksRemain) functions are called.
TEST_F(TaskEnvironmentTest,FastForwardAdvancesTickClock)438 TEST_F(TaskEnvironmentTest, FastForwardAdvancesTickClock) {
439 // Use a QUEUED execution-mode environment, so that no tasks are actually
440 // executed until RunUntilIdle()/FastForwardBy() are invoked.
441 TaskEnvironment task_environment(
442 TaskEnvironment::TimeSource::MOCK_TIME,
443 TaskEnvironment::ThreadPoolExecutionMode::QUEUED);
444
445 constexpr base::TimeDelta kShortTaskDelay = Days(1);
446 SingleThreadTaskRunner::GetCurrentDefault()->PostDelayedTask(
447 FROM_HERE, base::DoNothing(), kShortTaskDelay);
448
449 constexpr base::TimeDelta kLongTaskDelay = Days(7);
450 SingleThreadTaskRunner::GetCurrentDefault()->PostDelayedTask(
451 FROM_HERE, base::DoNothing(), kLongTaskDelay);
452
453 const base::TickClock* tick_clock = task_environment.GetMockTickClock();
454 base::TimeTicks tick_clock_ref = tick_clock->NowTicks();
455
456 // Make sure that |FastForwardBy| advances the clock.
457 task_environment.FastForwardBy(kShortTaskDelay);
458 EXPECT_EQ(kShortTaskDelay, tick_clock->NowTicks() - tick_clock_ref);
459
460 // Make sure that |FastForwardUntilNoTasksRemain| advances the clock.
461 task_environment.FastForwardUntilNoTasksRemain();
462 EXPECT_EQ(kLongTaskDelay, tick_clock->NowTicks() - tick_clock_ref);
463
464 // Fast-forwarding to a time at which there's no tasks should also advance the
465 // clock.
466 task_environment.FastForwardBy(kLongTaskDelay);
467 EXPECT_EQ(kLongTaskDelay * 2, tick_clock->NowTicks() - tick_clock_ref);
468 }
469
TEST_F(TaskEnvironmentTest,FastForwardAdvancesMockClock)470 TEST_F(TaskEnvironmentTest, FastForwardAdvancesMockClock) {
471 constexpr base::TimeDelta kDelay = Seconds(42);
472 TaskEnvironment task_environment(TaskEnvironment::TimeSource::MOCK_TIME);
473
474 const Clock* clock = task_environment.GetMockClock();
475 const Time start_time = clock->Now();
476 task_environment.FastForwardBy(kDelay);
477
478 EXPECT_EQ(start_time + kDelay, clock->Now());
479 }
480
TEST_F(TaskEnvironmentTest,FastForwardAdvancesTime)481 TEST_F(TaskEnvironmentTest, FastForwardAdvancesTime) {
482 constexpr base::TimeDelta kDelay = Seconds(42);
483 TaskEnvironment task_environment(TaskEnvironment::TimeSource::MOCK_TIME);
484
485 const Time start_time = base::Time::Now();
486 task_environment.FastForwardBy(kDelay);
487 EXPECT_EQ(start_time + kDelay, base::Time::Now());
488 }
489
TEST_F(TaskEnvironmentTest,FastForwardAdvancesTimeTicks)490 TEST_F(TaskEnvironmentTest, FastForwardAdvancesTimeTicks) {
491 constexpr base::TimeDelta kDelay = Seconds(42);
492 TaskEnvironment task_environment(TaskEnvironment::TimeSource::MOCK_TIME);
493
494 const TimeTicks start_time = base::TimeTicks::Now();
495 task_environment.FastForwardBy(kDelay);
496 EXPECT_EQ(start_time + kDelay, base::TimeTicks::Now());
497 }
498
TEST_F(TaskEnvironmentTest,AdvanceClockAdvancesTickClock)499 TEST_F(TaskEnvironmentTest, AdvanceClockAdvancesTickClock) {
500 constexpr base::TimeDelta kDelay = Seconds(42);
501 TaskEnvironment task_environment(TaskEnvironment::TimeSource::MOCK_TIME);
502
503 const base::TickClock* tick_clock = task_environment.GetMockTickClock();
504 const base::TimeTicks start_time = tick_clock->NowTicks();
505 task_environment.AdvanceClock(kDelay);
506
507 EXPECT_EQ(start_time + kDelay, tick_clock->NowTicks());
508 }
509
TEST_F(TaskEnvironmentTest,AdvanceClockAdvancesMockClock)510 TEST_F(TaskEnvironmentTest, AdvanceClockAdvancesMockClock) {
511 constexpr base::TimeDelta kDelay = Seconds(42);
512 TaskEnvironment task_environment(TaskEnvironment::TimeSource::MOCK_TIME);
513
514 const Clock* clock = task_environment.GetMockClock();
515 const Time start_time = clock->Now();
516 task_environment.AdvanceClock(kDelay);
517
518 EXPECT_EQ(start_time + kDelay, clock->Now());
519 }
520
TEST_F(TaskEnvironmentTest,AdvanceClockAdvancesTime)521 TEST_F(TaskEnvironmentTest, AdvanceClockAdvancesTime) {
522 constexpr base::TimeDelta kDelay = Seconds(42);
523 TaskEnvironment task_environment(TaskEnvironment::TimeSource::MOCK_TIME);
524
525 const Time start_time = base::Time::Now();
526 task_environment.AdvanceClock(kDelay);
527 EXPECT_EQ(start_time + kDelay, base::Time::Now());
528 }
529
TEST_F(TaskEnvironmentTest,AdvanceClockAdvancesTimeTicks)530 TEST_F(TaskEnvironmentTest, AdvanceClockAdvancesTimeTicks) {
531 constexpr base::TimeDelta kDelay = Seconds(42);
532 TaskEnvironment task_environment(TaskEnvironment::TimeSource::MOCK_TIME);
533
534 const TimeTicks start_time = base::TimeTicks::Now();
535 task_environment.AdvanceClock(kDelay);
536 EXPECT_EQ(start_time + kDelay, base::TimeTicks::Now());
537 }
538
TEST_F(TaskEnvironmentTest,AdvanceClockAdvancesLiveTicks)539 TEST_F(TaskEnvironmentTest, AdvanceClockAdvancesLiveTicks) {
540 constexpr base::TimeDelta kDelay = Seconds(42);
541 TaskEnvironment task_environment(TaskEnvironment::TimeSource::MOCK_TIME);
542
543 const LiveTicks start_time = base::LiveTicks::Now();
544 task_environment.AdvanceClock(kDelay);
545 EXPECT_EQ(start_time + kDelay, base::LiveTicks::Now());
546 }
547
TEST_F(TaskEnvironmentTest,SuspendedAdvanceClockDoesntAdvanceLiveTicks)548 TEST_F(TaskEnvironmentTest, SuspendedAdvanceClockDoesntAdvanceLiveTicks) {
549 constexpr base::TimeDelta kDelay = Seconds(42);
550 TaskEnvironment task_environment(TaskEnvironment::TimeSource::MOCK_TIME);
551
552 const TimeTicks start_time = base::TimeTicks::Now();
553 const LiveTicks live_start_time = base::LiveTicks::Now();
554 task_environment.SuspendedAdvanceClock(kDelay);
555 EXPECT_EQ(live_start_time, base::LiveTicks::Now());
556 EXPECT_EQ(start_time + kDelay, base::TimeTicks::Now());
557 }
558
TEST_F(TaskEnvironmentTest,AdvanceClockDoesNotRunTasks)559 TEST_F(TaskEnvironmentTest, AdvanceClockDoesNotRunTasks) {
560 TaskEnvironment task_environment(TaskEnvironment::TimeSource::MOCK_TIME);
561
562 constexpr base::TimeDelta kTaskDelay = Days(1);
563 SingleThreadTaskRunner::GetCurrentDefault()->PostDelayedTask(
564 FROM_HERE, base::DoNothing(), kTaskDelay);
565
566 EXPECT_EQ(1U, task_environment.GetPendingMainThreadTaskCount());
567 EXPECT_TRUE(task_environment.NextTaskIsDelayed());
568
569 task_environment.AdvanceClock(kTaskDelay);
570
571 // The task is still pending, but is now runnable.
572 EXPECT_EQ(1U, task_environment.GetPendingMainThreadTaskCount());
573 EXPECT_FALSE(task_environment.NextTaskIsDelayed());
574 }
575
TEST_F(TaskEnvironmentTest,SuspendedAdvanceClockDoesNotRunTasks)576 TEST_F(TaskEnvironmentTest, SuspendedAdvanceClockDoesNotRunTasks) {
577 TaskEnvironment task_environment(TaskEnvironment::TimeSource::MOCK_TIME);
578
579 constexpr base::TimeDelta kTaskDelay = Days(1);
580 SingleThreadTaskRunner::GetCurrentDefault()->PostDelayedTask(
581 FROM_HERE, base::DoNothing(), kTaskDelay);
582
583 EXPECT_EQ(1U, task_environment.GetPendingMainThreadTaskCount());
584 EXPECT_TRUE(task_environment.NextTaskIsDelayed());
585
586 task_environment.SuspendedAdvanceClock(kTaskDelay);
587
588 // The task is still pending, but is now runnable.
589 EXPECT_EQ(1U, task_environment.GetPendingMainThreadTaskCount());
590 EXPECT_FALSE(task_environment.NextTaskIsDelayed());
591 }
592
TEST_F(TaskEnvironmentTest,AdvanceClockSchedulesRipeDelayedTasks)593 TEST_F(TaskEnvironmentTest, AdvanceClockSchedulesRipeDelayedTasks) {
594 TaskEnvironment task_environment(TaskEnvironment::TimeSource::MOCK_TIME);
595
596 bool ran = false;
597
598 constexpr base::TimeDelta kTaskDelay = Days(1);
599 ThreadPool::PostDelayedTask(
600 FROM_HERE, base::BindLambdaForTesting([&]() { ran = true; }), kTaskDelay);
601
602 task_environment.AdvanceClock(kTaskDelay);
603 EXPECT_FALSE(ran);
604 task_environment.RunUntilIdle();
605 EXPECT_TRUE(ran);
606 }
607
TEST_F(TaskEnvironmentTest,SuspendedAdvanceClockSchedulesRipeDelayedTasks)608 TEST_F(TaskEnvironmentTest, SuspendedAdvanceClockSchedulesRipeDelayedTasks) {
609 TaskEnvironment task_environment(TaskEnvironment::TimeSource::MOCK_TIME);
610
611 bool ran = false;
612
613 constexpr base::TimeDelta kTaskDelay = Days(1);
614 ThreadPool::PostDelayedTask(
615 FROM_HERE, base::BindLambdaForTesting([&]() { ran = true; }), kTaskDelay);
616
617 task_environment.SuspendedAdvanceClock(kTaskDelay);
618 EXPECT_FALSE(ran);
619 task_environment.RunUntilIdle();
620 EXPECT_TRUE(ran);
621 }
622
623 // Verify that FastForwardBy() runs existing immediate tasks before advancing,
624 // then advances to the next delayed task, runs it, then advances the remainder
625 // of time when out of tasks.
TEST_F(TaskEnvironmentTest,FastForwardOnlyAdvancesWhenIdle)626 TEST_F(TaskEnvironmentTest, FastForwardOnlyAdvancesWhenIdle) {
627 TaskEnvironment task_environment(TaskEnvironment::TimeSource::MOCK_TIME);
628
629 const TimeTicks start_time = base::TimeTicks::Now();
630
631 constexpr base::TimeDelta kDelay = Seconds(42);
632 constexpr base::TimeDelta kFastForwardUntil = Seconds(100);
633 SingleThreadTaskRunner::GetCurrentDefault()->PostTask(
634 FROM_HERE, BindLambdaForTesting(
635 [&]() { EXPECT_EQ(start_time, base::TimeTicks::Now()); }));
636 SingleThreadTaskRunner::GetCurrentDefault()->PostDelayedTask(
637 FROM_HERE, BindLambdaForTesting([&]() {
638 EXPECT_EQ(start_time + kDelay, base::TimeTicks::Now());
639 }),
640 kDelay);
641 task_environment.FastForwardBy(kFastForwardUntil);
642 EXPECT_EQ(start_time + kFastForwardUntil, base::TimeTicks::Now());
643 }
644
645 // Verify that SuspendedFastForwardBy() behaves as FastForwardBy() but doesn't
646 // advance `LiveTicks`
TEST_F(TaskEnvironmentTest,SuspendedFastForwardOnlyAdvancesWhenIdle)647 TEST_F(TaskEnvironmentTest, SuspendedFastForwardOnlyAdvancesWhenIdle) {
648 TaskEnvironment task_environment(TaskEnvironment::TimeSource::MOCK_TIME);
649
650 const TimeTicks start_time = base::TimeTicks::Now();
651 const LiveTicks live_start_time = base::LiveTicks::Now();
652
653 constexpr base::TimeDelta kDelay = Seconds(42);
654 constexpr base::TimeDelta kFastForwardUntil = Seconds(100);
655 SingleThreadTaskRunner::GetCurrentDefault()->PostTask(
656 FROM_HERE, BindLambdaForTesting([&]() {
657 EXPECT_EQ(start_time, base::TimeTicks::Now());
658 EXPECT_EQ(live_start_time, base::LiveTicks::Now());
659 }));
660 SingleThreadTaskRunner::GetCurrentDefault()->PostDelayedTask(
661 FROM_HERE, BindLambdaForTesting([&]() {
662 EXPECT_EQ(start_time + kDelay, base::TimeTicks::Now());
663 EXPECT_EQ(live_start_time, base::LiveTicks::Now());
664 }),
665 kDelay);
666 task_environment.SuspendedFastForwardBy(kFastForwardUntil);
667 EXPECT_EQ(start_time + kFastForwardUntil, base::TimeTicks::Now());
668 EXPECT_EQ(live_start_time, base::LiveTicks::Now());
669 }
670
671 // FastForwardBy(0) should be equivalent of RunUntilIdle().
TEST_F(TaskEnvironmentTest,FastForwardZero)672 TEST_F(TaskEnvironmentTest, FastForwardZero) {
673 TaskEnvironment task_environment(TaskEnvironment::TimeSource::MOCK_TIME);
674
675 std::atomic_int run_count{0};
676
677 for (int i = 0; i < 1000; ++i) {
678 SingleThreadTaskRunner::GetCurrentDefault()->PostTask(
679 FROM_HERE, BindLambdaForTesting([&]() {
680 run_count.fetch_add(1, std::memory_order_relaxed);
681 }));
682 ThreadPool::PostTask(FROM_HERE, BindLambdaForTesting([&]() {
683 run_count.fetch_add(1, std::memory_order_relaxed);
684 }));
685 }
686
687 task_environment.FastForwardBy(base::TimeDelta());
688
689 EXPECT_EQ(2000, run_count.load(std::memory_order_relaxed));
690 }
691
TEST_F(TaskEnvironmentTest,NestedFastForwardBy)692 TEST_F(TaskEnvironmentTest, NestedFastForwardBy) {
693 TaskEnvironment task_environment(TaskEnvironment::TimeSource::MOCK_TIME);
694
695 constexpr TimeDelta kDelayPerTask = Milliseconds(1);
696 const TimeTicks start_time = task_environment.NowTicks();
697 const LiveTicks live_start_time = task_environment.NowLiveTicks();
698
699 int max_nesting_level = 0;
700
701 RepeatingClosure post_fast_forwarding_task;
702 post_fast_forwarding_task = BindLambdaForTesting([&]() {
703 if (max_nesting_level < 5) {
704 ++max_nesting_level;
705 SingleThreadTaskRunner::GetCurrentDefault()->PostDelayedTask(
706 FROM_HERE, post_fast_forwarding_task, kDelayPerTask);
707 task_environment.FastForwardBy(kDelayPerTask);
708 }
709 });
710 post_fast_forwarding_task.Run();
711
712 EXPECT_EQ(max_nesting_level, 5);
713 EXPECT_EQ(task_environment.NowTicks(), start_time + kDelayPerTask * 5);
714 EXPECT_EQ(task_environment.NowLiveTicks(),
715 live_start_time + kDelayPerTask * 5);
716 }
717
TEST_F(TaskEnvironmentTest,NestedRunInFastForwardBy)718 TEST_F(TaskEnvironmentTest, NestedRunInFastForwardBy) {
719 TaskEnvironment task_environment(TaskEnvironment::TimeSource::MOCK_TIME);
720
721 constexpr TimeDelta kDelayPerTask = Milliseconds(1);
722 const TimeTicks start_time = task_environment.NowTicks();
723 const LiveTicks live_start_time = task_environment.NowLiveTicks();
724
725 std::vector<RunLoop*> run_loops;
726
727 RepeatingClosure post_and_runloop_task;
728 post_and_runloop_task = BindLambdaForTesting([&]() {
729 // Run 4 nested run loops on top of the initial FastForwardBy().
730 if (run_loops.size() < 4U) {
731 SingleThreadTaskRunner::GetCurrentDefault()->PostDelayedTask(
732 FROM_HERE, post_and_runloop_task, kDelayPerTask);
733
734 RunLoop run_loop(RunLoop::Type::kNestableTasksAllowed);
735 run_loops.push_back(&run_loop);
736 run_loop.Run();
737 } else {
738 for (RunLoop* run_loop : run_loops) {
739 run_loop->Quit();
740 }
741 }
742 });
743
744 // Initial task is FastForwardBy().
745 SingleThreadTaskRunner::GetCurrentDefault()->PostDelayedTask(
746 FROM_HERE, post_and_runloop_task, kDelayPerTask);
747 task_environment.FastForwardBy(kDelayPerTask);
748
749 EXPECT_EQ(run_loops.size(), 4U);
750 EXPECT_EQ(task_environment.NowTicks(), start_time + kDelayPerTask * 5);
751 EXPECT_EQ(task_environment.NowLiveTicks(),
752 live_start_time + kDelayPerTask * 5);
753 }
754
TEST_F(TaskEnvironmentTest,CrossThreadImmediateTaskPostingDoesntAffectMockTime)755 TEST_F(TaskEnvironmentTest,
756 CrossThreadImmediateTaskPostingDoesntAffectMockTime) {
757 TaskEnvironment task_environment(TaskEnvironment::TimeSource::MOCK_TIME);
758
759 int count = 0;
760
761 // Post tasks delayd between 0 and 999 seconds.
762 for (int i = 0; i < 1000; ++i) {
763 const TimeDelta delay = Seconds(i);
764 SingleThreadTaskRunner::GetCurrentDefault()->PostDelayedTask(
765 FROM_HERE,
766 BindOnce(
767 [](TimeTicks expected_run_time, int* count) {
768 EXPECT_EQ(expected_run_time, TimeTicks::Now());
769 ++*count;
770 },
771 TimeTicks::Now() + delay, &count),
772 delay);
773 }
774
775 // Having a bunch of tasks running in parallel and replying to the main thread
776 // shouldn't affect the rest of this test. Wait for the first task to run
777 // before proceeding with the test to increase the likelihood of exercising
778 // races.
779 base::WaitableEvent first_reply_is_incoming;
780 for (int i = 0; i < 1000; ++i) {
781 ThreadPool::PostTaskAndReply(
782 FROM_HERE,
783 BindOnce(&WaitableEvent::Signal, Unretained(&first_reply_is_incoming)),
784 DoNothing());
785 }
786 first_reply_is_incoming.Wait();
787
788 task_environment.FastForwardBy(Seconds(1000));
789
790 // If this test flakes it's because there's an error with MockTimeDomain.
791 EXPECT_EQ(count, 1000);
792
793 // Flush any remaining asynchronous tasks with Unretained() state.
794 task_environment.RunUntilIdle();
795 }
796
TEST_F(TaskEnvironmentTest,MultiThreadedMockTime)797 TEST_F(TaskEnvironmentTest, MultiThreadedMockTime) {
798 TaskEnvironment task_environment(TaskEnvironment::TimeSource::MOCK_TIME);
799
800 constexpr TimeDelta kOneMs = Milliseconds(1);
801 const TimeTicks start_time = task_environment.NowTicks();
802 const TimeTicks end_time = start_time + Milliseconds(1'000);
803
804 // Last TimeTicks::Now() seen from either contexts.
805 TimeTicks last_main_thread_ticks = start_time;
806 TimeTicks last_thread_pool_ticks = start_time;
807
808 RepeatingClosure post_main_thread_delayed_task;
809 post_main_thread_delayed_task = BindLambdaForTesting([&]() {
810 // Expect that time only moves forward.
811 EXPECT_GE(task_environment.NowTicks(), last_main_thread_ticks);
812
813 // Post four tasks to exercise the system some more but only if this is the
814 // first task at its runtime (otherwise we end up with 4^10'000 tasks by
815 // the end!).
816 if (last_main_thread_ticks < task_environment.NowTicks() &&
817 task_environment.NowTicks() < end_time) {
818 SequencedTaskRunner::GetCurrentDefault()->PostDelayedTask(
819 FROM_HERE, post_main_thread_delayed_task, kOneMs);
820 SequencedTaskRunner::GetCurrentDefault()->PostDelayedTask(
821 FROM_HERE, post_main_thread_delayed_task, kOneMs);
822 SequencedTaskRunner::GetCurrentDefault()->PostDelayedTask(
823 FROM_HERE, post_main_thread_delayed_task, kOneMs);
824 SequencedTaskRunner::GetCurrentDefault()->PostDelayedTask(
825 FROM_HERE, post_main_thread_delayed_task, kOneMs);
826 }
827
828 last_main_thread_ticks = task_environment.NowTicks();
829 });
830
831 RepeatingClosure post_thread_pool_delayed_task;
832 post_thread_pool_delayed_task = BindLambdaForTesting([&]() {
833 // Expect that time only moves forward.
834 EXPECT_GE(task_environment.NowTicks(), last_thread_pool_ticks);
835
836 // Post four tasks to exercise the system some more but only if this is the
837 // first task at its runtime (otherwise we end up with 4^10'000 tasks by
838 // the end!).
839 if (last_thread_pool_ticks < task_environment.NowTicks() &&
840 task_environment.NowTicks() < end_time) {
841 SequencedTaskRunner::GetCurrentDefault()->PostDelayedTask(
842 FROM_HERE, post_thread_pool_delayed_task, kOneMs);
843 SequencedTaskRunner::GetCurrentDefault()->PostDelayedTask(
844 FROM_HERE, post_thread_pool_delayed_task, kOneMs);
845 SequencedTaskRunner::GetCurrentDefault()->PostDelayedTask(
846 FROM_HERE, post_thread_pool_delayed_task, kOneMs);
847 SequencedTaskRunner::GetCurrentDefault()->PostDelayedTask(
848 FROM_HERE, post_thread_pool_delayed_task, kOneMs);
849
850 EXPECT_LT(task_environment.NowTicks(), end_time);
851 }
852
853 last_thread_pool_ticks = task_environment.NowTicks();
854 });
855
856 SingleThreadTaskRunner::GetCurrentDefault()->PostDelayedTask(
857 FROM_HERE, post_main_thread_delayed_task, kOneMs);
858 ThreadPool::CreateSequencedTaskRunner({})->PostDelayedTask(
859 FROM_HERE, post_thread_pool_delayed_task, kOneMs);
860
861 task_environment.FastForwardUntilNoTasksRemain();
862
863 EXPECT_EQ(last_main_thread_ticks, end_time);
864 EXPECT_EQ(last_thread_pool_ticks, end_time);
865 EXPECT_EQ(task_environment.NowTicks(), end_time);
866 }
867
868 // This test ensures the implementation of FastForwardBy() doesn't fast-forward
869 // beyond the cap it reaches idle with pending delayed tasks further ahead on
870 // the main thread.
TEST_F(TaskEnvironmentTest,MultiThreadedFastForwardBy)871 TEST_F(TaskEnvironmentTest, MultiThreadedFastForwardBy) {
872 TaskEnvironment task_environment(TaskEnvironment::TimeSource::MOCK_TIME);
873
874 const TimeTicks start_time = task_environment.NowTicks();
875 const LiveTicks live_start_time = task_environment.NowLiveTicks();
876
877 // The 1s delayed task in the pool should run but not the 5s delayed task on
878 // the main thread and fast-forward by should be capped at +2s.
879 SingleThreadTaskRunner::GetCurrentDefault()->PostDelayedTask(
880 FROM_HERE, MakeExpectedNotRunClosure(FROM_HERE), Seconds(5));
881 ThreadPool::PostDelayedTask(FROM_HERE, {}, MakeExpectedRunClosure(FROM_HERE),
882 Seconds(1));
883 task_environment.FastForwardBy(Seconds(2));
884
885 EXPECT_EQ(task_environment.NowTicks(), start_time + Seconds(2));
886 EXPECT_EQ(task_environment.NowLiveTicks(), live_start_time + Seconds(2));
887 }
888
889 // Verify that ThreadPoolExecutionMode::QUEUED doesn't prevent running tasks and
890 // advancing time on the main thread.
TEST_F(TaskEnvironmentTest,MultiThreadedMockTimeAndThreadPoolQueuedMode)891 TEST_F(TaskEnvironmentTest, MultiThreadedMockTimeAndThreadPoolQueuedMode) {
892 TaskEnvironment task_environment(
893 TaskEnvironment::TimeSource::MOCK_TIME,
894 TaskEnvironment::ThreadPoolExecutionMode::QUEUED);
895
896 // Atomic because it's updated from concurrent tasks in the ThreadPool
897 // (could use std::memory_order_releaxed on all accesses but keeping implicit
898 // operators because the test reads better that way).
899 std::atomic_int count = 0;
900 const TimeTicks start_time = task_environment.NowTicks();
901
902 RunLoop run_loop;
903
904 // Neither of these should run automatically per
905 // ThreadPoolExecutionMode::QUEUED.
906 ThreadPool::PostTask(FROM_HERE,
907 BindLambdaForTesting([&]() { count += 128; }));
908 ThreadPool::PostDelayedTask(
909 FROM_HERE, {}, BindLambdaForTesting([&]() { count += 256; }), Seconds(5));
910
911 // Time should auto-advance to +500s in RunLoop::Run() without having to run
912 // the above forcefully QUEUED tasks.
913 SingleThreadTaskRunner::GetCurrentDefault()->PostTask(
914 FROM_HERE, BindLambdaForTesting([&]() { count += 1; }));
915 SingleThreadTaskRunner::GetCurrentDefault()->PostDelayedTask(
916 FROM_HERE, BindLambdaForTesting([&]() {
917 count += 2;
918 run_loop.Quit();
919 }),
920 Seconds(500));
921
922 int expected_value = 0;
923 EXPECT_EQ(expected_value, count);
924 run_loop.Run();
925 expected_value += 1;
926 expected_value += 2;
927 EXPECT_EQ(expected_value, count);
928 EXPECT_EQ(task_environment.NowTicks() - start_time, Seconds(500));
929
930 // Fast-forward through all remaining tasks, this should unblock QUEUED tasks
931 // in the thread pool but shouldn't need to advance time to process them.
932 task_environment.FastForwardUntilNoTasksRemain();
933 expected_value += 128;
934 expected_value += 256;
935 EXPECT_EQ(expected_value, count);
936 EXPECT_EQ(task_environment.NowTicks() - start_time, Seconds(500));
937
938 // Test advancing time to a QUEUED task in the future.
939 ThreadPool::PostDelayedTask(
940 FROM_HERE, BindLambdaForTesting([&]() { count += 512; }), Seconds(5));
941 task_environment.FastForwardBy(Seconds(7));
942 expected_value += 512;
943 EXPECT_EQ(expected_value, count);
944 EXPECT_EQ(task_environment.NowTicks() - start_time, Seconds(507));
945
946 // Confirm that QUEUED mode is still active after the above fast forwarding
947 // (only the main thread task should run from RunLoop).
948 ThreadPool::PostTask(FROM_HERE,
949 BindLambdaForTesting([&]() { count += 1024; }));
950 SingleThreadTaskRunner::GetCurrentDefault()->PostTask(
951 FROM_HERE, BindLambdaForTesting([&]() { count += 2048; }));
952 PlatformThread::Sleep(Milliseconds(1));
953 RunLoop().RunUntilIdle();
954 expected_value += 2048;
955 EXPECT_EQ(expected_value, count);
956 EXPECT_EQ(task_environment.NowTicks() - start_time, Seconds(507));
957
958 // Run the remaining task to avoid use-after-free on |count| from
959 // ~TaskEnvironment().
960 task_environment.RunUntilIdle();
961 expected_value += 1024;
962 EXPECT_EQ(expected_value, count);
963 }
964
965 #if BUILDFLAG(IS_WIN)
966 // Regression test to ensure that TaskEnvironment enables the MTA in the
967 // thread pool (so that the test environment matches that of the browser process
968 // and com_init_util.h's assertions are happy in unit tests).
TEST_F(TaskEnvironmentTest,ThreadPoolPoolAllowsMTA)969 TEST_F(TaskEnvironmentTest, ThreadPoolPoolAllowsMTA) {
970 TaskEnvironment task_environment;
971 ThreadPool::PostTask(FROM_HERE, BindOnce(&win::AssertComApartmentType,
972 win::ComApartmentType::MTA));
973 task_environment.RunUntilIdle();
974 }
975 #endif // BUILDFLAG(IS_WIN)
976
TEST_F(TaskEnvironmentTest,SetsDefaultRunTimeout)977 TEST_F(TaskEnvironmentTest, SetsDefaultRunTimeout) {
978 const RunLoop::RunLoopTimeout* old_run_timeout =
979 ScopedRunLoopTimeout::GetTimeoutForCurrentThread();
980
981 {
982 TaskEnvironment task_environment;
983
984 // TaskEnvironment should set a default Run() timeout that fails the
985 // calling test (before test_launcher_timeout()).
986
987 const RunLoop::RunLoopTimeout* run_timeout =
988 ScopedRunLoopTimeout::GetTimeoutForCurrentThread();
989 EXPECT_NE(run_timeout, old_run_timeout);
990 EXPECT_TRUE(run_timeout);
991 if (!debug::BeingDebugged()) {
992 EXPECT_LT(run_timeout->timeout, TestTimeouts::test_launcher_timeout());
993 }
994 static auto& static_on_timeout_cb = run_timeout->on_timeout;
995 #if defined(__clang__) && defined(_MSC_VER)
996 EXPECT_NONFATAL_FAILURE(
997 static_on_timeout_cb.Run(FROM_HERE),
998 "RunLoop::Run() timed out. Timeout set at "
999 // We don't test the line number but it would be present.
1000 "TaskEnvironment@base\\test\\task_environment.cc:");
1001 #else
1002 EXPECT_NONFATAL_FAILURE(
1003 static_on_timeout_cb.Run(FROM_HERE),
1004 "RunLoop::Run() timed out. Timeout set at "
1005 // We don't test the line number but it would be present.
1006 "TaskEnvironment@base/test/task_environment.cc:");
1007 #endif
1008 }
1009
1010 EXPECT_EQ(ScopedRunLoopTimeout::GetTimeoutForCurrentThread(),
1011 old_run_timeout);
1012 }
1013
TEST_F(TaskEnvironmentTest,DescribeCurrentTasksHasPendingMainThreadTasks)1014 TEST_F(TaskEnvironmentTest, DescribeCurrentTasksHasPendingMainThreadTasks) {
1015 TaskEnvironment task_environment;
1016 SingleThreadTaskRunner::GetCurrentDefault()->PostTask(FROM_HERE, DoNothing());
1017
1018 test::MockLog mock_log;
1019 mock_log.StartCapturingLogs();
1020
1021 // Thread pool tasks (none here) are logged.
1022 EXPECT_CALL(mock_log, Log(::logging::LOG_INFO, _, _, _,
1023 HasSubstr("ThreadPool currently running tasks")))
1024 .WillOnce(Return(true));
1025 // The pending task posted above to the main thread is logged.
1026 EXPECT_CALL(mock_log, Log(::logging::LOG_INFO, _, _, _,
1027 HasSubstr("task_environment_unittest.cc")))
1028 .WillOnce(Return(true));
1029 task_environment.DescribeCurrentTasks();
1030
1031 task_environment.RunUntilIdle();
1032
1033 // Thread pool tasks (none here) are logged.
1034 EXPECT_CALL(mock_log, Log(::logging::LOG_INFO, _, _, _,
1035 HasSubstr("ThreadPool currently running tasks")))
1036 .WillOnce(Return(true));
1037 // Pending tasks (none left) are logged.
1038 EXPECT_CALL(mock_log, Log(::logging::LOG_INFO, _, _, _,
1039 HasSubstr("\"immediate_work_queue_size\":0")))
1040 .WillOnce(Return(true));
1041 task_environment.DescribeCurrentTasks();
1042 }
1043
TEST_F(TaskEnvironmentTest,DescribeCurrentTasksHasThreadPoolTasks)1044 TEST_F(TaskEnvironmentTest, DescribeCurrentTasksHasThreadPoolTasks) {
1045 TaskEnvironment task_environment;
1046
1047 // Let the test block until the thread pool task is running.
1048 base::WaitableEvent wait_for_thread_pool_task_start;
1049 // Let the thread pool task block until the test has a chance to see it
1050 // running.
1051 base::WaitableEvent block_thread_pool_task;
1052
1053 scoped_refptr<SequencedTaskRunner> thread_pool_task_runner =
1054 base::ThreadPool::CreateSequencedTaskRunner(
1055 {WithBaseSyncPrimitives(), TaskShutdownBehavior::SKIP_ON_SHUTDOWN});
1056 thread_pool_task_runner->PostTask(FROM_HERE, BindLambdaForTesting([&]() {
1057 // The test waits until this task is
1058 // running.
1059 wait_for_thread_pool_task_start.Signal();
1060 // Wait until the test is done with this
1061 // task.
1062 block_thread_pool_task.Wait();
1063 }));
1064 wait_for_thread_pool_task_start.Wait();
1065
1066 test::MockLog mock_log;
1067 mock_log.StartCapturingLogs();
1068
1069 // The pending task posted above is logged.
1070 EXPECT_CALL(mock_log, Log(::logging::LOG_INFO, _, _, _,
1071 HasSubstr("task_environment_unittest.cc")))
1072 .WillOnce(Return(true));
1073 // Pending tasks (none here) are logged.
1074 EXPECT_CALL(mock_log, Log(::logging::LOG_INFO, _, _, _,
1075 HasSubstr("\"immediate_work_queue_size\":0")))
1076 .WillOnce(Return(true));
1077 task_environment.DescribeCurrentTasks();
1078
1079 block_thread_pool_task.Signal();
1080 // Wait for the thread pool task to complete.
1081 task_environment.RunUntilIdle();
1082
1083 // The current thread pool tasks (none left) are logged.
1084 EXPECT_CALL(mock_log, Log(::logging::LOG_INFO, _, _, _,
1085 Not(HasSubstr("task_environment_unittest.cc"))))
1086 .WillOnce(Return(true));
1087 // Main thread pending tasks (none here) are logged.
1088 EXPECT_CALL(mock_log, Log(::logging::LOG_INFO, _, _, _,
1089 HasSubstr("\"immediate_work_queue_size\":0")))
1090 .WillOnce(Return(true));
1091 task_environment.DescribeCurrentTasks();
1092 }
1093
TEST_F(TaskEnvironmentTest,Basic)1094 TEST_F(TaskEnvironmentTest, Basic) {
1095 TaskEnvironment task_environment(
1096 TaskEnvironment::TimeSource::MOCK_TIME,
1097 TaskEnvironment::ThreadPoolExecutionMode::QUEUED);
1098
1099 int counter = 0;
1100
1101 SingleThreadTaskRunner::GetCurrentDefault()->PostTask(
1102 FROM_HERE,
1103 BindOnce([](int* counter) { *counter += 1; }, Unretained(&counter)));
1104 SingleThreadTaskRunner::GetCurrentDefault()->PostTask(
1105 FROM_HERE,
1106 BindOnce([](int* counter) { *counter += 32; }, Unretained(&counter)));
1107 SingleThreadTaskRunner::GetCurrentDefault()->PostDelayedTask(
1108 FROM_HERE,
1109 BindOnce([](int* counter) { *counter += 256; }, Unretained(&counter)),
1110 Seconds(3));
1111 SingleThreadTaskRunner::GetCurrentDefault()->PostDelayedTask(
1112 FROM_HERE,
1113 BindOnce([](int* counter) { *counter += 64; }, Unretained(&counter)),
1114 Seconds(1));
1115 SingleThreadTaskRunner::GetCurrentDefault()->PostDelayedTask(
1116 FROM_HERE,
1117 BindOnce([](int* counter) { *counter += 1024; }, Unretained(&counter)),
1118 Minutes(20));
1119 SingleThreadTaskRunner::GetCurrentDefault()->PostDelayedTask(
1120 FROM_HERE,
1121 BindOnce([](int* counter) { *counter += 4096; }, Unretained(&counter)),
1122 Days(20));
1123
1124 int expected_value = 0;
1125 EXPECT_EQ(expected_value, counter);
1126 task_environment.RunUntilIdle();
1127 expected_value += 1;
1128 expected_value += 32;
1129 EXPECT_EQ(expected_value, counter);
1130
1131 task_environment.RunUntilIdle();
1132 EXPECT_EQ(expected_value, counter);
1133
1134 task_environment.FastForwardBy(Seconds(1));
1135 expected_value += 64;
1136 EXPECT_EQ(expected_value, counter);
1137
1138 task_environment.FastForwardBy(Seconds(5));
1139 expected_value += 256;
1140 EXPECT_EQ(expected_value, counter);
1141
1142 task_environment.FastForwardUntilNoTasksRemain();
1143 expected_value += 1024;
1144 expected_value += 4096;
1145 EXPECT_EQ(expected_value, counter);
1146 }
1147
TEST_F(TaskEnvironmentTest,RunLoopDriveable)1148 TEST_F(TaskEnvironmentTest, RunLoopDriveable) {
1149 TaskEnvironment task_environment(
1150 TaskEnvironment::TimeSource::MOCK_TIME,
1151 TaskEnvironment::ThreadPoolExecutionMode::QUEUED);
1152
1153 int counter = 0;
1154 SingleThreadTaskRunner::GetCurrentDefault()->PostTask(
1155 FROM_HERE, base::BindOnce([](int* counter) { *counter += 1; },
1156 Unretained(&counter)));
1157 SingleThreadTaskRunner::GetCurrentDefault()->PostTask(
1158 FROM_HERE, base::BindOnce([](int* counter) { *counter += 32; },
1159 Unretained(&counter)));
1160 SingleThreadTaskRunner::GetCurrentDefault()->PostDelayedTask(
1161 FROM_HERE,
1162 base::BindOnce([](int* counter) { *counter += 256; },
1163 Unretained(&counter)),
1164 Seconds(3));
1165 SingleThreadTaskRunner::GetCurrentDefault()->PostDelayedTask(
1166 FROM_HERE,
1167 base::BindOnce([](int* counter) { *counter += 64; },
1168 Unretained(&counter)),
1169 Seconds(1));
1170 SingleThreadTaskRunner::GetCurrentDefault()->PostDelayedTask(
1171 FROM_HERE,
1172 base::BindOnce([](int* counter) { *counter += 1024; },
1173 Unretained(&counter)),
1174 Minutes(20));
1175 SingleThreadTaskRunner::GetCurrentDefault()->PostDelayedTask(
1176 FROM_HERE,
1177 base::BindOnce([](int* counter) { *counter += 4096; },
1178 Unretained(&counter)),
1179 Days(20));
1180
1181 int expected_value = 0;
1182 EXPECT_EQ(expected_value, counter);
1183 RunLoop().RunUntilIdle();
1184 expected_value += 1;
1185 expected_value += 32;
1186 EXPECT_EQ(expected_value, counter);
1187
1188 RunLoop().RunUntilIdle();
1189 EXPECT_EQ(expected_value, counter);
1190
1191 {
1192 RunLoop run_loop;
1193 SingleThreadTaskRunner::GetCurrentDefault()->PostDelayedTask(
1194 FROM_HERE, run_loop.QuitClosure(), Seconds(1));
1195 SingleThreadTaskRunner::GetCurrentDefault()->PostDelayedTask(
1196 FROM_HERE,
1197 base::BindOnce([](int* counter) { *counter += 8192; },
1198 Unretained(&counter)),
1199 Seconds(1));
1200
1201 // The QuitClosure() should be ordered between the 64 and the 8192
1202 // increments and should preempt the latter.
1203 run_loop.Run();
1204 expected_value += 64;
1205 EXPECT_EQ(expected_value, counter);
1206
1207 // Running until idle should process the 8192 increment whose delay has
1208 // expired in the previous Run().
1209 RunLoop().RunUntilIdle();
1210 expected_value += 8192;
1211 EXPECT_EQ(expected_value, counter);
1212 }
1213
1214 {
1215 RunLoop run_loop;
1216 SingleThreadTaskRunner::GetCurrentDefault()->PostDelayedTask(
1217 FROM_HERE, run_loop.QuitWhenIdleClosure(), Seconds(5));
1218 SingleThreadTaskRunner::GetCurrentDefault()->PostDelayedTask(
1219 FROM_HERE,
1220 base::BindOnce([](int* counter) { *counter += 16384; },
1221 Unretained(&counter)),
1222 Seconds(5));
1223
1224 // The QuitWhenIdleClosure() shouldn't preempt equally delayed tasks and as
1225 // such the 16384 increment should be processed before quitting.
1226 run_loop.Run();
1227 expected_value += 256;
1228 expected_value += 16384;
1229 EXPECT_EQ(expected_value, counter);
1230 }
1231
1232 // Process the remaining tasks (note: do not mimic this elsewhere,
1233 // TestMockTimeTaskRunner::FastForwardUntilNoTasksRemain() is a better API to
1234 // do this, this is just done here for the purpose of extensively testing the
1235 // RunLoop approach).
1236
1237 // Disable Run() timeout here, otherwise we'll fast-forward to it before we
1238 // reach the quit task.
1239 ScopedDisableRunLoopTimeout disable_timeout;
1240
1241 RunLoop run_loop;
1242 SingleThreadTaskRunner::GetCurrentDefault()->PostDelayedTask(
1243 FROM_HERE, run_loop.QuitWhenIdleClosure(), Days(50));
1244
1245 run_loop.Run();
1246 expected_value += 1024;
1247 expected_value += 4096;
1248 EXPECT_EQ(expected_value, counter);
1249 }
1250
1251 // Regression test for crbug.com/1263149
TEST_F(TaskEnvironmentTest,RunLoopGetsTurnAfterYieldingToPool)1252 TEST_F(TaskEnvironmentTest, RunLoopGetsTurnAfterYieldingToPool) {
1253 TaskEnvironment task_environment(TaskEnvironment::TimeSource::MOCK_TIME);
1254
1255 base::RunLoop run_loop;
1256 SingleThreadTaskRunner::GetCurrentDefault()->PostDelayedTask(
1257 FROM_HERE, run_loop.QuitClosure(), base::Seconds(1));
1258 ThreadPool::PostTask(FROM_HERE, base::DoNothing());
1259
1260 run_loop.Run();
1261 }
1262
1263 // Regression test for crbug.com/1263149#c4
TEST_F(TaskEnvironmentTest,ThreadPoolAdvancesTimeUnderIdleMainThread)1264 TEST_F(TaskEnvironmentTest, ThreadPoolAdvancesTimeUnderIdleMainThread) {
1265 TaskEnvironment task_environment(TaskEnvironment::TimeSource::MOCK_TIME);
1266
1267 base::RunLoop run_loop;
1268 ThreadPool::PostDelayedTask(FROM_HERE, base::DoNothing(), base::Seconds(1));
1269 ThreadPool::PostDelayedTask(FROM_HERE, run_loop.QuitClosure(),
1270 base::Seconds(2));
1271
1272 run_loop.Run();
1273 }
1274
1275 // Regression test for
1276 // https://chromium-review.googlesource.com/c/chromium/src/+/3255105/5 which
1277 // incorrectly tried to address crbug.com/1263149 with
1278 // ThreadPool::FlushForTesting(), stalling thread pool tasks that need main
1279 // thread collaboration.
TEST_F(TaskEnvironmentTest,MainThreadCanContributeWhileFlushingPool)1280 TEST_F(TaskEnvironmentTest, MainThreadCanContributeWhileFlushingPool) {
1281 TaskEnvironment task_environment(TaskEnvironment::TimeSource::MOCK_TIME);
1282
1283 base::RunLoop run_loop;
1284 SingleThreadTaskRunner::GetCurrentDefault()->PostDelayedTask(
1285 FROM_HERE, run_loop.QuitClosure(), base::Seconds(1));
1286 TestWaitableEvent wait_for_collaboration;
1287 ThreadPool::PostTask(FROM_HERE, BindLambdaForTesting([&]() {
1288 task_environment.GetMainThreadTaskRunner()->PostTask(
1289 FROM_HERE,
1290 BindOnce(&TestWaitableEvent::Signal,
1291 Unretained(&wait_for_collaboration)));
1292 wait_for_collaboration.Wait();
1293 }));
1294
1295 run_loop.Run();
1296 }
1297
TEST_F(TaskEnvironmentTest,CancelPendingTask)1298 TEST_F(TaskEnvironmentTest, CancelPendingTask) {
1299 TaskEnvironment task_environment(
1300 TaskEnvironment::TimeSource::MOCK_TIME,
1301 TaskEnvironment::ThreadPoolExecutionMode::QUEUED);
1302
1303 CancelableOnceClosure task1(BindOnce([]() {}));
1304 SingleThreadTaskRunner::GetCurrentDefault()->PostDelayedTask(
1305 FROM_HERE, task1.callback(), Seconds(1));
1306 EXPECT_TRUE(task_environment.MainThreadIsIdle());
1307 EXPECT_EQ(1u, task_environment.GetPendingMainThreadTaskCount());
1308 EXPECT_EQ(Seconds(1), task_environment.NextMainThreadPendingTaskDelay());
1309 EXPECT_TRUE(task_environment.MainThreadIsIdle());
1310 task1.Cancel();
1311 EXPECT_TRUE(task_environment.MainThreadIsIdle());
1312 EXPECT_EQ(TimeDelta::Max(),
1313 task_environment.NextMainThreadPendingTaskDelay());
1314
1315 CancelableRepeatingClosure task2(BindRepeating([]() {}));
1316 SingleThreadTaskRunner::GetCurrentDefault()->PostDelayedTask(
1317 FROM_HERE, task2.callback(), Seconds(1));
1318 task2.Cancel();
1319 EXPECT_EQ(0u, task_environment.GetPendingMainThreadTaskCount());
1320
1321 CancelableRepeatingClosure task3(BindRepeating([]() {}));
1322 SingleThreadTaskRunner::GetCurrentDefault()->PostDelayedTask(
1323 FROM_HERE, task3.callback(), Seconds(1));
1324 task3.Cancel();
1325 EXPECT_EQ(TimeDelta::Max(),
1326 task_environment.NextMainThreadPendingTaskDelay());
1327
1328 CancelableRepeatingClosure task4(BindRepeating([]() {}));
1329 SingleThreadTaskRunner::GetCurrentDefault()->PostDelayedTask(
1330 FROM_HERE, task4.callback(), Seconds(1));
1331 task4.Cancel();
1332 EXPECT_TRUE(task_environment.MainThreadIsIdle());
1333 }
1334
TEST_F(TaskEnvironmentTest,CancelPendingImmediateTask)1335 TEST_F(TaskEnvironmentTest, CancelPendingImmediateTask) {
1336 TaskEnvironment task_environment(TaskEnvironment::TimeSource::MOCK_TIME);
1337 EXPECT_TRUE(task_environment.MainThreadIsIdle());
1338
1339 CancelableOnceClosure task1(BindOnce([]() {}));
1340 SingleThreadTaskRunner::GetCurrentDefault()->PostTask(FROM_HERE,
1341 task1.callback());
1342 EXPECT_FALSE(task_environment.MainThreadIsIdle());
1343
1344 task1.Cancel();
1345 EXPECT_TRUE(task_environment.MainThreadIsIdle());
1346 }
1347
TEST_F(TaskEnvironmentTest,NoFastForwardToCancelledTask)1348 TEST_F(TaskEnvironmentTest, NoFastForwardToCancelledTask) {
1349 TaskEnvironment task_environment(
1350 TaskEnvironment::TimeSource::MOCK_TIME,
1351 TaskEnvironment::ThreadPoolExecutionMode::QUEUED);
1352
1353 TimeTicks start_time = task_environment.NowTicks();
1354 CancelableRepeatingClosure task(BindRepeating([]() {}));
1355 SingleThreadTaskRunner::GetCurrentDefault()->PostDelayedTask(
1356 FROM_HERE, task.callback(), Seconds(1));
1357 EXPECT_EQ(Seconds(1), task_environment.NextMainThreadPendingTaskDelay());
1358 task.Cancel();
1359 task_environment.FastForwardUntilNoTasksRemain();
1360 EXPECT_EQ(start_time, task_environment.NowTicks());
1361 }
1362
TEST_F(TaskEnvironmentTest,NextTaskIsDelayed)1363 TEST_F(TaskEnvironmentTest, NextTaskIsDelayed) {
1364 TaskEnvironment task_environment(TaskEnvironment::TimeSource::MOCK_TIME);
1365
1366 EXPECT_FALSE(task_environment.NextTaskIsDelayed());
1367 CancelableRepeatingClosure task(BindRepeating([]() {}));
1368 SingleThreadTaskRunner::GetCurrentDefault()->PostDelayedTask(
1369 FROM_HERE, task.callback(), Seconds(1));
1370 EXPECT_TRUE(task_environment.NextTaskIsDelayed());
1371 task.Cancel();
1372 EXPECT_FALSE(task_environment.NextTaskIsDelayed());
1373
1374 SingleThreadTaskRunner::GetCurrentDefault()->PostDelayedTask(
1375 FROM_HERE, BindOnce([]() {}), Seconds(2));
1376 EXPECT_TRUE(task_environment.NextTaskIsDelayed());
1377 task_environment.FastForwardUntilNoTasksRemain();
1378 EXPECT_FALSE(task_environment.NextTaskIsDelayed());
1379
1380 SingleThreadTaskRunner::GetCurrentDefault()->PostTask(FROM_HERE,
1381 BindOnce([]() {}));
1382 EXPECT_FALSE(task_environment.NextTaskIsDelayed());
1383 }
1384
TEST_F(TaskEnvironmentTest,NextMainThreadPendingTaskDelayWithImmediateTask)1385 TEST_F(TaskEnvironmentTest, NextMainThreadPendingTaskDelayWithImmediateTask) {
1386 TaskEnvironment task_environment(TaskEnvironment::TimeSource::MOCK_TIME);
1387
1388 EXPECT_EQ(TimeDelta::Max(),
1389 task_environment.NextMainThreadPendingTaskDelay());
1390 SingleThreadTaskRunner::GetCurrentDefault()->PostTask(FROM_HERE,
1391 BindOnce([]() {}));
1392 EXPECT_EQ(TimeDelta(), task_environment.NextMainThreadPendingTaskDelay());
1393 }
1394
TEST_F(TaskEnvironmentTest,TimeSourceMockTimeAlsoMocksNow)1395 TEST_F(TaskEnvironmentTest, TimeSourceMockTimeAlsoMocksNow) {
1396 TaskEnvironment task_environment(TaskEnvironment::TimeSource::MOCK_TIME);
1397
1398 const TimeTicks start_ticks = task_environment.NowTicks();
1399 EXPECT_EQ(TimeTicks::Now(), start_ticks);
1400
1401 const Time start_time = Time::Now();
1402
1403 const LiveTicks start_live_ticks = task_environment.NowLiveTicks();
1404 EXPECT_EQ(LiveTicks::Now(), start_live_ticks);
1405
1406 constexpr TimeDelta kDelay = Seconds(10);
1407 task_environment.FastForwardBy(kDelay);
1408 EXPECT_EQ(TimeTicks::Now(), start_ticks + kDelay);
1409 EXPECT_EQ(Time::Now(), start_time + kDelay);
1410 EXPECT_EQ(LiveTicks::Now(), start_live_ticks + kDelay);
1411 }
1412
TEST_F(TaskEnvironmentTest,SingleThread)1413 TEST_F(TaskEnvironmentTest, SingleThread) {
1414 SingleThreadTaskEnvironment task_environment;
1415 EXPECT_THAT(ThreadPoolInstance::Get(), IsNull());
1416
1417 bool ran = false;
1418 SingleThreadTaskRunner::GetCurrentDefault()->PostTask(
1419 FROM_HERE, base::BindLambdaForTesting([&]() { ran = true; }));
1420 RunLoop().RunUntilIdle();
1421 EXPECT_TRUE(ran);
1422
1423 EXPECT_DCHECK_DEATH(ThreadPool::PostTask(FROM_HERE, {}, DoNothing()));
1424 }
1425
1426 // Verify that traits other than ThreadingMode can be applied to
1427 // SingleThreadTaskEnvironment.
TEST_F(TaskEnvironmentTest,SingleThreadMockTime)1428 TEST_F(TaskEnvironmentTest, SingleThreadMockTime) {
1429 SingleThreadTaskEnvironment task_environment(
1430 TaskEnvironment::TimeSource::MOCK_TIME);
1431
1432 const TimeTicks start_time = TimeTicks::Now();
1433
1434 constexpr TimeDelta kDelay = Seconds(100);
1435
1436 int counter = 0;
1437 SingleThreadTaskRunner::GetCurrentDefault()->PostDelayedTask(
1438 FROM_HERE, base::BindLambdaForTesting([&]() { counter += 1; }), kDelay);
1439 SingleThreadTaskRunner::GetCurrentDefault()->PostTask(
1440 FROM_HERE, base::BindLambdaForTesting([&]() { counter += 2; }));
1441
1442 int expected_value = 0;
1443 EXPECT_EQ(expected_value, counter);
1444
1445 task_environment.RunUntilIdle();
1446 expected_value += 2;
1447 EXPECT_EQ(expected_value, counter);
1448
1449 task_environment.FastForwardUntilNoTasksRemain();
1450 expected_value += 1;
1451 EXPECT_EQ(expected_value, counter);
1452 EXPECT_EQ(TimeTicks::Now(), start_time + kDelay);
1453 }
1454
1455 #if BUILDFLAG(IS_WIN)
1456 namespace {
1457
1458 enum class ApartmentType {
1459 kSTA,
1460 kMTA,
1461 };
1462
InitializeSTAApartment()1463 void InitializeSTAApartment() {
1464 base::win::ScopedCOMInitializer initializer;
1465 EXPECT_TRUE(initializer.Succeeded());
1466 }
1467
InitializeMTAApartment()1468 void InitializeMTAApartment() {
1469 base::win::ScopedCOMInitializer initializer(
1470 base::win::ScopedCOMInitializer::kMTA);
1471 EXPECT_TRUE(initializer.Succeeded());
1472 }
1473
InitializeCOMOnWorker(TaskEnvironment::ThreadPoolCOMEnvironment com_environment,ApartmentType apartment_type)1474 void InitializeCOMOnWorker(
1475 TaskEnvironment::ThreadPoolCOMEnvironment com_environment,
1476 ApartmentType apartment_type) {
1477 TaskEnvironment task_environment(com_environment);
1478 ThreadPool::PostTask(FROM_HERE, BindOnce(apartment_type == ApartmentType::kSTA
1479 ? &InitializeSTAApartment
1480 : &InitializeMTAApartment));
1481 task_environment.RunUntilIdle();
1482 }
1483
1484 } // namespace
1485
TEST_F(TaskEnvironmentTest,DefaultCOMEnvironment)1486 TEST_F(TaskEnvironmentTest, DefaultCOMEnvironment) {
1487 // Attempt to initialize an MTA COM apartment. Expect this to succeed since
1488 // the thread is already in an MTA apartment.
1489 InitializeCOMOnWorker(TaskEnvironment::ThreadPoolCOMEnvironment::DEFAULT,
1490 ApartmentType::kMTA);
1491
1492 // Attempt to initialize an STA COM apartment. Expect this to fail since the
1493 // thread is already in an MTA apartment.
1494 EXPECT_DCHECK_DEATH(InitializeCOMOnWorker(
1495 TaskEnvironment::ThreadPoolCOMEnvironment::DEFAULT, ApartmentType::kSTA));
1496 }
1497
TEST_F(TaskEnvironmentTest,NoCOMEnvironment)1498 TEST_F(TaskEnvironmentTest, NoCOMEnvironment) {
1499 // Attempt to initialize both MTA and STA COM apartments. Both should succeed
1500 // when the thread is not already in an apartment.
1501 InitializeCOMOnWorker(TaskEnvironment::ThreadPoolCOMEnvironment::NONE,
1502 ApartmentType::kMTA);
1503 InitializeCOMOnWorker(TaskEnvironment::ThreadPoolCOMEnvironment::NONE,
1504 ApartmentType::kSTA);
1505 }
1506 #endif // BUILDFLAG(IS_WIN)
1507
1508 // TODO(crbug.com/1318840): Re-enable this test
1509 #if BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_LINUX)
1510 #define MAYBE_ParallelExecutionFence DISABLED_ParallelExecutionFence
1511 #else
1512 #define MAYBE_ParallelExecutionFence ParallelExecutionFence
1513 #endif
TEST_F(TaskEnvironmentTest,MAYBE_ParallelExecutionFence)1514 TEST_F(TaskEnvironmentTest, MAYBE_ParallelExecutionFence) {
1515 TaskEnvironment task_environment;
1516
1517 constexpr int kNumParallelTasks =
1518 TaskEnvironment::kNumForegroundThreadPoolThreads;
1519
1520 TestWaitableEvent resume_main_thread;
1521 TestWaitableEvent all_runs_done;
1522 // Counters, all accessed/modified with memory_order_relaxed as no memory
1523 // ordering is necessary between operations.
1524 std::atomic_int completed_runs{0};
1525 std::atomic_int next_run{1};
1526
1527 // Each task will repost itself until run 500. Run #50 will signal
1528 // |resume_main_thread|.
1529 RepeatingClosure task = BindLambdaForTesting([&]() {
1530 int this_run = next_run.fetch_add(1, std::memory_order_relaxed);
1531
1532 if (this_run == 50) {
1533 resume_main_thread.Signal();
1534 }
1535
1536 // Sleep after signaling to increase the likelihood the main thread installs
1537 // the fence during this run and must wait on this task.
1538 if (this_run >= 50 && this_run < 50 + kNumParallelTasks) {
1539 PlatformThread::Sleep(Milliseconds(5));
1540 }
1541
1542 // Repost self until the last kNumParallelTasks.
1543 if (this_run <= 500 - kNumParallelTasks) {
1544 ThreadPool::PostTask(task);
1545 }
1546
1547 completed_runs.fetch_add(1, std::memory_order_relaxed);
1548
1549 if (this_run == 500) {
1550 all_runs_done.Signal();
1551 }
1552 });
1553 for (int i = 0; i < kNumParallelTasks; ++i) {
1554 ThreadPool::PostTask(task);
1555 }
1556
1557 resume_main_thread.Wait();
1558 ASSERT_GE(next_run.load(std::memory_order_relaxed), 50);
1559
1560 {
1561 // Confirm that no run happens while the fence is up.
1562 TaskEnvironment::ParallelExecutionFence fence;
1563
1564 // All runs are complete.
1565 const int completed_runs1 = completed_runs.load(std::memory_order_relaxed);
1566 const int next_run1 = next_run.load(std::memory_order_relaxed);
1567 EXPECT_EQ(completed_runs1, next_run1 - 1);
1568
1569 // Given a bit more time, no additional run starts nor completes.
1570 PlatformThread::Sleep(Milliseconds(30));
1571 const int completed_runs2 = completed_runs.load(std::memory_order_relaxed);
1572 const int next_run2 = next_run.load(std::memory_order_relaxed);
1573 EXPECT_EQ(completed_runs1, completed_runs2);
1574 EXPECT_EQ(next_run1, next_run2);
1575 }
1576
1577 // Runs resume automatically after taking down the fence (without needing to
1578 // call RunUntilIdle()).
1579 all_runs_done.Wait();
1580 ASSERT_EQ(completed_runs.load(std::memory_order_relaxed), 500);
1581 ASSERT_EQ(next_run.load(std::memory_order_relaxed), 501);
1582 }
1583
TEST_F(TaskEnvironmentTest,ParallelExecutionFenceWithoutTaskEnvironment)1584 TEST_F(TaskEnvironmentTest, ParallelExecutionFenceWithoutTaskEnvironment) {
1585 // Noops (doesn't crash) without a TaskEnvironment.
1586 TaskEnvironment::ParallelExecutionFence fence;
1587 }
1588
TEST_F(TaskEnvironmentTest,ParallelExecutionFenceWithSingleThreadTaskEnvironment)1589 TEST_F(TaskEnvironmentTest,
1590 ParallelExecutionFenceWithSingleThreadTaskEnvironment) {
1591 SingleThreadTaskEnvironment task_environment;
1592 // Noops (doesn't crash), with a SingleThreadTaskEnvironment/
1593 TaskEnvironment::ParallelExecutionFence fence;
1594 }
1595
1596 // Android doesn't support death tests, see base/test/gtest_util.h
1597 #if !BUILDFLAG(IS_ANDROID)
TEST_F(TaskEnvironmentTest,ParallelExecutionFenceNonMainThreadDeath)1598 TEST_F(TaskEnvironmentTest, ParallelExecutionFenceNonMainThreadDeath) {
1599 TaskEnvironment task_environment;
1600
1601 ThreadPool::PostTask(BindOnce([]() {
1602 #if CHECK_WILL_STREAM()
1603 const char kFailureLog[] = "ParallelExecutionFence invoked from worker";
1604 #else
1605 const char kFailureLog[] = "";
1606 #endif
1607 EXPECT_DEATH_IF_SUPPORTED(
1608 { TaskEnvironment::ParallelExecutionFence fence(kFailureLog); },
1609 kFailureLog);
1610 }));
1611
1612 task_environment.RunUntilIdle();
1613 }
1614 #endif // !BUILDFLAG(IS_ANDROID)
1615
1616 namespace {
FailOnTaskEnvironmentLog(int severity,const char * file,int line,size_t message_start,const std::string & str)1617 bool FailOnTaskEnvironmentLog(int severity,
1618 const char* file,
1619 int line,
1620 size_t message_start,
1621 const std::string& str) {
1622 StringPiece file_str(file);
1623 if (file_str.find("task_environment.cc") != StringPiece::npos) {
1624 ADD_FAILURE() << str;
1625 return true;
1626 }
1627 return false;
1628 }
1629 } // namespace
1630
1631 // Regression test for crbug.com/1293931
TEST_F(TaskEnvironmentTest,DisallowRunTasksRetriesForFullTimeout)1632 TEST_F(TaskEnvironmentTest, DisallowRunTasksRetriesForFullTimeout) {
1633 TaskEnvironment task_environment;
1634
1635 // Verify that steps below can let 1 second pass without generating logs.
1636 auto previous_handler = logging::GetLogMessageHandler();
1637 logging::SetLogMessageHandler(&FailOnTaskEnvironmentLog);
1638
1639 TestWaitableEvent worker_running;
1640 TestWaitableEvent resume_worker_task;
1641
1642 ThreadPool::PostTask(BindLambdaForTesting([&]() {
1643 worker_running.Signal();
1644 resume_worker_task.Wait();
1645 }));
1646
1647 // Churn on this task so that TestTaskTracker::task_completed_cv_ gets
1648 // signaled a bunch and reproduces the bug's conditions
1649 // (TestTaskTracker::DisallowRunTasks gets early chances to quit).
1650 RepeatingClosure infinite_repost = BindLambdaForTesting([&]() {
1651 if (!resume_worker_task.IsSignaled()) {
1652 ThreadPool::PostTask(infinite_repost);
1653 }
1654 });
1655 ThreadPool::PostTask(infinite_repost);
1656
1657 // Allow ThreadPool quiescence after 1 second of test.
1658 ThreadPool::PostDelayedTask(
1659 FROM_HERE,
1660 BindOnce(&TestWaitableEvent::Signal, Unretained(&resume_worker_task)),
1661 Seconds(1));
1662
1663 worker_running.Wait();
1664 {
1665 // Attempt to instantiate a ParallelExecutionFence. Without the fix to
1666 // crbug.com/1293931, this would result in quickly exiting DisallowRunTasks
1667 // without waiting for the intended 5 seconds timeout and would emit
1668 // erroneous WARNING logs about slow tasks. This test passses if it doesn't
1669 // trip FailOnTaskEnvironmentLog().
1670 TaskEnvironment::ParallelExecutionFence fence;
1671 }
1672
1673 // Flush the last |infinite_repost| task to avoid a UAF on
1674 // |resume_worker_task|.
1675 task_environment.RunUntilIdle();
1676
1677 logging::SetLogMessageHandler(previous_handler);
1678 }
1679
TEST_F(TaskEnvironmentTest,RunUntilQuit_RunsMainThread)1680 TEST_F(TaskEnvironmentTest, RunUntilQuit_RunsMainThread) {
1681 TaskEnvironment task_environment;
1682 bool task_run = false;
1683 auto quit = task_environment.QuitClosure();
1684
1685 SequencedTaskRunner::GetCurrentDefault()->PostTask(
1686 FROM_HERE, BindLambdaForTesting([&]() {
1687 task_run = true;
1688 quit.Run();
1689 }));
1690 task_environment.RunUntilQuit();
1691
1692 ASSERT_TRUE(task_run);
1693 }
1694
TEST_F(TaskEnvironmentTest,RunUntilQuit_RunsThreadPool)1695 TEST_F(TaskEnvironmentTest, RunUntilQuit_RunsThreadPool) {
1696 TaskEnvironment task_environment;
1697 bool task_run = false;
1698 auto quit = task_environment.QuitClosure();
1699
1700 ThreadPool::PostTask(FROM_HERE, BindLambdaForTesting([&]() {
1701 task_run = true;
1702 quit.Run();
1703 }));
1704 task_environment.RunUntilQuit();
1705
1706 ASSERT_TRUE(task_run);
1707 }
1708
1709 namespace {
1710
1711 class TestLogger {
1712 public:
GetLog() const1713 std::vector<std::string> GetLog() const {
1714 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
1715 return log_;
1716 }
1717
LogMessage(std::string s)1718 void LogMessage(std::string s) {
1719 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
1720 log_.push_back(std::move(s));
1721 }
1722
1723 // If n=0 then executes `done` and returns. Otherwise adds `n` to the log and
1724 // reschedules itself with (n - 1).
CountDown(int n,OnceClosure done)1725 void CountDown(int n, OnceClosure done) {
1726 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
1727 if (n == 0) {
1728 std::move(done).Run();
1729 return;
1730 }
1731
1732 log_.push_back(NumberToString(n));
1733
1734 SequencedTaskRunner::GetCurrentDefault()->PostTask(
1735 FROM_HERE, BindOnce(&TestLogger::CountDown, Unretained(this), n - 1,
1736 std::move(done)));
1737 }
1738
1739 private:
1740 std::vector<std::string> log_ GUARDED_BY_CONTEXT(sequence_checker_);
1741 SEQUENCE_CHECKER(sequence_checker_);
1742 };
1743
1744 } // namespace
1745
TEST_F(TaskEnvironmentTest,RunUntilQuit_QueuedExecution)1746 TEST_F(TaskEnvironmentTest, RunUntilQuit_QueuedExecution) {
1747 TaskEnvironment task_environment(
1748 TaskEnvironment::ThreadPoolExecutionMode::QUEUED);
1749
1750 SequenceBound<TestLogger> logger(ThreadPool::CreateSequencedTaskRunner({}));
1751 logger.AsyncCall(&TestLogger::CountDown)
1752 .WithArgs(5, task_environment.QuitClosure());
1753 // Because `task_environment` was created with
1754 // ThreadPoolExecutionMode::QUEUED, we are guaranteed that LogMessage() will
1755 // be called after the first run on CountDown() and before the rest.
1756 logger.AsyncCall(&TestLogger::LogMessage).WithArgs("Test");
1757 task_environment.RunUntilQuit();
1758
1759 // Get the log and confirm that LogMessage() ran when expected.
1760 std::vector<std::string> actual_log;
1761 auto quit = task_environment.QuitClosure();
1762 logger.AsyncCall(&TestLogger::GetLog)
1763 .Then(BindLambdaForTesting([&](std::vector<std::string> log) {
1764 actual_log = log;
1765 quit.Run();
1766 }));
1767 task_environment.RunUntilQuit();
1768
1769 ASSERT_THAT(actual_log,
1770 testing::ElementsAre("5", "Test", "4", "3", "2", "1"));
1771 }
1772
TEST_F(TaskEnvironmentTest,RunUntilQuit_ThreadPoolStaysQueued)1773 TEST_F(TaskEnvironmentTest, RunUntilQuit_ThreadPoolStaysQueued) {
1774 TaskEnvironment task_environment(
1775 TaskEnvironment::ThreadPoolExecutionMode::QUEUED);
1776
1777 ThreadPool::PostTask(FROM_HERE, task_environment.QuitClosure());
1778 task_environment.RunUntilQuit();
1779
1780 // RunUntilQuit() let the thread pool execute until the quit closure was run.
1781 // Verify that execution is now queued again.
1782
1783 bool task_run = false;
1784 ThreadPool::PostTask(FROM_HERE,
1785 BindLambdaForTesting([&]() { task_run = true; }));
1786 // Wait a little bit to let the task run if execution is not queued.
1787 PlatformThread::Sleep(Milliseconds(10));
1788
1789 ASSERT_FALSE(task_run);
1790
1791 // Run the queued task now (if we don't, it'll run when `task_environment` is
1792 // destroyed, and `task_run` is out of scope).
1793 task_environment.RunUntilIdle();
1794 }
1795
TEST_F(TaskEnvironmentTest,RunUntilQuit_QuitClosureInvalidatedByRun)1796 TEST_F(TaskEnvironmentTest, RunUntilQuit_QuitClosureInvalidatedByRun) {
1797 TaskEnvironment task_environment(
1798 TaskEnvironment::ThreadPoolExecutionMode::QUEUED);
1799
1800 auto quit1 = task_environment.QuitClosure();
1801 auto quit2 = task_environment.QuitClosure();
1802 quit1.Run();
1803 task_environment.RunUntilQuit(); // Invalidates `quit1` and `quit2`.
1804 auto quit3 = task_environment.QuitClosure();
1805
1806 std::vector<std::string> log;
1807 // Running `quit1` or `quit2` will have no effect.
1808 SequencedTaskRunner::GetCurrentDefault()->PostTask(FROM_HERE, quit1);
1809 SequencedTaskRunner::GetCurrentDefault()->PostTask(FROM_HERE, quit2);
1810 // This line will be logged.
1811 SequencedTaskRunner::GetCurrentDefault()->PostTask(
1812 FROM_HERE, BindLambdaForTesting([&]() { log.push_back("after quit2"); }));
1813 // `quit3` will terminate execution.
1814 SequencedTaskRunner::GetCurrentDefault()->PostTask(FROM_HERE, quit3);
1815 // This line will *not* be logged.
1816 SequencedTaskRunner::GetCurrentDefault()->PostTask(
1817 FROM_HERE, BindLambdaForTesting([&]() { log.push_back("after quit3"); }));
1818 task_environment.RunUntilQuit();
1819
1820 ASSERT_THAT(log, testing::ElementsAre("after quit2"));
1821
1822 // Run the queued task now (if we don't, it might run when `task_environment`
1823 // is destroyed, and `log` is out of scope).
1824 task_environment.RunUntilIdle();
1825 }
1826
TEST_F(TaskEnvironmentTest,RunUntilQuit_MustCallQuitClosureFirst)1827 TEST_F(TaskEnvironmentTest, RunUntilQuit_MustCallQuitClosureFirst) {
1828 TaskEnvironment task_environment;
1829 EXPECT_DCHECK_DEATH_WITH(
1830 task_environment.RunUntilQuit(),
1831 R"(QuitClosure\(\) not called before RunUntilQuit\(\))");
1832 }
1833
1834 } // namespace test
1835 } // namespace base
1836