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