diff options
author | dkegel@google.com <dkegel@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-02-14 23:14:35 +0000 |
---|---|---|
committer | dkegel@google.com <dkegel@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-02-14 23:14:35 +0000 |
commit | 518fdec3a07a94dc45d6e7e4ad1b529747dc03d3 (patch) | |
tree | fb2b17479a907a8960a8dc865630fe7272d041fc /net/url_request | |
parent | 5e997eacfb2234633831d06c91859ee76af44468 (diff) | |
download | chromium_src-518fdec3a07a94dc45d6e7e4ad1b529747dc03d3.zip chromium_src-518fdec3a07a94dc45d6e7e4ad1b529747dc03d3.tar.gz chromium_src-518fdec3a07a94dc45d6e7e4ad1b529747dc03d3.tar.bz2 |
Reverting r9823 (http://codereview.chromium.org/16207) because
1) the Interactive Tests (dbg) buildbot needs the SSL cert installed
2) the same buildbot showed a refcounting problem, e.g.
FATAL:ref_counted.cc(22)] Check failed: in_dtor_. RefCounted object deleted without calling Release()
c:\b\slave\chromium-dbg-builder\build\src\chrome\browser\views\find_bar_win_interactive_uitest.cc(57): error: Value of: NULL != server.get()
Actual: false
Expected: true
[ FAILED ] FindInPageTest.CrashEscHandlers (2109 ms)
3) the Webkit Linux buildbot failed four tests
redirect302-frames.html cross-frame-access-protocol-explicit-domain.html
cross-frame-access-protocol.html origin-header-for-https.html
I'm leaving the tcp_pinger files in for the moment, they shouldn't hurt anything.
Review URL: http://codereview.chromium.org/23028
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@9827 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/url_request')
-rw-r--r-- | net/url_request/url_request_unittest.cc | 17 | ||||
-rw-r--r-- | net/url_request/url_request_unittest.h | 479 |
2 files changed, 376 insertions, 120 deletions
diff --git a/net/url_request/url_request_unittest.cc b/net/url_request/url_request_unittest.cc index 4ab4285..21d1c72 100644 --- a/net/url_request/url_request_unittest.cc +++ b/net/url_request/url_request_unittest.cc @@ -180,14 +180,17 @@ TEST_F(URLRequestTest, GetTest) { } class HTTPSRequestTest : public testing::Test { + protected: + HTTPSRequestTest() : util_() {} + + SSLTestUtil util_; }; #if defined(OS_MACOSX) -// ssl_client_socket_mac.cc crashes currently in GetSSLInfo -// when called on a connection with an unrecognized certificate -#define MAYBE_HTTPSGetTest DISABLED_HTTPSGetTest +// TODO(port): support temporary root cert on mac +#define MAYBE_HTTPSGetTest DISABLED_HTTPSGetTest #else -#define MAYBE_HTTPSGetTest HTTPSGetTest +#define MAYBE_HTTPSGetTest HTTPSGetTest #endif TEST_F(HTTPSRequestTest, MAYBE_HTTPSGetTest) { @@ -196,9 +199,11 @@ TEST_F(HTTPSRequestTest, MAYBE_HTTPSGetTest) { // so this test doesn't really need to specify a document root. // But if it did, a good one would be net/data/ssl. scoped_refptr<HTTPSTestServer> server = - HTTPSTestServer::CreateGoodServer(L"net/data/ssl"); + HTTPSTestServer::CreateServer(util_.kHostName, util_.kOKHTTPSPort, + L"net/data/ssl", util_.GetOKCertPath().ToWStringHack()); ASSERT_TRUE(NULL != server.get()); + EXPECT_TRUE(util_.CheckCATrusted()); TestDelegate d; { TestURLRequest r(server->TestServerPage(""), &d); @@ -217,8 +222,6 @@ TEST_F(HTTPSRequestTest, MAYBE_HTTPSGetTest) { #endif } -// TODO(dkegel): add test for expired and mismatched certificates here - TEST_F(URLRequestTest, CancelTest) { TestDelegate d; { diff --git a/net/url_request/url_request_unittest.h b/net/url_request/url_request_unittest.h index e6f4da6..7107d50 100644 --- a/net/url_request/url_request_unittest.h +++ b/net/url_request/url_request_unittest.h @@ -13,7 +13,6 @@ #include "base/file_path.h" #include "base/file_util.h" -#include "base/logging.h" #include "base/message_loop.h" #include "base/path_service.h" #include "base/platform_thread.h" @@ -24,7 +23,6 @@ #include "base/waitable_event.h" #include "net/base/io_buffer.h" #include "net/base/net_errors.h" -#include "net/base/ssl_test_util.h" #include "net/http/http_network_layer.h" #include "net/url_request/url_request.h" #include "net/proxy/proxy_service.h" @@ -212,9 +210,48 @@ class TestDelegate : public URLRequest::Delegate { // that can provide various responses useful for testing. class BaseTestServer : public base::RefCounted<BaseTestServer> { protected: - BaseTestServer() { } + BaseTestServer() + : process_handle_(NULL) { + } public: + virtual ~BaseTestServer() { + if (!IsFinished()) + if (!WaitToFinish(1000)) + Kill(); + } + + bool IsFinished() { + return WaitToFinish(0); + } + + void Kill() { + if (process_handle_) { +#if defined(OS_WIN) + base::KillProcess(process_handle_, 0, true); +#elif defined(OS_POSIX) + // Make sure the process has exited and clean up the process to avoid + // a zombie. + kill(process_handle_, SIGINT); + waitpid(process_handle_, 0, 0); +#endif + base::CloseProcessHandle(process_handle_); + process_handle_ = NULL; + } + } + + bool WaitToFinish(int milliseconds) { + if (process_handle_ == 0) + return true; + bool ret = base::WaitForSingleProcess(process_handle_, milliseconds); + if (ret) { + base::CloseProcessHandle(process_handle_); + process_handle_ = NULL; + } + + return ret; + } + GURL TestServerPage(const std::string& base_address, const std::string& path) { return GURL(base_address + path); @@ -228,50 +265,142 @@ class BaseTestServer : public base::RefCounted<BaseTestServer> { return GURL(base_address_ + WideToUTF8(path)); } - virtual bool MakeGETRequest(const std::string& page_name) = 0; + void SetPythonPaths() { +#if defined(OS_WIN) + // Set up PYTHONPATH so that Python is able to find the in-tree copy of + // pyftpdlib. + static bool set_python_path = false; + if (!set_python_path) { + FilePath pyftpdlib_path; + ASSERT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT, &pyftpdlib_path)); + pyftpdlib_path = pyftpdlib_path.Append(L"third_party"); + pyftpdlib_path = pyftpdlib_path.Append(L"pyftpdlib"); + + const wchar_t kPythonPath[] = L"PYTHONPATH"; + wchar_t python_path_c[1024]; + if (GetEnvironmentVariable(kPythonPath, python_path_c, 1023) > 0) { + // PYTHONPATH is already set, append to it. + std::wstring python_path(python_path_c); + python_path.append(L":"); + python_path.append(pyftpdlib_path.value()); + SetEnvironmentVariableW(kPythonPath, python_path.c_str()); + } else { + SetEnvironmentVariableW(kPythonPath, pyftpdlib_path.value().c_str()); + } - protected: - bool Start(net::TestServerLauncher::Protocol protocol, - const std::string& host_name, int port, - const FilePath& document_root, - const FilePath& cert_path) { - std::string blank; - return Start(protocol, host_name, port, document_root, cert_path, - blank, blank); - } - - bool Start(net::TestServerLauncher::Protocol protocol, - const std::string& host_name, int port, - const FilePath& document_root, - const FilePath& cert_path, - const std::string& url_user, - const std::string& url_password) { - if (!launcher_.Start(protocol, - host_name, port, document_root, cert_path)) - return false; + set_python_path = true; + } +#elif defined(OS_POSIX) + // Set up PYTHONPATH so that Python is able to find the in-tree copy of + // tlslite and pyftpdlib. + static bool set_python_path = false; + if (!set_python_path) { + FilePath tlslite_path; + FilePath pyftpdlib_path; + ASSERT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT, &tlslite_path)); + tlslite_path = tlslite_path.Append("third_party"); + tlslite_path = tlslite_path.Append("tlslite"); + + ASSERT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT, &pyftpdlib_path)); + pyftpdlib_path = pyftpdlib_path.Append("third_party"); + pyftpdlib_path = pyftpdlib_path.Append("pyftpdlib"); + + const char kPythonPath[] = "PYTHONPATH"; + char* python_path_c = getenv(kPythonPath); + if (python_path_c) { + // PYTHONPATH is already set, append to it. + std::string python_path(python_path_c); + python_path.append(":"); + python_path.append(tlslite_path.value()); + python_path.append(":"); + python_path.append(pyftpdlib_path.value()); + setenv(kPythonPath, python_path.c_str(), 1); + } else { + std::string python_path = tlslite_path.value().c_str(); + python_path.append(":"); + python_path.append(pyftpdlib_path.value()); + setenv(kPythonPath, python_path.c_str(), 1); + } + set_python_path = true; + } +#endif + } - std::string scheme; - if (protocol == net::TestServerLauncher::ProtoFTP) - scheme = "ftp"; - else - scheme = "http"; - if (!cert_path.empty()) - scheme.push_back('s'); - - std::string port_str = IntToString(port); - if (url_user.empty()) { - base_address_ = scheme + "://" + host_name + ":" + port_str + "/"; + void SetAppPath(const std::string& host_name, int port, + const std::wstring& document_root, const std::string& scheme, + std::wstring* testserver_path, std::wstring* test_data_directory) { + port_str_ = IntToString(port); + if (url_user_.empty()) { + base_address_ = scheme + "://" + host_name + ":" + port_str_ + "/"; } else { - if (url_password.empty()) - base_address_ = scheme + "://" + url_user + "@" + - host_name + ":" + port_str + "/"; + if (url_password_.empty()) + base_address_ = scheme + "://" + url_user_ + "@" + + host_name + ":" + port_str_ + "/"; else - base_address_ = scheme + "://" + url_user + ":" + url_password + - "@" + host_name + ":" + port_str + "/"; + base_address_ = scheme + "://" + url_user_ + ":" + url_password_ + + "@" + host_name + ":" + port_str_ + "/"; + } + + ASSERT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT, testserver_path)); + file_util::AppendToPath(testserver_path, L"net"); + file_util::AppendToPath(testserver_path, L"tools"); + file_util::AppendToPath(testserver_path, L"testserver"); + file_util::AppendToPath(testserver_path, L"testserver.py"); + + ASSERT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT, &python_runtime_)); + file_util::AppendToPath(&python_runtime_, L"third_party"); + file_util::AppendToPath(&python_runtime_, L"python_24"); + file_util::AppendToPath(&python_runtime_, L"python.exe"); + + PathService::Get(base::DIR_SOURCE_ROOT, test_data_directory); + std::wstring normalized_document_root = document_root; + +#if defined(OS_WIN) + // It is just for windows only and have no effect on other OS + std::replace(normalized_document_root.begin(), + normalized_document_root.end(), + L'/', FilePath::kSeparators[0]); +#endif + if (!normalized_document_root.empty()) + file_util::AppendToPath(test_data_directory, normalized_document_root); + data_directory_ = *test_data_directory; + } + +#if defined(OS_WIN) + void LaunchApp(const std::wstring& command_line) { + ASSERT_TRUE(base::LaunchApp(command_line, false, true, &process_handle_)) << + "Failed to launch " << command_line; + } +#elif defined(OS_POSIX) + void LaunchApp(const std::vector<std::string>& command_line) { + base::file_handle_mapping_vector fds_empty; + ASSERT_TRUE(base::LaunchApp(command_line, fds_empty, false, + &process_handle_)) << + "Failed to launch " << command_line[0] << " ..."; + } +#endif + + virtual bool MakeGETRequest(const std::string& page_name) = 0; + + // Verify that the Server is actually started. + // Otherwise tests can fail if they run faster than Python can start. + bool VerifyLaunchApp(const std::string& page_name) { + int retries = 10; + bool success; + while ((success = MakeGETRequest(page_name)) == false && retries > 0) { + retries--; + PlatformThread::Sleep(500); } + if (!success) + return false; return true; } + std::wstring GetDataDirectory() { + return data_directory_; + } + + protected: // Used by MakeGETRequest to implement sync load behavior. class SyncTestDelegate : public TestDelegate { public: @@ -294,13 +423,18 @@ class BaseTestServer : public base::RefCounted<BaseTestServer> { bool success_; DISALLOW_COPY_AND_ASSIGN(SyncTestDelegate); }; - net::TestServerLauncher launcher_; + std::string host_name_; std::string base_address_; + std::string url_user_; + std::string url_password_; + std::wstring python_runtime_; + std::wstring data_directory_; + base::ProcessHandle process_handle_; + std::string port_str_; + }; - -// HTTP class HTTPTestServer : public BaseTestServer { protected: explicit HTTPTestServer() : loop_(NULL) { @@ -313,16 +447,37 @@ class HTTPTestServer : public BaseTestServer { MessageLoop* loop) { HTTPTestServer* test_server = new HTTPTestServer(); test_server->loop_ = loop; - FilePath no_cert; - FilePath docroot = FilePath::FromWStringHack(document_root); - if (!test_server->Start(net::TestServerLauncher::ProtoHTTP, - kDefaultHostName, kHTTPDefaultPort, docroot, no_cert)) { + if (!test_server->Init(kDefaultHostName, kHTTPDefaultPort, document_root)) { delete test_server; return NULL; } return test_server; } + bool Init(const std::string& host_name, int port, + const std::wstring& document_root) { + std::wstring testserver_path; + std::wstring test_data_directory; + host_name_ = host_name; +#if defined(OS_WIN) + std::wstring command_line; +#elif defined(OS_POSIX) + std::vector<std::string> command_line; +#endif + + // Set PYTHONPATH for tlslite and pyftpdlib + SetPythonPaths(); + SetAppPath(host_name, port, document_root, scheme(), + &testserver_path, &test_data_directory); + SetCommandLineOption(testserver_path, test_data_directory, &command_line); + LaunchApp(command_line); + if (!VerifyLaunchApp("hello.html")) { + LOG(ERROR) << "Webserver not starting properly"; + return false; + } + return true; + } + // A subclass may wish to send the request in a different manner virtual bool MakeGETRequest(const std::string& page_name) { const GURL& url = TestServerPage(page_name); @@ -361,8 +516,54 @@ class HTTPTestServer : public BaseTestServer { EXPECT_TRUE(request->is_pending()); } + virtual ~HTTPTestServer() { + Stop(); + } + + void Stop() { + if (IsFinished()) + return; + + // here we append the time to avoid problems where the kill page + // is being cached rather than being executed on the server + std::string page_name = StringPrintf("kill?%u", + static_cast<int>(base::Time::Now().ToInternalValue())); + int retry_count = 5; + while (retry_count > 0) { + bool r = MakeGETRequest(page_name); + // BUG #1048625 causes the kill GET to fail. For now we just retry. + // Once the bug is fixed, we should remove the while loop and put back + // the following DCHECK. + // DCHECK(r); + if (r) + break; + retry_count--; + } + // Make sure we were successfull in stopping the testserver. + DCHECK(retry_count > 0); + } + virtual std::string scheme() { return "http"; } +#if defined(OS_WIN) + virtual void SetCommandLineOption(const std::wstring& testserver_path, + const std::wstring& test_data_directory, + std::wstring* command_line ) { + command_line->append(L"\"" + python_runtime_ + L"\" " + L"\"" + + testserver_path + L"\" --port=" + UTF8ToWide(port_str_) + + L" --data-dir=\"" + test_data_directory + L"\""); + } +#elif defined(OS_POSIX) + virtual void SetCommandLineOption(const std::wstring& testserver_path, + const std::wstring& test_data_directory, + std::vector<std::string>* command_line) { + command_line->push_back("python"); + command_line->push_back(WideToUTF8(testserver_path)); + command_line->push_back("--port=" + port_str_); + command_line->push_back("--data-dir=" + WideToUTF8(test_data_directory)); + } +#endif + private: // If non-null a background thread isn't created and instead this message loop // is used. @@ -371,75 +572,51 @@ class HTTPTestServer : public BaseTestServer { class HTTPSTestServer : public HTTPTestServer { protected: - explicit HTTPSTestServer() { + explicit HTTPSTestServer(const std::wstring& cert_path) + : cert_path_(cert_path) { } public: - // Create a server with a valid certificate - // TODO(dkegel): HTTPSTestServer should not require an instance to specify - // stock test certificates - static HTTPSTestServer* CreateGoodServer(const std::wstring& document_root) { - HTTPSTestServer* test_server = new HTTPSTestServer(); - FilePath docroot = FilePath::FromWStringHack(document_root); - FilePath certpath = test_server->launcher_.GetOKCertPath(); - if (!test_server->Start(net::TestServerLauncher::ProtoHTTP, - net::TestServerLauncher::kHostName, - net::TestServerLauncher::kOKHTTPSPort, - docroot, certpath)) { - delete test_server; - return NULL; - } - return test_server; - } - - // Create a server with an up to date certificate for the wrong hostname - // for this host - static HTTPSTestServer* CreateMismatchedServer( - const std::wstring& document_root) { - HTTPSTestServer* test_server = new HTTPSTestServer(); - FilePath docroot = FilePath::FromWStringHack(document_root); - FilePath certpath = test_server->launcher_.GetOKCertPath(); - if (!test_server->Start(net::TestServerLauncher::ProtoHTTP, - net::TestServerLauncher::kMismatchedHostName, - net::TestServerLauncher::kOKHTTPSPort, - docroot, certpath)) { - delete test_server; - return NULL; - } - return test_server; - } - - // Create a server with an expired certificate - static HTTPSTestServer* CreateExpiredServer( - const std::wstring& document_root) { - HTTPSTestServer* test_server = new HTTPSTestServer(); - FilePath docroot = FilePath::FromWStringHack(document_root); - FilePath certpath = test_server->launcher_.GetExpiredCertPath(); - if (!test_server->Start(net::TestServerLauncher::ProtoHTTP, - net::TestServerLauncher::kHostName, - net::TestServerLauncher::kBadHTTPSPort, - docroot, certpath)) { - delete test_server; - return NULL; - } - return test_server; - } - - // Create a server with an arbitrary certificate static HTTPSTestServer* CreateServer(const std::string& host_name, int port, const std::wstring& document_root, const std::wstring& cert_path) { - HTTPSTestServer* test_server = new HTTPSTestServer(); - FilePath docroot = FilePath::FromWStringHack(document_root); - FilePath certpath = FilePath::FromWStringHack(cert_path); - if (!test_server->Start(net::TestServerLauncher::ProtoHTTP, - host_name, port, docroot, certpath)) { + HTTPSTestServer* test_server = new HTTPSTestServer(cert_path); + if (!test_server->Init(host_name, port, document_root)) { delete test_server; return NULL; } return test_server; } +#if defined(OS_WIN) + virtual void SetCommandLineOption(const std::wstring& testserver_path, + const std::wstring& test_data_directory, + std::wstring* command_line ) { + command_line->append(L"\"" + python_runtime_ + L"\" " + L"\"" + + testserver_path + L"\"" + L" --port=" + + UTF8ToWide(port_str_) + L" --data-dir=\"" + + test_data_directory + L"\""); + if (!cert_path_.empty()) { + command_line->append(L" --https=\""); + command_line->append(cert_path_); + command_line->append(L"\""); + } + } +#elif defined(OS_POSIX) + virtual void SetCommandLineOption(const std::wstring& testserver_path, + const std::wstring& test_data_directory, + std::vector<std::string>* command_line) { + command_line->push_back("python"); + command_line->push_back(WideToUTF8(testserver_path)); + command_line->push_back("--port=" + port_str_); + command_line->push_back("--data-dir=" + WideToUTF8(test_data_directory)); + if (!cert_path_.empty()) + command_line->push_back("--https=" + WideToUTF8(cert_path_)); +} +#endif + + virtual std::string scheme() { return "https"; } + virtual ~HTTPSTestServer() { } @@ -449,32 +626,88 @@ class HTTPSTestServer : public HTTPTestServer { class FTPTestServer : public BaseTestServer { - public: + protected: FTPTestServer() { } + public: + FTPTestServer(const std::string& url_user, const std::string& url_password) { + url_user_ = url_user; + url_password_ = url_password; + } + static FTPTestServer* CreateServer(const std::wstring& document_root) { - std::string blank; - return CreateServer(document_root, blank, blank); + FTPTestServer* test_server = new FTPTestServer(); + if (!test_server->Init(kDefaultHostName, kFTPDefaultPort, document_root)) { + delete test_server; + return NULL; + } + return test_server; } static FTPTestServer* CreateServer(const std::wstring& document_root, const std::string& url_user, const std::string& url_password) { - FTPTestServer* test_server = new FTPTestServer(); - FilePath docroot = FilePath::FromWStringHack(document_root); - FilePath no_cert; - if (!test_server->Start(net::TestServerLauncher::ProtoFTP, - kDefaultHostName, kFTPDefaultPort, docroot, no_cert, - url_user, url_password)) { + FTPTestServer* test_server = new FTPTestServer(url_user, url_password); + if (!test_server->Init(kDefaultHostName, kFTPDefaultPort, document_root)) { delete test_server; return NULL; } return test_server; } + bool Init(const std::string& host_name, int port, + const std::wstring& document_root) { + std::wstring testserver_path; + std::wstring test_data_directory; + host_name_ = host_name; + +#if defined(OS_WIN) + std::wstring command_line; +#elif defined(OS_POSIX) + std::vector<std::string> command_line; +#endif + + // Set PYTHONPATH for tlslite and pyftpdlib + SetPythonPaths(); + SetAppPath(kDefaultHostName, port, document_root, scheme(), + &testserver_path, &test_data_directory); + SetCommandLineOption(testserver_path, test_data_directory, &command_line); + LaunchApp(command_line); + if (!VerifyLaunchApp("/LICENSE")) { + LOG(ERROR) << "FTPServer not starting properly."; + return false; + } + return true; + } + + virtual ~FTPTestServer() { + Stop(); + } + + void Stop() { + if (IsFinished()) + return; + + const std::string base_address = scheme() + "://" + host_name_ + ":" + + port_str_ + "/"; + const GURL& url = TestServerPage(base_address, "kill"); + TestDelegate d; + URLRequest request(url, &d); + request.set_context(new TestURLRequestContext()); + request.set_method("GET"); + request.Start(); + EXPECT_TRUE(request.is_pending()); + + MessageLoop::current()->Run(); + } + + virtual std::string scheme() { return "ftp"; } + virtual bool MakeGETRequest(const std::string& page_name) { - const GURL& url = TestServerPage(base_address_, page_name); + const std::string base_address = scheme() + "://" + host_name_ + ":" + + port_str_ + "/"; + const GURL& url = TestServerPage(base_address, page_name); TestDelegate d; URLRequest request(url, &d); request.set_context(new TestURLRequestContext()); @@ -489,6 +722,26 @@ class FTPTestServer : public BaseTestServer { return true; } +#if defined(OS_WIN) + virtual void SetCommandLineOption(const std::wstring& testserver_path, + const std::wstring& test_data_directory, + std::wstring* command_line ) { + command_line->append(L"\"" + python_runtime_ + L"\" " + L"\"" + + testserver_path + L"\"" + L" -f " + L" --port=" + + UTF8ToWide(port_str_) + L" --data-dir=\"" + + test_data_directory + L"\""); + } +#elif defined(OS_POSIX) + virtual void SetCommandLineOption(const std::wstring& testserver_path, + const std::wstring& test_data_directory, + std::vector<std::string>* command_line) { + command_line->push_back("python"); + command_line->push_back(WideToUTF8(testserver_path)); + command_line->push_back(" -f "); + command_line->push_back("--data-dir=" + WideToUTF8(test_data_directory)); + command_line->push_back("--port=" + port_str_); + } +#endif }; #endif // NET_URL_REQUEST_URL_REQUEST_UNITTEST_H_ |