Commit 85765d50 authored by Lily Houghton's avatar Lily Houghton Committed by Commit Bot

Convert Chromedriver tests to use the HttpServer class from the network service.

This refactors the chromedriver unit tests, particularly those in net_util_unittest,
sync_websocket_unittest, and websocket_unittest, as well as the TestHttpServer class,
to use the network service's HttpServer class (instead of the one in net/).

Bug: 821000
Change-Id: Icc4479b656936f38e86d104004d1dd703d845dda
Reviewed-on: https://chromium-review.googlesource.com/1038544
Commit-Queue: Lily Houghton <lilyhoughton@chromium.org>
Reviewed-by: default avatarJohn Chen <johnchen@chromium.org>
Reviewed-by: default avatarHelen Li <xunjieli@chromium.org>
Cr-Commit-Position: refs/heads/master@{#560310}
parent b06d77da
......@@ -424,6 +424,7 @@ test("chromedriver_tests") {
"net/test_http_server.cc",
"net/test_http_server.h",
"net/websocket_unittest.cc",
"run_all_unittests.cc",
]
# TODO(jschuh): crbug.com/167187 fix size_t to int truncations.
......@@ -432,10 +433,12 @@ test("chromedriver_tests") {
deps = [
":lib",
"//base",
"//base/test:run_all_unittests",
"//mojo/edk",
"//net",
"//net:http_server",
"//net:test_support",
"//services/network:network_service",
"//services/network/public/cpp",
"//services/network/public/mojom",
"//testing/gtest",
"//ui/events:test_support",
"//url",
......
......@@ -241,7 +241,7 @@ bool DevToolsHttpClient::FetchUrlAndLog(const std::string& url,
URLRequestContextGetter* getter,
std::string* response) {
VLOG(1) << "DevTools request: " << url;
bool ok = FetchUrl(url, getter, response);
bool ok = FetchUrl(url, getter, response, nullptr);
if (ok) {
VLOG(1) << "DevTools response: " << *response;
} else {
......
......@@ -32,11 +32,13 @@ class SyncUrlFetcher : public net::URLFetcherDelegate {
~SyncUrlFetcher() override {}
bool Fetch() {
bool Fetch(int* response_code) {
getter_->GetNetworkTaskRunner()->PostTask(
FROM_HERE, base::BindOnce(&SyncUrlFetcher::FetchOnIOThread,
base::Unretained(this)));
event_.Wait();
if (response_code)
*response_code = response_code_;
return success_;
}
......@@ -48,9 +50,15 @@ class SyncUrlFetcher : public net::URLFetcherDelegate {
}
void OnURLFetchComplete(const net::URLFetcher* source) override {
success_ = (source->GetResponseCode() == 200);
if (success_)
success_ = source->GetResponseAsString(response_);
response_code_ = -1;
success_ = false;
if (source->GetStatus().is_success()) {
response_code_ = source->GetResponseCode();
if (response_code_ == 200) {
success_ = source->GetResponseAsString(response_);
}
}
fetcher_.reset(); // Destroy the fetcher on IO thread.
event_.Signal();
}
......@@ -62,6 +70,7 @@ class SyncUrlFetcher : public net::URLFetcherDelegate {
base::WaitableEvent event_;
std::unique_ptr<net::URLFetcher> fetcher_;
bool success_;
int response_code_;
};
} // namespace
......@@ -93,6 +102,7 @@ int NetAddress::port() const {
bool FetchUrl(const std::string& url,
URLRequestContextGetter* getter,
std::string* response) {
return SyncUrlFetcher(GURL(url), getter, response).Fetch();
std::string* response,
int* response_code) {
return SyncUrlFetcher(GURL(url), getter, response).Fetch(response_code);
}
......@@ -31,8 +31,11 @@ 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|.
// Sets |response_code| to the response code of the fetch if there were no
// network errors, otherwise it is set to -1.
bool FetchUrl(const std::string& url,
URLRequestContextGetter* getter,
std::string* response);
std::string* response,
int* response_code);
#endif // CHROME_TEST_CHROMEDRIVER_NET_NET_UTIL_H_
......@@ -15,23 +15,27 @@
#include "base/single_thread_task_runner.h"
#include "base/strings/stringprintf.h"
#include "base/synchronization/waitable_event.h"
#include "base/test/bind_test_util.h"
#include "base/test/scoped_task_environment.h"
#include "base/threading/thread.h"
#include "chrome/test/chromedriver/net/url_request_context_getter.h"
#include "mojo/public/cpp/bindings/interface_request.h"
#include "net/base/ip_endpoint.h"
#include "net/base/net_errors.h"
#include "net/log/net_log_source.h"
#include "net/server/http_server.h"
#include "net/server/http_server_request_info.h"
#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/network_context.h"
#include "services/network/network_service.h"
#include "services/network/public/cpp/server/http_server.h"
#include "services/network/public/cpp/server/http_server_request_info.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace {
class FetchUrlTest : public testing::Test,
public net::HttpServer::Delegate {
public network::server::HttpServer::Delegate {
public:
FetchUrlTest()
: io_thread_("io"),
......@@ -41,44 +45,79 @@ class FetchUrlTest : public testing::Test,
base::Thread::Options options(base::MessageLoop::TYPE_IO, 0);
CHECK(io_thread_.StartWithOptions(options));
context_getter_ = new URLRequestContextGetter(io_thread_.task_runner());
}
void StartOnServerThread(base::WaitableEvent* event) {
network_service_ = network::NetworkService::CreateForTesting();
network::mojom::NetworkContextParamsPtr context_params =
network::mojom::NetworkContextParams::New();
// Use a fixed proxy config, to avoid dependencies on local network
// configuration.
context_params->initial_proxy_config =
net::ProxyConfigWithAnnotation::CreateDirect();
network_context_ = std::make_unique<network::NetworkContext>(
network_service_.get(), mojo::MakeRequest(&network_context_ptr_),
std::move(context_params));
int net_error = net::ERR_FAILED;
base::Optional<net::IPEndPoint> local_address;
network::mojom::TCPServerSocketPtr server_socket;
base::RunLoop run_loop;
network_context_->CreateTCPServerSocket(
net::IPEndPoint(net::IPAddress::IPv6Localhost(), 0), 1 /* backlog */,
net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS),
mojo::MakeRequest(&server_socket),
base::BindLambdaForTesting(
[&](int result, const base::Optional<net::IPEndPoint>& local_addr) {
net_error = result;
local_address = local_addr;
run_loop.Quit();
}));
run_loop.Run();
EXPECT_EQ(net::OK, net_error);
server_url_ = base::StringPrintf("http://[::1]:%d", local_address->port());
server_.reset(
new network::server::HttpServer(std::move(server_socket), this));
event->Signal();
}
void StopOnServerThread(base::WaitableEvent* event) {
server_.reset(nullptr);
network_context_.reset(nullptr);
network_service_.reset(nullptr);
event->Signal();
}
void SetUp() override {
base::WaitableEvent event(base::WaitableEvent::ResetPolicy::AUTOMATIC,
base::WaitableEvent::InitialState::NOT_SIGNALED);
io_thread_.task_runner()->PostTask(
FROM_HERE, base::BindOnce(&FetchUrlTest::InitOnIO,
FROM_HERE, base::BindOnce(&FetchUrlTest::StartOnServerThread,
base::Unretained(this), &event));
event.Wait();
}
~FetchUrlTest() override {
void TearDown() override {
if (!io_thread_.IsRunning())
return;
base::WaitableEvent event(base::WaitableEvent::ResetPolicy::AUTOMATIC,
base::WaitableEvent::InitialState::NOT_SIGNALED);
io_thread_.task_runner()->PostTask(
FROM_HERE, base::BindOnce(&FetchUrlTest::DestroyServerOnIO,
FROM_HERE, base::BindOnce(&FetchUrlTest::StopOnServerThread,
base::Unretained(this), &event));
event.Wait();
io_thread_.Stop();
}
void InitOnIO(base::WaitableEvent* event) {
std::unique_ptr<net::ServerSocket> server_socket(
new net::TCPServerSocket(NULL, net::NetLogSource()));
server_socket->ListenWithAddressAndPort("127.0.0.1", 0, 1);
server_.reset(new net::HttpServer(std::move(server_socket), this));
net::IPEndPoint address;
CHECK_EQ(net::OK, server_->GetLocalAddress(&address));
server_url_ = base::StringPrintf("http://127.0.0.1:%d", address.port());
event->Signal();
}
void DestroyServerOnIO(base::WaitableEvent* event) {
server_.reset(NULL);
event->Signal();
}
// Overridden from net::HttpServer::Delegate:
// Overridden from network::server::HttpServer::Delegate:
void OnConnect(int connection_id) override {}
void OnHttpRequest(int connection_id,
const net::HttpServerRequestInfo& info) override {
void OnHttpRequest(
int connection_id,
const network::server::HttpServerRequestInfo& info) override {
switch (response_) {
case kSendHello:
server_->Send200(connection_id, "hello", "text/plain",
......@@ -95,8 +134,9 @@ class FetchUrlTest : public testing::Test,
}
}
void OnWebSocketRequest(int connection_id,
const net::HttpServerRequestInfo& info) override {}
void OnWebSocketRequest(
int connection_id,
const network::server::HttpServerRequestInfo& info) override {}
void OnWebSocketMessage(int connection_id, const std::string& data) override {
}
void OnClose(int connection_id) override {}
......@@ -110,37 +150,53 @@ class FetchUrlTest : public testing::Test,
base::Thread io_thread_;
ServerResponse response_;
std::unique_ptr<net::HttpServer> server_;
std::unique_ptr<network::server::HttpServer> server_;
base::test::ScopedTaskEnvironment scoped_task_environment_;
std::unique_ptr<network::NetworkService> network_service_;
std::unique_ptr<network::NetworkContext> network_context_;
network::mojom::NetworkContextPtr network_context_ptr_;
scoped_refptr<URLRequestContextGetter> context_getter_;
std::string server_url_;
base::test::ScopedTaskEnvironment scoped_task_environment_;
};
} // namespace
TEST_F(FetchUrlTest, Http200) {
response_ = kSendHello;
std::string response("stuff");
ASSERT_TRUE(FetchUrl(server_url_, context_getter_.get(), &response));
int response_code = -1;
ASSERT_TRUE(
FetchUrl(server_url_, context_getter_.get(), &response, &response_code));
EXPECT_EQ(response_code, 200);
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));
int response_code = -1;
ASSERT_FALSE(
FetchUrl(server_url_, context_getter_.get(), &response, &response_code));
EXPECT_EQ(response_code, 404);
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));
int response_code = -1;
ASSERT_FALSE(
FetchUrl(server_url_, context_getter_.get(), &response, &response_code));
EXPECT_LT(response_code, 0);
ASSERT_STREQ("stuff", response.c_str());
}
TEST_F(FetchUrlTest, NoServer) {
std::string response("stuff");
ASSERT_FALSE(
FetchUrl("http://localhost:33333", context_getter_.get(), &response));
int response_code = -1;
ASSERT_FALSE(FetchUrl("http://localhost:33333", context_getter_.get(),
&response, &response_code));
EXPECT_LT(response_code, 0);
ASSERT_STREQ("stuff", response.c_str());
}
......@@ -8,6 +8,7 @@
#include "base/memory/ref_counted.h"
#include "base/message_loop/message_loop.h"
#include "base/single_thread_task_runner.h"
#include "base/test/scoped_task_environment.h"
#include "base/threading/platform_thread.h"
#include "base/threading/thread.h"
#include "base/time/time.h"
......@@ -23,7 +24,9 @@ namespace {
class SyncWebSocketImplTest : public testing::Test {
protected:
SyncWebSocketImplTest()
: client_thread_("ClientThread"),
: task_environment_(
base::test::ScopedTaskEnvironment::MainThreadType::IO),
client_thread_("ClientThread"),
long_timeout_(base::TimeDelta::FromMinutes(1)) {}
~SyncWebSocketImplTest() override {}
......@@ -38,6 +41,7 @@ class SyncWebSocketImplTest : public testing::Test {
Timeout long_timeout() const { return Timeout(long_timeout_); }
base::test::ScopedTaskEnvironment task_environment_;
base::Thread client_thread_;
TestHttpServer server_;
scoped_refptr<URLRequestContextGetter> context_getter_;
......
......@@ -10,15 +10,18 @@
#include "base/callback_helpers.h"
#include "base/location.h"
#include "base/message_loop/message_loop.h"
#include "base/single_thread_task_runner.h"
#include "base/strings/stringprintf.h"
#include "base/test/bind_test_util.h"
#include "base/test/scoped_task_environment.h"
#include "base/time/time.h"
#include "net/base/ip_endpoint.h"
#include "net/base/net_errors.h"
#include "net/log/net_log_source.h"
#include "net/server/http_server_request_info.h"
#include "net/socket/tcp_server_socket.h"
#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
#include "services/network/network_context.h"
#include "services/network/network_service.h"
#include "services/network/public/cpp/server/http_server_request_info.h"
#include "testing/gtest/include/gtest/gtest.h"
const int kBufferSize = 100 * 1024 * 1024; // 100 MB
......@@ -92,7 +95,7 @@ void TestHttpServer::OnConnect(int connection_id) {
void TestHttpServer::OnWebSocketRequest(
int connection_id,
const net::HttpServerRequestInfo& info) {
const network::server::HttpServerRequestInfo& info) {
WebSocketRequestAction action;
{
base::AutoLock lock(action_lock_);
......@@ -145,26 +148,53 @@ void TestHttpServer::OnClose(int connection_id) {
void TestHttpServer::StartOnServerThread(bool* success,
base::WaitableEvent* event) {
std::unique_ptr<net::ServerSocket> server_socket(
new net::TCPServerSocket(NULL, net::NetLogSource()));
server_socket->ListenWithAddressAndPort("127.0.0.1", 0, 1);
server_.reset(new net::HttpServer(std::move(server_socket), this));
network_service_ = network::NetworkService::CreateForTesting();
network::mojom::NetworkContextParamsPtr context_params =
network::mojom::NetworkContextParams::New();
// Use a fixed proxy config, to avoid dependencies on local network
// configuration.
context_params->initial_proxy_config =
net::ProxyConfigWithAnnotation::CreateDirect();
network_context_ = std::make_unique<network::NetworkContext>(
network_service_.get(), mojo::MakeRequest(&network_context_ptr_),
std::move(context_params));
int net_error = net::ERR_FAILED;
net::IPEndPoint address;
int error = server_->GetLocalAddress(&address);
EXPECT_EQ(net::OK, error);
if (error == net::OK) {
base::RunLoop run_loop(base::RunLoop::Type::kNestableTasksAllowed);
network::mojom::TCPServerSocketPtr server_socket;
network_context_ptr_->CreateTCPServerSocket(
net::IPEndPoint(net::IPAddress::IPv6Localhost(), 0), 1 /* backlog */,
net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS),
mojo::MakeRequest(&server_socket),
base::BindLambdaForTesting(
[&](int result, const base::Optional<net::IPEndPoint>& local_addr) {
net_error = result;
address = local_addr.value();
run_loop.Quit();
}));
run_loop.Run();
EXPECT_EQ(net::OK, net_error);
server_ = std::make_unique<network::server::HttpServer>(
std::move(server_socket), this);
if (net_error == net::OK) {
base::AutoLock lock(url_lock_);
web_socket_url_ = GURL(base::StringPrintf("ws://127.0.0.1:%d",
address.port()));
web_socket_url_ = GURL(base::StringPrintf("ws://[::1]:%d", address.port()));
} else {
server_.reset(NULL);
server_.reset(nullptr);
}
*success = server_.get();
event->Signal();
}
void TestHttpServer::StopOnServerThread(base::WaitableEvent* event) {
server_.reset(NULL);
server_ = nullptr;
network_context_ptr_.reset();
network_context_ = nullptr;
network_service_ = nullptr;
event->Signal();
}
......@@ -12,8 +12,11 @@
#include "base/memory/ref_counted.h"
#include "base/synchronization/lock.h"
#include "base/synchronization/waitable_event.h"
#include "base/test/scoped_task_environment.h"
#include "base/threading/thread.h"
#include "net/server/http_server.h"
#include "services/network/network_context.h"
#include "services/network/network_service.h"
#include "services/network/public/cpp/server/http_server.h"
#include "url/gurl.h"
namespace base {
......@@ -23,7 +26,7 @@ class WaitableEvent;
// HTTP server for web socket testing purposes that runs on its own thread.
// All public methods are thread safe and may be called on any thread, unless
// noted otherwise.
class TestHttpServer : public net::HttpServer::Delegate {
class TestHttpServer : public network::server::HttpServer::Delegate {
public:
enum WebSocketRequestAction {
kAccept,
......@@ -63,12 +66,14 @@ class TestHttpServer : public net::HttpServer::Delegate {
// Returns the web socket URL that points to the server.
GURL web_socket_url() const;
// Overridden from net::HttpServer::Delegate:
// Overridden from network::server::HttpServer::Delegate:
void OnConnect(int connection_id) override;
void OnHttpRequest(int connection_id,
const net::HttpServerRequestInfo& info) override {}
void OnWebSocketRequest(int connection_id,
const net::HttpServerRequestInfo& info) override;
void OnHttpRequest(
int connection_id,
const network::server::HttpServerRequestInfo& info) override {}
void OnWebSocketRequest(
int connection_id,
const network::server::HttpServerRequestInfo& info) override;
void OnWebSocketMessage(int connection_id, const std::string& data) override;
void OnClose(int connection_id) override;
......@@ -79,7 +84,7 @@ class TestHttpServer : public net::HttpServer::Delegate {
base::Thread thread_;
// Access only on the server thread.
std::unique_ptr<net::HttpServer> server_;
std::unique_ptr<network::server::HttpServer> server_;
// Access only on the server thread.
std::set<int> connections_;
......@@ -90,6 +95,11 @@ class TestHttpServer : public net::HttpServer::Delegate {
mutable base::Lock url_lock_;
GURL web_socket_url_;
std::unique_ptr<network::NetworkService> network_service_;
std::unique_ptr<network::NetworkContext> network_context_;
network::mojom::NetworkContextPtr network_context_ptr_;
// Protects the action flags and |message_callback_|.
base::Lock action_lock_;
WebSocketRequestAction request_action_;
......
......@@ -31,9 +31,10 @@ void OnConnectFinished(base::RunLoop* run_loop, int* save_error, int error) {
run_loop->Quit();
}
void RunPending(base::MessageLoop* loop) {
void RunPending(base::test::ScopedTaskEnvironment* task_env) {
base::RunLoop run_loop;
loop->task_runner()->PostTask(FROM_HERE, run_loop.QuitClosure());
task_env->GetMainThreadTaskRunner()->PostTask(FROM_HERE,
run_loop.QuitClosure());
run_loop.Run();
}
......@@ -80,7 +81,9 @@ class CloseListener : public WebSocketListener {
class WebSocketTest : public testing::Test {
public:
WebSocketTest() {}
WebSocketTest()
: task_environment_(
base::test::ScopedTaskEnvironment::MainThreadType::IO) {}
~WebSocketTest() override {}
void SetUp() override { ASSERT_TRUE(server_.Start()); }
......@@ -94,8 +97,8 @@ class WebSocketTest : public testing::Test {
std::unique_ptr<WebSocket> sock(new WebSocket(url, listener));
base::RunLoop run_loop;
sock->Connect(base::Bind(&OnConnectFinished, &run_loop, &error));
loop_.task_runner()->PostDelayedTask(FROM_HERE, run_loop.QuitClosure(),
base::TimeDelta::FromSeconds(10));
task_environment_.GetMainThreadTaskRunner()->PostDelayedTask(
FROM_HERE, run_loop.QuitClosure(), base::TimeDelta::FromSeconds(10));
run_loop.Run();
if (error == net::OK)
return sock;
......@@ -115,12 +118,12 @@ class WebSocketTest : public testing::Test {
ASSERT_TRUE(sock->Send(messages[i]));
}
base::RunLoop run_loop;
loop_.task_runner()->PostDelayedTask(FROM_HERE, run_loop.QuitClosure(),
base::TimeDelta::FromSeconds(10));
task_environment_.GetMainThreadTaskRunner()->PostDelayedTask(
FROM_HERE, run_loop.QuitClosure(), base::TimeDelta::FromSeconds(10));
run_loop.Run();
}
base::MessageLoopForIO loop_;
base::test::ScopedTaskEnvironment task_environment_;
TestHttpServer server_;
};
......@@ -134,7 +137,7 @@ TEST_F(WebSocketTest, CreateDestroy) {
TEST_F(WebSocketTest, Connect) {
CloseListener listener(NULL);
ASSERT_TRUE(CreateWebSocket(server_.web_socket_url(), &listener));
RunPending(&loop_);
RunPending(&task_environment_);
ASSERT_TRUE(server_.WaitForConnectionsToClose());
}
......@@ -147,7 +150,7 @@ TEST_F(WebSocketTest, Connect404) {
server_.SetRequestAction(TestHttpServer::kNotFound);
CloseListener listener(NULL);
ASSERT_FALSE(CreateWebSocket(server_.web_socket_url(), NULL));
RunPending(&loop_);
RunPending(&task_environment_);
ASSERT_TRUE(server_.WaitForConnectionsToClose());
}
......@@ -164,8 +167,8 @@ TEST_F(WebSocketTest, CloseOnReceive) {
std::unique_ptr<WebSocket> sock(CreateConnectedWebSocket(&listener));
ASSERT_TRUE(sock);
ASSERT_TRUE(sock->Send("hi"));
loop_.task_runner()->PostDelayedTask(FROM_HERE, run_loop.QuitClosure(),
base::TimeDelta::FromSeconds(10));
task_environment_.GetMainThreadTaskRunner()->PostDelayedTask(
FROM_HERE, run_loop.QuitClosure(), base::TimeDelta::FromSeconds(10));
run_loop.Run();
}
......@@ -177,8 +180,8 @@ TEST_F(WebSocketTest, CloseOnSend) {
server_.Stop();
sock->Send("hi");
loop_.task_runner()->PostDelayedTask(FROM_HERE, run_loop.QuitClosure(),
base::TimeDelta::FromSeconds(10));
task_environment_.GetMainThreadTaskRunner()->PostDelayedTask(
FROM_HERE, run_loop.QuitClosure(), base::TimeDelta::FromSeconds(10));
run_loop.Run();
ASSERT_FALSE(sock->Send("hi"));
}
......
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <memory>
#include "base/bind.h"
#include "base/message_loop/message_loop.h"
#include "base/test/launcher/unit_test_launcher.h"
#include "base/test/test_io_thread.h"
#include "base/test/test_suite.h"
#include "build/build_config.h"
#include "mojo/edk/embedder/embedder.h"
int main(int argc, char** argv) {
base::TestSuite test_suite(argc, argv);
mojo::edk::Init();
return base::LaunchUnitTests(
argc, argv,
base::BindOnce(&base::TestSuite::Run, base::Unretained(&test_suite)));
}
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