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

Side by Side Diff: base/test/multiprocess_test_android.cc

Issue 1952513003: Fix Android multi-process tests on M. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 7 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 (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "base/test/multiprocess_test.h" 5 #include "base/test/multiprocess_test.h"
6 6
7 #include <errno.h> 7 #include <errno.h>
8 #include <string.h> 8 #include <string.h>
9 #include <sys/types.h> 9 #include <sys/types.h>
10 #include <sys/socket.h> 10 #include <sys/socket.h>
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
96 // Starts a child test helper process. 96 // Starts a child test helper process.
97 Process StartChildTestHelper(const std::string& procname, 97 Process StartChildTestHelper(const std::string& procname,
98 const CommandLine& base_command_line, 98 const CommandLine& base_command_line,
99 const LaunchOptions& options); 99 const LaunchOptions& options);
100 100
101 // Waits for a child test helper process. 101 // Waits for a child test helper process.
102 bool WaitForChildExitWithTimeout(const Process& process, TimeDelta timeout, 102 bool WaitForChildExitWithTimeout(const Process& process, TimeDelta timeout,
103 int* exit_code); 103 int* exit_code);
104 104
105 bool IsReady() const { return child_fd_ != -1; } 105 bool IsReady() const { return child_fd_ != -1; }
106 bool IsChild() const { return parent_fd_ != -1; } 106 bool IsChild() const { return is_child_; }
107 107
108 private: 108 private:
109 // Wrappers around sendmsg/recvmsg that supports message fragmentation. 109 // Wrappers around sendmsg/recvmsg that supports message fragmentation.
110 void Send(int fd, const MessageHeader* msg, const std::vector<int>& fds); 110 void Send(int fd, const MessageHeader* msg, const std::vector<int>& fds);
111 ssize_t Recv(int fd, void* buf, std::vector<ScopedFD>* fds); 111 ssize_t Recv(int fd, void* buf, std::vector<ScopedFD>* fds);
112 112
113 // Parent process implementation. 113 // Parent process implementation.
114 void DoParent(int fd); 114 void DoParent(int fd);
115 // Helper process implementation. 115 // Helper process implementation.
116 void DoHelper(int fd); 116 void DoHelper(int fd);
117 117
118 void StartProcessInHelper(const StartProcessRequest* request, 118 void StartProcessInHelper(const StartProcessRequest* request,
119 std::vector<ScopedFD> fds); 119 std::vector<ScopedFD> fds);
120 void WaitForChildInHelper(const WaitProcessRequest* request); 120 void WaitForChildInHelper(const WaitProcessRequest* request);
121 121
122 bool is_child_ = false;
123
122 // Parent vars. 124 // Parent vars.
123 int child_fd_ = -1; 125 int child_fd_ = -1;
124 126
125 // Helper vars. 127 // Helper vars.
126 int parent_fd_ = -1; 128 int parent_fd_ = -1;
127 MainFunction main_ = nullptr; 129 MainFunction main_ = nullptr;
128 130
129 DISALLOW_COPY_AND_ASSIGN(LaunchHelper); 131 DISALLOW_COPY_AND_ASSIGN(LaunchHelper);
130 }; 132 };
131 133
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
197 } 199 }
198 return header->size; 200 return header->size;
199 } 201 }
200 202
201 void LaunchHelper::DoParent(int fd) { 203 void LaunchHelper::DoParent(int fd) {
202 child_fd_ = fd; 204 child_fd_ = fd;
203 } 205 }
204 206
205 void LaunchHelper::DoHelper(int fd) { 207 void LaunchHelper::DoHelper(int fd) {
206 parent_fd_ = fd; 208 parent_fd_ = fd;
209 is_child_ = true;
207 std::unique_ptr<char[]> buf(new char[kMaxMessageSize]); 210 std::unique_ptr<char[]> buf(new char[kMaxMessageSize]);
208 while (true) { 211 while (true) {
209 // Wait for a message from the parent. 212 // Wait for a message from the parent.
210 std::vector<ScopedFD> fds; 213 std::vector<ScopedFD> fds;
211 ssize_t size = Recv(parent_fd_, buf.get(), &fds); 214 ssize_t size = Recv(parent_fd_, buf.get(), &fds);
212 if (size == 0 || (size < 0 && errno == ECONNRESET)) { 215 if (size == 0 || (size < 0 && errno == ECONNRESET)) {
213 _exit(0); 216 _exit(0);
214 } 217 }
215 PCHECK(size > 0); 218 PCHECK(size > 0);
216 219
(...skipping 23 matching lines...) Expand all
240 PCHECK(pid >= 0) << "Fork failed"; 243 PCHECK(pid >= 0) << "Fork failed";
241 if (pid) { 244 if (pid) {
242 // Helper. 245 // Helper.
243 StartProcessResponse resp; 246 StartProcessResponse resp;
244 resp.child_pid = pid; 247 resp.child_pid = pid;
245 Send(parent_fd_, reinterpret_cast<const MessageHeader*>(&resp), 248 Send(parent_fd_, reinterpret_cast<const MessageHeader*>(&resp),
246 std::vector<int>()); 249 std::vector<int>());
247 } else { 250 } else {
248 // Child. 251 // Child.
249 PCHECK(close(parent_fd_) == 0); 252 PCHECK(close(parent_fd_) == 0);
253 parent_fd_ = -1;
250 CommandLine::Reset(); 254 CommandLine::Reset();
251 255
252 Pickle serialised_extra(reinterpret_cast<const char*>(request + 1), 256 Pickle serialised_extra(reinterpret_cast<const char*>(request + 1),
253 request->header.size - sizeof(StartProcessRequest)); 257 request->header.size - sizeof(StartProcessRequest));
254 PickleIterator iter(serialised_extra); 258 PickleIterator iter(serialised_extra);
255 std::vector<std::string> args; 259 std::vector<std::string> args;
256 for (size_t i = 0; i < request->num_args; i++) { 260 for (size_t i = 0; i < request->num_args; i++) {
257 std::string arg; 261 std::string arg;
258 CHECK(iter.ReadString(&arg)); 262 CHECK(iter.ReadString(&arg));
259 args.push_back(std::move(arg)); 263 args.push_back(std::move(arg));
260 } 264 }
261 265
262 CHECK_EQ(request->num_fds, fds.size()); 266 CHECK_EQ(request->num_fds, fds.size());
263 for (size_t i = 0; i < request->num_fds; i++) { 267 for (size_t i = 0; i < request->num_fds; i++) {
264 int new_fd; 268 int new_fd;
265 CHECK(iter.ReadInt(&new_fd)); 269 CHECK(iter.ReadInt(&new_fd));
266 int old_fd = fds[i].release(); 270 int old_fd = fds[i].release();
267 if (dup2(old_fd, new_fd) < 0) { 271 if (new_fd != old_fd) {
268 PLOG(FATAL) << "dup2"; 272 if (dup2(old_fd, new_fd) < 0) {
273 PLOG(FATAL) << "dup2";
274 }
275 PCHECK(close(old_fd) == 0);
269 } 276 }
270 PCHECK(close(old_fd) == 0);
271 } 277 }
272 278
273 std::unique_ptr<char*[]> argv(new char*[args.size()]); 279 std::unique_ptr<char*[]> argv(new char*[args.size()]);
274 for (size_t i = 0; i < args.size(); i++) { 280 for (size_t i = 0; i < args.size(); i++) {
275 argv[i] = const_cast<char*>(args[i].c_str()); 281 argv[i] = const_cast<char*>(args[i].c_str());
276 } 282 }
277 _exit(main_(args.size(), argv.get())); 283 _exit(main_(args.size(), argv.get()));
278 NOTREACHED(); 284 NOTREACHED();
279 } 285 }
280 } 286 }
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
363 } // namespace 369 } // namespace
364 370
365 void InitAndroidMultiProcessTestHelper(int (*main)(int, char**)) { 371 void InitAndroidMultiProcessTestHelper(int (*main)(int, char**)) {
366 DCHECK(main); 372 DCHECK(main);
367 // Don't allow child processes to themselves create new child processes. 373 // Don't allow child processes to themselves create new child processes.
368 if (g_launch_helper.Get().IsChild()) 374 if (g_launch_helper.Get().IsChild())
369 return; 375 return;
370 g_launch_helper.Get().Init(main); 376 g_launch_helper.Get().Init(main);
371 } 377 }
372 378
379 bool AndroidIsChildProcess() {
380 return g_launch_helper.Get().IsChild();
381 }
382
373 bool AndroidWaitForChildExitWithTimeout( 383 bool AndroidWaitForChildExitWithTimeout(
374 const Process& process, TimeDelta timeout, int* exit_code) { 384 const Process& process, TimeDelta timeout, int* exit_code) {
375 CHECK(g_launch_helper.Get().IsReady()); 385 CHECK(g_launch_helper.Get().IsReady());
376 return g_launch_helper.Get().WaitForChildExitWithTimeout( 386 return g_launch_helper.Get().WaitForChildExitWithTimeout(
377 process, timeout, exit_code); 387 process, timeout, exit_code);
378 } 388 }
379 389
380 // A very basic implementation for Android. On Android tests can run in an APK 390 // A very basic implementation for Android. On Android tests can run in an APK
381 // and we don't have an executable to exec*. This implementation does the bare 391 // and we don't have an executable to exec*. This implementation does the bare
382 // minimum to execute the method specified by procname (in the child process). 392 // minimum to execute the method specified by procname (in the child process).
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
433 CommandLine* command_line = CommandLine::ForCurrentProcess(); 443 CommandLine* command_line = CommandLine::ForCurrentProcess();
434 command_line->InitFromArgv(base_command_line.argv()); 444 command_line->InitFromArgv(base_command_line.argv());
435 if (!command_line->HasSwitch(switches::kTestChildProcess)) 445 if (!command_line->HasSwitch(switches::kTestChildProcess))
436 command_line->AppendSwitchASCII(switches::kTestChildProcess, procname); 446 command_line->AppendSwitchASCII(switches::kTestChildProcess, procname);
437 447
438 _exit(multi_process_function_list::InvokeChildProcessTest(procname)); 448 _exit(multi_process_function_list::InvokeChildProcessTest(procname));
439 return Process(); 449 return Process();
440 } 450 }
441 451
442 } // namespace base 452 } // namespace base
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698