GoogleURLTrackerInfoBarDelegate: Initialize uninitialized member in constructor.
[chromium-blink-merge.git] / chrome / browser / performance_monitor / performance_monitor_browsertest.cc
blob96629f90d736a65a4c0221294891f37ecbcc46f5
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 "base/command_line.h"
6 #include "base/files/file_path.h"
7 #include "base/logging.h"
8 #include "base/path_service.h"
9 #include "base/strings/string_number_conversions.h"
10 #include "base/threading/sequenced_worker_pool.h"
11 #include "chrome/browser/browser_process.h"
12 #include "chrome/browser/chrome_notification_types.h"
13 #include "chrome/browser/extensions/extension_browsertest.h"
14 #include "chrome/browser/extensions/extension_service.h"
15 #include "chrome/browser/performance_monitor/constants.h"
16 #include "chrome/browser/performance_monitor/database.h"
17 #include "chrome/browser/performance_monitor/metric.h"
18 #include "chrome/browser/performance_monitor/performance_monitor.h"
19 #include "chrome/browser/prefs/session_startup_pref.h"
20 #include "chrome/browser/profiles/profile.h"
21 #include "chrome/browser/profiles/profile_manager.h"
22 #include "chrome/browser/sessions/session_service.h"
23 #include "chrome/browser/sessions/session_service_factory.h"
24 #include "chrome/browser/sessions/session_service_test_helper.h"
25 #include "chrome/browser/ui/browser.h"
26 #include "chrome/browser/ui/browser_commands.h"
27 #include "chrome/browser/ui/browser_navigator.h"
28 #include "chrome/browser/ui/browser_window.h"
29 #include "chrome/browser/ui/host_desktop.h"
30 #include "chrome/browser/ui/tabs/tab_strip_model.h"
31 #include "chrome/common/chrome_constants.h"
32 #include "chrome/common/chrome_paths.h"
33 #include "chrome/common/chrome_switches.h"
34 #include "chrome/common/chrome_version_info.h"
35 #include "chrome/common/url_constants.h"
36 #include "chrome/test/base/ui_test_utils.h"
37 #include "content/public/browser/notification_registrar.h"
38 #include "content/public/browser/notification_service.h"
39 #include "content/public/common/page_transition_types.h"
40 #include "content/public/test/browser_test_utils.h"
41 #include "content/public/test/test_navigation_observer.h"
42 #include "content/public/test/test_utils.h"
43 #include "extensions/common/extension.h"
45 #if defined(OS_CHROMEOS)
46 #include "chrome/browser/chromeos/login/users/user_manager.h"
47 #include "chrome/browser/chromeos/profiles/profile_helper.h"
48 #include "chromeos/chromeos_switches.h"
49 #endif
51 #if defined(OS_MACOSX)
52 #include "base/mac/scoped_nsautorelease_pool.h"
53 #endif
55 using extensions::Extension;
57 namespace performance_monitor {
59 namespace {
61 const base::TimeDelta kMaxStartupTime = base::TimeDelta::FromMinutes(3);
63 #if defined(OS_CHROMEOS)
64 // User account email and directory hash for secondary account for multi-profile
65 // sensitive test cases.
66 const char kSecondProfileAccount[] = "profile2@test.com";
67 const char kSecondProfileHash[] = "profile2";
68 #endif
70 // Helper struct to store the information of an extension; this is needed if the
71 // pointer to the extension ever becomes invalid (e.g., if we uninstall the
72 // extension).
73 struct ExtensionBasicInfo {
74 // Empty constructor for stl-container-happiness.
75 ExtensionBasicInfo() {
77 explicit ExtensionBasicInfo(const Extension* extension)
78 : description(extension->description()),
79 id(extension->id()),
80 name(extension->name()),
81 url(extension->url().spec()),
82 version(extension->VersionString()),
83 location(extension->location()) {
86 std::string description;
87 std::string id;
88 std::string name;
89 std::string url;
90 std::string version;
91 extensions::Manifest::Location location;
94 // Compare the fields of |extension| to those in |value|; this is a check to
95 // make sure the extension data was recorded properly in the event.
96 void ValidateExtensionInfo(const ExtensionBasicInfo extension,
97 const base::DictionaryValue* value) {
98 std::string extension_description;
99 std::string extension_id;
100 std::string extension_name;
101 std::string extension_url;
102 std::string extension_version;
103 int extension_location;
105 ASSERT_TRUE(value->GetString("extensionDescription",
106 &extension_description));
107 ASSERT_EQ(extension.description, extension_description);
108 ASSERT_TRUE(value->GetString("extensionId", &extension_id));
109 ASSERT_EQ(extension.id, extension_id);
110 ASSERT_TRUE(value->GetString("extensionName", &extension_name));
111 ASSERT_EQ(extension.name, extension_name);
112 ASSERT_TRUE(value->GetString("extensionUrl", &extension_url));
113 ASSERT_EQ(extension.url, extension_url);
114 ASSERT_TRUE(value->GetString("extensionVersion", &extension_version));
115 ASSERT_EQ(extension.version, extension_version);
116 ASSERT_TRUE(value->GetInteger("extensionLocation", &extension_location));
117 ASSERT_EQ(extension.location, extension_location);
120 // Verify that a particular event has the proper type.
121 void CheckEventType(int expected_event_type, const linked_ptr<Event>& event) {
122 int event_type = -1;
123 ASSERT_TRUE(event->data()->GetInteger("eventType", &event_type));
124 ASSERT_EQ(expected_event_type, event_type);
125 ASSERT_EQ(expected_event_type, event->type());
128 // Verify that we received the proper number of events, checking the type of
129 // each one.
130 void CheckEventTypes(const std::vector<int>& expected_event_types,
131 const Database::EventVector& events) {
132 ASSERT_EQ(expected_event_types.size(), events.size());
134 for (size_t i = 0; i < expected_event_types.size(); ++i)
135 CheckEventType(expected_event_types[i], events[i]);
138 // Check that we received the proper number of events, that each event is of the
139 // proper type, and that each event recorded the proper information about the
140 // extension.
141 void CheckExtensionEvents(
142 const std::vector<int>& expected_event_types,
143 const Database::EventVector& events,
144 const std::vector<ExtensionBasicInfo>& extension_infos) {
145 CheckEventTypes(expected_event_types, events);
147 for (size_t i = 0; i < expected_event_types.size(); ++i) {
148 ValidateExtensionInfo(extension_infos[i], events[i]->data());
149 int event_type;
150 ASSERT_TRUE(events[i]->data()->GetInteger("eventType", &event_type));
151 ASSERT_EQ(expected_event_types[i], event_type);
155 } // namespace
157 class PerformanceMonitorBrowserTest : public ExtensionBrowserTest {
158 public:
159 virtual void SetUpOnMainThread() OVERRIDE {
160 CHECK(db_dir_.CreateUniqueTempDir());
161 performance_monitor_ = PerformanceMonitor::GetInstance();
162 performance_monitor_->SetDatabasePath(db_dir_.path());
164 // PerformanceMonitor's initialization process involves a significant
165 // amount of thread-hopping between the UI thread and the background thread.
166 // If we begin the tests prior to full initialization, we cannot predict
167 // the behavior or mock synchronicity as we must. Wait for initialization
168 // to complete fully before proceeding with the test.
169 content::WindowedNotificationObserver windowed_observer(
170 chrome::NOTIFICATION_PERFORMANCE_MONITOR_INITIALIZED,
171 content::NotificationService::AllSources());
173 // We stop the timer in charge of doing timed collections so that we can
174 // enforce when, and how many times, we do these collections.
175 performance_monitor_->disable_timer_autostart_for_testing_ = true;
176 // Force metrics to be stored, regardless of switches used.
177 performance_monitor_->database_logging_enabled_ = true;
178 performance_monitor_->Initialize();
180 windowed_observer.Wait();
183 // A handle for gathering statistics from the database, which must be done on
184 // the background thread. Since we are testing, we can mock synchronicity with
185 // FlushForTesting().
186 void GatherStatistics() {
187 performance_monitor_->next_collection_time_ = base::Time::Now();
188 performance_monitor_->GatherMetricsMapOnUIThread();
190 RunAllPendingInMessageLoop(content::BrowserThread::IO);
191 content::BrowserThread::GetBlockingPool()->FlushForTesting();
194 void GetEventsOnBackgroundThread(Database::EventVector* events) {
195 // base::Time is potentially flaky in that there is no guarantee that it
196 // won't actually decrease between successive calls. If we call GetEvents
197 // and the Database uses base::Time::Now() and gets a lesser time, then it
198 // will return 0 events. Thus, we use a time that is guaranteed to be in the
199 // future (for at least the next couple hundred thousand years).
200 *events = performance_monitor_->database()->GetEvents(
201 base::Time(), base::Time::FromInternalValue(kint64max));
204 // A handle for getting the events from the database, which must be done on
205 // the background thread. Since we are testing, we can mock synchronicity
206 // with FlushForTesting().
207 Database::EventVector GetEvents() {
208 // Ensure that any event insertions happen prior to getting events in order
209 // to avoid race conditions.
210 content::BrowserThread::GetBlockingPool()->FlushForTesting();
211 content::RunAllPendingInMessageLoop();
213 Database::EventVector events;
214 content::BrowserThread::PostBlockingPoolSequencedTask(
215 Database::kDatabaseSequenceToken,
216 FROM_HERE,
217 base::Bind(&PerformanceMonitorBrowserTest::GetEventsOnBackgroundThread,
218 base::Unretained(this),
219 &events));
221 content::BrowserThread::GetBlockingPool()->FlushForTesting();
222 return events;
225 void GetStatsOnBackgroundThread(Database::MetricVector* metrics,
226 MetricType type) {
227 *metrics = *performance_monitor_->database()->GetStatsForActivityAndMetric(
228 type, base::Time(), base::Time::FromInternalValue(kint64max));
231 // A handle for getting statistics from the database (see previous comments on
232 // GetEvents() and GetEventsOnBackgroundThread).
233 Database::MetricVector GetStats(MetricType type) {
234 content::BrowserThread::GetBlockingPool()->FlushForTesting();
235 content::RunAllPendingInMessageLoop();
237 Database::MetricVector metrics;
238 content::BrowserThread::PostBlockingPoolSequencedTask(
239 Database::kDatabaseSequenceToken,
240 FROM_HERE,
241 base::Bind(&PerformanceMonitorBrowserTest::GetStatsOnBackgroundThread,
242 base::Unretained(this),
243 &metrics,
244 type));
246 content::BrowserThread::GetBlockingPool()->FlushForTesting();
247 return metrics;
250 // A handle for inserting a state value into the database, which must be done
251 // on the background thread. This is useful for mocking up a scenario in which
252 // the database has prior data stored. We mock synchronicity with
253 // FlushForTesting().
254 void AddStateValue(const std::string& key, const std::string& value) {
255 content::BrowserThread::PostBlockingPoolSequencedTask(
256 Database::kDatabaseSequenceToken,
257 FROM_HERE,
258 base::Bind(base::IgnoreResult(&Database::AddStateValue),
259 base::Unretained(performance_monitor()->database()),
260 key,
261 value));
263 content::BrowserThread::GetBlockingPool()->FlushForTesting();
266 // A handle for PerformanceMonitor::CheckForVersionUpdateOnBackgroundThread();
267 // we mock synchronicity with FlushForTesting().
268 void CheckForVersionUpdate() {
269 content::BrowserThread::PostBlockingPoolSequencedTask(
270 Database::kDatabaseSequenceToken,
271 FROM_HERE,
272 base::Bind(&PerformanceMonitor::CheckForVersionUpdateOnBackgroundThread,
273 base::Unretained(performance_monitor())));
275 content::BrowserThread::GetBlockingPool()->FlushForTesting();
278 PerformanceMonitor* performance_monitor() const {
279 return performance_monitor_;
282 protected:
283 base::ScopedTempDir db_dir_;
284 PerformanceMonitor* performance_monitor_;
287 class PerformanceMonitorUncleanExitBrowserTest
288 : public PerformanceMonitorBrowserTest,
289 public testing::WithParamInterface<bool> {
290 public:
291 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
292 PerformanceMonitorBrowserTest::SetUpCommandLine(command_line);
293 #if defined(OS_CHROMEOS)
294 command_line->AppendSwitch(
295 chromeos::switches::kIgnoreUserProfileMappingForTests);
296 #endif
299 virtual bool SetUpUserDataDirectory() OVERRIDE {
300 base::FilePath user_data_directory;
301 PathService::Get(chrome::DIR_USER_DATA, &user_data_directory);
303 // On CrOS, if we are "logged in" with the --login-profile switch,
304 // the default profile will be different. We check if we are logged in, and,
305 // if we are, we use that profile name instead. (Note: trybots will
306 // typically be logged in with 'user'.)
307 #if defined(OS_CHROMEOS)
308 const CommandLine command_line = *CommandLine::ForCurrentProcess();
309 if (command_line.HasSwitch(chromeos::switches::kLoginProfile)) {
310 first_profile_name_ =
311 command_line.GetSwitchValueASCII(chromeos::switches::kLoginProfile);
312 } else {
313 first_profile_name_ = chrome::kInitialProfile;
315 #else
316 first_profile_name_ = chrome::kInitialProfile;
317 #endif
319 base::FilePath first_profile =
320 user_data_directory.AppendASCII(first_profile_name_);
321 CHECK(base::CreateDirectory(first_profile));
323 base::FilePath stock_prefs_file;
324 PathService::Get(chrome::DIR_TEST_DATA, &stock_prefs_file);
325 stock_prefs_file = stock_prefs_file.AppendASCII("performance_monitor")
326 .AppendASCII("unclean_exit_prefs");
327 CHECK(base::PathExists(stock_prefs_file));
329 base::FilePath first_profile_prefs_file =
330 first_profile.Append(chrome::kPreferencesFilename);
331 CHECK(base::CopyFile(stock_prefs_file, first_profile_prefs_file));
332 CHECK(base::PathExists(first_profile_prefs_file));
334 second_profile_name_ =
335 std::string(chrome::kMultiProfileDirPrefix)
336 .append(base::IntToString(1));
337 #if defined(OS_CHROMEOS)
338 if (GetParam()) {
339 second_profile_name_ = chromeos::ProfileHelper::GetUserProfileDir(
340 kSecondProfileHash).BaseName().value();
342 #endif
344 base::FilePath second_profile =
345 user_data_directory.AppendASCII(second_profile_name_);
346 CHECK(base::CreateDirectory(second_profile));
348 base::FilePath second_profile_prefs_file =
349 second_profile.Append(chrome::kPreferencesFilename);
350 CHECK(base::CopyFile(stock_prefs_file, second_profile_prefs_file));
351 CHECK(base::PathExists(second_profile_prefs_file));
353 return true;
356 #if defined(OS_CHROMEOS)
357 virtual void AddSecondUserAccount() {
358 // Add second user account for multi-profile test.
359 if (GetParam()) {
360 chromeos::UserManager::Get()->UserLoggedIn(kSecondProfileAccount,
361 kSecondProfileHash,
362 false);
365 #endif
367 protected:
368 std::string first_profile_name_;
369 std::string second_profile_name_;
372 class PerformanceMonitorSessionRestoreBrowserTest
373 : public PerformanceMonitorBrowserTest {
374 public:
375 virtual void SetUpOnMainThread() OVERRIDE {
376 SessionStartupPref pref(SessionStartupPref::LAST);
377 SessionStartupPref::SetStartupPref(browser()->profile(), pref);
378 #if defined(OS_CHROMEOS) || defined (OS_MACOSX)
379 // Undo the effect of kBrowserAliveWithNoWindows in defaults.cc so that we
380 // can get these test to work without quitting.
381 SessionServiceTestHelper helper(
382 SessionServiceFactory::GetForProfile(browser()->profile()));
383 helper.SetForceBrowserNotAliveWithNoWindows(true);
384 helper.ReleaseService();
385 #endif
387 PerformanceMonitorBrowserTest::SetUpOnMainThread();
390 Browser* QuitBrowserAndRestore(Browser* browser, int expected_tab_count) {
391 Profile* profile = browser->profile();
393 // Close the browser.
394 g_browser_process->AddRefModule();
395 content::WindowedNotificationObserver observer(
396 chrome::NOTIFICATION_BROWSER_CLOSED,
397 content::NotificationService::AllSources());
398 browser->window()->Close();
399 #if defined(OS_MACOSX)
400 // BrowserWindowController depends on the auto release pool being recycled
401 // in the message loop to delete itself, which frees the Browser object
402 // which fires this event.
403 AutoreleasePool()->Recycle();
404 #endif
405 observer.Wait();
407 // Create a new window, which should trigger session restore.
408 content::TestNavigationObserver restore_observer(NULL, expected_tab_count);
409 restore_observer.StartWatchingNewWebContents();
410 ui_test_utils::BrowserAddedObserver window_observer;
411 chrome::NewEmptyWindow(profile, chrome::GetActiveDesktop());
412 Browser* new_browser = window_observer.WaitForSingleNewBrowser();
413 restore_observer.Wait();
414 g_browser_process->ReleaseModule();
416 return new_browser;
420 // Test that PerformanceMonitor will correctly record an extension installation
421 // event.
422 IN_PROC_BROWSER_TEST_F(PerformanceMonitorBrowserTest, InstallExtensionEvent) {
423 base::FilePath extension_path;
424 PathService::Get(chrome::DIR_TEST_DATA, &extension_path);
425 extension_path = extension_path.AppendASCII("performance_monitor")
426 .AppendASCII("extensions")
427 .AppendASCII("simple_extension_v1");
428 const Extension* extension = LoadExtension(extension_path);
430 std::vector<ExtensionBasicInfo> extension_infos;
431 extension_infos.push_back(ExtensionBasicInfo(extension));
433 std::vector<int> expected_event_types;
434 expected_event_types.push_back(EVENT_EXTENSION_INSTALL);
436 Database::EventVector events = GetEvents();
437 CheckExtensionEvents(expected_event_types, events, extension_infos);
440 // Test that PerformanceMonitor will correctly record events as an extension is
441 // disabled and enabled.
442 // Test is falky, see http://crbug.com/157980
443 IN_PROC_BROWSER_TEST_F(PerformanceMonitorBrowserTest,
444 DISABLED_DisableAndEnableExtensionEvent) {
445 const int kNumEvents = 3;
447 base::FilePath extension_path;
448 PathService::Get(chrome::DIR_TEST_DATA, &extension_path);
449 extension_path = extension_path.AppendASCII("performance_monitor")
450 .AppendASCII("extensions")
451 .AppendASCII("simple_extension_v1");
452 const Extension* extension = LoadExtension(extension_path);
454 DisableExtension(extension->id());
455 EnableExtension(extension->id());
457 std::vector<ExtensionBasicInfo> extension_infos;
458 // There will be three events in all, each pertaining to the same extension:
459 // Extension Install
460 // Extension Disable
461 // Extension Enable
462 for (int i = 0; i < kNumEvents; ++i)
463 extension_infos.push_back(ExtensionBasicInfo(extension));
465 std::vector<int> expected_event_types;
466 expected_event_types.push_back(EVENT_EXTENSION_INSTALL);
467 expected_event_types.push_back(EVENT_EXTENSION_DISABLE);
468 expected_event_types.push_back(EVENT_EXTENSION_ENABLE);
470 Database::EventVector events = GetEvents();
471 CheckExtensionEvents(expected_event_types, events, extension_infos);
474 // Test that PerformanceMonitor correctly records an extension update event.
475 IN_PROC_BROWSER_TEST_F(PerformanceMonitorBrowserTest, UpdateExtensionEvent) {
476 base::ScopedTempDir temp_dir;
477 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
479 base::FilePath test_data_dir;
480 PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir);
481 test_data_dir = test_data_dir.AppendASCII("performance_monitor")
482 .AppendASCII("extensions");
484 // We need two versions of the same extension.
485 base::FilePath pem_path = test_data_dir.AppendASCII("simple_extension.pem");
486 base::FilePath path_v1_ = PackExtensionWithOptions(
487 test_data_dir.AppendASCII("simple_extension_v1"),
488 temp_dir.path().AppendASCII("simple_extension1.crx"),
489 pem_path,
490 base::FilePath());
491 base::FilePath path_v2_ = PackExtensionWithOptions(
492 test_data_dir.AppendASCII("simple_extension_v2"),
493 temp_dir.path().AppendASCII("simple_extension2.crx"),
494 pem_path,
495 base::FilePath());
497 const extensions::Extension* extension = InstallExtension(path_v1_, 1);
499 std::vector<ExtensionBasicInfo> extension_infos;
500 extension_infos.push_back(ExtensionBasicInfo(extension));
502 ExtensionService* extension_service =
503 browser()->profile()->GetExtensionService();
505 extensions::CrxInstaller* crx_installer = NULL;
507 // Create an observer to wait for the update to finish.
508 content::WindowedNotificationObserver windowed_observer(
509 chrome::NOTIFICATION_CRX_INSTALLER_DONE,
510 content::Source<extensions::CrxInstaller>(crx_installer));
511 ASSERT_TRUE(extension_service->
512 UpdateExtension(extension->id(), path_v2_, true, &crx_installer));
513 windowed_observer.Wait();
515 extension = extension_service->GetExtensionById(
516 extension_infos[0].id, false); // don't include disabled extensions.
518 // The total series of events for this process will be:
519 // Extension Install - install version 1
520 // Extension Install - install version 2
521 // Extension Update - signal the udate to version 2
522 // We push back the corresponding ExtensionBasicInfos.
523 extension_infos.push_back(ExtensionBasicInfo(extension));
524 extension_infos.push_back(extension_infos[1]);
526 std::vector<int> expected_event_types;
527 expected_event_types.push_back(EVENT_EXTENSION_INSTALL);
528 expected_event_types.push_back(EVENT_EXTENSION_INSTALL);
529 expected_event_types.push_back(EVENT_EXTENSION_UPDATE);
531 Database::EventVector events = GetEvents();
533 CheckExtensionEvents(expected_event_types, events, extension_infos);
536 IN_PROC_BROWSER_TEST_F(PerformanceMonitorBrowserTest, UninstallExtensionEvent) {
537 const int kNumEvents = 2;
538 base::FilePath extension_path;
539 PathService::Get(chrome::DIR_TEST_DATA, &extension_path);
540 extension_path = extension_path.AppendASCII("performance_monitor")
541 .AppendASCII("extensions")
542 .AppendASCII("simple_extension_v1");
543 const Extension* extension = LoadExtension(extension_path);
545 std::vector<ExtensionBasicInfo> extension_infos;
546 // There will be two events, both pertaining to the same extension:
547 // Extension Install
548 // Extension Uninstall
549 for (int i = 0; i < kNumEvents; ++i)
550 extension_infos.push_back(ExtensionBasicInfo(extension));
552 UninstallExtension(extension->id());
554 std::vector<int> expected_event_types;
555 expected_event_types.push_back(EVENT_EXTENSION_INSTALL);
556 expected_event_types.push_back(EVENT_EXTENSION_UNINSTALL);
558 Database::EventVector events = GetEvents();
560 CheckExtensionEvents(expected_event_types, events, extension_infos);
563 IN_PROC_BROWSER_TEST_F(PerformanceMonitorBrowserTest, NewVersionEvent) {
564 const char kOldVersion[] = "0.0";
566 // The version in the database right now will be the current version of chrome
567 // (gathered at initialization of PerformanceMonitor). Replace this with an
568 // older version so an event is generated.
569 AddStateValue(kStateChromeVersion, kOldVersion);
571 CheckForVersionUpdate();
573 chrome::VersionInfo version;
574 ASSERT_TRUE(version.is_valid());
575 std::string version_string = version.Version();
577 Database::EventVector events = GetEvents();
578 ASSERT_EQ(1u, events.size());
579 ASSERT_EQ(EVENT_CHROME_UPDATE, events[0]->type());
581 const base::DictionaryValue* value;
582 ASSERT_TRUE(events[0]->data()->GetAsDictionary(&value));
584 std::string previous_version;
585 std::string current_version;
587 ASSERT_TRUE(value->GetString("previousVersion", &previous_version));
588 ASSERT_EQ(kOldVersion, previous_version);
589 ASSERT_TRUE(value->GetString("currentVersion", &current_version));
590 ASSERT_EQ(version_string, current_version);
593 // crbug.com/160502
594 IN_PROC_BROWSER_TEST_F(PerformanceMonitorBrowserTest,
595 DISABLED_GatherStatistics) {
596 GatherStatistics();
598 // No stats should be recorded for this CPUUsage because this was the first
599 // call to GatherStatistics.
600 Database::MetricVector stats = GetStats(METRIC_CPU_USAGE);
601 ASSERT_EQ(0u, stats.size());
603 stats = GetStats(METRIC_PRIVATE_MEMORY_USAGE);
604 ASSERT_EQ(1u, stats.size());
605 EXPECT_GT(stats[0].value, 0);
607 stats = GetStats(METRIC_SHARED_MEMORY_USAGE);
608 ASSERT_EQ(1u, stats.size());
609 EXPECT_GT(stats[0].value, 0);
611 // Open new tabs to incur CPU usage.
612 for (int i = 0; i < 10; ++i) {
613 chrome::NavigateParams params(
614 browser(), ui_test_utils::GetTestUrl(
615 base::FilePath(base::FilePath::kCurrentDirectory),
616 base::FilePath(FILE_PATH_LITERAL("title1.html"))),
617 content::PAGE_TRANSITION_LINK);
618 params.disposition = NEW_BACKGROUND_TAB;
619 ui_test_utils::NavigateToURL(&params);
621 GatherStatistics();
623 // One CPUUsage stat should exist now.
624 stats = GetStats(METRIC_CPU_USAGE);
625 ASSERT_EQ(1u, stats.size());
626 EXPECT_GT(stats[0].value, 0);
628 stats = GetStats(METRIC_PRIVATE_MEMORY_USAGE);
629 ASSERT_EQ(2u, stats.size());
630 EXPECT_GT(stats[1].value, 0);
632 stats = GetStats(METRIC_SHARED_MEMORY_USAGE);
633 ASSERT_EQ(2u, stats.size());
634 EXPECT_GT(stats[1].value, 0);
637 // Disabled on other platforms because of flakiness: http://crbug.com/159172.
638 #if !defined(OS_WIN)
639 // Disabled on Windows due to a bug where Windows will return a normal exit
640 // code in the testing environment, even if the process died (this is not the
641 // case when hand-testing). This code can be traced to MSDN functions in
642 // base::GetTerminationStatus(), so there's not much we can do.
643 IN_PROC_BROWSER_TEST_F(PerformanceMonitorBrowserTest,
644 DISABLED_RendererKilledEvent) {
645 content::CrashTab(browser()->tab_strip_model()->GetActiveWebContents());
647 Database::EventVector events = GetEvents();
649 ASSERT_EQ(1u, events.size());
650 CheckEventType(EVENT_RENDERER_KILLED, events[0]);
652 // Check the url - since we never went anywhere, this should be about:blank.
653 std::string url;
654 ASSERT_TRUE(events[0]->data()->GetString("url", &url));
655 ASSERT_EQ("about:blank", url);
657 #endif // !defined(OS_WIN)
659 // TODO(jam): http://crbug.com/350550
660 #if !(defined(OS_CHROMEOS) && defined(ADDRESS_SANITIZER))
661 IN_PROC_BROWSER_TEST_F(PerformanceMonitorBrowserTest, RendererCrashEvent) {
662 content::RenderProcessHostWatcher observer(
663 browser()->tab_strip_model()->GetActiveWebContents(),
664 content::RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);
666 ui_test_utils::NavigateToURL(browser(), GURL(content::kChromeUICrashURL));
668 observer.Wait();
670 Database::EventVector events = GetEvents();
671 ASSERT_EQ(1u, events.size());
673 CheckEventType(EVENT_RENDERER_CRASH, events[0]);
675 std::string url;
676 ASSERT_TRUE(events[0]->data()->GetString("url", &url));
677 ASSERT_EQ("chrome://crash/", url);
679 #endif
681 IN_PROC_BROWSER_TEST_P(PerformanceMonitorUncleanExitBrowserTest,
682 OneProfileUncleanExit) {
683 // Initialize the database value (if there's no value in the database, it
684 // can't determine the last active time of the profile, and doesn't insert
685 // the event).
686 const std::string time = "12985807272597591";
687 AddStateValue(kStateProfilePrefix + first_profile_name_, time);
689 performance_monitor()->CheckForUncleanExits();
690 content::RunAllPendingInMessageLoop();
692 Database::EventVector events = GetEvents();
694 const size_t kNumEvents = 1;
695 ASSERT_EQ(kNumEvents, events.size());
697 CheckEventType(EVENT_UNCLEAN_EXIT, events[0]);
699 std::string event_profile;
700 ASSERT_TRUE(events[0]->data()->GetString("profileName", &event_profile));
701 ASSERT_EQ(first_profile_name_, event_profile);
704 IN_PROC_BROWSER_TEST_P(PerformanceMonitorUncleanExitBrowserTest,
705 TwoProfileUncleanExit) {
706 #if defined(OS_CHROMEOS)
707 AddSecondUserAccount();
708 #endif
710 base::FilePath second_profile_path;
711 PathService::Get(chrome::DIR_USER_DATA, &second_profile_path);
712 second_profile_path = second_profile_path.AppendASCII(second_profile_name_);
714 const std::string time1 = "12985807272597591";
715 const std::string time2 = "12985807272599918";
717 // Initialize the database.
718 AddStateValue(kStateProfilePrefix + first_profile_name_, time1);
719 AddStateValue(kStateProfilePrefix + second_profile_name_, time2);
721 performance_monitor()->CheckForUncleanExits();
722 content::RunAllPendingInMessageLoop();
724 // Load the second profile, which has also exited uncleanly. Note that since
725 // the second profile is new, component extensions will be installed as part
726 // of the browser startup for that profile, generating extra events.
727 g_browser_process->profile_manager()->GetProfile(second_profile_path);
728 content::RunAllPendingInMessageLoop();
730 Database::EventVector events = GetEvents();
732 const size_t kNumUncleanExitEvents = 2;
733 size_t num_unclean_exit_events = 0;
734 for (size_t i = 0; i < events.size(); ++i) {
735 int event_type = -1;
736 if (events[i]->data()->GetInteger("eventType", &event_type) &&
737 event_type == EVENT_EXTENSION_INSTALL) {
738 continue;
740 CheckEventType(EVENT_UNCLEAN_EXIT, events[i]);
741 ++num_unclean_exit_events;
743 ASSERT_EQ(kNumUncleanExitEvents, num_unclean_exit_events);
745 std::string event_profile;
746 ASSERT_TRUE(events[0]->data()->GetString("profileName", &event_profile));
747 ASSERT_EQ(first_profile_name_, event_profile);
749 ASSERT_TRUE(events[1]->data()->GetString("profileName", &event_profile));
750 ASSERT_EQ(second_profile_name_, event_profile);
753 IN_PROC_BROWSER_TEST_F(PerformanceMonitorBrowserTest, StartupTime) {
754 Database::MetricVector metrics = GetStats(METRIC_TEST_STARTUP_TIME);
756 ASSERT_EQ(1u, metrics.size());
757 ASSERT_LT(metrics[0].value, kMaxStartupTime.ToInternalValue());
760 IN_PROC_BROWSER_TEST_F(PerformanceMonitorSessionRestoreBrowserTest,
761 StartupWithSessionRestore) {
762 ui_test_utils::NavigateToURL(
763 browser(), ui_test_utils::GetTestUrl(
764 base::FilePath(base::FilePath::kCurrentDirectory),
765 base::FilePath(FILE_PATH_LITERAL("title1.html"))));
767 QuitBrowserAndRestore(browser(), 1);
769 Database::MetricVector metrics = GetStats(METRIC_TEST_STARTUP_TIME);
770 ASSERT_EQ(1u, metrics.size());
771 ASSERT_LT(metrics[0].value, kMaxStartupTime.ToInternalValue());
773 metrics = GetStats(METRIC_SESSION_RESTORE_TIME);
774 ASSERT_EQ(1u, metrics.size());
775 ASSERT_LT(metrics[0].value, kMaxStartupTime.ToInternalValue());
778 IN_PROC_BROWSER_TEST_F(PerformanceMonitorBrowserTest, PageLoadTime) {
779 const base::TimeDelta kMaxLoadTime = base::TimeDelta::FromSeconds(30);
781 ui_test_utils::NavigateToURL(
782 browser(), ui_test_utils::GetTestUrl(
783 base::FilePath(base::FilePath::kCurrentDirectory),
784 base::FilePath(FILE_PATH_LITERAL("title1.html"))));
786 ui_test_utils::NavigateToURL(
787 browser(), ui_test_utils::GetTestUrl(
788 base::FilePath(base::FilePath::kCurrentDirectory),
789 base::FilePath(FILE_PATH_LITERAL("title1.html"))));
791 Database::MetricVector metrics = GetStats(METRIC_PAGE_LOAD_TIME);
793 ASSERT_EQ(2u, metrics.size());
794 ASSERT_LT(metrics[0].value, kMaxLoadTime.ToInternalValue());
795 ASSERT_LT(metrics[1].value, kMaxLoadTime.ToInternalValue());
798 IN_PROC_BROWSER_TEST_F(PerformanceMonitorBrowserTest, NetworkBytesRead) {
799 base::FilePath test_dir;
800 PathService::Get(chrome::DIR_TEST_DATA, &test_dir);
802 int64 page1_size = 0;
803 ASSERT_TRUE(base::GetFileSize(test_dir.AppendASCII("title1.html"),
804 &page1_size));
806 int64 page2_size = 0;
807 ASSERT_TRUE(base::GetFileSize(test_dir.AppendASCII("title2.html"),
808 &page2_size));
810 ASSERT_TRUE(test_server()->Start());
812 ui_test_utils::NavigateToURL(
813 browser(),
814 test_server()->GetURL(std::string("files/").append("title1.html")));
816 GatherStatistics();
818 Database::MetricVector metrics = GetStats(METRIC_NETWORK_BYTES_READ);
819 ASSERT_EQ(1u, metrics.size());
820 // Since these pages are read over the "network" (actually the test_server),
821 // some extraneous information is carried along, and the best check we can do
822 // is for greater than or equal to.
823 EXPECT_GE(metrics[0].value, page1_size);
825 ui_test_utils::NavigateToURL(
826 browser(),
827 test_server()->GetURL(std::string("files/").append("title2.html")));
829 GatherStatistics();
831 metrics = GetStats(METRIC_NETWORK_BYTES_READ);
832 ASSERT_EQ(2u, metrics.size());
833 EXPECT_GE(metrics[1].value, page1_size + page2_size);
836 INSTANTIATE_TEST_CASE_P(PerformanceMonitorUncleanExitBrowserTestInstantiation,
837 PerformanceMonitorUncleanExitBrowserTest,
838 testing::Bool());
840 } // namespace performance_monitor