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