Index: mojo/edk/test/multiprocess_test_helper.cc |
diff --git a/mojo/edk/test/multiprocess_test_helper.cc b/mojo/edk/test/multiprocess_test_helper.cc |
index 0490119abbc227a32bdedcccd05c685379e7b834..316bc795fd7a6e991072fb36842e7eebc4f9e338 100644 |
--- a/mojo/edk/test/multiprocess_test_helper.cc |
+++ b/mojo/edk/test/multiprocess_test_helper.cc |
@@ -4,15 +4,23 @@ |
#include "mojo/edk/test/multiprocess_test_helper.h" |
+#include <functional> |
#include <utility> |
+#include "base/bind.h" |
#include "base/command_line.h" |
#include "base/logging.h" |
+#include "base/memory/ref_counted.h" |
#include "base/process/kill.h" |
#include "base/process/process_handle.h" |
+#include "base/run_loop.h" |
+#include "base/strings/stringprintf.h" |
+#include "base/task_runner.h" |
+#include "base/thread_task_runner_handle.h" |
#include "build/build_config.h" |
#include "mojo/edk/embedder/embedder.h" |
#include "mojo/edk/embedder/platform_channel_pair.h" |
+#include "testing/gtest/include/gtest/gtest.h" |
#if defined(OS_WIN) |
#include "base/win/windows_version.h" |
@@ -22,29 +30,61 @@ namespace mojo { |
namespace edk { |
namespace test { |
-const char kBrokerHandleSwitch[] = "broker-handle"; |
+namespace { |
-MultiprocessTestHelper::MultiprocessTestHelper() { |
- platform_channel_pair_.reset(new PlatformChannelPair()); |
- server_platform_handle = platform_channel_pair_->PassServerHandle(); |
- broker_platform_channel_pair_.reset(new PlatformChannelPair()); |
+const char kMojoPrimordialPipeToken[] = "mojo-primordial-pipe-token"; |
+ |
+void RunHandlerOnMainThread(std::function<int(MojoHandle)> handler, |
+ int* exit_code, |
+ const base::Closure& quit_closure, |
+ ScopedMessagePipeHandle pipe) { |
+ *exit_code = handler(pipe.get().value()); |
+ quit_closure.Run(); |
+} |
+ |
+void RunHandler(std::function<int(MojoHandle)> handler, |
+ int* exit_code, |
+ const base::Closure& quit_closure, |
+ scoped_refptr<base::TaskRunner> task_runner, |
+ ScopedMessagePipeHandle pipe) { |
+ task_runner->PostTask( |
+ FROM_HERE, |
+ base::Bind(&RunHandlerOnMainThread, handler, base::Unretained(exit_code), |
+ quit_closure, base::Passed(&pipe))); |
+} |
+ |
+int RunClientFunction(std::function<int(MojoHandle)> handler) { |
+ base::MessageLoop message_loop; |
+ base::RunLoop run_loop; |
+ int exit_code = 0; |
+ CHECK(!MultiprocessTestHelper::primordial_pipe_token.empty()); |
+ CreateChildMessagePipe( |
+ MultiprocessTestHelper::primordial_pipe_token, |
+ base::Bind(&RunHandler, handler, base::Unretained(&exit_code), |
+ run_loop.QuitClosure(), base::ThreadTaskRunnerHandle::Get())); |
+ run_loop.Run(); |
+ return exit_code; |
} |
+} // namespace |
+ |
+MultiprocessTestHelper::MultiprocessTestHelper() {} |
+ |
MultiprocessTestHelper::~MultiprocessTestHelper() { |
CHECK(!test_child_.IsValid()); |
- server_platform_handle.reset(); |
- platform_channel_pair_.reset(); |
} |
-void MultiprocessTestHelper::StartChild(const std::string& test_child_name) { |
- StartChildWithExtraSwitch(test_child_name, std::string(), std::string()); |
+void MultiprocessTestHelper::StartChild(const std::string& test_child_name, |
+ const HandlerCallback& callback) { |
+ StartChildWithExtraSwitch( |
+ test_child_name, std::string(), std::string(), callback); |
} |
void MultiprocessTestHelper::StartChildWithExtraSwitch( |
const std::string& test_child_name, |
const std::string& switch_string, |
- const std::string& switch_value) { |
- CHECK(platform_channel_pair_); |
+ const std::string& switch_value, |
+ const HandlerCallback& callback) { |
CHECK(!test_child_name.empty()); |
CHECK(!test_child_.IsValid()); |
@@ -52,13 +92,14 @@ void MultiprocessTestHelper::StartChildWithExtraSwitch( |
base::CommandLine command_line( |
base::GetMultiProcessTestChildBaseCommandLine()); |
+ |
+ PlatformChannelPair channel; |
HandlePassingInformation handle_passing_info; |
- platform_channel_pair_->PrepareToPassClientHandleToChildProcess( |
- &command_line, &handle_passing_info); |
+ channel.PrepareToPassClientHandleToChildProcess(&command_line, |
+ &handle_passing_info); |
- std::string broker_handle = broker_platform_channel_pair_-> |
- PrepareToPassClientHandleToChildProcessAsString(&handle_passing_info); |
- command_line.AppendSwitchASCII(kBrokerHandleSwitch, broker_handle); |
+ std::string pipe_token = mojo::edk::GenerateRandomToken(); |
+ command_line.AppendSwitchASCII(kMojoPrimordialPipeToken, pipe_token); |
if (!switch_string.empty()) { |
CHECK(!command_line.HasSwitch(switch_string)); |
@@ -83,11 +124,10 @@ void MultiprocessTestHelper::StartChildWithExtraSwitch( |
test_child_ = |
base::SpawnMultiProcessTestChild(test_child_main, command_line, options); |
- platform_channel_pair_->ChildProcessLaunched(); |
+ channel.ChildProcessLaunched(); |
- broker_platform_channel_pair_->ChildProcessLaunched(); |
- ChildProcessLaunched(test_child_.Handle(), |
- broker_platform_channel_pair_->PassServerHandle()); |
+ ChildProcessLaunched(test_child_.Handle(), channel.PassServerHandle()); |
+ CreateParentMessagePipe(pipe_token, callback); |
CHECK(test_child_.IsValid()); |
} |
@@ -109,21 +149,36 @@ bool MultiprocessTestHelper::WaitForChildTestShutdown() { |
// static |
void MultiprocessTestHelper::ChildSetup() { |
CHECK(base::CommandLine::InitializedForCurrentProcess()); |
- client_platform_handle = |
+ |
+ primordial_pipe_token = base::CommandLine::ForCurrentProcess() |
+ ->GetSwitchValueASCII(kMojoPrimordialPipeToken); |
+ CHECK(!primordial_pipe_token.empty()); |
+ |
+ SetParentPipeHandle( |
PlatformChannelPair::PassClientHandleFromParentProcess( |
- *base::CommandLine::ForCurrentProcess()); |
- |
- std::string broker_handle_str = |
- base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII( |
- kBrokerHandleSwitch); |
- ScopedPlatformHandle broker_handle = |
- PlatformChannelPair::PassClientHandleFromParentProcessFromString( |
- broker_handle_str); |
- SetParentPipeHandle(std::move(broker_handle)); |
+ *base::CommandLine::ForCurrentProcess())); |
+} |
+ |
+// static |
+int MultiprocessTestHelper::RunClientMain( |
+ const base::Callback<int(MojoHandle)>& main) { |
+ return RunClientFunction([main](MojoHandle handle){ |
+ return main.Run(handle); |
+ }); |
+} |
+ |
+// static |
+int MultiprocessTestHelper::RunClientTestMain( |
+ const base::Callback<void(MojoHandle)>& main) { |
+ return RunClientFunction([main](MojoHandle handle) { |
+ main.Run(handle); |
+ return (::testing::Test::HasFatalFailure() || |
+ ::testing::Test::HasNonfatalFailure()) ? 1 : 0; |
+ }); |
} |
// static |
-ScopedPlatformHandle MultiprocessTestHelper::client_platform_handle; |
+std::string MultiprocessTestHelper::primordial_pipe_token; |
} // namespace test |
} // namespace edk |