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

Side by Side Diff: chrome/browser/performance_monitor/performance_monitor_browsertest.cc

Issue 10568014: CPM Extension Event Watching Browsertests (Closed) Base URL: http://git.chromium.org/chromium/src.git@dc_extension_event_watching
Patch Set: Created 8 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 (c) 2010 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 "chrome/test/base/in_process_browser_test.h"
6
7 #include "base/file_path.h"
8 #include "base/logging.h"
9 #include "base/path_service.h"
10 #include "base/threading/sequenced_worker_pool.h"
11 #include "chrome/browser/performance_monitor/database.h"
12 #include "chrome/browser/performance_monitor/performance_monitor.h"
13 #include "chrome/browser/extensions/extension_browsertest.h"
14 #include "chrome/browser/extensions/extension_service.h"
15 #include "chrome/browser/extensions/unpacked_installer.h"
16 #include "chrome/browser/profiles/profile.h"
17 #include "chrome/browser/ui/browser.h"
18 #include "chrome/common/chrome_notification_types.h"
19 #include "chrome/common/chrome_paths.h"
20 #include "chrome/common/extensions/extension.h"
21 #include "chrome/test/base/ui_test_utils.h"
22 #include "content/public/browser/notification_registrar.h"
23 #include "content/public/browser/notification_service.h"
24
25 using extensions::Extension;
26 using performance_monitor::Event;
27
28 namespace {
29
30 // Helper struct to store the information of an extension; this is needed if the
31 // pointer to the extension ever becomes invalid (e.g., if we uninstall the
32 // extension).
33 struct ExtensionBasicInfo {
34 // Empty constructor for stl-container-happiness.
35 ExtensionBasicInfo() {
36 }
37 explicit ExtensionBasicInfo(const Extension* extension)
38 : description(extension->description()),
39 id(extension->id()),
40 name(extension->name()),
41 url(extension->url().spec()),
42 version(extension->VersionString()),
43 location(extension->location()) {
44 }
45
46 std::string description;
47 std::string id;
48 std::string name;
49 std::string url;
50 std::string version;
51 Extension::Location location;
52 };
53
54 // Compare the fields of |extension| to those in |value|; this is a check to
55 // make sure the extension data was recorded properly in the event.
56 void ValidateExtensionInfo(const ExtensionBasicInfo extension,
57 const DictionaryValue* value) {
58 std::string extension_description;
59 std::string extension_id;
60 std::string extension_name;
61 std::string extension_url;
62 std::string extension_version;
63 int extension_location;
64
65 ASSERT_TRUE(value->GetString("extension_description",
66 &extension_description));
67 ASSERT_EQ(extension.description, extension_description);
68 ASSERT_TRUE(value->GetString("extension_id", &extension_id));
69 ASSERT_EQ(extension.id, extension_id);
70 ASSERT_TRUE(value->GetString("extension_name", &extension_name));
71 ASSERT_EQ(extension.name, extension_name);
72 ASSERT_TRUE(value->GetString("extension_url", &extension_url));
73 ASSERT_EQ(extension.url, extension_url);
74 ASSERT_TRUE(value->GetString("extension_version", &extension_version));
75 ASSERT_EQ(extension.version, extension_version);
76 ASSERT_TRUE(value->GetInteger("extension_location", &extension_location));
77 ASSERT_EQ(extension.location, extension_location);
78 }
79
80 // Check that we received the proper number of events, that each event is of the
81 // proper type, and that each event recorded the proper information about the
82 // extension.
83 void CheckExtensionEvents(std::vector<int> expected_event_types,
84 std::vector<ExtensionBasicInfo> extension_infos,
85 const std::vector<linked_ptr<Event> >& events) {
86 ASSERT_EQ(expected_event_types.size(), events.size());
87
88 for (size_t i = 0; i < expected_event_types.size(); ++i) {
89 const base::DictionaryValue* value;
90 ASSERT_TRUE(events[i]->data()->GetAsDictionary(&value));
Yoyo Zhou 2012/06/27 19:59:25 data() is already a DictionaryValue, so you don't
Devlin 2012/06/27 21:04:06 Whoops, forgot we changed this... Done.
91 ValidateExtensionInfo(extension_infos[i], value);
92 int event_type;
93 ASSERT_TRUE(value->GetInteger("type", &event_type));
94 ASSERT_EQ(expected_event_types[i], event_type);
95 }
96 }
97
98 } // namespace
99
100 namespace performance_monitor {
101
102 // The main class to test PerformanceMonitor; since much of the information in
103 // PerformanceMonitor comes from extensions, we extend ExtensionBrowserTest.
Yoyo Zhou 2012/06/27 19:59:25 nit: This is exactly what ExtensionBrowserTest is
Devlin 2012/06/27 21:04:06 Done.
104 class PerformanceMonitorBrowserTest : public ExtensionBrowserTest {
105 public:
106 virtual void SetUpOnMainThread() {
107 CHECK(db_dir_.CreateUniqueTempDir());
108 performance_monitor_ = PerformanceMonitor::GetInstance();
109 performance_monitor_->SetDatabasePath(db_dir_.path());
110 performance_monitor_->Start();
111
112 // Wait for DB to finish setting up.
113 content::BrowserThread::GetBlockingPool()->FlushForTesting();
114 }
115
116 void GetEventsOnBackgroundThread(std::vector<linked_ptr<Event> >* events) {
117 *events = performance_monitor_->database()->GetEvents();
118 }
119
120 // A handle for getting the events from the database, which must be done on
121 // the background thread. Since we are testing, and can mock synchronicity
Yoyo Zhou 2012/06/27 19:59:25 nit: s/and/we/
Devlin 2012/06/27 21:04:06 Done.
122 // with FlushForTesting().
123 std::vector<linked_ptr<Event> > GetEvents() {
124 std::vector<linked_ptr<Event> > events;
125 content::BrowserThread::PostBlockingPoolSequencedTask(
126 Database::kDatabaseSequenceToken,
127 FROM_HERE,
128 base::Bind(&PerformanceMonitorBrowserTest::GetEventsOnBackgroundThread,
129 base::Unretained(this),
130 &events));
131
132 content::BrowserThread::GetBlockingPool()->FlushForTesting();
133 return events;
134 }
135
136 PerformanceMonitor* performance_monitor() const {
137 return performance_monitor_;
138 }
139
140 protected:
141 ScopedTempDir db_dir_;
142 PerformanceMonitor* performance_monitor_;
Yoyo Zhou 2012/06/27 19:59:25 This is leaked. Use a scoped_ptr.
Devlin 2012/06/27 21:04:06 I could be wrong, but my understanding is as follo
Yoyo Zhou 2012/06/27 21:55:51 Whoops, I wasn't reading carefully enough. It shou
143 };
144
145 // Test that PerformanceMonitor will correctly record an extension installation
146 // event.
147 IN_PROC_BROWSER_TEST_F(PerformanceMonitorBrowserTest, InstallExtensionEvent) {
148 FilePath extension_path;
149 PathService::Get(chrome::DIR_TEST_DATA, &extension_path);
150 extension_path = extension_path.AppendASCII("performance_monitor")
151 .AppendASCII("extensions")
152 .AppendASCII("simple_extension_v1");
153 const Extension* extension = LoadExtension(extension_path);
154
155 std::vector<ExtensionBasicInfo> extension_infos;
156 extension_infos.push_back(ExtensionBasicInfo(extension));
157
158 std::vector<int> expected_event_types;
159 expected_event_types.push_back(EVENT_EXTENSION_INSTALL);
160
161 std::vector<linked_ptr<Event> > events = GetEvents();
162 CheckExtensionEvents(expected_event_types, extension_infos, events);
163 }
164
165 // Test that PerformanceMonitor will correctly record events as an extension is
166 // disabled and enabled.
167 IN_PROC_BROWSER_TEST_F(PerformanceMonitorBrowserTest,
168 DisableAndEnableExtensionEvent) {
169 const int kNumEvents = 3;
170
171 FilePath extension_path;
172 PathService::Get(chrome::DIR_TEST_DATA, &extension_path);
173 extension_path = extension_path.AppendASCII("performance_monitor")
174 .AppendASCII("extensions")
175 .AppendASCII("simple_extension_v1");
176 const Extension* extension = LoadExtension(extension_path);
177
178 DisableExtension(extension->id());
179 EnableExtension(extension->id());
180
181 std::vector<ExtensionBasicInfo> extension_infos;
182 // There will be three events in all, each pertaining to the same extension:
183 // Extension Install
184 // Extension Disable (Unload)
185 // Extension Enable
186 for (int i = 0; i < kNumEvents; ++i)
187 extension_infos.push_back(ExtensionBasicInfo(extension));
188
189 std::vector<int> expected_event_types;
190 expected_event_types.push_back(EVENT_EXTENSION_INSTALL);
191 expected_event_types.push_back(EVENT_EXTENSION_UNLOAD);
192 expected_event_types.push_back(EVENT_EXTENSION_ENABLE);
193
194 std::vector<linked_ptr<Event> > events = GetEvents();
195 CheckExtensionEvents(expected_event_types, extension_infos, events);
196
197 // There will be an additional field on the Disable event: Unload Reason.
Yoyo Zhou 2012/06/27 19:59:25 the Unload event
Devlin 2012/06/27 21:04:06 Done.
198 const base::DictionaryValue* value;
199 int unload_reason = 0;
200 ASSERT_TRUE(events[1]->data()->GetAsDictionary(&value));
Yoyo Zhou 2012/06/27 19:59:25 ditto
Devlin 2012/06/27 21:04:06 Done.
201 ASSERT_TRUE(value->GetInteger("unload_reason", &unload_reason));
202 ASSERT_EQ(extension_misc::UNLOAD_REASON_DISABLE, unload_reason);
203 }
204
205 // Test that PerformanceMonitor correctly records an extension update event.
206 IN_PROC_BROWSER_TEST_F(PerformanceMonitorBrowserTest, UpdateExtensionEvent) {
207 ScopedTempDir temp_dir;
208 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
209
210 FilePath test_data_dir;
211 PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir);
212 test_data_dir = test_data_dir.AppendASCII("performance_monitor")
213 .AppendASCII("extensions");
214
215 // We need two versions of the same extension.
216 FilePath pem_path = test_data_dir.AppendASCII("simple_extension.pem");
217 FilePath path_v1_ = PackExtensionWithOptions(
218 test_data_dir.AppendASCII("simple_extension_v1"),
219 temp_dir.path().AppendASCII("simple_extension1.crx"),
220 pem_path,
221 FilePath());
222 FilePath path_v2_ = PackExtensionWithOptions(
223 test_data_dir.AppendASCII("simple_extension_v2"),
224 temp_dir.path().AppendASCII("simple_extension2.crx"),
225 pem_path,
226 FilePath());
227
228 const extensions::Extension* extension = InstallExtension(path_v1_, 1);
229
230 std::vector<ExtensionBasicInfo> extension_infos;
Yoyo Zhou 2012/06/27 19:59:25 Move this down to where the rest of extension_info
Devlin 2012/06/27 21:04:06 Can't :( InstallExtension returns an Extension*;
231 extension_infos.push_back(ExtensionBasicInfo(extension));
232
233 ExtensionService* extension_service =
234 browser()->profile()->GetExtensionService();
235
236 CrxInstaller* crx_installer = NULL;
237
238 ASSERT_TRUE(extension_service->
239 UpdateExtension(extension->id(), path_v2_, GURL(), &crx_installer));
240
241 // Observe implementation in ExtensionBrowserTest; this will exit the loop
242 // upon receipt of the notification.
243 content::NotificationRegistrar registrar;
Yoyo Zhou 2012/06/27 19:59:25 You probably want something like WindowedNotificat
Devlin 2012/06/27 21:04:06 Ooooh, fancy. Didn't know about that. Thanks :)
244 registrar.Add(this, chrome::NOTIFICATION_CRX_INSTALLER_DONE,
245 content::Source<CrxInstaller>(crx_installer));
246
247 ui_test_utils::RunMessageLoop();
248
249 extension = extension_service->GetExtensionById(
250 extension_infos[0].id, false); // don't include disabled extensions.
251
252 // The total series of events for this process will be:
253 // Extension Install - install version 1
254 // Extension Install - install version 2
255 // Extension Unload - disable version 1
256 // Extension Update - signal the udate to version 2
257 // We push back the corresponding ExtensionBasicInfos.
258 extension_infos.push_back(ExtensionBasicInfo(extension));
259 extension_infos.push_back(extension_infos[0]);
260 extension_infos.push_back(extension_infos[1]);
261
262 std::vector<int> expected_event_types;
263 expected_event_types.push_back(EVENT_EXTENSION_INSTALL);
264 expected_event_types.push_back(EVENT_EXTENSION_INSTALL);
265 expected_event_types.push_back(EVENT_EXTENSION_UNLOAD);
266 expected_event_types.push_back(EVENT_EXTENSION_UPDATE);
267
268 std::vector<linked_ptr<Event> > events = GetEvents();
269
270 CheckExtensionEvents(expected_event_types, extension_infos, events);
271
272 // There will be an additional field: The unload reason.
273 const base::DictionaryValue* value;
274 int unload_reason = 0;
275 ASSERT_TRUE(events[2]->data()->GetAsDictionary(&value));
Yoyo Zhou 2012/06/27 19:59:25 ditto
Devlin 2012/06/27 21:04:06 Done.
276 ASSERT_TRUE(value->GetInteger("unload_reason", &unload_reason));
277 ASSERT_EQ(extension_misc::UNLOAD_REASON_UPDATE, unload_reason);
278 }
279
280 } // namespace performance_monitor
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698