[lldb] Add a SubsystemRAII that takes care of calling Initialize and Terminate in the unit tests

Summary:
Many of our tests need to initialize certain subsystems/plugins of LLDB such as
`FileSystem` or `HostInfo` by calling their static `Initialize` functions before the
test starts and then calling `::Terminate` after the test is done (in reverse order).
This adds a lot of error-prone boilerplate code to our testing code.

This patch adds a RAII called SubsystemRAII that ensures that we always call
::Initialize and then call ::Terminate after the test is done (and that the Terminate
calls are always in the reverse order of the ::Initialize calls). It also gets rid of
all of the boilerplate that we had for these calls.

Per-fixture initialization is still not very nice with this approach as it would
require some kind of static unique_ptr that gets manually assigned/reseted
from the gtest SetUpTestCase/TearDownTestCase functions. Because of that
I changed all per-fixture setup to now do per-test setup which can be done
by just having the SubsystemRAII as a member of the test fixture. This change doesn't
influence our normal test runtime as LIT anyway runs each test case separately
(and the Initialize/Terminate calls are anyway not very expensive). It will however
make running all tests in a single executable slightly slower.

Reviewers: labath, JDevlieghere, martong, espindola, shafik

Reviewed By: labath

Subscribers: mgorny, rnkovacs, emaste, MaskRay, abidh, lldb-commits

Tags: #lldb

Differential Revision: https://reviews.llvm.org/D71630
This commit is contained in:
Raphael Isemann 2019-12-23 10:38:12 +01:00
parent 70fa4c4f88
commit 5dca0596a9
27 changed files with 261 additions and 231 deletions

View File

