Distribute autoupdate across threads. (#3443)

Also switch how we ensure that stdin is closed for tests, so that `bazel
run` doesn't hang if invoked manually.

---------

Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
This commit is contained in:
Richard Smith
2023-12-02 00:26:16 +00:00
committed by GitHub
co-authored by Jon Ross-Perkins
parent b8d4e2f41b
commit 9c46d15f78
2 changed files with 28 additions and 8 deletions
+27 -7
View File
@@ -20,6 +20,8 @@
#include "llvm/Support/InitLLVM.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/PrettyStackTrace.h"
#include "llvm/Support/Process.h"
#include "llvm/Support/ThreadPool.h"
#include "testing/file_test/autoupdate.h"
ABSL_FLAG(std::vector<std::string>, file_tests, {},
@@ -30,6 +32,9 @@ ABSL_FLAG(std::string, test_targets_file, "",
ABSL_FLAG(bool, autoupdate, false,
"Instead of verifying files match test output, autoupdate files "
"based on test output.");
ABSL_FLAG(unsigned int, threads, 0,
"Number of threads to use when autoupdating tests, or 0 to "
"automatically determine a thread count.");
namespace Carbon::Testing {
@@ -720,18 +725,33 @@ static auto Main(int argc, char** argv) -> int {
return EXIT_FAILURE;
}
// Tests might try to read from stdin. Ensure those reads fail by closing
// stdin and reopening it as /dev/null. Note that STDIN_FILENO doesn't exist
// on Windows, but POSIX requires it to be 0.
llvm::sys::Process::SafelyCloseFileDescriptor(0);
llvm::sys::Process::FixupStandardFileDescriptors();
llvm::SmallVector<std::string> tests = GetTests();
auto test_factory = GetFileTestFactory();
if (absl::GetFlag(FLAGS_autoupdate)) {
llvm::ThreadPool pool({.ThreadsRequested = absl::GetFlag(FLAGS_threads)});
std::mutex errs_mutex;
for (const auto& test_name : tests) {
std::unique_ptr<FileTestBase> test(test_factory.factory_fn(test_name));
auto result = test->Autoupdate();
if (result.ok()) {
llvm::errs() << (*result ? "!" : ".");
} else {
llvm::errs() << result.error().message() << "\n";
}
pool.async([&test_factory, &errs_mutex, test_name] {
std::unique_ptr<FileTestBase> test(test_factory.factory_fn(test_name));
auto result = test->Autoupdate();
// Guard access to llvm::errs, which is not thread-safe.
std::unique_lock<std::mutex> lock(errs_mutex);
if (result.ok()) {
llvm::errs() << (*result ? "!" : ".");
} else {
llvm::errs() << "\n" << result.error().message() << "\n";
}
});
}
pool.wait();
llvm::errs() << "\nDone!\n";
return EXIT_SUCCESS;
} else {
+1 -1
View File
@@ -43,7 +43,7 @@ def main() -> None:
argv.append("--file_tests=" + ",".join(file_tests))
# Provide an empty stdin so that the driver tests that read from stdin
# don't block waiting for input. This matches the behavior of `bazel test`.
subprocess.run(argv, check=True, stdin=subprocess.DEVNULL)
subprocess.run(argv, check=True)
if __name__ == "__main__":