multiprocess_test.h 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  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. #ifndef BASE_TEST_MULTIPROCESS_TEST_H_
  5. #define BASE_TEST_MULTIPROCESS_TEST_H_
  6. #include <string>
  7. #include <gtest/gtest.h>
  8. #include "butil/basictypes.h"
  9. #include "butil/process/launch.h"
  10. #include "butil/process/process_handle.h"
  11. #include "butil/build_config.h"
  12. namespace butil {
  13. class CommandLine;
  14. // Helpers to spawn a child for a multiprocess test and execute a designated
  15. // function. Use these when you already have another base class for your test
  16. // fixture, but you want (some) of your tests to be multiprocess (otherwise you
  17. // may just want to derive your fixture from |MultiProcessTest|, below).
  18. //
  19. // Use these helpers as follows:
  20. //
  21. // TEST_F(MyTest, ATest) {
  22. // CommandLine command_line(
  23. // butil::GetMultiProcessTestChildBaseCommandLine());
  24. // // Maybe add our own switches to |command_line|....
  25. //
  26. // LaunchOptions options;
  27. // // Maybe set some options (e.g., |start_hidden| on Windows)....
  28. //
  29. // // Start a child process and run |a_test_func|.
  30. // butil::ProcessHandle test_child_handle =
  31. // butil::SpawnMultiProcessTestChild("a_test_func", command_line,
  32. // options);
  33. //
  34. // // Do stuff involving |test_child_handle| and the child process....
  35. //
  36. // int rv = -1;
  37. // ASSERT_TRUE(butil::WaitForExitCodeWithTimeout(
  38. // test_child_handle, &rv, TestTimeouts::action_timeout()));
  39. // butil::CloseProcessHandle(test_child_handle);
  40. // EXPECT_EQ(0, rv);
  41. // }
  42. //
  43. // // Note: |MULTIPROCESS_TEST_MAIN()| is defined in
  44. // // test/multi_process_function_list.h.
  45. // MULTIPROCESS_TEST_MAIN(a_test_func) {
  46. // // Code here runs in a child process....
  47. // return 0;
  48. // }
  49. // Spawns a child process and executes the function |procname| declared using
  50. // |MULTIPROCESS_TEST_MAIN()| or |MULTIPROCESS_TEST_MAIN_WITH_SETUP()|.
  51. // |command_line| should be as provided by
  52. // |GetMultiProcessTestChildBaseCommandLine()| (below), possibly with arguments
  53. // added. Note: On Windows, you probably want to set |options.start_hidden|.
  54. ProcessHandle SpawnMultiProcessTestChild(
  55. const std::string& procname,
  56. const CommandLine& command_line,
  57. const LaunchOptions& options);
  58. // Gets the base command line for |SpawnMultiProcessTestChild()|. To this, you
  59. // may add any flags needed for your child process.
  60. CommandLine GetMultiProcessTestChildBaseCommandLine();
  61. // MultiProcessTest ------------------------------------------------------------
  62. // A MultiProcessTest is a test class which makes it easier to
  63. // write a test which requires code running out of process.
  64. //
  65. // To create a multiprocess test simply follow these steps:
  66. //
  67. // 1) Derive your test from MultiProcessTest. Example:
  68. //
  69. // class MyTest : public MultiProcessTest {
  70. // };
  71. //
  72. // TEST_F(MyTest, TestCaseName) {
  73. // ...
  74. // }
  75. //
  76. // 2) Create a mainline function for the child processes and include
  77. // test/multiprocess_func_list.h.
  78. // See the declaration of the MULTIPROCESS_TEST_MAIN macro
  79. // in that file for an example.
  80. // 3) Call SpawnChild("foo"), where "foo" is the name of
  81. // the function you wish to run in the child processes.
  82. // That's it!
  83. class MultiProcessTest : public testing::Test {
  84. public:
  85. MultiProcessTest();
  86. protected:
  87. // Run a child process.
  88. // 'procname' is the name of a function which the child will
  89. // execute. It must be exported from this library in order to
  90. // run.
  91. //
  92. // Example signature:
  93. // extern "C" int __declspec(dllexport) FooBar() {
  94. // // do client work here
  95. // }
  96. //
  97. // Returns the handle to the child, or NULL on failure
  98. ProcessHandle SpawnChild(const std::string& procname);
  99. // Run a child process using the given launch options.
  100. //
  101. // Note: On Windows, you probably want to set |options.start_hidden|.
  102. ProcessHandle SpawnChildWithOptions(const std::string& procname,
  103. const LaunchOptions& options);
  104. // Set up the command line used to spawn the child process.
  105. // Override this to add things to the command line (calling this first in the
  106. // override).
  107. // Note that currently some tests rely on this providing a full command line,
  108. // which they then use directly with |LaunchProcess()|.
  109. // TODO(viettrungluu): Remove this and add a virtual
  110. // |ModifyChildCommandLine()|; make the two divergent uses more sane.
  111. virtual CommandLine MakeCmdLine(const std::string& procname);
  112. private:
  113. DISALLOW_COPY_AND_ASSIGN(MultiProcessTest);
  114. };
  115. } // namespace butil
  116. #endif // BASE_TEST_MULTIPROCESS_TEST_H_