summaryrefslogtreecommitdiffstats
path: root/net/base/ssl_test_util.cc
diff options
context:
space:
mode:
authordkegel@google.com <dkegel@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-02-14 05:26:10 +0000
committerdkegel@google.com <dkegel@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-02-14 05:26:10 +0000
commitee287e40bb740d7238717a97b5f635ae3e68c47a (patch)
tree4515656a0a870939dbcf6892b48baa02c99c26ca /net/base/ssl_test_util.cc
parent0afe827a49501c6801c3c9efbbdb1f64aa010beb (diff)
downloadchromium_src-ee287e40bb740d7238717a97b5f635ae3e68c47a.zip
chromium_src-ee287e40bb740d7238717a97b5f635ae3e68c47a.tar.gz
chromium_src-ee287e40bb740d7238717a97b5f635ae3e68c47a.tar.bz2
ssl_client_socket_unittest.cc: launch local server with TestServerLauncher
rather than use bugs.webkit.org, fixes TODO(darin) Add tests with bad server certs ssl_client_socket_nss.cc: fix bugs revealed by new tests tcp_pinger.cc: helper class to do synchronous connect from tests. Has to work inside ui tests where one can't use TestCompletionCallback. ssl_test_util: renamed class TestServerLauncher, added Start/Stop methods. Make part of net.lib to work around link error in test_shell_tests. url_request_unittest.h: use TestServerLauncher to manage server. SSL client tests disabled for now on Mac. BUG=7114 Review URL: http://codereview.chromium.org/16207 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@9823 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/base/ssl_test_util.cc')
-rw-r--r--net/base/ssl_test_util.cc226
1 files changed, 202 insertions, 24 deletions
diff --git a/net/base/ssl_test_util.cc b/net/base/ssl_test_util.cc
index d22e4fd..a6ad137 100644
--- a/net/base/ssl_test_util.cc
+++ b/net/base/ssl_test_util.cc
@@ -5,6 +5,8 @@
#include <string>
#include <algorithm>
+#include "net/base/ssl_test_util.h"
+
#include "build/build_config.h"
#if defined(OS_WIN)
@@ -27,16 +29,15 @@
#include "base/file_util.h"
#include "base/logging.h"
#include "base/path_service.h"
+#include "base/platform_thread.h"
+#include "base/string_util.h"
+#include "net/base/tcp_pinger.h"
+#include "net/base/host_resolver.h"
+#include "net/base/tcp_client_socket.h"
+#include "net/base/test_completion_callback.h"
+#include "testing/platform_test.h"
-#include "net/base/ssl_test_util.h"
-
-// static
-const char SSLTestUtil::kHostName[] = "127.0.0.1";
-const int SSLTestUtil::kOKHTTPSPort = 9443;
-const int SSLTestUtil::kBadHTTPSPort = 9666;
-
-// The issuer name of the cert that should be trusted for the test to work.
-const wchar_t SSLTestUtil::kCertIssuerName[] = L"Test CA";
+namespace {
#if defined(OS_LINUX)
static CERTCertificate* LoadTemporaryCert(const FilePath& filename) {
@@ -67,57 +68,231 @@ static CERTCertificate* LoadTemporaryCert(const FilePath& filename) {
rv = CERT_ChangeCertTrust(CERT_GetDefaultCertDB(), cert, &trust);
if (rv != SECSuccess) {
- LOG(ERROR) << "Can't change trust for certificate "
+ LOG(ERROR) << "Can't change trust for certificate "
<< filename.ToWStringHack();
CERT_DestroyCertificate(cert);
return NULL;
}
- LOG(INFO) << "Loaded temporary certificate " << filename.ToWStringHack();
+ // TODO(dkegel): figure out how to get this to only happen once?
return cert;
}
#endif
-SSLTestUtil::SSLTestUtil() {
- PathService::Get(base::DIR_SOURCE_ROOT, &cert_dir_);
- cert_dir_ = cert_dir_.AppendASCII("net");
- cert_dir_ = cert_dir_.AppendASCII("data");
- cert_dir_ = cert_dir_.AppendASCII("ssl");
- cert_dir_ = cert_dir_.AppendASCII("certificates");
+} // namespace
+
+namespace net {
+
+// static
+const char TestServerLauncher::kHostName[] = "127.0.0.1";
+const char TestServerLauncher::kMismatchedHostName[] = "localhost";
+const int TestServerLauncher::kOKHTTPSPort = 9443;
+const int TestServerLauncher::kBadHTTPSPort = 9666;
+
+// The issuer name of the cert that should be trusted for the test to work.
+const wchar_t TestServerLauncher::kCertIssuerName[] = L"Test CA";
+
+TestServerLauncher::TestServerLauncher() : process_handle_(NULL)
+#if defined(OS_LINUX)
+, cert_(NULL)
+#endif
+{
+ PathService::Get(base::DIR_SOURCE_ROOT, &data_dir_);
+ data_dir_ = data_dir_.Append(FILE_PATH_LITERAL("net"))
+ .Append(FILE_PATH_LITERAL("data"))
+ .Append(FILE_PATH_LITERAL("ssl"));
+ cert_dir_ = data_dir_.Append(FILE_PATH_LITERAL("certificates"));
+}
+
+namespace {
+
+void AppendToPythonPath(FilePath dir) {
+ // Do nothing if dir already on path.
+
+#if defined(OS_WIN)
+ const wchar_t kPythonPath[] = L"PYTHONPATH";
+ // FIXME(dkegel): handle longer PYTHONPATH variables
+ wchar_t oldpath[4096];
+ if (GetEnvironmentVariable(kPythonPath, oldpath, sizeof(oldpath)) == 0) {
+ SetEnvironmentVariableW(kPythonPath, dir.value().c_str());
+ } else if (!wcsstr(oldpath, dir.value().c_str())) {
+ std::wstring newpath(oldpath);
+ newpath.append(L":");
+ newpath.append(dir.value());
+ SetEnvironmentVariableW(kPythonPath, newpath.c_str());
+ }
+#elif defined(OS_POSIX)
+ const char kPythonPath[] = "PYTHONPATH";
+ const char* oldpath = getenv(kPythonPath);
+ if (!oldpath) {
+ setenv(kPythonPath, dir.value().c_str(), 1);
+ } else if (!strstr(oldpath, dir.value().c_str())) {
+ std::string newpath(oldpath);
+ newpath.append(":");
+ newpath.append(dir.value());
+ setenv(kPythonPath, newpath.c_str(), 1);
+ }
+#endif
+}
+
+} // end namespace
+
+void TestServerLauncher::SetPythonPath() {
+ FilePath third_party_dir;
+ ASSERT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT, &third_party_dir));
+ third_party_dir = third_party_dir.Append(FILE_PATH_LITERAL("third_party"));
+
+ AppendToPythonPath(third_party_dir.Append(FILE_PATH_LITERAL("tlslite")));
+ AppendToPythonPath(third_party_dir.Append(FILE_PATH_LITERAL("pyftpdlib")));
+}
+
+bool TestServerLauncher::Start(Protocol protocol,
+ const std::string& host_name, int port,
+ const FilePath& document_root,
+ const FilePath& cert_path) {
+ if (!TestServerLauncher::CheckCATrusted())
+ return false;
+
+ std::string port_str = IntToString(port);
+
+ // Get path to python server script
+ FilePath testserver_path;
+ if (!PathService::Get(base::DIR_SOURCE_ROOT, &testserver_path))
+ 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"));
+
+ FilePath test_data_directory;
+ PathService::Get(base::DIR_SOURCE_ROOT, &test_data_directory);
+ test_data_directory = test_data_directory.Append(document_root);
#if defined(OS_LINUX)
- cert_ = reinterpret_cast<PrivateCERTCertificate*>(
+ if (!cert_ && !cert_path.value().empty()) {
+ cert_ = reinterpret_cast<PrivateCERTCertificate*>(
LoadTemporaryCert(GetRootCertPath()));
- DCHECK(cert_);
+ DCHECK(cert_);
+ }
#endif
+
+ SetPythonPath();
+
+#if defined(OS_WIN)
+ // Get path to python interpreter
+ if (!PathService::Get(base::DIR_SOURCE_ROOT, &python_runtime_))
+ return false;
+ python_runtime_ = python_runtime_
+ .Append(FILE_PATH_LITERAL("third_party"))
+ .Append(FILE_PATH_LITERAL("python_24"))
+ .Append(FILE_PATH_LITERAL("python.exe"));
+
+ std::wstring command_line =
+ L"\"" + python_runtime_.ToWStringHack() + L"\" " +
+ L"\"" + testserver_path.ToWStringHack() +
+ L"\" --port=" + UTF8ToWide(port_str) +
+ L" --data-dir=\"" + test_data_directory.ToWStringHack() + L"\"";
+ if (protocol == ProtoFTP)
+ command_line.append(L" -f");
+ if (!cert_path.value().empty()) {
+ command_line.append(L" --https=\"");
+ command_line.append(cert_path.ToWStringHack());
+ command_line.append(L"\"");
+ }
+
+ if (!base::LaunchApp(command_line, false, true, &process_handle_)) {
+ LOG(ERROR) << "Failed to launch " << command_line;
+ return false;
+ }
+#elif defined(OS_POSIX)
+ std::vector<std::string> command_line;
+ command_line.push_back("python");
+ command_line.push_back(WideToUTF8(testserver_path.ToWStringHack()));
+ command_line.push_back("--port=" + port_str);
+ command_line.push_back("--data-dir=" +
+ WideToUTF8(test_data_directory.ToWStringHack()));
+ if (protocol == ProtoFTP)
+ command_line.push_back("-f");
+ if (!cert_path.value().empty())
+ command_line.push_back("--https=" + WideToUTF8(cert_path.ToWStringHack()));
+
+ base::file_handle_mapping_vector no_mappings;
+ LOG(INFO) << "Trying to launch " << command_line[0] << " ...";
+ if (!base::LaunchApp(command_line, no_mappings, false, &process_handle_)) {
+ LOG(ERROR) << "Failed to launch " << command_line[0] << " ...";
+ return false;
+ }
+#endif
+
+ // Let the server start, then verify that it's up.
+ // Our server is Python, and takes about 500ms to start
+ // up the first time, and about 200ms after that.
+ if (!Wait(host_name, port)) {
+ LOG(ERROR) << "Failed to connect to server";
+ Stop();
+ return false;
+ }
+
+ LOG(INFO) << "Started on port " << port_str;
+ return true;
+}
+
+bool TestServerLauncher::Wait(const std::string& host_name, int port) {
+ // Verify that the webserver is actually started.
+ // Otherwise tests can fail if they run faster than Python can start.
+ net::AddressList addr;
+ net::HostResolver resolver;
+ int rv = resolver.Resolve(host_name, port, &addr, NULL);
+ if (rv != net::OK)
+ return false;
+
+ net::TCPPinger pinger(addr);
+ rv = pinger.Ping();
+ return rv == net::OK;
+}
+
+void TestServerLauncher::Stop() {
+ if (!process_handle_)
+ return;
+
+ base::KillProcess(process_handle_, 1, true);
+
+#if defined(OS_WIN)
+ CloseHandle(process_handle_);
+#endif
+
+ process_handle_ = NULL;
+ LOG(INFO) << "Stopped.";
}
-SSLTestUtil::~SSLTestUtil() {
+TestServerLauncher::~TestServerLauncher() {
#if defined(OS_LINUX)
if (cert_)
CERT_DestroyCertificate(reinterpret_cast<CERTCertificate*>(cert_));
#endif
+ Stop();
}
-FilePath SSLTestUtil::GetRootCertPath() {
+FilePath TestServerLauncher::GetRootCertPath() {
FilePath path(cert_dir_);
path = path.AppendASCII("root_ca_cert.crt");
return path;
}
-FilePath SSLTestUtil::GetOKCertPath() {
+FilePath TestServerLauncher::GetOKCertPath() {
FilePath path(cert_dir_);
path = path.AppendASCII("ok_cert.pem");
return path;
}
-FilePath SSLTestUtil::GetExpiredCertPath() {
+FilePath TestServerLauncher::GetExpiredCertPath() {
FilePath path(cert_dir_);
path = path.AppendASCII("expired_cert.pem");
return path;
}
-bool SSLTestUtil::CheckCATrusted() {
+bool TestServerLauncher::CheckCATrusted() {
// TODO(port): Port either this or LoadTemporaryCert to MacOSX.
#if defined(OS_WIN)
HCERTSTORE cert_store = CertOpenSystemStore(NULL, L"ROOT");
@@ -146,3 +321,6 @@ bool SSLTestUtil::CheckCATrusted() {
#endif
return true;
}
+
+} // namespace net
+