1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150
|
// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef BASE_TEST_MULTIPROCESS_TEST_H_
#define BASE_TEST_MULTIPROCESS_TEST_H_
#include <string>
#include "base/process/launch.h"
#include "base/process/process.h"
#include "build/build_config.h"
#include "testing/platform_test.h"
namespace base {
class CommandLine;
// 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::Process test_child_process =
// base::SpawnMultiProcessTestChild("a_test_func", command_line,
// options);
//
// // Do stuff involving |test_child_process| and the child process....
//
// int rv = -1;
// ASSERT_TRUE(base::WaitForMultiprocessTestChildExit(test_child_process,
// TestTimeouts::action_timeout(), &rv));
// EXPECT_EQ(0, rv);
// }
//
// // Note: |MULTIPROCESS_TEST_MAIN()| is defined in
// // testing/multiprocess_func_list.h.
// MULTIPROCESS_TEST_MAIN(a_test_func) {
// // Code here runs in a child process....
// return 0;
// }
//
// If you need to terminate the child process, use the
// TerminateMultiProcessTestChild method to ensure that test will work on
// Android.
// 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|.
Process SpawnMultiProcessTestChild(const std::string& procname,
const CommandLine& command_line,
const LaunchOptions& options);
// Gets the base command line for |SpawnMultiProcessTestChild()|. To this, you
// may add any flags needed for your child process.
CommandLine GetMultiProcessTestChildBaseCommandLine();
// Waits for the child process to exit. Returns true if the process exited
// within |timeout| and sets |exit_code| if non null.
bool WaitForMultiprocessTestChildExit(const Process& process,
TimeDelta timeout,
int* exit_code);
// Terminates |process| with |exit_code|. If |wait| is true, this call blocks
// until the process actually terminates.
bool TerminateMultiProcessTestChild(const Process& process,
int exit_code,
bool wait);
#if BUILDFLAG(IS_ANDROID)
// Returns whether the child process exited cleanly from the main runloop.
bool MultiProcessTestChildHasCleanExit(const Process& process);
#endif
// MultiProcessTest ------------------------------------------------------------
// A MultiProcessTest is a test class which makes it easier to
// write a test which requires code running out of process.
//
// To create a multiprocess test simply follow these steps:
//
// 1) Derive your test from MultiProcessTest. Example:
//
// class MyTest : public MultiProcessTest {
// };
//
// TEST_F(MyTest, TestCaseName) {
// ...
// }
//
// 2) Create a mainline function for the child processes and include
// testing/multiprocess_func_list.h.
// See the declaration of the MULTIPROCESS_TEST_MAIN macro
// in that file for an example.
// 3) Call SpawnChild("foo"), where "foo" is the name of
// the function you wish to run in the child processes.
// That's it!
class MultiProcessTest : public PlatformTest {
public:
MultiProcessTest();
MultiProcessTest(const MultiProcessTest&) = delete;
MultiProcessTest& operator=(const MultiProcessTest&) = delete;
protected:
// Run a child process.
// 'procname' is the name of a function which the child will
// execute. It must be exported from this library in order to
// run.
//
// Example signature:
// extern "C" int __declspec(dllexport) FooBar() {
// // do client work here
// }
//
// Returns the child process.
Process SpawnChild(const std::string& procname);
// Run a child process using the given launch options.
//
// Note: On Windows, you probably want to set |options.start_hidden|.
Process SpawnChildWithOptions(const std::string& procname,
const LaunchOptions& options);
// 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);
};
} // namespace base
#endif // BASE_TEST_MULTIPROCESS_TEST_H_
|