1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef CHROME_TEST_AUTOMATION_PROXY_LAUNCHER_H_ 6 #define CHROME_TEST_AUTOMATION_PROXY_LAUNCHER_H_ 7 8 #include <string> 9 10 #include "base/basictypes.h" 11 #include "base/callback.h" 12 #include "base/command_line.h" 13 #include "base/compiler_specific.h" 14 #include "base/files/scoped_temp_dir.h" 15 #include "base/memory/scoped_ptr.h" 16 #include "base/process/process.h" 17 #include "base/time/time.h" 18 19 class AutomationProxy; 20 21 // Base class for all ProxyLauncher implementations. Contains functionality 22 // fo launching, terminating, and connecting tests to browser processes. This 23 // class determines which AutomationProxy implementation is used by a test. 24 // Command line arguments passed to the browser are set in this class. 25 // 26 // Subclass from this class to use a different AutomationProxy 27 // implementation or to override browser launching behavior. 28 class ProxyLauncher { 29 public: 30 // Default ID for named testing interface. 31 static const char kDefaultInterfaceId[]; 32 33 // Different ways to quit the browser. 34 enum ShutdownType { 35 WINDOW_CLOSE, 36 USER_QUIT, 37 SESSION_ENDING, 38 }; 39 40 // POD containing state variables that determine how to launch browser. 41 struct LaunchState { 42 // If true the profile is cleared before launching. 43 bool clear_profile; 44 45 // If set, the profiles in this path are copied 46 // into the user data directory for the test. 47 base::FilePath template_user_data; 48 49 // Called just before starting the browser to allow any setup of the 50 // profile for the run time environment. 51 base::Closure setup_profile_callback; 52 53 // Command line to launch the browser. 54 CommandLine command; 55 56 // Should we supply the testing channel id on the command line? 57 bool include_testing_id; 58 59 // If true, the window is shown. Otherwise it is hidden. 60 bool show_window; 61 }; 62 63 ProxyLauncher(); 64 65 virtual ~ProxyLauncher(); 66 67 // Launches the browser if needed and establishes a connection with it. 68 // Returns true on success. 69 virtual bool InitializeConnection( 70 const LaunchState& state, 71 bool wait_for_initial_loads) WARN_UNUSED_RESULT = 0; 72 73 // Shuts down the browser if needed and destroys any 74 // connections established by InitalizeConnection. 75 virtual void TerminateConnection() = 0; 76 77 // Launches the browser and IPC testing connection in server mode. 78 // Returns true on success. 79 bool LaunchBrowserAndServer(const LaunchState& state, 80 bool wait_for_initial_loads) WARN_UNUSED_RESULT; 81 82 // Launches the IPC testing connection in client mode, 83 // which then attempts to connect to a browser. 84 // Returns true on success. 85 bool ConnectToRunningBrowser(bool wait_for_initial_loads) WARN_UNUSED_RESULT; 86 87 // Paired with LaunchBrowserAndServer(). 88 // Closes the browser and IPC testing server. 89 void CloseBrowserAndServer(); 90 91 // Launches the browser with the given command line. Returns true on success. 92 // TODO(phajdan.jr): Make LaunchBrowser private. 93 bool LaunchBrowser(const LaunchState& state) WARN_UNUSED_RESULT; 94 95 // Exits out of browser instance. 96 void QuitBrowser(); 97 98 // Terminates the browser, simulates end of session. 99 void TerminateBrowser(); 100 101 // Check that no processes related to Chrome exist, displaying 102 // the given message if any do. 103 void AssertAppNotRunning(const std::string& error_message); 104 105 // Wait for the browser process to shut down on its own (i.e. as a result of 106 // some action that your test has taken). If it has exited within |timeout|, 107 // puts the exit code in |exit_code| and returns true. 108 bool WaitForBrowserProcessToQuit(base::TimeDelta timeout, int* exit_code); 109 110 AutomationProxy* automation() const; 111 112 // Return the user data directory being used by the browser instance. 113 base::FilePath user_data_dir() const; 114 115 // Get the handle of browser process connected to the automation. This 116 // function only returns a reference to the handle so the caller does not 117 // own the handle returned. 118 base::ProcessHandle process() const; 119 120 // Return the process id of the browser process (-1 on error). 121 base::ProcessId process_id() const; 122 123 // Return the time when the browser was run. 124 base::TimeTicks browser_launch_time() const; 125 126 // Return how long the shutdown took. 127 base::TimeDelta browser_quit_time() const; 128 129 // Sets the shutdown type, which defaults to WINDOW_CLOSE. 130 void set_shutdown_type(ShutdownType value) { 131 shutdown_type_ = value; 132 } 133 134 protected: 135 // Creates an automation proxy. 136 virtual AutomationProxy* CreateAutomationProxy( 137 base::TimeDelta execution_timeout) = 0; 138 139 // Returns the automation proxy's channel with any prefixes prepended, 140 // for passing as a command line parameter over to the browser. 141 virtual std::string PrefixedChannelID() const = 0; 142 143 // Paired with ConnectToRunningBrowser(). 144 // Disconnects the testing IPC from the browser. 145 void DisconnectFromRunningBrowser(); 146 147 private: 148 bool WaitForBrowserLaunch(bool wait_for_initial_loads) WARN_UNUSED_RESULT; 149 150 // Prepare command line that will be used to launch the child browser process. 151 void PrepareTestCommandline(CommandLine* command_line, 152 bool include_testing_id); 153 154 bool LaunchBrowserHelper(const LaunchState& state, 155 bool main_launch, 156 bool wait, 157 base::ProcessHandle* process) WARN_UNUSED_RESULT; 158 159 scoped_ptr<AutomationProxy> automation_proxy_; 160 161 // We use a temporary directory for profile to avoid issues with being 162 // unable to delete some files because they're in use, etc. 163 base::ScopedTempDir temp_profile_dir_; 164 165 // Handle to the first Chrome process. 166 base::ProcessHandle process_; 167 168 // PID of |process_| (for debugging). 169 base::ProcessId process_id_; 170 171 // Time when the browser was run. 172 base::TimeTicks browser_launch_time_; 173 174 // How long the shutdown took. 175 base::TimeDelta browser_quit_time_; 176 177 // The method for shutting down the browser. Used in ShutdownTest. 178 ShutdownType shutdown_type_; 179 180 // If true, runs the renderer outside the sandbox. 181 bool no_sandbox_; 182 183 // If true, write full memory dump during crash. 184 bool full_memory_dump_; 185 186 // If true, a user is paying attention to the test, so show error dialogs. 187 bool show_error_dialogs_; 188 189 // Enable dchecks in release mode. 190 bool enable_dcheck_; 191 192 // Dump process memory on dcheck without crashing. 193 bool silent_dump_on_dcheck_; 194 195 // Disable breakpad on the browser. 196 bool disable_breakpad_; 197 198 // Flags passed to the JS engine. 199 std::string js_flags_; 200 201 // Logging level. 202 std::string log_level_; 203 204 DISALLOW_COPY_AND_ASSIGN(ProxyLauncher); 205 }; 206 207 // Uses an automation proxy that communicates over a named socket. 208 // This is used if you want to connect an AutomationProxy 209 // to a browser process that is already running. 210 // The channel id of the proxy is a constant specified by kInterfacePath. 211 class NamedProxyLauncher : public ProxyLauncher { 212 public: 213 // If launch_browser is true, launches Chrome with named interface enabled. 214 // Otherwise, there should be an existing instance the proxy can connect to. 215 NamedProxyLauncher(const std::string& channel_id, 216 bool launch_browser, bool disconnect_on_failure); 217 218 virtual AutomationProxy* CreateAutomationProxy( 219 base::TimeDelta execution_timeout); 220 virtual bool InitializeConnection( 221 const LaunchState& state, 222 bool wait_for_initial_loads) OVERRIDE WARN_UNUSED_RESULT; 223 virtual void TerminateConnection(); 224 virtual std::string PrefixedChannelID() const; 225 226 protected: 227 std::string channel_id_; // Channel id of automation proxy. 228 bool launch_browser_; // True if we should launch the browser too. 229 bool disconnect_on_failure_; // True if we disconnect on IPC channel failure. 230 231 private: 232 DISALLOW_COPY_AND_ASSIGN(NamedProxyLauncher); 233 }; 234 235 // Uses an automation proxy that communicates over an anonymous socket. 236 class AnonymousProxyLauncher : public ProxyLauncher { 237 public: 238 explicit AnonymousProxyLauncher(bool disconnect_on_failure); 239 virtual AutomationProxy* CreateAutomationProxy( 240 base::TimeDelta execution_timeout); 241 virtual bool InitializeConnection( 242 const LaunchState& state, 243 bool wait_for_initial_loads) OVERRIDE WARN_UNUSED_RESULT; 244 virtual void TerminateConnection(); 245 virtual std::string PrefixedChannelID() const; 246 247 protected: 248 std::string channel_id_; // Channel id of automation proxy. 249 bool disconnect_on_failure_; // True if we disconnect on IPC channel failure. 250 251 private: 252 DISALLOW_COPY_AND_ASSIGN(AnonymousProxyLauncher); 253 }; 254 255 #endif // CHROME_TEST_AUTOMATION_PROXY_LAUNCHER_H_ 256