1 // Copyright 2013 The Chromium Authors 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_LAUNCHER_TEST_LAUNCHER_H_ 6 #define BASE_TEST_LAUNCHER_TEST_LAUNCHER_H_ 7 8 #include <stddef.h> 9 #include <stdint.h> 10 11 #include <memory> 12 #include <set> 13 #include <string> 14 #include <unordered_set> 15 #include <vector> 16 17 #include "base/command_line.h" 18 #include "base/memory/raw_ptr.h" 19 #include "base/process/launch.h" 20 #include "base/test/gtest_util.h" 21 #include "base/test/launcher/test_result.h" 22 #include "base/test/launcher/test_results_tracker.h" 23 #include "base/threading/platform_thread.h" 24 #include "base/threading/thread_checker.h" 25 #include "base/time/time.h" 26 #include "base/timer/timer.h" 27 #include "build/build_config.h" 28 29 namespace base { 30 31 // Constants for GTest command-line flags. 32 extern const char kGTestFilterFlag[]; 33 extern const char kGTestFlagfileFlag[]; 34 extern const char kGTestHelpFlag[]; 35 extern const char kGTestListTestsFlag[]; 36 extern const char kGTestRepeatFlag[]; 37 extern const char kGTestRunDisabledTestsFlag[]; 38 extern const char kGTestOutputFlag[]; 39 extern const char kGTestShuffleFlag[]; 40 extern const char kGTestRandomSeedFlag[]; 41 extern const char kIsolatedScriptRunDisabledTestsFlag[]; 42 extern const char kIsolatedScriptTestFilterFlag[]; 43 extern const char kIsolatedScriptTestRepeatFlag[]; 44 45 // Interface for use with LaunchTests that abstracts away exact details 46 // which tests and how are run. 47 class TestLauncherDelegate { 48 public: 49 // Called to get names of tests available for running. The delegate 50 // must put the result in |output| and return true on success. 51 virtual bool GetTests(std::vector<TestIdentifier>* output) = 0; 52 53 // Additional delegate TestResult processing. ProcessTestResults(std::vector<TestResult> & test_results,TimeDelta elapsed_time)54 virtual void ProcessTestResults(std::vector<TestResult>& test_results, 55 TimeDelta elapsed_time) {} 56 57 // Called to get the command line for the specified tests. 58 // |output_file_| is populated with the path to the result file, and must 59 // be inside |temp_dir|. 60 virtual CommandLine GetCommandLine(const std::vector<std::string>& test_names, 61 const FilePath& temp_dir, 62 FilePath* output_file) = 0; 63 64 // Invoked when a test process exceeds its runtime, immediately before it is 65 // terminated. |command_line| is the command line used to launch the process. 66 // NOTE: this method is invoked on the thread the process is launched on. OnTestTimedOut(const CommandLine & cmd_line)67 virtual void OnTestTimedOut(const CommandLine& cmd_line) {} 68 69 // Returns the delegate specific wrapper for command line. 70 // If it is not empty, it is prepended to the final command line. 71 virtual std::string GetWrapper() = 0; 72 73 // Returns the delegate specific flags for launch options. 74 // The flags are specified in LaunchChildGTestProcessFlags. 75 virtual int GetLaunchOptions() = 0; 76 77 // Returns the delegate specific timeout per test. 78 virtual TimeDelta GetTimeout() = 0; 79 80 // Returns the delegate specific batch size. 81 virtual size_t GetBatchSize() = 0; 82 83 // Returns true if test should run. 84 virtual bool ShouldRunTest(const TestIdentifier& test); 85 86 protected: 87 virtual ~TestLauncherDelegate(); 88 }; 89 90 // Launches tests using a TestLauncherDelegate. 91 class TestLauncher { 92 public: 93 // Flags controlling behavior of LaunchChildGTestProcess. 94 enum LaunchChildGTestProcessFlags { 95 // Allows usage of job objects on Windows. Helps properly clean up child 96 // processes. 97 USE_JOB_OBJECTS = (1 << 0), 98 99 // Allows breakaway from job on Windows. May result in some child processes 100 // not being properly terminated after launcher dies if these processes 101 // fail to cooperate. 102 ALLOW_BREAKAWAY_FROM_JOB = (1 << 1), 103 }; 104 105 // Enum for subprocess stdio redirect. 106 enum StdioRedirect { AUTO, ALWAYS, NEVER }; 107 108 struct LaunchOptions { 109 LaunchOptions(); 110 LaunchOptions(const LaunchOptions& other); 111 ~LaunchOptions(); 112 113 int flags = 0; 114 // These mirror values in base::LaunchOptions, see it for details. 115 #if BUILDFLAG(IS_WIN) 116 base::LaunchOptions::Inherit inherit_mode = 117 base::LaunchOptions::Inherit::kSpecific; 118 base::HandlesToInheritVector handles_to_inherit; 119 #else 120 FileHandleMappingVector fds_to_remap; 121 #endif 122 }; 123 124 // Constructor. |parallel_jobs| is the limit of simultaneous parallel test 125 // jobs. |retry_limit| is the default limit of retries for bots or all tests. 126 TestLauncher(TestLauncherDelegate* launcher_delegate, 127 size_t parallel_jobs, 128 size_t retry_limit = 1U); 129 130 TestLauncher(const TestLauncher&) = delete; 131 TestLauncher& operator=(const TestLauncher&) = delete; 132 133 // virtual to mock in testing. 134 virtual ~TestLauncher(); 135 136 // Runs the launcher. Must be called at most once. 137 // command_line is null by default. 138 // if null, uses command line for current process. 139 [[nodiscard]] bool Run(CommandLine* command_line = nullptr); 140 141 // Launches a child process (assumed to be gtest-based binary) which runs 142 // tests indicated by |test_names|. 143 // |task_runner| is used to post results back to the launcher on the main 144 // thread. |task_temp_dir| is used for child process files such as user data, 145 // result file, and flag_file. |child_temp_dir|, if not empty, specifies a 146 // directory (within task_temp_dir) that the child process will use as its 147 // process-wide temporary directory. 148 // virtual to mock in testing. 149 virtual void LaunchChildGTestProcess( 150 scoped_refptr<TaskRunner> task_runner, 151 const std::vector<std::string>& test_names, 152 const FilePath& task_temp_dir, 153 const FilePath& child_temp_dir); 154 155 // Called when a test has finished running. 156 void OnTestFinished(const TestResult& result); 157 158 // Returns true if child test processes should have dedicated temporary 159 // directories. SupportsPerChildTempDirs()160 static constexpr bool SupportsPerChildTempDirs() { 161 #if BUILDFLAG(IS_WIN) 162 return true; 163 #else 164 // TODO(https://crbug.com/1038857): Enable for macOS, Linux, and Fuchsia. 165 return false; 166 #endif 167 } 168 169 private: 170 [[nodiscard]] bool Init(CommandLine* command_line); 171 172 // Gets tests from the delegate, and converts to TestInfo objects. 173 // Catches and logs uninstantiated parameterized tests. 174 // Returns false if delegate fails to return tests. 175 bool InitTests(); 176 177 // Some of the TestLauncherDelegate implementations don't call into gtest 178 // until they've already split into test-specific processes. This results 179 // in gtest's native shuffle implementation attempting to shuffle one test. 180 // Shuffling the list of tests in the test launcher (before the delegate 181 // gets involved) ensures that the entire shard is shuffled. 182 bool ShuffleTests(CommandLine* command_line); 183 184 // Move all PRE_ tests prior to the final test in order. 185 // Validate tests names. This includes no name conflict between tests 186 // without DISABLED_ prefix, and orphaned PRE_ tests. 187 // Add all tests and disabled tests names to result tracker. 188 // Filter Disabled tests if not flagged to run. 189 // Returns false if any violation is found. 190 bool ProcessAndValidateTests(); 191 192 // Runs all tests in current iteration. 193 void RunTests(); 194 195 // Print test names that almost match a filter (matches *<filter>*). 196 void PrintFuzzyMatchingTestNames(); 197 198 // Retry to run tests that failed during RunTests. 199 // Returns false if retry still fails or unable to start. 200 bool RunRetryTests(); 201 202 void CombinePositiveTestFilters(std::vector<std::string> filter_a, 203 std::vector<std::string> filter_b); 204 205 // Rest counters, retry tests list, and test result tracker. 206 void OnTestIterationStart(); 207 208 #if BUILDFLAG(IS_POSIX) 209 void OnShutdownPipeReadable(); 210 #endif 211 212 // Saves test results summary as JSON if requested from command line. 213 void MaybeSaveSummaryAsJSON(const std::vector<std::string>& additional_tags); 214 215 // Called when a test iteration is finished. 216 void OnTestIterationFinished(); 217 218 // Called by the delay timer when no output was made for a while. 219 void OnOutputTimeout(); 220 221 // Creates and starts a ThreadPoolInstance with |num_parallel_jobs| dedicated 222 // to foreground blocking tasks (corresponds to the traits used to launch and 223 // wait for child processes). virtual to mock in testing. 224 virtual void CreateAndStartThreadPool(size_t num_parallel_jobs); 225 226 // Callback to receive result of a test. 227 // |result_file| is a path to xml file written by child process. 228 // It contains information about test and failed 229 // EXPECT/ASSERT/DCHECK statements. Test launcher parses that 230 // file to get additional information about test run (status, 231 // error-messages, stack-traces and file/line for failures). 232 // |thread_id| is the actual worker thread that launching the child process. 233 // |process_num| is a sequence number of the process executed in the run. 234 // |leaked_items| is the number of files and/or directories remaining in the 235 // child process's temporary directory upon its termination. 236 void ProcessTestResults(const std::vector<std::string>& test_names, 237 const FilePath& result_file, 238 const std::string& output, 239 TimeDelta elapsed_time, 240 int exit_code, 241 bool was_timeout, 242 PlatformThreadId thread_id, 243 int process_num, 244 int leaked_items); 245 246 std::vector<std::string> CollectTests(); 247 248 // Make sure we don't accidentally call the wrong methods e.g. on the worker 249 // pool thread. Should be the first member so that it's destroyed last: when 250 // destroying other members, especially the worker pool, we may check the code 251 // is running on the correct thread. 252 ThreadChecker thread_checker_; 253 254 raw_ptr<TestLauncherDelegate> launcher_delegate_; 255 256 // Support for outer sharding, just like gtest does. 257 int32_t total_shards_; // Total number of outer shards, at least one. 258 int32_t shard_index_; // Index of shard the launcher is to run. 259 260 int cycles_; // Number of remaining test iterations, or -1 for infinite. 261 262 // Test filters (empty means no filter). 263 bool has_at_least_one_positive_filter_; 264 std::vector<std::string> positive_test_filter_; 265 std::vector<std::string> negative_test_filter_; 266 267 // Class to encapsulate gtest information. 268 class TestInfo; 269 270 // Tests to use (cached result of TestLauncherDelegate::GetTests). 271 std::vector<TestInfo> tests_; 272 273 // Threshold for number of broken tests. 274 size_t broken_threshold_; 275 276 // Number of tests started in this iteration. 277 size_t test_started_count_; 278 279 // Number of tests finished in this iteration. 280 size_t test_finished_count_; 281 282 // Number of tests successfully finished in this iteration. 283 size_t test_success_count_; 284 285 // Number of tests either timing out or having an unknown result, 286 // likely indicating a more systemic problem if widespread. 287 size_t test_broken_count_; 288 289 // How many retries are left. 290 size_t retries_left_; 291 292 // Maximum number of retries per iteration. 293 size_t retry_limit_; 294 295 // Maximum number of output bytes per test. 296 size_t output_bytes_limit_; 297 298 // If true will not early exit nor skip retries even if too many tests are 299 // broken. 300 bool force_run_broken_tests_; 301 302 // Tests to retry in this iteration. 303 std::unordered_set<std::string> tests_to_retry_; 304 305 TestResultsTracker results_tracker_; 306 307 // Watchdog timer to make sure we do not go without output for too long. 308 DelayTimer watchdog_timer_; 309 310 // Number of jobs to run in parallel. 311 size_t parallel_jobs_; 312 313 // Switch to control tests stdio :{auto, always, never} 314 StdioRedirect print_test_stdio_; 315 316 // Skip disabled tests unless explicitly requested. 317 bool skip_disabled_tests_; 318 319 // Stop test iterations due to failure. 320 bool stop_on_failure_; 321 322 // Path to JSON summary result file. 323 FilePath summary_path_; 324 325 // Path to trace file. 326 FilePath trace_path_; 327 328 // redirect stdio of subprocess 329 bool redirect_stdio_; 330 331 // Number of times all tests should be repeated during each iteration. 332 // 1 if gtest_repeat is not specified or gtest_break_on_failure is specified. 333 // Otherwise it matches gtest_repeat value. 334 int repeats_per_iteration_ = 1; 335 }; 336 337 // Watch a gtest XML result file for tests run in a batch to complete. 338 class ResultWatcher { 339 public: 340 ResultWatcher(FilePath result_file, size_t num_tests); 341 342 // Poll the incomplete result file, blocking until the batch completes or a 343 // test timed out. Returns true iff no tests timed out. 344 bool PollUntilDone(TimeDelta timeout_per_test); 345 346 // Wait and block for up to `timeout` before we poll the result file again. 347 // Returns true iff we should stop polling the results early. 348 virtual bool WaitWithTimeout(TimeDelta timeout) = 0; 349 350 private: 351 // Read the results, check if a timeout occurred, and then return how long 352 // the polling loop should wait for. A nonpositive return value indicates a 353 // timeout (i.e., the next check is overdue). 354 // 355 // If a timeout did not occur, this method tries to schedule the next check 356 // for `timeout_per_test` since the last test completed. 357 TimeDelta PollOnce(TimeDelta timeout_per_test); 358 359 // Get the timestamp of the test that completed most recently. If no tests 360 // have completed, return the null time. 361 Time LatestCompletionTimestamp(const std::vector<TestResult>& test_results); 362 363 // Path to the results file. 364 FilePath result_file_; 365 366 // The number of tests that run in this batch. 367 size_t num_tests_; 368 369 // The threshold past which we attribute a large time since latest completion 370 // to daylight savings time instead of a timed out test. 371 static constexpr TimeDelta kDaylightSavingsThreshold = Minutes(50); 372 }; 373 374 // Return the number of parallel jobs to use, or 0U in case of error. 375 size_t NumParallelJobs(unsigned int cores_per_job); 376 377 // Extract part from |full_output| that applies to |result|. 378 std::string GetTestOutputSnippet(const TestResult& result, 379 const std::string& full_output); 380 381 // Truncates a snippet to approximately the allowed length, while trying to 382 // retain fatal messages. Exposed for testing only. 383 std::string TruncateSnippetFocused(const base::StringPiece snippet, 384 size_t byte_limit); 385 386 } // namespace base 387 388 #endif // BASE_TEST_LAUNCHER_TEST_LAUNCHER_H_ 389