Move MatchPattern to its own header and the base namespace.
[chromium-blink-merge.git] / chrome / browser / task_manager / task_manager_browsertest_util.cc
blob4addcb0a518187f449e95b0874de132c27f804cb
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/location.h"
8 #include "base/run_loop.h"
9 #include "base/single_thread_task_runner.h"
10 #include "base/strings/pattern.h"
11 #include "base/strings/string16.h"
12 #include "base/strings/string_util.h"
13 #include "base/strings/utf_string_conversions.h"
14 #include "base/test/test_timeouts.h"
15 #include "base/thread_task_runner_handle.h"
16 #include "base/timer/timer.h"
17 #include "chrome/browser/browser_process.h"
18 #include "chrome/browser/profiles/profile.h"
19 #include "chrome/browser/task_manager/resource_provider.h"
20 #include "chrome/browser/task_manager/task_manager.h"
21 #include "chrome/grit/generated_resources.h"
22 #include "extensions/strings/grit/extensions_strings.h"
23 #include "testing/gtest/include/gtest/gtest.h"
24 #include "ui/base/l10n/l10n_util.h"
26 namespace task_manager {
27 namespace browsertest_util {
29 namespace {
31 class ResourceChangeObserver : public TaskManagerModelObserver {
32 public:
33 ResourceChangeObserver(const TaskManagerModel* model,
34 int required_count,
35 const base::string16& title_pattern,
36 ColumnSpecifier column_specifier,
37 size_t min_column_value)
38 : model_(model),
39 required_count_(required_count),
40 title_pattern_(title_pattern),
41 column_specifier_(column_specifier),
42 min_column_value_(min_column_value) {}
44 void OnModelChanged() override { OnResourceChange(); }
46 void OnItemsChanged(int start, int length) override { OnResourceChange(); }
48 void OnItemsAdded(int start, int length) override { OnResourceChange(); }
50 void OnItemsRemoved(int start, int length) override { OnResourceChange(); }
52 void RunUntilSatisfied() {
53 // See if the condition is satisfied without having to run the loop. This
54 // check has to be placed after the installation of the
55 // TaskManagerModelObserver, because resources may change before that.
56 if (IsSatisfied())
57 return;
59 timer_.Start(FROM_HERE,
60 TestTimeouts::action_timeout(),
61 this,
62 &ResourceChangeObserver::OnTimeout);
64 run_loop_.Run();
66 // If we succeeded normally (no timeout), check our post condition again
67 // before returning control to the test. If it is no longer satisfied, the
68 // test is likely flaky: we were waiting for a state that was only achieved
69 // emphemerally), so treat this as a failure.
70 if (!IsSatisfied() && timer_.IsRunning()) {
71 FAIL() << "Wait condition satisfied only emphemerally. Likely test "
72 << "problem. Maybe wait instead for the state below?\n"
73 << DumpTaskManagerModel();
76 timer_.Stop();
79 private:
80 void OnResourceChange() {
81 if (!IsSatisfied())
82 return;
84 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
85 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 if (!base::MatchPattern(model_->GetResourceTitle(i), title_pattern_))
94 continue;
96 if (GetColumnValue(i) < min_column_value_)
97 continue;
99 match_count++;
101 return match_count;
104 size_t GetColumnValue(int index) {
105 size_t value = 0;
106 bool success = false;
107 switch (column_specifier_) {
108 case COLUMN_NONE:
109 break;
110 case V8_MEMORY:
111 success = model_->GetV8Memory(index, &value);
112 break;
113 case V8_MEMORY_USED:
114 success = model_->GetV8MemoryUsed(index, &value);
115 break;
116 case SQLITE_MEMORY_USED:
117 success = model_->GetSqliteMemoryUsedBytes(index, &value);
118 break;
120 if (!success)
121 return 0;
122 return value;
125 const char* GetColumnName() {
126 switch (column_specifier_) {
127 case COLUMN_NONE:
128 return "N/A";
129 case V8_MEMORY:
130 return "V8 Memory";
131 case V8_MEMORY_USED:
132 return "V8 Memory Used";
133 case SQLITE_MEMORY_USED:
134 return "SQLite Memory Used";
136 return "N/A";
139 void OnTimeout() {
140 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
141 run_loop_.QuitClosure());
142 FAIL() << "Timed out.\n" << DumpTaskManagerModel();
145 testing::Message DumpTaskManagerModel() {
146 testing::Message task_manager_state_dump;
147 task_manager_state_dump << "Waiting for exactly " << required_count_
148 << " matches of wildcard pattern \""
149 << base::UTF16ToASCII(title_pattern_) << "\"";
150 if (min_column_value_ > 0) {
151 task_manager_state_dump << " && [" << GetColumnName()
152 << " >= " << min_column_value_ << "]";
154 task_manager_state_dump << "\nCurrently there are " << CountMatches()
155 << " matches.";
156 task_manager_state_dump << "\nCurrent Task Manager Model is:";
157 for (int i = 0; i < model_->ResourceCount(); i++) {
158 task_manager_state_dump
159 << "\n > " << std::setw(40) << std::left
160 << base::UTF16ToASCII(model_->GetResourceTitle(i));
161 if (min_column_value_ > 0) {
162 task_manager_state_dump << " [" << GetColumnName()
163 << " == " << GetColumnValue(i) << "]";
166 return task_manager_state_dump;
169 const TaskManagerModel* model_;
170 const int required_count_;
171 const base::string16 title_pattern_;
172 const ColumnSpecifier column_specifier_;
173 const size_t min_column_value_;
174 base::RunLoop run_loop_;
175 base::OneShotTimer<ResourceChangeObserver> timer_;
178 } // namespace
180 void WaitForTaskManagerRows(int required_count,
181 const base::string16& title_pattern) {
182 TaskManagerModel* model = TaskManager::GetInstance()->model();
184 const int column_value_dont_care = 0;
185 ResourceChangeObserver observer(model, required_count, title_pattern,
186 COLUMN_NONE, column_value_dont_care);
187 model->AddObserver(&observer);
188 observer.RunUntilSatisfied();
189 model->RemoveObserver(&observer);
192 void WaitForTaskManagerStatToExceed(const base::string16& title_pattern,
193 ColumnSpecifier column_getter,
194 size_t min_column_value) {
195 TaskManagerModel* model = TaskManager::GetInstance()->model();
197 const int wait_for_one_match = 1;
198 ResourceChangeObserver observer(model, wait_for_one_match, title_pattern,
199 column_getter, min_column_value);
200 model->AddObserver(&observer);
201 observer.RunUntilSatisfied();
202 model->RemoveObserver(&observer);
205 base::string16 MatchTab(const char* title) {
206 return l10n_util::GetStringFUTF16(IDS_TASK_MANAGER_TAB_PREFIX,
207 base::ASCIIToUTF16(title));
210 base::string16 MatchAnyTab() { return MatchTab("*"); }
212 base::string16 MatchAboutBlankTab() { return MatchTab("about:blank"); }
214 base::string16 MatchExtension(const char* title) {
215 return l10n_util::GetStringFUTF16(IDS_TASK_MANAGER_EXTENSION_PREFIX,
216 base::ASCIIToUTF16(title));
219 base::string16 MatchAnyExtension() { return MatchExtension("*"); }
221 base::string16 MatchApp(const char* title) {
222 return l10n_util::GetStringFUTF16(IDS_TASK_MANAGER_APP_PREFIX,
223 base::ASCIIToUTF16(title));
226 base::string16 MatchAnyApp() { return MatchApp("*"); }
228 base::string16 MatchWebView(const char* title) {
229 return l10n_util::GetStringFUTF16(
230 IDS_EXTENSION_TASK_MANAGER_WEBVIEW_TAG_PREFIX,
231 base::ASCIIToUTF16(title));
234 base::string16 MatchAnyWebView() { return MatchWebView("*"); }
236 base::string16 MatchBackground(const char* title) {
237 return l10n_util::GetStringFUTF16(IDS_TASK_MANAGER_BACKGROUND_PREFIX,
238 base::ASCIIToUTF16(title));
241 base::string16 MatchAnyBackground() { return MatchBackground("*"); }
243 base::string16 MatchPrint(const char* title) {
244 return l10n_util::GetStringFUTF16(IDS_TASK_MANAGER_PRINT_PREFIX,
245 base::ASCIIToUTF16(title));
248 base::string16 MatchAnyPrint() { return MatchPrint("*"); }
250 base::string16 MatchSubframe(const char* title) {
251 return l10n_util::GetStringFUTF16(IDS_TASK_MANAGER_SUBFRAME_PREFIX,
252 base::ASCIIToUTF16(title));
255 base::string16 MatchAnySubframe() {
256 return MatchSubframe("*");
259 base::string16 MatchUtility(const base::string16& title) {
260 return l10n_util::GetStringFUTF16(IDS_TASK_MANAGER_UTILITY_PREFIX, title);
263 base::string16 MatchAnyUtility() {
264 return MatchUtility(base::ASCIIToUTF16("*"));
267 } // namespace browsertest_util
268 } // namespace task_manager