| Index: net/test/spawner_communicator.cc
|
| diff --git a/net/test/spawner_communicator.cc b/net/test/spawner_communicator.cc
|
| deleted file mode 100644
|
| index 97bc8f8e80172b2d9448f093557fb0ccf8a82c0a..0000000000000000000000000000000000000000
|
| --- a/net/test/spawner_communicator.cc
|
| +++ /dev/null
|
| @@ -1,377 +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/spawner_communicator.h"
|
| -
|
| -#include "base/json/json_reader.h"
|
| -#include "base/logging.h"
|
| -#include "base/stringprintf.h"
|
| -#include "base/supports_user_data.h"
|
| -#include "base/test/test_timeouts.h"
|
| -#include "base/time.h"
|
| -#include "base/values.h"
|
| -#include "build/build_config.h"
|
| -#include "googleurl/src/gurl.h"
|
| -#include "net/base/net_util.h"
|
| -#include "net/base/upload_bytes_element_reader.h"
|
| -#include "net/base/upload_data_stream.h"
|
| -#include "net/http/http_response_headers.h"
|
| -#include "net/url_request/url_request_test_util.h"
|
| -
|
| -namespace net {
|
| -
|
| -namespace {
|
| -
|
| -GURL GenerateSpawnerCommandURL(const std::string& command, uint16 port) {
|
| - // Always performs HTTP request for sending command to the spawner server.
|
| - return GURL(base::StringPrintf("%s:%u/%s", "http://127.0.0.1", port,
|
| - command.c_str()));
|
| -}
|
| -
|
| -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 id, int* result_code, std::string* data_received)
|
| - : request_id_(id),
|
| - buf_(new IOBuffer(kBufferSize)),
|
| - result_code_(result_code),
|
| - data_received_(data_received),
|
| - response_started_count_(0) {
|
| - DCHECK(result_code);
|
| - *result_code_ = OK;
|
| - DCHECK(data_received);
|
| - data_received_->clear();
|
| - }
|
| -
|
| - virtual ~SpawnerRequestData() {}
|
| -
|
| - bool DoesRequestIdMatch(int request_id) const {
|
| - return request_id_ == request_id;
|
| - }
|
| -
|
| - IOBuffer* buf() const { return buf_.get(); }
|
| -
|
| - bool IsResultOK() const { return *result_code_ == OK; }
|
| -
|
| - 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:
|
| - // Unique ID for the current request.
|
| - int request_id_;
|
| -
|
| - // 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_;
|
| -
|
| - DISALLOW_COPY_AND_ASSIGN(SpawnerRequestData);
|
| -};
|
| -
|
| -} // namespace
|
| -
|
| -SpawnerCommunicator::SpawnerCommunicator(uint16 port)
|
| - : io_thread_("spawner_communicator"),
|
| - event_(false, false),
|
| - port_(port),
|
| - next_id_(0),
|
| - weak_factory_(this),
|
| - is_running_(false) {}
|
| -
|
| -SpawnerCommunicator::~SpawnerCommunicator() {
|
| - DCHECK(!is_running_);
|
| -}
|
| -
|
| -void SpawnerCommunicator::WaitForResponse() {
|
| - DCHECK_NE(MessageLoop::current(), io_thread_.message_loop());
|
| - event_.Wait();
|
| - event_.Reset();
|
| -}
|
| -
|
| -void SpawnerCommunicator::StartIOThread() {
|
| - DCHECK_NE(MessageLoop::current(), io_thread_.message_loop());
|
| - if (is_running_)
|
| - return;
|
| -
|
| - allowed_port_.reset(new ScopedPortException(port_));
|
| - base::Thread::Options options;
|
| - options.message_loop_type = MessageLoop::TYPE_IO;
|
| - is_running_ = io_thread_.StartWithOptions(options);
|
| - DCHECK(is_running_);
|
| -}
|
| -
|
| -void SpawnerCommunicator::Shutdown() {
|
| - DCHECK_NE(MessageLoop::current(), io_thread_.message_loop());
|
| - DCHECK(is_running_);
|
| - // The request and its context should be created and destroyed only on the
|
| - // IO thread.
|
| - DCHECK(!cur_request_.get());
|
| - DCHECK(!context_.get());
|
| - is_running_ = false;
|
| - io_thread_.Stop();
|
| - allowed_port_.reset();
|
| -}
|
| -
|
| -void SpawnerCommunicator::SendCommandAndWaitForResult(
|
| - const std::string& command,
|
| - const std::string& post_data,
|
| - int* result_code,
|
| - std::string* data_received) {
|
| - if (!result_code || !data_received)
|
| - return;
|
| - // 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.
|
| - io_thread_.message_loop()->PostTask(FROM_HERE, base::Bind(
|
| - &SpawnerCommunicator::SendCommandAndWaitForResultOnIOThread,
|
| - base::Unretained(this), command, post_data, result_code, data_received));
|
| - WaitForResponse();
|
| -}
|
| -
|
| -void SpawnerCommunicator::SendCommandAndWaitForResultOnIOThread(
|
| - const std::string& command,
|
| - const std::string& post_data,
|
| - int* result_code,
|
| - std::string* data_received) {
|
| - MessageLoop* loop = io_thread_.message_loop();
|
| - DCHECK(loop);
|
| - DCHECK_EQ(MessageLoop::current(), loop);
|
| -
|
| - // Prepare the URLRequest for sending the command.
|
| - DCHECK(!cur_request_.get());
|
| - context_.reset(new TestURLRequestContext);
|
| - cur_request_.reset(context_->CreateRequest(
|
| - GenerateSpawnerCommandURL(command, port_), this));
|
| - DCHECK(cur_request_.get());
|
| - int current_request_id = ++next_id_;
|
| - SpawnerRequestData* data = new SpawnerRequestData(current_request_id,
|
| - result_code,
|
| - data_received);
|
| - DCHECK(data);
|
| - cur_request_->SetUserData(this, data);
|
| -
|
| - if (post_data.empty()) {
|
| - cur_request_->set_method("GET");
|
| - } else {
|
| - cur_request_->set_method("POST");
|
| - scoped_ptr<UploadElementReader> reader(
|
| - UploadOwnedBytesElementReader::CreateWithString(post_data));
|
| - cur_request_->set_upload(make_scoped_ptr(
|
| - UploadDataStream::CreateWithReader(reader.Pass(), 0)));
|
| - net::HttpRequestHeaders headers;
|
| - headers.SetHeader(net::HttpRequestHeaders::kContentType,
|
| - "application/json");
|
| - cur_request_->SetExtraRequestHeaders(headers);
|
| - }
|
| -
|
| - // Post a task to timeout this request if it takes too long.
|
| - MessageLoop::current()->PostDelayedTask(
|
| - FROM_HERE,
|
| - base::Bind(&SpawnerCommunicator::OnTimeout, weak_factory_.GetWeakPtr(),
|
| - current_request_id),
|
| - TestTimeouts::action_max_timeout());
|
| -
|
| - // Start the request.
|
| - cur_request_->Start();
|
| -}
|
| -
|
| -void SpawnerCommunicator::OnTimeout(int id) {
|
| - // Timeout tasks may outlive the URLRequest they reference. Make sure it
|
| - // is still applicable.
|
| - if (!cur_request_.get())
|
| - return;
|
| - SpawnerRequestData* data =
|
| - static_cast<SpawnerRequestData*>(cur_request_->GetUserData(this));
|
| - DCHECK(data);
|
| -
|
| - if (!data->DoesRequestIdMatch(id))
|
| - return;
|
| - // Set the result code and cancel the timed-out task.
|
| - data->SetResultCode(ERR_TIMED_OUT);
|
| - cur_request_->Cancel();
|
| - OnSpawnerCommandCompleted(cur_request_.get());
|
| -}
|
| -
|
| -void SpawnerCommunicator::OnSpawnerCommandCompleted(URLRequest* request) {
|
| - if (!cur_request_.get())
|
| - return;
|
| - DCHECK_EQ(request, cur_request_.get());
|
| - SpawnerRequestData* data =
|
| - static_cast<SpawnerRequestData*>(cur_request_->GetUserData(this));
|
| - DCHECK(data);
|
| -
|
| - // If request is faild,return the error code.
|
| - if (!cur_request_->status().is_success())
|
| - data->SetResultCode(cur_request_->status().error());
|
| -
|
| - if (!data->IsResultOK()) {
|
| - LOG(ERROR) << "request failed, status: "
|
| - << static_cast<int>(request->status().status())
|
| - << ", error: " << request->status().error();
|
| - // Clear the buffer of received data if any net error happened.
|
| - data->ClearReceivedData();
|
| - } else {
|
| - DCHECK_EQ(1, data->response_started_count());
|
| - }
|
| -
|
| - // Clear current request to indicate the completion of sending a command
|
| - // to spawner server and getting the result.
|
| - cur_request_.reset();
|
| - context_.reset();
|
| - // Invalidate the weak pointers on the IO thread.
|
| - weak_factory_.InvalidateWeakPtrs();
|
| -
|
| - // Wakeup the caller in user thread.
|
| - event_.Signal();
|
| -}
|
| -
|
| -void SpawnerCommunicator::ReadResult(URLRequest* request) {
|
| - 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 num_bytes;
|
| - if (!request->Read(buf, kBufferSize, &num_bytes)) {
|
| - // Check whether the read failed synchronously.
|
| - if (!request->status().is_io_pending())
|
| - OnSpawnerCommandCompleted(request);
|
| - return;
|
| - }
|
| - if (!data->ConsumeBytesRead(num_bytes)) {
|
| - OnSpawnerCommandCompleted(request);
|
| - return;
|
| - }
|
| - }
|
| -}
|
| -
|
| -void SpawnerCommunicator::OnResponseStarted(URLRequest* request) {
|
| - DCHECK_EQ(request, cur_request_.get());
|
| - SpawnerRequestData* data =
|
| - static_cast<SpawnerRequestData*>(cur_request_->GetUserData(this));
|
| - DCHECK(data);
|
| -
|
| - data->IncreaseResponseStartedCount();
|
| -
|
| - if (!request->status().is_success()) {
|
| - OnSpawnerCommandCompleted(request);
|
| - return;
|
| - }
|
| -
|
| - // Require HTTP responses to have a success status code.
|
| - if (request->GetResponseCode() != 200) {
|
| - LOG(ERROR) << "Spawner server returned bad status: "
|
| - << request->response_headers()->GetStatusLine();
|
| - data->SetResultCode(ERR_FAILED);
|
| - request->Cancel();
|
| - OnSpawnerCommandCompleted(request);
|
| - return;
|
| - }
|
| -
|
| - ReadResult(request);
|
| -}
|
| -
|
| -void SpawnerCommunicator::OnReadCompleted(URLRequest* request, int 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 {
|
| - OnSpawnerCommandCompleted(request);
|
| - }
|
| -}
|
| -
|
| -bool SpawnerCommunicator::StartServer(const std::string& arguments,
|
| - uint16* port) {
|
| - *port = 0;
|
| - // Send the start command to spawner server to start the Python test server
|
| - // on remote machine.
|
| - std::string server_return_data;
|
| - int result_code;
|
| - SendCommandAndWaitForResult("start", arguments, &result_code,
|
| - &server_return_data);
|
| - if (OK != result_code || server_return_data.empty())
|
| - return false;
|
| -
|
| - // Check whether the data returned from spawner server is JSON-formatted.
|
| - scoped_ptr<base::Value> value(base::JSONReader::Read(server_return_data));
|
| - if (!value.get() || !value->IsType(base::Value::TYPE_DICTIONARY)) {
|
| - LOG(ERROR) << "Invalid server data: " << server_return_data.c_str();
|
| - return false;
|
| - }
|
| -
|
| - // Check whether spawner server returns valid data.
|
| - DictionaryValue* server_data = static_cast<DictionaryValue*>(value.get());
|
| - std::string message;
|
| - if (!server_data->GetString("message", &message) || message != "started") {
|
| - LOG(ERROR) << "Invalid message in server data: ";
|
| - return false;
|
| - }
|
| - int int_port;
|
| - if (!server_data->GetInteger("port", &int_port) || int_port <= 0 ||
|
| - int_port > kuint16max) {
|
| - LOG(ERROR) << "Invalid port value: " << int_port;
|
| - return false;
|
| - }
|
| - *port = static_cast<uint16>(int_port);
|
| - return true;
|
| -}
|
| -
|
| -bool SpawnerCommunicator::StopServer() {
|
| - // 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 (!is_running_)
|
| - 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;
|
| - int result_code;
|
| - SendCommandAndWaitForResult("kill", "", &result_code, &server_return_data);
|
| - Shutdown();
|
| - if (OK != result_code || server_return_data != "killed")
|
| - return false;
|
| - return true;
|
| -}
|
| -
|
| -} // namespace net
|
|
|