diff options
author | nirnimesh@chromium.org <nirnimesh@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-01-08 02:04:59 +0000 |
---|---|---|
committer | nirnimesh@chromium.org <nirnimesh@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-01-08 02:04:59 +0000 |
commit | c405290f60432b22e8e862377b4f00e6177b4451 (patch) | |
tree | a710eb4876a4ea9013715ba90a27139d5da835bc /chrome | |
parent | 079443435c92b0294d63682c39a26df3391018c4 (diff) | |
download | chromium_src-c405290f60432b22e8e862377b4f00e6177b4451.zip chromium_src-c405290f60432b22e8e862377b4f00e6177b4451.tar.gz chromium_src-c405290f60432b22e8e862377b4f00e6177b4451.tar.bz2 |
Moves everything related to launching and terminating the browser from UITestBase into ProxyLauncher.
The primary changes are in ui_test.* and proxy_launcher.*. The changes in the remaining files are mostly just changing namespaces from UITestBase:: to ProxyLauncher::.
BUG=None.
TEST=All tests should pass. No functionality change.
Review URL: http://codereview.chromium.org/5967003
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@70827 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
25 files changed, 1016 insertions, 721 deletions
diff --git a/chrome/browser/dom_ui/new_tab_ui_uitest.cc b/chrome/browser/dom_ui/new_tab_ui_uitest.cc index 51d2b05..5b3bd0d 100644 --- a/chrome/browser/dom_ui/new_tab_ui_uitest.cc +++ b/chrome/browser/dom_ui/new_tab_ui_uitest.cc @@ -22,11 +22,11 @@ class NewTabUITest : public UITest { dom_automation_enabled_ = true; // Set home page to the empty string so that we can set the home page using // preferences. - homepage_ = ""; + set_homepage(""); // Setup the DEFAULT_THEME profile (has fake history entries). set_template_user_data(UITest::ComputeTypicalUserDataSource( - UITest::DEFAULT_THEME)); + ProxyLauncher::DEFAULT_THEME)); } }; diff --git a/chrome/browser/metrics/metrics_service_uitest.cc b/chrome/browser/metrics/metrics_service_uitest.cc index 77117f8..24ea726 100644 --- a/chrome/browser/metrics/metrics_service_uitest.cc +++ b/chrome/browser/metrics/metrics_service_uitest.cc @@ -73,7 +73,7 @@ TEST_F(MetricsServiceTest, CloseRenderersNormally) { TEST_F(MetricsServiceTest, CrashRenderers) { // This doesn't make sense to test in single process mode. - if (in_process_renderer_) + if (ProxyLauncher::in_process_renderer()) return; OpenTabs(); diff --git a/chrome/browser/renderer_host/resource_dispatcher_host_uitest.cc b/chrome/browser/renderer_host/resource_dispatcher_host_uitest.cc index 7732032..2b6c5a6 100644 --- a/chrome/browser/renderer_host/resource_dispatcher_host_uitest.cc +++ b/chrome/browser/renderer_host/resource_dispatcher_host_uitest.cc @@ -202,7 +202,7 @@ TEST_F(ResourceDispatcherTest, CrossSiteOnunloadCookie) { // strip the app on the build bots, this is bad times. TEST_F(ResourceDispatcherTest, CrossSiteAfterCrash) { // This test only works in multi-process mode - if (in_process_renderer()) + if (ProxyLauncher::in_process_renderer()) return; scoped_refptr<BrowserProxy> browser_proxy(automation()->GetBrowserWindow(0)); diff --git a/chrome/browser/sanity_uitest.cc b/chrome/browser/sanity_uitest.cc index cecbd71..cd02db2 100644 --- a/chrome/browser/sanity_uitest.cc +++ b/chrome/browser/sanity_uitest.cc @@ -17,7 +17,7 @@ class GoogleTest : public UITest { GoogleTest() : UITest() { FilePath test_file = test_data_directory_.AppendASCII("google").AppendASCII("google.html"); - homepage_ = GURL(net::FilePathToFileURL(test_file)).spec(); + set_homepage(GURL(net::FilePathToFileURL(test_file)).spec()); } }; @@ -34,7 +34,7 @@ class ColumnLayout : public UITest { protected: ColumnLayout() : UITest() { FilePath test_file = test_data_directory_.AppendASCII("columns.html"); - homepage_ = GURL(net::FilePathToFileURL(test_file)).spec(); + set_homepage(GURL(net::FilePathToFileURL(test_file)).spec()); } }; diff --git a/chrome/browser/session_history_uitest.cc b/chrome/browser/session_history_uitest.cc index 4889a81..1553b1d 100644 --- a/chrome/browser/session_history_uitest.cc +++ b/chrome/browser/session_history_uitest.cc @@ -156,7 +156,7 @@ TEST_F(SessionHistoryTest, MAYBE_FrameBackForward) { ASSERT_TRUE(test_server_.Start()); // about:blank should be loaded first. - GURL home(homepage_); + GURL home(homepage()); ASSERT_FALSE(tab_->GoBack()); EXPECT_EQ(L"", GetTabTitle()); EXPECT_EQ(home, GetTabURL()); diff --git a/chrome/browser/sessions/session_restore_uitest.cc b/chrome/browser/sessions/session_restore_uitest.cc index 051ecf7..5dcbb77 100644 --- a/chrome/browser/sessions/session_restore_uitest.cc +++ b/chrome/browser/sessions/session_restore_uitest.cc @@ -32,7 +32,7 @@ class SessionRestoreUITest : public UITest { virtual void QuitBrowserAndRestore(int expected_tab_count) { #if defined(OS_MACOSX) - shutdown_type_ = UITestBase::USER_QUIT; + shutdown_type_ = ProxyLauncher::USER_QUIT; #endif UITest::TearDown(); @@ -444,7 +444,7 @@ TEST_F(SessionRestoreUITest, TwoWindowsCloseOneRestoreOnlyOne) { // process.) // Flaky as per http://crbug.com/52022 TEST_F(SessionRestoreUITest, FLAKY_ShareProcessesOnRestore) { - if (in_process_renderer()) { + if (ProxyLauncher::in_process_renderer()) { // No point in running this test in single process mode. return; } diff --git a/chrome/browser/ui/tests/browser_uitest.cc b/chrome/browser/ui/tests/browser_uitest.cc index f3cfc78..680a86a 100644 --- a/chrome/browser/ui/tests/browser_uitest.cc +++ b/chrome/browser/ui/tests/browser_uitest.cc @@ -83,7 +83,7 @@ TEST_F(BrowserTest, PosixSessionEnd) { #ifdef CHROME_V8 TEST_F(BrowserTest, NullOpenerRedirectForksProcess) { // This test only works in multi-process mode - if (in_process_renderer()) + if (ProxyLauncher::in_process_renderer()) return; net::TestServer test_server(net::TestServer::TYPE_HTTP, @@ -134,7 +134,7 @@ TEST_F(BrowserTest, NullOpenerRedirectForksProcess) { // a same-page-redirect) will not fork a new process. TEST_F(BrowserTest, MAYBE_OtherRedirectsDontForkProcess) { // This test only works in multi-process mode - if (in_process_renderer()) + if (ProxyLauncher::in_process_renderer()) return; net::TestServer test_server(net::TestServer::TYPE_HTTP, diff --git a/chrome/common/logging_chrome_uitest.cc b/chrome/common/logging_chrome_uitest.cc index 96e3205..5d4236a 100644 --- a/chrome/common/logging_chrome_uitest.cc +++ b/chrome/common/logging_chrome_uitest.cc @@ -98,7 +98,7 @@ class AssertionTest : public UITest { #define Assertion DISABLED_Assertion #endif TEST_F(AssertionTest, Assertion) { - if (UITest::in_process_renderer()) { + if (ProxyLauncher::in_process_renderer()) { // in process mode doesn't do the crashing. expected_errors_ = 0; expected_crashes_ = 0; @@ -133,7 +133,7 @@ class CheckFalseTest : public UITest { #endif // Launch the app in assertion test mode, then close the app. TEST_F(CheckFalseTest, CheckFails) { - if (UITest::in_process_renderer()) { + if (ProxyLauncher::in_process_renderer()) { // in process mode doesn't do the crashing. expected_errors_ = 0; expected_crashes_ = 0; @@ -171,7 +171,7 @@ class RendererCrashTest : public UITest { #endif // Launch the app in renderer crash test mode, then close the app. TEST_F(RendererCrashTest, Crash) { - if (UITest::in_process_renderer()) { + if (ProxyLauncher::in_process_renderer()) { // in process mode doesn't do the crashing. expected_crashes_ = 0; } else { diff --git a/chrome/test/automation/automation_proxy_uitest.cc b/chrome/test/automation/automation_proxy_uitest.cc index 465b610..ab65c43 100644 --- a/chrome/test/automation/automation_proxy_uitest.cc +++ b/chrome/test/automation/automation_proxy_uitest.cc @@ -63,8 +63,9 @@ class ExternalTabUITestMockLauncher : public ProxyLauncher { return *mock_; } - void InitializeConnection(UITestBase* ui_test_base) const { - ui_test_base->LaunchBrowserAndServer(); + void InitializeConnection(const LaunchState& state, + bool wait_for_initial_loads) { + LaunchBrowserAndServer(state, wait_for_initial_loads); } std::string PrefixedChannelID() const { @@ -885,6 +886,10 @@ template <typename T> T** ReceivePointer(scoped_refptr<T>& p) { // NOLINT return reinterpret_cast<T**>(&p); } +ExternalTabUITest::ExternalTabUITest() : UITest(MessageLoop::TYPE_UI) { + launcher_.reset(CreateProxyLauncher()); +} + // Replace the default automation proxy with our mock client. ProxyLauncher* ExternalTabUITest::CreateProxyLauncher() { return new ExternalTabUITestMockLauncher(&mock_); diff --git a/chrome/test/automation/automation_proxy_uitest.h b/chrome/test/automation/automation_proxy_uitest.h index c08aa91..2ce19d4 100644 --- a/chrome/test/automation/automation_proxy_uitest.h +++ b/chrome/test/automation/automation_proxy_uitest.h @@ -109,7 +109,7 @@ class ExternalTabUITestMockClient : public AutomationProxy { // Base your external tab UI tests on this. class ExternalTabUITest : public UITest { public: - ExternalTabUITest() : UITest(MessageLoop::TYPE_UI) {} + ExternalTabUITest(); // Override UITest's CreateProxyLauncher to provide the unit test // with our special implementation of AutomationProxy. // This function is called from within UITest::SetUp(). diff --git a/chrome/test/automation/proxy_launcher.cc b/chrome/test/automation/proxy_launcher.cc index 1d1583c..d30f212 100644 --- a/chrome/test/automation/proxy_launcher.cc +++ b/chrome/test/automation/proxy_launcher.cc @@ -4,14 +4,482 @@ #include "chrome/test/automation/proxy_launcher.h" -#include "base/threading/platform_thread.h" +#include "app/sql/connection.h" +#include "base/file_util.h" +#include "base/string_number_conversions.h" +#include "base/string_split.h" +#include "base/string_util.h" +#include "base/stringprintf.h" +#include "base/test/test_file_util.h" +#include "base/test/test_timeouts.h" +#include "base/utf_string_conversions.h" +#include "chrome/app/chrome_command_ids.h" #include "chrome/common/automation_constants.h" +#include "chrome/common/child_process_info.h" +#include "chrome/common/chrome_constants.h" +#include "chrome/common/chrome_switches.h" +#include "chrome/common/debug_flags.h" #include "chrome/common/logging_chrome.h" +#include "chrome/common/url_constants.h" +#include "chrome/test/chrome_process_util.h" +#include "chrome/test/test_launcher_utils.h" +#include "chrome/test/test_switches.h" #include "chrome/test/automation/automation_proxy.h" #include "chrome/test/ui/ui_test.h" +namespace { + +// Passed as value of kTestType. +const char kUITestType[] = "ui"; + // Default path of named testing interface. -static const char kInterfacePath[] = "/var/tmp/ChromeTestingInterface"; +const char kInterfacePath[] = "/var/tmp/ChromeTestingInterface"; + +// Rewrite the preferences file to point to the proper image directory. +void RewritePreferencesFile(const FilePath& user_data_dir) { + const FilePath pref_template_path( + user_data_dir.AppendASCII("Default").AppendASCII("PreferencesTemplate")); + const FilePath pref_path( + user_data_dir.AppendASCII("Default").AppendASCII("Preferences")); + + // Read in preferences template. + std::string pref_string; + EXPECT_TRUE(file_util::ReadFileToString(pref_template_path, &pref_string)); + string16 format_string = ASCIIToUTF16(pref_string); + + // Make sure temp directory has the proper format for writing to prefs file. +#if defined(OS_POSIX) + std::wstring user_data_dir_w(ASCIIToWide(user_data_dir.value())); +#elif defined(OS_WIN) + std::wstring user_data_dir_w(user_data_dir.value()); + // In Windows, the FilePath will write '\' for the path separators; change + // these to a separator that won't trigger escapes. + std::replace(user_data_dir_w.begin(), + user_data_dir_w.end(), '\\', '/'); +#endif + + // Rewrite prefs file. + std::vector<string16> subst; + subst.push_back(WideToUTF16(user_data_dir_w)); + const std::string prefs_string = + UTF16ToASCII(ReplaceStringPlaceholders(format_string, subst, NULL)); + EXPECT_TRUE(file_util::WriteFile(pref_path, prefs_string.c_str(), + prefs_string.size())); + file_util::EvictFileFromSystemCache(pref_path); +} + +// We want to have a current history database when we start the browser so +// things like the NTP will have thumbnails. This method updates the dates +// in the history to be more recent. +void UpdateHistoryDates(const FilePath& user_data_dir) { + // Migrate the times in the segment_usage table to yesterday so we get + // actual thumbnails on the NTP. + sql::Connection db; + FilePath history = + user_data_dir.AppendASCII("Default").AppendASCII("History"); + // Not all test profiles have a history file. + if (!file_util::PathExists(history)) + return; + + ASSERT_TRUE(db.Open(history)); + base::Time yesterday = base::Time::Now() - base::TimeDelta::FromDays(1); + std::string yesterday_str = base::Int64ToString(yesterday.ToInternalValue()); + std::string query = StringPrintf( + "UPDATE segment_usage " + "SET time_slot = %s " + "WHERE id IN (SELECT id FROM segment_usage WHERE time_slot > 0);", + yesterday_str.c_str()); + ASSERT_TRUE(db.Execute(query.c_str())); + db.Close(); + file_util::EvictFileFromSystemCache(history); +} + +} // namespace + +// ProxyLauncher functions + +bool ProxyLauncher::in_process_renderer_ = false; +bool ProxyLauncher::no_sandbox_ = false; +bool ProxyLauncher::full_memory_dump_ = false; +bool ProxyLauncher::safe_plugins_ = false; +bool ProxyLauncher::show_error_dialogs_ = true; +bool ProxyLauncher::dump_histograms_on_exit_ = false; +bool ProxyLauncher::enable_dcheck_ = false; +bool ProxyLauncher::silent_dump_on_dcheck_ = false; +bool ProxyLauncher::disable_breakpad_ = false; +std::string ProxyLauncher::js_flags_ = ""; +std::string ProxyLauncher::log_level_ = ""; + +ProxyLauncher::ProxyLauncher() + : process_(base::kNullProcessHandle), + process_id_(-1) {} + +ProxyLauncher::~ProxyLauncher() {} + +void ProxyLauncher::WaitForBrowserLaunch(bool wait_for_initial_loads) { + ASSERT_EQ(AUTOMATION_SUCCESS, automation_proxy_->WaitForAppLaunch()) + << "Error while awaiting automation ping from browser process"; + if (wait_for_initial_loads) + ASSERT_TRUE(automation_proxy_->WaitForInitialLoads()); + else + base::PlatformThread::Sleep(TestTimeouts::action_timeout_ms()); + + EXPECT_TRUE(automation()->SetFilteredInet(ShouldFilterInet())); +} + +void ProxyLauncher::LaunchBrowserAndServer(const LaunchState& state, + bool wait_for_initial_loads) { + // Set up IPC testing interface as a server. + automation_proxy_.reset(CreateAutomationProxy( + TestTimeouts::command_execution_timeout_ms())); + + LaunchBrowser(state); + WaitForBrowserLaunch(wait_for_initial_loads); +} + +void ProxyLauncher::ConnectToRunningBrowser(bool wait_for_initial_loads) { + // Set up IPC testing interface as a client. + automation_proxy_.reset(CreateAutomationProxy( + TestTimeouts::command_execution_timeout_ms())); + WaitForBrowserLaunch(wait_for_initial_loads); +} + +void ProxyLauncher::CloseBrowserAndServer(ShutdownType shutdown_type) { + QuitBrowser(shutdown_type); + CleanupAppProcesses(); + + // Suppress spammy failures that seem to be occurring when running + // the UI tests in single-process mode. + // TODO(jhughes): figure out why this is necessary at all, and fix it + if (!in_process_renderer_) + AssertAppNotRunning( + StringPrintf(L"Unable to quit all browser processes. Original PID %d", + &process_id_)); + + automation_proxy_.reset(); // Shut down IPC testing interface. +} + +void ProxyLauncher::LaunchBrowser(const LaunchState& state) { + if (state.clear_profile || !temp_profile_dir_.IsValid()) { + temp_profile_dir_.Delete(); + ASSERT_TRUE(temp_profile_dir_.CreateUniqueTempDir()); + + ASSERT_TRUE(test_launcher_utils::OverrideUserDataDir(user_data_dir())); + } + + if (!state.template_user_data.empty()) { + // Recursively copy the template directory to the user_data_dir. + ASSERT_TRUE(file_util::CopyRecursiveDirNoCache( + state.template_user_data, + user_data_dir())); + // If we're using the complex theme data, we need to write the + // user_data_dir_ to our preferences file. + if (state.profile_type == COMPLEX_THEME) { + RewritePreferencesFile(user_data_dir()); + } + + // Update the history file to include recent dates. + UpdateHistoryDates(user_data_dir()); + } + + ASSERT_TRUE(LaunchBrowserHelper(state, false, &process_)); + process_id_ = base::GetProcId(process_); +} + +#if !defined(OS_MACOSX) +bool ProxyLauncher::LaunchAnotherBrowserBlockUntilClosed( + const LaunchState& state) { + return LaunchBrowserHelper(state, true, NULL); +} +#endif + +void ProxyLauncher::QuitBrowser(ShutdownType shutdown_type) { + if (SESSION_ENDING == shutdown_type) { + TerminateBrowser(); + return; + } + + // There's nothing to do here if the browser is not running. + // WARNING: There is a race condition here where the browser may shut down + // after this check but before some later automation call. Your test should + // use WaitForBrowserProcessToQuit() if it intentionally + // causes the browser to shut down. + if (IsBrowserRunning()) { + base::TimeTicks quit_start = base::TimeTicks::Now(); + EXPECT_TRUE(automation()->SetFilteredInet(false)); + + if (WINDOW_CLOSE == shutdown_type) { + int window_count = 0; + EXPECT_TRUE(automation()->GetBrowserWindowCount(&window_count)); + + // Synchronously close all but the last browser window. Closing them + // one-by-one may help with stability. + while (window_count > 1) { + scoped_refptr<BrowserProxy> browser_proxy = + automation()->GetBrowserWindow(0); + EXPECT_TRUE(browser_proxy.get()); + if (browser_proxy.get()) { + EXPECT_TRUE(browser_proxy->RunCommand(IDC_CLOSE_WINDOW)); + EXPECT_TRUE(automation()->GetBrowserWindowCount(&window_count)); + } else { + break; + } + } + + // Close the last window asynchronously, because the browser may + // shutdown faster than it will be able to send a synchronous response + // to our message. + scoped_refptr<BrowserProxy> browser_proxy = + automation()->GetBrowserWindow(0); + EXPECT_TRUE(browser_proxy.get()); + if (browser_proxy.get()) { + EXPECT_TRUE(browser_proxy->ApplyAccelerator(IDC_CLOSE_WINDOW)); + browser_proxy = NULL; + } + } else if (USER_QUIT == shutdown_type) { + scoped_refptr<BrowserProxy> browser_proxy = + automation()->GetBrowserWindow(0); + EXPECT_TRUE(browser_proxy.get()); + if (browser_proxy.get()) { + EXPECT_TRUE(browser_proxy->RunCommandAsync(IDC_EXIT)); + } + } else { + NOTREACHED() << "Invalid shutdown type " << shutdown_type; + } + + // Now, drop the automation IPC channel so that the automation provider in + // the browser notices and drops its reference to the browser process. + automation()->Disconnect(); + + // Wait for the browser process to quit. It should quit once all tabs have + // been closed. + if (!WaitForBrowserProcessToQuit( + TestTimeouts::wait_for_terminate_timeout_ms())) { + // We need to force the browser to quit because it didn't quit fast + // enough. Take no chance and kill every chrome processes. + CleanupAppProcesses(); + } + browser_quit_time_ = base::TimeTicks::Now() - quit_start; + } + + // Don't forget to close the handle + base::CloseProcessHandle(process_); + process_ = base::kNullProcessHandle; + process_id_ = -1; +} + +void ProxyLauncher::TerminateBrowser() { + if (IsBrowserRunning()) { + base::TimeTicks quit_start = base::TimeTicks::Now(); + EXPECT_TRUE(automation()->SetFilteredInet(false)); +#if defined(OS_WIN) + scoped_refptr<BrowserProxy> browser(automation()->GetBrowserWindow(0)); + ASSERT_TRUE(browser.get()); + ASSERT_TRUE(browser->TerminateSession()); +#endif // defined(OS_WIN) + + // Now, drop the automation IPC channel so that the automation provider in + // the browser notices and drops its reference to the browser process. + automation()->Disconnect(); + +#if defined(OS_POSIX) + EXPECT_EQ(kill(process_, SIGTERM), 0); +#endif // OS_POSIX + + if (!WaitForBrowserProcessToQuit( + TestTimeouts::wait_for_terminate_timeout_ms())) { + // We need to force the browser to quit because it didn't quit fast + // enough. Take no chance and kill every chrome processes. + CleanupAppProcesses(); + } + browser_quit_time_ = base::TimeTicks::Now() - quit_start; + } + + // Don't forget to close the handle + base::CloseProcessHandle(process_); + process_ = base::kNullProcessHandle; + process_id_ = -1; +} + +void ProxyLauncher::AssertAppNotRunning(const std::wstring& error_message) { + std::wstring final_error_message(error_message); + + ChromeProcessList processes = GetRunningChromeProcesses(process_id_); + if (!processes.empty()) { + final_error_message += L" Leftover PIDs: ["; + for (ChromeProcessList::const_iterator it = processes.begin(); + it != processes.end(); ++it) { + final_error_message += StringPrintf(L" %d", *it); + } + final_error_message += L" ]"; + } + ASSERT_TRUE(processes.empty()) << final_error_message; +} + +void ProxyLauncher::CleanupAppProcesses() { + TerminateAllChromeProcesses(process_id_); +} + +bool ProxyLauncher::WaitForBrowserProcessToQuit(int timeout) { +#ifdef WAIT_FOR_DEBUGGER_ON_OPEN + timeout = 500000; +#endif + return base::WaitForSingleProcess(process_, timeout); +} + +bool ProxyLauncher::IsBrowserRunning() { + return CrashAwareSleep(0); +} + +bool ProxyLauncher::CrashAwareSleep(int timeout_ms) { + return base::CrashAwareSleep(process_, timeout_ms); +} + +void ProxyLauncher::PrepareTestCommandline(CommandLine* command_line, + bool include_testing_id) { + // Propagate commandline settings from test_launcher_utils. + test_launcher_utils::PrepareBrowserCommandLineForTests(command_line); + + // Add any explicit command line flags passed to the process. + CommandLine::StringType extra_chrome_flags = + CommandLine::ForCurrentProcess()->GetSwitchValueNative( + switches::kExtraChromeFlags); + if (!extra_chrome_flags.empty()) { + // Split by spaces and append to command line + std::vector<CommandLine::StringType> flags; + base::SplitString(extra_chrome_flags, ' ', &flags); + for (size_t i = 0; i < flags.size(); ++i) + command_line->AppendArgNative(flags[i]); + } + + // No default browser check, it would create an info-bar (if we are not the + // default browser) that could conflicts with some tests expectations. + command_line->AppendSwitch(switches::kNoDefaultBrowserCheck); + + // This is a UI test. + command_line->AppendSwitchASCII(switches::kTestType, kUITestType); + + // Tell the browser to use a temporary directory just for this test. + command_line->AppendSwitchPath(switches::kUserDataDir, user_data_dir()); + + if (include_testing_id) + command_line->AppendSwitchASCII(switches::kTestingChannelID, + PrefixedChannelID()); + + if (!show_error_dialogs_ && + !CommandLine::ForCurrentProcess()->HasSwitch( + switches::kEnableErrorDialogs)) { + command_line->AppendSwitch(switches::kNoErrorDialogs); + } + if (in_process_renderer_) + command_line->AppendSwitch(switches::kSingleProcess); + if (no_sandbox_) + command_line->AppendSwitch(switches::kNoSandbox); + if (full_memory_dump_) + command_line->AppendSwitch(switches::kFullMemoryCrashReport); + if (safe_plugins_) + command_line->AppendSwitch(switches::kSafePlugins); + if (enable_dcheck_) + command_line->AppendSwitch(switches::kEnableDCHECK); + if (silent_dump_on_dcheck_) + command_line->AppendSwitch(switches::kSilentDumpOnDCHECK); + if (disable_breakpad_) + command_line->AppendSwitch(switches::kDisableBreakpad); + + if (!js_flags_.empty()) + command_line->AppendSwitchASCII(switches::kJavaScriptFlags, js_flags_); + if (!log_level_.empty()) + command_line->AppendSwitchASCII(switches::kLoggingLevel, log_level_); + + command_line->AppendSwitch(switches::kMetricsRecordingOnly); + + if (!CommandLine::ForCurrentProcess()->HasSwitch( + switches::kEnableErrorDialogs)) + command_line->AppendSwitch(switches::kEnableLogging); + + if (dump_histograms_on_exit_) + command_line->AppendSwitch(switches::kDumpHistogramsOnExit); + +#ifdef WAIT_FOR_DEBUGGER_ON_OPEN + command_line->AppendSwitch(switches::kDebugOnStart); +#endif + + // The tests assume that file:// URIs can freely access other file:// URIs. + command_line->AppendSwitch(switches::kAllowFileAccessFromFiles); + + // Disable TabCloseableStateWatcher for tests. + command_line->AppendSwitch(switches::kDisableTabCloseableStateWatcher); + + // Allow file:// access on ChromeOS. + command_line->AppendSwitch(switches::kAllowFileAccess); +} + +bool ProxyLauncher::LaunchBrowserHelper(const LaunchState& state, bool wait, + base::ProcessHandle* process) { + FilePath command = state.browser_directory.Append( + chrome::kBrowserProcessExecutablePath); + + CommandLine command_line(command); + + // Add command line arguments that should be applied to all UI tests. + PrepareTestCommandline(&command_line, state.include_testing_id); + DebugFlags::ProcessDebugFlags( + &command_line, ChildProcessInfo::UNKNOWN_PROCESS, false); + command_line.AppendArguments(state.arguments, false); + + // TODO(phajdan.jr): Only run it for "main" browser launch. + browser_launch_time_ = base::TimeTicks::Now(); + +#if defined(OS_WIN) + bool started = base::LaunchApp(command_line, wait, + !state.show_window, process); +#elif defined(OS_POSIX) + // Sometimes one needs to run the browser under a special environment + // (e.g. valgrind) without also running the test harness (e.g. python) + // under the special environment. Provide a way to wrap the browser + // commandline with a special prefix to invoke the special environment. + const char* browser_wrapper = getenv("BROWSER_WRAPPER"); + if (browser_wrapper) { + command_line.PrependWrapper(browser_wrapper); + VLOG(1) << "BROWSER_WRAPPER was set, prefixing command_line with " + << browser_wrapper; + } + + base::file_handle_mapping_vector fds; + if (automation_proxy_.get()) + fds = automation_proxy_->fds_to_map(); + + bool started = base::LaunchApp(command_line.argv(), fds, wait, process); +#endif + + return started; +} + +AutomationProxy* ProxyLauncher::automation() const { + EXPECT_TRUE(automation_proxy_.get()); + return automation_proxy_.get(); +} + +FilePath ProxyLauncher::user_data_dir() const { + EXPECT_TRUE(temp_profile_dir_.IsValid()); + return temp_profile_dir_.path(); +} + +base::ProcessHandle ProxyLauncher::process() const { + return process_; +} + +base::ProcessId ProxyLauncher::process_id() const { + return process_id_; +} + +base::TimeTicks ProxyLauncher::browser_launch_time() const { + return browser_launch_time_; +} + +base::TimeDelta ProxyLauncher::browser_quit_time() const { + return browser_quit_time_; +} // NamedProxyLauncher functions @@ -30,10 +498,11 @@ AutomationProxy* NamedProxyLauncher::CreateAutomationProxy( return proxy; } -void NamedProxyLauncher::InitializeConnection(UITestBase* ui_test_base) const { +void NamedProxyLauncher::InitializeConnection(const LaunchState& state, + bool wait_for_initial_loads) { if (launch_browser_) { // Set up IPC testing interface as a client. - ui_test_base->LaunchBrowser(); + LaunchBrowser(state); // Wait for browser to be ready for connections. struct stat file_info; @@ -41,7 +510,7 @@ void NamedProxyLauncher::InitializeConnection(UITestBase* ui_test_base) const { base::PlatformThread::Sleep(automation::kSleepTime); } - ui_test_base->ConnectToRunningBrowser(); + ConnectToRunningBrowser(wait_for_initial_loads); } std::string NamedProxyLauncher::PrefixedChannelID() const { @@ -65,12 +534,11 @@ AutomationProxy* AnonymousProxyLauncher::CreateAutomationProxy( return proxy; } -void AnonymousProxyLauncher::InitializeConnection( - UITestBase* ui_test_base) const { - ui_test_base->LaunchBrowserAndServer(); +void AnonymousProxyLauncher::InitializeConnection(const LaunchState& state, + bool wait_for_initial_loads) { + LaunchBrowserAndServer(state, wait_for_initial_loads); } std::string AnonymousProxyLauncher::PrefixedChannelID() const { return channel_id_; } - diff --git a/chrome/test/automation/proxy_launcher.h b/chrome/test/automation/proxy_launcher.h index 0f4d04d..497d376 100644 --- a/chrome/test/automation/proxy_launcher.h +++ b/chrome/test/automation/proxy_launcher.h @@ -8,30 +8,284 @@ #include <string> #include "base/basictypes.h" +#include "base/command_line.h" +#include "base/process.h" +#include "base/scoped_ptr.h" +#include "base/scoped_temp_dir.h" +#include "base/time.h" class AutomationProxy; -class UITestBase; -// Subclass from this class to use a different implementation of AutomationProxy -// or to use different channel IDs inside a class that derives from UITest. +// Base class for all ProxyLauncher implementations. Contains functionality +// fo launching, terminating, and connecting tests to browser processes. This +// class determines which AutomationProxy implementation is used by a test. +// Command line arguments passed to the browser are set in this class. +// +// Subclass from this class to use a different AutomationProxy +// implementation or to override browser launching behavior. class ProxyLauncher { public: - ProxyLauncher() {} - virtual ~ProxyLauncher() {} + // Profile theme type choices. + enum ProfileType { + DEFAULT_THEME = 0, + COMPLEX_THEME = 1, + NATIVE_THEME = 2, + CUSTOM_FRAME = 3, + CUSTOM_FRAME_NATIVE_THEME = 4, + }; + + // Different ways to quit the browser. + enum ShutdownType { + WINDOW_CLOSE, + USER_QUIT, + SESSION_ENDING, + }; + + // POD containing state variables that determine how to launch browser. + typedef struct { + // If true the profile is cleared before launching. + bool clear_profile; + + // If set, the profiles in this path are copied + // into the user data directory for the test. + FilePath& template_user_data; + + // Profile theme type. + ProfileType profile_type; + + // Path to the browser executable. + FilePath browser_directory; + + // Command line arguments passed to the browser. + CommandLine& arguments; + + // Should we supply the testing channel id on the command line? + bool include_testing_id; + + // If true, the window is shown. Otherwise it is hidden. + bool show_window; + } LaunchState; + + ProxyLauncher(); + + virtual ~ProxyLauncher(); // Creates an automation proxy. virtual AutomationProxy* CreateAutomationProxy( int execution_timeout) = 0; - // Launches the browser if needed and establishes a connection - // connection with it using the specified UITestBase. - virtual void InitializeConnection(UITestBase* ui_test_base) const = 0; + // Launches the browser if needed and establishes a connection with it. + virtual void InitializeConnection(const LaunchState& state, + bool wait_for_initial_loads) = 0; // Returns the automation proxy's channel with any prefixes prepended, // for passing as a command line parameter over to the browser. virtual std::string PrefixedChannelID() const = 0; + // Launches the browser and IPC testing connection in server mode. + void LaunchBrowserAndServer(const LaunchState& state, + bool wait_for_initial_loads); + + // Launches the IPC testing connection in client mode, + // which then attempts to connect to a browser. + void ConnectToRunningBrowser(bool wait_for_initial_loads); + + // Only for pyauto. + void set_command_execution_timeout_ms(int timeout); + + // Closes the browser and IPC testing server. + void CloseBrowserAndServer(ShutdownType shutdown_type); + + // Launches the browser with the given command line. + // TODO(phajdan.jr): Make LaunchBrowser private. Tests should use + // LaunchAnotherBrowserBlockUntilClosed. + void LaunchBrowser(const LaunchState& state); + +#if !defined(OS_MACOSX) + // This function is not defined on the Mac because the concept + // doesn't apply to Mac; you can't have N browser processes. + + // Launches another browser process and waits for it to finish. + // Returns true on success. + bool LaunchAnotherBrowserBlockUntilClosed(const LaunchState& state); +#endif + + // Exits out of browser instance. + void QuitBrowser(ShutdownType shutdown_type); + + // Terminates the browser, simulates end of session. + void TerminateBrowser(); + + // Check that no processes related to Chrome exist, displaying + // the given message if any do. + void AssertAppNotRunning(const std::wstring& error_message); + + // Returns true when the browser process is running, independent if any + // renderer process exists or not. It will returns false if an user closed the + // window or if the browser process died by itself. + bool IsBrowserRunning(); + + // Returns true when timeout_ms milliseconds have elapsed. + // Returns false if the browser process died while waiting. + bool CrashAwareSleep(int timeout_ms); + + // Wait for the browser process to shut down on its own (i.e. as a result of + // some action that your test has taken). + bool WaitForBrowserProcessToQuit(int timeout); + + AutomationProxy* automation() const; + + // Return the user data directory being used by the browser instance. + FilePath user_data_dir() const; + + // Get the handle of browser process connected to the automation. This + // function only returns a reference to the handle so the caller does not + // own the handle returned. + base::ProcessHandle process() const; + + // Return the process id of the browser process (-1 on error). + base::ProcessId process_id() const; + + // Return the time when the browser was run. + base::TimeTicks browser_launch_time() const; + + // Return how long the shutdown took. + base::TimeDelta browser_quit_time() const; + + // Get/Set a flag to run the renderer in-process when running the tests. + static bool in_process_renderer() { return in_process_renderer_; } + static void set_in_process_renderer(bool value) { + in_process_renderer_ = value; + } + + // Get/Set a flag to run the renderer outside the sandbox when running tests. + static bool no_sandbox() { return no_sandbox_; } + static void set_no_sandbox(bool value) { + no_sandbox_ = value; + } + + // Get/Set a flag to run with DCHECKs enabled in release. + static bool enable_dcheck() { return enable_dcheck_; } + static void set_enable_dcheck(bool value) { + enable_dcheck_ = value; + } + + // Get/Set a flag to dump the process memory without crashing on DCHECKs. + static bool silent_dump_on_dcheck() { return silent_dump_on_dcheck_; } + static void set_silent_dump_on_dcheck(bool value) { + silent_dump_on_dcheck_ = value; + } + + // Get/Set a flag to disable breakpad handling. + static bool disable_breakpad() { return disable_breakpad_; } + static void set_disable_breakpad(bool value) { + disable_breakpad_ = value; + } + + // Get/Set a flag to run the plugin processes inside the sandbox when running + // the tests + static bool safe_plugins() { return safe_plugins_; } + static void set_safe_plugins(bool value) { + safe_plugins_ = value; + } + + static bool show_error_dialogs() { return show_error_dialogs_; } + static void set_show_error_dialogs(bool value) { + show_error_dialogs_ = value; + } + + static bool full_memory_dump() { return full_memory_dump_; } + static void set_full_memory_dump(bool value) { + full_memory_dump_ = value; + } + + static bool dump_histograms_on_exit() { return dump_histograms_on_exit_; } + static void set_dump_histograms_on_exit(bool value) { + dump_histograms_on_exit_ = value; + } + + static const std::string& js_flags() { return js_flags_; } + static void set_js_flags(const std::string& value) { + js_flags_ = value; + } + + static const std::string& log_level() { return log_level_; } + static void set_log_level(const std::string& value) { + log_level_ = value; + } + + protected: + virtual bool ShouldFilterInet() { + return true; + } + private: + void WaitForBrowserLaunch(bool wait_for_initial_loads); + + // Prepare command line that will be used to launch the child browser process. + void PrepareTestCommandline(CommandLine* command_line, + bool include_testing_id); + + bool LaunchBrowserHelper(const LaunchState& state, bool wait, + base::ProcessHandle* process); + + // Wait a certain amount of time for all the app processes to exit, + // forcibly killing them if they haven't exited by then. + // It has the side-effect of killing every browser window opened in your + // session, even those unrelated in the test. + void CleanupAppProcesses(); + + scoped_ptr<AutomationProxy> automation_proxy_; + + // We use a temporary directory for profile to avoid issues with being + // unable to delete some files because they're in use, etc. + ScopedTempDir temp_profile_dir_; + + // Handle to the first Chrome process. + base::ProcessHandle process_; + + // PID of |process_| (for debugging). + base::ProcessId process_id_; + + // Time when the browser was run. + base::TimeTicks browser_launch_time_; + + // How long the shutdown took. + base::TimeDelta browser_quit_time_; + + // True if we're in single process mode. + static bool in_process_renderer_; + + // If true, runs the renderer outside the sandbox. + static bool no_sandbox_; + + // If true, runs plugin processes inside the sandbox. + static bool safe_plugins_; + + // If true, write full memory dump during crash. + static bool full_memory_dump_; + + // If true, a user is paying attention to the test, so show error dialogs. + static bool show_error_dialogs_; + + // Include histograms in log on exit. + static bool dump_histograms_on_exit_; + + // Enable dchecks in release mode. + static bool enable_dcheck_; + + // Dump process memory on dcheck without crashing. + static bool silent_dump_on_dcheck_; + + // Disable breakpad on the browser. + static bool disable_breakpad_; + + // Flags passed to the JS engine. + static std::string js_flags_; + + // Logging level. + static std::string log_level_; + DISALLOW_COPY_AND_ASSIGN(ProxyLauncher); }; @@ -46,7 +300,8 @@ class NamedProxyLauncher : public ProxyLauncher { NamedProxyLauncher(bool launch_browser, bool disconnect_on_failure); virtual AutomationProxy* CreateAutomationProxy(int execution_timeout); - virtual void InitializeConnection(UITestBase* ui_test_base) const; + virtual void InitializeConnection(const LaunchState& state, + bool wait_for_initial_loads); virtual std::string PrefixedChannelID() const; protected: @@ -63,7 +318,8 @@ class AnonymousProxyLauncher : public ProxyLauncher { public: explicit AnonymousProxyLauncher(bool disconnect_on_failure); virtual AutomationProxy* CreateAutomationProxy(int execution_timeout); - virtual void InitializeConnection(UITestBase* ui_test_base) const; + virtual void InitializeConnection(const LaunchState& state, + bool wait_for_initial_loads); virtual std::string PrefixedChannelID() const; protected: @@ -75,4 +331,3 @@ class AnonymousProxyLauncher : public ProxyLauncher { }; #endif // CHROME_TEST_AUTOMATION_PROXY_LAUNCHER_H_ - diff --git a/chrome/test/interactive_ui/fast_shutdown_interactive_uitest.cc b/chrome/test/interactive_ui/fast_shutdown_interactive_uitest.cc index 550f8d4..fb617a5 100644 --- a/chrome/test/interactive_ui/fast_shutdown_interactive_uitest.cc +++ b/chrome/test/interactive_ui/fast_shutdown_interactive_uitest.cc @@ -54,5 +54,6 @@ TEST_F(FastShutdown, MAYBE_SlowTermination) { ASSERT_TRUE(automation()->WaitForAppModalDialog()); ASSERT_TRUE(automation()->ClickAppModalDialogButton( MessageBoxFlags::DIALOGBUTTON_OK)); - ASSERT_TRUE(WaitForBrowserProcessToQuit()); + ASSERT_TRUE(WaitForBrowserProcessToQuit( + TestTimeouts::wait_for_terminate_timeout_ms())); } diff --git a/chrome/test/interactive_ui/npapi_interactive_test.cc b/chrome/test/interactive_ui/npapi_interactive_test.cc index c6e40b2..c5a7884 100644 --- a/chrome/test/interactive_ui/npapi_interactive_test.cc +++ b/chrome/test/interactive_ui/npapi_interactive_test.cc @@ -45,7 +45,7 @@ static const FilePath::CharType* kTestDir = FILE_PATH_LITERAL("npapi"); // Tests if a plugin executing a self deleting script in the context of // a synchronous mousemove works correctly TEST_F(NPAPIVisiblePluginTester, SelfDeletePluginInvokeInSynchronousMouseMove) { - if (UITest::in_process_renderer()) + if (ProxyLauncher::in_process_renderer()) return; show_window_ = true; @@ -67,7 +67,7 @@ TEST_F(NPAPIVisiblePluginTester, SelfDeletePluginInvokeInSynchronousMouseMove) { // Flaky, http://crbug.com/60071. TEST_F(NPAPIVisiblePluginTester, FLAKY_GetURLRequest404Response) { - if (UITest::in_process_renderer()) + if (ProxyLauncher::in_process_renderer()) return; GURL url(URLRequestMockHTTPJob::GetMockUrl( diff --git a/chrome/test/reliability/page_load_test.cc b/chrome/test/reliability/page_load_test.cc index 2aeb0a7a..a799c1d 100644 --- a/chrome/test/reliability/page_load_test.cc +++ b/chrome/test/reliability/page_load_test.cc @@ -331,7 +331,7 @@ class PageLoadTest : public UITest { // Also don't run if running as a standalone program which is for // distributed testing, to avoid mistakenly hitting web sites with many // instances. - if (in_process_renderer() || g_stand_alone) + if (ProxyLauncher::in_process_renderer() || g_stand_alone) return; // For usage 1 NavigationMetrics metrics; diff --git a/chrome/test/startup/feature_startup_test.cc b/chrome/test/startup/feature_startup_test.cc index a9480eb..7468a77 100644 --- a/chrome/test/startup/feature_startup_test.cc +++ b/chrome/test/startup/feature_startup_test.cc @@ -39,7 +39,7 @@ class NewTabUIStartupTest : public UIPerfTest { PrintResultList("new_tab", "", label, times, "ms", important); } - void InitProfile(UITest::ProfileType profile_type) { + void InitProfile(ProxyLauncher::ProfileType profile_type) { profile_type_ = profile_type; // Install the location of the test profile file. @@ -55,7 +55,7 @@ class NewTabUIStartupTest : public UIPerfTest { // |want_warm| is true if we should output warm-disk timings, false if // we should report cold timings. void RunStartupTest(const char* label, bool want_warm, bool important, - UITest::ProfileType profile_type) { + ProxyLauncher::ProfileType profile_type) { InitProfile(profile_type); TimeDelta timings[kNumCycles]; @@ -103,7 +103,7 @@ class NewTabUIStartupTest : public UIPerfTest { } void RunNewTabTimingTest() { - InitProfile(UITest::DEFAULT_THEME); + InitProfile(ProxyLauncher::DEFAULT_THEME); TimeDelta scriptstart_times[kNumCycles]; TimeDelta domcontentloaded_times[kNumCycles]; @@ -163,29 +163,29 @@ class NewTabUIStartupTest : public UIPerfTest { TEST_F(NewTabUIStartupTest, PerfRefCold) { UseReferenceBuild(); RunStartupTest("tab_cold_ref", false /* cold */, true /* important */, - UITest::DEFAULT_THEME); + ProxyLauncher::DEFAULT_THEME); } TEST_F(NewTabUIStartupTest, PerfCold) { RunStartupTest("tab_cold", false /* cold */, true /* important */, - UITest::DEFAULT_THEME); + ProxyLauncher::DEFAULT_THEME); } TEST_F(NewTabUIStartupTest, PerfRefWarm) { UseReferenceBuild(); RunStartupTest("tab_warm_ref", true /* warm */, true /* not important */, - UITest::DEFAULT_THEME); + ProxyLauncher::DEFAULT_THEME); } TEST_F(NewTabUIStartupTest, PerfWarm) { RunStartupTest("tab_warm", true /* warm */, true /* not important */, - UITest::DEFAULT_THEME); + ProxyLauncher::DEFAULT_THEME); } TEST_F(NewTabUIStartupTest, ComplexThemeCold) { RunStartupTest("tab_complex_theme_cold", false /* cold */, false /* not important */, - UITest::COMPLEX_THEME); + ProxyLauncher::COMPLEX_THEME); } TEST_F(NewTabUIStartupTest, NewTabTimingTestsCold) { @@ -196,19 +196,19 @@ TEST_F(NewTabUIStartupTest, NewTabTimingTestsCold) { TEST_F(NewTabUIStartupTest, GtkThemeCold) { RunStartupTest("tab_gtk_theme_cold", false /* cold */, false /* not important */, - UITest::NATIVE_THEME); + ProxyLauncher::NATIVE_THEME); } TEST_F(NewTabUIStartupTest, NativeFrameCold) { RunStartupTest("tab_custom_frame_cold", false /* cold */, false /* not important */, - UITest::CUSTOM_FRAME); + ProxyLauncher::CUSTOM_FRAME); } TEST_F(NewTabUIStartupTest, NativeFrameGtkThemeCold) { RunStartupTest("tab_custom_frame_gtk_theme_cold", false /* cold */, false /* not important */, - UITest::CUSTOM_FRAME_NATIVE_THEME); + ProxyLauncher::CUSTOM_FRAME_NATIVE_THEME); } #endif diff --git a/chrome/test/startup/shutdown_test.cc b/chrome/test/startup/shutdown_test.cc index a0d64e1..19033cb 100644 --- a/chrome/test/startup/shutdown_test.cc +++ b/chrome/test/startup/shutdown_test.cc @@ -66,7 +66,7 @@ class ShutdownTest : public UIPerfTest { void RunShutdownTest(const char* graph, const char* trace, bool important, TestSize test_size, - UITest::ShutdownType shutdown_type) { + ProxyLauncher::ShutdownType shutdown_type) { const int kNumCyclesMax = 20; int numCycles = kNumCyclesMax; scoped_ptr<base::Environment> env(base::Environment::Create()); @@ -92,7 +92,7 @@ class ShutdownTest : public UIPerfTest { } set_shutdown_type(shutdown_type); UITest::TearDown(); - timings[i] = browser_quit_time_; + timings[i] = browser_quit_time(); if (i == 0) { // Re-use the profile data after first run so that the noise from @@ -113,27 +113,28 @@ class ShutdownTest : public UIPerfTest { TEST_F(ShutdownTest, SimpleWindowClose) { RunShutdownTest("shutdown", "simple-window-close", - true, /* important */ SIMPLE, UITest::WINDOW_CLOSE); + true, /* important */ SIMPLE, ProxyLauncher::WINDOW_CLOSE); } TEST_F(ShutdownTest, SimpleUserQuit) { RunShutdownTest("shutdown", "simple-user-quit", - true, /* important */ SIMPLE, UITest::USER_QUIT); + true, /* important */ SIMPLE, ProxyLauncher::USER_QUIT); } TEST_F(ShutdownTest, SimpleSessionEnding) { RunShutdownTest("shutdown", "simple-session-ending", - true, /* important */ SIMPLE, UITest::SESSION_ENDING); + true, /* important */ SIMPLE, ProxyLauncher::SESSION_ENDING); } TEST_F(ShutdownTest, TwentyTabsWindowClose) { RunShutdownTest("shutdown", "twentytabs-window-close", - true, /* important */ TWENTY_TABS, UITest::WINDOW_CLOSE); + true, /* important */ TWENTY_TABS, + ProxyLauncher::WINDOW_CLOSE); } TEST_F(ShutdownTest, TwentyTabsUserQuit) { RunShutdownTest("shutdown", "twentytabs-user-quit", - true, /* important */ TWENTY_TABS, UITest::USER_QUIT); + true, /* important */ TWENTY_TABS, ProxyLauncher::USER_QUIT); } // http://crbug.com/40671 @@ -145,7 +146,8 @@ TEST_F(ShutdownTest, TwentyTabsUserQuit) { TEST_F(ShutdownTest, MAYBE_TwentyTabsSessionEnding) { RunShutdownTest("shutdown", "twentytabs-session-ending", - true, /* important */ TWENTY_TABS, UITest::SESSION_ENDING); + true, /* important */ TWENTY_TABS, + ProxyLauncher::SESSION_ENDING); } } // namespace diff --git a/chrome/test/startup/startup_test.cc b/chrome/test/startup/startup_test.cc index 1604f86..437a844 100644 --- a/chrome/test/startup/startup_test.cc +++ b/chrome/test/startup/startup_test.cc @@ -90,14 +90,14 @@ class StartupTest : public UIPerfTest { void RunStartupTest(const char* graph, const char* trace, TestColdness test_cold, TestImportance test_importance, - UITest::ProfileType profile_type, + ProxyLauncher::ProfileType profile_type, int num_tabs, int nth_timed_tab) { bool important = (test_importance == IMPORTANT); profile_type_ = profile_type; // Sets the profile data for the run. For now, this is only used for // the non-default themes test. - if (profile_type != UITest::DEFAULT_THEME) { + if (profile_type != ProxyLauncher::DEFAULT_THEME) { set_template_user_data(UITest::ComputeTypicalUserDataSource( profile_type)); } @@ -187,7 +187,7 @@ class StartupTest : public UIPerfTest { num_tabs = 0; } } - timings[i].end_to_end = end_time - browser_launch_time_; + timings[i].end_to_end = end_time - browser_launch_time(); UITest::TearDown(); if (i == 0) { @@ -246,18 +246,21 @@ class StartupTest : public UIPerfTest { }; TEST_F(StartupTest, PerfWarm) { - RunStartupTest("warm", "t", WARM, IMPORTANT, UITest::DEFAULT_THEME, 0, 0); + RunStartupTest("warm", "t", WARM, IMPORTANT, + ProxyLauncher::DEFAULT_THEME, 0, 0); } TEST_F(StartupTest, PerfReferenceWarm) { UseReferenceBuild(); - RunStartupTest("warm", "t_ref", WARM, IMPORTANT, UITest::DEFAULT_THEME, 0, 0); + RunStartupTest("warm", "t_ref", WARM, IMPORTANT, + ProxyLauncher::DEFAULT_THEME, 0, 0); } // TODO(mpcomplete): Should we have reference timings for all these? TEST_F(StartupTest, PerfCold) { - RunStartupTest("cold", "t", COLD, NOT_IMPORTANT, UITest::DEFAULT_THEME, 0, 0); + RunStartupTest("cold", "t", COLD, NOT_IMPORTANT, + ProxyLauncher::DEFAULT_THEME, 0, 0); } void StartupTest::RunPerfTestWithManyTabs(const char* graph, const char* trace, @@ -272,7 +275,7 @@ void StartupTest::RunPerfTestWithManyTabs(const char* graph, const char* trace, UITest::SetUp(); // Set flags to ensure profile is saved and can be restored. #if defined(OS_MACOSX) - shutdown_type_ = UITestBase::USER_QUIT; + shutdown_type_ = ProxyLauncher::USER_QUIT; #endif clear_profile_ = false; // Quit and set flags to restore session. @@ -286,8 +289,8 @@ void StartupTest::RunPerfTestWithManyTabs(const char* graph, const char* trace, launch_arguments_.AppendSwitchASCII(switches::kRestoreLastSession, base::IntToString(tab_count)); } - RunStartupTest(graph, trace, WARM, NOT_IMPORTANT, UITest::DEFAULT_THEME, - tab_count, nth_timed_tab); + RunStartupTest(graph, trace, WARM, NOT_IMPORTANT, + ProxyLauncher::DEFAULT_THEME, tab_count, nth_timed_tab); } TEST_F(StartupTest, PerfFewTabs) { @@ -350,21 +353,21 @@ TEST_F(StartupTest, PerfExtensionEmpty) { SetUpWithFileURL(); SetUpWithExtensionsProfile("empty"); RunStartupTest("warm", "extension_empty", WARM, NOT_IMPORTANT, - UITest::DEFAULT_THEME, 1, 0); + ProxyLauncher::DEFAULT_THEME, 1, 0); } TEST_F(StartupTest, PerfExtensionContentScript1) { SetUpWithFileURL(); SetUpWithExtensionsProfile("content_scripts1"); RunStartupTest("warm", "extension_content_scripts1", WARM, NOT_IMPORTANT, - UITest::DEFAULT_THEME, 1, 0); + ProxyLauncher::DEFAULT_THEME, 1, 0); } TEST_F(StartupTest, MAYBE_PerfExtensionContentScript50) { SetUpWithFileURL(); SetUpWithExtensionsProfile("content_scripts50"); RunStartupTest("warm", "extension_content_scripts50", WARM, NOT_IMPORTANT, - UITest::DEFAULT_THEME, 1, 0); + ProxyLauncher::DEFAULT_THEME, 1, 0); } #if defined(OS_WIN) @@ -372,35 +375,35 @@ TEST_F(StartupTest, MAYBE_PerfExtensionContentScript50) { TEST_F(StartupTest, PerfGears) { SetUpWithFileURL(); RunStartupTest("warm", "gears", WARM, NOT_IMPORTANT, - UITest::DEFAULT_THEME, 1, 0); + ProxyLauncher::DEFAULT_THEME, 1, 0); } TEST_F(StartupTest, PerfColdGears) { SetUpWithFileURL(); RunStartupTest("cold", "gears", COLD, NOT_IMPORTANT, - UITest::DEFAULT_THEME, 1, 0); + ProxyLauncher::DEFAULT_THEME, 1, 0); } #endif TEST_F(StartupTest, PerfComplexTheme) { RunStartupTest("warm", "t-theme", WARM, NOT_IMPORTANT, - UITest::COMPLEX_THEME, 0, 0); + ProxyLauncher::COMPLEX_THEME, 0, 0); } #if defined(OS_LINUX) TEST_F(StartupTest, PerfGtkTheme) { RunStartupTest("warm", "gtk-theme", WARM, NOT_IMPORTANT, - UITest::NATIVE_THEME, 0, 0); + ProxyLauncher::NATIVE_THEME, 0, 0); } TEST_F(StartupTest, PrefNativeFrame) { RunStartupTest("warm", "custom-frame", WARM, NOT_IMPORTANT, - UITest::CUSTOM_FRAME, 0, 0); + ProxyLauncher::CUSTOM_FRAME, 0, 0); } TEST_F(StartupTest, PerfNativeFrameGtkTheme) { RunStartupTest("warm", "custom-frame-gtk-theme", WARM, NOT_IMPORTANT, - UITest::CUSTOM_FRAME_NATIVE_THEME, 0, 0); + ProxyLauncher::CUSTOM_FRAME_NATIVE_THEME, 0, 0); } #endif diff --git a/chrome/test/ui/layout_plugin_uitest.cc b/chrome/test/ui/layout_plugin_uitest.cc index e309937..07fab43 100644 --- a/chrome/test/ui/layout_plugin_uitest.cc +++ b/chrome/test/ui/layout_plugin_uitest.cc @@ -68,7 +68,7 @@ TEST_F(LayoutPluginTester, FLAKY_SelfDeletePluginInvoke) { } TEST_F(LayoutPluginTester, NPObjectReleasedOnDestruction) { - if (UITest::in_process_renderer()) + if (ProxyLauncher::in_process_renderer()) return; const FilePath test_case( diff --git a/chrome/test/ui/npapi_uitest.cc b/chrome/test/ui/npapi_uitest.cc index 77a80b2..f522e16 100644 --- a/chrome/test/ui/npapi_uitest.cc +++ b/chrome/test/ui/npapi_uitest.cc @@ -113,7 +113,7 @@ TEST_F(NPAPITesterBase, NPObjectProxy) { // http://crbug.com/44960 TEST_F(NPAPIVisiblePluginTester, FLAKY_SelfDeletePluginInvokeInSynchronousPaint) { - if (UITest::in_process_renderer()) + if (ProxyLauncher::in_process_renderer()) return; show_window_ = true; @@ -128,7 +128,7 @@ TEST_F(NPAPIVisiblePluginTester, #endif TEST_F(NPAPIVisiblePluginTester, SelfDeletePluginInNewStream) { - if (UITest::in_process_renderer()) + if (ProxyLauncher::in_process_renderer()) return; show_window_ = true; @@ -190,7 +190,7 @@ TEST_F(NPAPIVisiblePluginTester, AlertInWindowMessage) { } TEST_F(NPAPIVisiblePluginTester, VerifyNPObjectLifetimeTest) { - if (UITest::in_process_renderer()) + if (ProxyLauncher::in_process_renderer()) return; show_window_ = true; @@ -212,7 +212,7 @@ TEST_F(NPAPIVisiblePluginTester, NewFails) { } TEST_F(NPAPIVisiblePluginTester, SelfDeletePluginInNPNEvaluate) { - if (UITest::in_process_renderer()) + if (ProxyLauncher::in_process_renderer()) return; const FilePath test_case( @@ -225,7 +225,7 @@ TEST_F(NPAPIVisiblePluginTester, SelfDeletePluginInNPNEvaluate) { } TEST_F(NPAPIVisiblePluginTester, SelfDeleteCreatePluginInNPNEvaluate) { - if (UITest::in_process_renderer()) + if (ProxyLauncher::in_process_renderer()) return; const FilePath test_case( @@ -243,7 +243,7 @@ TEST_F(NPAPIVisiblePluginTester, SelfDeleteCreatePluginInNPNEvaluate) { // test is crashy. I could not repro the crash on my local setup. Leaving this // marked as FLAKY for now while we watch this on the builders. TEST_F(NPAPIVisiblePluginTester, FLAKY_OpenPopupWindowWithPlugin) { - if (UITest::in_process_renderer()) + if (ProxyLauncher::in_process_renderer()) return; const FilePath test_case( @@ -257,7 +257,7 @@ TEST_F(NPAPIVisiblePluginTester, FLAKY_OpenPopupWindowWithPlugin) { // Test checking the privacy mode is off. TEST_F(NPAPITesterBase, PrivateDisabled) { - if (UITest::in_process_renderer()) + if (ProxyLauncher::in_process_renderer()) return; const FilePath test_case(FILE_PATH_LITERAL("private.html")); @@ -285,7 +285,7 @@ TEST_F(NPAPITesterBase, PluginThreadAsyncCall) { // Test checking the privacy mode is on. TEST_F(NPAPIIncognitoTester, PrivateEnabled) { - if (UITest::in_process_renderer()) + if (ProxyLauncher::in_process_renderer()) return; const FilePath test_case(FILE_PATH_LITERAL("private.html?private")); @@ -299,7 +299,7 @@ TEST_F(NPAPIIncognitoTester, PrivateEnabled) { // Test a browser hang due to special case of multiple // plugin instances indulged in sync calls across renderer. TEST_F(NPAPIVisiblePluginTester, MultipleInstancesSyncCalls) { - if (UITest::in_process_renderer()) + if (ProxyLauncher::in_process_renderer()) return; const FilePath test_case( @@ -312,7 +312,7 @@ TEST_F(NPAPIVisiblePluginTester, MultipleInstancesSyncCalls) { #endif TEST_F(NPAPIVisiblePluginTester, GetURLRequestFailWrite) { - if (UITest::in_process_renderer()) + if (ProxyLauncher::in_process_renderer()) return; GURL url(URLRequestMockHTTPJob::GetMockUrl( @@ -327,7 +327,7 @@ TEST_F(NPAPIVisiblePluginTester, GetURLRequestFailWrite) { #if defined(OS_WIN) TEST_F(NPAPITesterBase, EnsureScriptingWorksInDestroy) { - if (UITest::in_process_renderer()) + if (ProxyLauncher::in_process_renderer()) return; const FilePath test_case( @@ -342,7 +342,7 @@ TEST_F(NPAPITesterBase, EnsureScriptingWorksInDestroy) { // This test uses a Windows Event to signal to the plugin that it should crash // on NP_Initialize. TEST_F(NPAPITesterBase, NoHangIfInitCrashes) { - if (UITest::in_process_renderer()) + if (ProxyLauncher::in_process_renderer()) return; // Only Windows implements the crash service for now. @@ -364,7 +364,7 @@ TEST_F(NPAPITesterBase, NoHangIfInitCrashes) { #endif TEST_F(NPAPIVisiblePluginTester, PluginReferrerTest) { - if (UITest::in_process_renderer()) + if (ProxyLauncher::in_process_renderer()) return; GURL url(URLRequestMockHTTPJob::GetMockUrl( @@ -379,7 +379,7 @@ TEST_F(NPAPIVisiblePluginTester, PluginReferrerTest) { #if defined(OS_MACOSX) TEST_F(NPAPIVisiblePluginTester, PluginConvertPointTest) { - if (UITest::in_process_renderer()) + if (ProxyLauncher::in_process_renderer()) return; scoped_refptr<BrowserProxy> browser(automation()->GetBrowserWindow(0)); diff --git a/chrome/test/ui/ui_perf_test.cc b/chrome/test/ui/ui_perf_test.cc index c234abf..a8b7ca1 100644 --- a/chrome/test/ui/ui_perf_test.cc +++ b/chrome/test/ui/ui_perf_test.cc @@ -67,7 +67,8 @@ void UIPerfTest::PrintResultsImpl(const std::string& measurement, } void UIPerfTest::PrintIOPerfInfo(const char* test_name) { - ChromeProcessList chrome_processes(GetRunningChromeProcesses(process_id_)); + ChromeProcessList chrome_processes( + GetRunningChromeProcesses(browser_process_id())); size_t read_op_b = 0; size_t read_op_r = 0; @@ -173,7 +174,8 @@ void UIPerfTest::PrintIOPerfInfo(const char* test_name) { } void UIPerfTest::PrintMemoryUsageInfo(const char* test_name) { - ChromeProcessList chrome_processes(GetRunningChromeProcesses(process_id_)); + ChromeProcessList chrome_processes( + GetRunningChromeProcesses(browser_process_id())); size_t browser_virtual_size = 0; size_t browser_working_set_size = 0; diff --git a/chrome/test/ui/ui_test.cc b/chrome/test/ui/ui_test.cc index 9ef3ae6..cc456a1 100644 --- a/chrome/test/ui/ui_test.cc +++ b/chrome/test/ui/ui_test.cc @@ -61,9 +61,6 @@ using base::Time; using base::TimeDelta; using base::TimeTicks; -// Passed as value of kTestType. -static const char kUITestType[] = "ui"; - const wchar_t UITestBase::kFailedNoCrashService[] = #if defined(OS_WIN) L"NOTE: This test is expected to fail if crash_service.exe is not " @@ -75,17 +72,6 @@ const wchar_t UITestBase::kFailedNoCrashService[] = #else L"NOTE: Crash service not ported to this platform!"; #endif -bool UITestBase::in_process_renderer_ = false; -bool UITestBase::no_sandbox_ = false; -bool UITestBase::full_memory_dump_ = false; -bool UITestBase::safe_plugins_ = false; -bool UITestBase::show_error_dialogs_ = true; -bool UITestBase::dump_histograms_on_exit_ = false; -bool UITestBase::enable_dcheck_ = false; -bool UITestBase::silent_dump_on_dcheck_ = false; -bool UITestBase::disable_breakpad_ = false; -std::string UITestBase::js_flags_ = ""; -std::string UITestBase::log_level_ = ""; // Uncomment this line to have the spawned process wait for the debugger to // attach. This only works on Windows. On posix systems, you can set the @@ -99,51 +85,47 @@ UITestBase::UITestBase() homepage_(chrome::kAboutBlankURL), wait_for_initial_loads_(true), dom_automation_enabled_(false), - process_(base::kNullProcessHandle), - process_id_(-1), show_window_(false), clear_profile_(true), include_testing_id_(true), enable_file_cookies_(true), - profile_type_(UITestBase::DEFAULT_THEME), - shutdown_type_(UITestBase::WINDOW_CLOSE), - temp_profile_dir_(new ScopedTempDir()) { + profile_type_(ProxyLauncher::DEFAULT_THEME), + shutdown_type_(ProxyLauncher::WINDOW_CLOSE) { PathService::Get(chrome::DIR_APP, &browser_directory_); PathService::Get(chrome::DIR_TEST_DATA, &test_data_directory_); + launcher_.reset(CreateProxyLauncher()); } UITestBase::UITestBase(MessageLoop::Type msg_loop_type) : launch_arguments_(CommandLine::NO_PROGRAM), expected_errors_(0), expected_crashes_(0), - homepage_(chrome::kAboutBlankURL), wait_for_initial_loads_(true), dom_automation_enabled_(false), - process_(base::kNullProcessHandle), - process_id_(-1), show_window_(false), clear_profile_(true), include_testing_id_(true), enable_file_cookies_(true), - profile_type_(UITestBase::DEFAULT_THEME), - shutdown_type_(UITestBase::WINDOW_CLOSE) { + profile_type_(ProxyLauncher::DEFAULT_THEME), + shutdown_type_(ProxyLauncher::WINDOW_CLOSE) { PathService::Get(chrome::DIR_APP, &browser_directory_); PathService::Get(chrome::DIR_TEST_DATA, &test_data_directory_); + launcher_.reset(CreateProxyLauncher()); } -UITestBase::~UITestBase() { -} +UITestBase::~UITestBase() {} void UITestBase::SetUp() { - AssertAppNotRunning(L"Please close any other instances " - L"of the app before testing."); + launcher_->AssertAppNotRunning(L"Please close any other instances " + L"of the app before testing."); JavaScriptExecutionController::set_timeout( TestTimeouts::action_max_timeout_ms()); test_start_time_ = Time::NowFromSystemTime(); - launcher_.reset(CreateProxyLauncher()); - launcher_->InitializeConnection(this); + SetLaunchSwitches(); + launcher_->InitializeConnection(DefaultLaunchState(), + wait_for_initial_loads_); } void UITestBase::TearDown() { @@ -178,7 +160,7 @@ void UITestBase::TearDown() { // TODO(phajdan.jr): get rid of set_command_execution_timeout_ms. void UITestBase::set_command_execution_timeout_ms(int timeout) { - automation_proxy_->set_command_execution_timeout_ms(timeout); + automation()->set_command_execution_timeout_ms(timeout); VLOG(1) << "Automation command execution timeout set to " << timeout << " ms"; } @@ -186,210 +168,61 @@ ProxyLauncher* UITestBase::CreateProxyLauncher() { return new AnonymousProxyLauncher(false); } +void UITestBase::SetLaunchSwitches() { + // We need cookies on file:// for things like the page cycler. + if (enable_file_cookies_) + launch_arguments_.AppendSwitch(switches::kEnableFileCookies); + if (dom_automation_enabled_) + launch_arguments_.AppendSwitch(switches::kDomAutomationController); + if (!homepage_.empty()) + launch_arguments_.AppendSwitchASCII(switches::kHomePage, homepage_); + if (!test_name_.empty()) + launch_arguments_.AppendSwitchASCII(switches::kTestName, test_name_); +} + void UITestBase::LaunchBrowser() { LaunchBrowser(launch_arguments_, clear_profile_); } void UITestBase::LaunchBrowserAndServer() { - // Set up IPC testing interface as a server. - automation_proxy_.reset(launcher_->CreateAutomationProxy( - TestTimeouts::command_execution_timeout_ms())); - - LaunchBrowser(launch_arguments_, clear_profile_); - WaitForBrowserLaunch(); + launcher_->LaunchBrowserAndServer(DefaultLaunchState(), + wait_for_initial_loads_); } void UITestBase::ConnectToRunningBrowser() { - // Set up IPC testing interface as a client. - automation_proxy_.reset(launcher_->CreateAutomationProxy( - TestTimeouts::command_execution_timeout_ms())); - WaitForBrowserLaunch(); -} - -void UITestBase::WaitForBrowserLaunch() { - ASSERT_EQ(AUTOMATION_SUCCESS, automation_proxy_->WaitForAppLaunch()) - << "Error while awaiting automation ping from browser process"; - if (wait_for_initial_loads_) - ASSERT_TRUE(automation_proxy_->WaitForInitialLoads()); - else - base::PlatformThread::Sleep(sleep_timeout_ms()); - - EXPECT_TRUE(automation()->SetFilteredInet(ShouldFilterInet())); + launcher_->ConnectToRunningBrowser(wait_for_initial_loads_); } void UITestBase::CloseBrowserAndServer() { - QuitBrowser(); - CleanupAppProcesses(); - - // Suppress spammy failures that seem to be occurring when running - // the UI tests in single-process mode. - // TODO(jhughes): figure out why this is necessary at all, and fix it - if (!in_process_renderer_) - AssertAppNotRunning(StringPrintf( - L"Unable to quit all browser processes. Original PID %d", process_id_)); - - automation_proxy_.reset(); // Shut down IPC testing interface. + launcher_->CloseBrowserAndServer(shutdown_type_); } void UITestBase::LaunchBrowser(const CommandLine& arguments, bool clear_profile) { - if (clear_profile || !temp_profile_dir_->IsValid()) { - temp_profile_dir_.reset(new ScopedTempDir()); - ASSERT_TRUE(temp_profile_dir_->CreateUniqueTempDir()); - - ASSERT_TRUE( - test_launcher_utils::OverrideUserDataDir(temp_profile_dir_->path())); - } - - if (!template_user_data_.empty()) { - // Recursively copy the template directory to the user_data_dir. - ASSERT_TRUE(file_util::CopyRecursiveDirNoCache( - template_user_data_, - user_data_dir())); - // If we're using the complex theme data, we need to write the - // user_data_dir_ to our preferences file. - if (profile_type_ == UITestBase::COMPLEX_THEME) { - RewritePreferencesFile(user_data_dir()); - } - - // Update the history file to include recent dates. - UpdateHistoryDates(); - } - - ASSERT_TRUE(LaunchBrowserHelper(arguments, false, &process_)); - process_id_ = base::GetProcId(process_); + ProxyLauncher::LaunchState state = DefaultLaunchState(); + state.clear_profile = clear_profile; + launcher_->LaunchBrowser(state); } #if !defined(OS_MACOSX) bool UITestBase::LaunchAnotherBrowserBlockUntilClosed( const CommandLine& cmdline) { - return LaunchBrowserHelper(cmdline, true, NULL); + ProxyLauncher::LaunchState state = DefaultLaunchState(); + state.arguments = cmdline; + return launcher_->LaunchAnotherBrowserBlockUntilClosed(state); } #endif void UITestBase::QuitBrowser() { - if (SESSION_ENDING == shutdown_type_) { - TerminateBrowser(); - return; - } - - // There's nothing to do here if the browser is not running. - // WARNING: There is a race condition here where the browser may shut down - // after this check but before some later automation call. Your test should - // use WaitForBrowserProcessToQuit() if it intentionally - // causes the browser to shut down. - if (IsBrowserRunning()) { - TimeTicks quit_start = TimeTicks::Now(); - EXPECT_TRUE(automation()->SetFilteredInet(false)); - - if (WINDOW_CLOSE == shutdown_type_) { - int window_count = 0; - EXPECT_TRUE(automation()->GetBrowserWindowCount(&window_count)); - - // Synchronously close all but the last browser window. Closing them - // one-by-one may help with stability. - while (window_count > 1) { - scoped_refptr<BrowserProxy> browser_proxy = - automation()->GetBrowserWindow(0); - EXPECT_TRUE(browser_proxy.get()); - if (browser_proxy.get()) { - EXPECT_TRUE(browser_proxy->RunCommand(IDC_CLOSE_WINDOW)); - EXPECT_TRUE(automation()->GetBrowserWindowCount(&window_count)); - } else { - break; - } - } - - // Close the last window asynchronously, because the browser may - // shutdown faster than it will be able to send a synchronous response - // to our message. - scoped_refptr<BrowserProxy> browser_proxy = - automation()->GetBrowserWindow(0); - EXPECT_TRUE(browser_proxy.get()); - if (browser_proxy.get()) { - EXPECT_TRUE(browser_proxy->ApplyAccelerator(IDC_CLOSE_WINDOW)); - browser_proxy = NULL; - } - } else if (USER_QUIT == shutdown_type_) { - scoped_refptr<BrowserProxy> browser_proxy = - automation()->GetBrowserWindow(0); - EXPECT_TRUE(browser_proxy.get()); - if (browser_proxy.get()) { - EXPECT_TRUE(browser_proxy->RunCommandAsync(IDC_EXIT)); - } - } else { - NOTREACHED() << "Invalid shutdown type " << shutdown_type_; - } - - // Now, drop the automation IPC channel so that the automation provider in - // the browser notices and drops its reference to the browser process. - automation()->Disconnect(); - - // Wait for the browser process to quit. It should quit once all tabs have - // been closed. - if (!WaitForBrowserProcessToQuit()) { - // We need to force the browser to quit because it didn't quit fast - // enough. Take no chance and kill every chrome processes. - CleanupAppProcesses(); - } - browser_quit_time_ = TimeTicks::Now() - quit_start; - } - - // Don't forget to close the handle - base::CloseProcessHandle(process_); - process_ = base::kNullProcessHandle; - process_id_ = -1; + launcher_->QuitBrowser(shutdown_type_); } void UITestBase::TerminateBrowser() { - if (IsBrowserRunning()) { - TimeTicks quit_start = TimeTicks::Now(); - EXPECT_TRUE(automation()->SetFilteredInet(false)); -#if defined(OS_WIN) - scoped_refptr<BrowserProxy> browser(automation()->GetBrowserWindow(0)); - ASSERT_TRUE(browser.get()); - ASSERT_TRUE(browser->TerminateSession()); -#endif // defined(OS_WIN) - - // Now, drop the automation IPC channel so that the automation provider in - // the browser notices and drops its reference to the browser process. - automation()->Disconnect(); - -#if defined(OS_POSIX) - EXPECT_EQ(kill(process_, SIGTERM), 0); -#endif // OS_POSIX - - if (!WaitForBrowserProcessToQuit()) { - // We need to force the browser to quit because it didn't quit fast - // enough. Take no chance and kill every chrome processes. - CleanupAppProcesses(); - } - browser_quit_time_ = TimeTicks::Now() - quit_start; - } - - // Don't forget to close the handle - base::CloseProcessHandle(process_); - process_ = base::kNullProcessHandle; - process_id_ = -1; -} - -void UITestBase::AssertAppNotRunning(const std::wstring& error_message) { - std::wstring final_error_message(error_message); - - ChromeProcessList processes = GetRunningChromeProcesses(process_id_); - if (!processes.empty()) { - final_error_message += L" Leftover PIDs: ["; - for (ChromeProcessList::const_iterator it = processes.begin(); - it != processes.end(); ++it) { - final_error_message += StringPrintf(L" %d", *it); - } - final_error_message += L" ]"; - } - ASSERT_TRUE(processes.empty()) << final_error_message; + launcher_->TerminateBrowser(); } void UITestBase::CleanupAppProcesses() { - TerminateAllChromeProcesses(process_id_); + TerminateAllChromeProcesses(browser_process_id()); } scoped_refptr<TabProxy> UITestBase::GetActiveTab(int window_index) { @@ -464,13 +297,8 @@ void UITestBase::NavigateToURLBlockUntilNavigationsComplete( url, number_of_navigations)) << url.spec(); } -bool UITestBase::WaitForBrowserProcessToQuit() { - // Wait for the browser process to quit. - int timeout = TestTimeouts::wait_for_terminate_timeout_ms(); -#ifdef WAIT_FOR_DEBUGGER_ON_OPEN - timeout = 500000; -#endif - return base::WaitForSingleProcess(process_, timeout); +bool UITestBase::WaitForBrowserProcessToQuit(int timeout) { + return launcher_->WaitForBrowserProcessToQuit(timeout); } bool UITestBase::WaitForBookmarkBarVisibilityChange(BrowserProxy* browser, @@ -533,11 +361,11 @@ int UITestBase::GetActiveTabIndex(int window_index) { } bool UITestBase::IsBrowserRunning() { - return CrashAwareSleep(0); + return launcher_->IsBrowserRunning(); } -bool UITestBase::CrashAwareSleep(int time_out_ms) { - return base::CrashAwareSleep(process_, time_out_ms); +bool UITestBase::CrashAwareSleep(int timeout_ms) { + return launcher_->CrashAwareSleep(timeout_ms); } int UITestBase::GetTabCount() { @@ -585,7 +413,7 @@ FilePath UITestBase::GetDownloadDirectory() { } void UITestBase::CloseBrowserAsync(BrowserProxy* browser) const { - ASSERT_TRUE(automation_proxy_->Send( + ASSERT_TRUE(automation()->Send( new AutomationMsg_CloseBrowserRequestAsync(browser->handle()))); } @@ -597,7 +425,7 @@ bool UITestBase::CloseBrowser(BrowserProxy* browser, bool result = true; - bool succeeded = automation_proxy_->Send(new AutomationMsg_CloseBrowser( + bool succeeded = automation()->Send(new AutomationMsg_CloseBrowser( browser->handle(), &result, application_closed)); if (!succeeded) @@ -605,7 +433,7 @@ bool UITestBase::CloseBrowser(BrowserProxy* browser, if (*application_closed) { // Let's wait until the process dies (if it is not gone already). - bool success = base::WaitForSingleProcess(process_, base::kNoTimeout); + bool success = base::WaitForSingleProcess(process(), base::kNoTimeout); EXPECT_TRUE(success); } @@ -613,63 +441,26 @@ bool UITestBase::CloseBrowser(BrowserProxy* browser, } // static -void UITestBase::RewritePreferencesFile(const FilePath& user_data_dir) { - const FilePath pref_template_path( - user_data_dir.AppendASCII("Default").AppendASCII("PreferencesTemplate")); - const FilePath pref_path( - user_data_dir.AppendASCII("Default").AppendASCII("Preferences")); - - // Read in preferences template. - std::string pref_string; - EXPECT_TRUE(file_util::ReadFileToString(pref_template_path, &pref_string)); - string16 format_string = ASCIIToUTF16(pref_string); - - // Make sure temp directory has the proper format for writing to prefs file. -#if defined(OS_POSIX) - std::wstring user_data_dir_w(ASCIIToWide(user_data_dir.value())); -#elif defined(OS_WIN) - std::wstring user_data_dir_w(user_data_dir.value()); - // In Windows, the FilePath will write '\' for the path separators; change - // these to a separator that won't trigger escapes. - std::replace(user_data_dir_w.begin(), - user_data_dir_w.end(), '\\', '/'); -#endif - - // Rewrite prefs file. - std::vector<string16> subst; - subst.push_back(WideToUTF16(user_data_dir_w)); - const std::string prefs_string = - UTF16ToASCII(ReplaceStringPlaceholders(format_string, subst, NULL)); - EXPECT_TRUE(file_util::WriteFile(pref_path, prefs_string.c_str(), - prefs_string.size())); - file_util::EvictFileFromSystemCache(pref_path); -} - -FilePath UITestBase::user_data_dir() const { - EXPECT_TRUE(temp_profile_dir_->IsValid()); - return temp_profile_dir_->path(); -} - -// static -FilePath UITestBase::ComputeTypicalUserDataSource(ProfileType profile_type) { +FilePath UITestBase::ComputeTypicalUserDataSource( + ProxyLauncher::ProfileType profile_type) { FilePath source_history_file; EXPECT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &source_history_file)); source_history_file = source_history_file.AppendASCII("profiles"); switch (profile_type) { - case UITestBase::DEFAULT_THEME: + case ProxyLauncher::DEFAULT_THEME: source_history_file = source_history_file.AppendASCII("typical_history"); break; - case UITestBase::COMPLEX_THEME: + case ProxyLauncher::COMPLEX_THEME: source_history_file = source_history_file.AppendASCII("complex_theme"); break; - case UITestBase::NATIVE_THEME: + case ProxyLauncher::NATIVE_THEME: source_history_file = source_history_file.AppendASCII("gtk_theme"); break; - case UITestBase::CUSTOM_FRAME: + case ProxyLauncher::CUSTOM_FRAME: source_history_file = source_history_file.AppendASCII("custom_frame"); break; - case UITestBase::CUSTOM_FRAME_NATIVE_THEME: + case ProxyLauncher::CUSTOM_FRAME_NATIVE_THEME: source_history_file = source_history_file.AppendASCII("custom_frame_gtk_theme"); break; @@ -679,163 +470,6 @@ FilePath UITestBase::ComputeTypicalUserDataSource(ProfileType profile_type) { return source_history_file; } -void UITestBase::PrepareTestCommandline(CommandLine* command_line) { - // Propagate commandline settings from test_launcher_utils. - test_launcher_utils::PrepareBrowserCommandLineForTests(command_line); - - // Add any explicit command line flags passed to the process. - CommandLine::StringType extra_chrome_flags = - CommandLine::ForCurrentProcess()->GetSwitchValueNative( - switches::kExtraChromeFlags); - if (!extra_chrome_flags.empty()) { - // Split by spaces and append to command line - std::vector<CommandLine::StringType> flags; - base::SplitString(extra_chrome_flags, ' ', &flags); - for (size_t i = 0; i < flags.size(); ++i) - command_line->AppendArgNative(flags[i]); - } - - // No default browser check, it would create an info-bar (if we are not the - // default browser) that could conflicts with some tests expectations. - command_line->AppendSwitch(switches::kNoDefaultBrowserCheck); - - // This is a UI test. - command_line->AppendSwitchASCII(switches::kTestType, kUITestType); - - // Tell the browser to use a temporary directory just for this test. - command_line->AppendSwitchPath(switches::kUserDataDir, user_data_dir()); - - // We need cookies on file:// for things like the page cycler. - if (enable_file_cookies_) - command_line->AppendSwitch(switches::kEnableFileCookies); - - if (dom_automation_enabled_) - command_line->AppendSwitch(switches::kDomAutomationController); - - if (include_testing_id_) - command_line->AppendSwitchASCII(switches::kTestingChannelID, - launcher_->PrefixedChannelID()); - - if (!show_error_dialogs_ && - !CommandLine::ForCurrentProcess()->HasSwitch( - switches::kEnableErrorDialogs)) { - command_line->AppendSwitch(switches::kNoErrorDialogs); - } - if (in_process_renderer_) - command_line->AppendSwitch(switches::kSingleProcess); - if (no_sandbox_) - command_line->AppendSwitch(switches::kNoSandbox); - if (full_memory_dump_) - command_line->AppendSwitch(switches::kFullMemoryCrashReport); - if (safe_plugins_) - command_line->AppendSwitch(switches::kSafePlugins); - if (enable_dcheck_) - command_line->AppendSwitch(switches::kEnableDCHECK); - if (silent_dump_on_dcheck_) - command_line->AppendSwitch(switches::kSilentDumpOnDCHECK); - if (disable_breakpad_) - command_line->AppendSwitch(switches::kDisableBreakpad); - if (!homepage_.empty()) - command_line->AppendSwitchASCII(switches::kHomePage, homepage_); - - if (!js_flags_.empty()) - command_line->AppendSwitchASCII(switches::kJavaScriptFlags, js_flags_); - if (!log_level_.empty()) - command_line->AppendSwitchASCII(switches::kLoggingLevel, log_level_); - - command_line->AppendSwitch(switches::kMetricsRecordingOnly); - - if (!CommandLine::ForCurrentProcess()->HasSwitch( - switches::kEnableErrorDialogs)) - command_line->AppendSwitch(switches::kEnableLogging); - - if (dump_histograms_on_exit_) - command_line->AppendSwitch(switches::kDumpHistogramsOnExit); - -#ifdef WAIT_FOR_DEBUGGER_ON_OPEN - command_line->AppendSwitch(switches::kDebugOnStart); -#endif - - if (!ui_test_name_.empty()) - command_line->AppendSwitchASCII(switches::kTestName, ui_test_name_); - - // The tests assume that file:// URIs can freely access other file:// URIs. - command_line->AppendSwitch(switches::kAllowFileAccessFromFiles); - - // Disable TabCloseableStateWatcher for tests. - command_line->AppendSwitch(switches::kDisableTabCloseableStateWatcher); - - // Allow file:// access on ChromeOS. - command_line->AppendSwitch(switches::kAllowFileAccess); -} - -bool UITestBase::LaunchBrowserHelper(const CommandLine& arguments, - bool wait, - base::ProcessHandle* process) { - FilePath command = browser_directory_.Append( - chrome::kBrowserProcessExecutablePath); - - CommandLine command_line(command); - - // Add command line arguments that should be applied to all UI tests. - PrepareTestCommandline(&command_line); - DebugFlags::ProcessDebugFlags( - &command_line, ChildProcessInfo::UNKNOWN_PROCESS, false); - command_line.AppendArguments(arguments, false); - - // TODO(phajdan.jr): Only run it for "main" browser launch. - browser_launch_time_ = TimeTicks::Now(); - -#if defined(OS_WIN) - bool started = base::LaunchApp(command_line, - wait, - !show_window_, - process); -#elif defined(OS_POSIX) - // Sometimes one needs to run the browser under a special environment - // (e.g. valgrind) without also running the test harness (e.g. python) - // under the special environment. Provide a way to wrap the browser - // commandline with a special prefix to invoke the special environment. - const char* browser_wrapper = getenv("BROWSER_WRAPPER"); - if (browser_wrapper) { - command_line.PrependWrapper(browser_wrapper); - VLOG(1) << "BROWSER_WRAPPER was set, prefixing command_line with " - << browser_wrapper; - } - - base::file_handle_mapping_vector fds; - if (automation_proxy_.get()) - fds = automation_proxy_->fds_to_map(); - - bool started = base::LaunchApp(command_line.argv(), fds, wait, process); -#endif - - return started; -} - -void UITestBase::UpdateHistoryDates() { - // Migrate the times in the segment_usage table to yesterday so we get - // actual thumbnails on the NTP. - sql::Connection db; - FilePath history = - user_data_dir().AppendASCII("Default").AppendASCII("History"); - // Not all test profiles have a history file. - if (!file_util::PathExists(history)) - return; - - ASSERT_TRUE(db.Open(history)); - Time yesterday = Time::Now() - TimeDelta::FromDays(1); - std::string yesterday_str = base::Int64ToString(yesterday.ToInternalValue()); - std::string query = StringPrintf( - "UPDATE segment_usage " - "SET time_slot = %s " - "WHERE id IN (SELECT id FROM segment_usage WHERE time_slot > 0);", - yesterday_str.c_str()); - ASSERT_TRUE(db.Execute(query.c_str())); - db.Close(); - file_util::EvictFileFromSystemCache(history); -} - int UITestBase::GetCrashCount() { FilePath crash_dump_path; PathService::Get(chrome::DIR_CRASH_DUMPS, &crash_dump_path); @@ -862,8 +496,8 @@ void UITest::SetUp() { const testing::TestInfo* const test_info = testing::UnitTest::GetInstance()->current_test_info(); if (test_info) { - set_ui_test_name(test_info->test_case_name() + std::string(".") + - test_info->name()); + set_test_name(test_info->test_case_name() + std::string(".") + + test_info->name()); } // Force tests to use OSMesa if they launch the GPU process. This is in @@ -964,7 +598,7 @@ void UITest::StopHttpServer() { } int UITest::GetBrowserProcessCount() { - return GetRunningChromeProcesses(process_id_).size(); + return GetRunningChromeProcesses(browser_process_id()).size(); } static DictionaryValue* LoadDictionaryValueFromPath(const FilePath& path) { @@ -1073,9 +707,9 @@ void UITest::WaitForGeneratedFileAndCheck( bool UITest::WaitUntilJavaScriptCondition(TabProxy* tab, const std::wstring& frame_xpath, const std::wstring& jscript, - int time_out_ms) { + int timeout_ms) { const int kIntervalMs = 250; - const int kMaxIntervals = time_out_ms / kIntervalMs; + const int kMaxIntervals = timeout_ms / kIntervalMs; // Wait until the test signals it has completed. for (int i = 0; i < kMaxIntervals; ++i) { @@ -1101,10 +735,10 @@ bool UITest::WaitUntilJavaScriptCondition(TabProxy* tab, bool UITest::WaitUntilCookieValue(TabProxy* tab, const GURL& url, const char* cookie_name, - int time_out_ms, + int timeout_ms, const char* expected_value) { const int kIntervalMs = 250; - const int kMaxIntervals = time_out_ms / kIntervalMs; + const int kMaxIntervals = timeout_ms / kIntervalMs; std::string cookie_value; for (int i = 0; i < kMaxIntervals; ++i) { @@ -1125,9 +759,9 @@ bool UITest::WaitUntilCookieValue(TabProxy* tab, std::string UITest::WaitUntilCookieNonEmpty(TabProxy* tab, const GURL& url, const char* cookie_name, - int time_out_ms) { + int timeout_ms) { const int kIntervalMs = 250; - const int kMaxIntervals = time_out_ms / kIntervalMs; + const int kMaxIntervals = timeout_ms / kIntervalMs; for (int i = 0; i < kMaxIntervals; ++i) { bool browser_survived = CrashAwareSleep(kIntervalMs); diff --git a/chrome/test/ui/ui_test.h b/chrome/test/ui/ui_test.h index 3305cc5..99c83b9 100644 --- a/chrome/test/ui/ui_test.h +++ b/chrome/test/ui/ui_test.h @@ -31,6 +31,7 @@ // AutomationProxy here, but many files that #include this one don't // themselves #include automation_proxy.h. #include "chrome/test/automation/automation_proxy.h" +#include "chrome/test/automation/proxy_launcher.h" #include "testing/platform_test.h" class AutomationProxy; @@ -38,7 +39,6 @@ class BrowserProxy; class DictionaryValue; class FilePath; class GURL; -class ProxyLauncher; class ScopedTempDir; class TabProxy; @@ -162,9 +162,9 @@ class UITestBase { // window or if the browser process died by itself. bool IsBrowserRunning(); - // Returns true when time_out_ms milliseconds have elapsed. + // Returns true when timeout_ms milliseconds have elapsed. // Returns false if the browser process died while waiting. - bool CrashAwareSleep(int time_out_ms); + bool CrashAwareSleep(int timeout_ms); // Returns the number of tabs in the first window. If no windows exist, // causes a test failure and returns 0. @@ -179,7 +179,7 @@ class UITestBase { // Wait for the browser process to shut down on its own (i.e. as a result of // some action that your test has taken). - bool WaitForBrowserProcessToQuit(); + bool WaitForBrowserProcessToQuit(int timeout); // Waits until the Bookmark bar has stopped animating and become fully visible // (if |wait_for_open| is true) or fully hidden (if |wait_for_open| is false). @@ -202,90 +202,16 @@ class UITestBase { // Gets the directory for the currently active profile in the browser. FilePath GetDownloadDirectory(); - // Get the handle of browser process connected to the automation. This - // function only retruns a reference to the handle so the caller does not - // own the handle returned. - base::ProcessHandle process() { return process_; } - - // Get/Set a flag to run the renderer in process when running the - // tests. - static bool in_process_renderer() { return in_process_renderer_; } - static void set_in_process_renderer(bool value) { - in_process_renderer_ = value; - } - - // Get/Set a flag to run the renderer outside the sandbox when running the - // tests - static bool no_sandbox() { return no_sandbox_; } - static void set_no_sandbox(bool value) { - no_sandbox_ = value; - } - - // Get/Set a flag to run with DCHECKs enabled in release. - static bool enable_dcheck() { return enable_dcheck_; } - static void set_enable_dcheck(bool value) { - enable_dcheck_ = value; - } - - // Get/Set a flag to dump the process memory without crashing on DCHECKs. - static bool silent_dump_on_dcheck() { return silent_dump_on_dcheck_; } - static void set_silent_dump_on_dcheck(bool value) { - silent_dump_on_dcheck_ = value; - } - - // Get/Set a flag to disable breakpad handling. - static bool disable_breakpad() { return disable_breakpad_; } - static void set_disable_breakpad(bool value) { - disable_breakpad_ = value; - } - - // Get/Set a flag to run the plugin processes inside the sandbox when running - // the tests - static bool safe_plugins() { return safe_plugins_; } - static void set_safe_plugins(bool value) { - safe_plugins_ = value; - } - - static bool show_error_dialogs() { return show_error_dialogs_; } - static void set_show_error_dialogs(bool value) { - show_error_dialogs_ = value; - } - - static bool full_memory_dump() { return full_memory_dump_; } - static void set_full_memory_dump(bool value) { - full_memory_dump_ = value; - } - - static bool dump_histograms_on_exit() { return dump_histograms_on_exit_; } - static void set_dump_histograms_on_exit(bool value) { - dump_histograms_on_exit_ = value; - } - - static const std::string& js_flags() { return js_flags_; } - static void set_js_flags(const std::string& value) { - js_flags_ = value; - } - - static const std::string& log_level() { return log_level_; } - static void set_log_level(const std::string& value) { - log_level_ = value; - } - - // Profile theme type choices. - typedef enum { - DEFAULT_THEME = 0, - COMPLEX_THEME = 1, - NATIVE_THEME = 2, - CUSTOM_FRAME = 3, - CUSTOM_FRAME_NATIVE_THEME = 4, - } ProfileType; - // Returns the directory name where the "typical" user data is that we use // for testing. - static FilePath ComputeTypicalUserDataSource(ProfileType profile_type); + static FilePath ComputeTypicalUserDataSource( + ProxyLauncher::ProfileType profile_type); - // Rewrite the preferences file to point to the proper image directory. - static void RewritePreferencesFile(const FilePath& user_data_dir); + // Return the user data directory being used by the browser instance in + // UITest::SetUp(). + FilePath user_data_dir() const { + return launcher_->user_data_dir(); + } // Called by some tests that wish to have a base profile to start from. This // "user data directory" (containing one or more profiles) will be recursively @@ -297,12 +223,23 @@ class UITestBase { template_user_data_ = template_user_data; } - // Return the user data directory being used by the browser instance in - // UITest::SetUp(). - FilePath user_data_dir() const; + // Get the handle of browser process connected to the automation. This + // function only returns a reference to the handle so the caller does not + // own the handle returned. + base::ProcessHandle process() const { return launcher_->process(); } // Return the process id of the browser process (-1 on error). - base::ProcessId browser_process_id() const { return process_id_; } + base::ProcessId browser_process_id() const { return launcher_->process_id(); } + + // Return the time when the browser was run. + base::TimeTicks browser_launch_time() const { + return launcher_->browser_launch_time(); + } + + // Return how long the shutdown took. + base::TimeDelta browser_quit_time() const { + return launcher_->browser_quit_time(); + } // Compatibility timeout accessors. // TODO(phajdan.jr): update callers and remove these. @@ -323,10 +260,6 @@ class UITestBase { return TestTimeouts::huge_test_timeout_ms(); } - void set_ui_test_name(const std::string& name) { - ui_test_name_ = name; - } - // Fetch the state which determines whether the profile will be cleared on // next startup. bool get_clear_profile() const { @@ -338,21 +271,23 @@ class UITestBase { clear_profile_ = clear_profile; } + // homepage_ accessor. + std::string homepage() { + return homepage_; + } + // Sets homepage_. Should be called before launching browser to have // any effect. void set_homepage(const std::string& homepage) { homepage_ = homepage; } - // Different ways to quit the browser. - typedef enum { - WINDOW_CLOSE, - USER_QUIT, - SESSION_ENDING, - } ShutdownType; + void set_test_name(const std::string& name) { + test_name_ = name; + } // Sets the shutdown type, which defaults to WINDOW_CLOSE. - void set_shutdown_type(ShutdownType value) { + void set_shutdown_type(ProxyLauncher::ShutdownType value) { shutdown_type_ = value; } @@ -362,21 +297,27 @@ class UITestBase { // Use Chromium binaries from the given directory. void SetBrowserDirectory(const FilePath& dir); - private: - // Check that no processes related to Chrome exist, displaying - // the given message if any do. - void AssertAppNotRunning(const std::wstring& error_message); - protected: - AutomationProxy* automation() { - EXPECT_TRUE(automation_proxy_.get()); - return automation_proxy_.get(); + AutomationProxy* automation() const { + return launcher_->automation(); + } + + ProxyLauncher::LaunchState DefaultLaunchState() { + ProxyLauncher::LaunchState state = + { clear_profile_, template_user_data_, profile_type_, + browser_directory_, launch_arguments_, + include_testing_id_, show_window_ }; + return state; } virtual bool ShouldFilterInet() { return true; } + // Extra command-line switches that need to be passed to the browser are + // added in this function. Add new command-line switches here. + void SetLaunchSwitches(); + // Wait a certain amount of time for all the app processes to exit, // forcibly killing them if they haven't exited by then. // It has the side-effect of killing every browser window opened in your @@ -394,80 +335,64 @@ class UITestBase { // ********* Member variables ********* - FilePath browser_directory_; // Path to the browser executable. - FilePath test_data_directory_; // Path to the unit test data. - CommandLine launch_arguments_; // Command to launch the browser - size_t expected_errors_; // The number of errors expected during - // the run (generally 0). - int expected_crashes_; // The number of crashes expected during - // the run (generally 0). - std::string homepage_; // Homepage used for testing. - bool wait_for_initial_loads_; // Wait for initial loads to complete - // in SetUp() before running test body. - base::TimeTicks browser_launch_time_; // Time when the browser was run. - base::TimeDelta browser_quit_time_; // How long the shutdown took. - bool dom_automation_enabled_; // This can be set to true to have the - // test run the dom automation case. - FilePath template_user_data_; // See set_template_user_data(). - base::ProcessHandle process_; // Handle to the first Chrome process. - base::ProcessId process_id_; // PID of |process_| (for debugging). - static bool in_process_renderer_; // true if we're in single process mode - bool show_window_; // Determines if the window is shown or - // hidden. Defaults to hidden. - bool clear_profile_; // If true the profile is cleared before - // launching. Default is true. - bool include_testing_id_; // Should we supply the testing channel - // id on the command line? Default is - // true. - bool enable_file_cookies_; // Enable file cookies, default is true. - scoped_ptr<ProxyLauncher> launcher_; // Launches browser and AutomationProxy. - ProfileType profile_type_; // Are we using a profile with a - // complex theme? - FilePath websocket_pid_file_; // PID file for websocket server. - ShutdownType shutdown_type_; // The method for shutting down - // the browser. Used in ShutdownTest. + // Path to the browser executable. + FilePath browser_directory_; + + // Path to the unit test data. + FilePath test_data_directory_; + + // Command to launch the browser + CommandLine launch_arguments_; + + // The number of errors expected during the run (generally 0). + size_t expected_errors_; + + // The number of crashes expected during the run (generally 0). + int expected_crashes_; + + // Homepage used for testing. + std::string homepage_; + + // Name of currently running automated test passed to Chrome process. + std::string test_name_; + + // Wait for initial loads to complete in SetUp() before running test body. + bool wait_for_initial_loads_; + + // This can be set to true to have the test run the dom automation case. + bool dom_automation_enabled_; + + // See set_template_user_data(). + FilePath template_user_data_; + + // Determines if the window is shown or hidden. Defaults to hidden. + bool show_window_; + + // If true the profile is cleared before launching. Default is true. + bool clear_profile_; + + // Should we supply the testing channel id + // on the command line? Default is true. + bool include_testing_id_; + + // Enable file cookies, default is true. + bool enable_file_cookies_; + + // Launches browser and AutomationProxy. + scoped_ptr<ProxyLauncher> launcher_; + + // Are we using a profile with a complex theme? + ProxyLauncher::ProfileType profile_type_; + + // PID file for websocket server. + FilePath websocket_pid_file_; + + // The method for shutting down the browser. Used in ShutdownTest. + ProxyLauncher::ShutdownType shutdown_type_; private: - void WaitForBrowserLaunch(); - - bool LaunchBrowserHelper(const CommandLine& arguments, - bool wait, - base::ProcessHandle* process); - - // Prepare command line that will be used to launch the child browser process - // with an UI test. - void PrepareTestCommandline(CommandLine* arguments); - - // We want to have a current history database when we start the browser so - // things like the NTP will have thumbnails. This method updates the dates - // in the history to be more recent. - void UpdateHistoryDates(); - - base::Time test_start_time_; // Time the test was started - // (so we can check for new crash dumps) - static bool no_sandbox_; - static bool safe_plugins_; - static bool full_memory_dump_; // If true, write full memory dump - // during crash. - static bool show_error_dialogs_; // If true, a user is paying attention - // to the test, so show error dialogs. - static bool dump_histograms_on_exit_; // Include histograms in log on exit. - static bool enable_dcheck_; // Enable dchecks in release mode. - static bool silent_dump_on_dcheck_; // Dump process memory on dcheck without - // crashing. - static bool disable_breakpad_; // Disable breakpad on the browser. - static int timeout_ms_; // Timeout in milliseconds to wait - // for an test to finish. - static std::string js_flags_; // Flags passed to the JS engine. - static std::string log_level_; // Logging level. - - scoped_ptr<AutomationProxy> automation_proxy_; - - std::string ui_test_name_; - - // We use a temporary directory for profile to avoid issues with being - // unable to delete some files because they're in use, etc. - scoped_ptr<ScopedTempDir> temp_profile_dir_; + // Time the test was started (so we can check for new crash dumps) + base::Time test_start_time_; }; class UITest : public UITestBase, public PlatformTest { @@ -532,34 +457,34 @@ class UITest : public UITestBase, public PlatformTest { // following conditions hold true: // - The JavaScript condition evaluates to true (return true). // - The browser process died (return false). - // - The time_out value has been exceeded (return false). + // - The timeout value has been exceeded (return false). // // The JavaScript expression is executed in the context of the frame that // matches the provided xpath. bool WaitUntilJavaScriptCondition(TabProxy* tab, const std::wstring& frame_xpath, const std::wstring& jscript, - int time_out_ms); + int timeout_ms); // Polls the tab for the cookie_name cookie and returns once one of the // following conditions hold true: // - The cookie is of expected_value. // - The browser process died. - // - The time_out value has been exceeded. + // - The timeout value has been exceeded. bool WaitUntilCookieValue(TabProxy* tab, const GURL& url, const char* cookie_name, - int time_out_ms, + int timeout_ms, const char* expected_value); // Polls the tab for the cookie_name cookie and returns once one of the // following conditions hold true: // - The cookie is set to any value. // - The browser process died. - // - The time_out value has been exceeded. + // - The timeout value has been exceeded. std::string WaitUntilCookieNonEmpty(TabProxy* tab, const GURL& url, const char* cookie_name, - int time_out_ms); + int timeout_ms); // Checks whether the download shelf is visible in the current browser, giving // it a chance to appear (we don't know the exact timing) while finishing as diff --git a/chrome/test/ui/ui_test_suite.cc b/chrome/test/ui/ui_test_suite.cc index 9e0f39a..bde938c 100644 --- a/chrome/test/ui/ui_test_suite.cc +++ b/chrome/test/ui/ui_test_suite.cc @@ -31,21 +31,21 @@ void UITestSuite::Initialize() { ChromeTestSuite::Initialize(); const CommandLine& parsed_command_line = *CommandLine::ForCurrentProcess(); - UITest::set_in_process_renderer( + ProxyLauncher::set_in_process_renderer( parsed_command_line.HasSwitch(switches::kSingleProcess)); - UITest::set_no_sandbox( + ProxyLauncher::set_no_sandbox( parsed_command_line.HasSwitch(switches::kNoSandbox)); - UITest::set_full_memory_dump( + ProxyLauncher::set_full_memory_dump( parsed_command_line.HasSwitch(switches::kFullMemoryCrashReport)); - UITest::set_safe_plugins( + ProxyLauncher::set_safe_plugins( parsed_command_line.HasSwitch(switches::kSafePlugins)); - UITest::set_dump_histograms_on_exit( + ProxyLauncher::set_dump_histograms_on_exit( parsed_command_line.HasSwitch(switches::kDumpHistogramsOnExit)); - UITest::set_enable_dcheck( + ProxyLauncher::set_enable_dcheck( parsed_command_line.HasSwitch(switches::kEnableDCHECK)); - UITest::set_silent_dump_on_dcheck( + ProxyLauncher::set_silent_dump_on_dcheck( parsed_command_line.HasSwitch(switches::kSilentDumpOnDCHECK)); - UITest::set_disable_breakpad( + ProxyLauncher::set_disable_breakpad( parsed_command_line.HasSwitch(switches::kDisableBreakpad)); #if defined(OS_WIN) @@ -78,11 +78,11 @@ void UITestSuite::Initialize() { std::string js_flags = parsed_command_line.GetSwitchValueASCII(switches::kJavaScriptFlags); if (!js_flags.empty()) - UITest::set_js_flags(js_flags); + ProxyLauncher::set_js_flags(js_flags); std::string log_level = parsed_command_line.GetSwitchValueASCII(switches::kLoggingLevel); if (!log_level.empty()) - UITest::set_log_level(log_level); + ProxyLauncher::set_log_level(log_level); #if defined(OS_WIN) LoadCrashService(); @@ -100,7 +100,7 @@ void UITestSuite::Shutdown() { void UITestSuite::SuppressErrorDialogs() { TestSuite::SuppressErrorDialogs(); - UITest::set_show_error_dialogs(false); + ProxyLauncher::set_show_error_dialogs(false); } #if defined(OS_WIN) diff --git a/chrome/worker/worker_uitest.cc b/chrome/worker/worker_uitest.cc index 3babc78..3edd294 100644 --- a/chrome/worker/worker_uitest.cc +++ b/chrome/worker/worker_uitest.cc @@ -84,7 +84,7 @@ class WorkerTest : public UILayoutTest { bool WaitForProcessCountToBe(int tabs, int workers) { // The 1 is for the browser process. int number_of_processes = 1 + workers + - (UITest::in_process_renderer() ? 0 : tabs); + (ProxyLauncher::in_process_renderer() ? 0 : tabs); #if defined(OS_LINUX) // On Linux, we also have a zygote process and a sandbox host process. number_of_processes += 2; |