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