OLD | NEW |
| (Empty) |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | |
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 "components/scheduler/child/scheduler_helper.h" | |
6 | |
7 #include "base/callback.h" | |
8 #include "base/macros.h" | |
9 #include "base/memory/ptr_util.h" | |
10 #include "base/test/simple_test_tick_clock.h" | |
11 #include "cc/test/ordered_simple_task_runner.h" | |
12 #include "components/scheduler/base/lazy_now.h" | |
13 #include "components/scheduler/base/task_queue.h" | |
14 #include "components/scheduler/base/test_time_source.h" | |
15 #include "components/scheduler/child/scheduler_tqm_delegate_for_test.h" | |
16 #include "testing/gmock/include/gmock/gmock.h" | |
17 #include "testing/gtest/include/gtest/gtest.h" | |
18 | |
19 using testing::_; | |
20 using testing::AnyNumber; | |
21 using testing::Invoke; | |
22 using testing::Return; | |
23 | |
24 namespace scheduler { | |
25 | |
26 namespace { | |
27 void AppendToVectorTestTask(std::vector<std::string>* vector, | |
28 std::string value) { | |
29 vector->push_back(value); | |
30 } | |
31 | |
32 void AppendToVectorReentrantTask(base::SingleThreadTaskRunner* task_runner, | |
33 std::vector<int>* vector, | |
34 int* reentrant_count, | |
35 int max_reentrant_count) { | |
36 vector->push_back((*reentrant_count)++); | |
37 if (*reentrant_count < max_reentrant_count) { | |
38 task_runner->PostTask( | |
39 FROM_HERE, | |
40 base::Bind(AppendToVectorReentrantTask, base::Unretained(task_runner), | |
41 vector, reentrant_count, max_reentrant_count)); | |
42 } | |
43 } | |
44 | |
45 }; // namespace | |
46 | |
47 class SchedulerHelperTest : public testing::Test { | |
48 public: | |
49 SchedulerHelperTest() | |
50 : clock_(new base::SimpleTestTickClock()), | |
51 mock_task_runner_(new cc::OrderedSimpleTaskRunner(clock_.get(), false)), | |
52 main_task_runner_(SchedulerTqmDelegateForTest::Create( | |
53 mock_task_runner_, | |
54 base::WrapUnique(new TestTimeSource(clock_.get())))), | |
55 scheduler_helper_(new SchedulerHelper( | |
56 main_task_runner_, | |
57 "test.scheduler", | |
58 TRACE_DISABLED_BY_DEFAULT("test.scheduler"), | |
59 TRACE_DISABLED_BY_DEFAULT("test.scheduler.dbg"))), | |
60 default_task_runner_(scheduler_helper_->DefaultTaskRunner()) { | |
61 clock_->Advance(base::TimeDelta::FromMicroseconds(5000)); | |
62 } | |
63 | |
64 ~SchedulerHelperTest() override {} | |
65 | |
66 void TearDown() override { | |
67 // Check that all tests stop posting tasks. | |
68 mock_task_runner_->SetAutoAdvanceNowToPendingTasks(true); | |
69 while (mock_task_runner_->RunUntilIdle()) { | |
70 } | |
71 } | |
72 | |
73 void RunUntilIdle() { mock_task_runner_->RunUntilIdle(); } | |
74 | |
75 template <typename E> | |
76 static void CallForEachEnumValue(E first, | |
77 E last, | |
78 const char* (*function)(E)) { | |
79 for (E val = first; val < last; | |
80 val = static_cast<E>(static_cast<int>(val) + 1)) { | |
81 (*function)(val); | |
82 } | |
83 } | |
84 | |
85 protected: | |
86 std::unique_ptr<base::SimpleTestTickClock> clock_; | |
87 scoped_refptr<cc::OrderedSimpleTaskRunner> mock_task_runner_; | |
88 | |
89 scoped_refptr<SchedulerTqmDelegateForTest> main_task_runner_; | |
90 std::unique_ptr<SchedulerHelper> scheduler_helper_; | |
91 scoped_refptr<base::SingleThreadTaskRunner> default_task_runner_; | |
92 | |
93 DISALLOW_COPY_AND_ASSIGN(SchedulerHelperTest); | |
94 }; | |
95 | |
96 TEST_F(SchedulerHelperTest, TestPostDefaultTask) { | |
97 std::vector<std::string> run_order; | |
98 default_task_runner_->PostTask( | |
99 FROM_HERE, base::Bind(&AppendToVectorTestTask, &run_order, "D1")); | |
100 default_task_runner_->PostTask( | |
101 FROM_HERE, base::Bind(&AppendToVectorTestTask, &run_order, "D2")); | |
102 default_task_runner_->PostTask( | |
103 FROM_HERE, base::Bind(&AppendToVectorTestTask, &run_order, "D3")); | |
104 default_task_runner_->PostTask( | |
105 FROM_HERE, base::Bind(&AppendToVectorTestTask, &run_order, "D4")); | |
106 | |
107 RunUntilIdle(); | |
108 EXPECT_THAT(run_order, | |
109 testing::ElementsAre(std::string("D1"), std::string("D2"), | |
110 std::string("D3"), std::string("D4"))); | |
111 } | |
112 | |
113 TEST_F(SchedulerHelperTest, TestRentrantTask) { | |
114 int count = 0; | |
115 std::vector<int> run_order; | |
116 default_task_runner_->PostTask( | |
117 FROM_HERE, base::Bind(AppendToVectorReentrantTask, | |
118 base::RetainedRef(default_task_runner_), &run_order, | |
119 &count, 5)); | |
120 RunUntilIdle(); | |
121 | |
122 EXPECT_THAT(run_order, testing::ElementsAre(0, 1, 2, 3, 4)); | |
123 } | |
124 | |
125 TEST_F(SchedulerHelperTest, IsShutdown) { | |
126 EXPECT_FALSE(scheduler_helper_->IsShutdown()); | |
127 | |
128 scheduler_helper_->Shutdown(); | |
129 EXPECT_TRUE(scheduler_helper_->IsShutdown()); | |
130 } | |
131 | |
132 TEST_F(SchedulerHelperTest, DefaultTaskRunnerRegistration) { | |
133 EXPECT_EQ(main_task_runner_->default_task_runner(), | |
134 scheduler_helper_->DefaultTaskRunner()); | |
135 scheduler_helper_->Shutdown(); | |
136 EXPECT_EQ(nullptr, main_task_runner_->default_task_runner()); | |
137 } | |
138 | |
139 namespace { | |
140 class MockTaskObserver : public base::MessageLoop::TaskObserver { | |
141 public: | |
142 MOCK_METHOD1(DidProcessTask, void(const base::PendingTask& task)); | |
143 MOCK_METHOD1(WillProcessTask, void(const base::PendingTask& task)); | |
144 }; | |
145 | |
146 void NopTask() {} | |
147 } // namespace | |
148 | |
149 TEST_F(SchedulerHelperTest, ObserversNotifiedFor_DefaultTaskRunner) { | |
150 MockTaskObserver observer; | |
151 scheduler_helper_->AddTaskObserver(&observer); | |
152 | |
153 scheduler_helper_->DefaultTaskRunner()->PostTask(FROM_HERE, | |
154 base::Bind(&NopTask)); | |
155 | |
156 EXPECT_CALL(observer, WillProcessTask(_)).Times(1); | |
157 EXPECT_CALL(observer, DidProcessTask(_)).Times(1); | |
158 RunUntilIdle(); | |
159 } | |
160 | |
161 TEST_F(SchedulerHelperTest, ObserversNotNotifiedFor_ControlTaskRunner) { | |
162 MockTaskObserver observer; | |
163 scheduler_helper_->AddTaskObserver(&observer); | |
164 | |
165 scheduler_helper_->ControlTaskRunner()->PostTask(FROM_HERE, | |
166 base::Bind(&NopTask)); | |
167 | |
168 EXPECT_CALL(observer, WillProcessTask(_)).Times(0); | |
169 EXPECT_CALL(observer, DidProcessTask(_)).Times(0); | |
170 RunUntilIdle(); | |
171 } | |
172 | |
173 TEST_F(SchedulerHelperTest, | |
174 ObserversNotNotifiedFor_ControlAfterWakeUpTaskRunner) { | |
175 MockTaskObserver observer; | |
176 scheduler_helper_->AddTaskObserver(&observer); | |
177 | |
178 scheduler_helper_->ControlAfterWakeUpTaskRunner()->PostTask( | |
179 FROM_HERE, base::Bind(&NopTask)); | |
180 | |
181 EXPECT_CALL(observer, WillProcessTask(_)).Times(0); | |
182 EXPECT_CALL(observer, DidProcessTask(_)).Times(0); | |
183 LazyNow lazy_now(clock_.get()); | |
184 scheduler_helper_->ControlAfterWakeUpTaskRunner()->PumpQueue(&lazy_now, true); | |
185 RunUntilIdle(); | |
186 } | |
187 | |
188 namespace { | |
189 | |
190 class MockObserver : public SchedulerHelper::Observer { | |
191 public: | |
192 MOCK_METHOD1(OnUnregisterTaskQueue, | |
193 void(const scoped_refptr<TaskQueue>& queue)); | |
194 MOCK_METHOD2(OnTriedToExecuteBlockedTask, | |
195 void(const TaskQueue& queue, const base::PendingTask& task)); | |
196 }; | |
197 | |
198 } // namespace | |
199 | |
200 TEST_F(SchedulerHelperTest, OnUnregisterTaskQueue) { | |
201 MockObserver observer; | |
202 scheduler_helper_->SetObserver(&observer); | |
203 | |
204 scoped_refptr<TaskQueue> task_queue = | |
205 scheduler_helper_->NewTaskQueue(TaskQueue::Spec("test_queue")); | |
206 | |
207 EXPECT_CALL(observer, OnUnregisterTaskQueue(_)).Times(1); | |
208 task_queue->UnregisterTaskQueue(); | |
209 | |
210 scheduler_helper_->SetObserver(nullptr); | |
211 } | |
212 | |
213 TEST_F(SchedulerHelperTest, OnTriedToExecuteBlockedTask) { | |
214 MockObserver observer; | |
215 scheduler_helper_->SetObserver(&observer); | |
216 | |
217 scoped_refptr<TaskQueue> task_queue = scheduler_helper_->NewTaskQueue( | |
218 TaskQueue::Spec("test_queue").SetShouldReportWhenExecutionBlocked(true)); | |
219 task_queue->SetQueueEnabled(false); | |
220 task_queue->PostTask(FROM_HERE, base::Bind(&NopTask)); | |
221 | |
222 EXPECT_CALL(observer, OnTriedToExecuteBlockedTask(_, _)).Times(1); | |
223 RunUntilIdle(); | |
224 | |
225 scheduler_helper_->SetObserver(nullptr); | |
226 } | |
227 | |
228 } // namespace scheduler | |
OLD | NEW |