Adding instrumentation to locate the source of jankiness
[chromium-blink-merge.git] / chrome / browser / task_manager / task_manager_browsertest_util.cc
blobfce4ae4a9593f49ab0b17d0db0a1cecb890828d7
1 // Copyright (c) 2012 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 "chrome/browser/task_manager/task_manager_browsertest_util.h"
7 #include "base/message_loop/message_loop.h"
8 #include "base/run_loop.h"
9 #include "base/strings/string16.h"
10 #include "base/strings/string_util.h"
11 #include "base/strings/utf_string_conversions.h"
12 #include "base/test/test_timeouts.h"
13 #include "base/timer/timer.h"
14 #include "chrome/browser/browser_process.h"
15 #include "chrome/browser/profiles/profile.h"
16 #include "chrome/browser/task_manager/resource_provider.h"
17 #include "chrome/browser/task_manager/task_manager.h"
18 #include "chrome/grit/generated_resources.h"
19 #include "extensions/strings/grit/extensions_strings.h"
20 #include "testing/gtest/include/gtest/gtest.h"
21 #include "ui/base/l10n/l10n_util.h"
23 namespace task_manager {
24 namespace browsertest_util {
26 namespace {
28 class ResourceChangeObserver : public TaskManagerModelObserver {
29 public:
30 ResourceChangeObserver(const TaskManagerModel* model,
31 int required_count,
32 const base::string16& title_pattern)
33 : model_(model),
34 required_count_(required_count),
35 title_pattern_(title_pattern) {}
37 virtual void OnModelChanged() override {
38 OnResourceChange();
41 virtual void OnItemsChanged(int start, int length) override {
42 OnResourceChange();
45 virtual void OnItemsAdded(int start, int length) override {
46 OnResourceChange();
49 virtual void OnItemsRemoved(int start, int length) override {
50 OnResourceChange();
53 void RunUntilSatisfied() {
54 // See if the condition is satisfied without having to run the loop. This
55 // check has to be placed after the installation of the
56 // TaskManagerModelObserver, because resources may change before that.
57 if (IsSatisfied())
58 return;
60 timer_.Start(FROM_HERE,
61 TestTimeouts::action_timeout(),
62 this,
63 &ResourceChangeObserver::OnTimeout);
65 run_loop_.Run();
67 // If we succeeded normally (no timeout), check our post condition again
68 // before returning control to the test. If it is no longer satisfied, the
69 // test is likely flaky: we were waiting for a state that was only achieved
70 // emphemerally), so treat this as a failure.
71 if (!IsSatisfied() && timer_.IsRunning()) {
72 FAIL() << "Wait condition satisfied only emphemerally. Likely test "
73 << "problem. Maybe wait instead for the state below?\n"
74 << DumpTaskManagerModel();
77 timer_.Stop();
80 private:
81 void OnResourceChange() {
82 if (!IsSatisfied())
83 return;
85 base::MessageLoop::current()->PostTask(FROM_HERE, run_loop_.QuitClosure());
88 bool IsSatisfied() { return CountMatches() == required_count_; }
90 int CountMatches() {
91 int match_count = 0;
92 for (int i = 0; i < model_->ResourceCount(); i++) {
93 task_manager::Resource::Type type = model_->GetResourceType(i);
94 // Skip system infrastructure resources.
95 if (type == task_manager::Resource::BROWSER ||
96 type == task_manager::Resource::NACL ||
97 type == task_manager::Resource::GPU ||
98 type == task_manager::Resource::UTILITY ||
99 type == task_manager::Resource::ZYGOTE ||
100 type == task_manager::Resource::SANDBOX_HELPER) {
101 continue;
104 if (MatchPattern(model_->GetResourceTitle(i), title_pattern_)) {
105 match_count++;
108 return match_count;
111 void OnTimeout() {
112 base::MessageLoop::current()->PostTask(FROM_HERE, run_loop_.QuitClosure());
113 FAIL() << "Timed out.\n" << DumpTaskManagerModel();
116 testing::Message DumpTaskManagerModel() {
117 testing::Message task_manager_state_dump;
118 task_manager_state_dump << "Waiting for exactly " << required_count_
119 << " matches of wildcard pattern \""
120 << base::UTF16ToASCII(title_pattern_) << "\"\n";
121 task_manager_state_dump << "Currently there are " << CountMatches()
122 << " matches.\n";
123 task_manager_state_dump << "Current Task Manager Model is:\n";
124 for (int i = 0; i < model_->ResourceCount(); i++) {
125 task_manager_state_dump
126 << " > " << base::UTF16ToASCII(model_->GetResourceTitle(i)) << "\n";
128 return task_manager_state_dump;
131 const TaskManagerModel* model_;
132 const int required_count_;
133 const base::string16 title_pattern_;
134 base::RunLoop run_loop_;
135 base::OneShotTimer<ResourceChangeObserver> timer_;
138 } // namespace
140 void WaitForTaskManagerRows(int required_count,
141 const base::string16& title_pattern) {
142 TaskManagerModel* model = TaskManager::GetInstance()->model();
144 ResourceChangeObserver observer(model, required_count, title_pattern);
145 model->AddObserver(&observer);
146 observer.RunUntilSatisfied();
147 model->RemoveObserver(&observer);
150 base::string16 MatchTab(const char* title) {
151 return l10n_util::GetStringFUTF16(IDS_TASK_MANAGER_TAB_PREFIX,
152 base::ASCIIToUTF16(title));
155 base::string16 MatchAnyTab() { return MatchTab("*"); }
157 base::string16 MatchAboutBlankTab() { return MatchTab("about:blank"); }
159 base::string16 MatchExtension(const char* title) {
160 return l10n_util::GetStringFUTF16(IDS_TASK_MANAGER_EXTENSION_PREFIX,
161 base::ASCIIToUTF16(title));
164 base::string16 MatchAnyExtension() { return MatchExtension("*"); }
166 base::string16 MatchApp(const char* title) {
167 return l10n_util::GetStringFUTF16(IDS_TASK_MANAGER_APP_PREFIX,
168 base::ASCIIToUTF16(title));
171 base::string16 MatchAnyApp() { return MatchApp("*"); }
173 base::string16 MatchWebView(const char* title) {
174 return l10n_util::GetStringFUTF16(
175 IDS_EXTENSION_TASK_MANAGER_WEBVIEW_TAG_PREFIX,
176 base::ASCIIToUTF16(title));
179 base::string16 MatchAnyWebView() { return MatchWebView("*"); }
181 base::string16 MatchBackground(const char* title) {
182 return l10n_util::GetStringFUTF16(IDS_TASK_MANAGER_BACKGROUND_PREFIX,
183 base::ASCIIToUTF16(title));
186 base::string16 MatchAnyBackground() { return MatchBackground("*"); }
188 base::string16 MatchPrint(const char* title) {
189 return l10n_util::GetStringFUTF16(IDS_TASK_MANAGER_PRINT_PREFIX,
190 base::ASCIIToUTF16(title));
193 base::string16 MatchAnyPrint() { return MatchPrint("*"); }
195 } // namespace browsertest_util
196 } // namespace task_manager