unit_test_launcher.cc revision 0f1bc08d4cfcc34181b0b5cbf065c40f687bf740
13551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
23551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
33551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// found in the LICENSE file.
43551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
54e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/test/launcher/unit_test_launcher.h"
63551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
7424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "base/bind.h"
8424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "base/callback_helpers.h"
93551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "base/command_line.h"
103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "base/compiler_specific.h"
113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "base/file_util.h"
124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/files/scoped_temp_dir.h"
133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "base/format_macros.h"
1458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "base/message_loop/message_loop.h"
153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "base/stl_util.h"
1658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "base/strings/string_number_conversions.h"
173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "base/strings/string_util.h"
1858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "base/sys_info.h"
193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "base/test/gtest_xml_util.h"
204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/test/launcher/test_launcher.h"
21424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "base/test/test_switches.h"
223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "base/test/test_timeouts.h"
2358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "base/threading/thread_checker.h"
243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)namespace base {
273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)namespace {
293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
3058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// This constant controls how many tests are run in a single batch by default.
3158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)const size_t kDefaultTestBatchLimit = 10;
323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
33d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)const char kHelpFlag[] = "help";
34d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Flag to enable the new launcher logic.
363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// TODO(phajdan.jr): Remove it, http://crbug.com/236893 .
373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)const char kBraveNewTestLauncherFlag[] = "brave-new-test-launcher";
383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Flag to run all tests in a single process.
403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)const char kSingleProcessTestsFlag[] = "single-process-tests";
413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
42d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)void PrintUsage() {
43d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  fprintf(stdout,
44d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)          "Runs tests using the gtest framework, each batch of tests being\n"
45d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)          "run in their own process. Supported command-line flags:\n"
46d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)          "\n"
47d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)          "  --single-process-tests\n"
48d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)          "    Runs the tests and the launcher in the same process. Useful\n"
49d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)          "    for debugging a specific test in a debugger.\n"
50d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)          "  --test-launcher-jobs=N\n"
51d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)          "    Sets the number of parallel test jobs to N.\n"
52d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)          "  --test-launcher-batch-limit=N\n"
53d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)          "    Sets the limit of test batch to run in a single process to N.\n"
54d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)          "  --gtest_filter=...\n"
55d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)          "    Runs a subset of tests (see --gtest_help for more info).\n"
56d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)          "  --help\n"
57d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)          "    Shows this message.\n"
58d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)          "  --gtest_help\n"
59d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)          "    Shows the gtest help message.\n");
60d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  fflush(stdout);
61d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}
62d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Returns command line for child GTest process based on the command line
643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// of current process. |test_names| is a vector of test full names
653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// (e.g. "A.B"), |output_file| is path to the GTest XML output file.
663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)CommandLine GetCommandLineForChildGTestProcess(
673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    const std::vector<std::string>& test_names,
683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    const base::FilePath& output_file) {
69424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  CommandLine new_cmd_line(*CommandLine::ForCurrentProcess());
703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
71424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  new_cmd_line.AppendSwitchPath(switches::kTestLauncherOutput, output_file);
72424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  new_cmd_line.AppendSwitchASCII(kGTestFilterFlag, JoinString(test_names, ":"));
733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  new_cmd_line.AppendSwitch(kSingleProcessTestsFlag);
743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  new_cmd_line.AppendSwitch(kBraveNewTestLauncherFlag);
753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  return new_cmd_line;
773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)class UnitTestLauncherDelegate : public TestLauncherDelegate {
8058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) public:
810f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  explicit UnitTestLauncherDelegate(size_t batch_limit)
820f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      : batch_limit_(batch_limit) {
8358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
8458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
8558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  virtual ~UnitTestLauncherDelegate() {
8658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    DCHECK(thread_checker_.CalledOnValidThread());
8758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
8858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) private:
901e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  struct GTestCallbackState {
911e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    TestLauncher* test_launcher;
921e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    std::vector<std::string> test_names;
931e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    FilePath output_file;
943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  };
953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  virtual void OnTestIterationStarting() OVERRIDE {
974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // Nothing to do.
984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
10068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  virtual std::string GetTestNameForFiltering(
10168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      const testing::TestCase* test_case,
10268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      const testing::TestInfo* test_info) OVERRIDE {
10368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    DCHECK(thread_checker_.CalledOnValidThread());
10468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
10568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    return std::string(test_case->name()) + "." + test_info->name();
10668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  }
10768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
1083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual bool ShouldRunTest(const testing::TestCase* test_case,
1093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                             const testing::TestInfo* test_info) OVERRIDE {
11058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    DCHECK(thread_checker_.CalledOnValidThread());
11158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
1123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    // There is no additional logic to disable specific tests.
1133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return true;
1143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
1153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
1161e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  virtual size_t RunTests(TestLauncher* test_launcher,
1171e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                          const std::vector<std::string>& test_names) OVERRIDE {
11858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    DCHECK(thread_checker_.CalledOnValidThread());
11958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
1201e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    std::vector<std::string> batch;
1211e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    for (size_t i = 0; i < test_names.size(); i++) {
1221e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      batch.push_back(test_names[i]);
1231e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1241e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      if (batch.size() >= batch_limit_) {
1251e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        RunBatch(test_launcher, batch);
1261e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        batch.clear();
1271e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      }
1281e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    }
1291e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1301e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    RunBatch(test_launcher, batch);
1313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
1321e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    return test_names.size();
1333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
1343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
1351e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  virtual size_t RetryTests(
1361e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      TestLauncher* test_launcher,
1371e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      const std::vector<std::string>& test_names) OVERRIDE {
1381e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    MessageLoop::current()->PostTask(
1391e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        FROM_HERE,
1401e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        Bind(&UnitTestLauncherDelegate::RunSerially,
1411e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)             Unretained(this),
1421e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)             test_launcher,
1431e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)             test_names));
1441e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    return test_names.size();
1451e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
146424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
1471e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  void RunSerially(TestLauncher* test_launcher,
1481e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                   const std::vector<std::string>& test_names) {
1491e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    if (test_names.empty())
1503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      return;
1513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
1521e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    std::vector<std::string> new_test_names(test_names);
1531e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    std::string test_name(new_test_names.back());
1541e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    new_test_names.pop_back();
1551e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    // Create a dedicated temporary directory to store the xml result data
1573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    // per run to ensure clean state and make it possible to launch multiple
1583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    // processes in parallel.
1593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    base::FilePath output_file;
16058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    CHECK(file_util::CreateNewTempDirectory(FilePath::StringType(),
16158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                            &output_file));
16258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    output_file = output_file.AppendASCII("test_results.xml");
1633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
1641e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    std::vector<std::string> current_test_names;
1651e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    current_test_names.push_back(test_name);
1661e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    CommandLine cmd_line(
1671e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        GetCommandLineForChildGTestProcess(current_test_names, output_file));
1681e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1691e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    GTestCallbackState callback_state;
1701e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    callback_state.test_launcher = test_launcher;
1711e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    callback_state.test_names = current_test_names;
1721e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    callback_state.output_file = output_file;
1731e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1740f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    test_launcher->LaunchChildGTestProcess(
1751e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        cmd_line,
1761e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        std::string(),
1771e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        TestTimeouts::test_launcher_timeout(),
1781e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        Bind(&UnitTestLauncherDelegate::SerialGTestCallback,
1791e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)             Unretained(this),
1801e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)             callback_state,
1811e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)             new_test_names));
1821e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
1831e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1841e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  void RunBatch(TestLauncher* test_launcher,
1851e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                const std::vector<std::string>& test_names) {
1861e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    DCHECK(thread_checker_.CalledOnValidThread());
1871e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1881e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    if (test_names.empty())
1891e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      return;
1901e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1911e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    // Create a dedicated temporary directory to store the xml result data
1921e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    // per run to ensure clean state and make it possible to launch multiple
1931e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    // processes in parallel.
1941e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    base::FilePath output_file;
1951e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    CHECK(file_util::CreateNewTempDirectory(FilePath::StringType(),
1961e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                                            &output_file));
1971e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    output_file = output_file.AppendASCII("test_results.xml");
1983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
1993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    CommandLine cmd_line(
2003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        GetCommandLineForChildGTestProcess(test_names, output_file));
2013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
2023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    // Adjust the timeout depending on how many tests we're running
2033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    // (note that e.g. the last batch of tests will be smaller).
2043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    // TODO(phajdan.jr): Consider an adaptive timeout, which can change
2053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    // depending on how many tests ran and how many remain.
2063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    // Note: do NOT parse child's stdout to do that, it's known to be
2073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    // unreliable (e.g. buffering issues can mix up the output).
2083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    base::TimeDelta timeout =
20968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        test_names.size() * TestTimeouts::test_launcher_timeout();
2103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
2111e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    GTestCallbackState callback_state;
2121e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    callback_state.test_launcher = test_launcher;
2131e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    callback_state.test_names = test_names;
2141e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    callback_state.output_file = output_file;
2151e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
2160f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    test_launcher->LaunchChildGTestProcess(
21758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        cmd_line,
21858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        std::string(),
21958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        timeout,
22058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        Bind(&UnitTestLauncherDelegate::GTestCallback,
2211e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)             Unretained(this),
2221e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)             callback_state));
22358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
22458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
2251e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  void GTestCallback(const GTestCallbackState& callback_state,
22658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                     int exit_code,
22768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                     const TimeDelta& elapsed_time,
22858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                     bool was_timeout,
22958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                     const std::string& output) {
23058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    DCHECK(thread_checker_.CalledOnValidThread());
2311e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    std::vector<std::string> tests_to_relaunch_after_interruption;
2320f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    ProcessTestResults(callback_state.test_launcher,
2330f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                       callback_state.test_names,
2340f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                       callback_state.output_file,
2350f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                       output,
2360f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                       exit_code,
2370f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                       was_timeout,
2380f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                       &tests_to_relaunch_after_interruption);
23958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
2401e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    RunBatch(callback_state.test_launcher,
2411e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)             tests_to_relaunch_after_interruption);
24258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
24358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // The temporary file's directory is also temporary.
2441e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    DeleteFile(callback_state.output_file.DirName(), true);
2451e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
2461e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
2471e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  void SerialGTestCallback(const GTestCallbackState& callback_state,
2481e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                           const std::vector<std::string>& test_names,
2491e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                           int exit_code,
2501e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                           const TimeDelta& elapsed_time,
2511e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                           bool was_timeout,
2521e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                           const std::string& output) {
2531e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    DCHECK(thread_checker_.CalledOnValidThread());
2541e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    std::vector<std::string> tests_to_relaunch_after_interruption;
2551e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    bool called_any_callbacks =
2561e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        ProcessTestResults(callback_state.test_launcher,
2571e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                           callback_state.test_names,
2581e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                           callback_state.output_file,
2591e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                           output,
2601e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                           exit_code,
2611e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                           was_timeout,
2621e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                           &tests_to_relaunch_after_interruption);
2631e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
2641e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    // There is only one test, there cannot be other tests to relaunch
2651e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    // due to a crash.
2661e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    DCHECK(tests_to_relaunch_after_interruption.empty());
2671e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
2680f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    // There is only one test, we should have called back with its result.
2690f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    DCHECK(called_any_callbacks);
2701e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
2711e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    // The temporary file's directory is also temporary.
2721e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    DeleteFile(callback_state.output_file.DirName(), true);
2731e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
2741e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    MessageLoop::current()->PostTask(
2751e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        FROM_HERE,
2761e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        Bind(&UnitTestLauncherDelegate::RunSerially,
2771e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)             Unretained(this),
2781e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)             callback_state.test_launcher,
2791e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)             test_names));
28058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
28158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
28258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  static bool ProcessTestResults(
2831e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      TestLauncher* test_launcher,
2841e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      const std::vector<std::string>& test_names,
285424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      const base::FilePath& output_file,
28658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      const std::string& output,
287424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      int exit_code,
28858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      bool was_timeout,
2891e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      std::vector<std::string>* tests_to_relaunch_after_interruption) {
2903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    std::vector<TestResult> test_results;
291424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    bool crashed = false;
292424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    bool have_test_results =
293424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)        ProcessGTestOutput(output_file, &test_results, &crashed);
2943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
29558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    bool called_any_callback = false;
29658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
2973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    if (have_test_results) {
2983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      // TODO(phajdan.jr): Check for duplicates and mismatches between
2993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      // the results we got from XML file and tests we intended to run.
300424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      std::map<std::string, TestResult> results_map;
3013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      for (size_t i = 0; i < test_results.size(); i++)
3021e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        results_map[test_results[i].full_name] = test_results[i];
303424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
30458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      bool had_interrupted_test = false;
30558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
3061e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      for (size_t i = 0; i < test_names.size(); i++) {
3071e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        if (ContainsKey(results_map, test_names[i])) {
3081e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)          TestResult test_result = results_map[test_names[i]];
30958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          if (test_result.status == TestResult::TEST_CRASH) {
31058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)            had_interrupted_test = true;
31158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
31258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)            if (was_timeout) {
31358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)              // Fix up the test status: we forcibly kill the child process
31458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)              // after the timeout, so from XML results it looks just like
31558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)              // a crash.
31658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)              test_result.status = TestResult::TEST_TIMEOUT;
31758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)            }
31868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)          } else if (test_result.status == TestResult::TEST_SUCCESS ||
31968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                     test_result.status == TestResult::TEST_FAILURE) {
32068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)            // We run multiple tests in a batch with a timeout applied
32168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)            // to the entire batch. It is possible that with other tests
32268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)            // running quickly some tests take longer than the per-test timeout.
32368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)            // For consistent handling of tests independent of order and other
32468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)            // factors, mark them as timing out.
32568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)            if (test_result.elapsed_time >
32668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                TestTimeouts::test_launcher_timeout()) {
32768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)              test_result.status = TestResult::TEST_TIMEOUT;
32868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)            }
32958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          }
3304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)          test_result.output_snippet =
3314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)              GetTestOutputSnippet(test_result, output);
3321e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)          test_launcher->OnTestFinished(test_result);
33358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          called_any_callback = true;
33458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        } else if (had_interrupted_test) {
3351e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)          tests_to_relaunch_after_interruption->push_back(test_names[i]);
336424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)        } else {
337424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)          // TODO(phajdan.jr): Explicitly pass the info that the test didn't
338424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)          // run for a mysterious reason.
3391e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)          LOG(ERROR) << "no test result for " << test_names[i];
340424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)          TestResult test_result;
3411e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)          test_result.full_name = test_names[i];
34258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          test_result.status = TestResult::TEST_UNKNOWN;
3434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)          test_result.output_snippet =
3444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)              GetTestOutputSnippet(test_result, output);
3451e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)          test_launcher->OnTestFinished(test_result);
34658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          called_any_callback = true;
347424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)        }
3483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      }
3493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
350424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      // TODO(phajdan.jr): Handle the case where processing XML output
351424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      // indicates a crash but none of the test results is marked as crashing.
352424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
3533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      // TODO(phajdan.jr): Handle the case where the exit code is non-zero
3543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      // but results file indicates that all tests passed (e.g. crash during
3553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      // shutdown).
3563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    } else {
35758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      fprintf(stdout,
35858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)              "Failed to get out-of-band test success data, "
35958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)              "dumping full stdio below:\n%s\n",
36058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)              output.c_str());
36158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      fflush(stdout);
36258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
3633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      // We do not have reliable details about test results (parsing test
3643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      // stdout is known to be unreliable), apply the executable exit code
3653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      // to all tests.
3663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      // TODO(phajdan.jr): Be smarter about this, e.g. retry each test
3673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      // individually.
3681e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      for (size_t i = 0; i < test_names.size(); i++) {
3693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        TestResult test_result;
3701e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        test_result.full_name = test_names[i];
37158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        test_result.status = TestResult::TEST_UNKNOWN;
3721e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        test_launcher->OnTestFinished(test_result);
37358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        called_any_callback = true;
3743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      }
3753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    }
37658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
37758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return called_any_callback;
3783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
3793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
38068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  ThreadChecker thread_checker_;
38168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
38258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Maximum number of tests to run in a single batch.
38358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  size_t batch_limit_;
3843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)};
3853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
38658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)bool GetSwitchValueAsInt(const std::string& switch_name, int* result) {
38758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (!CommandLine::ForCurrentProcess()->HasSwitch(switch_name))
38858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return true;
38958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
39058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  std::string switch_value =
39158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      CommandLine::ForCurrentProcess()->GetSwitchValueASCII(switch_name);
39258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (!StringToInt(switch_value, result) || *result < 1) {
39358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    LOG(ERROR) << "Invalid value for " << switch_name << ": " << switch_value;
39458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return false;
39558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
39658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
39758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return true;
39858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
39958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
4003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}  // namespace
4013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
4023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)int LaunchUnitTests(int argc,
4033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                    char** argv,
4043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                    const RunTestSuiteCallback& run_test_suite) {
4053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  CommandLine::Init(argc, argv);
406d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  if (CommandLine::ForCurrentProcess()->HasSwitch(kGTestHelpFlag) ||
407d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      CommandLine::ForCurrentProcess()->HasSwitch(kSingleProcessTestsFlag) ||
4083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      !CommandLine::ForCurrentProcess()->HasSwitch(kBraveNewTestLauncherFlag)) {
4093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return run_test_suite.Run();
4103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
4113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
412d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  if (CommandLine::ForCurrentProcess()->HasSwitch(kHelpFlag)) {
413d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    PrintUsage();
414d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    return 0;
415d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  }
416d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
4173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  base::TimeTicks start_time(base::TimeTicks::Now());
4183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
41958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  testing::InitGoogleTest(&argc, argv);
42058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  TestTimeouts::Initialize();
42158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
42258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  int jobs = SysInfo::NumberOfProcessors();
42358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (!GetSwitchValueAsInt(switches::kTestLauncherJobs, &jobs))
42458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return 1;
42558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
42658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  int batch_limit = kDefaultTestBatchLimit;
42758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (!GetSwitchValueAsInt(switches::kTestLauncherBatchLimit, &batch_limit))
42858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return 1;
42958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
4303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  fprintf(stdout,
43158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          "Starting tests (using %d parallel jobs)...\n"
43258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          "IMPORTANT DEBUGGING NOTE: batches of tests are run inside their\n"
43358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          "own process. For debugging a test inside a debugger, use the\n"
43458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          "--gtest_filter=<your_test_name> flag along with\n"
43558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          "--single-process-tests.\n", jobs);
4363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  fflush(stdout);
4373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
43858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  MessageLoopForIO message_loop;
4393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
4400f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  base::UnitTestLauncherDelegate delegate(batch_limit);
4410f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  base::TestLauncher launcher(&delegate, jobs);
4428bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  bool success = launcher.Run(argc, argv);
4433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
4443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  fprintf(stdout,
4453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)          "Tests took %" PRId64 " seconds.\n",
4463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)          (base::TimeTicks::Now() - start_time).InSeconds());
4473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  fflush(stdout);
4483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
4498bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  return (success ? 0 : 1);
4503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
4513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
452424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}  // namespace base
453