OLD | NEW |
---|---|
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <stddef.h> | 5 #include <stddef.h> |
6 #include <stdint.h> | 6 #include <stdint.h> |
7 | 7 |
8 #include <limits> | 8 #include <limits> |
9 #include <map> | 9 #include <map> |
10 #include <string> | 10 #include <string> |
11 #include <vector> | 11 #include <vector> |
12 | 12 |
13 #include "base/macros.h" | 13 #include "base/macros.h" |
14 #include "base/strings/utf_string_conversions.h" | 14 #include "base/strings/utf_string_conversions.h" |
15 #include "base/timer/mock_timer.h" | 15 #include "base/timer/mock_timer.h" |
16 #include "chrome/browser/chromeos/resource_reporter/resource_reporter.h" | 16 #include "chrome/browser/chromeos/resource_reporter/resource_reporter.h" |
17 #include "chrome/browser/task_manager/test_task_manager.h" | 17 #include "chrome/browser/task_manager/test_task_manager.h" |
18 #include "content/public/test/test_browser_thread_bundle.h" | |
18 #include "testing/gtest/include/gtest/gtest.h" | 19 #include "testing/gtest/include/gtest/gtest.h" |
19 | 20 |
20 using task_manager::TaskId; | 21 using task_manager::TaskId; |
21 | 22 |
22 namespace chromeos { | 23 namespace chromeos { |
23 | 24 |
24 namespace { | 25 namespace { |
25 | 26 |
26 const int64_t k1KB = 1024; | 27 constexpr int64_t k1KB = 1024; |
27 const int64_t k1MB = 1024 * 1024; | 28 constexpr int64_t k1MB = 1024 * 1024; |
28 const int64_t k1GB = 1024 * 1024 * 1024; | 29 constexpr int64_t k1GB = 1024 * 1024 * 1024; |
30 | |
31 constexpr double kBrowserProcessCpu = 21.0; | |
32 constexpr int64_t kBrowserProcessMemory = 300 * k1MB; | |
33 constexpr double kGpuProcessCpu = 60.0; | |
34 constexpr int64_t kGpuProcessMemory = 900 * k1MB; | |
29 | 35 |
30 // A list of task records that we'll use to fill the task manager. | 36 // A list of task records that we'll use to fill the task manager. |
31 const ResourceReporter::TaskRecord kTestTasks[] = { | 37 const ResourceReporter::TaskRecord kTestTasks[] = { |
32 { 0, "0", 30.0, 43 * k1KB, false }, | 38 {0, "0", 30.0, 43 * k1KB, false}, |
33 { 1, "1", 9.0, 20 * k1MB, false }, | 39 {1, "1", 9.0, 20 * k1MB, false}, |
34 { 2, "2", 35.0, 3 * k1GB, false }, | 40 {2, "2", 35.0, 3 * k1GB, false}, |
35 { 3, "3", 21.0, 300 * k1MB, false }, // Browser task. | 41 // Browser task. |
36 { 4, "4", 85.0, 400 * k1KB, false }, | 42 {3, "3", kBrowserProcessCpu, kBrowserProcessMemory, false}, |
37 { 5, "5", 30.1, 500 * k1MB, false }, | 43 {4, "4", 85.0, 400 * k1KB, false}, |
38 { 6, "6", 60.0, 900 * k1MB, false }, // GPU task. | 44 {5, "5", 30.1, 500 * k1MB, false}, |
39 { 7, "7", 4.0, 1 * k1GB, false }, | 45 // GPU task. |
40 { 8, "8", 40.0, 64 * k1KB, false }, | 46 {6, "6", kGpuProcessCpu, kGpuProcessMemory, false}, |
41 { 9, "9", 93.0, 64 * k1MB, false }, | 47 {7, "7", 4.0, 1 * k1GB, false}, |
42 { 10, "10", 2.23, 2 * k1KB, false }, | 48 {8, "8", 40.0, 64 * k1KB, false}, |
43 { 11, "11", 55.0, 40 * k1MB, false }, | 49 {9, "9", 93.0, 64 * k1MB, false}, |
44 { 12, "12", 87.0, 30 * k1KB, false }, | 50 {10, "10", 2.23, 2 * k1KB, false}, |
51 {11, "11", 55.0, 40 * k1MB, false}, | |
52 {12, "12", 87.0, 30 * k1KB, false}, | |
45 }; | 53 }; |
46 | 54 |
47 // A list of task IDs that will be removed from the task manager later after all | 55 constexpr size_t kTasksSize = arraysize(kTestTasks); |
48 // the above tasks have been added. | |
49 const task_manager::TaskId kIdsOfTasksToRemove[] = { | |
50 4, 7, 12, 8, 5, | |
51 }; | |
52 | |
53 // Must be larger than |ResourceReporter::kTopConsumerCount| + 2 (to account for | |
54 // the browser and GPU tasks). | |
55 const size_t kTasksSize = arraysize(kTestTasks); | |
56 | |
57 // Must be smaller than |ResourceReporter::kTopConsumerCount|. | |
58 const size_t kInitiallyAddedTasks = kTasksSize - 6; | |
59 | |
60 // Must be such that |kTasksSize| - |kTasksToBeRemovedSize| is less than | |
61 // |ResourceReporter::kTopConsumerCount|. | |
62 const size_t kTasksToBeRemovedSize = arraysize(kIdsOfTasksToRemove); | |
63 | 56 |
64 // A test implementation of the task manager that can be used to collect CPU and | 57 // A test implementation of the task manager that can be used to collect CPU and |
65 // memory usage so that they can be tested with the resource reporter. | 58 // memory usage so that they can be tested with the resource reporter. |
66 class DummyTaskManager : public task_manager::TestTaskManager { | 59 class DummyTaskManager : public task_manager::TestTaskManager { |
67 public: | 60 public: |
68 DummyTaskManager() { | 61 DummyTaskManager() { |
69 set_timer_for_testing( | 62 set_timer_for_testing( |
70 std::unique_ptr<base::Timer>(new base::MockTimer(false, false))); | 63 std::unique_ptr<base::Timer>(new base::MockTimer(false, false))); |
71 } | 64 } |
72 ~DummyTaskManager() override {} | 65 ~DummyTaskManager() override {} |
(...skipping 18 matching lines...) Expand all Loading... | |
91 | 84 |
92 default: | 85 default: |
93 return task_manager::Task::RENDERER; | 86 return task_manager::Task::RENDERER; |
94 } | 87 } |
95 } | 88 } |
96 | 89 |
97 void AddTaskFromIndex(size_t index) { | 90 void AddTaskFromIndex(size_t index) { |
98 tasks_[kTestTasks[index].id] = &kTestTasks[index]; | 91 tasks_[kTestTasks[index].id] = &kTestTasks[index]; |
99 } | 92 } |
100 | 93 |
101 void RemoveTask(TaskId id) { | |
102 NotifyObserversOnTaskToBeRemoved(id); | |
103 | |
104 tasks_.erase(id); | |
105 } | |
106 | |
107 void ManualRefresh() { | 94 void ManualRefresh() { |
108 ids_.clear(); | 95 ids_.clear(); |
109 for (const auto& pair : tasks_) { | 96 for (const auto& pair : tasks_) |
110 ids_.push_back(pair.first); | 97 ids_.push_back(pair.first); |
111 } | |
112 | 98 |
113 NotifyObserversOnRefresh(ids_); | 99 NotifyObserversOnRefreshWithBackgroundCalculations(ids_); |
114 } | 100 } |
115 | 101 |
116 private: | 102 private: |
117 std::map<TaskId, const ResourceReporter::TaskRecord*> tasks_; | 103 std::map<TaskId, const ResourceReporter::TaskRecord*> tasks_; |
118 | 104 |
119 DISALLOW_COPY_AND_ASSIGN(DummyTaskManager); | 105 DISALLOW_COPY_AND_ASSIGN(DummyTaskManager); |
120 }; | 106 }; |
121 | 107 |
122 } // namespace | 108 } // namespace |
123 | 109 |
124 class ResourceReporterTest : public testing::Test { | 110 class ResourceReporterTest : public testing::Test { |
125 public: | 111 public: |
126 ResourceReporterTest() {} | 112 ResourceReporterTest() {} |
127 ~ResourceReporterTest() override {} | 113 ~ResourceReporterTest() override {} |
128 | 114 |
129 // Start / Stop observing the task manager. | 115 // Start / Stop observing the task manager. |
130 void Start() { | 116 void Start() { |
131 task_manager_.AddObserver(resource_reporter()); | 117 task_manager_.AddObserver(resource_reporter()); |
132 } | 118 } |
133 void Stop() { | 119 void Stop() { |
134 task_manager_.RemoveObserver(resource_reporter()); | 120 task_manager_.RemoveObserver(resource_reporter()); |
135 } | 121 } |
136 | 122 |
137 // Adds a number of tasks less than |kTopConsumersCount| to the task manager. | 123 // Adds a number of tasks less than |kTopConsumersCount| to the task manager. |
138 void AddInitialTasks() { | 124 void AddTasks() { |
139 for (size_t i = 0; i < kInitiallyAddedTasks; ++i) | 125 for (size_t i = 0; i < kTasksSize; ++i) |
140 task_manager_.AddTaskFromIndex(i); | 126 task_manager_.AddTaskFromIndex(i); |
141 } | 127 } |
142 | 128 |
143 // Adds all the remaining tasks to the task manager so that we have more than | |
144 // |kTopConsumersCount|. | |
145 void AddRemainingTasks() { | |
146 for (size_t i = kInitiallyAddedTasks; i < kTasksSize; ++i) | |
147 task_manager_.AddTaskFromIndex(i); | |
148 } | |
149 | |
150 // Remove the task with |id| from the task manager. | |
151 void RemoveTask(TaskId id) { | |
152 task_manager_.RemoveTask(id); | |
153 } | |
154 | |
155 // Manually refresh the task manager. | 129 // Manually refresh the task manager. |
156 void RefreshTaskManager() { | 130 void RefreshTaskManager() { |
157 task_manager_.ManualRefresh(); | 131 task_manager_.ManualRefresh(); |
158 } | 132 } |
159 | 133 |
160 // Tests that the task records in |ResourceReporter::task_records_by_cpu_| are | |
161 // properly sorted by the CPU usage in a descending order. | |
162 bool IsCpuRecordsSetSorted() const { | |
163 double current_cpu = std::numeric_limits<double>::max(); | |
164 for (auto* record : resource_reporter()->task_records_by_cpu_) { | |
165 if (record->cpu_percent > current_cpu) | |
166 return false; | |
167 current_cpu = record->cpu_percent; | |
168 } | |
169 | |
170 return true; | |
171 } | |
172 | |
173 // Tests that the task records in |ResourceReporter::task_records_by_memory_| | |
174 // are properly sorted by the memory usage in a descending order. | |
175 bool IsMemoryRecordsSetSorted() const { | |
176 int64_t current_memory = std::numeric_limits<int64_t>::max(); | |
177 for (auto* record : resource_reporter()->task_records_by_memory_) { | |
178 if (record->memory_bytes > current_memory) | |
179 return false; | |
180 current_memory = record->memory_bytes; | |
181 } | |
182 | |
183 return true; | |
184 } | |
185 | |
186 ResourceReporter* resource_reporter() const { | 134 ResourceReporter* resource_reporter() const { |
187 return ResourceReporter::GetInstance(); | 135 return ResourceReporter::GetInstance(); |
188 } | 136 } |
189 | 137 |
190 private: | 138 private: |
191 DummyTaskManager task_manager_; | 139 DummyTaskManager task_manager_; |
192 | 140 |
141 content::TestBrowserThreadBundle thread_bundle_; | |
ncarter (slow)
2016/09/29 21:32:12
The TestBrowserThreadBundle usually works best whe
afakhry
2016/10/04 18:28:58
Done.
| |
142 | |
193 DISALLOW_COPY_AND_ASSIGN(ResourceReporterTest); | 143 DISALLOW_COPY_AND_ASSIGN(ResourceReporterTest); |
194 }; | 144 }; |
195 | 145 |
196 // Tests that ResourceReporter::GetCpuRapporMetricName() returns the correct | 146 // Tests that ResourceReporter::GetCpuRapporMetricName() returns the correct |
197 // metric name that corresponds to the given CPU usage. | 147 // metric name that corresponds to the given CPU usage. |
198 TEST_F(ResourceReporterTest, TestGetCpuRapporMetricName) { | 148 TEST_F(ResourceReporterTest, TestGetCpuRapporMetricName) { |
199 EXPECT_EQ(ResourceReporter::CpuUsageRange::RANGE_0_TO_10_PERCENT, | 149 EXPECT_EQ(ResourceReporter::CpuUsageRange::RANGE_0_TO_10_PERCENT, |
200 ResourceReporter::GetCpuUsageRange(0.3)); | 150 ResourceReporter::GetCpuUsageRange(0.3)); |
201 EXPECT_EQ(ResourceReporter::CpuUsageRange::RANGE_0_TO_10_PERCENT, | 151 EXPECT_EQ(ResourceReporter::CpuUsageRange::RANGE_0_TO_10_PERCENT, |
202 ResourceReporter::GetCpuUsageRange(5.7)); | 152 ResourceReporter::GetCpuUsageRange(5.7)); |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
255 EXPECT_EQ(ResourceReporter::MemoryUsageRange::RANGE_800_TO_1_GB, | 205 EXPECT_EQ(ResourceReporter::MemoryUsageRange::RANGE_800_TO_1_GB, |
256 ResourceReporter::GetMemoryUsageRange(1 * k1GB)); | 206 ResourceReporter::GetMemoryUsageRange(1 * k1GB)); |
257 | 207 |
258 EXPECT_EQ(ResourceReporter::MemoryUsageRange::RANGE_ABOVE_1_GB, | 208 EXPECT_EQ(ResourceReporter::MemoryUsageRange::RANGE_ABOVE_1_GB, |
259 ResourceReporter::GetMemoryUsageRange(1 * k1GB + 1 * k1KB)); | 209 ResourceReporter::GetMemoryUsageRange(1 * k1GB + 1 * k1KB)); |
260 } | 210 } |
261 | 211 |
262 // Tests all the interactions between the resource reporter and the task | 212 // Tests all the interactions between the resource reporter and the task |
263 // manager. | 213 // manager. |
264 TEST_F(ResourceReporterTest, TestAll) { | 214 TEST_F(ResourceReporterTest, TestAll) { |
265 // First start by making sure that our assumptions are correct. | 215 AddTasks(); |
266 ASSERT_LT(kInitiallyAddedTasks, ResourceReporter::kTopConsumersCount); | |
267 ASSERT_LT(ResourceReporter::kTopConsumersCount, kTasksSize - 2); | |
268 ASSERT_LT(kTasksSize - kTasksToBeRemovedSize - 2, | |
269 ResourceReporter::kTopConsumersCount); | |
270 | 216 |
217 // A critical memory pressure event is simulated by starting the observation | |
218 // of the task manager, and then receiving an update after refresh. | |
271 Start(); | 219 Start(); |
220 RefreshTaskManager(); | |
272 | 221 |
273 // Add the initial tasks to the task manager, and expect that after a refresh | 222 // Make sure the ResourceReporter is not tracking any but the tasks exceeding |
274 // that the resource reporter is already tracking them, and the records are | 223 // the defined resource use thresholds. |
275 // sorted properly. | 224 ASSERT_FALSE(resource_reporter()->task_records_.empty()); |
276 AddInitialTasks(); | 225 for (const auto& task_record : resource_reporter()->task_records_) { |
277 RefreshTaskManager(); | 226 EXPECT_TRUE(task_record.cpu_percent >= |
278 // Browser and GPU tasks won't be added. | 227 ResourceReporter::kTaskCpuThresholdForReporting || |
279 EXPECT_EQ(kInitiallyAddedTasks - 2, | 228 task_record.memory_bytes >= |
280 resource_reporter()->task_records_.size()); | 229 ResourceReporter::kTaskMemoryThresholdForReporting); |
281 EXPECT_LE(resource_reporter()->task_records_by_cpu_.size(), | 230 } |
282 ResourceReporter::kTopConsumersCount); | |
283 EXPECT_LE(resource_reporter()->task_records_by_memory_.size(), | |
284 ResourceReporter::kTopConsumersCount); | |
285 EXPECT_TRUE(IsCpuRecordsSetSorted()); | |
286 EXPECT_TRUE(IsMemoryRecordsSetSorted()); | |
287 | 231 |
288 // After adding the remaining tasks which are more than |kTopConsumerCount|, | 232 // Make sure you have the right info about the Browser and GPU process. |
289 // we must expect that the records used for recording the samples are EQUAL to | 233 EXPECT_EQ(resource_reporter()->last_browser_process_cpu_, kBrowserProcessCpu); |
290 // |kTopConsumerCount|, and the records are still properly sorted. | 234 EXPECT_EQ(resource_reporter()->last_browser_process_memory_, |
291 AddRemainingTasks(); | 235 kBrowserProcessMemory); |
292 RefreshTaskManager(); | 236 EXPECT_EQ(resource_reporter()->last_gpu_process_cpu_, kGpuProcessCpu); |
293 EXPECT_EQ(kTasksSize - 2, resource_reporter()->task_records_.size()); | 237 EXPECT_EQ(resource_reporter()->last_gpu_process_memory_, kGpuProcessMemory); |
294 EXPECT_EQ(ResourceReporter::kTopConsumersCount, | |
295 resource_reporter()->task_records_by_cpu_.size()); | |
296 EXPECT_EQ(ResourceReporter::kTopConsumersCount, | |
297 resource_reporter()->task_records_by_memory_.size()); | |
298 EXPECT_TRUE(IsCpuRecordsSetSorted()); | |
299 EXPECT_TRUE(IsMemoryRecordsSetSorted()); | |
300 | 238 |
301 // Removing tasks from the task manager must result in their removal from the | 239 // Make sure that the ResourceReporter is no longer listening to the task |
302 // resource reporter immediately without having to wait until the next | 240 // manager. |
303 // refresh. | 241 EXPECT_FALSE(resource_reporter()->observed_task_manager()); |
304 for (const auto& id : kIdsOfTasksToRemove) | |
305 RemoveTask(id); | |
306 const size_t kExpectedTasksCount = kTasksSize - kTasksToBeRemovedSize - 2; | |
307 EXPECT_EQ(kExpectedTasksCount, resource_reporter()->task_records_.size()); | |
308 EXPECT_LE(resource_reporter()->task_records_by_cpu_.size(), | |
309 ResourceReporter::kTopConsumersCount); | |
310 EXPECT_LE(resource_reporter()->task_records_by_memory_.size(), | |
311 ResourceReporter::kTopConsumersCount); | |
312 EXPECT_TRUE(IsCpuRecordsSetSorted()); | |
313 EXPECT_TRUE(IsMemoryRecordsSetSorted()); | |
314 | |
315 // After refresh nothing changes. | |
316 RefreshTaskManager(); | |
317 EXPECT_EQ(kExpectedTasksCount, resource_reporter()->task_records_.size()); | |
318 EXPECT_LE(resource_reporter()->task_records_by_cpu_.size(), | |
319 ResourceReporter::kTopConsumersCount); | |
320 EXPECT_LE(resource_reporter()->task_records_by_memory_.size(), | |
321 ResourceReporter::kTopConsumersCount); | |
322 EXPECT_TRUE(IsCpuRecordsSetSorted()); | |
323 EXPECT_TRUE(IsMemoryRecordsSetSorted()); | |
324 | |
325 Stop(); | |
326 } | 242 } |
327 | 243 |
328 } // namespace chromeos | 244 } // namespace chromeos |
OLD | NEW |