diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2017-11-20 15:06:40 +0100 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2017-11-22 11:48:58 +0000 |
commit | daa093eea7c773db06799a13bd7e4e2e2a9f8f14 (patch) | |
tree | 96cc5e7b9194c1b29eab927730bfa419e7111c25 /chromium/net/test | |
parent | be59a35641616a4cf23c4a13fa0632624b021c1b (diff) | |
download | qtwebengine-chromium-daa093eea7c773db06799a13bd7e4e2e2a9f8f14.tar.gz |
BASELINE: Update Chromium to 63.0.3239.58
Change-Id: Ia93b322a00ba4dd4004f3bcf1254063ba90e1605
Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
Diffstat (limited to 'chromium/net/test')
19 files changed, 429 insertions, 586 deletions
diff --git a/chromium/net/test/embedded_test_server/default_handlers.cc b/chromium/net/test/embedded_test_server/default_handlers.cc index 38a8c3c1fa1..057d9a855d5 100644 --- a/chromium/net/test/embedded_test_server/default_handlers.cc +++ b/chromium/net/test/embedded_test_server/default_handlers.cc @@ -5,8 +5,10 @@ #include "net/test/embedded_test_server/default_handlers.h" #include <stdlib.h> + #include <ctime> #include <map> +#include <memory> #include <sstream> #include <string> #include <utility> @@ -20,7 +22,6 @@ #include "base/format_macros.h" #include "base/macros.h" #include "base/md5.h" -#include "base/memory/ptr_util.h" #include "base/path_service.h" #include "base/strings/string_split.h" #include "base/strings/string_util.h" diff --git a/chromium/net/test/embedded_test_server/embedded_test_server.cc b/chromium/net/test/embedded_test_server/embedded_test_server.cc index df705db89c3..de416f22aed 100644 --- a/chromium/net/test/embedded_test_server/embedded_test_server.cc +++ b/chromium/net/test/embedded_test_server/embedded_test_server.cc @@ -11,7 +11,6 @@ #include "base/files/file_util.h" #include "base/location.h" #include "base/logging.h" -#include "base/memory/ptr_util.h" #include "base/message_loop/message_loop.h" #include "base/path_service.h" #include "base/process/process_metrics.h" diff --git a/chromium/net/test/embedded_test_server/embedded_test_server_unittest.cc b/chromium/net/test/embedded_test_server/embedded_test_server_unittest.cc index f4c3c2c51b4..74b787284b7 100644 --- a/chromium/net/test/embedded_test_server/embedded_test_server_unittest.cc +++ b/chromium/net/test/embedded_test_server/embedded_test_server_unittest.cc @@ -7,7 +7,6 @@ #include <utility> #include "base/macros.h" -#include "base/memory/ptr_util.h" #include "base/memory/weak_ptr.h" #include "base/message_loop/message_loop.h" #include "base/path_service.h" @@ -464,7 +463,7 @@ class InfiniteResponse : public BasicHttpResponse { std::unique_ptr<HttpResponse> HandleInfiniteRequest( const HttpRequest& request) { - return base::WrapUnique(new InfiniteResponse); + return std::make_unique<InfiniteResponse>(); } } // anonymous namespace diff --git a/chromium/net/test/embedded_test_server/http_response.cc b/chromium/net/test/embedded_test_server/http_response.cc index 100f5d60009..fd5521197ba 100644 --- a/chromium/net/test/embedded_test_server/http_response.cc +++ b/chromium/net/test/embedded_test_server/http_response.cc @@ -27,9 +27,13 @@ void RawHttpResponse::SendResponse(const SendBytesCallback& send, std::string response; if (!headers_.empty()) { response = headers_; - if (!base::EndsWith(response, "\n", base::CompareCase::SENSITIVE)) - response += "\r\n"; - response += "\r\n" + contents_; + // LocateEndOfHeadersHelper() searches for the first "\n\n" and "\n\r\n" as + // the end of the header. + std::size_t index = response.find_last_not_of("\r\n"); + if (index != std::string::npos) + response.erase(index + 1); + response += "\n\n"; + response += contents_; } else { response = contents_; } diff --git a/chromium/net/test/embedded_test_server/request_handler_util.cc b/chromium/net/test/embedded_test_server/request_handler_util.cc index 2d26e243eca..eb46ac740a9 100644 --- a/chromium/net/test/embedded_test_server/request_handler_util.cc +++ b/chromium/net/test/embedded_test_server/request_handler_util.cc @@ -13,7 +13,6 @@ #include "base/base64.h" #include "base/files/file_util.h" #include "base/format_macros.h" -#include "base/memory/ptr_util.h" #include "base/strings/string_util.h" #include "base/strings/stringprintf.h" #include "base/threading/thread_restrictions.h" diff --git a/chromium/net/test/net_test_suite.cc b/chromium/net/test/net_test_suite.cc index 29e53db0f20..3d131ddffb9 100644 --- a/chromium/net/test/net_test_suite.cc +++ b/chromium/net/test/net_test_suite.cc @@ -5,7 +5,6 @@ #include "net/test/net_test_suite.h" #include "base/logging.h" -#include "base/memory/ptr_util.h" #include "base/test/scoped_task_environment.h" #include "net/base/network_change_notifier.h" #include "net/http/http_stream_factory.h" diff --git a/chromium/net/test/python_utils_unittest.cc b/chromium/net/test/python_utils_unittest.cc index 91f742ac83a..ec89b6279f2 100644 --- a/chromium/net/test/python_utils_unittest.cc +++ b/chromium/net/test/python_utils_unittest.cc @@ -54,12 +54,7 @@ TEST(PythonUtils, Append) { #endif } -#if defined(OS_ANDROID) -#define MAYBE_PythonRunTime DISABLED_PythonRunTime -#else -#define MAYBE_PythonRunTime PythonRunTime -#endif -TEST(PythonUtils, MAYBE_PythonRunTime) { +TEST(PythonUtils, PythonRunTime) { base::CommandLine cmd_line(base::CommandLine::NO_PROGRAM); EXPECT_TRUE(GetPythonCommand(&cmd_line)); diff --git a/chromium/net/test/spawned_test_server/base_test_server.cc b/chromium/net/test/spawned_test_server/base_test_server.cc index bf1a41dbd5c..69d9403c80a 100644 --- a/chromium/net/test/spawned_test_server/base_test_server.cc +++ b/chromium/net/test/spawned_test_server/base_test_server.cc @@ -14,7 +14,6 @@ #include "base/files/file_util.h" #include "base/json/json_reader.h" #include "base/logging.h" -#include "base/memory/ptr_util.h" #include "base/path_service.h" #include "base/values.h" #include "net/base/address_list.h" @@ -260,6 +259,10 @@ BaseTestServer::BaseTestServer(Type type, const SSLOptions& ssl_options) BaseTestServer::~BaseTestServer() {} +bool BaseTestServer::Start() { + return StartInBackground() && BlockUntilStarted(); +} + const HostPortPair& BaseTestServer::host_port_pair() const { DCHECK(started_); return host_port_pair_; @@ -463,6 +466,7 @@ bool BaseTestServer::SetAndParseServerData(const std::string& server_data, bool BaseTestServer::SetupWhenServerStarted() { DCHECK(host_port_pair_.port()); + DCHECK(!started_); if (UsingSSL(type_) && !LoadTestRootCert()) return false; diff --git a/chromium/net/test/spawned_test_server/base_test_server.h b/chromium/net/test/spawned_test_server/base_test_server.h index fd44381abc7..ae50bce1228 100644 --- a/chromium/net/test/spawned_test_server/base_test_server.h +++ b/chromium/net/test/spawned_test_server/base_test_server.h @@ -304,6 +304,29 @@ class BaseTestServer { // Initialize a TestServer with a specific set of SSLOptions for HTTPS or WSS. BaseTestServer(Type type, const SSLOptions& ssl_options); + // Starts the server blocking until the server is ready. + bool Start() WARN_UNUSED_RESULT; + + // Start the test server without blocking. Use this if you need multiple test + // servers (such as WebSockets and HTTP, or HTTP and HTTPS). You must call + // BlockUntilStarted on all servers your test requires before executing the + // test. For example: + // + // // Start the servers in parallel. + // ASSERT_TRUE(http_server.StartInBackground()); + // ASSERT_TRUE(websocket_server.StartInBackground()); + // // Wait for both servers to be ready. + // ASSERT_TRUE(http_server.BlockUntilStarted()); + // ASSERT_TRUE(websocket_server.BlockUntilStarted()); + // RunMyTest(); + // + // Returns true on success. + virtual bool StartInBackground() WARN_UNUSED_RESULT = 0; + + // Block until the test server is ready. Returns true on success. See + // StartInBackground() documentation for more information. + virtual bool BlockUntilStarted() WARN_UNUSED_RESULT = 0; + // Returns the host port pair used by current Python based test server only // if the server is started. const HostPortPair& host_port_pair() const; @@ -354,6 +377,8 @@ class BaseTestServer { virtual ~BaseTestServer(); Type type() const { return type_; } + bool started() const { return started_; } + // Gets port currently assigned to host_port_pair_ without checking // whether it's available (server started) or not. uint16_t GetPort(); diff --git a/chromium/net/test/spawned_test_server/local_test_server.cc b/chromium/net/test/spawned_test_server/local_test_server.cc index e1822dd85d6..3f0ad15fdca 100644 --- a/chromium/net/test/spawned_test_server/local_test_server.cc +++ b/chromium/net/test/spawned_test_server/local_test_server.cc @@ -24,7 +24,7 @@ bool AppendArgumentFromJSONValue(const std::string& key, const base::Value& value_node, base::CommandLine* command_line) { std::string argument_name = "--" + key; - switch (value_node.GetType()) { + switch (value_node.type()) { case base::Value::Type::NONE: command_line->AppendArg(argument_name); break; @@ -88,11 +88,9 @@ bool LocalTestServer::GetTestServerPath(base::FilePath* testserver_path) const { return true; } -bool LocalTestServer::Start() { - return StartInBackground() && BlockUntilStarted(); -} - bool LocalTestServer::StartInBackground() { + DCHECK(!started()); + base::ThreadRestrictions::ScopedAllowIO allow_io_from_test_code; // Get path to Python server script. diff --git a/chromium/net/test/spawned_test_server/local_test_server.h b/chromium/net/test/spawned_test_server/local_test_server.h index 6d8a3f8c82f..28f54967977 100644 --- a/chromium/net/test/spawned_test_server/local_test_server.h +++ b/chromium/net/test/spawned_test_server/local_test_server.h @@ -39,28 +39,9 @@ class LocalTestServer : public BaseTestServer { ~LocalTestServer() override; - // Start the test server and block until it's ready. Returns true on success. - bool Start() WARN_UNUSED_RESULT; - - // Start the test server without blocking. Use this if you need multiple test - // servers (such as WebSockets and HTTP, or HTTP and HTTPS). You must call - // BlockUntilStarted on all servers your test requires before executing the - // test. For example: - // - // // Start the servers in parallel. - // ASSERT_TRUE(http_server.StartInBackground()); - // ASSERT_TRUE(websocket_server.StartInBackground()); - // // Wait for both servers to be ready. - // ASSERT_TRUE(http_server.BlockUntilStarted()); - // ASSERT_TRUE(websocket_server.BlockUntilStarted()); - // RunMyTest(); - // - // Returns true on success. - bool StartInBackground() WARN_UNUSED_RESULT; - - // Block until ths test server is ready. Returns true on success. See - // StartInBackground() documentation for more information. - bool BlockUntilStarted() WARN_UNUSED_RESULT; + // BaseTestServer overrides. + bool StartInBackground() override WARN_UNUSED_RESULT; + bool BlockUntilStarted() override WARN_UNUSED_RESULT; // Stop the server started by Start(). bool Stop(); diff --git a/chromium/net/test/spawned_test_server/remote_test_server.cc b/chromium/net/test/spawned_test_server/remote_test_server.cc index 5bf7ed2a95b..6a26cde5f94 100644 --- a/chromium/net/test/spawned_test_server/remote_test_server.cc +++ b/chromium/net/test/spawned_test_server/remote_test_server.cc @@ -14,22 +14,24 @@ #include "base/files/file_util.h" #include "base/json/json_writer.h" #include "base/logging.h" +#include "base/message_loop/message_loop.h" #include "base/path_service.h" #include "base/strings/string_number_conversions.h" #include "base/strings/string_split.h" +#include "base/strings/stringprintf.h" #include "base/values.h" #include "net/base/host_port_pair.h" +#include "net/base/ip_endpoint.h" #include "net/base/net_errors.h" -#include "net/test/spawned_test_server/remote_test_server_config.h" #include "net/test/spawned_test_server/remote_test_server_proxy.h" -#include "net/test/spawned_test_server/spawner_communicator.h" +#include "net/test/spawned_test_server/remote_test_server_spawner_request.h" #include "url/gurl.h" namespace net { namespace { -// Please keep it sync with dictionary SERVER_TYPES in testserver.py +// Please keep in sync with dictionary SERVER_TYPES in testserver.py std::string GetServerTypeString(BaseTestServer::Type type) { switch (type) { case BaseTestServer::TYPE_FTP: @@ -72,13 +74,9 @@ RemoteTestServer::~RemoteTestServer() { Stop(); } -bool RemoteTestServer::Start() { - if (spawner_communicator_.get()) - return true; - - RemoteTestServerConfig config = RemoteTestServerConfig::Load(); - - spawner_communicator_ = std::make_unique<SpawnerCommunicator>(config); +bool RemoteTestServer::StartInBackground() { + DCHECK(!started()); + DCHECK(!start_request_); base::DictionaryValue arguments_dict; if (!GenerateArguments(&arguments_dict)) @@ -96,56 +94,62 @@ bool RemoteTestServer::Start() { if (arguments_string.empty()) return false; - // Start the Python test server on the remote machine. + start_request_ = std::make_unique<RemoteTestServerSpawnerRequest>( + io_thread_.task_runner(), config_.GetSpawnerUrl("start"), + arguments_string); + + return true; +} + +bool RemoteTestServer::BlockUntilStarted() { + DCHECK(start_request_); + std::string server_data; - if (!spawner_communicator_->StartServer(arguments_string, &server_data)) + bool request_result = start_request_->WaitForCompletion(&server_data); + start_request_.reset(); + if (!request_result) return false; // Parse server_data. - int server_port; if (server_data.empty() || - !SetAndParseServerData(server_data, &server_port)) { + !SetAndParseServerData(server_data, &remote_port_)) { LOG(ERROR) << "Could not parse server_data: " << server_data; return false; } // If the server is not on localhost then start a proxy on localhost to // forward connections to the server. - if (config.address() != IPAddress::IPv4Localhost()) { + if (config_.address() != IPAddress::IPv4Localhost()) { test_server_proxy_ = std::make_unique<RemoteTestServerProxy>( - IPEndPoint(config.address(), server_port), io_thread_.task_runner()); + IPEndPoint(config_.address(), remote_port_), io_thread_.task_runner()); SetPort(test_server_proxy_->local_port()); } else { - SetPort(server_port); + SetPort(remote_port_); } return SetupWhenServerStarted(); } -bool RemoteTestServer::StartInBackground() { - NOTIMPLEMENTED(); - return false; -} +bool RemoteTestServer::Stop() { + DCHECK(!start_request_); -bool RemoteTestServer::BlockUntilStarted() { - NOTIMPLEMENTED(); - return false; -} + if (remote_port_) { + std::unique_ptr<RemoteTestServerSpawnerRequest> kill_request = + std::make_unique<RemoteTestServerSpawnerRequest>( + io_thread_.task_runner(), + config_.GetSpawnerUrl( + base::StringPrintf("kill?port=%d", remote_port_)), + std::string()); -bool RemoteTestServer::Stop() { - if (!spawner_communicator_) - return true; + if (!kill_request->WaitForCompletion(nullptr)) + LOG(ERROR) << "Failed stopping RemoteTestServer"; - uint16_t port = GetPort(); - CleanUpWhenStoppingServer(); - bool stopped = spawner_communicator_->StopServer(port); + remote_port_ = 0; + } - if (!stopped) - LOG(ERROR) << "Failed stopping RemoteTestServer"; + CleanUpWhenStoppingServer(); - // Explicitly reset |spawner_communicator_| to avoid reusing the stopped one. - spawner_communicator_.reset(); - return stopped; + return true; } // On Android, the document root in the device is not the same as the document @@ -162,6 +166,8 @@ bool RemoteTestServer::Init(const base::FilePath& document_root) { if (document_root.IsAbsolute()) return false; + config_ = RemoteTestServerConfig::Load(); + bool thread_started = io_thread_.StartWithOptions( base::Thread::Options(base::MessageLoop::TYPE_IO, 0)); CHECK(thread_started); diff --git a/chromium/net/test/spawned_test_server/remote_test_server.h b/chromium/net/test/spawned_test_server/remote_test_server.h index 04dcdb4cf74..af75d2f3d27 100644 --- a/chromium/net/test/spawned_test_server/remote_test_server.h +++ b/chromium/net/test/spawned_test_server/remote_test_server.h @@ -10,14 +10,47 @@ #include "base/macros.h" #include "base/threading/thread.h" #include "net/test/spawned_test_server/base_test_server.h" +#include "net/test/spawned_test_server/remote_test_server_config.h" namespace net { -class SpawnerCommunicator; +class RemoteTestServerSpawnerRequest; class RemoteTestServerProxy; // The RemoteTestServer runs an external Python-based test server in another -// machine that is different from the machine in which RemoteTestServer runs. +// machine that is different from the machine that executes the tests. It is +// necessary because it's not always possible to run the test server on the same +// machine (it doesn't run on Android and Fuchsia because it's written in +// Python). +// +// The actual test server is executed on the host machine, while the unit tests +// themselves continue running on the device. To control the test server on the +// host machine, a second HTTP server is started, the spawner server, which +// controls the life cycle of remote test servers. Calls to start/kill the +// SpawnedTestServer are then redirected to the spawner server via +// this spawner communicator. The spawner is implemented in +// build/util/lib/common/chrome_test_server_spawner.py . +// +// Currently the following two commands are supported by spawner. +// +// (1) Start Python test server, format is: +// Path: "/start". +// Method: "POST". +// Data to server: all arguments needed to launch the Python test server, in +// JSON format. +// Data from server: a JSON dict includes the following two field if success, +// "port": the port the Python test server actually listen on that. +// "message": must be "started". +// +// (2) Kill Python test server, format is: +// Path: "/kill". +// Method: "GET". +// Data to server: port=<server_port>. +// Data from server: String "killed" returned if success. +// +// The internal I/O thread is required by net stack to perform net I/O. +// The Start/StopServer methods block the caller thread until result is +// fetched from spawner server or timed-out. class RemoteTestServer : public BaseTestServer { public: // Initialize a TestServer. |document_root| must be a relative path under the @@ -32,14 +65,9 @@ class RemoteTestServer : public BaseTestServer { ~RemoteTestServer() override; - // Starts the Python test server on the host, instead of on the device, and - // blocks until the server is ready. - bool Start() WARN_UNUSED_RESULT; - - // These are currently unused and unimplemented for RemoteTestServer. See - // the same methods in LocalTestServer for more information. - bool StartInBackground() WARN_UNUSED_RESULT; - bool BlockUntilStarted() WARN_UNUSED_RESULT; + // BaseTestServer overrides. + bool StartInBackground() override WARN_UNUSED_RESULT; + bool BlockUntilStarted() override WARN_UNUSED_RESULT; // Stops the Python test server that is running on the host machine. bool Stop(); @@ -53,13 +81,16 @@ class RemoteTestServer : public BaseTestServer { private: bool Init(const base::FilePath& document_root); - // Thread used to run all IO activity in |test_server_proxy_|. - // TODO(sergeyu): Use it for |spawner_communicator_| as well. + RemoteTestServerConfig config_; + + // Thread used to run all IO activity in RemoteTestServerSpawnerRequest and + // |test_server_proxy_|. base::Thread io_thread_; - // Helper to start and stop instances of the Python test server that runs on - // the host machine. - std::unique_ptr<SpawnerCommunicator> spawner_communicator_; + std::unique_ptr<RemoteTestServerSpawnerRequest> start_request_; + + // Server port. Non-zero when the server is running. + int remote_port_ = 0; std::unique_ptr<RemoteTestServerProxy> test_server_proxy_; diff --git a/chromium/net/test/spawned_test_server/remote_test_server_spawner_request.cc b/chromium/net/test/spawned_test_server/remote_test_server_spawner_request.cc new file mode 100644 index 00000000000..2202bd30345 --- /dev/null +++ b/chromium/net/test/spawned_test_server/remote_test_server_spawner_request.cc @@ -0,0 +1,227 @@ +// Copyright 2017 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 "net/test/spawned_test_server/remote_test_server_spawner_request.h" + +#include <utility> + +#include "base/location.h" +#include "base/logging.h" +#include "base/macros.h" +#include "base/single_thread_task_runner.h" +#include "base/synchronization/waitable_event.h" +#include "base/test/test_timeouts.h" +#include "base/threading/thread_task_runner_handle.h" +#include "base/time/time.h" +#include "base/timer/timer.h" +#include "build/build_config.h" +#include "net/base/elements_upload_data_stream.h" +#include "net/base/io_buffer.h" +#include "net/base/port_util.h" +#include "net/base/upload_bytes_element_reader.h" +#include "net/http/http_response_headers.h" +#include "net/url_request/url_request.h" +#include "net/url_request/url_request_test_util.h" +#include "url/gurl.h" + +namespace net { + +static const int kBufferSize = 2048; + +class RemoteTestServerSpawnerRequest::Core : public URLRequest::Delegate { + public: + Core(); + ~Core() override; + + void SendRequest(const GURL& url, const std::string& post_data); + + // Blocks until request is finished. If |response| isn't nullptr then server + // response is copied to *response. Returns true if the request was completed + // successfully. + bool WaitForCompletion(std::string* response) WARN_UNUSED_RESULT; + + private: + // URLRequest::Delegate methods. + void OnResponseStarted(URLRequest* request, int net_error) override; + void OnReadCompleted(URLRequest* request, int num_bytes) override; + + void ReadResponse(); + void OnCommandCompleted(int net_error); + void OnTimeout(); + + // Request results. + int result_code_ = 0; + std::string data_received_; + + // WaitableEvent to notify when the request is finished. + base::WaitableEvent event_; + + std::unique_ptr<URLRequestContext> context_; + std::unique_ptr<URLRequest> request_; + + scoped_refptr<IOBuffer> read_buffer_; + + std::unique_ptr<base::OneShotTimer> timeout_timer_; + + THREAD_CHECKER(thread_checker_); + + DISALLOW_COPY_AND_ASSIGN(Core); +}; + +RemoteTestServerSpawnerRequest::Core::Core() + : event_(base::WaitableEvent::ResetPolicy::AUTOMATIC, + base::WaitableEvent::InitialState::NOT_SIGNALED), + read_buffer_(new IOBuffer(kBufferSize)) { + DETACH_FROM_THREAD(thread_checker_); +} + +void RemoteTestServerSpawnerRequest::Core::SendRequest( + const GURL& url, + const std::string& post_data) { + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); + + // Prepare the URLRequest for sending the command. + DCHECK(!request_.get()); + context_.reset(new TestURLRequestContext); + request_ = context_->CreateRequest(url, DEFAULT_PRIORITY, this); + + if (post_data.empty()) { + request_->set_method("GET"); + } else { + request_->set_method("POST"); + std::unique_ptr<UploadElementReader> reader( + UploadOwnedBytesElementReader::CreateWithString(post_data)); + request_->set_upload( + ElementsUploadDataStream::CreateWithReader(std::move(reader), 0)); + request_->SetExtraRequestHeaderByName(HttpRequestHeaders::kContentType, + "application/json", + /*override=*/true); + } + + timeout_timer_ = std::make_unique<base::OneShotTimer>(); + timeout_timer_->Start(FROM_HERE, TestTimeouts::action_max_timeout(), + base::Bind(&Core::OnTimeout, base::Unretained(this))); + + request_->Start(); +} + +RemoteTestServerSpawnerRequest::Core::~Core() { + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); +} + +bool RemoteTestServerSpawnerRequest::Core::WaitForCompletion( + std::string* response) { + // Called by RemoteTestServerSpawnerRequest::WaitForCompletion() on the main + // thread. + + event_.Wait(); + if (response) + *response = data_received_; + return result_code_ == OK; +} + +void RemoteTestServerSpawnerRequest::Core::OnTimeout() { + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); + + int result = request_->CancelWithError(ERR_TIMED_OUT); + OnCommandCompleted(result); +} + +void RemoteTestServerSpawnerRequest::Core::OnCommandCompleted(int net_error) { + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); + DCHECK_NE(ERR_IO_PENDING, net_error); + DCHECK(!event_.IsSignaled()); + + // If request has failed, return the error code. + if (net_error != OK) { + LOG(ERROR) << "request failed, error: " << ErrorToString(net_error); + result_code_ = net_error; + } else if (request_->GetResponseCode() != 200) { + LOG(ERROR) << "Spawner server returned bad status: " + << request_->response_headers()->GetStatusLine() << ", " + << data_received_; + result_code_ = ERR_FAILED; + } + + if (result_code_ != OK) + data_received_.clear(); + + request_.reset(); + context_.reset(); + timeout_timer_.reset(); + + event_.Signal(); +} + +void RemoteTestServerSpawnerRequest::Core::ReadResponse() { + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); + + while (true) { + int result = request_->Read(read_buffer_.get(), kBufferSize); + if (result == ERR_IO_PENDING) + return; + + if (result <= 0) { + OnCommandCompleted(result); + return; + } + + data_received_.append(read_buffer_->data(), result); + } +} + +void RemoteTestServerSpawnerRequest::Core::OnResponseStarted( + URLRequest* request, + int net_error) { + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); + DCHECK_NE(ERR_IO_PENDING, net_error); + DCHECK_EQ(request, request_.get()); + + if (net_error != OK) { + OnCommandCompleted(net_error); + return; + } + + ReadResponse(); +} + +void RemoteTestServerSpawnerRequest::Core::OnReadCompleted(URLRequest* request, + int read_result) { + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); + DCHECK_NE(ERR_IO_PENDING, read_result); + DCHECK_EQ(request, request_.get()); + + if (read_result <= 0) { + OnCommandCompleted(read_result); + return; + } + + data_received_.append(read_buffer_->data(), read_result); + + ReadResponse(); +} + +RemoteTestServerSpawnerRequest::RemoteTestServerSpawnerRequest( + scoped_refptr<base::SingleThreadTaskRunner> io_task_runner, + const GURL& url, + const std::string& post_data) + : io_task_runner_(io_task_runner), + core_(new Core()), + allowed_port_(new ScopedPortException(url.EffectiveIntPort())) { + io_task_runner_->PostTask( + FROM_HERE, base::BindOnce(&Core::SendRequest, + base::Unretained(core_.get()), url, post_data)); +} + +RemoteTestServerSpawnerRequest::~RemoteTestServerSpawnerRequest() { + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); + io_task_runner_->DeleteSoon(FROM_HERE, core_.release()); +} + +bool RemoteTestServerSpawnerRequest::WaitForCompletion(std::string* response) { + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); + return core_->WaitForCompletion(response); +} + +} // namespace net diff --git a/chromium/net/test/spawned_test_server/remote_test_server_spawner_request.h b/chromium/net/test/spawned_test_server/remote_test_server_spawner_request.h new file mode 100644 index 00000000000..7abc4f521f5 --- /dev/null +++ b/chromium/net/test/spawned_test_server/remote_test_server_spawner_request.h @@ -0,0 +1,64 @@ +// Copyright 2017 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. + +#ifndef NET_TEST_SPAWNED_TEST_SERVER_REMOTE_TEST_SERVER_SPAWNER_REQUEST_H_ +#define NET_TEST_SPAWNED_TEST_SERVER_REMOTE_TEST_SERVER_SPAWNER_REQUEST_H_ + +#include <memory> +#include <string> + +#include "base/macros.h" +#include "base/memory/ref_counted.h" +#include "base/threading/thread_checker.h" + +class GURL; + +namespace base { +class SingleThreadTaskRunner; +} // namespace base + +namespace net { + +class ScopedPortException; + +// RemoteTestServerSpawnerRequest is used by RemoteTestServer to send a request +// to the test server spawner. +class RemoteTestServerSpawnerRequest { + public: + // Queries the specified URL. If |post_data| is empty then a GET request is + // sent. Otherwise |post_data| must be a json blob which is sent as a POST + // request body. + RemoteTestServerSpawnerRequest( + scoped_refptr<base::SingleThreadTaskRunner> io_task_runner, + const GURL& url, + const std::string& post_data); + ~RemoteTestServerSpawnerRequest(); + + // Blocks until request is finished. If |response| isn't nullptr then server + // response is copied to *response. Returns true if the request was completed + // successfully. + bool WaitForCompletion(std::string* response) WARN_UNUSED_RESULT; + + private: + class Core; + + scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_; + + // Core runs on |io_task_runner_|. It's responsible for sending the request + // and reading the response. + std::unique_ptr<Core> core_; + + // Helper to add spawner port to the list of the globally explicitly allowed + // ports. It needs to be here instead of in Core because ScopedPortException + // is not thread-safe. + std::unique_ptr<ScopedPortException> allowed_port_; + + THREAD_CHECKER(thread_checker_); + + DISALLOW_COPY_AND_ASSIGN(RemoteTestServerSpawnerRequest); +}; + +} // namespace net + +#endif // NET_TEST_SPAWNED_TEST_SERVER_REMOTE_TEST_SERVER_SPAWNER_REQUEST_H_ diff --git a/chromium/net/test/spawned_test_server/spawner_communicator.cc b/chromium/net/test/spawned_test_server/spawner_communicator.cc deleted file mode 100644 index 89680456373..00000000000 --- a/chromium/net/test/spawned_test_server/spawner_communicator.cc +++ /dev/null @@ -1,346 +0,0 @@ -// Copyright (c) 2012 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 "net/test/spawned_test_server/spawner_communicator.h" - -#include <inttypes.h> - -#include <limits> -#include <utility> - -#include "base/json/json_reader.h" -#include "base/location.h" -#include "base/logging.h" -#include "base/macros.h" -#include "base/message_loop/message_loop.h" -#include "base/single_thread_task_runner.h" -#include "base/strings/stringprintf.h" -#include "base/supports_user_data.h" -#include "base/test/test_timeouts.h" -#include "base/threading/thread_task_runner_handle.h" -#include "base/time/time.h" -#include "base/values.h" -#include "build/build_config.h" -#include "net/base/elements_upload_data_stream.h" -#include "net/base/port_util.h" -#include "net/base/request_priority.h" -#include "net/base/upload_bytes_element_reader.h" -#include "net/http/http_response_headers.h" -#include "net/url_request/url_request_test_util.h" -#include "url/gurl.h" - -namespace net { - -namespace { - -int kBufferSize = 2048; - -// A class to hold all data needed to send a command to spawner server. -class SpawnerRequestData : public base::SupportsUserData::Data { - public: - SpawnerRequestData(int* result_code, std::string* data_received) - : buf_(new IOBuffer(kBufferSize)), - result_code_(result_code), - data_received_(data_received) { - DCHECK(result_code); - *result_code_ = OK; - DCHECK(data_received); - data_received_->clear(); - } - - ~SpawnerRequestData() override {} - - IOBuffer* buf() const { return buf_.get(); } - - bool IsResultOK() const { return *result_code_ == OK; } - - const std::string& data_received() const { return *data_received_; } - void ClearReceivedData() { data_received_->clear(); } - - void SetResultCode(int result_code) { *result_code_ = result_code; } - - void IncreaseResponseStartedCount() { response_started_count_++; } - - int response_started_count() const { return response_started_count_; } - - // Write data read from URLRequest::Read() to |data_received_|. Returns true - // if |num_bytes| is great than 0. |num_bytes| is 0 for EOF, < 0 on errors. - bool ConsumeBytesRead(int num_bytes) { - // Error while reading, or EOF. - if (num_bytes <= 0) - return false; - - data_received_->append(buf_->data(), num_bytes); - return true; - } - - private: - // Buffer that URLRequest writes into. - scoped_refptr<IOBuffer> buf_; - - // Holds the error condition that was hit on the current request, or OK. - int* result_code_; - - // Data received from server; - std::string* data_received_; - - // Used to track how many times the OnResponseStarted get called after - // sending a command to spawner server. - int response_started_count_ = 0; - - DISALLOW_COPY_AND_ASSIGN(SpawnerRequestData); -}; - -} // namespace - -SpawnerCommunicator::SpawnerCommunicator(const RemoteTestServerConfig& config) - : config_(config), - io_thread_("spawner_communicator"), - event_(base::WaitableEvent::ResetPolicy::AUTOMATIC, - base::WaitableEvent::InitialState::NOT_SIGNALED) {} - -SpawnerCommunicator::~SpawnerCommunicator() { - DCHECK(!io_thread_.IsRunning()); -} - -void SpawnerCommunicator::WaitForResponse() { - DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); - event_.Wait(); - event_.Reset(); -} - -void SpawnerCommunicator::StartIOThread() { - DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); - if (io_thread_.IsRunning()) - return; - - bool thread_started = io_thread_.StartWithOptions( - base::Thread::Options(base::MessageLoop::TYPE_IO, 0)); - DCHECK(thread_started); -} - -void SpawnerCommunicator::Shutdown() { - DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); - DCHECK(io_thread_.IsRunning()); - // The request and its context should be created and destroyed only on the - // IO thread. - DCHECK(!cur_request_.get()); - DCHECK(!context_.get()); - io_thread_.Stop(); - allowed_port_.reset(); -} - -int SpawnerCommunicator::SendCommandAndWaitForResult( - const std::string& command, - const std::string& post_data, - std::string* data_received) { - DCHECK(data_received); - - // Start the communicator thread to talk to test server spawner. - StartIOThread(); - DCHECK(io_thread_.message_loop()); - - // Since the method will be blocked until SpawnerCommunicator gets result - // from the spawner server or timed-out. It's safe to use base::Unretained - // when using base::Bind. - int result_code; - io_thread_.task_runner()->PostTask( - FROM_HERE, - base::Bind(&SpawnerCommunicator::SendCommandAndWaitForResultOnIOThread, - base::Unretained(this), command, post_data, &result_code, - data_received)); - WaitForResponse(); - - return result_code; -} - -void SpawnerCommunicator::SendCommandAndWaitForResultOnIOThread( - const std::string& command, - const std::string& post_data, - int* result_code, - std::string* data_received) { - DCHECK(io_thread_.task_runner()->BelongsToCurrentThread()); - - // Prepare the URLRequest for sending the command. - DCHECK(!cur_request_.get()); - context_.reset(new TestURLRequestContext); - GURL url = config_.GetSpawnerUrl(command); - allowed_port_ = std::make_unique<ScopedPortException>(url.EffectiveIntPort()); - cur_request_ = context_->CreateRequest(url, DEFAULT_PRIORITY, this); - - DCHECK(cur_request_); - cur_request_->SetUserData( - this, std::make_unique<SpawnerRequestData>(result_code, data_received)); - - if (post_data.empty()) { - cur_request_->set_method("GET"); - } else { - cur_request_->set_method("POST"); - std::unique_ptr<UploadElementReader> reader( - UploadOwnedBytesElementReader::CreateWithString(post_data)); - cur_request_->set_upload( - ElementsUploadDataStream::CreateWithReader(std::move(reader), 0)); - HttpRequestHeaders headers; - headers.SetHeader(HttpRequestHeaders::kContentType, - "application/json"); - cur_request_->SetExtraRequestHeaders(headers); - } - - timeout_timer_ = std::make_unique<base::OneShotTimer>(); - timeout_timer_->Start( - FROM_HERE, TestTimeouts::action_max_timeout(), - base::Bind(&SpawnerCommunicator::OnTimeout, base::Unretained(this))); - - // Start the request. - cur_request_->Start(); -} - -void SpawnerCommunicator::OnTimeout() { - DCHECK(io_thread_.task_runner()->BelongsToCurrentThread()); - - SpawnerRequestData* data = - static_cast<SpawnerRequestData*>(cur_request_->GetUserData(this)); - DCHECK(data); - - // Set the result code and cancel the timed-out task. - int result = cur_request_->CancelWithError(ERR_TIMED_OUT); - OnSpawnerCommandCompleted(cur_request_.get(), result); -} - -void SpawnerCommunicator::OnSpawnerCommandCompleted(URLRequest* request, - int net_error) { - DCHECK(io_thread_.task_runner()->BelongsToCurrentThread()); - DCHECK_NE(ERR_IO_PENDING, net_error); - - if (!cur_request_.get()) - return; - DCHECK_EQ(request, cur_request_.get()); - SpawnerRequestData* data = - static_cast<SpawnerRequestData*>(cur_request_->GetUserData(this)); - DCHECK(data); - - // If request has failed, return the error code. - if (net_error != OK) { - LOG(ERROR) << "request failed, error: " << ErrorToString(net_error); - data->SetResultCode(net_error); - } else if (request->GetResponseCode() != 200) { - LOG(ERROR) << "Spawner server returned bad status: " - << request->response_headers()->GetStatusLine() << ", " - << data->data_received(); - data->SetResultCode(ERR_FAILED); - } else { - DCHECK_EQ(1, data->response_started_count()); - } - - if (!data->IsResultOK()) { - // Clear the buffer of received data if any net error happened. - data->ClearReceivedData(); - } - - // Clear current request to indicate the completion of sending a command - // to spawner server and getting the result. - cur_request_.reset(); - context_.reset(); - timeout_timer_.reset(); - - // Wakeup the caller in user thread. - event_.Signal(); -} - -void SpawnerCommunicator::ReadResult(URLRequest* request) { - DCHECK(io_thread_.task_runner()->BelongsToCurrentThread()); - DCHECK_EQ(request, cur_request_.get()); - SpawnerRequestData* data = - static_cast<SpawnerRequestData*>(cur_request_->GetUserData(this)); - DCHECK(data); - - IOBuffer* buf = data->buf(); - // Read as many bytes as are available synchronously. - while (true) { - int rv = request->Read(buf, kBufferSize); - if (rv == ERR_IO_PENDING) - return; - - if (rv < 0) { - OnSpawnerCommandCompleted(request, rv); - return; - } - - if (!data->ConsumeBytesRead(rv)) { - OnSpawnerCommandCompleted(request, rv); - return; - } - } -} - -void SpawnerCommunicator::OnResponseStarted(URLRequest* request, - int net_error) { - DCHECK(io_thread_.task_runner()->BelongsToCurrentThread()); - DCHECK_EQ(request, cur_request_.get()); - DCHECK_NE(ERR_IO_PENDING, net_error); - - SpawnerRequestData* data = - static_cast<SpawnerRequestData*>(cur_request_->GetUserData(this)); - DCHECK(data); - - data->IncreaseResponseStartedCount(); - - if (net_error != OK) { - OnSpawnerCommandCompleted(request, net_error); - return; - } - - ReadResult(request); -} - -void SpawnerCommunicator::OnReadCompleted(URLRequest* request, int num_bytes) { - DCHECK(io_thread_.task_runner()->BelongsToCurrentThread()); - DCHECK_NE(ERR_IO_PENDING, num_bytes); - - if (!cur_request_.get()) - return; - DCHECK_EQ(request, cur_request_.get()); - SpawnerRequestData* data = - static_cast<SpawnerRequestData*>(cur_request_->GetUserData(this)); - DCHECK(data); - - if (data->ConsumeBytesRead(num_bytes)) { - // Keep reading. - ReadResult(request); - } else { - // |bytes_read| < 0 - int net_error = num_bytes; - OnSpawnerCommandCompleted(request, net_error); - } -} - -bool SpawnerCommunicator::StartServer(const std::string& arguments, - std::string* server_data) { - DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); - // Send the start command to spawner server to start the Python test server - // on remote machine. - int result = SendCommandAndWaitForResult("start", arguments, server_data); - return result == OK; -} - -bool SpawnerCommunicator::StopServer(uint16_t port) { - DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); - // It's OK to stop the SpawnerCommunicator without starting it. Some tests - // have test server on their test fixture but do not actually use it. - if (!io_thread_.IsRunning()) - return true; - - // When the test is done, ask the test server spawner to kill the test server - // on the remote machine. - std::string server_return_data; - std::string command = base::StringPrintf("kill?port=%" PRIu16, port); - int result = - SendCommandAndWaitForResult(command, std::string(), &server_return_data); - Shutdown(); - if (result != OK || server_return_data != "killed") - return false; - return true; -} - -} // namespace net diff --git a/chromium/net/test/spawned_test_server/spawner_communicator.h b/chromium/net/test/spawned_test_server/spawner_communicator.h deleted file mode 100644 index 958cc79433c..00000000000 --- a/chromium/net/test/spawned_test_server/spawner_communicator.h +++ /dev/null @@ -1,144 +0,0 @@ -// Copyright (c) 2012 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. - -#ifndef NET_TEST_SPAWNED_TEST_SERVER_SPAWNER_COMMUNICATOR_H_ -#define NET_TEST_SPAWNED_TEST_SERVER_SPAWNER_COMMUNICATOR_H_ - -#include <stdint.h> - -#include <memory> -#include <string> - -#include "base/macros.h" -#include "base/synchronization/waitable_event.h" -#include "base/threading/thread.h" -#include "base/threading/thread_checker.h" -#include "net/test/spawned_test_server/remote_test_server_config.h" -#include "net/url_request/url_request.h" - -namespace base { -class OneShotTimer; -} // namespace base - -namespace net { - -class ScopedPortException; - -// SpawnerCommunicator communicates with a spawner server that runs on a -// remote system. -// -// The test server used by unit tests is written in Python. However, Android -// does not support running Python code, so the test server cannot run on the -// same device running unit tests. -// -// The actual test server is executed on the host machine, while the unit tests -// themselves continue running on the device. To control the test server on the -// host machine, a second HTTP server is started, the spawner server, which -// controls the life cycle of remote test servers. Calls to start/kill the -// SpawnedTestServer are then redirected to the spawner server via -// this spawner communicator. -// -// Currently only three commands are supported by spawner. -// -// (1) Start Python test server, format is: -// Path: "/start". -// Method: "POST". -// Data to server: all arguments needed to launch the Python test server, in -// JSON format. -// Data from server: a JSON dict includes the following two field if success, -// "port": the port the Python test server actually listen on that. -// "message": must be "started". -// -// (2) Kill Python test server, format is: -// Path: "/kill". -// Method: "GET". -// Data to server: port=<server_port>. -// Data from server: String "killed" returned if success. -// -// (3) Ping Python test server to see whether it is alive, format is: -// Path: "/ping". -// Method: "GET". -// Data to server: None. -// Data from server: String "ready" returned if success. -// -// The internal I/O thread is required by net stack to perform net I/O. -// The Start/StopServer methods block the caller thread until result is -// fetched from spawner server or timed-out. -class SpawnerCommunicator : public URLRequest::Delegate { - public: - explicit SpawnerCommunicator(const RemoteTestServerConfig& config); - ~SpawnerCommunicator() override; - - // Starts an instance of the Python test server on the host/ machine.If - // successfully started, returns true, setting |*server_data| to the server - // data returned by the spawner. - bool StartServer(const std::string& arguments, - std::string* server_data) WARN_UNUSED_RESULT; - bool StopServer(uint16_t port) WARN_UNUSED_RESULT; - - private: - // Starts the IO thread. Called on the user thread. - void StartIOThread(); - - // Shuts down the remote test server spawner. Called on the user thread. - void Shutdown(); - - // Waits for the server response on IO thread. Called on the user thread. - void WaitForResponse(); - - // Sends a command to the test server over HTTP, returning response data in - // |*data_received|, which must not be nullptr. If |post_data| is empty, HTTP - // GET will be used to send |command|. If |post_data| is non-empty, performs - // an HTTP POST. This method is called on the user thread. - int SendCommandAndWaitForResult(const std::string& command, - const std::string& post_data, - std::string* data_received); - - // Performs the command sending on the IO thread. Called on the IO thread. - void SendCommandAndWaitForResultOnIOThread(const std::string& command, - const std::string& post_data, - int* result_code, - std::string* data_received); - - // URLRequest::Delegate methods. Called on the IO thread. - void OnResponseStarted(URLRequest* request, int net_error) override; - void OnReadCompleted(URLRequest* request, int num_bytes) override; - - // Reads Result from the response. Called on the IO thread. - void ReadResult(URLRequest* request); - - // Called on the IO thread upon completion of the spawner command. - void OnSpawnerCommandCompleted(URLRequest* request, int net_error); - - // Timeout timer task. Runs on IO thread. - void OnTimeout(); - - const RemoteTestServerConfig config_; - - // A thread to communicate with test_spawner server. - base::Thread io_thread_; - - // WaitableEvent to notify whether the communication is done. - base::WaitableEvent event_; - - // Helper to add spawner port to the list of the globally explicitly allowed - // ports. - std::unique_ptr<ScopedPortException> allowed_port_; - - // Request context used by |cur_request_|. - std::unique_ptr<URLRequestContext> context_; - - // The current (in progress) request, or NULL. - std::unique_ptr<URLRequest> cur_request_; - - std::unique_ptr<base::OneShotTimer> timeout_timer_; - - THREAD_CHECKER(thread_checker_); - - DISALLOW_COPY_AND_ASSIGN(SpawnerCommunicator); -}; - -} // namespace net - -#endif // NET_TEST_SPAWNED_TEST_SERVER_SPAWNER_COMMUNICATOR_H_ diff --git a/chromium/net/test/url_request/url_request_hanging_read_job.cc b/chromium/net/test/url_request/url_request_hanging_read_job.cc index 2c947c884bb..1e1943578ff 100644 --- a/chromium/net/test/url_request/url_request_hanging_read_job.cc +++ b/chromium/net/test/url_request/url_request_hanging_read_job.cc @@ -4,11 +4,11 @@ #include "net/test/url_request/url_request_hanging_read_job.h" +#include <memory> #include <string> #include "base/bind.h" #include "base/location.h" -#include "base/memory/ptr_util.h" #include "base/strings/stringprintf.h" #include "base/threading/thread_task_runner_handle.h" #include "net/http/http_response_headers.h" diff --git a/chromium/net/test/url_request/url_request_mock_data_job.cc b/chromium/net/test/url_request/url_request_mock_data_job.cc index f526a35a67e..256acf2bf84 100644 --- a/chromium/net/test/url_request/url_request_mock_data_job.cc +++ b/chromium/net/test/url_request/url_request_mock_data_job.cc @@ -4,10 +4,11 @@ #include "net/test/url_request/url_request_mock_data_job.h" +#include <memory> + #include "base/bind.h" #include "base/location.h" #include "base/macros.h" -#include "base/memory/ptr_util.h" #include "base/single_thread_task_runner.h" #include "base/strings/string_number_conversions.h" #include "base/strings/stringprintf.h" |