OLD | NEW |
(Empty) | |
| 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 |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include <limits> |
| 6 #include <map> |
| 7 #include <string> |
| 8 #include <vector> |
| 9 |
| 10 #include "base/strings/utf_string_conversions.h" |
| 11 #include "base/timer/mock_timer.h" |
| 12 #include "chrome/browser/chromeos/resource_reporter/resource_reporter.h" |
| 13 #include "chrome/browser/task_management/test_task_manager.h" |
| 14 #include "testing/gtest/include/gtest/gtest.h" |
| 15 |
| 16 using task_management::TaskId; |
| 17 |
| 18 namespace chromeos { |
| 19 |
| 20 namespace { |
| 21 |
| 22 const int64_t k1KB = 1024; |
| 23 const int64_t k1MB = 1024 * 1024; |
| 24 const int64_t k1GB = 1024 * 1024 * 1024; |
| 25 |
| 26 // A list of task records that we'll use to fill the task manager. |
| 27 const ResourceReporter::TaskRecord kTestTasks[] = { |
| 28 { 0, "0", 30.0, 43 * k1KB, false }, |
| 29 { 1, "1", 9.0, 20 * k1MB, false }, |
| 30 { 2, "2", 35.0, 3 * k1GB, false }, |
| 31 { 3, "3", 21.0, 300 * k1MB, false }, // Browser task. |
| 32 { 4, "4", 85.0, 400 * k1KB, false }, |
| 33 { 5, "5", 30.1, 500 * k1MB, false }, |
| 34 { 6, "6", 60.0, 900 * k1MB, false }, // GPU task. |
| 35 { 7, "7", 4.0, 1 * k1GB, false }, |
| 36 { 8, "8", 40.0, 64 * k1KB, false }, |
| 37 { 9, "9", 93.0, 64 * k1MB, false }, |
| 38 { 10, "10", 2.23, 2 * k1KB, false }, |
| 39 { 11, "11", 55.0, 40 * k1MB, false }, |
| 40 { 12, "12", 87.0, 30 * k1KB, false }, |
| 41 }; |
| 42 |
| 43 // A list of task IDs that will be removed from the task manager later after all |
| 44 // the above tasks have been added. |
| 45 const task_management::TaskId kIdsOfTasksToRemove[] = { |
| 46 4, 7, 12, 8, 5, |
| 47 }; |
| 48 |
| 49 // Must be larger than |ResourceReporter::kTopConsumerCount| + 2 (to account for |
| 50 // the browser and GPU tasks). |
| 51 const size_t kTasksSize = arraysize(kTestTasks); |
| 52 |
| 53 // Must be smaller than |ResourceReporter::kTopConsumerCount|. |
| 54 const size_t kInitiallyAddedTasks = kTasksSize - 6; |
| 55 |
| 56 // Must be such that |kTasksSize| - |kTasksToBeRemovedSize| is less than |
| 57 // |ResourceReporter::kTopConsumerCount|. |
| 58 const size_t kTasksToBeRemovedSize = arraysize(kIdsOfTasksToRemove); |
| 59 |
| 60 // A test implementation of the task manager that can be used to collect CPU and |
| 61 // memory usage so that they can be tested with the resource reporter. |
| 62 class DummyTaskManager : public task_management::TestTaskManager { |
| 63 public: |
| 64 DummyTaskManager() { |
| 65 set_timer_for_testing( |
| 66 scoped_ptr<base::Timer>(new base::MockTimer(false, false))); |
| 67 } |
| 68 ~DummyTaskManager() override {} |
| 69 |
| 70 // task_management::TestTaskManager: |
| 71 double GetCpuUsage(TaskId task_id) const override { |
| 72 return tasks_.at(task_id)->cpu_percent; |
| 73 } |
| 74 int64 GetPhysicalMemoryUsage(TaskId task_id) const override { |
| 75 return tasks_.at(task_id)->memory_bytes; |
| 76 } |
| 77 const std::string& GetTaskNameForRappor(TaskId task_id) const override { |
| 78 return tasks_.at(task_id)->task_name_for_rappor; |
| 79 } |
| 80 task_management::Task::Type GetType(TaskId task_id) const override { |
| 81 switch (task_id) { |
| 82 case 3: |
| 83 return task_management::Task::BROWSER; |
| 84 |
| 85 case 6: |
| 86 return task_management::Task::GPU; |
| 87 |
| 88 default: |
| 89 return task_management::Task::RENDERER; |
| 90 } |
| 91 } |
| 92 |
| 93 void AddTaskFromIndex(size_t index) { |
| 94 tasks_[kTestTasks[index].id] = &kTestTasks[index]; |
| 95 } |
| 96 |
| 97 void RemoveTask(TaskId id) { |
| 98 NotifyObserversOnTaskToBeRemoved(id); |
| 99 |
| 100 tasks_.erase(id); |
| 101 } |
| 102 |
| 103 void ManualRefresh() { |
| 104 ids_.clear(); |
| 105 for (const auto& pair : tasks_) { |
| 106 ids_.push_back(pair.first); |
| 107 } |
| 108 |
| 109 NotifyObserversOnRefresh(ids_); |
| 110 } |
| 111 |
| 112 private: |
| 113 std::map<TaskId, const ResourceReporter::TaskRecord*> tasks_; |
| 114 |
| 115 DISALLOW_COPY_AND_ASSIGN(DummyTaskManager); |
| 116 }; |
| 117 |
| 118 } // namespace |
| 119 |
| 120 class ResourceReporterTest : public testing::Test { |
| 121 public: |
| 122 ResourceReporterTest() {} |
| 123 ~ResourceReporterTest() override {} |
| 124 |
| 125 // Start / Stop observing the task manager. |
| 126 void Start() { |
| 127 task_manager_.AddObserver(resource_reporter()); |
| 128 } |
| 129 void Stop() { |
| 130 task_manager_.RemoveObserver(resource_reporter()); |
| 131 } |
| 132 |
| 133 // Adds a number of tasks less than |kTopConsumersCount| to the task manager. |
| 134 void AddInitialTasks() { |
| 135 for (size_t i = 0; i < kInitiallyAddedTasks; ++i) |
| 136 task_manager_.AddTaskFromIndex(i); |
| 137 } |
| 138 |
| 139 // Adds all the remaining tasks to the task manager so that we have more than |
| 140 // |kTopConsumersCount|. |
| 141 void AddRemainingTasks() { |
| 142 for (size_t i = kInitiallyAddedTasks; i < kTasksSize; ++i) |
| 143 task_manager_.AddTaskFromIndex(i); |
| 144 } |
| 145 |
| 146 // Remove the task with |id| from the task manager. |
| 147 void RemoveTask(TaskId id) { |
| 148 task_manager_.RemoveTask(id); |
| 149 } |
| 150 |
| 151 // Manually refresh the task manager. |
| 152 void RefreshTaskManager() { |
| 153 task_manager_.ManualRefresh(); |
| 154 } |
| 155 |
| 156 // Tests that the task records in |ResourceReporter::task_records_by_cpu_| are |
| 157 // properly sorted by the CPU usage in a descending order. |
| 158 bool IsCpuRecordsSetSorted() const { |
| 159 double current_cpu = std::numeric_limits<double>::max(); |
| 160 for (const auto& record : resource_reporter()->task_records_by_cpu_) { |
| 161 if (record->cpu_percent > current_cpu) |
| 162 return false; |
| 163 current_cpu = record->cpu_percent; |
| 164 } |
| 165 |
| 166 return true; |
| 167 } |
| 168 |
| 169 // Tests that the task records in |ResourceReporter::task_records_by_memory_| |
| 170 // are properly sorted by the memory usage in a descending order. |
| 171 bool IsMemoryRecordsSetSorted() const { |
| 172 int64_t current_memory = std::numeric_limits<int64_t>::max(); |
| 173 for (const auto& record : resource_reporter()->task_records_by_memory_) { |
| 174 if (record->memory_bytes > current_memory) |
| 175 return false; |
| 176 current_memory = record->memory_bytes; |
| 177 } |
| 178 |
| 179 return true; |
| 180 } |
| 181 |
| 182 ResourceReporter* resource_reporter() const { |
| 183 return ResourceReporter::GetInstance(); |
| 184 } |
| 185 |
| 186 private: |
| 187 DummyTaskManager task_manager_; |
| 188 |
| 189 DISALLOW_COPY_AND_ASSIGN(ResourceReporterTest); |
| 190 }; |
| 191 |
| 192 // Tests that ResourceReporter::GetCpuRapporMetricName() returns the correct |
| 193 // metric name that corresponds to the given CPU usage. |
| 194 TEST_F(ResourceReporterTest, TestGetCpuRapporMetricName) { |
| 195 EXPECT_EQ(ResourceReporter::CpuUsageRange::RANGE_0_TO_10_PERCENT, |
| 196 ResourceReporter::GetCpuUsageRange(0.3)); |
| 197 EXPECT_EQ(ResourceReporter::CpuUsageRange::RANGE_0_TO_10_PERCENT, |
| 198 ResourceReporter::GetCpuUsageRange(5.7)); |
| 199 EXPECT_EQ(ResourceReporter::CpuUsageRange::RANGE_0_TO_10_PERCENT, |
| 200 ResourceReporter::GetCpuUsageRange(9.99)); |
| 201 EXPECT_EQ(ResourceReporter::CpuUsageRange::RANGE_0_TO_10_PERCENT, |
| 202 ResourceReporter::GetCpuUsageRange(10.0)); |
| 203 |
| 204 EXPECT_EQ(ResourceReporter::CpuUsageRange::RANGE_10_TO_30_PERCENT, |
| 205 ResourceReporter::GetCpuUsageRange(10.1)); |
| 206 EXPECT_EQ(ResourceReporter::CpuUsageRange::RANGE_10_TO_30_PERCENT, |
| 207 ResourceReporter::GetCpuUsageRange(29.99)); |
| 208 EXPECT_EQ(ResourceReporter::CpuUsageRange::RANGE_10_TO_30_PERCENT, |
| 209 ResourceReporter::GetCpuUsageRange(30.0)); |
| 210 |
| 211 EXPECT_EQ(ResourceReporter::CpuUsageRange::RANGE_30_TO_60_PERCENT, |
| 212 ResourceReporter::GetCpuUsageRange(30.1)); |
| 213 EXPECT_EQ(ResourceReporter::CpuUsageRange::RANGE_30_TO_60_PERCENT, |
| 214 ResourceReporter::GetCpuUsageRange(59.99)); |
| 215 EXPECT_EQ(ResourceReporter::CpuUsageRange::RANGE_30_TO_60_PERCENT, |
| 216 ResourceReporter::GetCpuUsageRange(60.0)); |
| 217 |
| 218 EXPECT_EQ(ResourceReporter::CpuUsageRange::RANGE_ABOVE_60_PERCENT, |
| 219 ResourceReporter::GetCpuUsageRange(60.1)); |
| 220 EXPECT_EQ(ResourceReporter::CpuUsageRange::RANGE_ABOVE_60_PERCENT, |
| 221 ResourceReporter::GetCpuUsageRange(100.0)); |
| 222 } |
| 223 |
| 224 // Tests that ResourceReporter::GetMemoryRapporMetricName() returns the correct |
| 225 // metric names for the given memory usage. |
| 226 TEST_F(ResourceReporterTest, TestGetMemoryRapporMetricName) { |
| 227 EXPECT_EQ(ResourceReporter::MemoryUsageRange::RANGE_0_TO_200_MB, |
| 228 ResourceReporter::GetMemoryUsageRange(2 * k1KB)); |
| 229 EXPECT_EQ(ResourceReporter::MemoryUsageRange::RANGE_0_TO_200_MB, |
| 230 ResourceReporter::GetMemoryUsageRange(20 * k1MB)); |
| 231 EXPECT_EQ(ResourceReporter::MemoryUsageRange::RANGE_0_TO_200_MB, |
| 232 ResourceReporter::GetMemoryUsageRange(200 * k1MB)); |
| 233 |
| 234 EXPECT_EQ(ResourceReporter::MemoryUsageRange::RANGE_200_TO_400_MB, |
| 235 ResourceReporter::GetMemoryUsageRange(201 * k1MB)); |
| 236 EXPECT_EQ(ResourceReporter::MemoryUsageRange::RANGE_200_TO_400_MB, |
| 237 ResourceReporter::GetMemoryUsageRange(400 * k1MB)); |
| 238 |
| 239 EXPECT_EQ(ResourceReporter::MemoryUsageRange::RANGE_400_TO_600_MB, |
| 240 ResourceReporter::GetMemoryUsageRange(401 * k1MB)); |
| 241 EXPECT_EQ(ResourceReporter::MemoryUsageRange::RANGE_400_TO_600_MB, |
| 242 ResourceReporter::GetMemoryUsageRange(600 * k1MB)); |
| 243 |
| 244 EXPECT_EQ(ResourceReporter::MemoryUsageRange::RANGE_600_TO_800_MB, |
| 245 ResourceReporter::GetMemoryUsageRange(601 * k1MB)); |
| 246 EXPECT_EQ(ResourceReporter::MemoryUsageRange::RANGE_600_TO_800_MB, |
| 247 ResourceReporter::GetMemoryUsageRange(800 * k1MB)); |
| 248 |
| 249 EXPECT_EQ(ResourceReporter::MemoryUsageRange::RANGE_800_TO_1_GB, |
| 250 ResourceReporter::GetMemoryUsageRange(801 * k1MB)); |
| 251 EXPECT_EQ(ResourceReporter::MemoryUsageRange::RANGE_800_TO_1_GB, |
| 252 ResourceReporter::GetMemoryUsageRange(1 * k1GB)); |
| 253 |
| 254 EXPECT_EQ(ResourceReporter::MemoryUsageRange::RANGE_ABOVE_1_GB, |
| 255 ResourceReporter::GetMemoryUsageRange(1 * k1GB + 1 * k1KB)); |
| 256 } |
| 257 |
| 258 // Tests all the interactions between the resource reporter and the task |
| 259 // manager. |
| 260 TEST_F(ResourceReporterTest, TestAll) { |
| 261 // First start by making sure that our assumptions are correct. |
| 262 ASSERT_LT(kInitiallyAddedTasks, ResourceReporter::kTopConsumersCount); |
| 263 ASSERT_LT(ResourceReporter::kTopConsumersCount, kTasksSize - 2); |
| 264 ASSERT_LT(kTasksSize - kTasksToBeRemovedSize - 2, |
| 265 ResourceReporter::kTopConsumersCount); |
| 266 |
| 267 Start(); |
| 268 |
| 269 // Add the initial tasks to the task manager, and expect that after a refresh |
| 270 // that the resource reporter is already tracking them, and the records are |
| 271 // sorted properly. |
| 272 AddInitialTasks(); |
| 273 RefreshTaskManager(); |
| 274 // Browser and GPU tasks won't be added. |
| 275 EXPECT_EQ(kInitiallyAddedTasks - 2, |
| 276 resource_reporter()->task_records_.size()); |
| 277 EXPECT_LE(resource_reporter()->task_records_by_cpu_.size(), |
| 278 ResourceReporter::kTopConsumersCount); |
| 279 EXPECT_LE(resource_reporter()->task_records_by_memory_.size(), |
| 280 ResourceReporter::kTopConsumersCount); |
| 281 EXPECT_TRUE(IsCpuRecordsSetSorted()); |
| 282 EXPECT_TRUE(IsMemoryRecordsSetSorted()); |
| 283 |
| 284 // After adding the remaining tasks which are more than |kTopConsumerCount|, |
| 285 // we must expect that the records used for recording the samples are EQUAL to |
| 286 // |kTopConsumerCount|, and the records are still properly sorted. |
| 287 AddRemainingTasks(); |
| 288 RefreshTaskManager(); |
| 289 EXPECT_EQ(kTasksSize - 2, resource_reporter()->task_records_.size()); |
| 290 EXPECT_EQ(ResourceReporter::kTopConsumersCount, |
| 291 resource_reporter()->task_records_by_cpu_.size()); |
| 292 EXPECT_EQ(ResourceReporter::kTopConsumersCount, |
| 293 resource_reporter()->task_records_by_memory_.size()); |
| 294 EXPECT_TRUE(IsCpuRecordsSetSorted()); |
| 295 EXPECT_TRUE(IsMemoryRecordsSetSorted()); |
| 296 |
| 297 // Removing tasks from the task manager must result in their removal from the |
| 298 // resource reporter immediately without having to wait until the next |
| 299 // refresh. |
| 300 for (const auto& id : kIdsOfTasksToRemove) |
| 301 RemoveTask(id); |
| 302 const size_t kExpectedTasksCount = kTasksSize - kTasksToBeRemovedSize - 2; |
| 303 EXPECT_EQ(kExpectedTasksCount, resource_reporter()->task_records_.size()); |
| 304 EXPECT_LE(resource_reporter()->task_records_by_cpu_.size(), |
| 305 ResourceReporter::kTopConsumersCount); |
| 306 EXPECT_LE(resource_reporter()->task_records_by_memory_.size(), |
| 307 ResourceReporter::kTopConsumersCount); |
| 308 EXPECT_TRUE(IsCpuRecordsSetSorted()); |
| 309 EXPECT_TRUE(IsMemoryRecordsSetSorted()); |
| 310 |
| 311 // After refresh nothing changes. |
| 312 RefreshTaskManager(); |
| 313 EXPECT_EQ(kExpectedTasksCount, resource_reporter()->task_records_.size()); |
| 314 EXPECT_LE(resource_reporter()->task_records_by_cpu_.size(), |
| 315 ResourceReporter::kTopConsumersCount); |
| 316 EXPECT_LE(resource_reporter()->task_records_by_memory_.size(), |
| 317 ResourceReporter::kTopConsumersCount); |
| 318 EXPECT_TRUE(IsCpuRecordsSetSorted()); |
| 319 EXPECT_TRUE(IsMemoryRecordsSetSorted()); |
| 320 |
| 321 Stop(); |
| 322 } |
| 323 |
| 324 } // namespace chromeos |
OLD | NEW |