| OLD | NEW |
| (Empty) |
| 1 // Copyright 2015 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 #include <inttypes.h> | |
| 6 #include <stdio.h> | |
| 7 | |
| 8 #include <string> | |
| 9 | |
| 10 #include "base/command_line.h" | |
| 11 #include "base/files/file_path.h" | |
| 12 #include "base/files/file_util.h" | |
| 13 #include "base/message_loop/message_loop.h" | |
| 14 #include "base/path_service.h" | |
| 15 #include "base/process/launch.h" | |
| 16 #include "base/strings/string_piece.h" | |
| 17 #include "base/strings/string_tokenizer.h" | |
| 18 #include "base/strings/string_util.h" | |
| 19 #include "base/sys_info.h" | |
| 20 #include "base/test/launcher/test_launcher.h" | |
| 21 #include "base/test/launcher/unit_test_launcher.h" | |
| 22 #include "base/test/test_switches.h" | |
| 23 #include "base/test/test_timeouts.h" | |
| 24 | |
| 25 namespace base { | |
| 26 | |
| 27 namespace { | |
| 28 | |
| 29 const char kHelpFlag[] = "help"; | |
| 30 | |
| 31 void PrintUsage() { | |
| 32 fprintf(stdout, | |
| 33 "Runs tests using the gtest framework, each batch of tests being\n" | |
| 34 "run in their own process. Supported command-line flags:\n" | |
| 35 "\n" | |
| 36 " Common flags:\n" | |
| 37 " --gtest_filter=...\n" | |
| 38 " Runs a subset of tests (see --gtest_help for more info).\n" | |
| 39 "\n" | |
| 40 " --help\n" | |
| 41 " Shows this message.\n" | |
| 42 "\n" | |
| 43 " Other flags:\n" | |
| 44 " --test-launcher-retry-limit=N\n" | |
| 45 " Sets the limit of test retries on failures to N.\n" | |
| 46 "\n" | |
| 47 " --test-launcher-summary-output=PATH\n" | |
| 48 " Saves a JSON machine-readable summary of the run.\n" | |
| 49 "\n" | |
| 50 " --test-launcher-print-test-stdio=auto|always|never\n" | |
| 51 " Controls when full test output is printed.\n" | |
| 52 " auto means to print it when the test failed.\n" | |
| 53 "\n" | |
| 54 " --test-launcher-total-shards=N\n" | |
| 55 " Sets the total number of shards to N.\n" | |
| 56 "\n" | |
| 57 " --test-launcher-shard-index=N\n" | |
| 58 " Sets the shard index to run to N (from 0 to TOTAL - 1).\n"); | |
| 59 fflush(stdout); | |
| 60 } | |
| 61 | |
| 62 class NonSfiUnitTestPlatformDelegate : public base::UnitTestPlatformDelegate { | |
| 63 public: | |
| 64 NonSfiUnitTestPlatformDelegate() { | |
| 65 } | |
| 66 | |
| 67 bool Init(const std::string& test_binary) { | |
| 68 base::FilePath dir_exe; | |
| 69 if (!PathService::Get(base::DIR_EXE, &dir_exe)) { | |
| 70 LOG(ERROR) << "Failed to get directory of the current executable."; | |
| 71 return false; | |
| 72 } | |
| 73 | |
| 74 test_path_ = dir_exe.AppendASCII(test_binary); | |
| 75 return true; | |
| 76 } | |
| 77 | |
| 78 private: | |
| 79 bool CreateTemporaryFile(base::FilePath* path) override { | |
| 80 if (!base::CreateNewTempDirectory(base::FilePath::StringType(), path)) | |
| 81 return false; | |
| 82 *path = path->AppendASCII("test_results.xml"); | |
| 83 return true; | |
| 84 } | |
| 85 | |
| 86 bool GetTests(std::vector<base::SplitTestName>* output) override { | |
| 87 base::FilePath output_file; | |
| 88 if (!base::CreateTemporaryFile(&output_file)) { | |
| 89 LOG(ERROR) << "Failed to create a temp file."; | |
| 90 return false; | |
| 91 } | |
| 92 | |
| 93 base::CommandLine cmd_line(test_path_); | |
| 94 cmd_line.AppendSwitchPath(switches::kTestLauncherListTests, output_file); | |
| 95 | |
| 96 base::LaunchOptions launch_options; | |
| 97 launch_options.wait = true; | |
| 98 | |
| 99 if (!base::LaunchProcess(cmd_line, launch_options).IsValid()) | |
| 100 return false; | |
| 101 | |
| 102 return base::ReadTestNamesFromFile(output_file, output); | |
| 103 } | |
| 104 | |
| 105 std::string GetWrapperForChildGTestProcess() override { | |
| 106 return std::string(); | |
| 107 } | |
| 108 | |
| 109 base::CommandLine GetCommandLineForChildGTestProcess( | |
| 110 const std::vector<std::string>& test_names, | |
| 111 const base::FilePath& output_file) override { | |
| 112 base::CommandLine cmd_line(test_path_); | |
| 113 cmd_line.AppendSwitchPath( | |
| 114 switches::kTestLauncherOutput, output_file); | |
| 115 cmd_line.AppendSwitchASCII(base::kGTestFilterFlag, | |
| 116 base::JoinString(test_names, ":")); | |
| 117 return cmd_line; | |
| 118 } | |
| 119 | |
| 120 void RelaunchTests(base::TestLauncher* test_launcher, | |
| 121 const std::vector<std::string>& test_names, | |
| 122 int launch_flags) override { | |
| 123 RunUnitTestsBatch(test_launcher, this, test_names, launch_flags); | |
| 124 } | |
| 125 | |
| 126 base::FilePath test_path_; | |
| 127 }; | |
| 128 | |
| 129 } // namespace | |
| 130 | |
| 131 int TestLauncherNonSfiMain(const std::string& test_binary) { | |
| 132 if (base::CommandLine::ForCurrentProcess()->HasSwitch(kHelpFlag)) { | |
| 133 PrintUsage(); | |
| 134 return 0; | |
| 135 } | |
| 136 | |
| 137 base::TimeTicks start_time(base::TimeTicks::Now()); | |
| 138 | |
| 139 TestTimeouts::Initialize(); | |
| 140 | |
| 141 base::MessageLoopForIO message_loop; | |
| 142 | |
| 143 NonSfiUnitTestPlatformDelegate platform_delegate; | |
| 144 if (!platform_delegate.Init(test_binary)) { | |
| 145 fprintf(stderr, "Failed to initialize test launcher.\n"); | |
| 146 fflush(stderr); | |
| 147 return 1; | |
| 148 } | |
| 149 | |
| 150 base::UnitTestLauncherDelegate delegate(&platform_delegate, 10, true); | |
| 151 base::TestLauncher launcher(&delegate, base::SysInfo::NumberOfProcessors()); | |
| 152 bool success = launcher.Run(); | |
| 153 | |
| 154 fprintf(stdout, "Tests took %" PRId64 " seconds.\n", | |
| 155 (base::TimeTicks::Now() - start_time).InSeconds()); | |
| 156 fflush(stdout); | |
| 157 return success ? 0 : 1; | |
| 158 } | |
| 159 | |
| 160 } // namespace base | |
| OLD | NEW |