OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
| 5 #include "chrome/browser/task_manager/task_manager_browsertest_util.h" |
| 6 |
5 #include "base/message_loop/message_loop.h" | 7 #include "base/message_loop/message_loop.h" |
6 #include "base/strings/stringprintf.h" | 8 #include "base/run_loop.h" |
7 #include "base/strings/utf_string_conversions.h" | 9 #include "base/strings/string16.h" |
| 10 #include "base/strings/string_util.h" |
| 11 #include "base/test/test_timeouts.h" |
| 12 #include "base/timer/timer.h" |
8 #include "chrome/browser/browser_process.h" | 13 #include "chrome/browser/browser_process.h" |
9 #include "chrome/browser/chrome_notification_types.h" | |
10 #include "chrome/browser/profiles/profile.h" | 14 #include "chrome/browser/profiles/profile.h" |
11 #include "chrome/browser/task_manager/resource_provider.h" | 15 #include "chrome/browser/task_manager/resource_provider.h" |
12 #include "chrome/browser/task_manager/task_manager.h" | 16 #include "chrome/browser/task_manager/task_manager.h" |
13 #include "chrome/browser/task_manager/task_manager_browsertest_util.h" | 17 #include "testing/gtest/include/gtest/gtest.h" |
14 #include "chrome/browser/ui/browser.h" | 18 |
15 #include "chrome/browser/ui/browser_dialogs.h" | 19 namespace task_manager { |
16 #include "chrome/browser/ui/browser_window.h" | 20 namespace browsertest_util { |
17 #include "chrome/test/base/ui_test_utils.h" | |
18 #include "content/public/browser/notification_source.h" | |
19 #include "content/public/browser/web_contents.h" | |
20 | 21 |
21 namespace { | 22 namespace { |
22 | 23 |
23 int GetWebResourceCount(const TaskManagerModel* model) { | |
24 int count = 0; | |
25 for (int i = 0; i < model->ResourceCount(); i++) { | |
26 task_manager::Resource::Type type = model->GetResourceType(i); | |
27 // Skip system infrastructure resources. | |
28 if (type == task_manager::Resource::BROWSER || | |
29 type == task_manager::Resource::NACL || | |
30 type == task_manager::Resource::GPU || | |
31 type == task_manager::Resource::UTILITY || | |
32 type == task_manager::Resource::ZYGOTE || | |
33 type == task_manager::Resource::SANDBOX_HELPER) { | |
34 continue; | |
35 } | |
36 | |
37 count++; | |
38 } | |
39 return count; | |
40 } | |
41 | |
42 class ResourceChangeObserver : public TaskManagerModelObserver { | 24 class ResourceChangeObserver : public TaskManagerModelObserver { |
43 public: | 25 public: |
44 ResourceChangeObserver(const TaskManagerModel* model, | 26 ResourceChangeObserver(const TaskManagerModel* model, |
45 int target_resource_count) | 27 int required_count, |
| 28 const base::string16& title_pattern) |
46 : model_(model), | 29 : model_(model), |
47 target_resource_count_(target_resource_count) { | 30 required_count_(required_count), |
48 } | 31 title_pattern_(title_pattern) {} |
49 | 32 |
50 virtual void OnModelChanged() OVERRIDE { | 33 virtual void OnModelChanged() OVERRIDE { |
51 OnResourceChange(); | 34 OnResourceChange(); |
52 } | 35 } |
53 | 36 |
54 virtual void OnItemsChanged(int start, int length) OVERRIDE { | 37 virtual void OnItemsChanged(int start, int length) OVERRIDE { |
55 OnResourceChange(); | 38 OnResourceChange(); |
56 } | 39 } |
57 | 40 |
58 virtual void OnItemsAdded(int start, int length) OVERRIDE { | 41 virtual void OnItemsAdded(int start, int length) OVERRIDE { |
59 OnResourceChange(); | 42 OnResourceChange(); |
60 } | 43 } |
61 | 44 |
62 virtual void OnItemsRemoved(int start, int length) OVERRIDE { | 45 virtual void OnItemsRemoved(int start, int length) OVERRIDE { |
63 OnResourceChange(); | 46 OnResourceChange(); |
64 } | 47 } |
65 | 48 |
| 49 void RunUntilSatisfied() { |
| 50 // See if the condition is satisfied without having to run the loop. This |
| 51 // check has to be placed after the installation of the |
| 52 // TaskManagerModelObserver, because resources may change before that. |
| 53 if (IsSatisfied()) |
| 54 return; |
| 55 |
| 56 timer_.Start(FROM_HERE, |
| 57 TestTimeouts::action_timeout(), |
| 58 this, |
| 59 &ResourceChangeObserver::OnTimeout); |
| 60 |
| 61 run_loop_.Run(); |
| 62 |
| 63 // If we succeeded normally (no timeout), check our post condition again |
| 64 // before returning control to the test. If it is no longer satisfied, the |
| 65 // test is likely flaky: we were waiting for a state that was only achieved |
| 66 // emphemerally), so treat this as a failure. |
| 67 if (!IsSatisfied() && timer_.IsRunning()) { |
| 68 FAIL() << "Wait condition satisfied only emphemerally. Likely test " |
| 69 << "problem. Maybe wait instead for the state below?\n" |
| 70 << DumpTaskManagerModel(); |
| 71 } |
| 72 |
| 73 timer_.Stop(); |
| 74 } |
| 75 |
66 private: | 76 private: |
67 void OnResourceChange() { | 77 void OnResourceChange() { |
68 if (GetWebResourceCount(model_) == target_resource_count_) | 78 if (!IsSatisfied()) |
69 base::MessageLoopForUI::current()->Quit(); | 79 return; |
| 80 |
| 81 base::MessageLoop::current()->PostTask(FROM_HERE, run_loop_.QuitClosure()); |
| 82 } |
| 83 |
| 84 bool IsSatisfied() { return CountMatches() == required_count_; } |
| 85 |
| 86 int CountMatches() { |
| 87 int match_count = 0; |
| 88 for (int i = 0; i < model_->ResourceCount(); i++) { |
| 89 task_manager::Resource::Type type = model_->GetResourceType(i); |
| 90 // Skip system infrastructure resources. |
| 91 if (type == task_manager::Resource::BROWSER || |
| 92 type == task_manager::Resource::NACL || |
| 93 type == task_manager::Resource::GPU || |
| 94 type == task_manager::Resource::UTILITY || |
| 95 type == task_manager::Resource::ZYGOTE || |
| 96 type == task_manager::Resource::SANDBOX_HELPER) { |
| 97 continue; |
| 98 } |
| 99 |
| 100 if (MatchPattern(model_->GetResourceTitle(i), title_pattern_)) { |
| 101 match_count++; |
| 102 } |
| 103 } |
| 104 return match_count; |
| 105 } |
| 106 |
| 107 void OnTimeout() { |
| 108 base::MessageLoop::current()->PostTask(FROM_HERE, run_loop_.QuitClosure()); |
| 109 FAIL() << "Timed out.\n" << DumpTaskManagerModel(); |
| 110 } |
| 111 |
| 112 testing::Message DumpTaskManagerModel() { |
| 113 testing::Message task_manager_state_dump; |
| 114 task_manager_state_dump << "Waiting for exactly " << required_count_ |
| 115 << " matches of wildcard pattern \"" |
| 116 << UTF16ToASCII(title_pattern_) << "\"\n"; |
| 117 task_manager_state_dump << "Currently there are " << CountMatches() |
| 118 << " matches.\n"; |
| 119 task_manager_state_dump << "Current Task Manager Model is:\n"; |
| 120 for (int i = 0; i < model_->ResourceCount(); i++) { |
| 121 task_manager_state_dump |
| 122 << " > " << UTF16ToASCII(model_->GetResourceTitle(i)) << "\n"; |
| 123 } |
| 124 return task_manager_state_dump; |
70 } | 125 } |
71 | 126 |
72 const TaskManagerModel* model_; | 127 const TaskManagerModel* model_; |
73 const int target_resource_count_; | 128 const int required_count_; |
| 129 const base::string16 title_pattern_; |
| 130 base::RunLoop run_loop_; |
| 131 base::OneShotTimer<ResourceChangeObserver> timer_; |
74 }; | 132 }; |
75 | 133 |
76 } // namespace | 134 } // namespace |
77 | 135 |
78 // static | 136 void WaitForTaskManagerRows(int required_count, |
79 void TaskManagerBrowserTestUtil::WaitForWebResourceChange(int target_count) { | 137 const base::string16& title_pattern) { |
80 TaskManagerModel* model = TaskManager::GetInstance()->model(); | 138 TaskManagerModel* model = TaskManager::GetInstance()->model(); |
81 | 139 |
82 ResourceChangeObserver observer(model, target_count); | 140 ResourceChangeObserver observer(model, required_count, title_pattern); |
83 model->AddObserver(&observer); | 141 model->AddObserver(&observer); |
84 | 142 observer.RunUntilSatisfied(); |
85 // Checks that the condition has not been satisfied yet. | |
86 // This check has to be placed after the installation of the observer, | |
87 // because resources may change before that. | |
88 if (GetWebResourceCount(model) == target_count) { | |
89 model->RemoveObserver(&observer); | |
90 return; | |
91 } | |
92 | |
93 content::RunMessageLoop(); | |
94 model->RemoveObserver(&observer); | 143 model->RemoveObserver(&observer); |
95 } | 144 } |
| 145 |
| 146 } // namespace browsertest_util |
| 147 } // namespace task_manager |
OLD | NEW |