Index: chrome/browser/chromeos/resource_reporter/resource_reporter_unittest.cc |
diff --git a/chrome/browser/chromeos/resource_reporter/resource_reporter_unittest.cc b/chrome/browser/chromeos/resource_reporter/resource_reporter_unittest.cc |
index bf9198b7d1cee55750d02ce28723c653f3e01f6d..f34342e3892874ac998dc5c8edc4378cab66ff69 100644 |
--- a/chrome/browser/chromeos/resource_reporter/resource_reporter_unittest.cc |
+++ b/chrome/browser/chromeos/resource_reporter/resource_reporter_unittest.cc |
@@ -11,10 +11,13 @@ |
#include <vector> |
#include "base/macros.h" |
+#include "base/memory/memory_pressure_monitor.h" |
+#include "base/run_loop.h" |
#include "base/strings/utf_string_conversions.h" |
#include "base/timer/mock_timer.h" |
#include "chrome/browser/chromeos/resource_reporter/resource_reporter.h" |
#include "chrome/browser/task_manager/test_task_manager.h" |
+#include "content/public/test/test_browser_thread_bundle.h" |
#include "testing/gtest/include/gtest/gtest.h" |
using task_manager::TaskId; |
@@ -23,43 +26,35 @@ namespace chromeos { |
namespace { |
-const int64_t k1KB = 1024; |
-const int64_t k1MB = 1024 * 1024; |
-const int64_t k1GB = 1024 * 1024 * 1024; |
+constexpr int64_t k1KB = 1024; |
+constexpr int64_t k1MB = 1024 * 1024; |
+constexpr int64_t k1GB = 1024 * 1024 * 1024; |
+ |
+constexpr double kBrowserProcessCpu = 21.0; |
+constexpr int64_t kBrowserProcessMemory = 300 * k1MB; |
+constexpr double kGpuProcessCpu = 60.0; |
+constexpr int64_t kGpuProcessMemory = 900 * k1MB; |
// A list of task records that we'll use to fill the task manager. |
const ResourceReporter::TaskRecord kTestTasks[] = { |
- { 0, "0", 30.0, 43 * k1KB, false }, |
- { 1, "1", 9.0, 20 * k1MB, false }, |
- { 2, "2", 35.0, 3 * k1GB, false }, |
- { 3, "3", 21.0, 300 * k1MB, false }, // Browser task. |
- { 4, "4", 85.0, 400 * k1KB, false }, |
- { 5, "5", 30.1, 500 * k1MB, false }, |
- { 6, "6", 60.0, 900 * k1MB, false }, // GPU task. |
- { 7, "7", 4.0, 1 * k1GB, false }, |
- { 8, "8", 40.0, 64 * k1KB, false }, |
- { 9, "9", 93.0, 64 * k1MB, false }, |
- { 10, "10", 2.23, 2 * k1KB, false }, |
- { 11, "11", 55.0, 40 * k1MB, false }, |
- { 12, "12", 87.0, 30 * k1KB, false }, |
-}; |
- |
-// A list of task IDs that will be removed from the task manager later after all |
-// the above tasks have been added. |
-const task_manager::TaskId kIdsOfTasksToRemove[] = { |
- 4, 7, 12, 8, 5, |
+ {0, "0", 30.0, 43 * k1KB, false}, |
+ {1, "1", 9.0, 20 * k1MB, false}, |
+ {2, "2", 35.0, 3 * k1GB, false}, |
+ // Browser task. |
+ {3, "3", kBrowserProcessCpu, kBrowserProcessMemory, false}, |
+ {4, "4", 85.0, 400 * k1KB, false}, |
+ {5, "5", 30.1, 500 * k1MB, false}, |
+ // GPU task. |
+ {6, "6", kGpuProcessCpu, kGpuProcessMemory, false}, |
+ {7, "7", 4.0, 1 * k1GB, false}, |
+ {8, "8", 40.0, 64 * k1KB, false}, |
+ {9, "9", 93.0, 64 * k1MB, false}, |
+ {10, "10", 2.23, 2 * k1KB, false}, |
+ {11, "11", 55.0, 40 * k1MB, false}, |
+ {12, "12", 87.0, 30 * k1KB, false}, |
}; |
-// Must be larger than |ResourceReporter::kTopConsumerCount| + 2 (to account for |
-// the browser and GPU tasks). |
-const size_t kTasksSize = arraysize(kTestTasks); |
- |
-// Must be smaller than |ResourceReporter::kTopConsumerCount|. |
-const size_t kInitiallyAddedTasks = kTasksSize - 6; |
- |
-// Must be such that |kTasksSize| - |kTasksToBeRemovedSize| is less than |
-// |ResourceReporter::kTopConsumerCount|. |
-const size_t kTasksToBeRemovedSize = arraysize(kIdsOfTasksToRemove); |
+constexpr size_t kTasksSize = arraysize(kTestTasks); |
// A test implementation of the task manager that can be used to collect CPU and |
// memory usage so that they can be tested with the resource reporter. |
@@ -98,19 +93,12 @@ class DummyTaskManager : public task_manager::TestTaskManager { |
tasks_[kTestTasks[index].id] = &kTestTasks[index]; |
} |
- void RemoveTask(TaskId id) { |
- NotifyObserversOnTaskToBeRemoved(id); |
- |
- tasks_.erase(id); |
- } |
- |
void ManualRefresh() { |
ids_.clear(); |
- for (const auto& pair : tasks_) { |
+ for (const auto& pair : tasks_) |
ids_.push_back(pair.first); |
- } |
- NotifyObserversOnRefresh(ids_); |
+ NotifyObserversOnRefreshWithBackgroundCalculations(ids_); |
} |
private: |
@@ -119,6 +107,31 @@ class DummyTaskManager : public task_manager::TestTaskManager { |
DISALLOW_COPY_AND_ASSIGN(DummyTaskManager); |
}; |
+class DummyMemoryPressureMonitor : public base::MemoryPressureMonitor { |
+ public: |
+ DummyMemoryPressureMonitor() |
+ : MemoryPressureMonitor(), |
+ memory_pressure_level_( |
+ MemoryPressureLevel::MEMORY_PRESSURE_LEVEL_NONE) {} |
+ ~DummyMemoryPressureMonitor() override {} |
+ |
+ void SetAndNotifyMemoryPressure(MemoryPressureLevel level) { |
+ memory_pressure_level_ = level; |
+ base::MemoryPressureListener::SimulatePressureNotification(level); |
+ } |
+ |
+ // base::CriticalMemoryPressureMonitor: |
+ MemoryPressureLevel GetCurrentPressureLevel() const override { |
+ return memory_pressure_level_; |
+ } |
+ void SetDispatchCallback(const DispatchCallback& callback) override {} |
+ |
+ private: |
+ MemoryPressureLevel memory_pressure_level_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(DummyMemoryPressureMonitor); |
+}; |
+ |
} // namespace |
class ResourceReporterTest : public testing::Test { |
@@ -126,68 +139,34 @@ class ResourceReporterTest : public testing::Test { |
ResourceReporterTest() {} |
~ResourceReporterTest() override {} |
- // Start / Stop observing the task manager. |
- void Start() { |
- task_manager_.AddObserver(resource_reporter()); |
- } |
- void Stop() { |
- task_manager_.RemoveObserver(resource_reporter()); |
+ void SetUp() override { |
+ resource_reporter()->StartMonitoring(&task_manager_); |
} |
- // Adds a number of tasks less than |kTopConsumersCount| to the task manager. |
- void AddInitialTasks() { |
- for (size_t i = 0; i < kInitiallyAddedTasks; ++i) |
- task_manager_.AddTaskFromIndex(i); |
- } |
+ void TearDown() override { resource_reporter()->StopMonitoring(); } |
- // Adds all the remaining tasks to the task manager so that we have more than |
- // |kTopConsumersCount|. |
- void AddRemainingTasks() { |
- for (size_t i = kInitiallyAddedTasks; i < kTasksSize; ++i) |
+ // Adds a number of tasks less than |kTopConsumersCount| to the task manager. |
+ void AddTasks() { |
+ for (size_t i = 0; i < kTasksSize; ++i) |
task_manager_.AddTaskFromIndex(i); |
} |
- // Remove the task with |id| from the task manager. |
- void RemoveTask(TaskId id) { |
- task_manager_.RemoveTask(id); |
- } |
- |
// Manually refresh the task manager. |
void RefreshTaskManager() { |
task_manager_.ManualRefresh(); |
} |
- // Tests that the task records in |ResourceReporter::task_records_by_cpu_| are |
- // properly sorted by the CPU usage in a descending order. |
- bool IsCpuRecordsSetSorted() const { |
- double current_cpu = std::numeric_limits<double>::max(); |
- for (auto* record : resource_reporter()->task_records_by_cpu_) { |
- if (record->cpu_percent > current_cpu) |
- return false; |
- current_cpu = record->cpu_percent; |
- } |
- |
- return true; |
- } |
- |
- // Tests that the task records in |ResourceReporter::task_records_by_memory_| |
- // are properly sorted by the memory usage in a descending order. |
- bool IsMemoryRecordsSetSorted() const { |
- int64_t current_memory = std::numeric_limits<int64_t>::max(); |
- for (auto* record : resource_reporter()->task_records_by_memory_) { |
- if (record->memory_bytes > current_memory) |
- return false; |
- current_memory = record->memory_bytes; |
- } |
- |
- return true; |
- } |
- |
ResourceReporter* resource_reporter() const { |
return ResourceReporter::GetInstance(); |
} |
+ DummyMemoryPressureMonitor* monitor() { return &monitor_; } |
+ |
private: |
+ content::TestBrowserThreadBundle thread_bundle_; |
+ |
+ DummyMemoryPressureMonitor monitor_; |
+ |
DummyTaskManager task_manager_; |
DISALLOW_COPY_AND_ASSIGN(ResourceReporterTest); |
@@ -262,67 +241,58 @@ TEST_F(ResourceReporterTest, TestGetMemoryRapporMetricName) { |
// Tests all the interactions between the resource reporter and the task |
// manager. |
TEST_F(ResourceReporterTest, TestAll) { |
- // First start by making sure that our assumptions are correct. |
- ASSERT_LT(kInitiallyAddedTasks, ResourceReporter::kTopConsumersCount); |
- ASSERT_LT(ResourceReporter::kTopConsumersCount, kTasksSize - 2); |
- ASSERT_LT(kTasksSize - kTasksToBeRemovedSize - 2, |
- ResourceReporter::kTopConsumersCount); |
- |
- Start(); |
- |
- // Add the initial tasks to the task manager, and expect that after a refresh |
- // that the resource reporter is already tracking them, and the records are |
- // sorted properly. |
- AddInitialTasks(); |
- RefreshTaskManager(); |
- // Browser and GPU tasks won't be added. |
- EXPECT_EQ(kInitiallyAddedTasks - 2, |
- resource_reporter()->task_records_.size()); |
- EXPECT_LE(resource_reporter()->task_records_by_cpu_.size(), |
- ResourceReporter::kTopConsumersCount); |
- EXPECT_LE(resource_reporter()->task_records_by_memory_.size(), |
- ResourceReporter::kTopConsumersCount); |
- EXPECT_TRUE(IsCpuRecordsSetSorted()); |
- EXPECT_TRUE(IsMemoryRecordsSetSorted()); |
- |
- // After adding the remaining tasks which are more than |kTopConsumerCount|, |
- // we must expect that the records used for recording the samples are EQUAL to |
- // |kTopConsumerCount|, and the records are still properly sorted. |
- AddRemainingTasks(); |
+ using MemoryPressureLevel = base::MemoryPressureListener::MemoryPressureLevel; |
+ |
+ // Moderate memory pressure events should not trigger any sampling. |
+ monitor()->SetAndNotifyMemoryPressure( |
+ MemoryPressureLevel::MEMORY_PRESSURE_LEVEL_MODERATE); |
+ base::RunLoop().RunUntilIdle(); |
+ EXPECT_FALSE(resource_reporter()->observed_task_manager()); |
+ |
+ // A critical memory pressure event, but the task manager is not tracking any |
+ // resource intensive tasks yet. |
+ monitor()->SetAndNotifyMemoryPressure( |
+ MemoryPressureLevel::MEMORY_PRESSURE_LEVEL_CRITICAL); |
+ base::RunLoop().RunUntilIdle(); |
+ // We should keep listening to the task manager, even after a refresh. |
RefreshTaskManager(); |
- EXPECT_EQ(kTasksSize - 2, resource_reporter()->task_records_.size()); |
- EXPECT_EQ(ResourceReporter::kTopConsumersCount, |
- resource_reporter()->task_records_by_cpu_.size()); |
- EXPECT_EQ(ResourceReporter::kTopConsumersCount, |
- resource_reporter()->task_records_by_memory_.size()); |
- EXPECT_TRUE(IsCpuRecordsSetSorted()); |
- EXPECT_TRUE(IsMemoryRecordsSetSorted()); |
- |
- // Removing tasks from the task manager must result in their removal from the |
- // resource reporter immediately without having to wait until the next |
- // refresh. |
- for (const auto& id : kIdsOfTasksToRemove) |
- RemoveTask(id); |
- const size_t kExpectedTasksCount = kTasksSize - kTasksToBeRemovedSize - 2; |
- EXPECT_EQ(kExpectedTasksCount, resource_reporter()->task_records_.size()); |
- EXPECT_LE(resource_reporter()->task_records_by_cpu_.size(), |
- ResourceReporter::kTopConsumersCount); |
- EXPECT_LE(resource_reporter()->task_records_by_memory_.size(), |
- ResourceReporter::kTopConsumersCount); |
- EXPECT_TRUE(IsCpuRecordsSetSorted()); |
- EXPECT_TRUE(IsMemoryRecordsSetSorted()); |
- |
- // After refresh nothing changes. |
+ EXPECT_TRUE(resource_reporter()->observed_task_manager()); |
+ |
+ // Memory pressure reduces to moderate again, we should stop watching the task |
+ // manager. |
+ monitor()->SetAndNotifyMemoryPressure( |
+ MemoryPressureLevel::MEMORY_PRESSURE_LEVEL_MODERATE); |
+ base::RunLoop().RunUntilIdle(); |
+ EXPECT_FALSE(resource_reporter()->observed_task_manager()); |
+ |
+ // Memory pressure becomes critical and we have violating tasks. |
+ AddTasks(); |
+ monitor()->SetAndNotifyMemoryPressure( |
+ MemoryPressureLevel::MEMORY_PRESSURE_LEVEL_CRITICAL); |
+ base::RunLoop().RunUntilIdle(); |
+ EXPECT_TRUE(resource_reporter()->observed_task_manager()); |
RefreshTaskManager(); |
- EXPECT_EQ(kExpectedTasksCount, resource_reporter()->task_records_.size()); |
- EXPECT_LE(resource_reporter()->task_records_by_cpu_.size(), |
- ResourceReporter::kTopConsumersCount); |
- EXPECT_LE(resource_reporter()->task_records_by_memory_.size(), |
- ResourceReporter::kTopConsumersCount); |
- EXPECT_TRUE(IsCpuRecordsSetSorted()); |
- EXPECT_TRUE(IsMemoryRecordsSetSorted()); |
- |
- Stop(); |
+ |
+ // Make sure that the ResourceReporter is no longer listening to the task |
+ // manager right after the refresh. |
+ EXPECT_FALSE(resource_reporter()->observed_task_manager()); |
+ |
+ // Make sure the ResourceReporter is not tracking any but the tasks exceeding |
+ // the defined resource use thresholds. |
+ ASSERT_FALSE(resource_reporter()->task_records_.empty()); |
+ for (const auto& task_record : resource_reporter()->task_records_) { |
+ EXPECT_TRUE(task_record.cpu_percent >= |
+ ResourceReporter::kTaskCpuThresholdForReporting || |
+ task_record.memory_bytes >= |
+ ResourceReporter::kTaskMemoryThresholdForReporting); |
+ } |
+ |
+ // Make sure you have the right info about the Browser and GPU process. |
+ EXPECT_EQ(resource_reporter()->last_browser_process_cpu_, kBrowserProcessCpu); |
+ EXPECT_EQ(resource_reporter()->last_browser_process_memory_, |
+ kBrowserProcessMemory); |
+ EXPECT_EQ(resource_reporter()->last_gpu_process_cpu_, kGpuProcessCpu); |
+ EXPECT_EQ(resource_reporter()->last_gpu_process_memory_, kGpuProcessMemory); |
} |
} // namespace chromeos |