• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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