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.
5 #include "base/run_loop.h"
6 #include "base/strings/utf_string_conversions.h"
7 #include "chrome/browser/task_management/providers/child_process_task.h"
8 #include "chrome/browser/task_management/providers/child_process_task_provider.h"
9 #include "chrome/browser/task_management/task_manager_observer.h"
10 #include "chrome/grit/generated_resources.h"
11 #include "components/nacl/common/nacl_process_type.h"
12 #include "content/public/browser/child_process_data.h"
13 #include "content/public/common/process_type.h"
14 #include "content/public/test/test_browser_thread_bundle.h"
15 #include "content/public/test/test_utils.h"
16 #include "testing/gtest/include/gtest/gtest.h"
17 #include "ui/base/l10n/l10n_util.h"
19 using content::ChildProcessData
;
21 namespace task_management
{
25 // Will be used to test the translation from |content::ProcessType| to
26 // |task_management::Task::Type|.
27 struct ProcessTypeTaskTypePair
{
29 Task::Type expected_task_type_
;
30 } process_task_types_pairs
[] = {
31 { content::PROCESS_TYPE_PLUGIN
, Task::PLUGIN
},
32 { content::PROCESS_TYPE_PPAPI_PLUGIN
, Task::PLUGIN
},
33 { content::PROCESS_TYPE_PPAPI_BROKER
, Task::PLUGIN
},
34 { content::PROCESS_TYPE_UTILITY
, Task::UTILITY
},
35 { content::PROCESS_TYPE_ZYGOTE
, Task::ZYGOTE
},
36 { content::PROCESS_TYPE_SANDBOX_HELPER
, Task::SANDBOX_HELPER
},
37 { content::PROCESS_TYPE_GPU
, Task::GPU
},
38 { PROCESS_TYPE_NACL_LOADER
, Task::NACL
},
39 { PROCESS_TYPE_NACL_BROKER
, Task::NACL
},
44 // Defines a test for the child process task provider and the child process
46 class ChildProcessTaskTest
47 : public testing::Test
,
48 public TaskProviderObserver
{
50 ChildProcessTaskTest()
55 ~ChildProcessTaskTest() override
{}
57 // task_management::TaskProviderObserver:
58 void TaskAdded(Task
* task
) override
{
60 if (provided_tasks_
.find(task
->process_handle()) != provided_tasks_
.end())
61 FAIL() << "ChildProcessTaskProvider must never provide duplicate tasks";
63 provided_tasks_
[task
->process_handle()] = task
;
66 void TaskRemoved(Task
* task
) override
{
68 provided_tasks_
.erase(task
->process_handle());
71 bool AreProviderContainersEmpty(
72 const ChildProcessTaskProvider
& provider
) const {
73 return provider
.tasks_by_handle_
.empty() && provider
.tasks_by_pid_
.empty();
77 std::map
<base::ProcessHandle
, Task
*> provided_tasks_
;
80 content::TestBrowserThreadBundle thread_bundle_
;
82 DISALLOW_COPY_AND_ASSIGN(ChildProcessTaskTest
);
85 // Perfoms a basic test.
86 TEST_F(ChildProcessTaskTest
, BasicTest
) {
87 ChildProcessTaskProvider provider
;
88 EXPECT_TRUE(provided_tasks_
.empty());
89 provider
.SetObserver(this);
90 content::RunAllPendingInMessageLoop();
91 ASSERT_TRUE(provided_tasks_
.empty()) <<
92 "unit tests don't have any browser child processes";
93 provider
.ClearObserver();
94 EXPECT_TRUE(provided_tasks_
.empty());
95 EXPECT_TRUE(AreProviderContainersEmpty(provider
));
98 // Tests everything related to child process task providing.
99 TEST_F(ChildProcessTaskTest
, TestAll
) {
100 ChildProcessTaskProvider provider
;
101 EXPECT_TRUE(provided_tasks_
.empty());
102 provider
.SetObserver(this);
103 content::RunAllPendingInMessageLoop();
104 ASSERT_TRUE(provided_tasks_
.empty());
106 // The following process which has handle = base::kNullProcessHandle, won't be
108 ChildProcessData
data1(0);
109 ASSERT_EQ(base::kNullProcessHandle
, data1
.handle
);
110 provider
.BrowserChildProcessHostConnected(data1
);
111 EXPECT_TRUE(provided_tasks_
.empty());
113 const int unique_id
= 245;
114 const base::string16
name(base::UTF8ToUTF16("Test Task"));
115 const base::string16
expected_name(l10n_util::GetStringFUTF16(
116 IDS_TASK_MANAGER_PLUGIN_PREFIX
, name
));
118 ChildProcessData
data2(content::PROCESS_TYPE_PLUGIN
);
119 data2
.handle
= base::GetCurrentProcessHandle();
121 data2
.id
= unique_id
;
122 provider
.BrowserChildProcessHostConnected(data2
);
123 ASSERT_EQ(1U, provided_tasks_
.size());
125 Task
* task
= provided_tasks_
.begin()->second
;
126 EXPECT_EQ(base::GetCurrentProcessHandle(), task
->process_handle());
127 EXPECT_EQ(base::GetCurrentProcId(), task
->process_id());
128 EXPECT_EQ(expected_name
, task
->title());
129 EXPECT_EQ(Task::PLUGIN
, task
->GetType());
130 EXPECT_EQ(unique_id
, task
->GetChildProcessUniqueID());
131 EXPECT_EQ(base::string16(), task
->GetProfileName());
132 EXPECT_FALSE(task
->ReportsSqliteMemory());
133 EXPECT_FALSE(task
->ReportsV8Memory());
134 EXPECT_FALSE(task
->ReportsWebCacheStats());
135 EXPECT_FALSE(task
->ReportsNetworkUsage());
137 // Make sure that the conversion from PID to Handle inside
138 // |GetTaskOfUrlRequest()| is working properly.
140 provider
.GetTaskOfUrlRequest(base::GetCurrentProcId(), 0, 0);
141 ASSERT_EQ(task
, found_task
);
142 const int64 bytes_read
= 1024;
143 found_task
->OnNetworkBytesRead(bytes_read
);
144 found_task
->Refresh(base::TimeDelta::FromSeconds(1),
145 REFRESH_TYPE_NETWORK_USAGE
);
147 EXPECT_TRUE(task
->ReportsNetworkUsage());
148 EXPECT_EQ(bytes_read
, task
->network_usage());
150 // Clearing the observer won't notify us of any tasks removals even though
151 // tasks will be actually deleted.
152 provider
.ClearObserver();
153 EXPECT_FALSE(provided_tasks_
.empty());
154 EXPECT_TRUE(AreProviderContainersEmpty(provider
));
157 // Tests the translation of |content::ProcessType| to
158 // |task_management::Task::Type|.
159 TEST_F(ChildProcessTaskTest
, ProcessTypeToTaskType
) {
160 ChildProcessTaskProvider provider
;
161 EXPECT_TRUE(provided_tasks_
.empty());
162 provider
.SetObserver(this);
163 content::RunAllPendingInMessageLoop();
164 ASSERT_TRUE(provided_tasks_
.empty());
166 for (auto& types_pair
: process_task_types_pairs
) {
168 ChildProcessData
data(types_pair
.process_type_
);
169 data
.handle
= base::GetCurrentProcessHandle();
170 provider
.BrowserChildProcessHostConnected(data
);
171 ASSERT_EQ(1U, provided_tasks_
.size());
172 Task
* task
= provided_tasks_
.begin()->second
;
173 EXPECT_EQ(base::GetCurrentProcessHandle(), task
->process_handle());
174 EXPECT_EQ(types_pair
.expected_task_type_
, task
->GetType());
177 provider
.BrowserChildProcessHostDisconnected(data
);
178 EXPECT_TRUE(provided_tasks_
.empty());
181 provider
.ClearObserver();
182 EXPECT_TRUE(AreProviderContainersEmpty(provider
));
185 } // namespace task_management