file_test_base.cpp 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622
  1. // Part of the Carbon Language project, under the Apache License v2.0 with LLVM
  2. // Exceptions. See /LICENSE for license information.
  3. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4. // Implementation-wise, this:
  5. //
  6. // - Uses the registered `FileTestFactory` to construct `FileTestBase`
  7. // instances.
  8. // - Constructs a `FileTestCase` that wraps each `FileTestBase` instance to
  9. // register with googletest, and to provide the actual `TestBody`.
  10. // - Using `FileTestEventListener`, runs tests in parallel prior to normal
  11. // googletest execution.
  12. // - This is required to support `--gtest_filter` and access `should_run`.
  13. // - Runs each `FileTestBase` instance to cache the `TestFile` on
  14. // `FileTestInfo`.
  15. // - Determines whether autoupdate would make changes, autoupdating if
  16. // requested.
  17. // - When googletest would normally execute the test, `FileTestCase::TestBody`
  18. // instead uses the cached state on `FileTestInfo`.
  19. // - This only occurs when neither autoupdating nor dumping output.
  20. #include "testing/file_test/file_test_base.h"
  21. #include <atomic>
  22. #include <chrono>
  23. #include <cstdlib>
  24. #include <filesystem>
  25. #include <functional>
  26. #include <memory>
  27. #include <mutex>
  28. #include <optional>
  29. #include <string>
  30. #include <string_view>
  31. #include <system_error>
  32. #include <utility>
  33. #include "absl/flags/flag.h"
  34. #include "absl/flags/parse.h"
  35. #include "absl/strings/str_join.h"
  36. #include "common/build_data.h"
  37. #include "common/check.h"
  38. #include "common/error.h"
  39. #include "common/exe_path.h"
  40. #include "common/init_llvm.h"
  41. #include "common/raw_string_ostream.h"
  42. #include "llvm/ADT/StringExtras.h"
  43. #include "llvm/Support/CrashRecoveryContext.h"
  44. #include "llvm/Support/FormatVariadic.h"
  45. #include "llvm/Support/MemoryBuffer.h"
  46. #include "llvm/Support/PrettyStackTrace.h"
  47. #include "llvm/Support/Process.h"
  48. #include "llvm/Support/ThreadPool.h"
  49. #include "testing/file_test/autoupdate.h"
  50. #include "testing/file_test/run_test.h"
  51. #include "testing/file_test/test_file.h"
  52. ABSL_FLAG(std::vector<std::string>, file_tests, {},
  53. "A comma-separated list of repo-relative names of test files. "
  54. "Similar to and overrides `--gtest_filter`, but doesn't require the "
  55. "test class name to be known.");
  56. ABSL_FLAG(bool, autoupdate, false,
  57. "Instead of verifying files match test output, autoupdate files "
  58. "based on test output.");
  59. ABSL_FLAG(unsigned int, threads, 0,
  60. "Number of threads to use when autoupdating tests, or 0 to "
  61. "automatically determine a thread count.");
  62. ABSL_FLAG(bool, dump_output, false,
  63. "Instead of verifying files match test output, directly dump output "
  64. "to stderr.");
  65. ABSL_FLAG(int, print_slowest_tests, 5,
  66. "The number of tests to print when showing slowest tests. Set to 0 "
  67. "to disabling printing. Set to -1 to print all tests.");
  68. namespace Carbon::Testing {
  69. // Information for a test case.
  70. struct FileTestInfo {
  71. // The name.
  72. std::string test_name;
  73. // A factory function for creating the test object.
  74. std::function<auto()->std::unique_ptr<FileTestBase>> factory_fn;
  75. // gtest's information about the test.
  76. ::testing::TestInfo* registered_test;
  77. // The test result, set after running.
  78. std::optional<ErrorOr<TestFile>> test_result;
  79. // Whether running autoupdate would change (or when autoupdating, already
  80. // changed) the test file. This may be true even if output passes test
  81. // expectations.
  82. bool autoupdate_differs = false;
  83. // Time spent in the test total, including processing and autoupdate.
  84. std::chrono::milliseconds elapsed_ms = std::chrono::milliseconds(0);
  85. };
  86. // Adapts a `FileTestBase` instance to gtest for outputting results.
  87. class FileTestCase : public testing::Test {
  88. public:
  89. explicit FileTestCase(FileTestInfo* test_info) : test_info_(test_info) {}
  90. // Runs a test and compares output. This keeps output split by line so that
  91. // issues are a little easier to identify by the different line.
  92. auto TestBody() -> void final;
  93. private:
  94. FileTestInfo* test_info_;
  95. };
  96. // Splits outputs to string_view because gtest handles string_view by default.
  97. static auto SplitOutput(llvm::StringRef output)
  98. -> llvm::SmallVector<std::string_view> {
  99. if (output.empty()) {
  100. return {};
  101. }
  102. llvm::SmallVector<llvm::StringRef> lines;
  103. llvm::StringRef(output).split(lines, "\n");
  104. return llvm::SmallVector<std::string_view>(lines.begin(), lines.end());
  105. }
  106. // Verify that the success and `fail_` prefix use correspond. Separately handle
  107. // both cases for clearer test failures.
  108. static auto CompareFailPrefix(llvm::StringRef filename, bool success) -> void {
  109. if (success) {
  110. EXPECT_FALSE(filename.starts_with("fail_"))
  111. << "`" << filename
  112. << "` succeeded; if success is expected, remove the `fail_` "
  113. "prefix.";
  114. } else {
  115. EXPECT_TRUE(filename.starts_with("fail_"))
  116. << "`" << filename
  117. << "` failed; if failure is expected, add the `fail_` prefix.";
  118. }
  119. }
  120. // Returns the requested bazel command string for the given execution mode.
  121. auto FileTestBase::GetBazelCommand(BazelMode mode) -> std::string {
  122. RawStringOstream args;
  123. args << "bazel " << ((mode == BazelMode::Test) ? "test" : "run") << " "
  124. << BuildData::TargetName << " ";
  125. switch (mode) {
  126. case BazelMode::Autoupdate:
  127. args << "-- --autoupdate ";
  128. break;
  129. case BazelMode::Dump:
  130. args << "-- --dump_output ";
  131. break;
  132. case BazelMode::Test:
  133. args << "--test_arg=";
  134. break;
  135. }
  136. args << "--file_tests=";
  137. args << test_name();
  138. return args.TakeStr();
  139. }
  140. // Runs the FileTestAutoupdater, returning the result.
  141. static auto RunAutoupdater(FileTestBase* test_base, const TestFile& test_file,
  142. bool dry_run) -> bool {
  143. if (!test_file.autoupdate_line_number) {
  144. return false;
  145. }
  146. llvm::SmallVector<llvm::StringRef> filenames;
  147. filenames.reserve(test_file.non_check_lines.size());
  148. if (test_file.has_splits) {
  149. // There are splits, so we provide an empty name for the first file.
  150. filenames.push_back({});
  151. }
  152. for (const auto& file : test_file.file_splits) {
  153. filenames.push_back(file.filename);
  154. }
  155. llvm::ArrayRef expected_filenames = filenames;
  156. if (filenames.size() > 1) {
  157. expected_filenames.consume_front();
  158. }
  159. return FileTestAutoupdater(
  160. std::filesystem::absolute(test_base->test_name().str()),
  161. test_base->GetBazelCommand(FileTestBase::BazelMode::Test),
  162. test_base->GetBazelCommand(FileTestBase::BazelMode::Dump),
  163. test_file.input_content, filenames,
  164. *test_file.autoupdate_line_number, test_file.autoupdate_split,
  165. test_file.non_check_lines, test_file.actual_stdout,
  166. test_file.actual_stderr,
  167. test_base->GetDefaultFileRE(expected_filenames),
  168. test_base->GetLineNumberReplacements(expected_filenames),
  169. [&](std::string& line) {
  170. test_base->DoExtraCheckReplacements(line);
  171. },
  172. [&](FileTestBase::CheckLineArray& lines, bool is_stderr) {
  173. test_base->FinalizeCheckLines(lines, is_stderr);
  174. })
  175. .Run(dry_run);
  176. }
  177. auto FileTestCase::TestBody() -> void {
  178. if (absl::GetFlag(FLAGS_autoupdate) || absl::GetFlag(FLAGS_dump_output)) {
  179. return;
  180. }
  181. CARBON_CHECK(test_info_->test_result,
  182. "Expected test to be run prior to TestBody: {0}",
  183. test_info_->test_name);
  184. ASSERT_TRUE(test_info_->test_result->ok())
  185. << test_info_->test_result->error();
  186. auto test_filename = std::filesystem::path(test_info_->test_name).filename();
  187. // Check success/failure against `fail_` prefixes.
  188. TestFile& test_file = **(test_info_->test_result);
  189. if (test_file.run_result.per_file_success.empty()) {
  190. CompareFailPrefix(test_filename.string(), test_file.run_result.success);
  191. } else {
  192. bool require_overall_failure = false;
  193. for (const auto& [filename, success] :
  194. test_file.run_result.per_file_success) {
  195. CompareFailPrefix(filename, success);
  196. if (!success) {
  197. require_overall_failure = true;
  198. }
  199. }
  200. if (require_overall_failure) {
  201. EXPECT_FALSE(test_file.run_result.success)
  202. << "There is a per-file failure expectation, so the overall result "
  203. "should have been a failure.";
  204. } else {
  205. // Individual files all succeeded, so the prefix is enforced on the main
  206. // test file.
  207. CompareFailPrefix(test_filename.string(), test_file.run_result.success);
  208. }
  209. }
  210. // Check results. Include a reminder for NOAUTOUPDATE tests.
  211. std::unique_ptr<testing::ScopedTrace> scoped_trace;
  212. if (!test_file.autoupdate_line_number) {
  213. scoped_trace = std::make_unique<testing::ScopedTrace>(
  214. __FILE__, __LINE__,
  215. "This file is NOAUTOUPDATE, so expected differences require manual "
  216. "updates.");
  217. }
  218. if (test_file.check_subset) {
  219. EXPECT_THAT(SplitOutput(test_file.actual_stdout),
  220. IsSupersetOf(test_file.expected_stdout))
  221. << "Actual text:\n"
  222. << test_file.actual_stdout;
  223. EXPECT_THAT(SplitOutput(test_file.actual_stderr),
  224. IsSupersetOf(test_file.expected_stderr))
  225. << "Actual text:\n"
  226. << test_file.actual_stderr;
  227. } else {
  228. EXPECT_THAT(SplitOutput(test_file.actual_stdout),
  229. ElementsAreArray(test_file.expected_stdout))
  230. << "Actual text:\n"
  231. << test_file.actual_stdout;
  232. EXPECT_THAT(SplitOutput(test_file.actual_stderr),
  233. ElementsAreArray(test_file.expected_stderr))
  234. << "Actual text:\n"
  235. << test_file.actual_stderr;
  236. }
  237. if (HasFailure()) {
  238. llvm::errs() << "\nTo test this file alone, run:\n "
  239. << test_info_->factory_fn()->GetBazelCommand(
  240. FileTestBase::BazelMode::Test)
  241. << "\n\n";
  242. if (!test_file.autoupdate_line_number) {
  243. llvm::errs() << "\nThis test is NOAUTOUPDATE.\n\n";
  244. }
  245. }
  246. if (test_info_->autoupdate_differs) {
  247. ADD_FAILURE() << "Autoupdate would make changes to the file content. Run:\n"
  248. << test_info_->factory_fn()->GetBazelCommand(
  249. FileTestBase::BazelMode::Autoupdate);
  250. }
  251. }
  252. auto FileTestBase::GetLineNumberReplacements(
  253. llvm::ArrayRef<llvm::StringRef> filenames) const
  254. -> llvm::SmallVector<LineNumberReplacement> {
  255. return {{.has_file = true,
  256. .re = std::make_shared<RE2>(
  257. llvm::formatv(R"(({0}):(\d+)?)", llvm::join(filenames, "|"))),
  258. .line_formatv = R"({0})"}};
  259. }
  260. // If `--file_tests` is set, transform it into a `--gtest_filter`.
  261. static auto MaybeApplyFileTestsFlag(llvm::StringRef factory_name) -> void {
  262. if (absl::GetFlag(FLAGS_file_tests).empty()) {
  263. return;
  264. }
  265. RawStringOstream filter;
  266. llvm::ListSeparator sep(":");
  267. for (const auto& file : absl::GetFlag(FLAGS_file_tests)) {
  268. filter << sep << factory_name << "." << file;
  269. }
  270. absl::SetFlag(&FLAGS_gtest_filter, filter.TakeStr());
  271. }
  272. // Loads tests from the manifest file, and registers them for execution. The
  273. // vector is taken as an output parameter so that the address of entries is
  274. // stable for the factory.
  275. static auto RegisterTests(FileTestFactory* test_factory,
  276. llvm::StringRef exe_path,
  277. llvm::SmallVectorImpl<FileTestInfo>& tests)
  278. -> ErrorOr<Success> {
  279. // Prepare the vector first, so that the location of entries won't change.
  280. for (auto& test_name : GetFileTestManifest()) {
  281. tests.push_back({.test_name = test_name});
  282. }
  283. // Amend entries with factory functions.
  284. for (auto& test : tests) {
  285. const std::string& test_name = test.test_name;
  286. test.factory_fn = [test_factory, exe_path, &test_name]() {
  287. return test_factory->factory_fn(exe_path, test_name);
  288. };
  289. test.registered_test = testing::RegisterTest(
  290. test_factory->name, test_name.c_str(), nullptr, test_name.c_str(),
  291. __FILE__, __LINE__, [&test]() { return new FileTestCase(&test); });
  292. }
  293. return Success();
  294. }
  295. // Implements the parallel test execution through gtest's listener support.
  296. class FileTestEventListener : public testing::EmptyTestEventListener {
  297. public:
  298. explicit FileTestEventListener(llvm::MutableArrayRef<FileTestInfo> tests)
  299. : tests_(tests) {}
  300. // Runs test during start, after `should_run` is initialized. This is
  301. // multi-threaded to get extra speed.
  302. auto OnTestProgramStart(const testing::UnitTest& /*unit_test*/)
  303. -> void override;
  304. private:
  305. llvm::MutableArrayRef<FileTestInfo> tests_;
  306. };
  307. // Returns true if the main thread should be used to run tests. This is if
  308. // either --dump_output is specified, or only 1 thread is needed to run tests.
  309. static auto SingleThreaded(llvm::ArrayRef<FileTestInfo> tests) -> bool {
  310. if (absl::GetFlag(FLAGS_dump_output) || absl::GetFlag(FLAGS_threads) == 1) {
  311. return true;
  312. }
  313. bool found_test_to_run = false;
  314. for (const auto& test : tests) {
  315. if (!test.registered_test->should_run()) {
  316. continue;
  317. }
  318. if (found_test_to_run) {
  319. // At least two tests will run, so multi-threaded.
  320. return false;
  321. }
  322. // Found the first test to run.
  323. found_test_to_run = true;
  324. }
  325. // 0 or 1 test will be run, so single-threaded.
  326. return true;
  327. }
  328. // Runs the test in the section that would be inside a lock, possibly inside a
  329. // CrashRecoveryContext.
  330. static auto RunSingleTestHelper(FileTestInfo& test, FileTestBase& test_instance)
  331. -> void {
  332. Timer timer;
  333. // Add a crash trace entry with the single-file test command.
  334. std::string test_command =
  335. test_instance.GetBazelCommand(FileTestBase::BazelMode::Test);
  336. llvm::PrettyStackTraceString stack_trace_entry(test_command.c_str());
  337. if (auto err = RunTestFile(test_instance, absl::GetFlag(FLAGS_dump_output),
  338. **test.test_result);
  339. !err.ok()) {
  340. test.test_result = std::move(err).error();
  341. }
  342. test.elapsed_ms += timer.elapsed_ms();
  343. }
  344. // Runs a single test. Uses a CrashRecoveryContext, and returns false on a
  345. // crash. For test_elapsed_ms, try to exclude time spent waiting on
  346. // output_mutex.
  347. static auto RunSingleTest(FileTestInfo& test, bool single_threaded,
  348. std::mutex& output_mutex) -> bool {
  349. std::unique_ptr<FileTestBase> test_instance(test.factory_fn());
  350. if (absl::GetFlag(FLAGS_dump_output)) {
  351. std::unique_lock<std::mutex> lock(output_mutex);
  352. llvm::errs() << "\n--- Dumping: " << test.test_name << "\n\n";
  353. } else if (single_threaded) {
  354. std::unique_lock<std::mutex> lock(output_mutex);
  355. llvm::errs() << "\nTEST: " << test.test_name << ' ';
  356. }
  357. // Load expected output.
  358. Timer process_timer;
  359. test.test_result = ProcessTestFile(test_instance->test_name(),
  360. absl::GetFlag(FLAGS_autoupdate));
  361. test.elapsed_ms = process_timer.elapsed_ms();
  362. if (test.test_result->ok()) {
  363. // Execution must be serialized for either serial tests or console
  364. // output.
  365. std::unique_lock<std::mutex> output_lock;
  366. if ((*test.test_result)->capture_console_output ||
  367. !test_instance->AllowParallelRun()) {
  368. output_lock = std::unique_lock<std::mutex>(output_mutex);
  369. }
  370. if (single_threaded) {
  371. RunSingleTestHelper(test, *test_instance);
  372. } else {
  373. // Use a crash recovery context to try to get a stack trace when
  374. // multiple threads may crash in parallel, which otherwise leads to the
  375. // program aborting without printing a stack trace.
  376. llvm::CrashRecoveryContext crc;
  377. crc.DumpStackAndCleanupOnFailure = true;
  378. if (!crc.RunSafely([&] { RunSingleTestHelper(test, *test_instance); })) {
  379. return false;
  380. }
  381. }
  382. }
  383. if (!test.test_result->ok()) {
  384. std::unique_lock<std::mutex> lock(output_mutex);
  385. if (!single_threaded) {
  386. llvm::errs() << "\n" << test.test_name << ": ";
  387. }
  388. llvm::errs() << test.test_result->error().message() << "\n";
  389. return true;
  390. }
  391. Timer autoupdate_timer;
  392. test.autoupdate_differs =
  393. RunAutoupdater(test_instance.get(), **test.test_result,
  394. /*dry_run=*/!absl::GetFlag(FLAGS_autoupdate));
  395. test.elapsed_ms += autoupdate_timer.elapsed_ms();
  396. std::unique_lock<std::mutex> lock(output_mutex);
  397. if (absl::GetFlag(FLAGS_dump_output)) {
  398. llvm::outs().flush();
  399. const TestFile& test_file = **test.test_result;
  400. llvm::errs() << "\n--- Exit with success: "
  401. << (test_file.run_result.success ? "true" : "false")
  402. << "\n--- Autoupdate differs: "
  403. << (test.autoupdate_differs ? "true" : "false") << "\n";
  404. } else {
  405. llvm::errs() << (test.autoupdate_differs ? "!" : ".");
  406. }
  407. return true;
  408. }
  409. auto FileTestEventListener::OnTestProgramStart(
  410. const testing::UnitTest& /*unit_test*/) -> void {
  411. bool single_threaded = SingleThreaded(tests_);
  412. std::unique_ptr<llvm::ThreadPoolInterface> pool;
  413. if (single_threaded) {
  414. pool = std::make_unique<llvm::SingleThreadExecutor>();
  415. } else {
  416. // Enable the CRC for use in `RunSingleTest`.
  417. llvm::CrashRecoveryContext::Enable();
  418. llvm::ThreadPoolStrategy thread_strategy = {
  419. .ThreadsRequested = absl::GetFlag(FLAGS_threads),
  420. // Disable hyper threads to reduce contention.
  421. .UseHyperThreads = false};
  422. pool = std::make_unique<llvm::DefaultThreadPool>(thread_strategy);
  423. }
  424. if (!absl::GetFlag(FLAGS_dump_output)) {
  425. llvm::errs() << "Running tests with " << pool->getMaxConcurrency()
  426. << " thread(s)\n";
  427. }
  428. // Guard access to output (stdout and stderr).
  429. std::mutex output_mutex;
  430. std::atomic<bool> crashed = false;
  431. Timer all_timer;
  432. int run_count = 0;
  433. for (auto& test : tests_) {
  434. if (!test.registered_test->should_run()) {
  435. continue;
  436. }
  437. ++run_count;
  438. pool->async([&] {
  439. // If any thread crashed, don't try running more.
  440. if (crashed) {
  441. return;
  442. }
  443. if (!RunSingleTest(test, single_threaded, output_mutex)) {
  444. crashed = true;
  445. }
  446. });
  447. }
  448. pool->wait();
  449. if (crashed) {
  450. // Abort rather than returning so that we don't get a LeakSanitizer report.
  451. // We expect to have leaked memory if one or more of our tests crashed.
  452. std::abort();
  453. }
  454. // Calculate the total test time.
  455. auto all_elapsed_ms = all_timer.elapsed_ms();
  456. auto total_elapsed_ms = std::chrono::milliseconds(0);
  457. for (auto& test : tests_) {
  458. total_elapsed_ms += test.elapsed_ms;
  459. }
  460. llvm::errs() << "\nRan " << run_count << " tests in "
  461. << all_elapsed_ms.count() << " ms wall time, "
  462. << total_elapsed_ms.count() << " ms across threads\n";
  463. // When there are multiple tests, give additional timing details, particularly
  464. // slowest tests.
  465. auto print_slowest_tests = absl::GetFlag(FLAGS_print_slowest_tests);
  466. if (run_count > 1 && print_slowest_tests != 0) {
  467. // Sort in a copy so that `FileTestCase` pointers to the original tests
  468. // remain stable.
  469. llvm::SmallVector<const FileTestInfo*> sorted_tests(
  470. llvm::make_pointer_range(tests_));
  471. llvm::sort(sorted_tests,
  472. [](const FileTestInfo* lhs, const FileTestInfo* rhs) {
  473. return lhs->elapsed_ms > rhs->elapsed_ms;
  474. });
  475. llvm::errs() << " Slowest tests:\n";
  476. int count = print_slowest_tests > 0 ? print_slowest_tests : run_count;
  477. for (const auto* test : llvm::ArrayRef(sorted_tests).take_front(count)) {
  478. std::chrono::milliseconds run_ms(0);
  479. if (test->test_result && test->test_result->ok()) {
  480. run_ms = test->test_result.value()->run_elapsed_ms;
  481. }
  482. llvm::errs() << " - " << test->test_name << ": "
  483. << test->elapsed_ms.count() << " ms, " << run_ms.count()
  484. << " ms in Run\n";
  485. }
  486. }
  487. }
  488. // Implements main() within the Carbon::Testing namespace for convenience.
  489. static auto Main(int argc, char** argv) -> ErrorOr<int> {
  490. // Default to brief because we expect lots of tests, and `FileTestBase`
  491. // provides some summaries. Note `--test_arg=--gtest_brief=0` works to restore
  492. // output.
  493. absl::SetFlag(&FLAGS_gtest_brief, 1);
  494. Carbon::InitLLVM init_llvm(argc, argv);
  495. testing::InitGoogleTest(&argc, argv);
  496. auto args = absl::ParseCommandLine(argc, argv);
  497. if (args.size() > 1) {
  498. ErrorBuilder b;
  499. b << "Unexpected arguments:";
  500. for (char* arg : llvm::ArrayRef(args).drop_front()) {
  501. b << " " << FormatEscaped(arg);
  502. }
  503. return b;
  504. }
  505. std::string exe_path = FindExecutablePath(argv[0]);
  506. // Tests might try to read from stdin. Ensure those reads fail by closing
  507. // stdin and reopening it as /dev/null. Note that STDIN_FILENO doesn't exist
  508. // on Windows, but POSIX requires it to be 0.
  509. if (std::error_code error =
  510. llvm::sys::Process::SafelyCloseFileDescriptor(0)) {
  511. return Error("Unable to close standard input: " + error.message());
  512. }
  513. if (std::error_code error =
  514. llvm::sys::Process::FixupStandardFileDescriptors()) {
  515. return Error("Unable to correct standard file descriptors: " +
  516. error.message());
  517. }
  518. if (absl::GetFlag(FLAGS_autoupdate) && absl::GetFlag(FLAGS_dump_output)) {
  519. return Error("--autoupdate and --dump_output are mutually exclusive.");
  520. }
  521. auto test_factory = GetFileTestFactory();
  522. MaybeApplyFileTestsFlag(test_factory.name);
  523. // Inline 0 entries because it will always be too large to store on the stack.
  524. llvm::SmallVector<FileTestInfo, 0> tests;
  525. CARBON_RETURN_IF_ERROR(RegisterTests(&test_factory, exe_path, tests));
  526. testing::TestEventListeners& listeners =
  527. testing::UnitTest::GetInstance()->listeners();
  528. if (absl::GetFlag(FLAGS_autoupdate) || absl::GetFlag(FLAGS_dump_output)) {
  529. // Suppress all of the default output.
  530. delete listeners.Release(listeners.default_result_printer());
  531. }
  532. // Use a listener to run tests in parallel.
  533. listeners.Append(new FileTestEventListener(tests));
  534. return RUN_ALL_TESTS();
  535. }
  536. } // namespace Carbon::Testing
  537. auto main(int argc, char** argv) -> int {
  538. if (auto result = Carbon::Testing::Main(argc, argv); result.ok()) {
  539. return *result;
  540. } else {
  541. llvm::errs() << result.error() << "\n";
  542. return EXIT_FAILURE;
  543. }
  544. }