Chromium Code Reviews| 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 |