Skip to content

Commit

Permalink
[chromedriver] Allow commands to be async. Run all commands on comman…
Browse files Browse the repository at this point in the history
…d thread.

This is in preparation for switching from mongoose to net::HttpServer.
BUG=none
[email protected]

Review URL: https://codereview.chromium.org/19977002

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@213200 0039d316-1c4b-4281-b951-d872f2087c98
  • Loading branch information
[email protected] committed Jul 23, 2013
1 parent aa7f22f commit 4c5658b
Show file tree
Hide file tree
Showing 24 changed files with 989 additions and 930 deletions.
41 changes: 25 additions & 16 deletions README.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@ contribute.
ChromeDriver is an implementation of the WebDriver standard,
which allows users to automate testing of their website across browsers.

See the user site at http://code.google.com/p/chromedriver.

=====Getting started=====
Build ChromeDriver by building the 'chromedriver2_server' target. This will
create an executable binary in the build folder named 'chromedriver2_server.exe'
on Windows or 'chromedriver2_server' on Mac and Linux.
create an executable binary in the build folder named
'chromedriver2_server[.exe]'.

Once built, ChromeDriver can be used interactively with python.

Expand All @@ -31,26 +33,30 @@ more detailed instructions see the wiki:

=====Architecture=====
ChromeDriver is shipped separately from Chrome. It controls Chrome out of
process through DevTools (WebKit Inspector). ChromeDriver is a standalone server
executable which communicates via the WebDriver JSON wire protocol. This can be
used with the open source WebDriver client libraries.

When a new session is created, a new thread is started that is dedicated to the
session. All commands for the session runs on this thread. This thread is
stopped when the session is deleted. Besides, there is an IO thread and it is
used to keep reading incoming data from Chrome in the background.
process through DevTools. ChromeDriver is a standalone server which
communicates with the WebDriver client via the WebDriver wire protocol, which
is essentially synchronous JSON commands over HTTP. WebDriver clients are
available in many languages, and many are available from the open source
selenium/webdriver project: http://code.google.com/p/selenium.

ChromeDriver has several threads. The webserver code, third_party/mongoose,
spawns a thread for the server socket and a certain amount of request handling
threads. When a request is received, the command is processed on the message
loop of the main thread, also called the command thread. Commands may be handled
asynchronously on the command thread, but the request handler threads
will block waiting for the response. One of the commands allows the user to
create a session, which includes spawning a dedicated session thread. Session
commands will be dispatched to the session thread and handled synchronously
there. Lastly, there is an IO/net thread on which the net/ code operates.
This is used to keep reading incoming data from Chrome in the background.

=====Code structure=====
Code under the 'chrome' subdirectory is intended to be unaware of WebDriver and
serve as a basic C++ interface for controlling Chrome remotely via DevTools.
As such, it should not have any WebDriver-related dependencies.

1) chrome/test/chromedriver
Implements chromedriver commands.

2) chrome/test/chromedriver/chrome
Code to deal with chrome specific stuff, like starting Chrome on different OS
platforms, controlling Chrome via DevTools, handling events from DevTools, etc.
A basic interface for controlling Chrome via DevTools. Should not have
knowledge about WebDriver, and thus not depend on chrome/test/chromedriver.

3) chrome/test/chromedriver/js
Javascript helper scripts.
Expand All @@ -71,6 +77,9 @@ An extension used for automating the desktop browser.
8) chrome/test/chromedriver/third_party
Third party libraries used by chromedriver.

9) third_party/mongoose
The webserver for chromedriver.

=====Testing=====
There are 4 test suites for verifying ChromeDriver's correctness:

Expand Down
1 change: 1 addition & 0 deletions alert_commands.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

#include "chrome/test/chromedriver/alert_commands.h"

#include "base/callback.h"
#include "base/values.h"
#include "chrome/test/chromedriver/chrome/chrome.h"
#include "chrome/test/chromedriver/chrome/devtools_client.h"
Expand Down
10 changes: 5 additions & 5 deletions chrome/adb_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
#include "base/logging.h"
#include "base/memory/ref_counted.h"
#include "base/message_loop/message_loop.h"
#include "base/message_loop/message_loop_proxy.h"
#include "base/single_thread_task_runner.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_split.h"
#include "base/strings/string_tokenizer.h"
Expand Down Expand Up @@ -71,10 +71,10 @@ void ExecuteCommandOnIOThread(
} // namespace

AdbImpl::AdbImpl(
const scoped_refptr<base::MessageLoopProxy>& io_message_loop_proxy,
const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner,
Log* log)
: io_message_loop_proxy_(io_message_loop_proxy), log_(log) {
CHECK(io_message_loop_proxy_.get());
: io_task_runner_(io_task_runner), log_(log) {
CHECK(io_task_runner_.get());
}

AdbImpl::~AdbImpl() {}
Expand Down Expand Up @@ -185,7 +185,7 @@ Status AdbImpl::ExecuteCommand(
const std::string& command, std::string* response) {
scoped_refptr<ResponseBuffer> response_buffer = new ResponseBuffer;
log_->AddEntry(Log::kDebug, "Sending adb command: " + command);
io_message_loop_proxy_->PostTask(
io_task_runner_->PostTask(
FROM_HERE,
base::Bind(&ExecuteCommandOnIOThread, command, response_buffer));
Status status = response_buffer->GetResponse(
Expand Down
6 changes: 3 additions & 3 deletions chrome/adb_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
#include "chrome/test/chromedriver/chrome/adb.h"

namespace base {
class MessageLoopProxy;
class SingleThreadTaskRunner;
}

class Log;
Expand All @@ -22,7 +22,7 @@ class Status;
class AdbImpl : public Adb {
public:
explicit AdbImpl(
const scoped_refptr<base::MessageLoopProxy>& io_message_loop_proxy,
const scoped_refptr<base::SingleThreadTaskRunner>& io_message_loop_proxy,
Log* log);
virtual ~AdbImpl();

Expand Down Expand Up @@ -53,7 +53,7 @@ class AdbImpl : public Adb {
const std::string& shell_command,
std::string* response);

scoped_refptr<base::MessageLoopProxy> io_message_loop_proxy_;
scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_;

Log* log_;
};
Expand Down
10 changes: 7 additions & 3 deletions command.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,14 @@ class Value;

class Status;

typedef base::Callback<Status(
typedef base::Callback<void(
const Status&,
scoped_ptr<base::Value>,
const std::string&)> CommandCallback;

typedef base::Callback<void(
const base::DictionaryValue&,
const std::string&,
scoped_ptr<base::Value>*,
std::string*)> Command;
const CommandCallback&)> Command;

#endif // CHROME_TEST_CHROMEDRIVER_COMMAND_H_
Loading

0 comments on commit 4c5658b

Please sign in to comment.