1// Copyright 2013 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "mojo/common/test/multiprocess_test_helper.h"
6
7#include "base/command_line.h"
8#include "base/logging.h"
9#include "base/process/kill.h"
10#include "base/process/process_handle.h"
11#include "build/build_config.h"
12#include "mojo/embedder/platform_channel_pair.h"
13
14namespace mojo {
15namespace test {
16
17MultiprocessTestHelper::MultiprocessTestHelper()
18    : test_child_handle_(base::kNullProcessHandle) {
19  platform_channel_pair_.reset(new embedder::PlatformChannelPair());
20  server_platform_handle = platform_channel_pair_->PassServerHandle();
21}
22
23MultiprocessTestHelper::~MultiprocessTestHelper() {
24  CHECK_EQ(test_child_handle_, base::kNullProcessHandle);
25  server_platform_handle.reset();
26  platform_channel_pair_.reset();
27}
28
29void MultiprocessTestHelper::StartChild(const std::string& test_child_name) {
30  CHECK(platform_channel_pair_.get());
31  CHECK(!test_child_name.empty());
32  CHECK_EQ(test_child_handle_, base::kNullProcessHandle);
33
34  std::string test_child_main = test_child_name + "TestChildMain";
35
36  base::CommandLine command_line(
37      base::GetMultiProcessTestChildBaseCommandLine());
38  embedder::HandlePassingInformation handle_passing_info;
39  platform_channel_pair_->PrepareToPassClientHandleToChildProcess(
40      &command_line, &handle_passing_info);
41
42  base::LaunchOptions options;
43#if defined(OS_POSIX)
44  options.fds_to_remap = &handle_passing_info;
45#elif defined(OS_WIN)
46  options.start_hidden = true;
47  options.handles_to_inherit = &handle_passing_info;
48#else
49#error "Not supported yet."
50#endif
51
52  test_child_handle_ =
53      base::SpawnMultiProcessTestChild(test_child_main, command_line, options);
54  platform_channel_pair_->ChildProcessLaunched();
55
56  CHECK_NE(test_child_handle_, base::kNullProcessHandle);
57}
58
59int MultiprocessTestHelper::WaitForChildShutdown() {
60  CHECK_NE(test_child_handle_, base::kNullProcessHandle);
61
62  int rv = -1;
63  CHECK(base::WaitForExitCodeWithTimeout(
64      test_child_handle_, &rv, TestTimeouts::action_timeout()));
65  base::CloseProcessHandle(test_child_handle_);
66  test_child_handle_ = base::kNullProcessHandle;
67  return rv;
68}
69
70bool MultiprocessTestHelper::WaitForChildTestShutdown() {
71  return WaitForChildShutdown() == 0;
72}
73
74// static
75void MultiprocessTestHelper::ChildSetup() {
76  CHECK(base::CommandLine::InitializedForCurrentProcess());
77  client_platform_handle =
78      embedder::PlatformChannelPair::PassClientHandleFromParentProcess(
79          *base::CommandLine::ForCurrentProcess());
80}
81
82// static
83embedder::ScopedPlatformHandle MultiprocessTestHelper::client_platform_handle;
84
85}  // namespace test
86}  // namespace mojo
87