1 // Copyright 2018 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "base/task/sequence_manager/thread_controller_with_message_pump_impl.h"
6
7 #include <queue>
8 #include <string>
9 #include <utility>
10 #include <vector>
11
12 #include "base/functional/bind.h"
13 #include "base/memory/raw_ptr.h"
14 #include "base/memory/scoped_refptr.h"
15 #include "base/task/sequence_manager/task_queue.h"
16 #include "base/task/sequence_manager/thread_controller_power_monitor.h"
17 #include "base/task/single_thread_task_runner.h"
18 #include "base/task/task_features.h"
19 #include "base/test/bind.h"
20 #include "base/test/mock_callback.h"
21 #include "base/test/scoped_feature_list.h"
22 #include "base/test/simple_test_tick_clock.h"
23 #include "base/time/time.h"
24 #include "build/build_config.h"
25 #include "testing/gmock/include/gmock/gmock.h"
26 #include "testing/gtest/include/gtest/gtest.h"
27 #include "third_party/abseil-cpp/absl/types/optional.h"
28
29 using testing::_;
30 using testing::Invoke;
31 using testing::ElementsAre;
32
33 namespace base::sequence_manager::internal {
34
35 namespace {
36
37 class ThreadControllerForTest : public ThreadControllerWithMessagePumpImpl {
38 public:
ThreadControllerForTest(std::unique_ptr<MessagePump> pump,const SequenceManager::Settings & settings)39 ThreadControllerForTest(std::unique_ptr<MessagePump> pump,
40 const SequenceManager::Settings& settings)
41 : ThreadControllerWithMessagePumpImpl(std::move(pump), settings) {}
42
~ThreadControllerForTest()43 ~ThreadControllerForTest() override {
44 if (trace_observer_)
45 RunLevelTracker::SetTraceObserverForTesting(nullptr);
46 }
47
48 using ThreadControllerWithMessagePumpImpl::BeforeWait;
49 using ThreadControllerWithMessagePumpImpl::DoIdleWork;
50 using ThreadControllerWithMessagePumpImpl::DoWork;
51 using ThreadControllerWithMessagePumpImpl::EnsureWorkScheduled;
52 using ThreadControllerWithMessagePumpImpl::OnBeginWorkItem;
53 using ThreadControllerWithMessagePumpImpl::OnEndWorkItem;
54 using ThreadControllerWithMessagePumpImpl::Quit;
55 using ThreadControllerWithMessagePumpImpl::Run;
56
57 using ThreadControllerWithMessagePumpImpl::MainThreadOnlyForTesting;
58 using ThreadControllerWithMessagePumpImpl::
59 ThreadControllerPowerMonitorForTesting;
60
61 class MockTraceObserver
62 : public ThreadController::RunLevelTracker::TraceObserverForTesting {
63 public:
64 MOCK_METHOD0(OnThreadControllerActiveBegin, void());
65 MOCK_METHOD0(OnThreadControllerActiveEnd, void());
66 MOCK_METHOD1(OnPhaseRecorded, void(Phase));
67 };
68
InstallTraceObserver()69 void InstallTraceObserver() {
70 trace_observer_.emplace();
71 RunLevelTracker::SetTraceObserverForTesting(&trace_observer_.value());
72
73 // EnableMessagePumpTimeKeeperMetrics is a no-op on hardware which lacks
74 // high-res clocks.
75 ASSERT_TRUE(TimeTicks::IsHighResolution());
76 EnableMessagePumpTimeKeeperMetrics("TestMainThread");
77 }
78
79 // Optionally emplaced, strict from then on.
80 absl::optional<testing::StrictMock<MockTraceObserver>> trace_observer_;
81 };
82
83 class MockMessagePump : public MessagePump {
84 public:
MockMessagePump()85 MockMessagePump() {}
~MockMessagePump()86 ~MockMessagePump() override {}
87
88 MOCK_METHOD1(Run, void(MessagePump::Delegate*));
89 MOCK_METHOD0(Quit, void());
90 MOCK_METHOD0(ScheduleWork, void());
91 MOCK_METHOD1(ScheduleDelayedWork_TimeTicks, void(const TimeTicks&));
92
ScheduleDelayedWork(const MessagePump::Delegate::NextWorkInfo & next_work_info)93 void ScheduleDelayedWork(
94 const MessagePump::Delegate::NextWorkInfo& next_work_info) override {
95 ScheduleDelayedWork_TimeTicks(next_work_info.delayed_run_time);
96 }
97 };
98
99 // TODO(crbug.com/901373): Deduplicate FakeTaskRunners.
100 class FakeTaskRunner : public SingleThreadTaskRunner {
101 public:
PostDelayedTask(const Location & from_here,OnceClosure task,TimeDelta delay)102 bool PostDelayedTask(const Location& from_here,
103 OnceClosure task,
104 TimeDelta delay) override {
105 return true;
106 }
107
PostNonNestableDelayedTask(const Location & from_here,OnceClosure task,TimeDelta delay)108 bool PostNonNestableDelayedTask(const Location& from_here,
109 OnceClosure task,
110 TimeDelta delay) override {
111 return true;
112 }
113
RunsTasksInCurrentSequence() const114 bool RunsTasksInCurrentSequence() const override { return true; }
115
116 protected:
117 ~FakeTaskRunner() override = default;
118 };
119
120 class FakeSequencedTaskSource : public SequencedTaskSource {
121 public:
FakeSequencedTaskSource(TickClock * clock)122 explicit FakeSequencedTaskSource(TickClock* clock) : clock_(clock) {}
123 ~FakeSequencedTaskSource() override = default;
124
SelectNextTask(LazyNow & lazy_now,SelectTaskOption option)125 absl::optional<SelectedTask> SelectNextTask(
126 LazyNow& lazy_now,
127 SelectTaskOption option) override {
128 if (tasks_.empty())
129 return absl::nullopt;
130 if (tasks_.front().delayed_run_time > clock_->NowTicks())
131 return absl::nullopt;
132 if (option == SequencedTaskSource::SelectTaskOption::kSkipDelayedTask &&
133 !tasks_.front().delayed_run_time.is_null()) {
134 return absl::nullopt;
135 }
136 task_execution_stack_.push_back(std::move(tasks_.front()));
137 tasks_.pop();
138 return SelectedTask(task_execution_stack_.back(),
139 TaskExecutionTraceLogger(),
140 static_cast<TaskQueue::QueuePriority>(
141 TaskQueue::DefaultQueuePriority::kNormalPriority),
142 QueueName::TEST_TQ);
143 }
144
DidRunTask(LazyNow & lazy_now)145 void DidRunTask(LazyNow& lazy_now) override {
146 task_execution_stack_.pop_back();
147 }
148
GetPendingWakeUp(LazyNow * lazy_now,SelectTaskOption option)149 absl::optional<WakeUp> GetPendingWakeUp(LazyNow* lazy_now,
150 SelectTaskOption option) override {
151 if (tasks_.empty())
152 return absl::nullopt;
153 if (option == SequencedTaskSource::SelectTaskOption::kSkipDelayedTask &&
154 !tasks_.front().delayed_run_time.is_null()) {
155 return absl::nullopt;
156 }
157 if (tasks_.front().delayed_run_time.is_null())
158 return WakeUp{};
159 if (lazy_now->Now() > tasks_.front().delayed_run_time)
160 return WakeUp{};
161 return WakeUp{tasks_.front().delayed_run_time};
162 }
163
AddTask(Location posted_from,OnceClosure task,TimeTicks delayed_run_time=TimeTicks (),TimeTicks queue_time=TimeTicks ())164 void AddTask(Location posted_from,
165 OnceClosure task,
166 TimeTicks delayed_run_time = TimeTicks(),
167 TimeTicks queue_time = TimeTicks()) {
168 DCHECK(tasks_.empty() || delayed_run_time.is_null() ||
169 tasks_.back().delayed_run_time < delayed_run_time);
170 tasks_.push(
171 Task(PostedTask(nullptr, std::move(task), posted_from, delayed_run_time,
172 base::subtle::DelayPolicy::kFlexibleNoSooner),
173 EnqueueOrder::FromIntForTesting(13), EnqueueOrder(), queue_time));
174 }
175
HasPendingHighResolutionTasks()176 bool HasPendingHighResolutionTasks() override {
177 return has_pending_high_resolution_tasks;
178 }
179
SetHasPendingHighResolutionTasks(bool state)180 void SetHasPendingHighResolutionTasks(bool state) {
181 has_pending_high_resolution_tasks = state;
182 }
183
OnSystemIdle()184 bool OnSystemIdle() override { return false; }
185
MaybeEmitTaskDetails(perfetto::EventContext & ctx,const SelectedTask & selected_task) const186 void MaybeEmitTaskDetails(perfetto::EventContext& ctx,
187 const SelectedTask& selected_task) const override {}
188
189 private:
190 raw_ptr<TickClock> clock_;
191 std::queue<Task> tasks_;
192 // Use std::deque() so that references returned by SelectNextTask() remain
193 // valid until the matching call to DidRunTask(), even when nested RunLoops
194 // cause tasks to be pushed on the stack in-between. This is needed because
195 // references are kept in local variables by calling code between
196 // SelectNextTask()/DidRunTask().
197 //
198 // See also `SequenceManagerImpl::MainThreadOnly::task_execution_stack`.
199 std::deque<Task> task_execution_stack_;
200 bool has_pending_high_resolution_tasks = false;
201 };
202
203 } // namespace
204
205 class ThreadControllerWithMessagePumpTestBase : public testing::Test {
206 public:
ThreadControllerWithMessagePumpTestBase(bool can_run_tasks_by_batches)207 explicit ThreadControllerWithMessagePumpTestBase(
208 bool can_run_tasks_by_batches)
209 : settings_(SequenceManager::Settings::Builder()
210 .SetTickClock(&clock_)
211 .SetCanRunTasksByBatches(can_run_tasks_by_batches)
212 .Build()),
213 thread_controller_(
214 std::make_unique<testing::StrictMock<MockMessagePump>>(),
215 settings_),
216 message_pump_(static_cast<MockMessagePump*>(
217 thread_controller_.GetBoundMessagePump())),
218 task_source_(&clock_) {
219 // SimpleTestTickClock starts at zero, but that also satisfies
220 // TimeTicks::is_null() and that throws off some ThreadController state.
221 // Move away from 0. All ThreadControllerWithMessagePumpTests should favor
222 // Advance() over SetNowTicks() for this reason.
223 clock_.Advance(Seconds(1000));
224
225 thread_controller_.SetWorkBatchSize(1);
226 thread_controller_.SetSequencedTaskSource(&task_source_);
227 }
228
SetUp()229 void SetUp() override {
230 ThreadControllerPowerMonitor::OverrideUsePowerMonitorForTesting(true);
231 }
232
TearDown()233 void TearDown() override { ThreadControllerPowerMonitor::ResetForTesting(); }
234
FromNow(TimeDelta delta)235 TimeTicks FromNow(TimeDelta delta) { return clock_.NowTicks() + delta; }
236
237 protected:
238 SimpleTestTickClock clock_;
239 SequenceManager::Settings settings_;
240 ThreadControllerForTest thread_controller_;
241 raw_ptr<MockMessagePump> message_pump_;
242 FakeSequencedTaskSource task_source_;
243 };
244
245 class ThreadControllerWithMessagePumpTest
246 : public ThreadControllerWithMessagePumpTestBase {
247 public:
ThreadControllerWithMessagePumpTest()248 ThreadControllerWithMessagePumpTest()
249 : ThreadControllerWithMessagePumpTestBase(
250 /* can_run_tasks_by_batches=*/true) {}
251 };
252
253 class ThreadControllerWithMessagePumpNoBatchesTest
254 : public ThreadControllerWithMessagePumpTestBase {
255 public:
ThreadControllerWithMessagePumpNoBatchesTest()256 ThreadControllerWithMessagePumpNoBatchesTest()
257 : ThreadControllerWithMessagePumpTestBase(
258 /* can_run_tasks_by_batches=*/false) {}
259 };
260
TEST_F(ThreadControllerWithMessagePumpTest,ScheduleDelayedWork)261 TEST_F(ThreadControllerWithMessagePumpTest, ScheduleDelayedWork) {
262 MockCallback<OnceClosure> task1;
263 task_source_.AddTask(FROM_HERE, task1.Get(), FromNow(Seconds(10)),
264 clock_.NowTicks());
265 MockCallback<OnceClosure> task2;
266 task_source_.AddTask(FROM_HERE, task2.Get());
267 MockCallback<OnceClosure> task3;
268 task_source_.AddTask(FROM_HERE, task3.Get(), FromNow(Seconds(20)),
269 clock_.NowTicks());
270
271 // Call a no-op DoWork. Expect that it doesn't do any work.
272 clock_.Advance(Seconds(5));
273 EXPECT_CALL(*message_pump_, ScheduleDelayedWork_TimeTicks(_)).Times(0);
274 {
275 auto next_work_info = thread_controller_.DoWork();
276 EXPECT_FALSE(next_work_info.is_immediate());
277 EXPECT_EQ(next_work_info.delayed_run_time, FromNow(Seconds(5)));
278 }
279 testing::Mock::VerifyAndClearExpectations(message_pump_);
280
281 // Call DoWork after the expiration of the delay.
282 // Expect that |task1| runs and the return value indicates that |task2| can
283 // run immediately.
284 clock_.Advance(Seconds(6));
285 EXPECT_CALL(task1, Run()).Times(1);
286 {
287 auto next_work_info = thread_controller_.DoWork();
288 EXPECT_TRUE(next_work_info.is_immediate());
289 }
290 testing::Mock::VerifyAndClearExpectations(&task1);
291
292 // Call DoWork. Expect |task2| to be run and the delayed run time of
293 // |task3| to be returned.
294 EXPECT_CALL(task2, Run()).Times(1);
295 {
296 auto next_work_info = thread_controller_.DoWork();
297 EXPECT_FALSE(next_work_info.is_immediate());
298 EXPECT_EQ(next_work_info.delayed_run_time, FromNow(Seconds(9)));
299 }
300 testing::Mock::VerifyAndClearExpectations(&task2);
301
302 // Call DoWork for the last task and expect to be told
303 // about the lack of further delayed work (next run time being TimeTicks()).
304 clock_.Advance(Seconds(10));
305 EXPECT_CALL(task3, Run()).Times(1);
306 {
307 auto next_work_info = thread_controller_.DoWork();
308 EXPECT_FALSE(next_work_info.is_immediate());
309 EXPECT_EQ(next_work_info.delayed_run_time, TimeTicks::Max());
310 }
311 testing::Mock::VerifyAndClearExpectations(&task3);
312 }
313
TEST_F(ThreadControllerWithMessagePumpTest,SetNextDelayedDoWork)314 TEST_F(ThreadControllerWithMessagePumpTest, SetNextDelayedDoWork) {
315 EXPECT_CALL(*message_pump_,
316 ScheduleDelayedWork_TimeTicks(FromNow(Seconds(123))));
317
318 LazyNow lazy_now(&clock_);
319 thread_controller_.SetNextDelayedDoWork(&lazy_now,
320 WakeUp{FromNow(Seconds(123))});
321 }
322
TEST_F(ThreadControllerWithMessagePumpTest,SetNextDelayedDoWork_CapAtOneDay)323 TEST_F(ThreadControllerWithMessagePumpTest, SetNextDelayedDoWork_CapAtOneDay) {
324 EXPECT_CALL(*message_pump_, ScheduleDelayedWork_TimeTicks(FromNow(Days(1))));
325
326 LazyNow lazy_now(&clock_);
327 thread_controller_.SetNextDelayedDoWork(&lazy_now, WakeUp{FromNow(Days(2))});
328 }
329
TEST_F(ThreadControllerWithMessagePumpTest,DelayedWork_CapAtOneDay)330 TEST_F(ThreadControllerWithMessagePumpTest, DelayedWork_CapAtOneDay) {
331 MockCallback<OnceClosure> task1;
332 task_source_.AddTask(FROM_HERE, task1.Get(), FromNow(Days(10)),
333 clock_.NowTicks());
334
335 auto next_work_info = thread_controller_.DoWork();
336 EXPECT_EQ(next_work_info.delayed_run_time, FromNow(Days(1)));
337 }
338
TEST_F(ThreadControllerWithMessagePumpTest,DoWorkDoesntScheduleDelayedWork)339 TEST_F(ThreadControllerWithMessagePumpTest, DoWorkDoesntScheduleDelayedWork) {
340 MockCallback<OnceClosure> task1;
341 task_source_.AddTask(FROM_HERE, task1.Get(), FromNow(Seconds(10)),
342 clock_.NowTicks());
343
344 EXPECT_CALL(*message_pump_, ScheduleDelayedWork_TimeTicks(_)).Times(0);
345 auto next_work_info = thread_controller_.DoWork();
346 EXPECT_EQ(next_work_info.delayed_run_time, FromNow(Seconds(10)));
347 }
348
TEST_F(ThreadControllerWithMessagePumpTest,NestedExecution)349 TEST_F(ThreadControllerWithMessagePumpTest, NestedExecution) {
350 // This test posts three immediate tasks. The first creates a nested RunLoop
351 // and the test expects that the second and third tasks are run outside of
352 // the nested loop.
353 std::vector<std::string> log;
354
355 SingleThreadTaskRunner::CurrentDefaultHandle handle(
356 MakeRefCounted<FakeTaskRunner>());
357
358 EXPECT_CALL(*message_pump_, Run(_))
359 .WillOnce(Invoke([&log, this](MessagePump::Delegate* delegate) {
360 log.push_back("entering top-level runloop");
361 EXPECT_EQ(delegate, &thread_controller_);
362 EXPECT_TRUE(delegate->DoWork().is_immediate());
363 EXPECT_TRUE(delegate->DoWork().is_immediate());
364 EXPECT_EQ(delegate->DoWork().delayed_run_time, TimeTicks::Max());
365 log.push_back("exiting top-level runloop");
366 }))
367 .WillOnce(Invoke([&log, this](MessagePump::Delegate* delegate) {
368 log.push_back("entering nested runloop");
369 EXPECT_EQ(delegate, &thread_controller_);
370 EXPECT_FALSE(thread_controller_.IsTaskExecutionAllowed());
371 EXPECT_EQ(delegate->DoWork().delayed_run_time, TimeTicks::Max());
372 log.push_back("exiting nested runloop");
373 }));
374
375 task_source_.AddTask(FROM_HERE,
376 base::BindOnce(
377 [](std::vector<std::string>* log,
378 ThreadControllerForTest* controller) {
379 EXPECT_FALSE(controller->IsTaskExecutionAllowed());
380 log->push_back("task1");
381 RunLoop().Run();
382 },
383 &log, &thread_controller_),
384 TimeTicks());
385 task_source_.AddTask(FROM_HERE,
386 base::BindOnce(
387 [](std::vector<std::string>* log,
388 ThreadControllerForTest* controller) {
389 EXPECT_FALSE(controller->IsTaskExecutionAllowed());
390 log->push_back("task2");
391 },
392 &log, &thread_controller_),
393 TimeTicks());
394 task_source_.AddTask(FROM_HERE,
395 base::BindOnce(
396 [](std::vector<std::string>* log,
397 ThreadControllerForTest* controller) {
398 EXPECT_FALSE(controller->IsTaskExecutionAllowed());
399 log->push_back("task3");
400 },
401 &log, &thread_controller_),
402 TimeTicks());
403
404 EXPECT_TRUE(thread_controller_.IsTaskExecutionAllowed());
405 RunLoop().Run();
406
407 EXPECT_THAT(log,
408 ElementsAre("entering top-level runloop", "task1",
409 "entering nested runloop", "exiting nested runloop",
410 "task2", "task3", "exiting top-level runloop"));
411 testing::Mock::VerifyAndClearExpectations(message_pump_);
412 }
413
TEST_F(ThreadControllerWithMessagePumpTest,NestedExecutionWithApplicationTasks)414 TEST_F(ThreadControllerWithMessagePumpTest,
415 NestedExecutionWithApplicationTasks) {
416 // This test is similar to the previous one, but execution is explicitly
417 // allowed (by specifying appropriate RunLoop type), and tasks are run inside
418 // nested runloop.
419 std::vector<std::string> log;
420
421 SingleThreadTaskRunner::CurrentDefaultHandle handle(
422 MakeRefCounted<FakeTaskRunner>());
423
424 EXPECT_CALL(*message_pump_, Run(_))
425 .WillOnce(Invoke([&log, this](MessagePump::Delegate* delegate) {
426 log.push_back("entering top-level runloop");
427 EXPECT_EQ(delegate, &thread_controller_);
428 EXPECT_EQ(delegate->DoWork().delayed_run_time, TimeTicks::Max());
429 log.push_back("exiting top-level runloop");
430 }))
431 .WillOnce(Invoke([&log, this](MessagePump::Delegate* delegate) {
432 log.push_back("entering nested runloop");
433 EXPECT_EQ(delegate, &thread_controller_);
434 EXPECT_TRUE(thread_controller_.IsTaskExecutionAllowed());
435 EXPECT_TRUE(delegate->DoWork().is_immediate());
436 EXPECT_EQ(delegate->DoWork().delayed_run_time, TimeTicks::Max());
437 log.push_back("exiting nested runloop");
438 }));
439
440 task_source_.AddTask(
441 FROM_HERE,
442 base::BindOnce(
443 [](std::vector<std::string>* log,
444 ThreadControllerForTest* controller) {
445 EXPECT_FALSE(controller->IsTaskExecutionAllowed());
446 log->push_back("task1");
447 RunLoop(RunLoop::Type::kNestableTasksAllowed).Run();
448 },
449 &log, &thread_controller_),
450 TimeTicks());
451 task_source_.AddTask(FROM_HERE,
452 base::BindOnce(
453 [](std::vector<std::string>* log,
454 ThreadControllerForTest* controller) {
455 EXPECT_FALSE(controller->IsTaskExecutionAllowed());
456 log->push_back("task2");
457 },
458 &log, &thread_controller_),
459 TimeTicks());
460 task_source_.AddTask(FROM_HERE,
461 base::BindOnce(
462 [](std::vector<std::string>* log,
463 ThreadControllerForTest* controller) {
464 EXPECT_FALSE(controller->IsTaskExecutionAllowed());
465 log->push_back("task3");
466 },
467 &log, &thread_controller_),
468 TimeTicks());
469
470 EXPECT_TRUE(thread_controller_.IsTaskExecutionAllowed());
471 RunLoop().Run();
472
473 EXPECT_THAT(
474 log, ElementsAre("entering top-level runloop", "task1",
475 "entering nested runloop", "task2", "task3",
476 "exiting nested runloop", "exiting top-level runloop"));
477 testing::Mock::VerifyAndClearExpectations(message_pump_);
478 }
479
TEST_F(ThreadControllerWithMessagePumpTest,SetDefaultTaskRunner)480 TEST_F(ThreadControllerWithMessagePumpTest, SetDefaultTaskRunner) {
481 scoped_refptr<SingleThreadTaskRunner> task_runner1 =
482 MakeRefCounted<FakeTaskRunner>();
483 thread_controller_.SetDefaultTaskRunner(task_runner1);
484 EXPECT_EQ(task_runner1, SingleThreadTaskRunner::GetCurrentDefault());
485
486 // Check that we are correctly supporting overriding.
487 scoped_refptr<SingleThreadTaskRunner> task_runner2 =
488 MakeRefCounted<FakeTaskRunner>();
489 thread_controller_.SetDefaultTaskRunner(task_runner2);
490 EXPECT_EQ(task_runner2, SingleThreadTaskRunner::GetCurrentDefault());
491 }
492
TEST_F(ThreadControllerWithMessagePumpTest,EnsureWorkScheduled)493 TEST_F(ThreadControllerWithMessagePumpTest, EnsureWorkScheduled) {
494 task_source_.AddTask(FROM_HERE, DoNothing());
495
496 // Ensure that the first ScheduleWork() call results in the pump being called.
497 EXPECT_CALL(*message_pump_, ScheduleWork());
498 thread_controller_.ScheduleWork();
499 testing::Mock::VerifyAndClearExpectations(message_pump_);
500
501 // Ensure that the subsequent ScheduleWork() does not call the pump.
502 thread_controller_.ScheduleWork();
503 testing::Mock::VerifyAndClearExpectations(message_pump_);
504
505 // EnsureWorkScheduled() doesn't need to do anything because there's a pending
506 // DoWork.
507 EXPECT_CALL(*message_pump_, ScheduleWork()).Times(0);
508 thread_controller_.EnsureWorkScheduled();
509 testing::Mock::VerifyAndClearExpectations(message_pump_);
510
511 EXPECT_EQ(thread_controller_.DoWork().delayed_run_time, TimeTicks::Max());
512
513 // EnsureWorkScheduled() calls the pump because there's no pending DoWork.
514 EXPECT_CALL(*message_pump_, ScheduleWork()).Times(1);
515 thread_controller_.EnsureWorkScheduled();
516 testing::Mock::VerifyAndClearExpectations(message_pump_);
517 }
518
TEST_F(ThreadControllerWithMessagePumpTest,WorkBatching)519 TEST_F(ThreadControllerWithMessagePumpTest, WorkBatching) {
520 SingleThreadTaskRunner::CurrentDefaultHandle handle(
521 MakeRefCounted<FakeTaskRunner>());
522
523 const int kBatchSize = 5;
524 thread_controller_.SetWorkBatchSize(kBatchSize);
525
526 int task_count = 0;
527 EXPECT_CALL(*message_pump_, Run(_))
528 .WillOnce(Invoke([&](MessagePump::Delegate* delegate) {
529 EXPECT_EQ(delegate->DoWork().delayed_run_time, TimeTicks::Max());
530 EXPECT_EQ(5, task_count);
531 }));
532
533 for (int i = 0; i < kBatchSize; i++) {
534 task_source_.AddTask(FROM_HERE, BindLambdaForTesting([&] { task_count++; }),
535 TimeTicks());
536 }
537
538 RunLoop run_loop;
539 run_loop.Run();
540 testing::Mock::VerifyAndClearExpectations(message_pump_);
541 }
542
TEST_F(ThreadControllerWithMessagePumpTest,QuitInterruptsBatch)543 TEST_F(ThreadControllerWithMessagePumpTest, QuitInterruptsBatch) {
544 // This check ensures that RunLoop::Quit() makes us drop back to a work batch
545 // size of 1.
546 SingleThreadTaskRunner::CurrentDefaultHandle handle(
547 MakeRefCounted<FakeTaskRunner>());
548
549 const int kBatchSize = 5;
550 thread_controller_.SetWorkBatchSize(kBatchSize);
551
552 int task_count = 0;
553 EXPECT_CALL(*message_pump_, Run(_))
554 .WillOnce(Invoke([&](MessagePump::Delegate* delegate) {
555 EXPECT_EQ(delegate->DoWork().delayed_run_time, TimeTicks::Max());
556 EXPECT_EQ(1, task_count);
557
558 // Somewhat counter-intuitive, but if the pump keeps calling us after
559 // Quit(), the delegate should still run tasks as normally. This is
560 // needed to support nested OS-level runloops that still pump
561 // application tasks (e.g., showing a popup menu on Mac).
562 EXPECT_EQ(delegate->DoWork().delayed_run_time, TimeTicks::Max());
563 EXPECT_EQ(2, task_count);
564 EXPECT_EQ(delegate->DoWork().delayed_run_time, TimeTicks::Max());
565 EXPECT_EQ(3, task_count);
566 }));
567 EXPECT_CALL(*message_pump_, Quit());
568
569 RunLoop run_loop;
570 for (int i = 0; i < kBatchSize; i++) {
571 task_source_.AddTask(FROM_HERE, BindLambdaForTesting([&] {
572 if (!task_count++)
573 run_loop.Quit();
574 }),
575 TimeTicks());
576 }
577
578 run_loop.Run();
579 testing::Mock::VerifyAndClearExpectations(message_pump_);
580 }
581
TEST_F(ThreadControllerWithMessagePumpTest,PrioritizeYieldingToNative)582 TEST_F(ThreadControllerWithMessagePumpTest, PrioritizeYieldingToNative) {
583 SingleThreadTaskRunner::CurrentDefaultHandle handle(
584 MakeRefCounted<FakeTaskRunner>());
585
586 testing::InSequence sequence;
587
588 RunLoop run_loop;
589 const auto delayed_time = FromNow(Seconds(10));
590 EXPECT_CALL(*message_pump_, Run(_))
591 .WillOnce(Invoke([&](MessagePump::Delegate* delegate) {
592 clock_.Advance(Seconds(5));
593 MockCallback<OnceClosure> tasks[5];
594
595 // A: Post 5 application tasks, 4 immediate 1 delayed.
596 // B: Run one of them (enter active)
597 // C: Expect we return immediate work item without yield_to_native
598 // (default behaviour).
599 // D: Set PrioritizeYieldingToNative until 8 seconds and run second
600 // task.
601 // E: Expect we return immediate work item with yield_to_native.
602 // F: Exceed the PrioritizeYieldingToNative deadline and run third task.
603 // G: Expect we return immediate work item without yield_to_native.
604 // H: Set PrioritizeYieldingToNative to Max() and run third of them
605 // I: Expect we return a delayed work item with yield_to_native.
606
607 // A:
608 task_source_.AddTask(FROM_HERE, tasks[0].Get(),
609 /* delayed_run_time=*/base::TimeTicks(),
610 /* queue_time=*/clock_.NowTicks());
611 task_source_.AddTask(FROM_HERE, tasks[1].Get(),
612 /* delayed_run_time=*/base::TimeTicks(),
613 /* queue_time=*/clock_.NowTicks());
614 task_source_.AddTask(FROM_HERE, tasks[2].Get(),
615 /* delayed_run_time=*/base::TimeTicks(),
616 /* queue_time=*/clock_.NowTicks());
617 task_source_.AddTask(FROM_HERE, tasks[3].Get(),
618 /* delayed_run_time=*/base::TimeTicks(),
619 /* queue_time=*/clock_.NowTicks());
620 task_source_.AddTask(FROM_HERE, tasks[4].Get(),
621 /* delayed_run_time=*/delayed_time,
622 /* queue_time=*/clock_.NowTicks());
623
624 // B:
625 EXPECT_CALL(tasks[0], Run());
626 auto next_work_item = thread_controller_.DoWork();
627 // C:
628 EXPECT_EQ(next_work_item.delayed_run_time, TimeTicks());
629 EXPECT_FALSE(next_work_item.yield_to_native);
630
631 // D:
632 thread_controller_.PrioritizeYieldingToNative(FromNow(Seconds(3)));
633 EXPECT_CALL(tasks[1], Run());
634 next_work_item = thread_controller_.DoWork();
635 // E:
636 EXPECT_EQ(next_work_item.delayed_run_time, TimeTicks());
637 EXPECT_TRUE(next_work_item.yield_to_native);
638
639 // F:
640 clock_.Advance(Seconds(3));
641 EXPECT_CALL(tasks[2], Run());
642 next_work_item = thread_controller_.DoWork();
643 // G:
644 EXPECT_EQ(next_work_item.delayed_run_time, TimeTicks());
645 EXPECT_FALSE(next_work_item.yield_to_native);
646
647 // H:
648 thread_controller_.PrioritizeYieldingToNative(base::TimeTicks::Max());
649 EXPECT_CALL(tasks[3], Run());
650 next_work_item = thread_controller_.DoWork();
651
652 // I:
653 EXPECT_EQ(next_work_item.delayed_run_time, delayed_time);
654 EXPECT_TRUE(next_work_item.yield_to_native);
655
656 EXPECT_FALSE(thread_controller_.DoIdleWork());
657 }));
658
659 run_loop.Run();
660 testing::Mock::VerifyAndClearExpectations(message_pump_);
661 }
662
TEST_F(ThreadControllerWithMessagePumpTest,EarlyQuit)663 TEST_F(ThreadControllerWithMessagePumpTest, EarlyQuit) {
664 // This test ensures that a opt-of-runloop Quit() (which is possible with some
665 // pump implementations) doesn't affect the next RunLoop::Run call.
666
667 SingleThreadTaskRunner::CurrentDefaultHandle handle(
668 MakeRefCounted<FakeTaskRunner>());
669
670 std::vector<std::string> log;
671
672 // This quit should be a no-op for future calls.
673 EXPECT_CALL(*message_pump_, Quit());
674 thread_controller_.Quit();
675 testing::Mock::VerifyAndClearExpectations(message_pump_);
676
677 EXPECT_CALL(*message_pump_, Run(_))
678 .WillOnce(Invoke([this](MessagePump::Delegate* delegate) {
679 EXPECT_EQ(delegate, &thread_controller_);
680 EXPECT_TRUE(delegate->DoWork().is_immediate());
681 EXPECT_EQ(delegate->DoWork().delayed_run_time, TimeTicks::Max());
682 }));
683
684 RunLoop run_loop;
685
686 task_source_.AddTask(
687 FROM_HERE,
688 base::BindOnce(
689 [](std::vector<std::string>* log) { log->push_back("task1"); }, &log),
690 TimeTicks());
691 task_source_.AddTask(
692 FROM_HERE,
693 base::BindOnce(
694 [](std::vector<std::string>* log) { log->push_back("task2"); }, &log),
695 TimeTicks());
696
697 run_loop.RunUntilIdle();
698
699 EXPECT_THAT(log, ElementsAre("task1", "task2"));
700 testing::Mock::VerifyAndClearExpectations(message_pump_);
701 }
702
TEST_F(ThreadControllerWithMessagePumpTest,NativeNestedMessageLoop)703 TEST_F(ThreadControllerWithMessagePumpTest, NativeNestedMessageLoop) {
704 bool did_run = false;
705 task_source_.AddTask(
706 FROM_HERE, BindLambdaForTesting([&] {
707 // Clear expectation set for the non-nested PostTask.
708 testing::Mock::VerifyAndClearExpectations(message_pump_);
709
710 EXPECT_FALSE(thread_controller_.IsTaskExecutionAllowed());
711 // SetTaskExecutionAllowed(true) should ScheduleWork.
712 EXPECT_CALL(*message_pump_, ScheduleWork());
713 thread_controller_.SetTaskExecutionAllowed(true);
714 testing::Mock::VerifyAndClearExpectations(message_pump_);
715
716 // There's no pending work so the native loop should go
717 // idle.
718 EXPECT_CALL(*message_pump_, ScheduleWork()).Times(0);
719 EXPECT_EQ(thread_controller_.DoWork().delayed_run_time,
720 TimeTicks::Max());
721 testing::Mock::VerifyAndClearExpectations(message_pump_);
722
723 // Simulate a native callback which posts a task, this
724 // should now ask the pump to ScheduleWork();
725 task_source_.AddTask(FROM_HERE, DoNothing());
726 EXPECT_CALL(*message_pump_, ScheduleWork());
727 thread_controller_.ScheduleWork();
728 testing::Mock::VerifyAndClearExpectations(message_pump_);
729
730 thread_controller_.SetTaskExecutionAllowed(false);
731
732 // Simulate a subsequent PostTask by the chromium task after
733 // we've left the native loop. This should not ScheduleWork
734 // on the pump because the ThreadController will do that
735 // after this task finishes.
736 task_source_.AddTask(FROM_HERE, DoNothing());
737 EXPECT_CALL(*message_pump_, ScheduleWork()).Times(0);
738 thread_controller_.ScheduleWork();
739
740 did_run = true;
741 }),
742 TimeTicks());
743
744 // Simulate a PostTask that enters a native nested message loop.
745 EXPECT_CALL(*message_pump_, ScheduleWork());
746 thread_controller_.ScheduleWork();
747 EXPECT_TRUE(thread_controller_.DoWork().is_immediate());
748 EXPECT_TRUE(did_run);
749 }
750
TEST_F(ThreadControllerWithMessagePumpTest,RunWithTimeout)751 TEST_F(ThreadControllerWithMessagePumpTest, RunWithTimeout) {
752 MockCallback<OnceClosure> task1;
753 task_source_.AddTask(FROM_HERE, task1.Get(), FromNow(Seconds(5)),
754 clock_.NowTicks());
755 MockCallback<OnceClosure> task2;
756 task_source_.AddTask(FROM_HERE, task2.Get(), FromNow(Seconds(10)),
757 clock_.NowTicks());
758 MockCallback<OnceClosure> task3;
759 task_source_.AddTask(FROM_HERE, task3.Get(), FromNow(Seconds(20)),
760 clock_.NowTicks());
761
762 EXPECT_CALL(*message_pump_, Run(_))
763 .WillOnce(Invoke([&](MessagePump::Delegate*) {
764 clock_.Advance(Seconds(5));
765 EXPECT_CALL(task1, Run()).Times(1);
766 EXPECT_EQ(thread_controller_.DoWork().delayed_run_time,
767 FromNow(Seconds(5)));
768
769 clock_.Advance(Seconds(5));
770 EXPECT_CALL(task2, Run()).Times(1);
771 EXPECT_EQ(thread_controller_.DoWork().delayed_run_time,
772 FromNow(Seconds(5)));
773
774 clock_.Advance(Seconds(5));
775 EXPECT_CALL(task3, Run()).Times(0);
776 EXPECT_EQ(thread_controller_.DoWork().delayed_run_time,
777 TimeTicks::Max());
778
779 EXPECT_CALL(*message_pump_, Quit());
780 EXPECT_FALSE(thread_controller_.DoIdleWork());
781 }));
782 thread_controller_.Run(true, Seconds(15));
783 }
784
785 #if BUILDFLAG(IS_WIN)
TEST_F(ThreadControllerWithMessagePumpTest,SetHighResolutionTimer)786 TEST_F(ThreadControllerWithMessagePumpTest, SetHighResolutionTimer) {
787 MockCallback<OnceClosure> task;
788 task_source_.AddTask(FROM_HERE, task.Get(), FromNow(Seconds(5)),
789 clock_.NowTicks());
790
791 SingleThreadTaskRunner::CurrentDefaultHandle handle(
792 MakeRefCounted<FakeTaskRunner>());
793
794 EXPECT_CALL(*message_pump_, Run(_))
795 .WillOnce(Invoke([&](MessagePump::Delegate* delegate) {
796 // Should initially not be in high resolution.
797 EXPECT_FALSE(
798 thread_controller_.MainThreadOnlyForTesting().in_high_res_mode);
799
800 // Ensures timer resolution is set to high resolution.
801 task_source_.SetHasPendingHighResolutionTasks(true);
802 EXPECT_FALSE(delegate->DoIdleWork());
803 EXPECT_TRUE(
804 thread_controller_.MainThreadOnlyForTesting().in_high_res_mode);
805
806 // Ensures time resolution is set back to low resolution.
807 task_source_.SetHasPendingHighResolutionTasks(false);
808 EXPECT_FALSE(delegate->DoIdleWork());
809 EXPECT_FALSE(
810 thread_controller_.MainThreadOnlyForTesting().in_high_res_mode);
811
812 EXPECT_CALL(*message_pump_, Quit());
813 thread_controller_.Quit();
814 }));
815
816 RunLoop run_loop;
817 run_loop.Run();
818 }
819 #endif // BUILDFLAG(IS_WIN)
820
821 #if BUILDFLAG(IS_WIN)
TEST_F(ThreadControllerWithMessagePumpTest,SetHighResolutionTimerWithPowerSuspend)822 TEST_F(ThreadControllerWithMessagePumpTest,
823 SetHighResolutionTimerWithPowerSuspend) {
824 MockCallback<OnceClosure> task;
825 task_source_.AddTask(FROM_HERE, task.Get(), FromNow(Seconds(5)),
826 clock_.NowTicks());
827
828 SingleThreadTaskRunner::CurrentDefaultHandle handle(
829 MakeRefCounted<FakeTaskRunner>());
830
831 EXPECT_CALL(*message_pump_, Run(_))
832 .WillOnce(Invoke([&](MessagePump::Delegate* delegate) {
833 // Should initially not be in high resolution.
834 EXPECT_FALSE(
835 thread_controller_.MainThreadOnlyForTesting().in_high_res_mode);
836
837 // The power suspend notification is sent.
838 thread_controller_.ThreadControllerPowerMonitorForTesting()
839 ->OnSuspend();
840
841 // The timer resolution should NOT be updated during power suspend.
842 task_source_.SetHasPendingHighResolutionTasks(true);
843 EXPECT_FALSE(delegate->DoIdleWork());
844 EXPECT_FALSE(
845 thread_controller_.MainThreadOnlyForTesting().in_high_res_mode);
846
847 // The power resume notification is sent.
848 thread_controller_.ThreadControllerPowerMonitorForTesting()->OnResume();
849
850 // Ensures timer resolution is set to high resolution.
851 EXPECT_FALSE(delegate->DoIdleWork());
852 EXPECT_TRUE(
853 thread_controller_.MainThreadOnlyForTesting().in_high_res_mode);
854
855 EXPECT_CALL(*message_pump_, Quit());
856 thread_controller_.Quit();
857 }));
858
859 RunLoop run_loop;
860 run_loop.Run();
861 }
862 #endif // BUILDFLAG(IS_WIN)
863
TEST_F(ThreadControllerWithMessagePumpTest,ScheduleDelayedWorkWithPowerSuspend)864 TEST_F(ThreadControllerWithMessagePumpTest,
865 ScheduleDelayedWorkWithPowerSuspend) {
866 SingleThreadTaskRunner::CurrentDefaultHandle handle(
867 MakeRefCounted<FakeTaskRunner>());
868
869 MockCallback<OnceClosure> task1;
870 task_source_.AddTask(FROM_HERE, task1.Get(), FromNow(Seconds(10)),
871 clock_.NowTicks());
872 MockCallback<OnceClosure> task2;
873 task_source_.AddTask(FROM_HERE, task2.Get(), FromNow(Seconds(15)),
874 clock_.NowTicks());
875
876 clock_.Advance(Seconds(5));
877
878 // Call a no-op DoWork. Expect that it doesn't do any work.
879 EXPECT_CALL(task1, Run()).Times(0);
880 EXPECT_CALL(task2, Run()).Times(0);
881 EXPECT_EQ(thread_controller_.DoWork().delayed_run_time, FromNow(Seconds(5)));
882 testing::Mock::VerifyAndClearExpectations(&task1);
883 testing::Mock::VerifyAndClearExpectations(&task2);
884
885 // Simulate a power suspend.
886 thread_controller_.ThreadControllerPowerMonitorForTesting()->OnSuspend();
887
888 // Delayed task is not yet ready to be executed.
889 EXPECT_CALL(task1, Run()).Times(0);
890 EXPECT_CALL(task2, Run()).Times(0);
891 EXPECT_EQ(thread_controller_.DoWork().delayed_run_time, TimeTicks::Max());
892 testing::Mock::VerifyAndClearExpectations(&task1);
893 testing::Mock::VerifyAndClearExpectations(&task2);
894
895 // Move time after the expiration delay of tasks.
896 clock_.Advance(Seconds(42));
897
898 // Should not process delayed tasks. The process is still in suspended power
899 // state.
900 EXPECT_CALL(task1, Run()).Times(0);
901 EXPECT_CALL(task2, Run()).Times(0);
902 EXPECT_EQ(thread_controller_.DoWork().delayed_run_time, TimeTicks::Max());
903 testing::Mock::VerifyAndClearExpectations(&task1);
904 testing::Mock::VerifyAndClearExpectations(&task2);
905
906 // Simulate a power resume.
907 thread_controller_.ThreadControllerPowerMonitorForTesting()->OnResume();
908
909 // No longer in suspended state. Controller should process both delayed tasks.
910 EXPECT_CALL(task1, Run()).Times(1);
911 EXPECT_CALL(task2, Run()).Times(1);
912 EXPECT_TRUE(thread_controller_.DoWork().is_immediate());
913 EXPECT_EQ(thread_controller_.DoWork().delayed_run_time, TimeTicks::Max());
914 testing::Mock::VerifyAndClearExpectations(&task1);
915 testing::Mock::VerifyAndClearExpectations(&task2);
916 }
917
TEST_F(ThreadControllerWithMessagePumpTest,ThreadControllerActiveSingleApplicationTask)918 TEST_F(ThreadControllerWithMessagePumpTest,
919 ThreadControllerActiveSingleApplicationTask) {
920 SingleThreadTaskRunner::CurrentDefaultHandle handle(
921 MakeRefCounted<FakeTaskRunner>());
922
923 thread_controller_.InstallTraceObserver();
924
925 testing::InSequence sequence;
926
927 RunLoop run_loop;
928 EXPECT_CALL(*thread_controller_.trace_observer_,
929 OnThreadControllerActiveBegin);
930 EXPECT_CALL(*message_pump_, Run(_))
931 .WillOnce(Invoke([&](MessagePump::Delegate* delegate) {
932 // Don't expect a call to OnThreadControllerActiveBegin on the first
933 // pass as the Run() call already triggered the active state.
934 bool first_pass = true;
935
936 // Post 1 task, run it, go idle, repeat 5 times. Expected to enter/exit
937 // "ThreadController active" state 5 consecutive times.
938 for (int i = 0; i < 5; ++i, first_pass = false) {
939 MockCallback<OnceClosure> task;
940 task_source_.AddTask(FROM_HERE, task.Get());
941
942 if (!first_pass) {
943 EXPECT_CALL(*thread_controller_.trace_observer_,
944 OnThreadControllerActiveBegin);
945 } else {
946 // The first pass begins with a kPumpOverhead phase as the
947 // RunLoop::Run() begins active. Subsequent passes begin idle and
948 // thus start with a kSelectingApplicationTask phase.
949 EXPECT_CALL(*thread_controller_.trace_observer_,
950 OnPhaseRecorded(ThreadController::kPumpOverhead));
951 }
952 EXPECT_CALL(
953 *thread_controller_.trace_observer_,
954 OnPhaseRecorded(ThreadController::kSelectingApplicationTask));
955 EXPECT_CALL(task, Run());
956 EXPECT_CALL(*thread_controller_.trace_observer_,
957 OnPhaseRecorded(ThreadController::kApplicationTask));
958 EXPECT_EQ(thread_controller_.DoWork().delayed_run_time,
959 TimeTicks::Max());
960
961 testing::Mock::VerifyAndClearExpectations(
962 &*thread_controller_.trace_observer_);
963
964 EXPECT_CALL(*thread_controller_.trace_observer_,
965 OnPhaseRecorded(ThreadController::kIdleWork));
966 EXPECT_CALL(*thread_controller_.trace_observer_,
967 OnThreadControllerActiveEnd);
968 EXPECT_FALSE(thread_controller_.DoIdleWork());
969
970 testing::Mock::VerifyAndClearExpectations(
971 &*thread_controller_.trace_observer_);
972 }
973 }));
974
975 RunLoop().Run();
976 }
977
TEST_F(ThreadControllerWithMessagePumpTest,ThreadControllerActiveMultipleApplicationTasks)978 TEST_F(ThreadControllerWithMessagePumpTest,
979 ThreadControllerActiveMultipleApplicationTasks) {
980 SingleThreadTaskRunner::CurrentDefaultHandle handle(
981 MakeRefCounted<FakeTaskRunner>());
982
983 thread_controller_.InstallTraceObserver();
984
985 testing::InSequence sequence;
986
987 RunLoop run_loop;
988 EXPECT_CALL(*thread_controller_.trace_observer_,
989 OnThreadControllerActiveBegin);
990 EXPECT_CALL(*message_pump_, Run(_))
991 .WillOnce(Invoke([&](MessagePump::Delegate* delegate) {
992 MockCallback<OnceClosure> tasks[5];
993 // Post 5 tasks, run them, go idle. Expected to only exit
994 // "ThreadController active" state at the end.
995 for (auto& t : tasks)
996 task_source_.AddTask(FROM_HERE, t.Get());
997 for (size_t i = 0; i < std::size(tasks); ++i) {
998 const TimeTicks expected_delayed_run_time =
999 i < std::size(tasks) - 1 ? TimeTicks() : TimeTicks::Max();
1000
1001 // The first pass begins with a kPumpOverhead phase as the
1002 // RunLoop::Run() begins active and the subsequent ones also do
1003 // (between the end of the last kChromeTask and the next
1004 // kSelectingApplicationTask).
1005 EXPECT_CALL(*thread_controller_.trace_observer_,
1006 OnPhaseRecorded(ThreadController::kPumpOverhead));
1007
1008 EXPECT_CALL(
1009 *thread_controller_.trace_observer_,
1010 OnPhaseRecorded(ThreadController::kSelectingApplicationTask));
1011 EXPECT_CALL(tasks[i], Run());
1012 EXPECT_CALL(*thread_controller_.trace_observer_,
1013 OnPhaseRecorded(ThreadController::kApplicationTask));
1014 EXPECT_EQ(thread_controller_.DoWork().delayed_run_time,
1015 expected_delayed_run_time);
1016 }
1017
1018 EXPECT_CALL(*thread_controller_.trace_observer_,
1019 OnPhaseRecorded(ThreadController::kIdleWork));
1020 EXPECT_CALL(*thread_controller_.trace_observer_,
1021 OnThreadControllerActiveEnd);
1022 EXPECT_FALSE(thread_controller_.DoIdleWork());
1023 }));
1024
1025 RunLoop().Run();
1026 }
1027
TEST_F(ThreadControllerWithMessagePumpTest,ThreadControllerActiveWakeUpForNothing)1028 TEST_F(ThreadControllerWithMessagePumpTest,
1029 ThreadControllerActiveWakeUpForNothing) {
1030 SingleThreadTaskRunner::CurrentDefaultHandle handle(
1031 MakeRefCounted<FakeTaskRunner>());
1032
1033 thread_controller_.InstallTraceObserver();
1034
1035 testing::InSequence sequence;
1036
1037 RunLoop run_loop;
1038 EXPECT_CALL(*thread_controller_.trace_observer_,
1039 OnThreadControllerActiveBegin);
1040 EXPECT_CALL(*message_pump_, Run(_))
1041 .WillOnce(Invoke([&](MessagePump::Delegate* delegate) {
1042 // Don't expect a call to OnThreadControllerActiveBegin on the first
1043 // pass as the Run() call already triggered the active state.
1044 bool first_pass = true;
1045
1046 // Invoke DoWork with no pending work, go idle, repeat 5 times. Expected
1047 // to enter/exit "ThreadController active" state 5 consecutive times.
1048 for (int i = 0; i < 5; ++i, first_pass = false) {
1049 if (!first_pass) {
1050 EXPECT_CALL(*thread_controller_.trace_observer_,
1051 OnThreadControllerActiveBegin);
1052 } else {
1053 // As-in ThreadControllerActiveSingleApplicationTask.
1054 EXPECT_CALL(*thread_controller_.trace_observer_,
1055 OnPhaseRecorded(ThreadController::kPumpOverhead));
1056 }
1057 EXPECT_CALL(
1058 *thread_controller_.trace_observer_,
1059 OnPhaseRecorded(ThreadController::kSelectingApplicationTask));
1060 EXPECT_CALL(*thread_controller_.trace_observer_,
1061 OnPhaseRecorded(ThreadController::kApplicationTask));
1062 EXPECT_EQ(thread_controller_.DoWork().delayed_run_time,
1063 TimeTicks::Max());
1064
1065 testing::Mock::VerifyAndClearExpectations(
1066 &*thread_controller_.trace_observer_);
1067
1068 EXPECT_CALL(*thread_controller_.trace_observer_,
1069 OnPhaseRecorded(ThreadController::kIdleWork));
1070 EXPECT_CALL(*thread_controller_.trace_observer_,
1071 OnThreadControllerActiveEnd);
1072 EXPECT_FALSE(thread_controller_.DoIdleWork());
1073
1074 testing::Mock::VerifyAndClearExpectations(
1075 &*thread_controller_.trace_observer_);
1076 }
1077 }));
1078
1079 RunLoop().Run();
1080 }
1081
TEST_F(ThreadControllerWithMessagePumpTest,DoWorkBatches)1082 TEST_F(ThreadControllerWithMessagePumpTest, DoWorkBatches) {
1083 base::test::ScopedFeatureList scoped_feature_list;
1084
1085 scoped_feature_list.InitAndEnableFeature(kRunTasksByBatches);
1086 ThreadControllerWithMessagePumpImpl::InitializeFeatures();
1087 MessagePump::InitializeFeatures();
1088
1089 int task_counter = 0;
1090 for (int i = 0; i < 2; i++) {
1091 task_source_.AddTask(
1092 FROM_HERE, BindLambdaForTesting([&] { task_counter++; }), TimeTicks());
1093 }
1094 thread_controller_.DoWork();
1095
1096 EXPECT_EQ(task_counter, 2);
1097 ThreadControllerWithMessagePumpImpl::ResetFeatures();
1098 }
1099
TEST_F(ThreadControllerWithMessagePumpNoBatchesTest,DoWorkBatches)1100 TEST_F(ThreadControllerWithMessagePumpNoBatchesTest, DoWorkBatches) {
1101 base::test::ScopedFeatureList scoped_feature_list;
1102
1103 scoped_feature_list.InitAndEnableFeature(kRunTasksByBatches);
1104 ThreadControllerWithMessagePumpImpl::InitializeFeatures();
1105 MessagePump::InitializeFeatures();
1106
1107 int task_counter = 0;
1108 for (int i = 0; i < 2; i++) {
1109 task_source_.AddTask(
1110 FROM_HERE, BindLambdaForTesting([&] { task_counter++; }), TimeTicks());
1111 }
1112 thread_controller_.DoWork();
1113
1114 // Only one task should run because the SequenceManager was configured to
1115 // disallow batches.
1116 EXPECT_EQ(task_counter, 1);
1117 ThreadControllerWithMessagePumpImpl::ResetFeatures();
1118 }
1119
TEST_F(ThreadControllerWithMessagePumpTest,DoWorkBatchesForSetTime)1120 TEST_F(ThreadControllerWithMessagePumpTest, DoWorkBatchesForSetTime) {
1121 base::test::ScopedFeatureList scoped_feature_list;
1122
1123 scoped_feature_list.InitAndEnableFeature(kRunTasksByBatches);
1124 ThreadControllerWithMessagePumpImpl::InitializeFeatures();
1125 MessagePump::InitializeFeatures();
1126
1127 int task_counter = 0;
1128
1129 for (int i = 0; i < 4; i++) {
1130 task_source_.AddTask(FROM_HERE, BindLambdaForTesting([&] {
1131 clock_.Advance(Milliseconds(4));
1132 task_counter++;
1133 }));
1134 }
1135 thread_controller_.DoWork();
1136
1137 EXPECT_EQ(task_counter, 2);
1138 ThreadControllerWithMessagePumpImpl::ResetFeatures();
1139 }
1140
TEST_F(ThreadControllerWithMessagePumpTest,ThreadControllerActiveAdvancedNesting)1141 TEST_F(ThreadControllerWithMessagePumpTest,
1142 ThreadControllerActiveAdvancedNesting) {
1143 SingleThreadTaskRunner::CurrentDefaultHandle handle(
1144 MakeRefCounted<FakeTaskRunner>());
1145
1146 thread_controller_.InstallTraceObserver();
1147
1148 testing::InSequence sequence;
1149
1150 RunLoop run_loop;
1151 EXPECT_CALL(*thread_controller_.trace_observer_,
1152 OnThreadControllerActiveBegin);
1153 EXPECT_CALL(*message_pump_, Run(_))
1154 .WillOnce(Invoke([&](MessagePump::Delegate* delegate) {
1155 MockCallback<OnceClosure> tasks[5];
1156
1157 // A: Post 2 tasks
1158 // B: Run one of them (enter active)
1159 // C: Enter a nested loop (enter nested active)
1160 // D: Run the next task (remain nested active)
1161 // E: Go idle (exit active)
1162 // F: Post 2 tasks
1163 // G: Run one (enter nested active)
1164 // H: exit nested loop (exit nested active)
1165 // I: Run the next one, go idle (remain active, exit active)
1166 // J: Post/run one more task, go idle (enter active, exit active)
1167 //
1168
1169 // A:
1170 task_source_.AddTask(FROM_HERE, tasks[0].Get());
1171 task_source_.AddTask(FROM_HERE, tasks[1].Get());
1172
1173 EXPECT_CALL(*thread_controller_.trace_observer_,
1174 OnPhaseRecorded(ThreadController::kPumpOverhead));
1175 EXPECT_CALL(
1176 *thread_controller_.trace_observer_,
1177 OnPhaseRecorded(ThreadController::kSelectingApplicationTask));
1178 EXPECT_CALL(tasks[0], Run()).WillOnce(Invoke([&]() {
1179 // C:
1180 // kChromeTask phase is suspended when the nested loop is entered.
1181 EXPECT_CALL(*thread_controller_.trace_observer_,
1182 OnPhaseRecorded(ThreadController::kApplicationTask));
1183 EXPECT_CALL(*thread_controller_.trace_observer_,
1184 OnThreadControllerActiveBegin);
1185 EXPECT_CALL(*message_pump_, Run(_))
1186 .WillOnce(Invoke([&](MessagePump::Delegate* delegate) {
1187 // D:
1188 EXPECT_CALL(tasks[1], Run());
1189 EXPECT_EQ(thread_controller_.DoWork().delayed_run_time,
1190 TimeTicks::Max());
1191 testing::Mock::VerifyAndClearExpectations(
1192 &*thread_controller_.trace_observer_);
1193
1194 // E:
1195 EXPECT_CALL(*thread_controller_.trace_observer_,
1196 OnThreadControllerActiveEnd);
1197 EXPECT_FALSE(thread_controller_.DoIdleWork());
1198 testing::Mock::VerifyAndClearExpectations(
1199 &*thread_controller_.trace_observer_);
1200
1201 // F:
1202 task_source_.AddTask(FROM_HERE, tasks[2].Get());
1203 task_source_.AddTask(FROM_HERE, tasks[3].Get());
1204
1205 // G:
1206 EXPECT_CALL(*thread_controller_.trace_observer_,
1207 OnThreadControllerActiveBegin);
1208 EXPECT_CALL(tasks[2], Run());
1209 EXPECT_EQ(thread_controller_.DoWork().delayed_run_time,
1210 TimeTicks());
1211 testing::Mock::VerifyAndClearExpectations(
1212 &*thread_controller_.trace_observer_);
1213
1214 // H:
1215 EXPECT_CALL(*thread_controller_.trace_observer_,
1216 OnThreadControllerActiveEnd);
1217 // The kNested phase (C) ends when the RunLoop exits...
1218 EXPECT_CALL(*thread_controller_.trace_observer_,
1219 OnPhaseRecorded(ThreadController::kNested));
1220 // ... and then the calling task (B) ends.
1221 EXPECT_CALL(
1222 *thread_controller_.trace_observer_,
1223 OnPhaseRecorded(ThreadController::kApplicationTask));
1224 }));
1225 RunLoop(RunLoop::Type::kNestableTasksAllowed).Run();
1226 }));
1227
1228 // B:
1229 EXPECT_EQ(thread_controller_.DoWork().delayed_run_time, TimeTicks());
1230 testing::Mock::VerifyAndClearExpectations(
1231 &*thread_controller_.trace_observer_);
1232
1233 // I:
1234 EXPECT_CALL(*thread_controller_.trace_observer_,
1235 OnPhaseRecorded(ThreadController::kPumpOverhead));
1236 EXPECT_CALL(
1237 *thread_controller_.trace_observer_,
1238 OnPhaseRecorded(ThreadController::kSelectingApplicationTask));
1239 EXPECT_CALL(tasks[3], Run());
1240 EXPECT_CALL(*thread_controller_.trace_observer_,
1241 OnPhaseRecorded(ThreadController::kApplicationTask));
1242 EXPECT_EQ(thread_controller_.DoWork().delayed_run_time,
1243 TimeTicks::Max());
1244 testing::Mock::VerifyAndClearExpectations(
1245 &*thread_controller_.trace_observer_);
1246
1247 EXPECT_CALL(*thread_controller_.trace_observer_,
1248 OnPhaseRecorded(ThreadController::kIdleWork));
1249 EXPECT_CALL(*thread_controller_.trace_observer_,
1250 OnThreadControllerActiveEnd);
1251 EXPECT_FALSE(thread_controller_.DoIdleWork());
1252 testing::Mock::VerifyAndClearExpectations(
1253 &*thread_controller_.trace_observer_);
1254
1255 // J:
1256 task_source_.AddTask(FROM_HERE, tasks[4].Get());
1257 EXPECT_CALL(*thread_controller_.trace_observer_,
1258 OnThreadControllerActiveBegin);
1259 EXPECT_CALL(
1260 *thread_controller_.trace_observer_,
1261 OnPhaseRecorded(ThreadController::kSelectingApplicationTask));
1262 EXPECT_CALL(tasks[4], Run());
1263 EXPECT_CALL(*thread_controller_.trace_observer_,
1264 OnPhaseRecorded(ThreadController::kApplicationTask));
1265 EXPECT_EQ(thread_controller_.DoWork().delayed_run_time,
1266 TimeTicks::Max());
1267 testing::Mock::VerifyAndClearExpectations(
1268 &*thread_controller_.trace_observer_);
1269
1270 EXPECT_CALL(*thread_controller_.trace_observer_,
1271 OnPhaseRecorded(ThreadController::kIdleWork));
1272 EXPECT_CALL(*thread_controller_.trace_observer_,
1273 OnThreadControllerActiveEnd);
1274 EXPECT_FALSE(thread_controller_.DoIdleWork());
1275 testing::Mock::VerifyAndClearExpectations(
1276 &*thread_controller_.trace_observer_);
1277 }));
1278
1279 RunLoop().Run();
1280 }
1281
TEST_F(ThreadControllerWithMessagePumpTest,ThreadControllerActiveNestedNativeLoop)1282 TEST_F(ThreadControllerWithMessagePumpTest,
1283 ThreadControllerActiveNestedNativeLoop) {
1284 SingleThreadTaskRunner::CurrentDefaultHandle handle(
1285 MakeRefCounted<FakeTaskRunner>());
1286
1287 thread_controller_.InstallTraceObserver();
1288
1289 testing::InSequence sequence;
1290
1291 RunLoop run_loop;
1292 EXPECT_CALL(*thread_controller_.trace_observer_,
1293 OnThreadControllerActiveBegin);
1294 EXPECT_CALL(*message_pump_, Run(_))
1295 .WillOnce(Invoke([&](MessagePump::Delegate* delegate) {
1296 MockCallback<OnceClosure> tasks[2];
1297 size_t run_level_depth = delegate->RunDepth();
1298
1299 // A: Post 2 application tasks
1300 // B: Run one of them which allows nested application tasks (enter
1301 // active)
1302 // C: Enter a native nested loop
1303 // D: Run a native task (enter nested active)
1304 // E: Run an application task (remain nested active)
1305 // F: Go idle (exit nested active)
1306 // G: Run a native task (enter nested active)
1307 // H: Exit native nested loop (end nested active)
1308 // I: Go idle (exit active)
1309
1310 // A:
1311 task_source_.AddTask(FROM_HERE, tasks[0].Get());
1312 task_source_.AddTask(FROM_HERE, tasks[1].Get());
1313
1314 EXPECT_CALL(*thread_controller_.trace_observer_,
1315 OnPhaseRecorded(ThreadController::kPumpOverhead));
1316 EXPECT_CALL(
1317 *thread_controller_.trace_observer_,
1318 OnPhaseRecorded(ThreadController::kSelectingApplicationTask));
1319 EXPECT_CALL(tasks[0], Run()).WillOnce(Invoke([&]() {
1320 // C:
1321 EXPECT_FALSE(thread_controller_.IsTaskExecutionAllowed());
1322 EXPECT_CALL(*message_pump_, ScheduleWork());
1323 thread_controller_.SetTaskExecutionAllowed(true);
1324 // i.e. simulate that something runs code within the scope of a
1325 // ScopedAllowApplicationTasksInNativeNestedLoop and ends up entering
1326 // a nested native loop which would invoke OnBeginWorkItem()
1327
1328 // D:
1329
1330 // kChromeTask phase is suspended when the nested native loop is
1331 // entered.
1332 EXPECT_CALL(*thread_controller_.trace_observer_,
1333 OnPhaseRecorded(ThreadController::kApplicationTask));
1334 EXPECT_CALL(*thread_controller_.trace_observer_,
1335 OnThreadControllerActiveBegin);
1336 thread_controller_.OnBeginWorkItem();
1337 testing::Mock::VerifyAndClearExpectations(
1338 &*thread_controller_.trace_observer_);
1339 thread_controller_.OnEndWorkItem(run_level_depth + 1);
1340
1341 // E:
1342 EXPECT_CALL(tasks[1], Run());
1343 EXPECT_EQ(thread_controller_.DoWork().delayed_run_time,
1344 TimeTicks::Max());
1345 testing::Mock::VerifyAndClearExpectations(
1346 &*thread_controller_.trace_observer_);
1347
1348 // F:
1349 EXPECT_CALL(*thread_controller_.trace_observer_,
1350 OnThreadControllerActiveEnd);
1351 EXPECT_FALSE(thread_controller_.DoIdleWork());
1352 testing::Mock::VerifyAndClearExpectations(
1353 &*thread_controller_.trace_observer_);
1354
1355 // G:
1356 EXPECT_CALL(*thread_controller_.trace_observer_,
1357 OnThreadControllerActiveBegin);
1358 thread_controller_.OnBeginWorkItem();
1359 testing::Mock::VerifyAndClearExpectations(
1360 &*thread_controller_.trace_observer_);
1361 thread_controller_.OnEndWorkItem(run_level_depth + 1);
1362
1363 // H:
1364 EXPECT_CALL(*thread_controller_.trace_observer_,
1365 OnThreadControllerActiveEnd);
1366 // The kNested phase (C) ends when the RunLoop exits and kChromeTask
1367 // doesn't resume as task (B) is done.
1368 EXPECT_CALL(*thread_controller_.trace_observer_,
1369 OnPhaseRecorded(ThreadController::kNested));
1370 thread_controller_.SetTaskExecutionAllowed(false);
1371 }));
1372
1373 // B:
1374 EXPECT_EQ(thread_controller_.DoWork().delayed_run_time,
1375 TimeTicks::Max());
1376 testing::Mock::VerifyAndClearExpectations(
1377 &*thread_controller_.trace_observer_);
1378
1379 // I:
1380 EXPECT_CALL(*thread_controller_.trace_observer_,
1381 OnPhaseRecorded(ThreadController::kIdleWork));
1382 EXPECT_CALL(*thread_controller_.trace_observer_,
1383 OnThreadControllerActiveEnd);
1384 EXPECT_FALSE(thread_controller_.DoIdleWork());
1385 testing::Mock::VerifyAndClearExpectations(
1386 &*thread_controller_.trace_observer_);
1387 }));
1388
1389 RunLoop().Run();
1390 }
1391
TEST_F(ThreadControllerWithMessagePumpTest,ThreadControllerActiveUnusedNativeLoop)1392 TEST_F(ThreadControllerWithMessagePumpTest,
1393 ThreadControllerActiveUnusedNativeLoop) {
1394 SingleThreadTaskRunner::CurrentDefaultHandle handle(
1395 MakeRefCounted<FakeTaskRunner>());
1396
1397 thread_controller_.InstallTraceObserver();
1398
1399 testing::InSequence sequence;
1400
1401 RunLoop run_loop;
1402 EXPECT_CALL(*thread_controller_.trace_observer_,
1403 OnThreadControllerActiveBegin);
1404 EXPECT_CALL(*message_pump_, Run(_))
1405 .WillOnce(Invoke([&](MessagePump::Delegate* delegate) {
1406 MockCallback<OnceClosure> tasks[2];
1407
1408 // A: Post 2 application tasks
1409 // B: Run one of them (enter active)
1410 // C: Allow entering a native loop but don't enter one (no-op)
1411 // D: Complete the task without having entered a native loop (no-op)
1412 // E: Run an application task (remain nested active)
1413 // F: Go idle (exit active)
1414
1415 // A:
1416 task_source_.AddTask(FROM_HERE, tasks[0].Get());
1417 task_source_.AddTask(FROM_HERE, tasks[1].Get());
1418
1419 EXPECT_CALL(*thread_controller_.trace_observer_,
1420 OnPhaseRecorded(ThreadController::kPumpOverhead));
1421 EXPECT_CALL(
1422 *thread_controller_.trace_observer_,
1423 OnPhaseRecorded(ThreadController::kSelectingApplicationTask));
1424 EXPECT_CALL(tasks[0], Run()).WillOnce(Invoke([&]() {
1425 // C:
1426 EXPECT_FALSE(thread_controller_.IsTaskExecutionAllowed());
1427 EXPECT_CALL(*message_pump_, ScheduleWork());
1428 thread_controller_.SetTaskExecutionAllowed(true);
1429
1430 // D:
1431 thread_controller_.SetTaskExecutionAllowed(false);
1432 EXPECT_CALL(*thread_controller_.trace_observer_,
1433 OnPhaseRecorded(ThreadController::kApplicationTask));
1434 }));
1435
1436 // B:
1437 EXPECT_EQ(thread_controller_.DoWork().delayed_run_time, TimeTicks());
1438 testing::Mock::VerifyAndClearExpectations(
1439 &*thread_controller_.trace_observer_);
1440
1441 // E:
1442 EXPECT_CALL(*thread_controller_.trace_observer_,
1443 OnPhaseRecorded(ThreadController::kPumpOverhead));
1444 EXPECT_CALL(
1445 *thread_controller_.trace_observer_,
1446 OnPhaseRecorded(ThreadController::kSelectingApplicationTask));
1447 EXPECT_CALL(tasks[1], Run());
1448 EXPECT_CALL(*thread_controller_.trace_observer_,
1449 OnPhaseRecorded(ThreadController::kApplicationTask));
1450 EXPECT_EQ(thread_controller_.DoWork().delayed_run_time,
1451 TimeTicks::Max());
1452 testing::Mock::VerifyAndClearExpectations(
1453 &*thread_controller_.trace_observer_);
1454
1455 // F:
1456 EXPECT_CALL(*thread_controller_.trace_observer_,
1457 OnPhaseRecorded(ThreadController::kIdleWork));
1458 EXPECT_CALL(*thread_controller_.trace_observer_,
1459 OnThreadControllerActiveEnd);
1460 EXPECT_FALSE(thread_controller_.DoIdleWork());
1461 testing::Mock::VerifyAndClearExpectations(
1462 &*thread_controller_.trace_observer_);
1463 }));
1464
1465 RunLoop().Run();
1466 }
1467
TEST_F(ThreadControllerWithMessagePumpTest,ThreadControllerActiveNestedNativeLoopWithoutAllowance)1468 TEST_F(ThreadControllerWithMessagePumpTest,
1469 ThreadControllerActiveNestedNativeLoopWithoutAllowance) {
1470 SingleThreadTaskRunner::CurrentDefaultHandle handle(
1471 MakeRefCounted<FakeTaskRunner>());
1472
1473 thread_controller_.InstallTraceObserver();
1474
1475 testing::InSequence sequence;
1476
1477 RunLoop run_loop;
1478 EXPECT_CALL(*thread_controller_.trace_observer_,
1479 OnThreadControllerActiveBegin);
1480 EXPECT_CALL(*message_pump_, Run(_))
1481 .WillOnce(Invoke([&](MessagePump::Delegate* delegate) {
1482 MockCallback<OnceClosure> tasks[2];
1483 size_t run_level_depth = delegate->RunDepth();
1484
1485 // A: Post 2 application tasks
1486 // B: Run one of them (enter active)
1487 // C: Enter a native nested loop (without having allowed nested
1488 // application tasks in B.)
1489 // D: Run a native task (enter nested active)
1490 // E: End task C. (which implicitly means the native loop is over).
1491 // F: Run an application task (remain active)
1492 // G: Go idle (exit active)
1493
1494 // A:
1495 task_source_.AddTask(FROM_HERE, tasks[0].Get());
1496 task_source_.AddTask(FROM_HERE, tasks[1].Get());
1497
1498 EXPECT_CALL(*thread_controller_.trace_observer_,
1499 OnPhaseRecorded(ThreadController::kPumpOverhead));
1500 EXPECT_CALL(
1501 *thread_controller_.trace_observer_,
1502 OnPhaseRecorded(ThreadController::kSelectingApplicationTask));
1503 EXPECT_CALL(tasks[0], Run()).WillOnce(Invoke([&]() {
1504 // C:
1505 // D:
1506 // kChromeTask phase is suspended when the nested loop is entered.
1507 EXPECT_CALL(*thread_controller_.trace_observer_,
1508 OnPhaseRecorded(ThreadController::kApplicationTask));
1509 EXPECT_CALL(*thread_controller_.trace_observer_,
1510 OnThreadControllerActiveBegin);
1511 thread_controller_.OnBeginWorkItem();
1512 testing::Mock::VerifyAndClearExpectations(
1513 &*thread_controller_.trace_observer_);
1514 thread_controller_.OnEndWorkItem(run_level_depth + 1);
1515
1516 // E:
1517 EXPECT_CALL(*thread_controller_.trace_observer_,
1518 OnThreadControllerActiveEnd);
1519 EXPECT_CALL(*thread_controller_.trace_observer_,
1520 OnPhaseRecorded(ThreadController::kNested));
1521 }));
1522
1523 // B:
1524 EXPECT_EQ(thread_controller_.DoWork().delayed_run_time, TimeTicks());
1525 testing::Mock::VerifyAndClearExpectations(
1526 &*thread_controller_.trace_observer_);
1527
1528 // F:
1529 EXPECT_CALL(*thread_controller_.trace_observer_,
1530 OnPhaseRecorded(ThreadController::kPumpOverhead));
1531 EXPECT_CALL(
1532 *thread_controller_.trace_observer_,
1533 OnPhaseRecorded(ThreadController::kSelectingApplicationTask));
1534 EXPECT_CALL(tasks[1], Run());
1535 EXPECT_CALL(*thread_controller_.trace_observer_,
1536 OnPhaseRecorded(ThreadController::kApplicationTask));
1537 EXPECT_EQ(thread_controller_.DoWork().delayed_run_time,
1538 TimeTicks::Max());
1539
1540 // G:
1541 EXPECT_CALL(*thread_controller_.trace_observer_,
1542 OnPhaseRecorded(ThreadController::kIdleWork));
1543 EXPECT_CALL(*thread_controller_.trace_observer_,
1544 OnThreadControllerActiveEnd);
1545 EXPECT_FALSE(thread_controller_.DoIdleWork());
1546 testing::Mock::VerifyAndClearExpectations(
1547 &*thread_controller_.trace_observer_);
1548 }));
1549
1550 RunLoop().Run();
1551 }
1552
TEST_F(ThreadControllerWithMessagePumpTest,ThreadControllerActiveMultipleNativeLoopsUnderOneApplicationTask)1553 TEST_F(ThreadControllerWithMessagePumpTest,
1554 ThreadControllerActiveMultipleNativeLoopsUnderOneApplicationTask) {
1555 SingleThreadTaskRunner::CurrentDefaultHandle handle(
1556 MakeRefCounted<FakeTaskRunner>());
1557
1558 thread_controller_.InstallTraceObserver();
1559
1560 testing::InSequence sequence;
1561
1562 RunLoop run_loop;
1563 EXPECT_CALL(*thread_controller_.trace_observer_,
1564 OnThreadControllerActiveBegin);
1565 EXPECT_CALL(*message_pump_, Run(_))
1566 .WillOnce(Invoke([&](MessagePump::Delegate* delegate) {
1567 MockCallback<OnceClosure> tasks[2];
1568 size_t run_level_depth = delegate->RunDepth();
1569
1570 // A: Post 1 application task
1571 // B: Run it
1572 // C: Enter a native nested loop (application tasks allowed)
1573 // D: Run a native task (enter nested active)
1574 // E: Exit nested loop (missed by RunLevelTracker -- no-op)
1575 // F: Enter another native nested loop (application tasks allowed)
1576 // G: Run a native task (no-op)
1577 // H: Exit nested loop (no-op)
1578 // I: End task (exit nested active)
1579 // J: Go idle (exit active)
1580
1581 // A:
1582 task_source_.AddTask(FROM_HERE, tasks[0].Get());
1583
1584 EXPECT_CALL(*thread_controller_.trace_observer_,
1585 OnPhaseRecorded(ThreadController::kPumpOverhead));
1586 EXPECT_CALL(
1587 *thread_controller_.trace_observer_,
1588 OnPhaseRecorded(ThreadController::kSelectingApplicationTask));
1589 EXPECT_CALL(tasks[0], Run()).WillOnce(Invoke([&]() {
1590 for (int i = 0; i < 2; ++i) {
1591 // C & F:
1592 EXPECT_FALSE(thread_controller_.IsTaskExecutionAllowed());
1593 EXPECT_CALL(*message_pump_, ScheduleWork());
1594 thread_controller_.SetTaskExecutionAllowed(true);
1595
1596 // D & G:
1597 if (i == 0) {
1598 // kChromeTask phase is suspended when the nested loop is entered.
1599 EXPECT_CALL(*thread_controller_.trace_observer_,
1600 OnPhaseRecorded(ThreadController::kApplicationTask));
1601 EXPECT_CALL(*thread_controller_.trace_observer_,
1602 OnThreadControllerActiveBegin);
1603 }
1604 thread_controller_.OnBeginWorkItem();
1605 testing::Mock::VerifyAndClearExpectations(
1606 &*thread_controller_.trace_observer_);
1607 thread_controller_.OnEndWorkItem(run_level_depth + 1);
1608
1609 // E & H:
1610 thread_controller_.SetTaskExecutionAllowed(false);
1611 testing::Mock::VerifyAndClearExpectations(
1612 &*thread_controller_.trace_observer_);
1613 }
1614
1615 // I:
1616 EXPECT_CALL(*thread_controller_.trace_observer_,
1617 OnThreadControllerActiveEnd);
1618 EXPECT_CALL(*thread_controller_.trace_observer_,
1619 OnPhaseRecorded(ThreadController::kNested));
1620 }));
1621
1622 // B:
1623 EXPECT_EQ(thread_controller_.DoWork().delayed_run_time,
1624 TimeTicks::Max());
1625 testing::Mock::VerifyAndClearExpectations(
1626 &*thread_controller_.trace_observer_);
1627
1628 // J:
1629 EXPECT_CALL(*thread_controller_.trace_observer_,
1630 OnPhaseRecorded(ThreadController::kIdleWork));
1631 EXPECT_CALL(*thread_controller_.trace_observer_,
1632 OnThreadControllerActiveEnd);
1633 EXPECT_FALSE(thread_controller_.DoIdleWork());
1634 testing::Mock::VerifyAndClearExpectations(
1635 &*thread_controller_.trace_observer_);
1636 }));
1637
1638 RunLoop().Run();
1639 }
1640
TEST_F(ThreadControllerWithMessagePumpTest,ThreadControllerActiveNativeLoopsReachingIdle)1641 TEST_F(ThreadControllerWithMessagePumpTest,
1642 ThreadControllerActiveNativeLoopsReachingIdle) {
1643 SingleThreadTaskRunner::CurrentDefaultHandle handle(
1644 MakeRefCounted<FakeTaskRunner>());
1645
1646 thread_controller_.InstallTraceObserver();
1647
1648 testing::InSequence sequence;
1649
1650 RunLoop run_loop;
1651 EXPECT_CALL(*thread_controller_.trace_observer_,
1652 OnThreadControllerActiveBegin);
1653 EXPECT_CALL(*message_pump_, Run(_))
1654 .WillOnce(Invoke([&](MessagePump::Delegate* delegate) {
1655 MockCallback<OnceClosure> task;
1656 size_t run_level_depth = delegate->RunDepth();
1657
1658 // A: Post 1 application task
1659 // B: Run it
1660 // C: Enter a native nested loop (application tasks allowed)
1661 // D: Run a native task (enter nested active)
1662 // E: Reach idle (nested inactive)
1663 // F: Run another task (nested active)
1664 // G: Exit nested loop (missed by RunLevelTracker -- no-op)
1665 // H: End task B (exit nested active)
1666 // I: Go idle (exit active)
1667 //
1668 // This exercises the heuristic in
1669 // ThreadControllerWithMessagePumpImpl::SetTaskExecutionAllowed() to
1670 // detect the end of a nested native loop before the end of the task
1671 // that triggered it. When application tasks are not allowed however,
1672 // there's nothing we can do detect and two native nested loops in a
1673 // row. They may look like a single one if the first one is quit before
1674 // it reaches idle.
1675
1676 // A:
1677 task_source_.AddTask(FROM_HERE, task.Get());
1678
1679 EXPECT_CALL(*thread_controller_.trace_observer_,
1680 OnPhaseRecorded(ThreadController::kPumpOverhead));
1681 EXPECT_CALL(
1682 *thread_controller_.trace_observer_,
1683 OnPhaseRecorded(ThreadController::kSelectingApplicationTask));
1684 EXPECT_CALL(task, Run()).WillOnce(Invoke([&]() {
1685 // C:
1686 EXPECT_FALSE(thread_controller_.IsTaskExecutionAllowed());
1687 EXPECT_CALL(*message_pump_, ScheduleWork());
1688 thread_controller_.SetTaskExecutionAllowed(true);
1689
1690 // D:
1691 // kChromeTask phase is suspended when the nested loop is entered.
1692 EXPECT_CALL(*thread_controller_.trace_observer_,
1693 OnPhaseRecorded(ThreadController::kApplicationTask));
1694 EXPECT_CALL(*thread_controller_.trace_observer_,
1695 OnThreadControllerActiveBegin);
1696 thread_controller_.OnBeginWorkItem();
1697 testing::Mock::VerifyAndClearExpectations(
1698 &*thread_controller_.trace_observer_);
1699 thread_controller_.OnEndWorkItem(run_level_depth + 1);
1700
1701 // E:
1702 EXPECT_CALL(*thread_controller_.trace_observer_,
1703 OnThreadControllerActiveEnd);
1704 thread_controller_.BeforeWait();
1705 testing::Mock::VerifyAndClearExpectations(
1706 &*thread_controller_.trace_observer_);
1707
1708 // F:
1709 EXPECT_CALL(*thread_controller_.trace_observer_,
1710 OnThreadControllerActiveBegin);
1711 thread_controller_.OnBeginWorkItem();
1712 testing::Mock::VerifyAndClearExpectations(
1713 &*thread_controller_.trace_observer_);
1714 thread_controller_.OnEndWorkItem(run_level_depth + 1);
1715
1716 // G:
1717 thread_controller_.SetTaskExecutionAllowed(false);
1718
1719 // H:
1720 EXPECT_CALL(*thread_controller_.trace_observer_,
1721 OnThreadControllerActiveEnd);
1722 EXPECT_CALL(*thread_controller_.trace_observer_,
1723 OnPhaseRecorded(ThreadController::kNested));
1724 }));
1725
1726 // B:
1727 EXPECT_EQ(thread_controller_.DoWork().delayed_run_time,
1728 TimeTicks::Max());
1729 testing::Mock::VerifyAndClearExpectations(
1730 &*thread_controller_.trace_observer_);
1731
1732 // I:
1733 EXPECT_CALL(*thread_controller_.trace_observer_,
1734 OnPhaseRecorded(ThreadController::kIdleWork));
1735 EXPECT_CALL(*thread_controller_.trace_observer_,
1736 OnThreadControllerActiveEnd);
1737 EXPECT_FALSE(thread_controller_.DoIdleWork());
1738 testing::Mock::VerifyAndClearExpectations(
1739 &*thread_controller_.trace_observer_);
1740 }));
1741
1742 RunLoop().Run();
1743 }
1744
TEST_F(ThreadControllerWithMessagePumpTest,ThreadControllerActiveQuitNestedWhileApplicationIdle)1745 TEST_F(ThreadControllerWithMessagePumpTest,
1746 ThreadControllerActiveQuitNestedWhileApplicationIdle) {
1747 SingleThreadTaskRunner::CurrentDefaultHandle handle(
1748 MakeRefCounted<FakeTaskRunner>());
1749
1750 thread_controller_.InstallTraceObserver();
1751
1752 testing::InSequence sequence;
1753
1754 RunLoop run_loop;
1755 EXPECT_CALL(*thread_controller_.trace_observer_,
1756 OnThreadControllerActiveBegin);
1757 EXPECT_CALL(*message_pump_, Run(_))
1758 .WillOnce(Invoke([&](MessagePump::Delegate* delegate) {
1759 MockCallback<OnceClosure> tasks[2];
1760
1761 // A: Post 2 application tasks
1762 // B: Run the first task
1763 // C: Enter a native nested loop (application tasks allowed)
1764 // D: Run the second task (enter nested active)
1765 // E: Reach idle
1766 // F: Run a native task (not visible to RunLevelTracker)
1767 // G: F quits the native nested loop (no-op)
1768 // H: End task B (exit nested active)
1769 // I: Go idle (exit active)
1770
1771 // A:
1772 task_source_.AddTask(FROM_HERE, tasks[0].Get());
1773 task_source_.AddTask(FROM_HERE, tasks[1].Get());
1774
1775 EXPECT_CALL(*thread_controller_.trace_observer_,
1776 OnPhaseRecorded(ThreadController::kPumpOverhead));
1777 EXPECT_CALL(
1778 *thread_controller_.trace_observer_,
1779 OnPhaseRecorded(ThreadController::kSelectingApplicationTask));
1780 EXPECT_CALL(tasks[0], Run()).WillOnce(Invoke([&]() {
1781 // C:
1782 EXPECT_FALSE(thread_controller_.IsTaskExecutionAllowed());
1783 EXPECT_CALL(*message_pump_, ScheduleWork());
1784 thread_controller_.SetTaskExecutionAllowed(true);
1785
1786 // D:
1787 // kChromeTask phase is suspended when the nested loop is entered.
1788 EXPECT_CALL(*thread_controller_.trace_observer_,
1789 OnPhaseRecorded(ThreadController::kApplicationTask));
1790 EXPECT_CALL(*thread_controller_.trace_observer_,
1791 OnThreadControllerActiveBegin);
1792 EXPECT_CALL(tasks[1], Run());
1793 EXPECT_EQ(thread_controller_.DoWork().delayed_run_time,
1794 TimeTicks::Max());
1795 testing::Mock::VerifyAndClearExpectations(
1796 &*thread_controller_.trace_observer_);
1797
1798 // E:
1799 EXPECT_CALL(*thread_controller_.trace_observer_,
1800 OnThreadControllerActiveEnd);
1801 thread_controller_.BeforeWait();
1802 testing::Mock::VerifyAndClearExpectations(
1803 &*thread_controller_.trace_observer_);
1804
1805 // F + G:
1806 thread_controller_.SetTaskExecutionAllowed(false);
1807
1808 // H:
1809 EXPECT_CALL(*thread_controller_.trace_observer_,
1810 OnPhaseRecorded(ThreadController::kNested));
1811 }));
1812
1813 // B:
1814 EXPECT_EQ(thread_controller_.DoWork().delayed_run_time,
1815 TimeTicks::Max());
1816 testing::Mock::VerifyAndClearExpectations(
1817 &*thread_controller_.trace_observer_);
1818
1819 // I:
1820 EXPECT_CALL(*thread_controller_.trace_observer_,
1821 OnPhaseRecorded(ThreadController::kIdleWork));
1822 EXPECT_CALL(*thread_controller_.trace_observer_,
1823 OnThreadControllerActiveEnd);
1824 EXPECT_FALSE(thread_controller_.DoIdleWork());
1825 testing::Mock::VerifyAndClearExpectations(
1826 &*thread_controller_.trace_observer_);
1827 }));
1828
1829 RunLoop().Run();
1830 }
1831
1832 // This test verifies the edge case where the first task on the stack is native
1833 // task which spins a native nested loop. That inner-loop should be allowed to
1834 // execute application tasks as the outer-loop didn't consume
1835 // |task_execution_allowed == true|. RunLevelTracker should support this use
1836 // case as well.
TEST_F(ThreadControllerWithMessagePumpTest,ThreadControllerActiveNestedWithinNativeAllowsApplicationTasks)1837 TEST_F(ThreadControllerWithMessagePumpTest,
1838 ThreadControllerActiveNestedWithinNativeAllowsApplicationTasks) {
1839 SingleThreadTaskRunner::CurrentDefaultHandle handle(
1840 MakeRefCounted<FakeTaskRunner>());
1841
1842 thread_controller_.InstallTraceObserver();
1843
1844 testing::InSequence sequence;
1845
1846 RunLoop run_loop;
1847 EXPECT_CALL(*thread_controller_.trace_observer_,
1848 OnThreadControllerActiveBegin);
1849 EXPECT_CALL(*message_pump_, Run(_))
1850 .WillOnce(Invoke([&](MessagePump::Delegate* delegate) {
1851 // Start this test idle for a change.
1852 EXPECT_CALL(*thread_controller_.trace_observer_,
1853 OnPhaseRecorded(ThreadController::kIdleWork));
1854 EXPECT_CALL(*thread_controller_.trace_observer_,
1855 OnThreadControllerActiveEnd);
1856 EXPECT_FALSE(thread_controller_.DoIdleWork());
1857 testing::Mock::VerifyAndClearExpectations(
1858 &*thread_controller_.trace_observer_);
1859
1860 MockCallback<OnceClosure> task;
1861 size_t run_level_depth = delegate->RunDepth();
1862
1863 // A: Post 1 application task
1864 // B: Run a native task
1865 // C: Enter a native nested loop (application tasks still allowed)
1866 // D: Run the application task (enter nested active)
1867 // E: End the native task (exit nested active)
1868 // F: Go idle (exit active)
1869
1870 // A:
1871 task_source_.AddTask(FROM_HERE, task.Get());
1872
1873 EXPECT_CALL(*thread_controller_.trace_observer_,
1874 OnThreadControllerActiveBegin)
1875 .WillOnce(Invoke([&]() {
1876 // C:
1877 EXPECT_TRUE(thread_controller_.IsTaskExecutionAllowed());
1878
1879 // D:
1880 // kNativeWork phase is suspended when the nested loop is entered.
1881 EXPECT_CALL(*thread_controller_.trace_observer_,
1882 OnPhaseRecorded(ThreadController::kNativeWork));
1883 EXPECT_CALL(*thread_controller_.trace_observer_,
1884 OnThreadControllerActiveBegin);
1885 EXPECT_CALL(task, Run());
1886 EXPECT_EQ(thread_controller_.DoWork().delayed_run_time,
1887 TimeTicks::Max());
1888 testing::Mock::VerifyAndClearExpectations(
1889 &*thread_controller_.trace_observer_);
1890 }));
1891
1892 // B:
1893 thread_controller_.OnBeginWorkItem();
1894 testing::Mock::VerifyAndClearExpectations(
1895 &*thread_controller_.trace_observer_);
1896
1897 // E:
1898 EXPECT_CALL(*thread_controller_.trace_observer_,
1899 OnThreadControllerActiveEnd);
1900 EXPECT_CALL(*thread_controller_.trace_observer_,
1901 OnPhaseRecorded(ThreadController::kNested));
1902 thread_controller_.OnEndWorkItem(run_level_depth);
1903
1904 // F:
1905 EXPECT_CALL(*thread_controller_.trace_observer_,
1906 OnPhaseRecorded(ThreadController::kIdleWork));
1907 EXPECT_CALL(*thread_controller_.trace_observer_,
1908 OnThreadControllerActiveEnd);
1909 EXPECT_FALSE(thread_controller_.DoIdleWork());
1910 testing::Mock::VerifyAndClearExpectations(
1911 &*thread_controller_.trace_observer_);
1912 }));
1913
1914 RunLoop().Run();
1915 }
1916
1917 // Same as ThreadControllerActiveNestedWithinNativeAllowsApplicationTasks but
1918 // with a dummy ScopedAllowApplicationTasksInNativeNestedLoop that is a
1919 // true=>true no-op for SetTaskExecutionAllowed(). This is a regression test
1920 // against another discussed implementation for RunLevelTracker which
1921 // would have used ScopedAllowApplicationTasksInNativeNestedLoop as a hint of
1922 // nested native loops. Doing so would have been incorrect because it assumes
1923 // that ScopedAllowApplicationTasksInNativeNestedLoop always toggles the
1924 // allowance away-from and back-to |false|.
TEST_F(ThreadControllerWithMessagePumpTest,ThreadControllerActiveDummyScopedAllowApplicationTasks)1925 TEST_F(ThreadControllerWithMessagePumpTest,
1926 ThreadControllerActiveDummyScopedAllowApplicationTasks) {
1927 SingleThreadTaskRunner::CurrentDefaultHandle handle(
1928 MakeRefCounted<FakeTaskRunner>());
1929
1930 thread_controller_.InstallTraceObserver();
1931
1932 testing::InSequence sequence;
1933
1934 RunLoop run_loop;
1935 EXPECT_CALL(*thread_controller_.trace_observer_,
1936 OnThreadControllerActiveBegin);
1937 EXPECT_CALL(*message_pump_, Run(_))
1938 .WillOnce(Invoke([&](MessagePump::Delegate* delegate) {
1939 // Start this test idle for a change.
1940 EXPECT_CALL(*thread_controller_.trace_observer_,
1941 OnPhaseRecorded(ThreadController::kIdleWork));
1942 EXPECT_CALL(*thread_controller_.trace_observer_,
1943 OnThreadControllerActiveEnd);
1944 EXPECT_FALSE(thread_controller_.DoIdleWork());
1945 testing::Mock::VerifyAndClearExpectations(
1946 &*thread_controller_.trace_observer_);
1947
1948 MockCallback<OnceClosure> task;
1949 size_t run_level_depth = delegate->RunDepth();
1950
1951 // A: Post 1 application task
1952 // B: Run a native task
1953 // C: Enter dummy ScopedAllowApplicationTasksInNativeNestedLoop
1954 // D: Enter a native nested loop (application tasks still allowed)
1955 // E: Run the application task (enter nested active)
1956 // F: Exit dummy scope (SetTaskExecutionAllowed(true)).
1957 // G: End the native task (exit nested active)
1958 // H: Go idle (exit active)
1959
1960 // A:
1961 task_source_.AddTask(FROM_HERE, task.Get());
1962
1963 EXPECT_CALL(*thread_controller_.trace_observer_,
1964 OnThreadControllerActiveBegin)
1965 .WillOnce(Invoke([&]() {
1966 // C + D:
1967 EXPECT_TRUE(thread_controller_.IsTaskExecutionAllowed());
1968 EXPECT_CALL(*message_pump_, ScheduleWork());
1969 thread_controller_.SetTaskExecutionAllowed(true);
1970 testing::Mock::VerifyAndClearExpectations(
1971 &*thread_controller_.trace_observer_);
1972
1973 // E:
1974 // kNativeWork phase is suspended when the nested loop is entered.
1975 EXPECT_CALL(*thread_controller_.trace_observer_,
1976 OnPhaseRecorded(ThreadController::kNativeWork));
1977 EXPECT_CALL(*thread_controller_.trace_observer_,
1978 OnThreadControllerActiveBegin);
1979 EXPECT_CALL(task, Run());
1980 EXPECT_EQ(thread_controller_.DoWork().delayed_run_time,
1981 TimeTicks::Max());
1982 testing::Mock::VerifyAndClearExpectations(
1983 &*thread_controller_.trace_observer_);
1984
1985 // F:
1986 EXPECT_CALL(*message_pump_, ScheduleWork());
1987 thread_controller_.SetTaskExecutionAllowed(true);
1988 }));
1989
1990 // B:
1991 thread_controller_.OnBeginWorkItem();
1992 testing::Mock::VerifyAndClearExpectations(
1993 &*thread_controller_.trace_observer_);
1994
1995 // G:
1996 EXPECT_CALL(*thread_controller_.trace_observer_,
1997 OnThreadControllerActiveEnd);
1998 EXPECT_CALL(*thread_controller_.trace_observer_,
1999 OnPhaseRecorded(ThreadController::kNested));
2000 thread_controller_.OnEndWorkItem(run_level_depth);
2001
2002 // H:
2003 EXPECT_CALL(*thread_controller_.trace_observer_,
2004 OnPhaseRecorded(ThreadController::kIdleWork));
2005 EXPECT_CALL(*thread_controller_.trace_observer_,
2006 OnThreadControllerActiveEnd);
2007 EXPECT_FALSE(thread_controller_.DoIdleWork());
2008 testing::Mock::VerifyAndClearExpectations(
2009 &*thread_controller_.trace_observer_);
2010 }));
2011
2012 RunLoop().Run();
2013 }
2014
2015 // Verify that the kScheduled phase is emitted when coming out of idle and
2016 // `queue_time` is set on PendingTasks.
TEST_F(ThreadControllerWithMessagePumpTest,MessagePumpPhasesWithQueuingTime)2017 TEST_F(ThreadControllerWithMessagePumpTest, MessagePumpPhasesWithQueuingTime) {
2018 SingleThreadTaskRunner::CurrentDefaultHandle handle(
2019 MakeRefCounted<FakeTaskRunner>());
2020
2021 thread_controller_.InstallTraceObserver();
2022
2023 testing::InSequence sequence;
2024
2025 RunLoop run_loop;
2026 EXPECT_CALL(*thread_controller_.trace_observer_,
2027 OnThreadControllerActiveBegin);
2028 EXPECT_CALL(*message_pump_, Run(_))
2029 .WillOnce(Invoke([&](MessagePump::Delegate* delegate) {
2030 // Start this test idle.
2031 EXPECT_CALL(*thread_controller_.trace_observer_,
2032 OnPhaseRecorded(ThreadController::kIdleWork));
2033 EXPECT_CALL(*thread_controller_.trace_observer_,
2034 OnThreadControllerActiveEnd);
2035 EXPECT_FALSE(thread_controller_.DoIdleWork());
2036 testing::Mock::VerifyAndClearExpectations(
2037 &*thread_controller_.trace_observer_);
2038
2039 MockCallback<OnceClosure> task1;
2040 task_source_.AddTask(FROM_HERE, task1.Get(),
2041 /*delayed_run_time=*/TimeTicks(),
2042 /*queue_time=*/clock_.NowTicks());
2043 MockCallback<OnceClosure> task2;
2044 task_source_.AddTask(FROM_HERE, task2.Get(),
2045 /*delayed_run_time=*/TimeTicks(),
2046 /*queue_time=*/clock_.NowTicks());
2047 // kScheduled is only emitted if in past.
2048 clock_.Advance(Milliseconds(1));
2049
2050 EXPECT_CALL(*thread_controller_.trace_observer_,
2051 OnThreadControllerActiveBegin);
2052 EXPECT_CALL(*thread_controller_.trace_observer_,
2053 OnPhaseRecorded(ThreadController::kScheduled));
2054 EXPECT_CALL(
2055 *thread_controller_.trace_observer_,
2056 OnPhaseRecorded(ThreadController::kSelectingApplicationTask));
2057 EXPECT_CALL(task1, Run());
2058 EXPECT_CALL(*thread_controller_.trace_observer_,
2059 OnPhaseRecorded(ThreadController::kApplicationTask));
2060 EXPECT_EQ(thread_controller_.DoWork().delayed_run_time, TimeTicks());
2061
2062 EXPECT_CALL(*thread_controller_.trace_observer_,
2063 OnPhaseRecorded(ThreadController::kPumpOverhead));
2064 EXPECT_CALL(
2065 *thread_controller_.trace_observer_,
2066 OnPhaseRecorded(ThreadController::kSelectingApplicationTask));
2067 EXPECT_CALL(task2, Run());
2068 EXPECT_CALL(*thread_controller_.trace_observer_,
2069 OnPhaseRecorded(ThreadController::kApplicationTask));
2070 EXPECT_EQ(thread_controller_.DoWork().delayed_run_time,
2071 TimeTicks::Max());
2072
2073 testing::Mock::VerifyAndClearExpectations(
2074 &*thread_controller_.trace_observer_);
2075
2076 EXPECT_CALL(*thread_controller_.trace_observer_,
2077 OnPhaseRecorded(ThreadController::kIdleWork));
2078 EXPECT_CALL(*thread_controller_.trace_observer_,
2079 OnThreadControllerActiveEnd);
2080 EXPECT_FALSE(thread_controller_.DoIdleWork());
2081
2082 testing::Mock::VerifyAndClearExpectations(
2083 &*thread_controller_.trace_observer_);
2084 }));
2085
2086 RunLoop().Run();
2087 }
2088
2089 } // namespace base::sequence_manager::internal
2090