diff options
Diffstat (limited to 'chrome/test/webdriver/server.cc')
-rw-r--r-- | chrome/test/webdriver/server.cc | 84 |
1 files changed, 70 insertions, 14 deletions
diff --git a/chrome/test/webdriver/server.cc b/chrome/test/webdriver/server.cc index 6409524..2994477 100644 --- a/chrome/test/webdriver/server.cc +++ b/chrome/test/webdriver/server.cc @@ -17,11 +17,15 @@ #include "base/at_exit.h" #include "base/command_line.h" #include "base/logging.h" +#include "base/string_number_conversions.h" #include "base/scoped_ptr.h" +#include "base/string_split.h" #include "base/string_util.h" +#include "base/synchronization/waitable_event.h" +#include "base/test/test_timeouts.h" #include "base/threading/platform_thread.h" #include "base/utf_string_conversions.h" - +#include "chrome/common/chrome_paths.h" #include "chrome/test/webdriver/dispatch.h" #include "chrome/test/webdriver/session_manager.h" #include "chrome/test/webdriver/utility_functions.h" @@ -55,12 +59,25 @@ signal_handler(int sig_num) { } namespace webdriver { + +void Shutdown(struct mg_connection* connection, + const struct mg_request_info* request_info, + void* user_data) { + base::WaitableEvent* shutdown_event = + reinterpret_cast<base::WaitableEvent*>(user_data); + mg_printf(connection, "HTTP/1.1 200 OK\r\n\r\n"); + shutdown_event->Signal(); +} + template <typename CommandType> void SetCallback(struct mg_context* ctx, const char* pattern) { mg_set_uri_callback(ctx, pattern, &Dispatch<CommandType>, NULL); } -void InitCallbacks(struct mg_context* ctx) { +void InitCallbacks(struct mg_context* ctx, + base::WaitableEvent* shutdown_event) { + mg_set_uri_callback(ctx, "/shutdown", &Shutdown, shutdown_event); + SetCallback<CreateSession>(ctx, "/session"); SetCallback<BackCommand>(ctx, "/session/*/back"); SetCallback<ExecuteCommand>(ctx, "/session/*/execute"); @@ -72,7 +89,7 @@ void InitCallbacks(struct mg_context* ctx) { SetCallback<SpeedCommand>(ctx, "/session/*/speed"); // WebElement commands - SetCallback<ImplicitWaitCommand>(ctx, "/session/*/timeouts/implicit_wait"); + SetCallback<ImplicitWaitCommand>(ctx, "/session/*/timeouts/implicit_wait"); SetCallback<FindOneElementCommand>(ctx, "/session/*/element"); SetCallback<FindManyElementsCommand>(ctx, "/session/*/elements"); SetCallback<FindOneElementCommand>(ctx, "/session/*/element/*/element"); @@ -84,13 +101,32 @@ void InitCallbacks(struct mg_context* ctx) { } } // namespace webdriver +// Configures mongoose according to the given command line flags. +// Returns true on success. +bool SetMongooseOptions(struct mg_context* ctx, + const std::string& port, + const std::string& root) { + if (!mg_set_option(ctx, "ports", port.c_str())) { + std::cout << "ChromeDriver cannot bind to port (" + << port.c_str() << ")" << std::endl; + return false; + } + if (root.length()) + mg_set_option(ctx, "root", root.c_str()); + // Lower the default idle time to 1 second. Idle time refers to how long a + // worker thread will wait for new connections before exiting. + // This is so mongoose quits in a reasonable amount of time. + mg_set_option(ctx, "idle_time", "1"); + return true; +} + // Sets up and runs the Mongoose HTTP server for the JSON over HTTP // protcol of webdriver. The spec is located at: // http://code.google.com/p/selenium/wiki/JsonWireProtocol. int main(int argc, char *argv[]) { struct mg_context *ctx; base::AtExitManager exit; - std::string port = "9515"; + base::WaitableEvent shutdown_event(false, false); #ifdef OS_POSIX CommandLine cmd_line = CommandLine(argc, argv); #elif OS_WIN @@ -111,9 +147,20 @@ int main(int argc, char *argv[]) { #endif srand((unsigned int)time(NULL)); - if (cmd_line.HasSwitch(std::string("port"))) { - port = cmd_line.GetSwitchValueASCII(std::string("port")); - } + // Register Chrome's path provider so that the AutomationProxy will find our + // built Chrome. + chrome::RegisterPathProvider(); + TestTimeouts::Initialize(); + + // Parse command line flags. + std::string port = "9515"; + std::string root; + if (cmd_line.HasSwitch("port")) + port = cmd_line.GetSwitchValueASCII("port"); + // By default, mongoose serves files from the current working directory. The + // 'root' flag allows the user to specify a different location to serve from. + if (cmd_line.HasSwitch("root")) + root = cmd_line.GetSwitchValueASCII("root"); VLOG(1) << "Using port: " << port; webdriver::SessionManager* session = webdriver::SessionManager::GetInstance(); @@ -123,14 +170,24 @@ int main(int argc, char *argv[]) { // Listen on port 9515 or port specified on command line. // TODO(jmikhail) Maybe add port 9516 as a secure connection. ctx = mg_start(); - mg_set_option(ctx, "ports", port.c_str()); + if (!SetMongooseOptions(ctx, port, root)) { + mg_stop(ctx); + return 1; + } - webdriver::InitCallbacks(ctx); + webdriver::InitCallbacks(ctx, &shutdown_event); - std::cout << "Starting server on port: " << port << std::endl; - // The default behavior is to run this service forever. - while (true) - base::PlatformThread::Sleep(3600); + // The tests depend on parsing the first line ChromeDriver outputs, + // so all other logging should happen after this. + std::cout << "Started ChromeDriver" << std::endl + << "port=" << port << std::endl; + + if (root.length()) { + VLOG(1) << "Serving files from the current working directory"; + } + + // Run until we receive command to shutdown. + shutdown_event.Wait(); // We should not reach here since the service should never quit. // TODO(jmikhail): register a listener for SIGTERM and break the @@ -138,4 +195,3 @@ int main(int argc, char *argv[]) { mg_stop(ctx); return (EXIT_SUCCESS); } - |