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