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 #ifndef MOJO_CORE_TEST_MULTIPROCESS_TEST_HELPER_H_
6 #define MOJO_CORE_TEST_MULTIPROCESS_TEST_HELPER_H_
7 
8 #include <string>
9 
10 #include "base/callback.h"
11 #include "base/macros.h"
12 #include "base/process/process.h"
13 #include "base/test/multiprocess_test.h"
14 #include "base/test/test_timeouts.h"
15 #include "mojo/public/cpp/system/message_pipe.h"
16 #include "testing/multiprocess_func_list.h"
17 
18 namespace mojo {
19 
20 class IsolatedConnection;
21 
22 namespace core {
23 namespace test {
24 
25 class MultiprocessTestHelper {
26  public:
27   using HandlerCallback = base::Callback<void(ScopedMessagePipeHandle)>;
28 
29   enum class LaunchType {
30     // Launch the child process as a child in the mojo system.
31     CHILD,
32 
33     // Launch the child process as an unrelated peer process in the mojo system.
34     PEER,
35 
36     // Launch the child process as a child in the mojo system, using a named
37     // pipe.
38     NAMED_CHILD,
39 
40     // Launch the child process as an unrelated peer process in the mojo
41     // system, using a named pipe.
42     NAMED_PEER,
43   };
44 
45   MultiprocessTestHelper();
46   ~MultiprocessTestHelper();
47 
48   // Start a child process and run the "main" function "named" |test_child_name|
49   // declared using |MOJO_MULTIPROCESS_TEST_CHILD_MAIN()| or
50   // |MOJO_MULTIPROCESS_TEST_CHILD_TEST()| (below).
51   ScopedMessagePipeHandle StartChild(
52       const std::string& test_child_name,
53       LaunchType launch_type = LaunchType::CHILD);
54 
55   // Like |StartChild()|, but appends an extra switch (with ASCII value) to the
56   // command line. (The switch must not already be present in the default
57   // command line.)
58   ScopedMessagePipeHandle StartChildWithExtraSwitch(
59       const std::string& test_child_name,
60       const std::string& switch_string,
61       const std::string& switch_value,
62       LaunchType launch_type);
63 
64   // Wait for the child process to terminate.
65   // Returns the exit code of the child process. Note that, though it's declared
66   // to be an |int|, the exit code is subject to mangling by the OS. E.g., we
67   // usually return -1 on error in the child (e.g., if |test_child_name| was not
68   // found), but this is mangled to 255 on Linux. You should only rely on codes
69   // 0-127 being preserved, and -1 being outside the range 0-127.
70   int WaitForChildShutdown();
71 
72   // Like |WaitForChildShutdown()|, but returns true on success (exit code of 0)
73   // and false otherwise. You probably want to do something like
74   // |EXPECT_TRUE(WaitForChildTestShutdown());|.
75   bool WaitForChildTestShutdown();
76 
test_child()77   const base::Process& test_child() const { return test_child_; }
78 
79   // Used by macros in mojo/core/test/mojo_test_base.h to support multiprocess
80   // test client initialization.
81   static void ChildSetup();
82   static int RunClientMain(const base::Callback<int(MojoHandle)>& main,
83                            bool pass_pipe_ownership_to_main = false);
84   static int RunClientTestMain(const base::Callback<void(MojoHandle)>& main);
85 
86   // For use (and only valid) in the child process:
87   static mojo::ScopedMessagePipeHandle primordial_pipe;
88 
89  private:
90   // Valid after |StartChild()| and before |WaitForChildShutdown()|.
91   base::Process test_child_;
92 
93   std::unique_ptr<IsolatedConnection> isolated_connection_;
94 
95   DISALLOW_COPY_AND_ASSIGN(MultiprocessTestHelper);
96 };
97 
98 }  // namespace test
99 }  // namespace core
100 }  // namespace mojo
101 
102 #endif  // MOJO_CORE_TEST_MULTIPROCESS_TEST_HELPER_H_
103