blob: 4769a00e0fddc41718a9ff1a9f594eabc53399c6 [file] [log] [blame]
thestig@chromium.org33d56572012-02-24 13:40:20 +09001// Copyright (c) 2012 The Chromium Authors. All rights reserved.
brettw@chromium.org1c8c3be2010-08-18 04:40:11 +09002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef BASE_TEST_MULTIPROCESS_TEST_H_
6#define BASE_TEST_MULTIPROCESS_TEST_H_
brettw@chromium.org1c8c3be2010-08-18 04:40:11 +09007
8#include <string>
9
10#include "base/basictypes.h"
rsesek@chromium.org687756f2013-07-26 06:38:23 +090011#include "base/process/launch.h"
12#include "base/process/process_handle.h"
brettw@chromium.org1c8c3be2010-08-18 04:40:11 +090013#include "build/build_config.h"
14#include "testing/platform_test.h"
15
16class CommandLine;
17
18namespace base {
19
viettrungluu@chromium.orgc2322b02014-03-09 06:01:26 +090020// Helpers to spawn a child for a multiprocess test and execute a designated
21// function. Use these when you already have another base class for your test
22// fixture, but you want (some) of your tests to be multiprocess (otherwise you
23// may just want to derive your fixture from |MultiProcessTest|, below).
24//
25// Use these helpers as follows:
26//
27// TEST_F(MyTest, ATest) {
28// CommandLine command_line(
29// base::GetMultiProcessTestChildBaseCommandLine());
30// // Maybe add our own switches to |command_line|....
31//
32// LaunchOptions options;
33// // Maybe set some options (e.g., |start_hidden| on Windows)....
34//
35// // Start a child process and run |a_test_func|.
36// base::ProcessHandle test_child_handle =
37// base::SpawnMultiProcessTestChild("a_test_func", command_line,
38// options, false);
39//
40// // Do stuff involving |test_child_handle| and the child process....
41//
42// int rv = -1;
43// ASSERT_TRUE(base::WaitForExitCodeWithTimeout(
44// test_child_handle, &rv, TestTimeouts::action_timeout()));
45// base::CloseProcessHandle(test_child_handle);
46// EXPECT_EQ(0, rv);
47// }
48//
49// // Note: |MULTIPROCESS_TEST_MAIN()| is defined in
50// // testing/multi_process_function_list.h.
51// MULTIPROCESS_TEST_MAIN(a_test_func) {
52// // Code here runs in a child process....
53// return 0;
54// }
55
56// Spawns a child process and executes the function |procname| declared using
57// |MULTIPROCESS_TEST_MAIN()| or |MULTIPROCESS_TEST_MAIN_WITH_SETUP()|.
58// |command_line| should be as provided by
59// |GetMultiProcessTestChildBaseCommandLine()| (below), possibly with arguments
60// added. Note: On Windows, you probably want to set |options.start_hidden|.
61ProcessHandle SpawnMultiProcessTestChild(
62 const std::string& procname,
63 const CommandLine& command_line,
64 const LaunchOptions& options,
65 bool debug_on_start);
66
67// Gets the base command line for |SpawnMultiProcessTestChild()|. To this, you
68// may add any flags needed for your child process.
69CommandLine GetMultiProcessTestChildBaseCommandLine();
70
71// MultiProcessTest ------------------------------------------------------------
72
brettw@chromium.org1c8c3be2010-08-18 04:40:11 +090073// A MultiProcessTest is a test class which makes it easier to
74// write a test which requires code running out of process.
75//
76// To create a multiprocess test simply follow these steps:
77//
78// 1) Derive your test from MultiProcessTest. Example:
79//
80// class MyTest : public MultiProcessTest {
81// };
82//
83// TEST_F(MyTest, TestCaseName) {
84// ...
85// }
86//
87// 2) Create a mainline function for the child processes and include
88// testing/multiprocess_func_list.h.
89// See the declaration of the MULTIPROCESS_TEST_MAIN macro
90// in that file for an example.
91// 3) Call SpawnChild("foo"), where "foo" is the name of
92// the function you wish to run in the child processes.
93// That's it!
94class MultiProcessTest : public PlatformTest {
95 public:
96 MultiProcessTest();
97
98 protected:
99 // Run a child process.
100 // 'procname' is the name of a function which the child will
101 // execute. It must be exported from this library in order to
102 // run.
103 //
104 // Example signature:
105 // extern "C" int __declspec(dllexport) FooBar() {
106 // // do client work here
107 // }
108 //
109 // Returns the handle to the child, or NULL on failure
110 ProcessHandle SpawnChild(const std::string& procname, bool debug_on_start);
111
viettrungluu@chromium.orgb1b55ff2013-12-07 06:23:35 +0900112 // Run a child process using the given launch options.
113 //
114 // Note: On Windows, you probably want to set |options.start_hidden|.
115 ProcessHandle SpawnChildWithOptions(const std::string& procname,
116 const LaunchOptions& options,
117 bool debug_on_start);
118
evan@chromium.org87b15df2010-10-16 04:51:20 +0900119 // Set up the command line used to spawn the child process.
viettrungluu@chromium.orgc2322b02014-03-09 06:01:26 +0900120 // Override this to add things to the command line (calling this first in the
121 // override).
122 // Note that currently some tests rely on this providing a full command line,
123 // which they then use directly with |LaunchProcess()|.
124 // TODO(viettrungluu): Remove this and add a virtual
125 // |ModifyChildCommandLine()|; make the two divergent uses more sane.
evan@chromium.org87b15df2010-10-16 04:51:20 +0900126 virtual CommandLine MakeCmdLine(const std::string& procname,
127 bool debug_on_start);
brettw@chromium.org1c8c3be2010-08-18 04:40:11 +0900128
129 private:
evan@chromium.org87b15df2010-10-16 04:51:20 +0900130 DISALLOW_COPY_AND_ASSIGN(MultiProcessTest);
brettw@chromium.org1c8c3be2010-08-18 04:40:11 +0900131};
132
133} // namespace base
134
135#endif // BASE_TEST_MULTIPROCESS_TEST_H_