| OLD | NEW |
| (Empty) | |
| 1 // Copyright 2016 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 "chrome/browser/task_manager/sampling/task_group.h" |
| 6 |
| 7 #include <memory> |
| 8 |
| 9 #include "base/bind.h" |
| 10 #include "base/bind_helpers.h" |
| 11 #include "base/macros.h" |
| 12 #include "base/memory/ptr_util.h" |
| 13 #include "base/memory/ref_counted.h" |
| 14 #include "base/message_loop/message_loop.h" |
| 15 #include "base/run_loop.h" |
| 16 #include "base/strings/string16.h" |
| 17 #include "base/test/gtest_util.h" |
| 18 #include "chrome/browser/task_manager/sampling/shared_sampler.h" |
| 19 #include "content/public/browser/browser_thread.h" |
| 20 #include "content/public/test/test_browser_thread_bundle.h" |
| 21 #include "gpu/ipc/common/memory_stats.h" |
| 22 #include "testing/gtest/include/gtest/gtest.h" |
| 23 |
| 24 namespace task_manager { |
| 25 |
| 26 namespace { |
| 27 |
| 28 class FakeTask : public Task { |
| 29 public: |
| 30 FakeTask(base::ProcessId process_id, Type type) |
| 31 : Task(base::string16(), |
| 32 "FakeTask", |
| 33 nullptr, |
| 34 base::kNullProcessHandle, |
| 35 process_id), |
| 36 type_(type) {} |
| 37 |
| 38 Type GetType() const override { return type_; } |
| 39 |
| 40 int GetChildProcessUniqueID() const override { return 0; } |
| 41 |
| 42 const Task* GetParentTask() const override { return nullptr; } |
| 43 |
| 44 int GetTabId() const override { return 0; } |
| 45 |
| 46 private: |
| 47 Type type_; |
| 48 |
| 49 DISALLOW_COPY_AND_ASSIGN(FakeTask); |
| 50 }; |
| 51 |
| 52 } // namespace |
| 53 |
| 54 class TaskGroupTest : public testing::Test { |
| 55 public: |
| 56 TaskGroupTest() |
| 57 : io_task_runner_(content::BrowserThread::GetTaskRunnerForThread( |
| 58 content::BrowserThread::IO)), |
| 59 run_loop_(base::MakeUnique<base::RunLoop>()), |
| 60 task_group_(base::Process::Current().Handle(), |
| 61 base::Process::Current().Pid(), |
| 62 base::Bind(&TaskGroupTest::OnBackgroundCalculationsDone, |
| 63 base::Unretained(this)), |
| 64 new SharedSampler(io_task_runner_), |
| 65 io_task_runner_), |
| 66 fake_task_(base::Process::Current().Pid(), Task::UNKNOWN) { |
| 67 // Refresh() is only valid on non-empty TaskGroups, so add a fake Task. |
| 68 task_group_.AddTask(&fake_task_); |
| 69 } |
| 70 |
| 71 protected: |
| 72 void OnBackgroundCalculationsDone() { |
| 73 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| 74 background_refresh_complete_ = true; |
| 75 run_loop_->QuitWhenIdle(); |
| 76 } |
| 77 |
| 78 content::TestBrowserThreadBundle browser_threads_; |
| 79 scoped_refptr<base::SequencedTaskRunner> io_task_runner_; |
| 80 std::unique_ptr<base::RunLoop> run_loop_; |
| 81 TaskGroup task_group_; |
| 82 FakeTask fake_task_; |
| 83 bool background_refresh_complete_ = false; |
| 84 |
| 85 DISALLOW_COPY_AND_ASSIGN(TaskGroupTest); |
| 86 }; |
| 87 |
| 88 // Verify that calling TaskGroup::Refresh() without specifying any fields to |
| 89 // refresh trivially completes, without crashing or leaving things in a weird |
| 90 // state. |
| 91 TEST_F(TaskGroupTest, NullRefresh) { |
| 92 task_group_.Refresh(gpu::VideoMemoryUsageStats(), base::TimeDelta(), 0); |
| 93 EXPECT_TRUE(task_group_.AreBackgroundCalculationsDone()); |
| 94 EXPECT_FALSE(background_refresh_complete_); |
| 95 } |
| 96 |
| 97 // Ensure that refreshing an empty TaskGroup causes a DCHECK (if enabled). |
| 98 TEST_F(TaskGroupTest, RefreshZeroTasksDeathTest) { |
| 99 // Remove the fake Task from the group. |
| 100 task_group_.RemoveTask(&fake_task_); |
| 101 |
| 102 EXPECT_DCHECK_DEATH( |
| 103 task_group_.Refresh(gpu::VideoMemoryUsageStats(), base::TimeDelta(), 0)); |
| 104 } |
| 105 |
| 106 // Verify that Refresh() for a field which can be refreshed synchronously |
| 107 // completes immediately, without leaving any background calculations pending. |
| 108 TEST_F(TaskGroupTest, SyncRefresh) { |
| 109 task_group_.Refresh(gpu::VideoMemoryUsageStats(), base::TimeDelta(), |
| 110 REFRESH_TYPE_NETWORK_USAGE); |
| 111 EXPECT_TRUE(task_group_.AreBackgroundCalculationsDone()); |
| 112 EXPECT_FALSE(background_refresh_complete_); |
| 113 } |
| 114 |
| 115 // Some fields are refreshed on a per-TaskGroup basis, but require asynchronous |
| 116 // work (e.g. on another thread) to complete. Memory is such a field, so verify |
| 117 // that it is correctly reported as requiring background calculations. |
| 118 TEST_F(TaskGroupTest, AsyncRefresh) { |
| 119 task_group_.Refresh(gpu::VideoMemoryUsageStats(), base::TimeDelta(), |
| 120 REFRESH_TYPE_MEMORY); |
| 121 EXPECT_FALSE(task_group_.AreBackgroundCalculationsDone()); |
| 122 |
| 123 ASSERT_FALSE(background_refresh_complete_); |
| 124 run_loop_->Run(); |
| 125 |
| 126 EXPECT_TRUE(task_group_.AreBackgroundCalculationsDone()); |
| 127 EXPECT_TRUE(background_refresh_complete_); |
| 128 } |
| 129 |
| 130 // Some fields are refreshed system-wide, via a SharedSampler, which completes |
| 131 // asynchronously. Idle wakeups are reported via SharedSampler on some systems |
| 132 // and via asynchronous refresh on others, so we just test that that field |
| 133 // requires background calculations, similarly to the AsyncRefresh test above. |
| 134 TEST_F(TaskGroupTest, SharedAsyncRefresh) { |
| 135 task_group_.Refresh(gpu::VideoMemoryUsageStats(), base::TimeDelta(), |
| 136 REFRESH_TYPE_IDLE_WAKEUPS); |
| 137 EXPECT_FALSE(task_group_.AreBackgroundCalculationsDone()); |
| 138 |
| 139 ASSERT_FALSE(background_refresh_complete_); |
| 140 run_loop_->Run(); |
| 141 |
| 142 EXPECT_TRUE(background_refresh_complete_); |
| 143 |
| 144 EXPECT_TRUE(task_group_.AreBackgroundCalculationsDone()); |
| 145 } |
| 146 |
| 147 // Ensure that if NaCl is enabled then calling Refresh with a NaCl Task active |
| 148 // results in asynchronous completion. Also verifies that if NaCl is disabled |
| 149 // then completion is synchronous. |
| 150 TEST_F(TaskGroupTest, NaclRefreshWithTask) { |
| 151 FakeTask fake_task(base::Process::Current().Pid(), Task::NACL); |
| 152 task_group_.AddTask(&fake_task); |
| 153 |
| 154 task_group_.Refresh(gpu::VideoMemoryUsageStats(), base::TimeDelta(), |
| 155 REFRESH_TYPE_NACL); |
| 156 #if !defined(DISABLE_NACL) |
| 157 EXPECT_FALSE(task_group_.AreBackgroundCalculationsDone()); |
| 158 |
| 159 ASSERT_FALSE(background_refresh_complete_); |
| 160 run_loop_->Run(); |
| 161 |
| 162 EXPECT_TRUE(background_refresh_complete_); |
| 163 #endif // !defined(DISABLE_NACL) |
| 164 |
| 165 EXPECT_TRUE(task_group_.AreBackgroundCalculationsDone()); |
| 166 } |
| 167 |
| 168 } // namespace task_manager |
| OLD | NEW |