run_testserver.cc revision 5821806d5e7f356e8fa4b058a389a808ea183019
1// Copyright (c) 2012 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. 4 5#include <stdio.h> 6 7#include "base/at_exit.h" 8#include "base/command_line.h" 9#include "base/file_path.h" 10#include "base/logging.h" 11#include "base/message_loop.h" 12#include "base/process_util.h" 13#include "base/string_number_conversions.h" 14#include "base/test/test_timeouts.h" 15#include "base/utf_string_conversions.h" 16#include "net/test/local_sync_test_server.h" 17#include "net/test/python_utils.h" 18#include "net/test/test_server.h" 19 20static void PrintUsage() { 21 printf("run_testserver --doc-root=relpath\n" 22 " [--http|--https|--ws|--wss|--ftp|--sync]\n" 23 " [--ssl-cert=ok|mismatched-name|expired]\n" 24 " [--port=<port>] [--xmpp-port=<xmpp_port>]\n"); 25 printf("(NOTE: relpath should be relative to the 'src' directory.\n"); 26 printf(" --port and --xmpp-port only work with the --sync flag.)\n"); 27} 28 29// Launches the chromiumsync_test script, testing the --sync functionality. 30static bool RunSyncTest() { 31 if (!net::TestServer::SetPythonPathStatic()) { 32 LOG(ERROR) << "Error trying to set python path. Exiting."; 33 return false; 34 } 35 36 FilePath sync_test_path; 37 if (!net::TestServer::GetTestServerDirectory(&sync_test_path)) { 38 LOG(ERROR) << "Error trying to get python test server path."; 39 return false; 40 } 41 42 sync_test_path = 43 sync_test_path.Append(FILE_PATH_LITERAL("chromiumsync_test.py")); 44 45 CommandLine python_command(CommandLine::NO_PROGRAM); 46 if (!GetPythonCommand(&python_command)) { 47 LOG(ERROR) << "Could not get python runtime command."; 48 return false; 49 } 50 51 python_command.AppendArgPath(sync_test_path); 52 if (!base::LaunchProcess(python_command, base::LaunchOptions(), NULL)) { 53 LOG(ERROR) << "Failed to launch test script."; 54 return false; 55 } 56 return true; 57} 58 59// Gets a port value from the switch with name |switch_name| and writes it to 60// |port|. Returns true if successful and false otherwise. 61static bool GetPortFromSwitch(const std::string& switch_name, uint16* port) { 62 DCHECK(port != NULL) << "|port| is NULL"; 63 CommandLine* command_line = CommandLine::ForCurrentProcess(); 64 int port_int = 0; 65 if (command_line->HasSwitch(switch_name)) { 66 std::string port_str = command_line->GetSwitchValueASCII(switch_name); 67 if (!base::StringToInt(port_str, &port_int)) { 68 LOG(WARNING) << "Could not extract port from switch " << switch_name; 69 return false; 70 } 71 } 72 *port = static_cast<uint16>(port_int); 73 return true; 74} 75 76int main(int argc, const char* argv[]) { 77 base::AtExitManager at_exit_manager; 78 MessageLoopForIO message_loop; 79 80 // Process command line 81 CommandLine::Init(argc, argv); 82 CommandLine* command_line = CommandLine::ForCurrentProcess(); 83 84 if (!logging::InitLogging( 85 FILE_PATH_LITERAL("testserver.log"), 86 logging::LOG_TO_BOTH_FILE_AND_SYSTEM_DEBUG_LOG, 87 logging::LOCK_LOG_FILE, 88 logging::APPEND_TO_OLD_LOG_FILE, 89 logging::DISABLE_DCHECK_FOR_NON_OFFICIAL_RELEASE_BUILDS)) { 90 printf("Error: could not initialize logging. Exiting.\n"); 91 return -1; 92 } 93 94 TestTimeouts::Initialize(); 95 96 if (command_line->GetSwitches().empty() || 97 command_line->HasSwitch("help") || 98 ((command_line->HasSwitch("port") || 99 command_line->HasSwitch("xmpp-port")) && 100 !command_line->HasSwitch("sync"))) { 101 PrintUsage(); 102 return -1; 103 } 104 105 net::TestServer::Type server_type; 106 if (command_line->HasSwitch("http")) { 107 server_type = net::TestServer::TYPE_HTTP; 108 } else if (command_line->HasSwitch("https")) { 109 server_type = net::TestServer::TYPE_HTTPS; 110 } else if (command_line->HasSwitch("ws")) { 111 server_type = net::TestServer::TYPE_WS; 112 } else if (command_line->HasSwitch("wss")) { 113 server_type = net::TestServer::TYPE_WSS; 114 } else if (command_line->HasSwitch("ftp")) { 115 server_type = net::TestServer::TYPE_FTP; 116 } else if (command_line->HasSwitch("sync")) { 117 server_type = net::TestServer::TYPE_SYNC; 118 } else if (command_line->HasSwitch("sync-test")) { 119 return RunSyncTest() ? 0 : -1; 120 } else { 121 // If no scheme switch is specified, select http or https scheme. 122 // TODO(toyoshim): Remove this estimation. 123 if (command_line->HasSwitch("ssl-cert")) 124 server_type = net::TestServer::TYPE_HTTPS; 125 else 126 server_type = net::TestServer::TYPE_HTTP; 127 } 128 129 net::TestServer::SSLOptions ssl_options; 130 if (command_line->HasSwitch("ssl-cert")) { 131 if (!net::TestServer::UsingSSL(server_type)) { 132 printf("Error: --ssl-cert is specified on non-secure scheme\n"); 133 PrintUsage(); 134 return -1; 135 } 136 std::string cert_option = command_line->GetSwitchValueASCII("ssl-cert"); 137 if (cert_option == "ok") { 138 ssl_options.server_certificate = net::TestServer::SSLOptions::CERT_OK; 139 } else if (cert_option == "mismatched-name") { 140 ssl_options.server_certificate = 141 net::TestServer::SSLOptions::CERT_MISMATCHED_NAME; 142 } else if (cert_option == "expired") { 143 ssl_options.server_certificate = 144 net::TestServer::SSLOptions::CERT_EXPIRED; 145 } else { 146 printf("Error: --ssl-cert has invalid value %s\n", cert_option.c_str()); 147 PrintUsage(); 148 return -1; 149 } 150 } 151 152 FilePath doc_root = command_line->GetSwitchValuePath("doc-root"); 153 if ((server_type != net::TestServer::TYPE_SYNC) && doc_root.empty()) { 154 printf("Error: --doc-root must be specified\n"); 155 PrintUsage(); 156 return -1; 157 } 158 159 scoped_ptr<net::TestServer> test_server; 160 if (net::TestServer::UsingSSL(server_type)) { 161 test_server.reset(new net::TestServer(server_type, ssl_options, doc_root)); 162 } else if (server_type == net::TestServer::TYPE_SYNC) { 163 uint16 port = 0; 164 uint16 xmpp_port = 0; 165 if (!GetPortFromSwitch("port", &port) || 166 !GetPortFromSwitch("xmpp-port", &xmpp_port)) { 167 printf("Error: Could not extract --port and/or --xmpp-port.\n"); 168 return -1; 169 } 170 test_server.reset(new net::LocalSyncTestServer(port, xmpp_port)); 171 } else { 172 test_server.reset(new net::TestServer(server_type, 173 net::TestServer::kLocalhost, 174 doc_root)); 175 } 176 177 if (!test_server->Start()) { 178 printf("Error: failed to start test server. Exiting.\n"); 179 return -1; 180 } 181 182 if (!file_util::DirectoryExists(test_server->document_root())) { 183 printf("Error: invalid doc root: \"%s\" does not exist!\n", 184 UTF16ToUTF8(test_server->document_root().LossyDisplayName()).c_str()); 185 return -1; 186 } 187 188 printf("testserver running at %s (type ctrl+c to exit)\n", 189 test_server->host_port_pair().ToString().c_str()); 190 191 message_loop.Run(); 192 return 0; 193} 194