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 "content/renderer/scheduler/renderer_scheduler_selector.h" | |
6 | |
7 #include "base/bind.h" | |
8 #include "base/memory/scoped_ptr.h" | |
9 #include "base/pending_task.h" | |
10 #include "testing/gmock/include/gmock/gmock.h" | |
Sami
2014/10/27 11:23:02
nit: I keep hearing rumors that gmock is deprecate
rmcilroy
2014/10/27 13:08:06
I'm only using this for testing::ElementsAre(). I
Sami
2014/10/27 13:44:40
I think that's fine to use it here. I couldn't fin
| |
11 #include "testing/gtest/include/gtest/gtest.h" | |
12 | |
13 namespace content { | |
14 | |
15 class RendererSchedulerSelectorTest : public testing::Test { | |
16 public: | |
17 RendererSchedulerSelectorTest() | |
18 : test_closure_(base::Bind(&RendererSchedulerSelectorTest::TestFunction)), | |
19 selector_(), | |
20 task_queues_() {} | |
21 virtual ~RendererSchedulerSelectorTest() {} | |
22 | |
23 std::vector<base::PendingTask> GetTasks(int count) { | |
24 std::vector<base::PendingTask> tasks; | |
25 for (int i = 0; i < count; i++) { | |
26 base::PendingTask task = base::PendingTask(FROM_HERE, test_closure_); | |
27 task.sequence_num = i; | |
28 tasks.push_back(task); | |
29 } | |
30 return tasks; | |
31 } | |
32 | |
33 void PushTasks(std::vector<base::PendingTask> tasks, | |
Sami
2014/10/27 11:23:02
nit: |tasks| could be a const ref.
rmcilroy
2014/10/27 13:08:06
Done.
| |
34 std::vector<size_t> queue_indices) { | |
35 EXPECT_EQ(tasks.size(), queue_indices.size()); | |
36 for (size_t i = 0; i < tasks.size(); i++) { | |
37 task_queues_[queue_indices[i]]->push(tasks[i]); | |
38 } | |
39 } | |
40 | |
41 std::vector<size_t> SelectedQueueOrder() { | |
42 std::vector<size_t> order; | |
43 size_t chosen_queue_index; | |
44 while (selector_.SelectWorkQueueToService(&chosen_queue_index)) { | |
45 order.push_back(chosen_queue_index); | |
46 task_queues_[chosen_queue_index]->pop(); | |
47 } | |
48 return order; | |
49 } | |
50 | |
51 static void TestFunction() {} | |
52 | |
53 protected: | |
54 virtual void SetUp() { | |
55 std::vector<const base::TaskQueue*> const_task_queues_; | |
56 for (size_t i = 0; i < kTaskQueueCount; i++) { | |
57 scoped_ptr<base::TaskQueue> task_queue = | |
58 make_scoped_ptr(new base::TaskQueue()); | |
59 const_task_queues_.push_back(task_queue.get()); | |
60 task_queues_.push_back(task_queue.Pass()); | |
61 } | |
62 selector_.RegisterWorkQueues(const_task_queues_); | |
63 } | |
64 | |
65 size_t kTaskQueueCount = 5; | |
66 base::Closure test_closure_; | |
67 RendererSchedulerSelector selector_; | |
68 std::vector<scoped_ptr<base::TaskQueue>> task_queues_; | |
69 }; | |
70 | |
71 TEST_F(RendererSchedulerSelectorTest, TestDefaultPriority) { | |
72 std::vector<base::PendingTask> tasks = GetTasks(5); | |
73 PushTasks(tasks, std::vector<size_t>{4, 3, 2, 1, 0}); | |
74 EXPECT_THAT(SelectedQueueOrder(), testing::ElementsAre(4, 3, 2, 1, 0)); | |
75 } | |
76 | |
77 TEST_F(RendererSchedulerSelectorTest, TestHighPriority) { | |
78 std::vector<base::PendingTask> tasks = GetTasks(5); | |
79 PushTasks(tasks, std::vector<size_t>{0, 1, 2, 3, 4}); | |
80 selector_.SetQueuePriority(2, RendererSchedulerSelector::kHighPriority); | |
81 EXPECT_THAT(SelectedQueueOrder(), testing::ElementsAre(2, 0, 1, 3, 4)); | |
82 } | |
83 | |
84 TEST_F(RendererSchedulerSelectorTest, TestBestEffortPriority) { | |
85 std::vector<base::PendingTask> tasks = GetTasks(5); | |
86 PushTasks(tasks, std::vector<size_t>{0, 1, 2, 3, 4}); | |
87 selector_.SetQueuePriority(0, RendererSchedulerSelector::kBestEffortPriority); | |
88 selector_.SetQueuePriority(2, RendererSchedulerSelector::kHighPriority); | |
89 EXPECT_THAT(SelectedQueueOrder(), testing::ElementsAre(2, 1, 3, 4, 0)); | |
90 } | |
91 | |
92 TEST_F(RendererSchedulerSelectorTest, TestControlPriority) { | |
93 std::vector<base::PendingTask> tasks = GetTasks(5); | |
94 PushTasks(tasks, std::vector<size_t>{0, 1, 2, 3, 4}); | |
95 selector_.SetQueuePriority(4, RendererSchedulerSelector::kControlPriority); | |
96 selector_.SetQueuePriority(2, RendererSchedulerSelector::kHighPriority); | |
97 EXPECT_THAT(SelectedQueueOrder(), testing::ElementsAre(4, 2, 0, 1, 3)); | |
98 } | |
99 | |
100 TEST_F(RendererSchedulerSelectorTest, TestDisableEnable) { | |
101 std::vector<base::PendingTask> tasks = GetTasks(5); | |
102 PushTasks(tasks, std::vector<size_t>{0, 1, 2, 3, 4}); | |
103 selector_.DisableQueue(2); | |
104 selector_.DisableQueue(4); | |
105 EXPECT_THAT(SelectedQueueOrder(), testing::ElementsAre(0, 1, 3)); | |
106 selector_.EnableQueue(2, RendererSchedulerSelector::kBestEffortPriority); | |
107 EXPECT_THAT(SelectedQueueOrder(), testing::ElementsAre(2)); | |
108 selector_.EnableQueue(4, RendererSchedulerSelector::kNormalPriority); | |
109 EXPECT_THAT(SelectedQueueOrder(), testing::ElementsAre(4)); | |
110 } | |
111 | |
112 TEST_F(RendererSchedulerSelectorTest, TestEmptyQueues) { | |
113 size_t chosen_queue_index = 0; | |
114 EXPECT_FALSE(selector_.SelectWorkQueueToService(&chosen_queue_index)); | |
115 | |
116 // Test only disabled queues. | |
117 std::vector<base::PendingTask> tasks = GetTasks(1); | |
118 PushTasks(tasks, std::vector<size_t>{0}); | |
119 selector_.DisableQueue(0); | |
120 EXPECT_FALSE(selector_.SelectWorkQueueToService(&chosen_queue_index)); | |
121 } | |
122 | |
123 TEST_F(RendererSchedulerSelectorTest, TestDelay) { | |
124 std::vector<base::PendingTask> tasks = GetTasks(5); | |
125 tasks[0].delayed_run_time = | |
126 base::TimeTicks() + base::TimeDelta::FromMilliseconds(200); | |
127 tasks[3].delayed_run_time = | |
128 base::TimeTicks() + base::TimeDelta::FromMilliseconds(100); | |
129 PushTasks(tasks, std::vector<size_t>{0, 1, 2, 3, 4}); | |
130 EXPECT_THAT(SelectedQueueOrder(), testing::ElementsAre(1, 2, 4, 3, 0)); | |
131 } | |
132 | |
133 TEST_F(RendererSchedulerSelectorTest, TestControlStarvesOthers) { | |
134 std::vector<base::PendingTask> tasks = GetTasks(4); | |
135 PushTasks(tasks, std::vector<size_t>{0, 1, 2, 3}); | |
136 selector_.SetQueuePriority(3, RendererSchedulerSelector::kControlPriority); | |
137 selector_.SetQueuePriority(2, RendererSchedulerSelector::kHighPriority); | |
138 selector_.SetQueuePriority(1, RendererSchedulerSelector::kBestEffortPriority); | |
139 for (int i = 0; i < 100; i++) { | |
140 size_t chosen_queue_index = 0; | |
141 EXPECT_TRUE(selector_.SelectWorkQueueToService(&chosen_queue_index)); | |
142 EXPECT_EQ(3ul, chosen_queue_index); | |
143 // Don't remove task from queue to simulate all queues still being full. | |
144 } | |
145 } | |
146 | |
147 TEST_F(RendererSchedulerSelectorTest, TestHighPriorityDoesNotStarveNormal) { | |
148 std::vector<base::PendingTask> tasks = GetTasks(3); | |
149 PushTasks(tasks, std::vector<size_t>{0, 1, 2}); | |
150 selector_.SetQueuePriority(2, RendererSchedulerSelector::kHighPriority); | |
151 selector_.SetQueuePriority(1, RendererSchedulerSelector::kBestEffortPriority); | |
152 std::vector<size_t> counts = {0, 0, 0}; | |
153 for (int i = 0; i < 100; i++) { | |
154 size_t chosen_queue_index = 0; | |
155 EXPECT_TRUE(selector_.SelectWorkQueueToService(&chosen_queue_index)); | |
156 counts[chosen_queue_index]++; | |
157 // Don't remove task from queue to simulate all queues still being full. | |
158 } | |
159 EXPECT_GT(counts[0], 0ul); // Check high doesn't starve normal. | |
160 EXPECT_GT(counts[2], counts[0]); // Check high get's more chance to run. | |
161 EXPECT_EQ(0ul, counts[1]); // Check best effort is starved. | |
162 } | |
163 | |
164 TEST_F(RendererSchedulerSelectorTest, TestBestEffortGetsStarved) { | |
165 std::vector<base::PendingTask> tasks = GetTasks(2); | |
166 PushTasks(tasks, std::vector<size_t>{0, 1}); | |
167 selector_.SetQueuePriority(0, RendererSchedulerSelector::kBestEffortPriority); | |
168 selector_.SetQueuePriority(1, RendererSchedulerSelector::kNormalPriority); | |
169 size_t chosen_queue_index = 0; | |
170 for (int i = 0; i < 100; i++) { | |
171 EXPECT_TRUE(selector_.SelectWorkQueueToService(&chosen_queue_index)); | |
172 EXPECT_EQ(1ul, chosen_queue_index); | |
173 // Don't remove task from queue to simulate all queues still being full. | |
174 } | |
175 selector_.SetQueuePriority(1, RendererSchedulerSelector::kHighPriority); | |
176 for (int i = 0; i < 100; i++) { | |
177 EXPECT_TRUE(selector_.SelectWorkQueueToService(&chosen_queue_index)); | |
178 EXPECT_EQ(1ul, chosen_queue_index); | |
179 // Don't remove task from queue to simulate all queues still being full. | |
180 } | |
181 selector_.SetQueuePriority(1, RendererSchedulerSelector::kControlPriority); | |
182 for (int i = 0; i < 100; i++) { | |
183 EXPECT_TRUE(selector_.SelectWorkQueueToService(&chosen_queue_index)); | |
184 EXPECT_EQ(1ul, chosen_queue_index); | |
185 // Don't remove task from queue to simulate all queues still being full. | |
186 } | |
187 } | |
188 | |
189 } // namespace content | |
OLD | NEW |