summaryrefslogtreecommitdiffstats
path: root/chrome/test/webdriver/server.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/test/webdriver/server.cc')
-rw-r--r--chrome/test/webdriver/server.cc84
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);
}
-