Revert "Fix broken channel icon in chrome://help on CrOS" and try again
[chromium-blink-merge.git] / net / test / spawned_test_server / remote_test_server.cc
blob0e1303e066c235b387fbeac524cb9afd8cdc8ff1
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "net/test/spawned_test_server/remote_test_server.h"
7 #include <vector>
9 #include "base/base_paths.h"
10 #include "base/files/file_path.h"
11 #include "base/files/file_util.h"
12 #include "base/json/json_writer.h"
13 #include "base/logging.h"
14 #include "base/path_service.h"
15 #include "base/strings/string_number_conversions.h"
16 #include "base/strings/string_split.h"
17 #include "base/values.h"
18 #include "net/base/host_port_pair.h"
19 #include "net/base/net_errors.h"
20 #include "net/test/spawned_test_server/spawner_communicator.h"
21 #include "url/gurl.h"
23 namespace net {
25 namespace {
27 // To reduce the running time of tests, tests may be sharded across several
28 // devices. This means that it may be necessary to support multiple instances
29 // of the test server spawner and the Python test server simultaneously on the
30 // same host. Each pair of (test server spawner, Python test server) correspond
31 // to a single testing device.
32 // The mapping between the test server spawner and the individual Python test
33 // servers is written to a file on the device prior to executing any tests.
34 base::FilePath GetTestServerPortInfoFile() {
35 #if !defined(OS_ANDROID)
36 return base::FilePath("/tmp/net-test-server-ports");
37 #else
38 base::FilePath test_data_dir;
39 PathService::Get(base::DIR_ANDROID_EXTERNAL_STORAGE, &test_data_dir);
40 return test_data_dir.Append("net-test-server-ports");
41 #endif
44 // Please keep it sync with dictionary SERVER_TYPES in testserver.py
45 std::string GetServerTypeString(BaseTestServer::Type type) {
46 switch (type) {
47 case BaseTestServer::TYPE_FTP:
48 return "ftp";
49 case BaseTestServer::TYPE_HTTP:
50 case BaseTestServer::TYPE_HTTPS:
51 return "http";
52 case BaseTestServer::TYPE_WS:
53 case BaseTestServer::TYPE_WSS:
54 return "ws";
55 case BaseTestServer::TYPE_TCP_ECHO:
56 return "tcpecho";
57 case BaseTestServer::TYPE_UDP_ECHO:
58 return "udpecho";
59 default:
60 NOTREACHED();
62 return std::string();
65 } // namespace
67 RemoteTestServer::RemoteTestServer(Type type,
68 const std::string& host,
69 const base::FilePath& document_root)
70 : BaseTestServer(type, host),
71 spawner_server_port_(0) {
72 if (!Init(document_root))
73 NOTREACHED();
76 RemoteTestServer::RemoteTestServer(Type type,
77 const SSLOptions& ssl_options,
78 const base::FilePath& document_root)
79 : BaseTestServer(type, ssl_options),
80 spawner_server_port_(0) {
81 if (!Init(document_root))
82 NOTREACHED();
85 RemoteTestServer::~RemoteTestServer() {
86 Stop();
89 bool RemoteTestServer::Start() {
90 if (spawner_communicator_.get())
91 return true;
92 spawner_communicator_.reset(new SpawnerCommunicator(spawner_server_port_));
94 base::DictionaryValue arguments_dict;
95 if (!GenerateArguments(&arguments_dict))
96 return false;
98 arguments_dict.Set("on-remote-server", base::Value::CreateNullValue());
100 // Append the 'server-type' argument which is used by spawner server to
101 // pass right server type to Python test server.
102 arguments_dict.SetString("server-type", GetServerTypeString(type()));
104 // Generate JSON-formatted argument string.
105 std::string arguments_string;
106 base::JSONWriter::Write(arguments_dict, &arguments_string);
107 if (arguments_string.empty())
108 return false;
110 // Start the Python test server on the remote machine.
111 uint16 test_server_port;
112 if (!spawner_communicator_->StartServer(arguments_string,
113 &test_server_port)) {
114 return false;
116 if (0 == test_server_port)
117 return false;
119 // Construct server data to initialize BaseTestServer::server_data_.
120 base::DictionaryValue server_data_dict;
121 // At this point, the test server should be spawned on the host. Update the
122 // local port to real port of Python test server, which will be forwarded to
123 // the remote server.
124 server_data_dict.SetInteger("port", test_server_port);
125 std::string server_data;
126 base::JSONWriter::Write(server_data_dict, &server_data);
127 if (server_data.empty() || !ParseServerData(server_data)) {
128 LOG(ERROR) << "Could not parse server_data: " << server_data;
129 return false;
132 return SetupWhenServerStarted();
135 bool RemoteTestServer::StartInBackground() {
136 NOTIMPLEMENTED();
137 return false;
140 bool RemoteTestServer::BlockUntilStarted() {
141 NOTIMPLEMENTED();
142 return false;
145 bool RemoteTestServer::Stop() {
146 if (!spawner_communicator_.get())
147 return true;
148 CleanUpWhenStoppingServer();
149 bool stopped = spawner_communicator_->StopServer();
150 // Explicitly reset |spawner_communicator_| to avoid reusing the stopped one.
151 spawner_communicator_.reset(NULL);
152 return stopped;
155 // On Android, the document root in the device is not the same as the document
156 // root in the host machine where the test server is launched. So prepend
157 // DIR_SOURCE_ROOT here to get the actual path of document root on the Android
158 // device.
159 base::FilePath RemoteTestServer::GetDocumentRoot() const {
160 base::FilePath src_dir;
161 PathService::Get(base::DIR_SOURCE_ROOT, &src_dir);
162 return src_dir.Append(document_root());
165 bool RemoteTestServer::Init(const base::FilePath& document_root) {
166 if (document_root.IsAbsolute())
167 return false;
169 // Gets ports information used by test server spawner and Python test server.
170 int test_server_port = 0;
172 // Parse file to extract the ports information.
173 std::string port_info;
174 if (!base::ReadFileToString(GetTestServerPortInfoFile(), &port_info) ||
175 port_info.empty()) {
176 return false;
179 std::vector<std::string> ports = base::SplitString(
180 port_info, ":", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
181 if (ports.size() != 2u)
182 return false;
184 // Verify the ports information.
185 base::StringToInt(ports[0], &spawner_server_port_);
186 if (!spawner_server_port_ ||
187 static_cast<uint32>(spawner_server_port_) >= kuint16max)
188 return false;
190 // Allow the test_server_port to be 0, which means the test server spawner
191 // will pick up a random port to run the test server.
192 base::StringToInt(ports[1], &test_server_port);
193 if (static_cast<uint32>(test_server_port) >= kuint16max)
194 return false;
195 SetPort(test_server_port);
197 // Unlike LocalTestServer, RemoteTestServer passes relative paths to the test
198 // server. The test server fails on empty strings in some configurations.
199 base::FilePath fixed_root = document_root;
200 if (fixed_root.empty())
201 fixed_root = base::FilePath(base::FilePath::kCurrentDirectory);
202 SetResourcePath(fixed_root, base::FilePath().AppendASCII("net")
203 .AppendASCII("data")
204 .AppendASCII("ssl")
205 .AppendASCII("certificates"));
206 return true;
209 } // namespace net