| Index: net/url_request/url_request_unittest.h
|
| ===================================================================
|
| --- net/url_request/url_request_unittest.h (revision 7499)
|
| +++ net/url_request/url_request_unittest.h (working copy)
|
| @@ -9,6 +9,7 @@
|
|
|
| #include <sstream>
|
| #include <string>
|
| +#include <vector>
|
|
|
| #include "base/file_path.h"
|
| #include "base/file_util.h"
|
| @@ -27,7 +28,9 @@
|
| #include "testing/gtest/include/gtest/gtest.h"
|
| #include "googleurl/src/url_util.h"
|
|
|
| -const int kDefaultPort = 1337;
|
| +const int kHTTPDefaultPort = 1337;
|
| +const int kFTPDefaultPort = 1338;
|
| +
|
| const std::string kDefaultHostName("localhost");
|
|
|
| // This URLRequestContext does not use a local cache.
|
| @@ -190,29 +193,37 @@
|
| char buf_[4096];
|
| };
|
|
|
| -// This object bounds the lifetime of an external python-based HTTP server
|
| +// This object bounds the lifetime of an external python-based HTTP/FTP server
|
| // that can provide various responses useful for testing.
|
| -class TestServer : public base::ProcessFilter {
|
| - public:
|
| - TestServer(const std::wstring& document_root)
|
| - : process_handle_(NULL),
|
| - is_shutdown_(true) {
|
| - Init(kDefaultHostName, kDefaultPort, document_root, std::wstring());
|
| +class BaseTestServer : public base::ProcessFilter,
|
| + public base::RefCounted<BaseTestServer> {
|
| + protected:
|
| + BaseTestServer()
|
| + : process_handle_(NULL) {
|
| }
|
|
|
| - virtual ~TestServer() {
|
| - Shutdown();
|
| + public:
|
| + virtual ~BaseTestServer() {
|
| + if (process_handle_) {
|
| +#if defined(OS_WIN)
|
| + CloseHandle(process_handle_);
|
| +#endif
|
| + process_handle_ = NULL;
|
| + }
|
| + // Make sure we don't leave any stray testserver processes laying around.
|
| + std::wstring testserver_name =
|
| + file_util::GetFilenameFromPath(python_runtime_);
|
| + base::CleanupProcesses(testserver_name, 10000, 1, this);
|
| + EXPECT_EQ(0, base::GetProcessCount(testserver_name, this));
|
| }
|
|
|
| // Implementation of ProcessFilter
|
| virtual bool Includes(uint32 pid, uint32 parent_pid) const {
|
| - // This function may be called after Shutdown(), in which process_handle_ is
|
| - // set to NULL. Since no process handle is set, it can't be included in the
|
| - // filter.
|
| + // Since no process handle is set, it can't be included in the filter.
|
| if (!process_handle_)
|
| return false;
|
| // TODO(port): rationalize return value of GetProcId
|
| - return pid == (uint32)base::GetProcId(process_handle_);
|
| + return pid == static_cast<uint32>(base::GetProcId(process_handle_));
|
| }
|
|
|
| GURL TestServerPage(const std::string& path) {
|
| @@ -223,101 +234,46 @@
|
| return GURL(base_address_ + WideToUTF8(path));
|
| }
|
|
|
| - // 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);
|
| + 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");
|
|
|
| - // Spin up a background thread for this request so that we have access to
|
| - // an IO message loop, and in cases where this thread already has an IO
|
| - // message loop, we also want to avoid spinning a nested message loop.
|
| -
|
| - SyncTestDelegate d;
|
| - {
|
| - base::Thread io_thread("MakeGETRequest");
|
| - base::Thread::Options options;
|
| - options.message_loop_type = MessageLoop::TYPE_IO;
|
| - io_thread.StartWithOptions(options);
|
| - io_thread.message_loop()->PostTask(FROM_HERE, NewRunnableFunction(
|
| - &TestServer::StartGETRequest, url, &d));
|
| - d.Wait();
|
| - }
|
| - return d.did_succeed();
|
| - }
|
| + 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());
|
| + }
|
|
|
| - bool init_successful() const { return init_successful_; }
|
| -
|
| - protected:
|
| - struct ManualInit {};
|
| -
|
| - // Used by subclasses that need to defer initialization until they are fully
|
| - // constructed. The subclass should call Init once it is ready (usually in
|
| - // its constructor).
|
| - TestServer(ManualInit)
|
| - : process_handle_(NULL),
|
| - init_successful_(false),
|
| - is_shutdown_(true) {
|
| - }
|
| -
|
| - virtual std::string scheme() { return std::string("http"); }
|
| -
|
| - // This is in a separate function so that we can have assertions and so that
|
| - // subclasses can call this later.
|
| - void Init(const std::string& host_name, int port,
|
| - const std::wstring& document_root,
|
| - const std::wstring& cert_path) {
|
| - std::stringstream ss;
|
| - std::string port_str;
|
| - ss << (port ? port : kDefaultPort);
|
| - ss >> port_str;
|
| - base_address_ = scheme() + "://" + host_name + ":" + port_str + "/";
|
| -
|
| - std::wstring testserver_path;
|
| - 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");
|
| -
|
| - std::wstring test_data_directory;
|
| - PathService::Get(base::DIR_SOURCE_ROOT, &test_data_directory);
|
| - std::wstring normalized_document_root = document_root;
|
| -#if defined(OS_WIN)
|
| - std::replace(normalized_document_root.begin(),
|
| - normalized_document_root.end(),
|
| - L'/', FilePath::kSeparators[0]);
|
| -#endif
|
| - file_util::AppendToPath(&test_data_directory, normalized_document_root);
|
| -
|
| -#if defined(OS_WIN)
|
| - std::wstring command_line =
|
| - L"\"" + python_runtime_ + L"\" " + L"\"" + testserver_path +
|
| - 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"\"");
|
| + set_python_path = true;
|
| }
|
| -
|
| - ASSERT_TRUE(
|
| - base::LaunchApp(command_line, false, true, &process_handle_)) <<
|
| - "Failed to launch " << command_line;
|
| #elif defined(OS_POSIX)
|
| // Set up PYTHONPATH so that Python is able to find the in-tree copy of
|
| - // tlslite.
|
| -
|
| + // 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) {
|
| @@ -325,81 +281,89 @@
|
| 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 {
|
| - setenv(kPythonPath, tlslite_path.value().c_str(), 1);
|
| + 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;
|
| }
|
| -
|
| - 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));
|
| -
|
| - base::file_handle_mapping_vector no_mappings;
|
| - ASSERT_TRUE(
|
| - base::LaunchApp(command_line, no_mappings, false, &process_handle_)) <<
|
| - "Failed to launch " << command_line[0] << " ...";
|
| #endif
|
| + }
|
|
|
| - // Verify that the webserver is actually started.
|
| - // Otherwise tests can fail if they run faster than Python can start.
|
| - int retries = 10;
|
| - bool success;
|
| - while ((success = MakeGETRequest("hello.html")) == false && retries > 0) {
|
| - retries--;
|
| - PlatformThread::Sleep(500);
|
| + 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_ + "/";
|
| + else
|
| + base_address_ = scheme + "://" + url_user_ + ":" + url_password_ +
|
| + "@" + host_name + ":" + port_str_ + "/";
|
| }
|
| - ASSERT_TRUE(success) << "Webserver not starting properly.";
|
|
|
| - init_successful_ = true;
|
| - is_shutdown_ = false;
|
| - }
|
| + 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");
|
|
|
| - void Shutdown() {
|
| - if (is_shutdown_)
|
| - return;
|
| + 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");
|
|
|
| - // here we append the time to avoid problems where the kill page
|
| - // is being cached rather than being executed on the server
|
| - std::ostringstream page_name;
|
| - page_name << "kill?" << (unsigned int)(base::Time::Now().ToInternalValue());
|
| - int retry_count = 5;
|
| - while (retry_count > 0) {
|
| - bool r = MakeGETRequest(page_name.str());
|
| - // 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);
|
| + PathService::Get(base::DIR_SOURCE_ROOT, test_data_directory);
|
| + std::wstring normalized_document_root = document_root;
|
|
|
| - if (process_handle_) {
|
| #if defined(OS_WIN)
|
| - CloseHandle(process_handle_);
|
| + // 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
|
| - process_handle_ = NULL;
|
| - }
|
| + if (!normalized_document_root.empty())
|
| + file_util::AppendToPath(test_data_directory, normalized_document_root);
|
|
|
| - // Make sure we don't leave any stray testserver processes laying around.
|
| - std::wstring testserver_name =
|
| - file_util::GetFilenameFromPath(python_runtime_);
|
| - base::CleanupProcesses(testserver_name, 10000, 1, this);
|
| - EXPECT_EQ(0, base::GetProcessCount(testserver_name, this));
|
| + }
|
|
|
| - is_shutdown_ = true;
|
| +#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) {
|
| + ASSERT_TRUE(base::LaunchApp(command_line, false, true, &process_handle_)) <<
|
| + "Failed to launch " << command_line[0] << " ...";
|
| + }
|
| +#endif
|
|
|
| - private:
|
| + 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;
|
| + }
|
| +
|
| + protected:
|
| // Used by MakeGETRequest to implement sync load behavior.
|
| class SyncTestDelegate : public TestDelegate {
|
| public:
|
| @@ -417,6 +381,73 @@
|
| bool success_;
|
| DISALLOW_COPY_AND_ASSIGN(SyncTestDelegate);
|
| };
|
| +
|
| + std::string base_address_;
|
| + std::string url_user_;
|
| + std::string url_password_;
|
| + std::wstring python_runtime_;
|
| + base::ProcessHandle process_handle_;
|
| + std::string port_str_;
|
| +};
|
| +
|
| +class HTTPTestServer : public BaseTestServer {
|
| + protected:
|
| + HTTPTestServer() {
|
| + }
|
| +
|
| + public:
|
| + static HTTPTestServer* CreateServer(const std::wstring& document_root) {
|
| + HTTPTestServer* test_server = new HTTPTestServer();
|
| + 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;
|
| +#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("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);
|
| +
|
| + // Spin up a background thread for this request so that we have access to
|
| + // an IO message loop, and in cases where this thread already has an IO
|
| + // message loop, we also want to avoid spinning a nested message loop.
|
| + SyncTestDelegate d;
|
| + {
|
| + base::Thread io_thread("MakeGETRequest");
|
| + base::Thread::Options options;
|
| + options.message_loop_type = MessageLoop::TYPE_IO;
|
| + io_thread.StartWithOptions(options);
|
| + io_thread.message_loop()->PostTask(FROM_HERE, NewRunnableFunction(
|
| + &HTTPTestServer::StartGETRequest, url, &d));
|
| + d.Wait();
|
| + }
|
| + return d.did_succeed();
|
| + }
|
| +
|
| static void StartGETRequest(const GURL& url, URLRequest::Delegate* delegate) {
|
| URLRequest* request = new URLRequest(url, delegate);
|
| request->set_context(new TestURLRequestContext());
|
| @@ -425,23 +456,212 @@
|
| EXPECT_TRUE(request->is_pending());
|
| }
|
|
|
| - std::string base_address_;
|
| - std::wstring python_runtime_;
|
| - base::ProcessHandle process_handle_;
|
| - bool init_successful_;
|
| - bool is_shutdown_;
|
| + virtual ~HTTPTestServer() {
|
| + // 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
|
| };
|
|
|
| -class HTTPSTestServer : public TestServer {
|
| +class HTTPSTestServer : public HTTPTestServer {
|
| + protected:
|
| + explicit HTTPSTestServer(const std::wstring& cert_path)
|
| + : cert_path_(cert_path) {
|
| + }
|
| +
|
| public:
|
| - HTTPSTestServer(const std::string& host_name, int port,
|
| - const std::wstring& document_root,
|
| - const std::wstring& cert_path) : TestServer(ManualInit()) {
|
| - Init(host_name, port, document_root, cert_path);
|
| + 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(cert_path);
|
| + if (!test_server->Init(host_name, port, document_root)) {
|
| + delete test_server;
|
| + return NULL;
|
| + }
|
| + return test_server;
|
| }
|
|
|
| - virtual std::string scheme() { return std::string("https"); }
|
| +#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() {
|
| + }
|
| +
|
| + protected:
|
| + std::wstring cert_path_;
|
| };
|
|
|
| +
|
| +class FTPTestServer : public BaseTestServer {
|
| + 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) {
|
| + 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(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;
|
| +
|
| +#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() {
|
| + int retry_count = 5;
|
| + while (retry_count > 0) {
|
| + bool r = MakeGETRequest("kill");
|
| + // 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 "ftp"; }
|
| +
|
| + virtual bool MakeGETRequest(const std::string& page_name) {
|
| + const GURL& url = TestServerPage(page_name);
|
| + 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();
|
| + if (request.is_pending())
|
| + return false;
|
| +
|
| + 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(" -f ");
|
| + command_line->push_back("--data-dir=" + WideToUTF8(test_data_directory));
|
| + command_line->push_back("--port=" + port_str_);
|
| + command_line->push_back("--data-dir=" + WideToUTF8(test_data_directory));
|
| + }
|
| +#endif
|
| +};
|
| +
|
| #endif // NET_URL_REQUEST_URL_REQUEST_UNITTEST_H_
|
| -
|
|
|