task_manager_browsertest_util.cc revision a1401311d1ab56c4ed0a474bd38c108f75cb0cd9
1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com// Copyright (c) 2012 The Chromium Authors. All rights reserved. 2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com// Use of this source code is governed by a BSD-style license that can be 3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com// found in the LICENSE file. 4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com 5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com#include "chrome/browser/task_manager/task_manager_browsertest_util.h" 6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com 7ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com#include "base/message_loop/message_loop.h" 8ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com#include "base/run_loop.h" 9ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com#include "base/strings/string16.h" 10ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com#include "base/strings/string_util.h" 11ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com#include "base/strings/utf_string_conversions.h" 122047f00e4698f83499ab91911999a65c21a951c9epoger@google.com#include "base/test/test_timeouts.h" 132047f00e4698f83499ab91911999a65c21a951c9epoger@google.com#include "base/timer/timer.h" 14ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com#include "chrome/browser/browser_process.h" 152047f00e4698f83499ab91911999a65c21a951c9epoger@google.com#include "chrome/browser/profiles/profile.h" 16ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com#include "chrome/browser/task_manager/resource_provider.h" 172047f00e4698f83499ab91911999a65c21a951c9epoger@google.com#include "chrome/browser/task_manager/task_manager.h" 18ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com#include "grit/generated_resources.h" 19ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com#include "testing/gtest/include/gtest/gtest.h" 20ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com#include "ui/base/l10n/l10n_util.h" 21ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com 22ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.comnamespace task_manager { 23ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.comnamespace browsertest_util { 24ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com 25ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.comnamespace { 26d41344553163085bfcfaf7d5882c6028934f8e3breed@android.com 27ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.comclass ResourceChangeObserver : public TaskManagerModelObserver { 28ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com public: 29ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com ResourceChangeObserver(const TaskManagerModel* model, 30ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com int required_count, 31ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com const base::string16& title_pattern) 32ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com : model_(model), 33ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com required_count_(required_count), 34ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com title_pattern_(title_pattern) {} 3580e39a77b16f4396eed230efea1d0b2fc8cbfb00reed@android.com 36ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com virtual void OnModelChanged() OVERRIDE { 37ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com OnResourceChange(); 38ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com } 394b7577b042966657c776fd95c67f9363af57945freed@android.com 404b7577b042966657c776fd95c67f9363af57945freed@android.com virtual void OnItemsChanged(int start, int length) OVERRIDE { 414b7577b042966657c776fd95c67f9363af57945freed@android.com OnResourceChange(); 424b7577b042966657c776fd95c67f9363af57945freed@android.com } 434b7577b042966657c776fd95c67f9363af57945freed@android.com 444b7577b042966657c776fd95c67f9363af57945freed@android.com virtual void OnItemsAdded(int start, int length) OVERRIDE { 454b7577b042966657c776fd95c67f9363af57945freed@android.com OnResourceChange(); 464b7577b042966657c776fd95c67f9363af57945freed@android.com } 474b7577b042966657c776fd95c67f9363af57945freed@android.com 484b7577b042966657c776fd95c67f9363af57945freed@android.com virtual void OnItemsRemoved(int start, int length) OVERRIDE { 494b7577b042966657c776fd95c67f9363af57945freed@android.com OnResourceChange(); 504b7577b042966657c776fd95c67f9363af57945freed@android.com } 514b7577b042966657c776fd95c67f9363af57945freed@android.com 524b7577b042966657c776fd95c67f9363af57945freed@android.com void RunUntilSatisfied() { 534b7577b042966657c776fd95c67f9363af57945freed@android.com // See if the condition is satisfied without having to run the loop. This 544b7577b042966657c776fd95c67f9363af57945freed@android.com // check has to be placed after the installation of the 554b7577b042966657c776fd95c67f9363af57945freed@android.com // TaskManagerModelObserver, because resources may change before that. 564b7577b042966657c776fd95c67f9363af57945freed@android.com if (IsSatisfied()) 574b7577b042966657c776fd95c67f9363af57945freed@android.com return; 58ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com 59ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com timer_.Start(FROM_HERE, 60ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com TestTimeouts::action_timeout(), 61ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com this, 62ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com &ResourceChangeObserver::OnTimeout); 63ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com 64ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com run_loop_.Run(); 65ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com 66ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com // If we succeeded normally (no timeout), check our post condition again 67ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com // before returning control to the test. If it is no longer satisfied, the 68ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com // test is likely flaky: we were waiting for a state that was only achieved 69ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com // emphemerally), so treat this as a failure. 70ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com if (!IsSatisfied() && timer_.IsRunning()) { 714b7577b042966657c776fd95c67f9363af57945freed@android.com FAIL() << "Wait condition satisfied only emphemerally. Likely test " 72ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com << "problem. Maybe wait instead for the state below?\n" 73ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com << DumpTaskManagerModel(); 74ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com } 75ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com 76ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com timer_.Stop(); 774b7577b042966657c776fd95c67f9363af57945freed@android.com } 78ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com 79ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com private: 80ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com void OnResourceChange() { 81ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com if (!IsSatisfied()) 82ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com return; 83ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com 84ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com base::MessageLoop::current()->PostTask(FROM_HERE, run_loop_.QuitClosure()); 85ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com } 86ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com 874b7577b042966657c776fd95c67f9363af57945freed@android.com bool IsSatisfied() { return CountMatches() == required_count_; } 884b7577b042966657c776fd95c67f9363af57945freed@android.com 8980e39a77b16f4396eed230efea1d0b2fc8cbfb00reed@android.com int CountMatches() { 90ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com int match_count = 0; 91ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com for (int i = 0; i < model_->ResourceCount(); i++) { 92ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com task_manager::Resource::Type type = model_->GetResourceType(i); 93ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com // Skip system infrastructure resources. 94ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com if (type == task_manager::Resource::BROWSER || 95ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com type == task_manager::Resource::NACL || 96ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com type == task_manager::Resource::GPU || 97ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com type == task_manager::Resource::UTILITY || 98ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com type == task_manager::Resource::ZYGOTE || 99ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com type == task_manager::Resource::SANDBOX_HELPER) { 100ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com continue; 101ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com } 102ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com 103ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com if (MatchPattern(model_->GetResourceTitle(i), title_pattern_)) { 104ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com match_count++; 105ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com } 106ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com } 107ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com return match_count; 108ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com } 109ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com 110ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com void OnTimeout() { 111ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com base::MessageLoop::current()->PostTask(FROM_HERE, run_loop_.QuitClosure()); 112ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com FAIL() << "Timed out.\n" << DumpTaskManagerModel(); 113ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com } 11480e39a77b16f4396eed230efea1d0b2fc8cbfb00reed@android.com 115ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com testing::Message DumpTaskManagerModel() { 116ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com testing::Message task_manager_state_dump; 11780e39a77b16f4396eed230efea1d0b2fc8cbfb00reed@android.com task_manager_state_dump << "Waiting for exactly " << required_count_ 118ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com << " matches of wildcard pattern \"" 119ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com << base::UTF16ToASCII(title_pattern_) << "\"\n"; 120ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com task_manager_state_dump << "Currently there are " << CountMatches() 121ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com << " matches.\n"; 122ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com task_manager_state_dump << "Current Task Manager Model is:\n"; 123ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com for (int i = 0; i < model_->ResourceCount(); i++) { 124ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com task_manager_state_dump 125ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com << " > " << base::UTF16ToASCII(model_->GetResourceTitle(i)) << "\n"; 126ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com } 1271ddd7c39289b7dd18537fdac4b630e378cd78842bungeman@google.com return task_manager_state_dump; 128ba7983e55ce15ddcd5534011935178760164fb9dbungeman@google.com } 1291ddd7c39289b7dd18537fdac4b630e378cd78842bungeman@google.com 1301ddd7c39289b7dd18537fdac4b630e378cd78842bungeman@google.com const TaskManagerModel* model_; 1311ddd7c39289b7dd18537fdac4b630e378cd78842bungeman@google.com const int required_count_; 1321ddd7c39289b7dd18537fdac4b630e378cd78842bungeman@google.com const base::string16 title_pattern_; 1331ddd7c39289b7dd18537fdac4b630e378cd78842bungeman@google.com base::RunLoop run_loop_; 1341ddd7c39289b7dd18537fdac4b630e378cd78842bungeman@google.com base::OneShotTimer<ResourceChangeObserver> timer_; 1351ddd7c39289b7dd18537fdac4b630e378cd78842bungeman@google.com}; 1361ddd7c39289b7dd18537fdac4b630e378cd78842bungeman@google.com 1371ddd7c39289b7dd18537fdac4b630e378cd78842bungeman@google.com} // namespace 1381ddd7c39289b7dd18537fdac4b630e378cd78842bungeman@google.com 1391ddd7c39289b7dd18537fdac4b630e378cd78842bungeman@google.comvoid WaitForTaskManagerRows(int required_count, 1401ddd7c39289b7dd18537fdac4b630e378cd78842bungeman@google.com const base::string16& title_pattern) { 1411ddd7c39289b7dd18537fdac4b630e378cd78842bungeman@google.com TaskManagerModel* model = TaskManager::GetInstance()->model(); 1421ddd7c39289b7dd18537fdac4b630e378cd78842bungeman@google.com 1431ddd7c39289b7dd18537fdac4b630e378cd78842bungeman@google.com ResourceChangeObserver observer(model, required_count, title_pattern); 1441ddd7c39289b7dd18537fdac4b630e378cd78842bungeman@google.com model->AddObserver(&observer); 1451ddd7c39289b7dd18537fdac4b630e378cd78842bungeman@google.com observer.RunUntilSatisfied(); 1461ddd7c39289b7dd18537fdac4b630e378cd78842bungeman@google.com model->RemoveObserver(&observer); 1471ddd7c39289b7dd18537fdac4b630e378cd78842bungeman@google.com} 1481ddd7c39289b7dd18537fdac4b630e378cd78842bungeman@google.com 149ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.combase::string16 MatchTab(const char* title) { 150ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com return l10n_util::GetStringFUTF16(IDS_TASK_MANAGER_TAB_PREFIX, 151d8730ea8b25d692c0656f8cf03f02aecfab2a17creed@android.com base::ASCIIToUTF16(title)); 152d8730ea8b25d692c0656f8cf03f02aecfab2a17creed@android.com} 153 154base::string16 MatchAnyTab() { return MatchTab("*"); } 155 156base::string16 MatchAboutBlankTab() { return MatchTab("about:blank"); } 157 158base::string16 MatchExtension(const char* title) { 159 return l10n_util::GetStringFUTF16(IDS_TASK_MANAGER_EXTENSION_PREFIX, 160 base::ASCIIToUTF16(title)); 161} 162 163base::string16 MatchAnyExtension() { return MatchExtension("*"); } 164 165base::string16 MatchApp(const char* title) { 166 return l10n_util::GetStringFUTF16(IDS_TASK_MANAGER_APP_PREFIX, 167 base::ASCIIToUTF16(title)); 168} 169 170base::string16 MatchAnyApp() { return MatchApp("*"); } 171 172base::string16 MatchWebView(const char* title) { 173 return l10n_util::GetStringFUTF16(IDS_TASK_MANAGER_WEBVIEW_TAG_PREFIX, 174 base::ASCIIToUTF16(title)); 175} 176 177base::string16 MatchAnyWebView() { return MatchWebView("*"); } 178 179base::string16 MatchBackground(const char* title) { 180 return l10n_util::GetStringFUTF16(IDS_TASK_MANAGER_BACKGROUND_PREFIX, 181 base::ASCIIToUTF16(title)); 182} 183base::string16 MatchAnyBackground() { return MatchBackground("*"); } 184 185} // namespace browsertest_util 186} // namespace task_manager 187