Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(173)

Side by Side Diff: chrome/browser/task_management/sampling/task_manager_impl_unittest.cc

Issue 2028753002: Make Task Manager sort more meaningful (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix unittest Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(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 <string>
6 #include <utility>
7 #include <vector>
8
9 #include "base/macros.h"
10 #include "base/strings/utf_string_conversions.h"
11 #include "chrome/browser/task_management/providers/task.h"
12 #include "chrome/browser/task_management/sampling/task_manager_impl.h"
13 #include "chrome/browser/task_management/task_manager_observer.h"
14 #include "content/public/test/test_browser_thread_bundle.h"
15 #include "testing/gtest/include/gtest/gtest.h"
16
17 namespace task_management {
18
19 namespace {
20
21 // A Task for unittests, not backed by a real process, that can report any given
22 // value.
23 class FakeTask : public Task {
24 public:
25 FakeTask(base::ProcessId process_id,
26 Type type,
27 const std::string& title,
28 int tab_id)
29 : Task(base::ASCIIToUTF16(title),
30 "FakeTask",
31 nullptr,
32 base::kNullProcessHandle,
33 process_id),
34 type_(type),
35 parent_(nullptr),
36 tab_id_(tab_id) {
37 TaskManagerImpl::GetInstance()->TaskAdded(this);
38 }
39
40 ~FakeTask() override { TaskManagerImpl::GetInstance()->TaskRemoved(this); }
41
42 Type GetType() const override { return type_; }
43
44 int GetChildProcessUniqueID() const override { return 0; }
45
46 const Task* GetParentTask() const override { return parent_; }
47
48 int GetTabId() const override { return tab_id_; }
49
50 void SetParent(Task* parent) { parent_ = parent; }
51
52 private:
53 Type type_;
54 Task* parent_;
55 int tab_id_;
56
57 DISALLOW_COPY_AND_ASSIGN(FakeTask);
58 };
59
60 } // namespace
61
62 class TaskManagerImplTest : public testing::Test, public TaskManagerObserver {
63 public:
64 TaskManagerImplTest()
65 : TaskManagerObserver(base::TimeDelta::FromSeconds(1),
66 REFRESH_TYPE_NONE) {
67 TaskManagerImpl::GetInstance()->AddObserver(this);
68 }
69 ~TaskManagerImplTest() override {
70 tasks_.clear();
71 observed_task_manager()->RemoveObserver(this);
72 }
73
74 FakeTask* AddTask(int pid_offset,
75 Task::Type type,
76 const std::string& title,
77 int tab_id) {
78 // Offset based on the current process id, to avoid collisions with the
79 // browser process task.
80 base::ProcessId process_id = base::GetCurrentProcId() + pid_offset;
81 tasks_.emplace_back(new FakeTask(process_id, type, title, tab_id));
82 return tasks_.back().get();
83 }
84
85 std::string DumpSortedTasks() {
86 std::string result;
87 for (TaskId task_id : observed_task_manager()->GetTaskIdsList()) {
88 result += base::UTF16ToUTF8(observed_task_manager()->GetTitle(task_id));
89 result += "\n";
90 }
91 return result;
92 }
93
94 private:
95 content::TestBrowserThreadBundle thread_bundle_;
96 std::vector<std::unique_ptr<FakeTask>> tasks_;
97 DISALLOW_COPY_AND_ASSIGN(TaskManagerImplTest);
98 };
99
100 TEST_F(TaskManagerImplTest, SortingTypes) {
101 AddTask(100, Task::GPU, "Gpu Process", -1);
102
103 Task* tab1 = AddTask(200, Task::RENDERER, "Tab One", 10);
104 AddTask(400, Task::EXTENSION, "Extension Subframe: Tab One", 10)
105 ->SetParent(tab1);
106 AddTask(300, Task::RENDERER, "Subframe: Tab One", 10)->SetParent(tab1);
107
108 Task* tab2 =
109 AddTask(200, Task::RENDERER, "Tab Two: sharing process with Tab One", 20);
110
111 AddTask(301, Task::RENDERER, "Subframe: Tab Two", 20)->SetParent(tab2);
112 AddTask(400, Task::EXTENSION, "Extension Subframe: Tab Two", 20)
113 ->SetParent(tab2);
114
115 AddTask(600, Task::ARC, "ARC", -1);
116 AddTask(800, Task::UTILITY, "Utility One", -1);
117 AddTask(700, Task::UTILITY, "Utility Two", -1);
118 AddTask(1000, Task::GUEST, "Guest", 20);
119 AddTask(900, Task::WORKER, "Worker", -1);
120 AddTask(500, Task::ZYGOTE, "Zygote", -1);
121
122 AddTask(300, Task::RENDERER, "Subframe: Tab One (2)", 10)->SetParent(tab1);
123 AddTask(300, Task::RENDERER, "Subframe: Tab One (third)", 10)
124 ->SetParent(tab1);
125 AddTask(300, Task::RENDERER, "Subframe: Tab One (4)", 10)->SetParent(tab1);
126
127 EXPECT_EQ(
128 "Browser\n"
129 "Gpu Process\n"
130 "ARC\n"
131 "Zygote\n"
132 "Utility One\n"
133 "Utility Two\n"
134 "Tab One\n"
135 "Tab Two: sharing process with Tab One\n"
136 "Subframe: Tab One\n"
137 "Subframe: Tab One (2)\n"
138 "Subframe: Tab One (third)\n"
139 "Subframe: Tab One (4)\n"
140 "Extension Subframe: Tab One\n"
141 "Extension Subframe: Tab Two\n"
142 "Subframe: Tab Two\n"
143 "Guest\n"
144 "Worker\n",
145 DumpSortedTasks());
146 }
147
148 TEST_F(TaskManagerImplTest, SortingCycles) {
149 // Two tabs, with subframes in the other's process. This induces a cycle in
150 // the TaskGroup dependencies, without being a cycle in the Tasks. This can
151 // happen in practice.
152 Task* tab1 = AddTask(200, Task::RENDERER, "Tab 1: Process 200", 10);
153 AddTask(300, Task::RENDERER, "Subframe in Tab 1: Process 300", 10)
154 ->SetParent(tab1);
155 Task* tab2 = AddTask(300, Task::RENDERER, "Tab 2: Process 300", 20);
156 AddTask(200, Task::RENDERER, "Subframe in Tab 2: Process 200", 20)
157 ->SetParent(tab2);
158
159 // Simulated GPU process.
160 AddTask(100, Task::GPU, "Gpu Process", -1);
161
162 // Two subframes that list each other as a parent (a true cycle). This
163 // shouldn't happen in practice, but we want the sorting code to handle it
164 // gracefully.
165 FakeTask* cycle1 = AddTask(501, Task::SANDBOX_HELPER, "Cycle 1", -1);
166 FakeTask* cycle2 = AddTask(500, Task::ARC, "Cycle 2", -1);
167 cycle1->SetParent(cycle2);
168 cycle2->SetParent(cycle1);
169
170 // A cycle where both elements are in the same group.
171 FakeTask* cycle3 = AddTask(600, Task::SANDBOX_HELPER, "Cycle 3", -1);
172 FakeTask* cycle4 = AddTask(600, Task::ARC, "Cycle 4", -1);
173 cycle3->SetParent(cycle4);
174 cycle4->SetParent(cycle3);
175
176 // Tasks listing a cycle as their parent.
177 FakeTask* lollipop5 = AddTask(701, Task::EXTENSION, "Child of Cycle 3", -1);
178 lollipop5->SetParent(cycle3);
179 FakeTask* lollipop6 = AddTask(700, Task::PLUGIN, "Child of Cycle 4", -1);
180 lollipop6->SetParent(cycle4);
181
182 // A task listing itself as parent.
183 FakeTask* self_cycle = AddTask(800, Task::RENDERER, "Self Cycle", 5);
184 self_cycle->SetParent(self_cycle);
185
186 // Add a plugin child to tab1 and tab2.
187 AddTask(900, Task::PLUGIN, "Plugin: Tab 2", 20)->SetParent(tab1);
188 AddTask(901, Task::PLUGIN, "Plugin: Tab 1", 10)->SetParent(tab1);
189
190 // Finish with a normal renderer task.
191 AddTask(903, Task::RENDERER, "Tab: Normal Renderer", 30);
192
193 // Cycles should wind up on the bottom of the list.
194 EXPECT_EQ(
195 "Browser\n"
196 "Gpu Process\n"
197 "Tab 1: Process 200\n"
198 "Subframe in Tab 2: Process 200\n"
199 "Tab 2: Process 300\n"
200 "Subframe in Tab 1: Process 300\n"
201 "Plugin: Tab 1\n"
202 "Plugin: Tab 2\n"
203 "Tab: Normal Renderer\n"
204 "Cycle 2\n" // ARC
205 "Cycle 1\n" // Child of 2
206 "Cycle 4\n" // ARC; task_id > Cycle 2's
207 "Cycle 3\n" // Same-process child of 4 (SANDBOX_HELPER > ARC)
208 "Child of Cycle 4\n" // Child of 4
209 "Child of Cycle 3\n" // Child of 3
210 "Self Cycle\n", // RENDERER (> ARC)
211 DumpSortedTasks());
212 }
213
214 } // namespace task_management
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698