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. 4 5#include "base/environment.h" 6#include "base/file_util.h" 7#include "base/path_service.h" 8#include "base/strings/string_number_conversions.h" 9#include "base/strings/stringprintf.h" 10#include "base/sys_info.h" 11#include "base/time/time.h" 12#include "chrome/common/chrome_constants.h" 13#include "chrome/common/chrome_paths.h" 14#include "chrome/common/env_vars.h" 15#include "chrome/test/automation/automation_proxy.h" 16#include "chrome/test/base/ui_test_utils.h" 17#include "chrome/test/perf/perf_test.h" 18#include "chrome/test/ui/ui_perf_test.h" 19#include "net/base/net_util.h" 20#include "testing/perf/perf_test.h" 21 22using base::TimeDelta; 23 24namespace { 25 26class ShutdownTest : public UIPerfTest { 27 public: 28 ShutdownTest() { 29 show_window_ = true; 30 } 31 virtual void SetUp() {} 32 virtual void TearDown() {} 33 34 enum TestSize { 35 SIMPLE, // Runs with no command line arguments (loads about:blank). 36 TWENTY_TABS, // Opens 5 copies of 4 different test pages. 37 }; 38 39 void SetUpTwentyTabs() { 40 int window_count; 41 ASSERT_TRUE(automation()->GetBrowserWindowCount(&window_count)); 42 ASSERT_EQ(1, window_count); 43 scoped_refptr<BrowserProxy> browser_proxy( 44 automation()->GetBrowserWindow(0)); 45 ASSERT_TRUE(browser_proxy.get()); 46 47 const base::FilePath kFastShutdownDir(FILE_PATH_LITERAL("fast_shutdown")); 48 const base::FilePath kCurrentDir(base::FilePath::kCurrentDirectory); 49 const base::FilePath test_cases[] = { 50 ui_test_utils::GetTestFilePath(kFastShutdownDir, 51 base::FilePath(FILE_PATH_LITERAL("on_before_unloader.html"))), 52 ui_test_utils::GetTestFilePath(kCurrentDir, 53 base::FilePath(FILE_PATH_LITERAL("animated-gifs.html"))), 54 ui_test_utils::GetTestFilePath(kCurrentDir, 55 base::FilePath(FILE_PATH_LITERAL("french_page.html"))), 56 ui_test_utils::GetTestFilePath(kCurrentDir, 57 base::FilePath(FILE_PATH_LITERAL("setcookie.html"))), 58 }; 59 60 for (size_t i = 0; i < arraysize(test_cases); i++) { 61 ASSERT_TRUE(base::PathExists(test_cases[i])); 62 for (size_t j = 0; j < 5; j++) { 63 ASSERT_TRUE(browser_proxy->AppendTab( 64 net::FilePathToFileURL(test_cases[i]))); 65 } 66 } 67 } 68 69 void RunShutdownTest(const char* graph, const char* trace, 70 bool important, TestSize test_size, 71 ProxyLauncher::ShutdownType shutdown_type) { 72#if defined(NDEBUG) 73 const int kNumCyclesMax = 20; 74#else 75 // Debug builds are too slow and we can't run that many cycles in a 76 // reasonable amount of time. 77 const int kNumCyclesMax = 10; 78#endif 79 int numCycles = kNumCyclesMax; 80 scoped_ptr<base::Environment> env(base::Environment::Create()); 81 std::string numCyclesEnv; 82 if (env->GetVar(env_vars::kStartupTestsNumCycles, &numCyclesEnv) && 83 base::StringToInt(numCyclesEnv, &numCycles)) { 84 if (numCycles <= kNumCyclesMax) { 85 VLOG(1) << env_vars::kStartupTestsNumCycles 86 << " set in environment, so setting numCycles to " << numCycles; 87 } else { 88 VLOG(1) << env_vars::kStartupTestsNumCycles 89 << " is higher than the max, setting numCycles to " 90 << kNumCyclesMax; 91 numCycles = kNumCyclesMax; 92 } 93 } 94 95 TimeDelta timings[kNumCyclesMax]; 96 for (int i = 0; i < numCycles; ++i) { 97 UITest::SetUp(); 98 if (test_size == TWENTY_TABS) { 99 SetUpTwentyTabs(); 100 } 101 set_shutdown_type(shutdown_type); 102 UITest::TearDown(); 103 timings[i] = browser_quit_time(); 104 105 if (i == 0) { 106 // Re-use the profile data after first run so that the noise from 107 // creating databases doesn't impact all the runs. 108 clear_profile_ = false; 109 // Clear template_user_data_ so we don't try to copy it over each time 110 // through. 111 set_template_user_data(base::FilePath()); 112 } 113 } 114 115 std::string times; 116 for (int i = 0; i < numCycles; ++i) 117 base::StringAppendF(×, "%.2f,", timings[i].InMillisecondsF()); 118 perf_test::PrintResultList( 119 graph, std::string(), trace, times, "ms", important); 120 } 121}; 122 123TEST_F(ShutdownTest, DISABLED_SimpleWindowClose) { 124 RunShutdownTest("shutdown", "simple-window-close", 125 true, /* important */ SIMPLE, ProxyLauncher::WINDOW_CLOSE); 126} 127 128TEST_F(ShutdownTest, SimpleUserQuit) { 129 RunShutdownTest("shutdown", "simple-user-quit", 130 true, /* important */ SIMPLE, ProxyLauncher::USER_QUIT); 131} 132 133TEST_F(ShutdownTest, SimpleSessionEnding) { 134 RunShutdownTest("shutdown", "simple-session-ending", 135 true, /* important */ SIMPLE, ProxyLauncher::SESSION_ENDING); 136} 137 138// http://crbug.com/110471 139#if defined(OS_WIN) && !defined(NDEBUG) 140#define MAYBE_TwentyTabsWindowClose DISABLED_TwentyTabsWindowClose 141#define MAYBE_TwentyTabsUserQuit DISABLED_TwentyTabsUserQuit 142#else 143#define MAYBE_TwentyTabsWindowClose TwentyTabsWindowClose 144#define MAYBE_TwentyTabsUserQuit TwentyTabsUserQuit 145#endif 146 147TEST_F(ShutdownTest, MAYBE_TwentyTabsWindowClose) { 148 RunShutdownTest("shutdown", "twentytabs-window-close", 149 true, /* important */ TWENTY_TABS, 150 ProxyLauncher::WINDOW_CLOSE); 151} 152 153TEST_F(ShutdownTest, MAYBE_TwentyTabsUserQuit) { 154 RunShutdownTest("shutdown", "twentytabs-user-quit", 155 true, /* important */ TWENTY_TABS, ProxyLauncher::USER_QUIT); 156} 157 158// http://crbug.com/40671 159#if defined(OS_WIN) && !defined(NDEBUG) 160#define MAYBE_TwentyTabsSessionEnding DISABLED_TwentyTabsSessionEnding 161#else 162#define MAYBE_TwentyTabsSessionEnding TwentyTabsSessionEnding 163#endif 164 165TEST_F(ShutdownTest, MAYBE_TwentyTabsSessionEnding) { 166 RunShutdownTest("shutdown", "twentytabs-session-ending", 167 true, /* important */ TWENTY_TABS, 168 ProxyLauncher::SESSION_ENDING); 169} 170 171} // namespace 172