[llvm-branch-commits] [flang] 44e74c7 - [flang][driver] Refactor unit tests for frontend actions (nfc)
Andrzej Warzynski via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Tue Dec 22 05:14:26 PST 2020
Author: Andrzej Warzynski
Date: 2020-12-22T13:06:56Z
New Revision: 44e74c75e614af453f4824cb9bf1f0056d7cf426
URL: https://github.com/llvm/llvm-project/commit/44e74c75e614af453f4824cb9bf1f0056d7cf426
DIFF: https://github.com/llvm/llvm-project/commit/44e74c75e614af453f4824cb9bf1f0056d7cf426.diff
LOG: [flang][driver] Refactor unit tests for frontend actions (nfc)
These patch implements a few non-functional-changes:
* switch to using test fixtures for better code sharing
* rename some variables (e.g. to communicate their purpose a bit better)
This patch doesn't change _what_ is being tested.
Differential Revision: https://reviews.llvm.org/D93544
Added:
Modified:
flang/unittests/Frontend/FrontendActionTest.cpp
Removed:
################################################################################
diff --git a/flang/unittests/Frontend/FrontendActionTest.cpp b/flang/unittests/Frontend/FrontendActionTest.cpp
index b49b7312525a..fb4de6d307cd 100644
--- a/flang/unittests/Frontend/FrontendActionTest.cpp
+++ b/flang/unittests/Frontend/FrontendActionTest.cpp
@@ -8,6 +8,7 @@
#include "gtest/gtest.h"
#include "flang/Frontend/CompilerInstance.h"
+#include "flang/Frontend/CompilerInvocation.h"
#include "flang/Frontend/FrontendOptions.h"
#include "flang/FrontendTool/Utils.h"
#include "llvm/Support/FileSystem.h"
@@ -17,119 +18,120 @@ using namespace Fortran::frontend;
namespace {
-TEST(FrontendAction, PrintPreprocessedInput) {
- std::string inputFile = "pp-test-file.f";
- std::error_code ec;
+class FrontendActionTest : public ::testing::Test {
+protected:
+ // AllSources (which is used to manage files inside every compiler
+ // instance), works with paths. So we need a filename and a path for the
+ // input file.
+ // TODO: We could use `-` for inputFilePath_, but then we'd need a way to
+ // write to stdin that's then read by AllSources. Ideally, AllSources should
+ // be capable of reading from any stream.
+ std::string inputFileName_;
+ std::string inputFilePath_;
+ // The output stream for the input file. Use this to populate the input.
+ std::unique_ptr<llvm::raw_fd_ostream> inputFileOs_;
+
+ std::error_code ec_;
+
+ CompilerInstance compInst_;
+ std::shared_ptr<CompilerInvocation> invocation_;
+
+ void SetUp() override {
+ // Generate a unique test file name.
+ const testing::TestInfo *const test_info =
+ testing::UnitTest::GetInstance()->current_test_info();
+ inputFileName_ = std::string(test_info->name()) + "_test-file.f";
+
+ // Create the input file stream. Note that this stream is populated
+ // separately in every test (i.e. the input is test specific).
+ inputFileOs_ = std::make_unique<llvm::raw_fd_ostream>(
+ inputFileName_, ec_, llvm::sys::fs::OF_None);
+ if (ec_)
+ FAIL() << "Failed to create the input file";
+
+ // Get the path of the input file.
+ llvm::SmallString<256> cwd;
+ if (std::error_code ec_ = llvm::sys::fs::current_path(cwd))
+ FAIL() << "Failed to obtain the current working directory";
+ inputFilePath_ = cwd.c_str();
+ inputFilePath_ += "/" + inputFileName_;
+
+ // Prepare the compiler (CompilerInvocation + CompilerInstance)
+ compInst_.CreateDiagnostics();
+ invocation_ = std::make_shared<CompilerInvocation>();
+
+ compInst_.set_invocation(std::move(invocation_));
+ compInst_.frontendOpts().inputs_.push_back(
+ FrontendInputFile(inputFilePath_, Language::Fortran));
+ }
+
+ void TearDown() override {
+ // Clear the input file.
+ llvm::sys::fs::remove(inputFileName_);
+
+ // Clear the output files.
+ // Note that these tests use an output buffer (as opposed to an output
+ // file), hence there are no physical output files to delete and
+ // `EraseFiles` is set to `false`. Also, some actions (e.g.
+ // `ParseSyntaxOnly`) don't generated output. In such cases there's no
+ // output to clear and `ClearOutputFile` returns immediately.
+ compInst_.ClearOutputFiles(/*EraseFiles=*/false);
+ }
+};
+
+TEST_F(FrontendActionTest, PrintPreprocessedInput) {
+ // Populate the input file with the pre-defined input and flush it.
+ *(inputFileOs_) << "#ifdef NEW\n"
+ << " Program A \n"
+ << "#else\n"
+ << " Program B\n"
+ << "#endif";
+ inputFileOs_.reset();
- // 1. Create the input file for the file manager
- // AllSources (which is used to manage files inside every compiler instance),
- // works with paths. This means that it requires a physical file. Create one.
- std::unique_ptr<llvm::raw_fd_ostream> os{
- new llvm::raw_fd_ostream(inputFile, ec, llvm::sys::fs::OF_None)};
- if (ec)
- FAIL() << "Fail to create the file need by the test";
+ // Set-up the action kind.
+ compInst_.invocation().frontendOpts().programAction_ = PrintPreprocessedInput;
- // Populate the input file with the pre-defined input and flush it.
- *(os) << "! test-file.F:\n"
- << "#ifdef NEW\n"
- << " Program A \n"
- << "#else\n"
- << " Program B\n"
- << "#endif";
- os.reset();
-
- // Get the path of the input file
- llvm::SmallString<64> cwd;
- if (std::error_code ec = llvm::sys::fs::current_path(cwd))
- FAIL() << "Failed to obtain the current working directory";
- std::string testFilePath(cwd.c_str());
- testFilePath += "/" + inputFile;
-
- // 2. Prepare the compiler (CompilerInvocation + CompilerInstance)
- CompilerInstance compInst;
- compInst.CreateDiagnostics();
- auto invocation = std::make_shared<CompilerInvocation>();
- invocation->frontendOpts().programAction_ = PrintPreprocessedInput;
-
- compInst.set_invocation(std::move(invocation));
- compInst.frontendOpts().inputs_.push_back(
- FrontendInputFile(testFilePath, Language::Fortran));
-
- // 3. Set-up the output stream. Using output buffer wrapped as an output
+ // Set-up the output stream. We are using output buffer wrapped as an output
// stream, as opposed to an actual file (or a file descriptor).
llvm::SmallVector<char, 256> outputFileBuffer;
std::unique_ptr<llvm::raw_pwrite_stream> outputFileStream(
new llvm::raw_svector_ostream(outputFileBuffer));
- compInst.set_outputStream(std::move(outputFileStream));
+ compInst_.set_outputStream(std::move(outputFileStream));
- // 4. Run the earlier defined FrontendAction
- bool success = ExecuteCompilerInvocation(&compInst);
+ // Execute the action.
+ bool success = ExecuteCompilerInvocation(&compInst_);
- // 5. Validate the expected output
+ // Validate the expected output.
EXPECT_TRUE(success);
EXPECT_TRUE(!outputFileBuffer.empty());
EXPECT_TRUE(
llvm::StringRef(outputFileBuffer.data()).startswith("program b\n"));
-
- // 6. Clear the input and the output files. Since we used an output buffer,
- // there are no physical output files to delete.
- llvm::sys::fs::remove(inputFile);
- compInst.ClearOutputFiles(/*EraseFiles=*/true);
}
-TEST(FrontendAction, ParseSyntaxOnly) {
- std::string inputFile = "syntax-only-test-file.f";
- std::error_code ec;
+TEST_F(FrontendActionTest, ParseSyntaxOnly) {
+ // Populate the input file with the pre-defined input and flush it.
+ *(inputFileOs_) << "IF (A > 0.0) IF (B < 0.0) A = LOG (A)\n"
+ << "END";
+ inputFileOs_.reset();
- // 1. Create the input file for the file manager
- // AllSources (which is used to manage files inside every compiler instance),
- // works with paths. This means that it requires a physical file. Create one.
- std::unique_ptr<llvm::raw_fd_ostream> os{
- new llvm::raw_fd_ostream(inputFile, ec, llvm::sys::fs::OF_None)};
- if (ec)
- FAIL() << "Fail to create the file need by the test";
+ // Set-up the action kind.
+ compInst_.invocation().frontendOpts().programAction_ = ParseSyntaxOnly;
- // Populate the input file with the pre-defined input and flush it.
- *(os) << "! if_stmt.f90:\n"
- << "IF (A > 0.0) IF (B < 0.0) A = LOG (A)\n"
- << "END";
- os.reset();
-
- // Get the path of the input file
- llvm::SmallString<64> cwd;
- if (std::error_code ec = llvm::sys::fs::current_path(cwd))
- FAIL() << "Failed to obtain the current working directory";
- std::string testFilePath(cwd.c_str());
- testFilePath += "/" + inputFile;
-
- // 2. Prepare the compiler (CompilerInvocation + CompilerInstance)
- CompilerInstance compInst;
- compInst.CreateDiagnostics();
- auto invocation = std::make_shared<CompilerInvocation>();
- invocation->frontendOpts().programAction_ = ParseSyntaxOnly;
-
- compInst.set_invocation(std::move(invocation));
- compInst.frontendOpts().inputs_.push_back(
- FrontendInputFile(testFilePath, Language::Fortran));
-
- // 3. Set-up the output stream for the semantic diagnostics.
+ // Set-up the output stream for the semantic diagnostics.
llvm::SmallVector<char, 256> outputDiagBuffer;
std::unique_ptr<llvm::raw_pwrite_stream> outputStream(
new llvm::raw_svector_ostream(outputDiagBuffer));
- compInst.set_semaOutputStream(std::move(outputStream));
+ compInst_.set_semaOutputStream(std::move(outputStream));
- // 4. Execute the ParseSyntaxOnly action
- bool success = ExecuteCompilerInvocation(&compInst);
+ // Execute the action.
+ bool success = ExecuteCompilerInvocation(&compInst_);
- // 5. Validate the expected output
+ // Validate the expected output.
EXPECT_FALSE(success);
EXPECT_TRUE(!outputDiagBuffer.empty());
EXPECT_TRUE(
llvm::StringRef(outputDiagBuffer.data())
.startswith(
- ":2:14: error: IF statement is not allowed in IF statement\n"));
-
- // 6. Clear the input files.
- llvm::sys::fs::remove(inputFile);
+ ":1:14: error: IF statement is not allowed in IF statement\n"));
}
} // namespace
More information about the llvm-branch-commits
mailing list