Commit 930cc098 authored by Antonio Gomes's avatar Antonio Gomes Committed by Commit Bot

Reland "Migrate chrome/test/chromedriver/net/net_util.cc using SimpleURLLoader"

This is a reland of c7e36b09

The difference between this CL and its original version
(https://crrev.com/c/c1289849) is that dependencies are made
more explicit in chrome/test/chromedriver/BUILD.gn.

TBR=mmenke@chromium.org,johnchen@chromium.org (John +1'ed the original incarnation of this CL at [1]).

Original change's description:
> Migrate chrome/test/chromedriver/net/net_util.cc using SimpleURLLoader
>
> URLFetcher will stop working with advent of Network Service, and
> SimpleURLLoader is the replacement API for most clients.
> This CL migrates chromedriver and its respective unittests away from
> URLFetcher.
>
> Note that because of the multithreaded nature of the code, the natural
> approach was to simply call SharedURLLoaderFactory::Clone and pass
> the "info" mojo handle accross threads, until the operational thread.
> However, the structure holding this mojo handle is called/passed from
>
>   (i) an indirect chain of BindRepeating calls,
>   (ii) various threads.
>
> Given that network::mojom::URLLoaderFactoryPtrInfo and
> network::SharedURLLoaderFactoryInfo are both move-only object
> (which does not comply with BingRepeating) and that raw
> a network::SharedURLoaderLoader instance must operate on the same
> thread it was created on, this CL comes up with a local thread-agnostic
> "wrapper" to mojom::URLLoaderFactory, named WrapperURLLoaderFactory
> (see chrome/test/chromedriver/server/http_handler.cc).
> Its instance replaces URLRequestContextGetter instead across threads
> and BindRepeating chains just fine.
>
> This CL is based on the original work of Sergio Villar (svillar@igalia.com)
> on [1].
>
> TBR=johnchen@chromium.org (John +1'ed the original incarnation of this CL at [1]).
>
> [1] https://crrev.com/c/1221256
>
> Bug: 872887
>
> Change-Id: I21386edb04b25438ba3aa40dd5ecc1461342aecf
> Reviewed-on: https://chromium-review.googlesource.com/c/1289849
> Commit-Queue: Antonio Gomes <tonikitoo@igalia.com>
> Reviewed-by: Matt Menke <mmenke@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#601422}

Bug: 872887
Change-Id: I645a34d28cfb92c15f2f2db409e0fe7cb7a5ac6b
Reviewed-on: https://chromium-review.googlesource.com/c/1292933Reviewed-by: default avatarAntonio Gomes <tonikitoo@igalia.com>
Commit-Queue: Antonio Gomes <tonikitoo@igalia.com>
Cr-Commit-Position: refs/heads/master@{#601478}
parent 9f97a015
......@@ -190,6 +190,8 @@ source_set("automation_client_lib") {
"//base",
"//base/third_party/dynamic_annotations",
"//net",
"//services/network/public/cpp",
"//services/network/public/mojom",
"//third_party/blink/public:buildflags",
"//third_party/zlib:minizip",
"//third_party/zlib/google:zip",
......@@ -303,6 +305,9 @@ source_set("lib") {
"//crypto",
"//net",
"//net/server:http_server",
"//services/network:network_service",
"//services/network/public/cpp",
"//services/network/public/mojom",
"//third_party/zlib",
"//ui/base",
"//ui/events:dom_keycode_converter",
......@@ -333,6 +338,8 @@ executable("chromedriver") {
deps = [
":lib",
"//build/win:default_exe_manifest",
"//mojo/core/embedder",
"//services/network/public/mojom",
]
}
......@@ -430,6 +437,7 @@ test("chromedriver_unittests") {
"//net",
"//net:test_support",
"//net/server:http_server",
"//services/network/public/mojom",
"//testing/gmock",
"//testing/gtest",
"//ui/base",
......@@ -458,9 +466,12 @@ test("chromedriver_tests") {
":lib",
"//base",
"//base/test:run_all_unittests",
"//mojo/core/embedder",
"//net",
"//net:test_support",
"//net/server:http_server",
"//services/network/public/cpp",
"//services/network/public/mojom",
"//testing/gtest",
"//ui/events:test_support",
"//url",
......
......@@ -21,7 +21,7 @@
#include "chrome/test/chromedriver/chrome/status.h"
#include "chrome/test/chromedriver/chrome/web_view_impl.h"
#include "chrome/test/chromedriver/net/net_util.h"
#include "chrome/test/chromedriver/net/url_request_context_getter.h"
#include "services/network/public/mojom/url_loader_factory.mojom.h"
WebViewInfo::WebViewInfo(const std::string& id,
const std::string& debugger_url,
......@@ -67,12 +67,12 @@ const WebViewInfo* WebViewsInfo::GetForId(const std::string& id) const {
DevToolsHttpClient::DevToolsHttpClient(
const NetAddress& address,
scoped_refptr<URLRequestContextGetter> context_getter,
network::mojom::URLLoaderFactory* factory,
const SyncWebSocketFactory& socket_factory,
std::unique_ptr<DeviceMetrics> device_metrics,
std::unique_ptr<std::set<WebViewInfo::Type>> window_types,
std::string page_load_strategy)
: context_getter_(context_getter),
: url_loader_factory_(factory),
socket_factory_(socket_factory),
server_url_("http://" + address.ToString()),
web_socket_url_prefix_(base::StringPrintf("ws://%s/devtools/page/",
......@@ -92,8 +92,7 @@ Status DevToolsHttpClient::Init(const base::TimeDelta& timeout) {
std::string version_url = server_url_ + "/json/version";
std::string data;
while (!FetchUrlAndLog(version_url, context_getter_.get(), &data)
|| data.empty()) {
while (!FetchUrlAndLog(version_url, &data) || data.empty()) {
if (base::TimeTicks::Now() > deadline)
return Status(kChromeNotReachable);
base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(50));
......@@ -104,7 +103,7 @@ Status DevToolsHttpClient::Init(const base::TimeDelta& timeout) {
Status DevToolsHttpClient::GetWebViewsInfo(WebViewsInfo* views_info) {
std::string data;
if (!FetchUrlAndLog(server_url_ + "/json", context_getter_.get(), &data))
if (!FetchUrlAndLog(server_url_ + "/json", &data))
return Status(kChromeNotReachable);
return internal::ParseWebViewsInfo(data, views_info);
......@@ -120,8 +119,7 @@ std::unique_ptr<DevToolsClient> DevToolsHttpClient::CreateClient(
Status DevToolsHttpClient::CloseWebView(const std::string& id) {
std::string data;
if (!FetchUrlAndLog(
server_url_ + "/json/close/" + id, context_getter_.get(), &data)) {
if (!FetchUrlAndLog(server_url_ + "/json/close/" + id, &data)) {
return Status(kOk); // Closing the last web view leads chrome to quit.
}
......@@ -144,8 +142,7 @@ Status DevToolsHttpClient::CloseWebView(const std::string& id) {
Status DevToolsHttpClient::ActivateWebView(const std::string& id) {
std::string data;
if (!FetchUrlAndLog(
server_url_ + "/json/activate/" + id, context_getter_.get(), &data))
if (!FetchUrlAndLog(server_url_ + "/json/activate/" + id, &data))
return Status(kUnknownError, "cannot activate web view");
return Status(kOk);
}
......@@ -239,10 +236,9 @@ Status DevToolsHttpClient::CloseFrontends(const std::string& for_client_id) {
}
bool DevToolsHttpClient::FetchUrlAndLog(const std::string& url,
URLRequestContextGetter* getter,
std::string* response) {
VLOG(1) << "DevTools HTTP Request: " << url;
bool ok = FetchUrl(url, getter, response);
bool ok = FetchUrl(url, url_loader_factory_, response);
if (ok) {
VLOG(1) << "DevTools HTTP Response: " << *response;
} else {
......
......@@ -21,11 +21,16 @@ namespace base {
class TimeDelta;
}
namespace network {
namespace mojom {
class URLLoaderFactory;
}
} // namespace network
struct DeviceMetrics;
class DevToolsClient;
class NetAddress;
class Status;
class URLRequestContextGetter;
struct WebViewInfo {
enum Type {
......@@ -75,7 +80,7 @@ class WebViewsInfo {
class DevToolsHttpClient {
public:
DevToolsHttpClient(const NetAddress& address,
scoped_refptr<URLRequestContextGetter> context_getter,
network::mojom::URLLoaderFactory* factory,
const SyncWebSocketFactory& socket_factory,
std::unique_ptr<DeviceMetrics> device_metrics,
std::unique_ptr<std::set<WebViewInfo::Type>> window_types,
......@@ -98,11 +103,9 @@ class DevToolsHttpClient {
private:
Status CloseFrontends(const std::string& for_client_id);
virtual bool FetchUrlAndLog(const std::string& url,
URLRequestContextGetter* getter,
std::string* response);
virtual bool FetchUrlAndLog(const std::string& url, std::string* response);
scoped_refptr<URLRequestContextGetter> context_getter_;
network::mojom::URLLoaderFactory* url_loader_factory_;
SyncWebSocketFactory socket_factory_;
std::string server_url_;
std::string web_socket_url_prefix_;
......
......@@ -51,9 +51,9 @@
#include "chrome/test/chromedriver/log_replay/chrome_replay_impl.h"
#include "chrome/test/chromedriver/log_replay/replay_http_client.h"
#include "chrome/test/chromedriver/net/net_util.h"
#include "chrome/test/chromedriver/net/url_request_context_getter.h"
#include "crypto/rsa_private_key.h"
#include "crypto/sha2.h"
#include "services/network/public/mojom/url_loader_factory.mojom.h"
#include "third_party/zlib/google/zip.h"
#include "url/gurl.h"
......@@ -197,7 +197,7 @@ Status PrepareDesktopCommandLine(const Capabilities& capabilities,
Status WaitForDevToolsAndCheckVersion(
const NetAddress& address,
URLRequestContextGetter* context_getter,
network::mojom::URLLoaderFactory* factory,
const SyncWebSocketFactory& socket_factory,
const Capabilities* capabilities,
int wait_time,
......@@ -221,12 +221,12 @@ Status WaitForDevToolsAndCheckVersion(
cmd_line->GetSwitchValueNative("devtools-replay");
base::FilePath log_file_path(log_path);
client.reset(
new ReplayHttpClient(address, context_getter, socket_factory,
new ReplayHttpClient(address, factory, socket_factory,
std::move(device_metrics), std::move(window_types),
capabilities->page_load_strategy, log_file_path));
} else {
client.reset(new DevToolsHttpClient(
address, context_getter, socket_factory, std::move(device_metrics),
address, factory, socket_factory, std::move(device_metrics),
std::move(window_types), capabilities->page_load_strategy));
}
......@@ -306,7 +306,7 @@ Status CreateBrowserwideDevToolsClientAndConnect(
}
Status LaunchRemoteChromeSession(
URLRequestContextGetter* context_getter,
network::mojom::URLLoaderFactory* factory,
const SyncWebSocketFactory& socket_factory,
const Capabilities& capabilities,
std::vector<std::unique_ptr<DevToolsEventListener>>
......@@ -315,8 +315,8 @@ Status LaunchRemoteChromeSession(
Status status(kOk);
std::unique_ptr<DevToolsHttpClient> devtools_http_client;
status = WaitForDevToolsAndCheckVersion(
capabilities.debugger_address, context_getter, socket_factory,
&capabilities, 60, &devtools_http_client);
capabilities.debugger_address, factory, socket_factory, &capabilities, 60,
&devtools_http_client);
if (status.IsError()) {
return Status(kUnknownError, "cannot connect to chrome at " +
capabilities.debugger_address.ToString(),
......@@ -340,7 +340,7 @@ Status LaunchRemoteChromeSession(
return Status(kOk);
}
Status LaunchDesktopChrome(URLRequestContextGetter* context_getter,
Status LaunchDesktopChrome(network::mojom::URLLoaderFactory* factory,
const SyncWebSocketFactory& socket_factory,
const Capabilities& capabilities,
std::vector<std::unique_ptr<DevToolsEventListener>>
......@@ -451,8 +451,8 @@ Status LaunchDesktopChrome(URLRequestContextGetter* context_getter,
}
if (status.IsOk()) {
status = WaitForDevToolsAndCheckVersion(
NetAddress(devtools_port), context_getter, socket_factory,
&capabilities, 1, &devtools_http_client);
NetAddress(devtools_port), factory, socket_factory, &capabilities, 1,
&devtools_http_client);
}
if (status.IsOk()) {
break;
......@@ -534,7 +534,7 @@ Status LaunchDesktopChrome(URLRequestContextGetter* context_getter,
return Status(kOk);
}
Status LaunchAndroidChrome(URLRequestContextGetter* context_getter,
Status LaunchAndroidChrome(network::mojom::URLLoaderFactory* factory,
const SyncWebSocketFactory& socket_factory,
const Capabilities& capabilities,
std::vector<std::unique_ptr<DevToolsEventListener>>
......@@ -571,9 +571,9 @@ Status LaunchAndroidChrome(URLRequestContextGetter* context_getter,
}
std::unique_ptr<DevToolsHttpClient> devtools_http_client;
status = WaitForDevToolsAndCheckVersion(
NetAddress(devtools_port), context_getter, socket_factory, &capabilities,
60, &devtools_http_client);
status = WaitForDevToolsAndCheckVersion(NetAddress(devtools_port), factory,
socket_factory, &capabilities, 60,
&devtools_http_client);
if (status.IsError()) {
device->TearDown();
return status;
......@@ -597,7 +597,7 @@ Status LaunchAndroidChrome(URLRequestContextGetter* context_getter,
return Status(kOk);
}
Status LaunchReplayChrome(URLRequestContextGetter* context_getter,
Status LaunchReplayChrome(network::mojom::URLLoaderFactory* factory,
const SyncWebSocketFactory& socket_factory,
const Capabilities& capabilities,
std::vector<std::unique_ptr<DevToolsEventListener>>
......@@ -625,9 +625,9 @@ Status LaunchReplayChrome(URLRequestContextGetter* context_getter,
#endif
std::unique_ptr<DevToolsHttpClient> devtools_http_client;
status = WaitForDevToolsAndCheckVersion(NetAddress(0), context_getter,
socket_factory, &capabilities, 1,
&devtools_http_client);
status =
WaitForDevToolsAndCheckVersion(NetAddress(0), factory, socket_factory,
&capabilities, 1, &devtools_http_client);
std::unique_ptr<DevToolsClient> devtools_websocket_client;
status = CreateBrowserwideDevToolsClientAndConnect(
......@@ -669,7 +669,7 @@ Status LaunchReplayChrome(URLRequestContextGetter* context_getter,
} // namespace
Status LaunchChrome(URLRequestContextGetter* context_getter,
Status LaunchChrome(network::mojom::URLLoaderFactory* factory,
const SyncWebSocketFactory& socket_factory,
DeviceManager* device_manager,
const Capabilities& capabilities,
......@@ -680,21 +680,21 @@ Status LaunchChrome(URLRequestContextGetter* context_getter,
if (capabilities.IsRemoteBrowser()) {
// TODO(johnchen): Clean up naming for ChromeDriver sessions created
// by connecting to an already-running Chrome at a given debuggerAddress.
return LaunchRemoteChromeSession(
context_getter, socket_factory, capabilities,
std::move(devtools_event_listeners), chrome);
return LaunchRemoteChromeSession(factory, socket_factory, capabilities,
std::move(devtools_event_listeners),
chrome);
}
const base::CommandLine* cmd_line = base::CommandLine::ForCurrentProcess();
if (capabilities.IsAndroid()) {
return LaunchAndroidChrome(context_getter, socket_factory, capabilities,
return LaunchAndroidChrome(factory, socket_factory, capabilities,
std::move(devtools_event_listeners),
device_manager, chrome);
} else if (cmd_line->HasSwitch("devtools-replay")) {
return LaunchReplayChrome(context_getter, socket_factory, capabilities,
return LaunchReplayChrome(factory, socket_factory, capabilities,
std::move(devtools_event_listeners), chrome,
w3c_compliant);
} else {
return LaunchDesktopChrome(context_getter, socket_factory, capabilities,
return LaunchDesktopChrome(factory, socket_factory, capabilities,
std::move(devtools_event_listeners), chrome,
w3c_compliant);
}
......
......@@ -22,12 +22,17 @@ class FilePath;
enum TerminationStatus;
}
namespace network {
namespace mojom {
class URLLoaderFactory;
}
} // namespace network
class Chrome;
class DeviceManager;
class Status;
class URLRequestContextGetter;
Status LaunchChrome(URLRequestContextGetter* context_getter,
Status LaunchChrome(network::mojom::URLLoaderFactory* factory,
const SyncWebSocketFactory& socket_factory,
DeviceManager* device_manager,
const Capabilities& capabilities,
......
......@@ -6,7 +6,7 @@
#include <utility>
#include "chrome/test/chromedriver/chrome/device_metrics.h"
#include "chrome/test/chromedriver/net/url_request_context_getter.h"
#include "services/network/public/mojom/url_loader_factory.mojom.h"
#include "url/gurl.h"
namespace {
......@@ -21,14 +21,14 @@ std::string UrlPath(const std::string& url) {
ReplayHttpClient::ReplayHttpClient(
const NetAddress& address,
scoped_refptr<URLRequestContextGetter> context_getter,
network::mojom::URLLoaderFactory* factory,
const SyncWebSocketFactory& socket_factory,
std::unique_ptr<DeviceMetrics> device_metrics,
std::unique_ptr<std::set<WebViewInfo::Type>> window_types,
std::string page_load_strategy,
const base::FilePath& log_path)
: DevToolsHttpClient(address,
context_getter,
factory,
socket_factory,
std::move(device_metrics),
std::move(window_types),
......@@ -37,7 +37,6 @@ ReplayHttpClient::ReplayHttpClient(
ReplayHttpClient::~ReplayHttpClient() {}
bool ReplayHttpClient::FetchUrlAndLog(const std::string& url,
URLRequestContextGetter* getter,
std::string* response) {
VLOG(1) << "DevTools HTTP Request: " << url;
std::string path_from_url = UrlPath(url);
......
......@@ -14,6 +14,12 @@
#include "chrome/test/chromedriver/log_replay/devtools_log_reader.h"
#include "chrome/test/chromedriver/net/sync_websocket_factory.h"
namespace network {
namespace mojom {
class URLLoaderFactory;
}
} // namespace network
// Subclass of DevToolsHttpClient that redirects communication
// that would happen with Chrome to a DevToolsLogReader (i.e. a ChromeDriver
// log file). This enables log replay of DevTools HTTP communication with
......@@ -22,7 +28,7 @@ class ReplayHttpClient : public DevToolsHttpClient {
public:
// Initializes a DevToolsLogReader with the given log file.
ReplayHttpClient(const NetAddress& address,
scoped_refptr<URLRequestContextGetter> context_getter,
network::mojom::URLLoaderFactory* factory,
const SyncWebSocketFactory& socket_factory,
std::unique_ptr<DeviceMetrics> device_metrics,
std::unique_ptr<std::set<WebViewInfo::Type>> window_types,
......@@ -38,7 +44,6 @@ class ReplayHttpClient : public DevToolsHttpClient {
// instead of actually sending an HTTP request it looks for the
// corresponding request in the log file and returns the response accordingly.
bool FetchUrlAndLog(const std::string& url,
URLRequestContextGetter* getter,
std::string* response) override;
};
......
......@@ -9,31 +9,34 @@
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/compiler_specific.h"
#include "base/sequenced_task_runner.h"
#include "base/strings/stringprintf.h"
#include "base/synchronization/waitable_event.h"
#include "chrome/test/chromedriver/net/url_request_context_getter.h"
#include "base/task/post_task.h"
#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
#include "net/url_request/url_fetcher.h"
#include "net/url_request/url_fetcher_delegate.h"
#include "services/network/public/cpp/simple_url_loader.h"
#include "services/network/public/mojom/url_loader_factory.mojom.h"
#include "url/gurl.h"
namespace {
class SyncUrlFetcher : public net::URLFetcherDelegate {
class SyncUrlFetcher {
public:
SyncUrlFetcher(const GURL& url,
URLRequestContextGetter* getter,
network::mojom::URLLoaderFactory* url_loader_factory,
std::string* response)
: url_(url),
getter_(getter),
url_loader_factory_(url_loader_factory),
network_task_runner_(
base::CreateSequencedTaskRunnerWithTraits({base::MayBlock()})),
response_(response),
event_(base::WaitableEvent::ResetPolicy::AUTOMATIC,
base::WaitableEvent::InitialState::NOT_SIGNALED) {}
~SyncUrlFetcher() override {}
~SyncUrlFetcher() {}
bool Fetch() {
getter_->GetNetworkTaskRunner()->PostTask(
network_task_runner_->PostTask(
FROM_HERE, base::BindOnce(&SyncUrlFetcher::FetchOnIOThread,
base::Unretained(this)));
event_.Wait();
......@@ -41,26 +44,36 @@ class SyncUrlFetcher : public net::URLFetcherDelegate {
}
void FetchOnIOThread() {
fetcher_ = net::URLFetcher::Create(url_, net::URLFetcher::GET, this,
TRAFFIC_ANNOTATION_FOR_TESTS);
fetcher_->SetRequestContext(getter_);
fetcher_->Start();
DCHECK(network_task_runner_->RunsTasksInCurrentSequence());
auto request = std::make_unique<network::ResourceRequest>();
request->url = url_;
loader_ = network::SimpleURLLoader::Create(std::move(request),
TRAFFIC_ANNOTATION_FOR_TESTS);
loader_->DownloadToStringOfUnboundedSizeUntilCrashAndDie(
url_loader_factory_, base::BindOnce(&SyncUrlFetcher::OnURLLoadComplete,
base::Unretained(this)));
}
void OnURLFetchComplete(const net::URLFetcher* source) override {
success_ = (source->GetResponseCode() == 200);
void OnURLLoadComplete(std::unique_ptr<std::string> response_body) {
int response_code = -1;
if (loader_->ResponseInfo() && loader_->ResponseInfo()->headers)
response_code = loader_->ResponseInfo()->headers->response_code();
success_ = response_code == 200 && response_body;
if (success_)
success_ = source->GetResponseAsString(response_);
fetcher_.reset(); // Destroy the fetcher on IO thread.
*response_ = std::move(*response_body);
loader_.reset();
event_.Signal();
}
private:
GURL url_;
URLRequestContextGetter* getter_;
network::mojom::URLLoaderFactory* url_loader_factory_;
const scoped_refptr<base::SequencedTaskRunner> network_task_runner_;
std::string* response_;
base::WaitableEvent event_;
std::unique_ptr<net::URLFetcher> fetcher_;
std::unique_ptr<network::SimpleURLLoader> loader_;
bool success_;
};
......@@ -92,7 +105,7 @@ int NetAddress::port() const {
}
bool FetchUrl(const std::string& url,
URLRequestContextGetter* getter,
network::mojom::URLLoaderFactory* factory,
std::string* response) {
return SyncUrlFetcher(GURL(url), getter, response).Fetch();
return SyncUrlFetcher(GURL(url), factory, response).Fetch();
}
......@@ -7,7 +7,11 @@
#include <string>
class URLRequestContextGetter;
namespace network {
namespace mojom {
class URLLoaderFactory;
}
} // namespace network
class NetAddress {
public:
......@@ -32,7 +36,7 @@ class NetAddress {
// Synchronously fetches data from a GET HTTP request to the given URL.
// Returns true if response is 200 OK and sets response body to |response|.
bool FetchUrl(const std::string& url,
URLRequestContextGetter* getter,
network::mojom::URLLoaderFactory* factory,
std::string* response);
#endif // CHROME_TEST_CHROMEDRIVER_NET_NET_UTIL_H_
......@@ -18,6 +18,7 @@
#include "base/test/scoped_task_environment.h"
#include "base/threading/thread.h"
#include "chrome/test/chromedriver/net/url_request_context_getter.h"
#include "mojo/core/embedder/embedder.h"
#include "net/base/ip_endpoint.h"
#include "net/base/net_errors.h"
#include "net/log/net_log_source.h"
......@@ -26,6 +27,8 @@
#include "net/socket/tcp_server_socket.h"
#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
#include "net/url_request/url_request_context_getter.h"
#include "services/network/public/cpp/shared_url_loader_factory.h"
#include "services/network/transitional_url_loader_factory_owner.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace {
......@@ -40,12 +43,19 @@ class FetchUrlTest : public testing::Test,
base::test::ScopedTaskEnvironment::MainThreadType::IO) {
base::Thread::Options options(base::MessageLoop::TYPE_IO, 0);
CHECK(io_thread_.StartWithOptions(options));
context_getter_ = new URLRequestContextGetter(io_thread_.task_runner());
scoped_refptr<URLRequestContextGetter> context_getter =
new URLRequestContextGetter(io_thread_.task_runner());
url_loader_factory_owner_ =
std::make_unique<network::TransitionalURLLoaderFactoryOwner>(
context_getter);
base::WaitableEvent event(base::WaitableEvent::ResetPolicy::AUTOMATIC,
base::WaitableEvent::InitialState::NOT_SIGNALED);
io_thread_.task_runner()->PostTask(
FROM_HERE, base::BindOnce(&FetchUrlTest::InitOnIO,
base::Unretained(this), &event));
mojo::core::Init();
event.Wait();
}
......@@ -95,6 +105,12 @@ class FetchUrlTest : public testing::Test,
}
}
bool DoFetchURL(const std::string& server_url, std::string* response) {
return FetchUrl(server_url,
url_loader_factory_owner_->GetURLLoaderFactory().get(),
response);
}
void OnWebSocketRequest(int connection_id,
const net::HttpServerRequestInfo& info) override {}
void OnWebSocketMessage(int connection_id, const std::string& data) override {
......@@ -111,7 +127,8 @@ class FetchUrlTest : public testing::Test,
base::Thread io_thread_;
ServerResponse response_;
std::unique_ptr<net::HttpServer> server_;
scoped_refptr<URLRequestContextGetter> context_getter_;
std::unique_ptr<network::TransitionalURLLoaderFactoryOwner>
url_loader_factory_owner_;
std::string server_url_;
base::test::ScopedTaskEnvironment scoped_task_environment_;
};
......@@ -120,27 +137,26 @@ class FetchUrlTest : public testing::Test,
TEST_F(FetchUrlTest, Http200) {
std::string response("stuff");
ASSERT_TRUE(FetchUrl(server_url_, context_getter_.get(), &response));
ASSERT_TRUE(DoFetchURL(server_url_, &response));
ASSERT_STREQ("hello", response.c_str());
}
TEST_F(FetchUrlTest, HttpNon200) {
response_ = kSend404;
std::string response("stuff");
ASSERT_FALSE(FetchUrl(server_url_, context_getter_.get(), &response));
ASSERT_FALSE(DoFetchURL(server_url_, &response));
ASSERT_STREQ("stuff", response.c_str());
}
TEST_F(FetchUrlTest, ConnectionClose) {
response_ = kClose;
std::string response("stuff");
ASSERT_FALSE(FetchUrl(server_url_, context_getter_.get(), &response));
ASSERT_FALSE(DoFetchURL(server_url_, &response));
ASSERT_STREQ("stuff", response.c_str());
}
TEST_F(FetchUrlTest, NoServer) {
std::string response("stuff");
ASSERT_FALSE(
FetchUrl("http://localhost:33333", context_getter_.get(), &response));
ASSERT_FALSE(DoFetchURL("http://localhost:33333", &response));
ASSERT_STREQ("stuff", response.c_str());
}
......@@ -38,6 +38,7 @@
#include "chrome/test/chromedriver/logging.h"
#include "chrome/test/chromedriver/server/http_handler.h"
#include "chrome/test/chromedriver/version.h"
#include "mojo/core/embedder/embedder.h"
#include "net/base/ip_address.h"
#include "net/base/ip_endpoint.h"
#include "net/base/net_errors.h"
......@@ -462,6 +463,8 @@ int main(int argc, char *argv[]) {
return 1;
}
mojo::core::Init();
base::TaskScheduler::CreateAndStartWithDefaultParams("ChromeDriver");
RunServer(port, allow_remote, whitelisted_ips, url_base, adb_port);
......
......@@ -35,6 +35,9 @@
#include "chrome/test/chromedriver/version.h"
#include "net/server/http_server_request_info.h"
#include "net/server/http_server_response_info.h"
#include "services/network/public/cpp/shared_url_loader_factory.h"
#include "services/network/public/mojom/url_loader_factory.mojom.h"
#include "services/network/transitional_url_loader_factory_owner.h"
#include "url/url_util.h"
#if defined(OS_MACOSX)
......@@ -49,6 +52,50 @@ const char kShutdownPath[] = "shutdown";
} // namespace
// WrapperURLLoaderFactory subclasses mojom::URLLoaderFactory as non-mojo, cross
// thread class. It basically posts ::CreateLoaderAndStart calls over to the UI
// thread, to call them on the real mojo object.
class WrapperURLLoaderFactory : public network::mojom::URLLoaderFactory {
public:
WrapperURLLoaderFactory(
scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory)
: url_loader_factory_(std::move(url_loader_factory)),
network_task_runner_(base::SequencedTaskRunnerHandle::Get()) {}
void CreateLoaderAndStart(network::mojom::URLLoaderRequest loader,
int32_t routing_id,
int32_t request_id,
uint32_t options,
const network::ResourceRequest& request,
network::mojom::URLLoaderClientPtr client,
const net::MutableNetworkTrafficAnnotationTag&
traffic_annotation) override {
if (network_task_runner_->RunsTasksInCurrentSequence()) {
url_loader_factory_->CreateLoaderAndStart(
std::move(loader), routing_id, request_id, options, request,
std::move(client), traffic_annotation);
} else {
network_task_runner_->PostTask(
FROM_HERE,
base::BindOnce(&WrapperURLLoaderFactory::CreateLoaderAndStart,
base::Unretained(this), std::move(loader), routing_id,
request_id, options, request, std::move(client),
traffic_annotation));
}
}
void Clone(network::mojom::URLLoaderFactoryRequest factory) override {
NOTIMPLEMENTED();
}
private:
scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory_;
// Runner for URLRequestContextGetter network thread.
scoped_refptr<base::SequencedTaskRunner> network_task_runner_;
DISALLOW_COPY_AND_ASSIGN(WrapperURLLoaderFactory);
};
CommandMapping::CommandMapping(HttpMethod method,
const std::string& path_pattern,
const Command& command)
......@@ -80,21 +127,26 @@ HttpHandler::HttpHandler(
socket_factory_ = CreateSyncWebSocketFactory(context_getter_.get());
adb_.reset(new AdbImpl(io_task_runner, adb_port));
device_manager_.reset(new DeviceManager(adb_.get()));
url_loader_factory_owner_ =
std::make_unique<network::TransitionalURLLoaderFactoryOwner>(
context_getter_.get());
wrapper_url_loader_factory_ = std::make_unique<WrapperURLLoaderFactory>(
url_loader_factory_owner_->GetURLLoaderFactory());
CommandMapping commands[] = {
//
// W3C standard endpoints
//
CommandMapping(kPost, internal::kNewSessionPathPattern,
base::BindRepeating(
&ExecuteCreateSession, &session_thread_map_,
WrapToCommand("InitSession",
base::BindRepeating(
&ExecuteInitSession,
InitSessionParams(
context_getter_, socket_factory_,
device_manager_.get()))))),
CommandMapping(
kPost, internal::kNewSessionPathPattern,
base::BindRepeating(
&ExecuteCreateSession, &session_thread_map_,
WrapToCommand("InitSession",
base::BindRepeating(
&ExecuteInitSession,
InitSessionParams(
wrapper_url_loader_factory_.get(),
socket_factory_, device_manager_.get()))))),
CommandMapping(kDelete, "session/:sessionId",
base::BindRepeating(
&ExecuteSessionCommand, &session_thread_map_, "Quit",
......
......@@ -34,9 +34,14 @@ class HttpServerRequestInfo;
class HttpServerResponseInfo;
}
namespace network {
class TransitionalURLLoaderFactoryOwner;
}
class Adb;
class DeviceManager;
class URLRequestContextGetter;
class WrapperURLLoaderFactory;
enum HttpMethod {
kGet,
......@@ -110,6 +115,9 @@ class HttpHandler {
std::string url_base_;
bool received_shutdown_;
scoped_refptr<URLRequestContextGetter> context_getter_;
std::unique_ptr<network::TransitionalURLLoaderFactoryOwner>
url_loader_factory_owner_;
std::unique_ptr<WrapperURLLoaderFactory> wrapper_url_loader_factory_;
SyncWebSocketFactory socket_factory_;
SessionThreadMap session_thread_map_;
std::unique_ptr<CommandMap> command_map_;
......
......@@ -34,10 +34,10 @@
#include "chrome/test/chromedriver/chrome_launcher.h"
#include "chrome/test/chromedriver/command_listener.h"
#include "chrome/test/chromedriver/logging.h"
#include "chrome/test/chromedriver/net/url_request_context_getter.h"
#include "chrome/test/chromedriver/session.h"
#include "chrome/test/chromedriver/util.h"
#include "chrome/test/chromedriver/version.h"
#include "services/network/public/mojom/url_loader_factory.mojom.h"
namespace {
......@@ -87,11 +87,10 @@ Status EvaluateScriptAndIgnoreResult(Session* session, std::string expression) {
} // namespace
InitSessionParams::InitSessionParams(
scoped_refptr<URLRequestContextGetter> context_getter,
const SyncWebSocketFactory& socket_factory,
DeviceManager* device_manager)
: context_getter(context_getter),
InitSessionParams::InitSessionParams(network::mojom::URLLoaderFactory* factory,
const SyncWebSocketFactory& socket_factory,
DeviceManager* device_manager)
: url_loader_factory(factory),
socket_factory(socket_factory),
device_manager(device_manager) {}
......@@ -267,10 +266,10 @@ Status InitSessionHelper(const InitSessionParams& bound_params,
session->command_listeners.swap(command_listeners);
status =
LaunchChrome(bound_params.context_getter.get(),
bound_params.socket_factory, bound_params.device_manager,
capabilities, std::move(devtools_event_listeners),
&session->chrome, session->w3c_compliant);
LaunchChrome(bound_params.url_loader_factory, bound_params.socket_factory,
bound_params.device_manager, capabilities,
std::move(devtools_event_listeners), &session->chrome,
session->w3c_compliant);
if (status.IsError())
return status;
......
......@@ -11,6 +11,7 @@
#include "base/callback_forward.h"
#include "chrome/test/chromedriver/command.h"
#include "chrome/test/chromedriver/net/sync_websocket_factory.h"
#include "services/network/public/mojom/url_loader_factory.mojom.h"
namespace base {
class DictionaryValue;
......@@ -20,16 +21,15 @@ class Value;
class DeviceManager;
struct Session;
class Status;
class URLRequestContextGetter;
struct InitSessionParams {
InitSessionParams(scoped_refptr<URLRequestContextGetter> context_getter,
InitSessionParams(network::mojom::URLLoaderFactory* factory,
const SyncWebSocketFactory& socket_factory,
DeviceManager* device_manager);
InitSessionParams(const InitSessionParams& other);
~InitSessionParams();
scoped_refptr<URLRequestContextGetter> context_getter;
network::mojom::URLLoaderFactory* url_loader_factory;
SyncWebSocketFactory socket_factory;
DeviceManager* device_manager;
};
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment