Index: lldb/unittests/Core/MangledTest.cpp =================================================================== --- lldb/unittests/Core/MangledTest.cpp +++ lldb/unittests/Core/MangledTest.cpp @@ -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, NameIndexes_FindFunctionSymbols) { - FileSystem::Initialize(); - HostInfo::Initialize(); - ObjectFileELF::Initialize(); - SymbolFileSymtab::Initialize(); + SubsystemRAII + Subsystems; auto ExpectedFile = TestFile::fromYaml(R"( --- !ELF @@ -251,9 +250,4 @@ 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(); } Index: lldb/unittests/Editline/EditlineTest.cpp =================================================================== --- lldb/unittests/Editline/EditlineTest.cpp +++ lldb/unittests/Editline/EditlineTest.cpp @@ -20,6 +20,7 @@ #include #include +#include "TestingSupport/SubsystemRAII.h" #include "lldb/Host/Editline.h" #include "lldb/Host/FileSystem.h" #include "lldb/Host/Pipe.h" @@ -242,7 +243,7 @@ } class EditlineTestFixture : public ::testing::Test { -private: + SubsystemRAII subsystems; EditlineAdapter _el_adapter; std::shared_ptr _sp_output_thread; @@ -253,8 +254,6 @@ } void SetUp() override { - FileSystem::Initialize(); - // Validate the editline adapter. EXPECT_TRUE(_el_adapter.IsValid()); if (!_el_adapter.IsValid()) @@ -269,8 +268,6 @@ _el_adapter.CloseInput(); if (_sp_output_thread) _sp_output_thread->join(); - - FileSystem::Terminate(); } EditlineAdapter &GetEditlineAdapter() { return _el_adapter; } Index: lldb/unittests/Expression/ClangParserTest.cpp =================================================================== --- lldb/unittests/Expression/ClangParserTest.cpp +++ lldb/unittests/Expression/ClangParserTest.cpp @@ -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 @@ namespace { struct ClangHostTest : public testing::Test { - static void SetUpTestCase() { - FileSystem::Initialize(); - HostInfo::Initialize(); - } - static void TearDownTestCase() { - HostInfo::Terminate(); - FileSystem::Terminate(); - } + SubsystemRAII subsystems; }; } // namespace Index: lldb/unittests/Expression/CppModuleConfigurationTest.cpp =================================================================== --- lldb/unittests/Expression/CppModuleConfigurationTest.cpp +++ lldb/unittests/Expression/CppModuleConfigurationTest.cpp @@ -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 @@ 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 subsystems; }; } // namespace Index: lldb/unittests/Expression/DWARFExpressionTest.cpp =================================================================== --- lldb/unittests/Expression/DWARFExpressionTest.cpp +++ lldb/unittests/Expression/DWARFExpressionTest.cpp @@ -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 @@ /// Helper class that can construct a module from YAML and evaluate /// DWARF expressions on it. class YAMLModuleTester { + SubsystemRAII subsystems; llvm::StringMap> m_sections_map; lldb::ModuleSP m_module_sp; lldb::ObjectFileSP m_objfile_sp; @@ -128,8 +130,6 @@ 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 @@ if (dwarf_unit) m_dwarf_unit = dwarf_unit.get(); } - ~YAMLModuleTester() { FileSystem::Terminate(); } DWARFUnitSP GetDwarfUnit() { return m_dwarf_unit; } // Evaluate a raw DWARF expression. Index: lldb/unittests/Host/HostInfoTest.cpp =================================================================== --- lldb/unittests/Host/HostInfoTest.cpp +++ lldb/unittests/Host/HostInfoTest.cpp @@ -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 @@ namespace { class HostInfoTest : public ::testing::Test { -public: - void SetUp() override { - FileSystem::Initialize(); - HostInfo::Initialize(); - } - void TearDown() override { - HostInfo::Terminate(); - FileSystem::Terminate(); - } + SubsystemRAII subsystems; }; } // namespace Index: lldb/unittests/Host/MainLoopTest.cpp =================================================================== --- lldb/unittests/Host/MainLoopTest.cpp +++ lldb/unittests/Host/MainLoopTest.cpp @@ -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 @@ namespace { class MainLoopTest : public testing::Test { public: - static void SetUpTestCase() { - ASSERT_THAT_ERROR(Socket::Initialize(), llvm::Succeeded()); - } - - static void TearDownTestCase() { Socket::Terminate(); } + SubsystemRAII subsystems; void SetUp() override { bool child_processes_inherit = false; Index: lldb/unittests/Interpreter/TestCompletion.cpp =================================================================== --- lldb/unittests/Interpreter/TestCompletion.cpp +++ lldb/unittests/Interpreter/TestCompletion.cpp @@ -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 @@ namespace { class CompletionTest : public testing::Test { + SubsystemRAII 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 @@ 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 @@ void TearDown() override { ASSERT_NO_ERROR(fs::remove_directories(BaseDir)); - FileSystem::Terminate(); } static bool HasEquivalentFile(const Twine &Path, const StringList &Paths) { Index: lldb/unittests/Language/Highlighting/HighlighterTest.cpp =================================================================== --- lldb/unittests/Language/Highlighting/HighlighterTest.cpp +++ lldb/unittests/Language/Highlighting/HighlighterTest.cpp @@ -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 + 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(); Index: lldb/unittests/ObjectFile/ELF/TestObjectFileELF.cpp =================================================================== --- lldb/unittests/ObjectFile/ELF/TestObjectFileELF.cpp +++ lldb/unittests/ObjectFile/ELF/TestObjectFileELF.cpp @@ -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; 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 + subsystems; }; TEST_F(ObjectFileELFTest, SectionsResolveConsistently) { Index: lldb/unittests/ObjectFile/PECOFF/TestPECallFrameInfo.cpp =================================================================== --- lldb/unittests/ObjectFile/PECOFF/TestPECallFrameInfo.cpp +++ lldb/unittests/ObjectFile/PECOFF/TestPECallFrameInfo.cpp @@ -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; class PECallFrameInfoTest : public testing::Test { -public: - void SetUp() override { - FileSystem::Initialize(); - ObjectFilePECOFF::Initialize(); - } - - void TearDown() override { - ObjectFilePECOFF::Terminate(); - FileSystem::Terminate(); - } + SubsystemRAII subsystems; protected: void GetUnwindPlan(addr_t file_addr, UnwindPlan &plan) const; Index: lldb/unittests/Symbol/TestClangASTImporter.cpp =================================================================== --- lldb/unittests/Symbol/TestClangASTImporter.cpp +++ lldb/unittests/Symbol/TestClangASTImporter.cpp @@ -6,6 +6,7 @@ // //===----------------------------------------------------------------------===// +#include "TestingSupport/SubsystemRAII.h" #include "gtest/gtest.h" #include "lldb/Host/FileSystem.h" @@ -22,16 +23,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 Subsystems; protected: std::unique_ptr createAST() { Index: lldb/unittests/Symbol/TestDWARFCallFrameInfo.cpp =================================================================== --- lldb/unittests/Symbol/TestDWARFCallFrameInfo.cpp +++ lldb/unittests/Symbol/TestDWARFCallFrameInfo.cpp @@ -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; 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 + subsystems; protected: void TestBasic(DWARFCallFrameInfo::Type type, llvm::StringRef symbol); Index: lldb/unittests/Symbol/TestLineEntry.cpp =================================================================== --- lldb/unittests/Symbol/TestLineEntry.cpp +++ lldb/unittests/Symbol/TestLineEntry.cpp @@ -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; class LineEntryTest : public testing::Test { + SubsystemRAII + subsystem; + public: void SetUp() override; - void TearDown() override { - ClangASTContext::Terminate(); - SymbolFileDWARF::Terminate(); - ObjectFileMachO::Terminate(); - HostInfo::Terminate(); - FileSystem::Terminate(); - } - protected: llvm::Expected GetLineEntryForLine(uint32_t line); llvm::Optional m_file; @@ -49,11 +46,6 @@ }; 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)); Index: lldb/unittests/SymbolFile/DWARF/DWARFASTParserClangTests.cpp =================================================================== --- lldb/unittests/SymbolFile/DWARF/DWARFASTParserClangTests.cpp +++ lldb/unittests/SymbolFile/DWARF/DWARFASTParserClangTests.cpp @@ -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 subsystems; }; namespace { Index: lldb/unittests/SymbolFile/DWARF/SymbolFileDWARFTests.cpp =================================================================== --- lldb/unittests/SymbolFile/DWARF/SymbolFileDWARFTests.cpp +++ lldb/unittests/SymbolFile/DWARF/SymbolFileDWARFTests.cpp @@ -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_private; class SymbolFileDWARFTests : public testing::Test { + SubsystemRAII + 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: Index: lldb/unittests/Target/ModuleCacheTest.cpp =================================================================== --- lldb/unittests/Target/ModuleCacheTest.cpp +++ lldb/unittests/Target/ModuleCacheTest.cpp @@ -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 @@ namespace { class ModuleCacheTest : public testing::Test { -public: - static void SetUpTestCase(); + SubsystemRAII + 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 @@ 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 @@ 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()); Index: lldb/unittests/TestingSupport/SubsystemRAII.h =================================================================== --- /dev/null +++ lldb/unittests/TestingSupport/SubsystemRAII.h @@ -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 + +namespace lldb_private { + +namespace detail { +/// Initializes and deinitializes a single subsystem. +/// @see SubsystemRAII +template struct SubsystemRAIICase { + + /// Calls ::Initialize if it has a void return type. + template + typename std::enable_if< + std::is_same::value>::type + CallInitialize() { + T::Initialize(); + } + + /// Calls ::Initialize if it has a llvm::Error return type and checks + /// the Error instance for success. + template + typename std::enable_if< + std::is_same::value>::type + CallInitialize() { + ASSERT_THAT_ERROR(T::Initialize(), llvm::Succeeded()); + } + + SubsystemRAIICase() { CallInitialize(); } + ~SubsystemRAIICase() { T::Terminate(); } +}; +} // namespace detail + +template 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 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 class SubsystemRAII { + detail::SubsystemRAIICase CurrentSubsystem; + SubsystemRAII RemainingSubsystems; +}; +} // namespace lldb_private + +#endif // LLDB_UNITTESTS_TESTINGSUPPORT_SUBSYSTEMRAII_H Index: lldb/unittests/Utility/CMakeLists.txt =================================================================== --- lldb/unittests/Utility/CMakeLists.txt +++ lldb/unittests/Utility/CMakeLists.txt @@ -32,6 +32,7 @@ StringLexerTest.cpp StringListTest.cpp StructuredDataTest.cpp + SubsystemRAIITest.cpp TildeExpressionResolverTest.cpp TimeoutTest.cpp TimerTest.cpp Index: lldb/unittests/Utility/SubsystemRAIITest.cpp =================================================================== --- /dev/null +++ lldb/unittests/Utility/SubsystemRAIITest.cpp @@ -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 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( + 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 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 subsystem, + SubsystemErrorString); +}