@ -8,6 +8,7 @@
#include "Plugins/ObjectFile/ELF/ObjectFileELF.h"
#include "Plugins/SymbolFile/Symtab/SymbolFileSymtab.h"
#include "TestingSupport/SubsystemRAII.h"
#include "TestingSupport/TestUtilities.h"
#include "lldb/Core/Mangled.h"
@ -58,10 +59,8 @@ TEST(MangledTest, EmptyForInvalidName) {
}
TEST(MangledTest, NameIndexes_FindFunctionSymbols) {
FileSystem::Initialize();
HostInfo::Initialize();
ObjectFileELF::Initialize();
SymbolFileSymtab::Initialize();
SubsystemRAII<FileSystem, HostInfo, ObjectFileELF, SymbolFileSymtab>
subsystems;
auto ExpectedFile = TestFile::fromYaml(R"(
--- !ELF
@ -251,9 +250,4 @@ Symbols:
EXPECT_EQ(0, Count("_Z12undemangableEvx42", eFunctionNameTypeMethod));
EXPECT_EQ(0, Count("undemangable", eFunctionNameTypeBase));
EXPECT_EQ(0, Count("undemangable", eFunctionNameTypeMethod));
SymbolFileSymtab::Terminate();
ObjectFileELF::Terminate();
HostInfo::Terminate();
FileSystem::Terminate();
}

View File

@ -20,6 +20,7 @@
#include <memory>
#include <thread>
#include "TestingSupport/SubsystemRAII.h"
#include "lldb/Host/Editline.h"
#include "lldb/Host/FileSystem.h"
#include "lldb/Host/Pipe.h"
@ -242,7 +243,7 @@ void EditlineAdapter::ConsumeAllOutput() {
}
class EditlineTestFixture : public ::testing::Test {
private:
SubsystemRAII<FileSystem> subsystems;
EditlineAdapter _el_adapter;
std::shared_ptr<std::thread> _sp_output_thread;
@ -253,8 +254,6 @@ public:
}
void SetUp() override {
FileSystem::Initialize();
// Validate the editline adapter.
EXPECT_TRUE(_el_adapter.IsValid());
if (!_el_adapter.IsValid())
@ -269,8 +268,6 @@ public:
_el_adapter.CloseInput();
if (_sp_output_thread)
_sp_output_thread->join();
FileSystem::Terminate();
}
EditlineAdapter &GetEditlineAdapter() { return _el_adapter; }

View File

@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//
#include "Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h"
#include "TestingSupport/SubsystemRAII.h"
#include "TestingSupport/Symbol/ClangTestUtils.h"
#include "lldb/Host/FileSystem.h"
#include "lldb/Host/HostInfo.h"
@ -54,14 +55,7 @@ private:
namespace {
struct ClangExpressionDeclMapTest : public testing::Test {
static void SetUpTestCase() {
FileSystem::Initialize();
HostInfo::Initialize();
}
static void TearDownTestCase() {
HostInfo::Terminate();
FileSystem::Terminate();
}
SubsystemRAII<FileSystem, HostInfo> subsystems;
/// The ClangASTImporter used during the test.
ClangASTImporterSP importer;

View File

@ -9,6 +9,7 @@
#include "clang/Basic/Version.h"
#include "Plugins/ExpressionParser/Clang/ClangHost.h"
#include "TestingSupport/SubsystemRAII.h"
#include "TestingSupport/TestUtilities.h"
#include "lldb/Host/FileSystem.h"
#include "lldb/Host/HostInfo.h"
@ -20,14 +21,7 @@ using namespace lldb_private;
namespace {
struct ClangHostTest : public testing::Test {
static void SetUpTestCase() {
FileSystem::Initialize();
HostInfo::Initialize();
}
static void TearDownTestCase() {
HostInfo::Terminate();
FileSystem::Terminate();
}
SubsystemRAII<FileSystem, HostInfo> subsystems;
};
} // namespace

View File

@ -8,6 +8,7 @@
#include "Plugins/ExpressionParser/Clang/CppModuleConfiguration.h"
#include "Plugins/ExpressionParser/Clang/ClangHost.h"
#include "TestingSupport/SubsystemRAII.h"
#include "lldb/Host/FileSystem.h"
#include "lldb/Host/HostInfo.h"
@ -18,16 +19,7 @@ using namespace lldb_private;
namespace {
struct CppModuleConfigurationTest : public testing::Test {
static void SetUpTestCase() {
// Getting the resource directory uses those subsystems, so we should
// initialize them.
FileSystem::Initialize();
HostInfo::Initialize();
}
static void TearDownTestCase() {
HostInfo::Terminate();
FileSystem::Terminate();
}
SubsystemRAII<FileSystem, HostInfo> subsystems;
};
} // namespace

View File

@ -9,6 +9,7 @@
#include "lldb/Expression/DWARFExpression.h"
#include "../../source/Plugins/SymbolFile/DWARF/DWARFUnit.h"
#include "../../source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h"
#include "TestingSupport/SubsystemRAII.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/Section.h"
#include "lldb/Core/Value.h"
@ -119,6 +120,7 @@ public:
/// Helper class that can construct a module from YAML and evaluate
/// DWARF expressions on it.
class YAMLModuleTester {
SubsystemRAII<FileSystem> subsystems;
llvm::StringMap<std::unique_ptr<llvm::MemoryBuffer>> m_sections_map;
lldb::ModuleSP m_module_sp;
lldb::ObjectFileSP m_objfile_sp;
@ -128,8 +130,6 @@ class YAMLModuleTester {
public:
/// Parse the debug info sections from the YAML description.
YAMLModuleTester(llvm::StringRef yaml_data, llvm::StringRef triple) {
FileSystem::Initialize();
auto sections_map = llvm::DWARFYAML::EmitDebugSections(yaml_data, true);
if (!sections_map)
return;
@ -153,7 +153,6 @@ public:
if (dwarf_unit)
m_dwarf_unit = dwarf_unit.get();
}
~YAMLModuleTester() { FileSystem::Terminate(); }
DWARFUnitSP GetDwarfUnit() { return m_dwarf_unit; }
// Evaluate a raw DWARF expression.

View File

@ -9,6 +9,7 @@
#include "SocketTestUtilities.h"
#include "gtest/gtest.h"
#include "TestingSupport/SubsystemRAII.h"
#include "lldb/Host/posix/ConnectionFileDescriptorPosix.h"
#include "lldb/Utility/UriParser.h"
@ -16,11 +17,7 @@ using namespace lldb_private;
class ConnectionFileDescriptorTest : public testing::Test {
public:
void SetUp() override {
ASSERT_THAT_ERROR(Socket::Initialize(), llvm::Succeeded());
}
void TearDown() override { Socket::Terminate(); }
SubsystemRAII<Socket> subsystems;
void TestGetURI(std::string ip) {
std::unique_ptr<TCPSocket> socket_a_up;

View File

@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//
#include "lldb/Host/HostInfo.h"
#include "TestingSupport/SubsystemRAII.h"
#include "TestingSupport/TestUtilities.h"
#include "lldb/Host/FileSystem.h"
#include "lldb/lldb-defines.h"
@ -17,15 +18,7 @@ using namespace llvm;
namespace {
class HostInfoTest : public ::testing::Test {
public:
void SetUp() override {
FileSystem::Initialize();
HostInfo::Initialize();
}
void TearDown() override {
HostInfo::Terminate();
FileSystem::Terminate();
}
SubsystemRAII<FileSystem, HostInfo> subsystems;
};
} // namespace

View File

@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//
#include "lldb/Host/MainLoop.h"
#include "TestingSupport/SubsystemRAII.h"
#include "lldb/Host/ConnectionFileDescriptor.h"
#include "lldb/Host/PseudoTerminal.h"
#include "lldb/Host/common/TCPSocket.h"
@ -19,11 +20,7 @@ using namespace lldb_private;
namespace {
class MainLoopTest : public testing::Test {
public:
static void SetUpTestCase() {
ASSERT_THAT_ERROR(Socket::Initialize(), llvm::Succeeded());
}
static void TearDownTestCase() { Socket::Terminate(); }
SubsystemRAII<Socket> subsystems;
void SetUp() override {
bool child_processes_inherit = false;

View File

@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//
#include "lldb/Host/SocketAddress.h"
#include "TestingSupport/SubsystemRAII.h"
#include "lldb/Host/Socket.h"
#include "llvm/Testing/Support/Error.h"
@ -17,10 +18,7 @@ using namespace lldb_private;
namespace {
class SocketAddressTest : public testing::Test {
public:
static void SetUpTestCase() {
ASSERT_THAT_ERROR(Socket::Initialize(), llvm::Succeeded());
}
static void TearDownTestCase() { Socket::Terminate(); }
SubsystemRAII<Socket> subsystems;
};
} // namespace

View File

@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//
#include "SocketTestUtilities.h"
#include "TestingSupport/SubsystemRAII.h"
#include "lldb/Host/Config.h"
#include "lldb/Utility/UriParser.h"
#include "gtest/gtest.h"
@ -15,11 +16,7 @@ using namespace lldb_private;
class SocketTest : public testing::Test {
public:
void SetUp() override {
ASSERT_THAT_ERROR(Socket::Initialize(), llvm::Succeeded());
}
void TearDown() override { Socket::Terminate(); }
SubsystemRAII<Socket> subsystems;
};
TEST_F(SocketTest, DecodeHostAndPort) {

View File

@ -15,6 +15,7 @@
#include "gtest/gtest.h"
#include "TestingSupport/MockTildeExpressionResolver.h"
#include "TestingSupport/SubsystemRAII.h"
#include "TestingSupport/TestUtilities.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/Support/FileSystem.h"
@ -29,6 +30,8 @@ using namespace lldb_private;
namespace {
class CompletionTest : public testing::Test {
SubsystemRAII<FileSystem> subsystems;
protected:
/// Unique temporary directory in which all created filesystem entities must
/// be placed. It is removed at the end of the test suite.
@ -56,8 +59,6 @@ protected:
SmallString<128> FileBaz;
void SetUp() override {
FileSystem::Initialize();
// chdir back into the original working dir this test binary started with.
// A previous test may have have changed the working dir.
ASSERT_NO_ERROR(fs::set_current_path(OriginalWorkingDir));
@ -100,7 +101,6 @@ protected:
void TearDown() override {
ASSERT_NO_ERROR(fs::remove_directories(BaseDir));
FileSystem::Terminate();
}
static bool HasEquivalentFile(const Twine &Path, const StringList &Paths) {

View File

@ -14,33 +14,18 @@
#include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h"
#include "Plugins/Language/ObjC/ObjCLanguage.h"
#include "Plugins/Language/ObjCPlusPlus/ObjCPlusPlusLanguage.h"
#include "TestingSupport/SubsystemRAII.h"
using namespace lldb_private;
namespace {
class HighlighterTest : public testing::Test {
public:
static void SetUpTestCase();
static void TearDownTestCase();
SubsystemRAII<FileSystem, CPlusPlusLanguage, ObjCLanguage,
ObjCPlusPlusLanguage>
subsystems;
};
} // namespace
void HighlighterTest::SetUpTestCase() {
// The HighlighterManager uses the language plugins under the hood, so we
// have to initialize them here for our test process.
FileSystem::Initialize();
CPlusPlusLanguage::Initialize();
ObjCLanguage::Initialize();
ObjCPlusPlusLanguage::Initialize();
}
void HighlighterTest::TearDownTestCase() {
CPlusPlusLanguage::Terminate();
ObjCLanguage::Terminate();
ObjCPlusPlusLanguage::Terminate();
FileSystem::Terminate();
}
static std::string getName(lldb::LanguageType type) {
HighlighterManager m;
return m.getHighlighterFor(type, "").GetName().str();

View File

@ -9,6 +9,7 @@
#include "Plugins/ObjectFile/ELF/ObjectFileELF.h"
#include "Plugins/SymbolFile/Symtab/SymbolFileSymtab.h"
#include "TestingSupport/SubsystemRAII.h"
#include "TestingSupport/TestUtilities.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleSpec.h"
@ -29,22 +30,8 @@ using namespace lldb_private;
using namespace lldb;
class ObjectFileELFTest : public testing::Test {
public:
void SetUp() override {
FileSystem::Initialize();
HostInfo::Initialize();
ObjectFileELF::Initialize();
SymbolFileSymtab::Initialize();
}
void TearDown() override {
SymbolFileSymtab::Terminate();
ObjectFileELF::Terminate();
HostInfo::Terminate();
FileSystem::Terminate();
}
protected:
SubsystemRAII<FileSystem, HostInfo, ObjectFileELF, SymbolFileSymtab>
subsystems;
};
TEST_F(ObjectFileELFTest, SectionsResolveConsistently) {

View File

@ -11,6 +11,7 @@
#include "Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h"
#include "Plugins/Process/Utility/lldb-x86-register-enums.h"
#include "TestingSupport/SubsystemRAII.h"
#include "TestingSupport/TestUtilities.h"
#include "lldb/Core/Module.h"
@ -22,16 +23,7 @@ using namespace lldb_private;
using namespace lldb;
class PECallFrameInfoTest : public testing::Test {
public:
void SetUp() override {
FileSystem::Initialize();
ObjectFilePECOFF::Initialize();
}
void TearDown() override {
ObjectFilePECOFF::Terminate();
FileSystem::Terminate();
}
SubsystemRAII<FileSystem, ObjectFilePECOFF> subsystems;
protected:
void GetUnwindPlan(addr_t file_addr, UnwindPlan &plan) const;

View File

@ -10,6 +10,7 @@
#include "Plugins/Process/minidump/MinidumpTypes.h"
#include "Plugins/Process/minidump/RegisterContextMinidump_x86_32.h"
#include "Plugins/Process/minidump/RegisterContextMinidump_x86_64.h"
#include "TestingSupport/SubsystemRAII.h"
#include "TestingSupport/TestUtilities.h"
#include "lldb/Host/FileSystem.h"
#include "lldb/Target/MemoryRegionInfo.h"
@ -37,9 +38,7 @@ using namespace minidump;
class MinidumpParserTest : public testing::Test {
public:
void SetUp() override { FileSystem::Initialize(); }
void TearDown() override { FileSystem::Terminate(); }
SubsystemRAII<FileSystem> subsystems;
void SetUpData(const char *minidump_filename) {
std::string filename = GetInputFilePath(minidump_filename);

View File

@ -8,6 +8,7 @@
#include "gtest/gtest.h"
#include "TestingSupport/SubsystemRAII.h"
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Host/FileSystem.h"
#include "lldb/Host/HostInfo.h"
@ -19,14 +20,7 @@ using namespace lldb_private;
namespace {
class SymbolsTest : public ::testing::Test {
public:
void SetUp() override {
FileSystem::Initialize();
HostInfo::Initialize();
}
void TearDown() override {
HostInfo::Terminate();
FileSystem::Terminate();
}
SubsystemRAII<FileSystem, HostInfo> subsystems;
};
} // namespace

View File

@ -6,6 +6,7 @@
//
//===----------------------------------------------------------------------===//
#include "TestingSupport/SubsystemRAII.h"
#include "lldb/Host/FileSystem.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Symbol/ClangASTContext.h"
@ -21,15 +22,7 @@ using namespace lldb_private;
class TestClangASTContext : public testing::Test {
public:
static void SetUpTestCase() {
FileSystem::Initialize();
HostInfo::Initialize();
}
static void TearDownTestCase() {
HostInfo::Terminate();
FileSystem::Terminate();
}
SubsystemRAII<FileSystem, HostInfo> subsystems;
void SetUp() override {
std::string triple = HostInfo::GetTargetTriple();

View File

@ -8,6 +8,7 @@
#include "gtest/gtest.h"
#include "TestingSupport/SubsystemRAII.h"
#include "TestingSupport/Symbol/ClangTestUtils.h"
#include "lldb/Host/FileSystem.h"
#include "lldb/Host/HostInfo.h"
@ -24,15 +25,7 @@ using namespace lldb_private;
class TestClangASTImporter : public testing::Test {
public:
static void SetUpTestCase() {
FileSystem::Initialize();
HostInfo::Initialize();
}
static void TearDownTestCase() {
HostInfo::Terminate();
FileSystem::Terminate();
}
SubsystemRAII<FileSystem, HostInfo> subsystems;
};
TEST_F(TestClangASTImporter, CanImportInvalidType) {

View File

@ -12,6 +12,7 @@
#include "Plugins/ObjectFile/ELF/ObjectFileELF.h"
#include "Plugins/Process/Utility/RegisterContext_x86.h"
#include "Plugins/SymbolFile/Symtab/SymbolFileSymtab.h"
#include "TestingSupport/SubsystemRAII.h"
#include "TestingSupport/TestUtilities.h"
#include "lldb/Core/Module.h"
@ -32,20 +33,8 @@ using namespace lldb_private;
using namespace lldb;
class DWARFCallFrameInfoTest : public testing::Test {
public:
void SetUp() override {
FileSystem::Initialize();
HostInfo::Initialize();
ObjectFileELF::Initialize();
SymbolFileSymtab::Initialize();
}
void TearDown() override {
SymbolFileSymtab::Terminate();
ObjectFileELF::Terminate();
HostInfo::Terminate();
FileSystem::Terminate();
}
SubsystemRAII<FileSystem, HostInfo, ObjectFileELF, SymbolFileSymtab>
subsystems;
protected:
void TestBasic(DWARFCallFrameInfo::Type type, llvm::StringRef symbol);

View File

@ -14,6 +14,7 @@
#include "Plugins/ObjectFile/Mach-O/ObjectFileMachO.h"
#include "Plugins/SymbolFile/DWARF/DWARFASTParserClang.h"
#include "Plugins/SymbolFile/DWARF/SymbolFileDWARF.h"
#include "TestingSupport/SubsystemRAII.h"
#include "TestingSupport/TestUtilities.h"
#include "lldb/Symbol/ClangASTContext.h"
@ -31,17 +32,13 @@ using namespace lldb_private;
using namespace lldb;
class LineEntryTest : public testing::Test {
SubsystemRAII<FileSystem, HostInfo, ObjectFileMachO, SymbolFileDWARF,
ClangASTContext>
subsystem;
public:
void SetUp() override;
void TearDown() override {
ClangASTContext::Terminate();
SymbolFileDWARF::Terminate();
ObjectFileMachO::Terminate();
HostInfo::Terminate();
FileSystem::Terminate();
}
protected:
llvm::Expected<LineEntry> GetLineEntryForLine(uint32_t line);
llvm::Optional<TestFile> m_file;
@ -49,11 +46,6 @@ protected:
};
void LineEntryTest::SetUp() {
FileSystem::Initialize();
HostInfo::Initialize();
ObjectFileMachO::Initialize();
SymbolFileDWARF::Initialize();
ClangASTContext::Initialize();
auto ExpectedFile = TestFile::fromYamlFile("inlined-functions.yaml");
ASSERT_THAT_EXPECTED(ExpectedFile, llvm::Succeeded());
m_file.emplace(std::move(*ExpectedFile));

View File

@ -6,26 +6,17 @@
//
//===----------------------------------------------------------------------===//
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "Plugins/SymbolFile/DWARF/DWARFASTParserClang.h"
#include "Plugins/SymbolFile/DWARF/DWARFDIE.h"
#include "TestingSupport/SubsystemRAII.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
using namespace lldb;
using namespace lldb_private;
class DWARFASTParserClangTests : public testing::Test {
public:
void SetUp() override {
FileSystem::Initialize();
ClangASTContext::Initialize();
}
void TearDown() override {
ClangASTContext::Terminate();
FileSystem::Terminate();
}
SubsystemRAII<FileSystem, ClangASTContext> subsystems;
};
namespace {

View File

@ -20,6 +20,7 @@
#include "Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.h"
#include "Plugins/SymbolFile/DWARF/SymbolFileDWARF.h"
#include "Plugins/SymbolFile/PDB/SymbolFilePDB.h"
#include "TestingSupport/SubsystemRAII.h"
#include "TestingSupport/TestUtilities.h"
#include "lldb/Core/Address.h"
#include "lldb/Core/Module.h"
@ -40,28 +41,13 @@ using namespace lldb;
using namespace lldb_private;
class SymbolFileDWARFTests : public testing::Test {
SubsystemRAII<FileSystem, HostInfo, ObjectFilePECOFF, SymbolFileDWARF,
ClangASTContext, SymbolFilePDB>
subsystems;
public:
void SetUp() override {
// Initialize and TearDown the plugin every time, so we get a brand new
// AST every time so that modifications to the AST from each test don't
// leak into the next test.
FileSystem::Initialize();
HostInfo::Initialize();
ObjectFilePECOFF::Initialize();
SymbolFileDWARF::Initialize();
ClangASTContext::Initialize();
SymbolFilePDB::Initialize();
m_dwarf_test_exe = GetInputFilePath("test-dwarf.exe");
}
void TearDown() override {
SymbolFilePDB::Terminate();
ClangASTContext::Initialize();
SymbolFileDWARF::Terminate();
ObjectFilePECOFF::Terminate();
HostInfo::Terminate();
FileSystem::Terminate();
m_dwarf_test_exe = GetInputFilePath("test-dwarf.exe");
}
protected:

View File

@ -6,6 +6,7 @@
#include "Plugins/ObjectFile/ELF/ObjectFileELF.h"
#include "Plugins/SymbolFile/Symtab/SymbolFileSymtab.h"
#include "TestingSupport/SubsystemRAII.h"
#include "TestingSupport/TestUtilities.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleSpec.h"
@ -20,23 +21,21 @@ using namespace lldb;
namespace {
class ModuleCacheTest : public testing::Test {
public:
static void SetUpTestCase();
SubsystemRAII<FileSystem, HostInfo, ObjectFileELF, SymbolFileSymtab>
subsystems;
static void TearDownTestCase();
public:
void SetUp() override;
protected:
static FileSpec s_cache_dir;
static std::string s_test_executable;
FileSpec s_cache_dir;
std::string s_test_executable;
void TryGetAndPut(const FileSpec &cache_dir, const char *hostname,
bool expect_download);
};
}
FileSpec ModuleCacheTest::s_cache_dir;
std::string ModuleCacheTest::s_test_executable;
static const char dummy_hostname[] = "dummy_hostname";
static const char dummy_remote_dir[] = "bin";
static const char module_name[] = "TestModule.so";
@ -66,23 +65,11 @@ static FileSpec GetSysrootView(FileSpec spec, const char *hostname) {
return spec;
}
void ModuleCacheTest::SetUpTestCase() {
FileSystem::Initialize();
HostInfo::Initialize();
ObjectFileELF::Initialize();
SymbolFileSymtab::Initialize();
void ModuleCacheTest::SetUp() {
s_cache_dir = HostInfo::GetProcessTempDir();
s_test_executable = GetInputFilePath(module_name);
}
void ModuleCacheTest::TearDownTestCase() {
SymbolFileSymtab::Terminate();
ObjectFileELF::Terminate();
HostInfo::Terminate();
FileSystem::Terminate();
}
static void VerifyDiskState(const FileSpec &cache_dir, const char *hostname) {
FileSpec uuid_view = GetUuidView(cache_dir);
EXPECT_TRUE(FileSystem::Instance().Exists(uuid_view))
@ -108,8 +95,8 @@ void ModuleCacheTest::TryGetAndPut(const FileSpec &cache_dir,
Status error = mc.GetAndPut(
cache_dir, hostname, module_spec,
[&download_called](const ModuleSpec &module_spec,
const FileSpec &tmp_download_file_spec) {
[&download_called, this](const ModuleSpec &module_spec,
const FileSpec &tmp_download_file_spec) {
download_called = true;
EXPECT_STREQ(GetDummyRemotePath().GetCString(),
module_spec.GetFileSpec().GetCString());

View File

@ -0,0 +1,90 @@
//===- SubsystemRAII.h ------------------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef LLDB_UNITTESTS_TESTINGSUPPORT_SUBSYSTEMRAII_H
#define LLDB_UNITTESTS_TESTINGSUPPORT_SUBSYSTEMRAII_H
#include "llvm/Support/Error.h"
#include "llvm/Testing/Support/Error.h"
#include "gtest/gtest.h"
#include <type_traits>
namespace lldb_private {
namespace detail {
/// Initializes and deinitializes a single subsystem.
/// @see SubsystemRAII
template <typename T> struct SubsystemRAIICase {
/// Calls ::Initialize if it has a void return type.
template <typename U = T>
typename std::enable_if<
std::is_same<decltype(U::Initialize()), void>::value>::type
CallInitialize() {
T::Initialize();
}
/// Calls ::Initialize if it has a llvm::Error return type and checks
/// the Error instance for success.
template <typename U = T>
typename std::enable_if<
std::is_same<decltype(U::Initialize()), llvm::Error>::value>::type
CallInitialize() {
ASSERT_THAT_ERROR(T::Initialize(), llvm::Succeeded());
}
SubsystemRAIICase() { CallInitialize(); }
~SubsystemRAIICase() { T::Terminate(); }
};
} // namespace detail
template <typename... T> class SubsystemRAII {};
/// RAII for initializing and deinitializing LLDB subsystems.
///
/// This RAII takes care of calling the Initialize and Terminate functions for
/// the subsystems specified by its template arguments. The ::Initialize
/// functions are called on construction for each subsystem template parameter
/// in the order in which they are passed as template parameters.
/// The ::Terminate functions are called in the reverse order at destruction
/// time.
///
/// If the ::Initialize function returns an llvm::Error this function handles
/// the Error instance (by checking that there is no error).
///
/// Constructing this RAII in a scope like this:
///
/// @code{.cpp}
/// {
/// SubsystemRAII<FileSystem, HostInfo, Socket> Subsystems;
/// DoingTestWork();
/// }
/// @endcode
///
/// is equivalent to the following code:
///
/// @code{.cpp}
/// {
/// FileSystem::Initialize();
/// HostInfo::Initialize();
/// ASSERT_THAT_ERROR(Socket::Initialize(), llvm::Succeeded());
///
/// DoingTestWork();
///
/// Socket::Terminate();
/// FileSystem::Terminate();
/// HostInfo::Terminate();
/// }
/// @endcode
template <typename T, typename... Ts> class SubsystemRAII<T, Ts...> {
detail::SubsystemRAIICase<T> CurrentSubsystem;
SubsystemRAII<Ts...> RemainingSubsystems;
};
} // namespace lldb_private
#endif // LLDB_UNITTESTS_TESTINGSUPPORT_SUBSYSTEMRAII_H

View File

@ -32,6 +32,7 @@ add_lldb_unittest(UtilityTests
StringLexerTest.cpp
StringListTest.cpp
StructuredDataTest.cpp
SubsystemRAIITest.cpp
TildeExpressionResolverTest.cpp
TimeoutTest.cpp
TimerTest.cpp

View File

@ -0,0 +1,99 @@
//===-- SubsystemRAIITest.cpp -----------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "gtest/gtest-spi.h"
#include "gtest/gtest.h"
#include "TestingSupport/SubsystemRAII.h"
using namespace lldb_private;
namespace {
enum class SystemState {
/// Start state of the subsystem.
Start,
/// Initialize has been called but Terminate hasn't been called yet.
Initialized,
/// Terminate has been called.
Terminated
};
struct TestSubsystem {
static SystemState state;
static void Initialize() {
assert(state == SystemState::Start);
state = SystemState::Initialized;
}
static void Terminate() {
assert(state == SystemState::Initialized);
state = SystemState::Terminated;
}
};
} // namespace
SystemState TestSubsystem::state = SystemState::Start;
TEST(SubsystemRAIITest, NormalSubsystem) {
// Tests that SubsystemRAII handles Initialize functions that return void.
EXPECT_EQ(SystemState::Start, TestSubsystem::state);
{
SubsystemRAII<TestSubsystem> subsystem;
EXPECT_EQ(SystemState::Initialized, TestSubsystem::state);
}
EXPECT_EQ(SystemState::Terminated, TestSubsystem::state);
}
static const char *SubsystemErrorString = "Initialize failed";
namespace {
struct TestSubsystemWithError {
static SystemState state;
static bool will_fail;
static llvm::Error Initialize() {
assert(state == SystemState::Start);
state = SystemState::Initialized;
if (will_fail)
return llvm::make_error<llvm::StringError>(
SubsystemErrorString, llvm::inconvertibleErrorCode());
return llvm::Error::success();
}
static void Terminate() {
assert(state == SystemState::Initialized);
state = SystemState::Terminated;
}
/// Reset the subsystem to the default state for testing.
static void Reset() { state = SystemState::Start; }
};
} // namespace
SystemState TestSubsystemWithError::state = SystemState::Start;
bool TestSubsystemWithError::will_fail = false;
TEST(SubsystemRAIITest, SubsystemWithErrorSuccess) {
// Tests that SubsystemRAII handles llvm::success() returned from
// Initialize.
TestSubsystemWithError::Reset();
EXPECT_EQ(SystemState::Start, TestSubsystemWithError::state);
{
TestSubsystemWithError::will_fail = false;
SubsystemRAII<TestSubsystemWithError> subsystem;
EXPECT_EQ(SystemState::Initialized, TestSubsystemWithError::state);
}
EXPECT_EQ(SystemState::Terminated, TestSubsystemWithError::state);
}
TEST(SubsystemRAIITest, SubsystemWithErrorFailure) {
// Tests that SubsystemRAII handles any errors returned from
// Initialize.
TestSubsystemWithError::Reset();
EXPECT_EQ(SystemState::Start, TestSubsystemWithError::state);
TestSubsystemWithError::will_fail = true;
EXPECT_FATAL_FAILURE(SubsystemRAII<TestSubsystemWithError> subsystem,
SubsystemErrorString);
}