Add multiprocess test helper functions.

Don't force people who want to write multiprocess tests to derive their
test fixture from MultiProcessTest.

TBR=phajdan.jr@chromium.org

Review URL: https://codereview.chromium.org/189373002

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@255796 0039d316-1c4b-4281-b951-d872f2087c98
parent 43ebe9ea
......@@ -9,6 +9,34 @@
namespace base {
#if !defined(OS_ANDROID)
ProcessHandle SpawnMultiProcessTestChild(
const std::string& procname,
const CommandLine& base_command_line,
const LaunchOptions& options,
bool debug_on_start) {
CommandLine command_line(base_command_line);
// TODO(viettrungluu): See comment above |MakeCmdLine()| in the header file.
// This is a temporary hack, since |MakeCmdLine()| has to provide a full
// command line.
if (!command_line.HasSwitch(switches::kTestChildProcess)) {
command_line.AppendSwitchASCII(switches::kTestChildProcess, procname);
if (debug_on_start)
command_line.AppendSwitch(switches::kDebugOnStart);
}
ProcessHandle handle = kNullProcessHandle;
LaunchProcess(command_line, options, &handle);
return handle;
}
#endif // !defined(OS_ANDROID)
CommandLine GetMultiProcessTestChildBaseCommandLine() {
return *CommandLine::ForCurrentProcess();
}
// MultiProcessTest ------------------------------------------------------------
MultiProcessTest::MultiProcessTest() {
}
......@@ -21,24 +49,23 @@ ProcessHandle MultiProcessTest::SpawnChild(const std::string& procname,
return SpawnChildWithOptions(procname, options, debug_on_start);
}
#if !defined(OS_ANDROID)
ProcessHandle MultiProcessTest::SpawnChildWithOptions(
const std::string& procname,
const LaunchOptions& options,
bool debug_on_start) {
ProcessHandle handle = kNullProcessHandle;
LaunchProcess(MakeCmdLine(procname, debug_on_start), options, &handle);
return handle;
return SpawnMultiProcessTestChild(procname,
MakeCmdLine(procname, debug_on_start),
options,
debug_on_start);
}
#endif
CommandLine MultiProcessTest::MakeCmdLine(const std::string& procname,
bool debug_on_start) {
CommandLine cl(*CommandLine::ForCurrentProcess());
cl.AppendSwitchASCII(switches::kTestChildProcess, procname);
CommandLine command_line = GetMultiProcessTestChildBaseCommandLine();
command_line.AppendSwitchASCII(switches::kTestChildProcess, procname);
if (debug_on_start)
cl.AppendSwitch(switches::kDebugOnStart);
return cl;
command_line.AppendSwitch(switches::kDebugOnStart);
return command_line;
}
} // namespace base
......@@ -17,6 +17,59 @@ class CommandLine;
namespace base {
// Helpers to spawn a child for a multiprocess test and execute a designated
// function. Use these when you already have another base class for your test
// fixture, but you want (some) of your tests to be multiprocess (otherwise you
// may just want to derive your fixture from |MultiProcessTest|, below).
//
// Use these helpers as follows:
//
// TEST_F(MyTest, ATest) {
// CommandLine command_line(
// base::GetMultiProcessTestChildBaseCommandLine());
// // Maybe add our own switches to |command_line|....
//
// LaunchOptions options;
// // Maybe set some options (e.g., |start_hidden| on Windows)....
//
// // Start a child process and run |a_test_func|.
// base::ProcessHandle test_child_handle =
// base::SpawnMultiProcessTestChild("a_test_func", command_line,
// options, false);
//
// // Do stuff involving |test_child_handle| and the child process....
//
// int rv = -1;
// ASSERT_TRUE(base::WaitForExitCodeWithTimeout(
// test_child_handle, &rv, TestTimeouts::action_timeout()));
// base::CloseProcessHandle(test_child_handle);
// EXPECT_EQ(0, rv);
// }
//
// // Note: |MULTIPROCESS_TEST_MAIN()| is defined in
// // testing/multi_process_function_list.h.
// MULTIPROCESS_TEST_MAIN(a_test_func) {
// // Code here runs in a child process....
// return 0;
// }
// Spawns a child process and executes the function |procname| declared using
// |MULTIPROCESS_TEST_MAIN()| or |MULTIPROCESS_TEST_MAIN_WITH_SETUP()|.
// |command_line| should be as provided by
// |GetMultiProcessTestChildBaseCommandLine()| (below), possibly with arguments
// added. Note: On Windows, you probably want to set |options.start_hidden|.
ProcessHandle SpawnMultiProcessTestChild(
const std::string& procname,
const CommandLine& command_line,
const LaunchOptions& options,
bool debug_on_start);
// Gets the base command line for |SpawnMultiProcessTestChild()|. To this, you
// may add any flags needed for your child process.
CommandLine GetMultiProcessTestChildBaseCommandLine();
// MultiProcessTest ------------------------------------------------------------
// A MultiProcessTest is a test class which makes it easier to
// write a test which requires code running out of process.
//
......@@ -64,6 +117,12 @@ class MultiProcessTest : public PlatformTest {
bool debug_on_start);
// Set up the command line used to spawn the child process.
// Override this to add things to the command line (calling this first in the
// override).
// Note that currently some tests rely on this providing a full command line,
// which they then use directly with |LaunchProcess()|.
// TODO(viettrungluu): Remove this and add a virtual
// |ModifyChildCommandLine()|; make the two divergent uses more sane.
virtual CommandLine MakeCmdLine(const std::string& procname,
bool debug_on_start);
......
......@@ -15,14 +15,15 @@ namespace base {
// A very basic implementation for Android. On Android tests can run in an APK
// and we don't have an executable to exec*. This implementation does the bare
// minimum to execute the method specified by procname (in the child process).
// - |base_command_line| is ignored.
// - All options except |fds_to_remap| are ignored.
// - |debug_on_start| is ignored.
ProcessHandle MultiProcessTest::SpawnChildWithOptions(
const std::string& procname,
const LaunchOptions& options,
bool debug_on_start) {
// TODO(vtl): The FD-remapping done below is wrong in the presence of cycles
// (e.g., fd1 -> fd2, fd2 -> fd1). crbug.com/326576
ProcessHandle SpawnMultiProcessTestChild(const std::string& procname,
const CommandLine& base_command_line,
const LaunchOptions& options,
bool debug_on_start) {
// TODO(viettrungluu): The FD-remapping done below is wrong in the presence of
// cycles (e.g., fd1 -> fd2, fd2 -> fd1). crbug.com/326576
FileHandleMappingVector empty;
const FileHandleMappingVector* fds_to_remap =
options.fds_to_remap ? options.fds_to_remap : ∅
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment