Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(212)

Side by Side Diff: mojo/edk/test/multiprocess_test_helper.cc

Issue 1585493002: [mojo] Ports EDK (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "mojo/edk/test/multiprocess_test_helper.h" 5 #include "mojo/edk/test/multiprocess_test_helper.h"
6 6
7 #include <functional>
7 #include <utility> 8 #include <utility>
8 9
10 #include "base/bind.h"
9 #include "base/command_line.h" 11 #include "base/command_line.h"
10 #include "base/logging.h" 12 #include "base/logging.h"
13 #include "base/memory/ref_counted.h"
11 #include "base/process/kill.h" 14 #include "base/process/kill.h"
12 #include "base/process/process_handle.h" 15 #include "base/process/process_handle.h"
16 #include "base/run_loop.h"
17 #include "base/strings/stringprintf.h"
18 #include "base/task_runner.h"
19 #include "base/thread_task_runner_handle.h"
13 #include "build/build_config.h" 20 #include "build/build_config.h"
14 #include "mojo/edk/embedder/embedder.h" 21 #include "mojo/edk/embedder/embedder.h"
15 #include "mojo/edk/embedder/platform_channel_pair.h" 22 #include "mojo/edk/embedder/platform_channel_pair.h"
23 #include "testing/gtest/include/gtest/gtest.h"
16 24
17 #if defined(OS_WIN) 25 #if defined(OS_WIN)
18 #include "base/win/windows_version.h" 26 #include "base/win/windows_version.h"
19 #endif 27 #endif
20 28
21 namespace mojo { 29 namespace mojo {
22 namespace edk { 30 namespace edk {
23 namespace test { 31 namespace test {
24 32
25 const char kBrokerHandleSwitch[] = "broker-handle"; 33 namespace {
26 34
27 MultiprocessTestHelper::MultiprocessTestHelper() { 35 const char kMojoPrimordialPipeToken[] = "mojo-primordial-pipe-token";
28 platform_channel_pair_.reset(new PlatformChannelPair()); 36
29 server_platform_handle = platform_channel_pair_->PassServerHandle(); 37 void RunHandlerOnMainThread(std::function<int(MojoHandle)> handler,
30 broker_platform_channel_pair_.reset(new PlatformChannelPair()); 38 int* exit_code,
39 const base::Closure& quit_closure,
40 ScopedMessagePipeHandle pipe) {
41 *exit_code = handler(pipe.get().value());
42 quit_closure.Run();
31 } 43 }
32 44
45 void RunHandler(std::function<int(MojoHandle)> handler,
46 int* exit_code,
47 const base::Closure& quit_closure,
48 scoped_refptr<base::TaskRunner> task_runner,
49 ScopedMessagePipeHandle pipe) {
50 task_runner->PostTask(
51 FROM_HERE,
52 base::Bind(&RunHandlerOnMainThread, handler, base::Unretained(exit_code),
53 quit_closure, base::Passed(&pipe)));
54 }
55
56 int RunClientFunction(std::function<int(MojoHandle)> handler) {
57 base::MessageLoop message_loop;
58 base::RunLoop run_loop;
59 int exit_code = 0;
60 CHECK(!MultiprocessTestHelper::primordial_pipe_token.empty());
61 CreateChildMessagePipe(
62 MultiprocessTestHelper::primordial_pipe_token,
63 base::Bind(&RunHandler, handler, base::Unretained(&exit_code),
64 run_loop.QuitClosure(), base::ThreadTaskRunnerHandle::Get()));
65 run_loop.Run();
66 return exit_code;
67 }
68
69 } // namespace
70
71 MultiprocessTestHelper::MultiprocessTestHelper() {}
72
33 MultiprocessTestHelper::~MultiprocessTestHelper() { 73 MultiprocessTestHelper::~MultiprocessTestHelper() {
34 CHECK(!test_child_.IsValid()); 74 CHECK(!test_child_.IsValid());
35 server_platform_handle.reset();
36 platform_channel_pair_.reset();
37 } 75 }
38 76
39 void MultiprocessTestHelper::StartChild(const std::string& test_child_name) { 77 void MultiprocessTestHelper::StartChild(const std::string& test_child_name,
40 StartChildWithExtraSwitch(test_child_name, std::string(), std::string()); 78 const HandlerCallback& callback) {
79 StartChildWithExtraSwitch(
80 test_child_name, std::string(), std::string(), callback);
41 } 81 }
42 82
43 void MultiprocessTestHelper::StartChildWithExtraSwitch( 83 void MultiprocessTestHelper::StartChildWithExtraSwitch(
44 const std::string& test_child_name, 84 const std::string& test_child_name,
45 const std::string& switch_string, 85 const std::string& switch_string,
46 const std::string& switch_value) { 86 const std::string& switch_value,
47 CHECK(platform_channel_pair_); 87 const HandlerCallback& callback) {
48 CHECK(!test_child_name.empty()); 88 CHECK(!test_child_name.empty());
49 CHECK(!test_child_.IsValid()); 89 CHECK(!test_child_.IsValid());
50 90
51 std::string test_child_main = test_child_name + "TestChildMain"; 91 std::string test_child_main = test_child_name + "TestChildMain";
52 92
53 base::CommandLine command_line( 93 base::CommandLine command_line(
54 base::GetMultiProcessTestChildBaseCommandLine()); 94 base::GetMultiProcessTestChildBaseCommandLine());
95
96 PlatformChannelPair channel;
55 HandlePassingInformation handle_passing_info; 97 HandlePassingInformation handle_passing_info;
56 platform_channel_pair_->PrepareToPassClientHandleToChildProcess( 98 channel.PrepareToPassClientHandleToChildProcess(&command_line,
57 &command_line, &handle_passing_info); 99 &handle_passing_info);
58 100
59 std::string broker_handle = broker_platform_channel_pair_-> 101 std::string pipe_token = mojo::edk::GenerateRandomToken();
60 PrepareToPassClientHandleToChildProcessAsString(&handle_passing_info); 102 command_line.AppendSwitchASCII(kMojoPrimordialPipeToken, pipe_token);
61 command_line.AppendSwitchASCII(kBrokerHandleSwitch, broker_handle);
62 103
63 if (!switch_string.empty()) { 104 if (!switch_string.empty()) {
64 CHECK(!command_line.HasSwitch(switch_string)); 105 CHECK(!command_line.HasSwitch(switch_string));
65 if (!switch_value.empty()) 106 if (!switch_value.empty())
66 command_line.AppendSwitchASCII(switch_string, switch_value); 107 command_line.AppendSwitchASCII(switch_string, switch_value);
67 else 108 else
68 command_line.AppendSwitch(switch_string); 109 command_line.AppendSwitch(switch_string);
69 } 110 }
70 111
71 base::LaunchOptions options; 112 base::LaunchOptions options;
72 #if defined(OS_POSIX) 113 #if defined(OS_POSIX)
73 options.fds_to_remap = &handle_passing_info; 114 options.fds_to_remap = &handle_passing_info;
74 #elif defined(OS_WIN) 115 #elif defined(OS_WIN)
75 options.start_hidden = true; 116 options.start_hidden = true;
76 if (base::win::GetVersion() >= base::win::VERSION_VISTA) 117 if (base::win::GetVersion() >= base::win::VERSION_VISTA)
77 options.handles_to_inherit = &handle_passing_info; 118 options.handles_to_inherit = &handle_passing_info;
78 else 119 else
79 options.inherit_handles = true; 120 options.inherit_handles = true;
80 #else 121 #else
81 #error "Not supported yet." 122 #error "Not supported yet."
82 #endif 123 #endif
83 124
84 test_child_ = 125 test_child_ =
85 base::SpawnMultiProcessTestChild(test_child_main, command_line, options); 126 base::SpawnMultiProcessTestChild(test_child_main, command_line, options);
86 platform_channel_pair_->ChildProcessLaunched(); 127 channel.ChildProcessLaunched();
87 128
88 broker_platform_channel_pair_->ChildProcessLaunched(); 129 ChildProcessLaunched(test_child_.Handle(), channel.PassServerHandle());
89 ChildProcessLaunched(test_child_.Handle(), 130 CreateParentMessagePipe(pipe_token, callback);
90 broker_platform_channel_pair_->PassServerHandle());
91 131
92 CHECK(test_child_.IsValid()); 132 CHECK(test_child_.IsValid());
93 } 133 }
94 134
95 int MultiprocessTestHelper::WaitForChildShutdown() { 135 int MultiprocessTestHelper::WaitForChildShutdown() {
96 CHECK(test_child_.IsValid()); 136 CHECK(test_child_.IsValid());
97 137
98 int rv = -1; 138 int rv = -1;
99 CHECK( 139 CHECK(
100 test_child_.WaitForExitWithTimeout(TestTimeouts::action_timeout(), &rv)); 140 test_child_.WaitForExitWithTimeout(TestTimeouts::action_timeout(), &rv));
101 test_child_.Close(); 141 test_child_.Close();
102 return rv; 142 return rv;
103 } 143 }
104 144
105 bool MultiprocessTestHelper::WaitForChildTestShutdown() { 145 bool MultiprocessTestHelper::WaitForChildTestShutdown() {
106 return WaitForChildShutdown() == 0; 146 return WaitForChildShutdown() == 0;
107 } 147 }
108 148
109 // static 149 // static
110 void MultiprocessTestHelper::ChildSetup() { 150 void MultiprocessTestHelper::ChildSetup() {
111 CHECK(base::CommandLine::InitializedForCurrentProcess()); 151 CHECK(base::CommandLine::InitializedForCurrentProcess());
112 client_platform_handle = 152
153 primordial_pipe_token = base::CommandLine::ForCurrentProcess()
154 ->GetSwitchValueASCII(kMojoPrimordialPipeToken);
155 CHECK(!primordial_pipe_token.empty());
156
157 SetParentPipeHandle(
113 PlatformChannelPair::PassClientHandleFromParentProcess( 158 PlatformChannelPair::PassClientHandleFromParentProcess(
114 *base::CommandLine::ForCurrentProcess()); 159 *base::CommandLine::ForCurrentProcess()));
115
116 std::string broker_handle_str =
117 base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
118 kBrokerHandleSwitch);
119 ScopedPlatformHandle broker_handle =
120 PlatformChannelPair::PassClientHandleFromParentProcessFromString(
121 broker_handle_str);
122 SetParentPipeHandle(std::move(broker_handle));
123 } 160 }
124 161
125 // static 162 // static
126 ScopedPlatformHandle MultiprocessTestHelper::client_platform_handle; 163 int MultiprocessTestHelper::RunClientMain(
164 const base::Callback<int(MojoHandle)>& main) {
165 return RunClientFunction([main](MojoHandle handle){
166 return main.Run(handle);
167 });
168 }
169
170 // static
171 int MultiprocessTestHelper::RunClientTestMain(
172 const base::Callback<void(MojoHandle)>& main) {
173 return RunClientFunction([main](MojoHandle handle) {
174 main.Run(handle);
175 return (::testing::Test::HasFatalFailure() ||
176 ::testing::Test::HasNonfatalFailure()) ? 1 : 0;
177 });
178 }
179
180 // static
181 std::string MultiprocessTestHelper::primordial_pipe_token;
127 182
128 } // namespace test 183 } // namespace test
129 } // namespace edk 184 } // namespace edk
130 } // namespace mojo 185 } // namespace mojo
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698