summaryrefslogtreecommitdiffstats
path: root/net/test/local_test_server.cc
diff options
context:
space:
mode:
authorjnd@chromium.org <jnd@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-03-12 06:04:43 +0000
committerjnd@chromium.org <jnd@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-03-12 06:04:43 +0000
commit31526823f1e7e7f1418f44cfb0f4e0283daf54ec (patch)
treeb751259ceec955513fcceaec3272316570e0d33c /net/test/local_test_server.cc
parente4f849682312f4300e6447b7227650e38c8d8415 (diff)
downloadchromium_src-31526823f1e7e7f1418f44cfb0f4e0283daf54ec.zip
chromium_src-31526823f1e7e7f1418f44cfb0f4e0283daf54ec.tar.gz
chromium_src-31526823f1e7e7f1418f44cfb0f4e0283daf54ec.tar.bz2
Make test server to talk with the python test server which is running on remote machine.
For Chromium/Android platform, since there is no python env support on Android device, we have to run the test server on the remote host and let the test server to talk with it. Also add the net_util.h into some test files to fix compilation error. They used to implicitly rely on the net_util.h definition by including test_server.h, but the net_util.h is removed from test_server.h in this patch. Since the fix in those test files are trivial, Ryan and Paweł are OK with the patch, just TBR to the owners to skip the owner presubmit check for landing. TBR=owners BUG=None TEST=net_unittests should pass on all platforms Review URL: http://codereview.chromium.org/9359051 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@126100 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/test/local_test_server.cc')
-rw-r--r--net/test/local_test_server.cc237
1 files changed, 237 insertions, 0 deletions
diff --git a/net/test/local_test_server.cc b/net/test/local_test_server.cc
new file mode 100644
index 0000000..c36d2ff
--- /dev/null
+++ b/net/test/local_test_server.cc
@@ -0,0 +1,237 @@
+// 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/local_test_server.h"
+
+#include "base/command_line.h"
+#include "base/json/json_reader.h"
+#include "base/logging.h"
+#include "base/path_service.h"
+#include "base/process_util.h"
+#include "base/string_number_conversions.h"
+#include "base/values.h"
+#include "googleurl/src/gurl.h"
+#include "net/base/host_port_pair.h"
+#include "net/base/net_errors.h"
+#include "net/test/python_utils.h"
+
+namespace net {
+
+namespace {
+
+bool AppendArgumentFromJSONValue(const std::string& key,
+ const base::Value& value_node,
+ CommandLine* command_line) {
+ std::string argument_name = "--" + key;
+ switch (value_node.GetType()) {
+ case base::Value::TYPE_NULL:
+ command_line->AppendArg(argument_name);
+ break;
+ case base::Value::TYPE_INTEGER: {
+ int value;
+ bool result = value_node.GetAsInteger(&value);
+ DCHECK(result);
+ command_line->AppendArg(argument_name + "=" + base::IntToString(value));
+ break;
+ }
+ case Value::TYPE_STRING: {
+ std::string value;
+ bool result = value_node.GetAsString(&value);
+ if (!result || value.empty())
+ return false;
+ command_line->AppendArg(argument_name + "=" + value);
+ break;
+ }
+ case base::Value::TYPE_BOOLEAN:
+ case base::Value::TYPE_DOUBLE:
+ case base::Value::TYPE_LIST:
+ case base::Value::TYPE_DICTIONARY:
+ case base::Value::TYPE_BINARY:
+ default:
+ NOTREACHED() << "improper json type";
+ return false;
+ }
+ return true;
+}
+
+} // namespace
+
+LocalTestServer::LocalTestServer(Type type,
+ const std::string& host,
+ const FilePath& document_root)
+ : BaseTestServer(type, host) {
+ if (!Init(document_root))
+ NOTREACHED();
+}
+
+LocalTestServer::LocalTestServer(const HTTPSOptions& https_options,
+ const FilePath& document_root)
+ : BaseTestServer(https_options) {
+ if (!Init(document_root))
+ NOTREACHED();
+}
+
+LocalTestServer::~LocalTestServer() {
+ Stop();
+}
+
+bool LocalTestServer::Start() {
+ // Get path to Python server script.
+ FilePath testserver_path;
+ if (!PathService::Get(base::DIR_SOURCE_ROOT, &testserver_path)) {
+ LOG(ERROR) << "Failed to get DIR_SOURCE_ROOT";
+ return false;
+ }
+ testserver_path = testserver_path
+ .Append(FILE_PATH_LITERAL("net"))
+ .Append(FILE_PATH_LITERAL("tools"))
+ .Append(FILE_PATH_LITERAL("testserver"))
+ .Append(FILE_PATH_LITERAL("testserver.py"));
+
+ if (!SetPythonPath())
+ return false;
+
+ if (!LaunchPython(testserver_path))
+ return false;
+
+ if (!WaitToStart()) {
+ Stop();
+ return false;
+ }
+
+ return SetupWhenServerStarted();
+}
+
+bool LocalTestServer::Stop() {
+ CleanUpWhenStoppingServer();
+
+ if (!process_handle_)
+ return true;
+
+ // First check if the process has already terminated.
+ bool ret = base::WaitForSingleProcess(process_handle_, 0);
+ if (!ret)
+ ret = base::KillProcess(process_handle_, 1, true);
+
+ if (ret) {
+ base::CloseProcessHandle(process_handle_);
+ process_handle_ = base::kNullProcessHandle;
+ } else {
+ VLOG(1) << "Kill failed?";
+ }
+
+ return ret;
+}
+
+bool LocalTestServer::Init(const FilePath& document_root) {
+ if (document_root.IsAbsolute())
+ return false;
+
+ // At this point, the port that the test server will listen on is unknown.
+ // The test server will listen on an ephemeral port, and write the port
+ // number out over a pipe that this TestServer object will read from. Once
+ // that is complete, the host port pair will contain the actual port.
+ DCHECK(!GetPort());
+ process_handle_ = base::kNullProcessHandle;
+
+ FilePath src_dir;
+ if (!PathService::Get(base::DIR_SOURCE_ROOT, &src_dir))
+ return false;
+ SetResourcePath(src_dir.Append(document_root),
+ src_dir.AppendASCII("net")
+ .AppendASCII("data")
+ .AppendASCII("ssl")
+ .AppendASCII("certificates"));
+ return true;
+}
+
+bool LocalTestServer::SetPythonPath() const {
+ FilePath third_party_dir;
+ if (!PathService::Get(base::DIR_SOURCE_ROOT, &third_party_dir)) {
+ LOG(ERROR) << "Failed to get DIR_SOURCE_ROOT";
+ return false;
+ }
+ third_party_dir = third_party_dir.AppendASCII("third_party");
+
+ // For simplejson. (simplejson, unlike all the other Python modules
+ // we include, doesn't have an extra 'simplejson' directory, so we
+ // need to include its parent directory, i.e. third_party_dir).
+ AppendToPythonPath(third_party_dir);
+
+ AppendToPythonPath(third_party_dir.AppendASCII("tlslite"));
+ AppendToPythonPath(
+ third_party_dir.AppendASCII("pyftpdlib").AppendASCII("src"));
+
+ // Locate the Python code generated by the protocol buffers compiler.
+ FilePath pyproto_dir;
+ if (!GetPyProtoPath(&pyproto_dir)) {
+ LOG(WARNING) << "Cannot find pyproto dir for generated code. "
+ << "Testserver features that rely on it will not work";
+ return true;
+ }
+
+ AppendToPythonPath(pyproto_dir);
+ AppendToPythonPath(pyproto_dir.AppendASCII("sync").AppendASCII("protocol"));
+ AppendToPythonPath(pyproto_dir.AppendASCII("chrome")
+ .AppendASCII("browser")
+ .AppendASCII("policy")
+ .AppendASCII("proto"));
+
+ return true;
+}
+
+bool LocalTestServer::AddCommandLineArguments(CommandLine* command_line) const {
+ base::DictionaryValue arguments_dict;
+ if (!GenerateArguments(&arguments_dict))
+ return false;
+
+ // Serialize the argument dictionary into CommandLine.
+ for (DictionaryValue::Iterator it(arguments_dict); it.HasNext();
+ it.Advance()) {
+ const base::Value& value = it.value();
+ const std::string& key = it.key();
+
+ // Add arguments from a list.
+ if (value.IsType(Value::TYPE_LIST)) {
+ const base::ListValue* list = NULL;
+ if (!value.GetAsList(&list) || !list || list->empty())
+ return false;
+ for (base::ListValue::const_iterator list_it = list->begin();
+ list_it != list->end(); ++list_it) {
+ if (!AppendArgumentFromJSONValue(key, *(*list_it), command_line))
+ return false;
+ }
+ } else if (!AppendArgumentFromJSONValue(key, value, command_line)) {
+ return false;
+ }
+ }
+
+ // Append the appropriate server type argument.
+ switch (type()) {
+ case TYPE_HTTP:
+ case TYPE_HTTPS:
+ // The default type is HTTP, no argument required.
+ break;
+ case TYPE_FTP:
+ command_line->AppendArg("-f");
+ break;
+ case TYPE_SYNC:
+ command_line->AppendArg("--sync");
+ break;
+ case TYPE_TCP_ECHO:
+ command_line->AppendArg("--tcp-echo");
+ break;
+ case TYPE_UDP_ECHO:
+ command_line->AppendArg("--udp-echo");
+ break;
+ default:
+ NOTREACHED();
+ return false;
+ }
+
+ return true;
+}
+
+} // namespace net
+