| 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 |