Home | History | Annotate | Download | only in test
      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
      3 // found in the LICENSE file.
      4 
      5 #ifndef BASE_TEST_MULTIPROCESS_TEST_H_
      6 #define BASE_TEST_MULTIPROCESS_TEST_H_
      7 
      8 #include <string>
      9 
     10 #include "base/macros.h"
     11 #include "base/process/launch.h"
     12 #include "base/process/process.h"
     13 #include "build/build_config.h"
     14 #include "testing/platform_test.h"
     15 
     16 namespace base {
     17 
     18 class CommandLine;
     19 
     20 // 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::Process test_child_process =
     37 //         base::SpawnMultiProcessTestChild("a_test_func", command_line,
     38 //                                          options);
     39 //
     40 //     // Do stuff involving |test_child_process| and the child process....
     41 //
     42 //     int rv = -1;
     43 //     ASSERT_TRUE(test_child_process.WaitForExitWithTimeout(
     44 //         TestTimeouts::action_timeout(), &rv));
     45 //     EXPECT_EQ(0, rv);
     46 //   }
     47 //
     48 //   // Note: |MULTIPROCESS_TEST_MAIN()| is defined in
     49 //   // testing/multi_process_function_list.h.
     50 //   MULTIPROCESS_TEST_MAIN(a_test_func) {
     51 //     // Code here runs in a child process....
     52 //     return 0;
     53 //   }
     54 
     55 // Spawns a child process and executes the function |procname| declared using
     56 // |MULTIPROCESS_TEST_MAIN()| or |MULTIPROCESS_TEST_MAIN_WITH_SETUP()|.
     57 // |command_line| should be as provided by
     58 // |GetMultiProcessTestChildBaseCommandLine()| (below), possibly with arguments
     59 // added. Note: On Windows, you probably want to set |options.start_hidden|.
     60 Process SpawnMultiProcessTestChild(
     61     const std::string& procname,
     62     const CommandLine& command_line,
     63     const LaunchOptions& options);
     64 
     65 // Gets the base command line for |SpawnMultiProcessTestChild()|. To this, you
     66 // may add any flags needed for your child process.
     67 CommandLine GetMultiProcessTestChildBaseCommandLine();
     68 
     69 #if defined(OS_ANDROID)
     70 
     71 // Enable the alternate test child implementation which support spawning a child
     72 // after threads have been created. If used, this MUST be the first line of
     73 // main(). The main function is passed in to avoid a link-time dependency in
     74 // component builds.
     75 void InitAndroidMultiProcessTestHelper(int (*main)(int, char**));
     76 
     77 // Returns true if the current process is a test child.
     78 bool AndroidIsChildProcess();
     79 
     80 // Wait for a test child to exit if the alternate test child implementation is
     81 // being used.
     82 bool AndroidWaitForChildExitWithTimeout(
     83     const Process& process, TimeDelta timeout, int* exit_code)
     84     WARN_UNUSED_RESULT;
     85 
     86 #endif  // defined(OS_ANDROID)
     87 
     88 // MultiProcessTest ------------------------------------------------------------
     89 
     90 // A MultiProcessTest is a test class which makes it easier to
     91 // write a test which requires code running out of process.
     92 //
     93 // To create a multiprocess test simply follow these steps:
     94 //
     95 // 1) Derive your test from MultiProcessTest. Example:
     96 //
     97 //    class MyTest : public MultiProcessTest {
     98 //    };
     99 //
    100 //    TEST_F(MyTest, TestCaseName) {
    101 //      ...
    102 //    }
    103 //
    104 // 2) Create a mainline function for the child processes and include
    105 //    testing/multiprocess_func_list.h.
    106 //    See the declaration of the MULTIPROCESS_TEST_MAIN macro
    107 //    in that file for an example.
    108 // 3) Call SpawnChild("foo"), where "foo" is the name of
    109 //    the function you wish to run in the child processes.
    110 // That's it!
    111 class MultiProcessTest : public PlatformTest {
    112  public:
    113   MultiProcessTest();
    114 
    115  protected:
    116   // Run a child process.
    117   // 'procname' is the name of a function which the child will
    118   // execute.  It must be exported from this library in order to
    119   // run.
    120   //
    121   // Example signature:
    122   //    extern "C" int __declspec(dllexport) FooBar() {
    123   //         // do client work here
    124   //    }
    125   //
    126   // Returns the child process.
    127   Process SpawnChild(const std::string& procname);
    128 
    129   // Run a child process using the given launch options.
    130   //
    131   // Note: On Windows, you probably want to set |options.start_hidden|.
    132   Process SpawnChildWithOptions(const std::string& procname,
    133                                 const LaunchOptions& options);
    134 
    135   // Set up the command line used to spawn the child process.
    136   // Override this to add things to the command line (calling this first in the
    137   // override).
    138   // Note that currently some tests rely on this providing a full command line,
    139   // which they then use directly with |LaunchProcess()|.
    140   // TODO(viettrungluu): Remove this and add a virtual
    141   // |ModifyChildCommandLine()|; make the two divergent uses more sane.
    142   virtual CommandLine MakeCmdLine(const std::string& procname);
    143 
    144  private:
    145   DISALLOW_COPY_AND_ASSIGN(MultiProcessTest);
    146 };
    147 
    148 }  // namespace base
    149 
    150 #endif  // BASE_TEST_MULTIPROCESS_TEST_H_
    151