Index: chrome/test/base/ui_test_utils.cc |
diff --git a/chrome/test/base/ui_test_utils.cc b/chrome/test/base/ui_test_utils.cc |
index 6ef89a132effffa558afc35295f72dbacaae0869..0c2a6d5045e2de37bea89f7c191ec9808b7a3ad5 100644 |
--- a/chrome/test/base/ui_test_utils.cc |
+++ b/chrome/test/base/ui_test_utils.cc |
@@ -6,6 +6,10 @@ |
#include <vector> |
+#if defined(OS_WIN) |
Paweł Hajdan Jr.
2011/11/22 16:38:37
nit: I think we include C headers before C++ ones.
Takashi Toyoshima
2011/11/22 20:13:42
Oh, sorry and thanks.
|
+#include <windows.h> |
+#endif |
+ |
#include "base/bind.h" |
#include "base/bind_helpers.h" |
#include "base/callback.h" |
@@ -16,6 +20,7 @@ |
#include "base/message_loop.h" |
#include "base/path_service.h" |
#include "base/process_util.h" |
+#include "base/string_number_conversions.h" |
#include "base/utf_string_conversions.h" |
#include "base/values.h" |
#include "chrome/browser/automation/ui_controls.h" |
@@ -62,6 +67,8 @@ |
#include "ui/aura/desktop.h" |
#endif |
+static const int kDefaultWsPort = 8880; |
+ |
namespace ui_test_utils { |
namespace { |
@@ -697,6 +704,47 @@ void AppendToPythonPath(const FilePath& dir) { |
} // anonymous namespace |
+#if defined(OS_POSIX) |
+class OrphanedWebSocketServerFilter : public base::ProcessFilter { |
+ public: |
+ OrphanedWebSocketServerFilter(std::string script_name, std::string port) |
+ : script_name_(script_name), |
+ port_(port) {} |
+ |
+ virtual bool Includes(const base::ProcessEntry& entry) const { |
+ // The parent process of orphaned WebSocket servers must be root process. |
+ if (entry.parent_pid() != 1) |
+ return false; |
+ |
+ // Python script name must be ended with specified script name. |
+ const std::string &script_name = entry.cmd_line_args()[2]; |
+ if (script_name.find_last_of(script_name_) != script_name.size() - 1) |
+ return false; |
+ |
+ // Check if an argument sequence like "--port 8880" exist. |
+ bool found = false; |
+ for (std::vector<std::string>::const_iterator it = |
+ entry.cmd_line_args().begin(); |
+ it != entry.cmd_line_args().end(); |
+ ++it) { |
+ if (*it == "--port") { |
+ ++it; |
+ if (it == entry.cmd_line_args().end() && *it == port_) { |
+ found = true; |
+ break; |
+ } |
+ } |
+ } |
+ return found; |
+ } |
+ |
+ private: |
+ std::string script_name_; |
+ std::string port_; |
+ DISALLOW_COPY_AND_ASSIGN(OrphanedWebSocketServerFilter); |
+}; |
+#endif |
+ |
TestWebSocketServer::TestWebSocketServer() : started_(false) { |
} |
@@ -710,6 +758,7 @@ bool TestWebSocketServer::Start(const FilePath& root_directory) { |
cmd_line->AppendArg("--register_cygwin"); |
cmd_line->AppendArgNative(FILE_PATH_LITERAL("--root=") + |
root_directory.value()); |
+ cmd_line->AppendArg("--port=" + base::IntToString(kDefaultWsPort)); |
if (!temp_dir_.CreateUniqueTempDir()) { |
LOG(ERROR) << "Unable to create a temporary directory."; |
return false; |
@@ -718,7 +767,37 @@ bool TestWebSocketServer::Start(const FilePath& root_directory) { |
cmd_line->AppendArgNative(FILE_PATH_LITERAL("--pidfile=") + |
websocket_pid_file_.value()); |
SetPythonPath(); |
+ |
base::LaunchOptions options; |
+ |
+#if defined(OS_POSIX) |
+ // Try to kill any orphaned WebSocket server processes that may be running. |
+ OrphanedWebSocketServerFilter filter("standalone.py", |
+ base::IntToString(kDefaultWsPort)); |
+ if (!base::KillProcesses("python", -1, &filter)) |
Paweł Hajdan Jr.
2011/11/22 16:38:37
I think you could use process groups on POSIX in a
Takashi Toyoshima
2011/11/22 20:13:42
Done.
|
+ LOG(WARNING) << |
+ "Failed to clean up older orphaned WebSocket server instance."; |
+#elif defined(OS_WIN) |
+ job_handle_.Set(CreateJobObject(NULL, NULL)); |
+ if (!job_handle_.IsValid()) { |
+ LOG(ERROR) << "Could not create JobObject."; |
+ return false; |
+ } |
+ |
+ JOBOBJECT_EXTENDED_LIMIT_INFORMATION limit_info = {0}; |
+ limit_info.BasicLimitInformation.LimitFlags = |
+ JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE; |
+ if (0 == SetInformationJobObject(job_handle_.Get(), |
Paweł Hajdan Jr.
2011/11/22 16:38:37
I think this is the third occurrence of this code
Takashi Toyoshima
2011/11/22 20:13:42
OK, I found the same code sequence in five source
|
+ JobObjectExtendedLimitInformation, &limit_info, sizeof(limit_info))) { |
+ LOG(ERROR) << "Could not SetInformationJobObject."; |
+ return false; |
+ } |
+ |
+ options.inherit_handles = true; |
+ options.job_handle = job_handle_.Get(); |
+#endif |
+ |
+ // Launch a new WebSocket server process. |
options.wait = true; |
if (!base::LaunchProcess(*cmd_line.get(), options, NULL)) { |
LOG(ERROR) << "Unable to launch websocket server."; |