| #include "gtest/gtest.h" |
| |
| #include "llvm/ADT/SmallString.h" |
| #include "llvm/Support/FileSystem.h" |
| #include "llvm/Support/Path.h" |
| |
| #include "Plugins/ObjectFile/ELF/ObjectFileELF.h" |
| #include "lldb/Core/Module.h" |
| #include "lldb/Core/ModuleSpec.h" |
| #include "lldb/Host/HostInfo.h" |
| #include "lldb/Symbol/SymbolContext.h" |
| #include "lldb/Target/ModuleCache.h" |
| #include "TestingSupport/TestUtilities.h" |
| |
| using namespace lldb_private; |
| using namespace lldb; |
| |
| namespace { |
| |
| class ModuleCacheTest : public testing::Test { |
| public: |
| static void SetUpTestCase(); |
| |
| static void TearDownTestCase(); |
| |
| protected: |
| static FileSpec s_cache_dir; |
| static 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"; |
| static const char module_uuid[] = |
| "F4E7E991-9B61-6AD4-0073-561AC3D9FA10-C043A476"; |
| static const uint32_t uuid_bytes = 20; |
| static const size_t module_size = 5602; |
| |
| static FileSpec GetDummyRemotePath() { |
| FileSpec fs("/", false, FileSpec::Style::posix); |
| fs.AppendPathComponent(dummy_remote_dir); |
| fs.AppendPathComponent(module_name); |
| return fs; |
| } |
| |
| static FileSpec GetUuidView(FileSpec spec) { |
| spec.AppendPathComponent(".cache"); |
| spec.AppendPathComponent(module_uuid); |
| spec.AppendPathComponent(module_name); |
| return spec; |
| } |
| |
| static FileSpec GetSysrootView(FileSpec spec, const char *hostname) { |
| spec.AppendPathComponent(hostname); |
| spec.AppendPathComponent(dummy_remote_dir); |
| spec.AppendPathComponent(module_name); |
| return spec; |
| } |
| |
| void ModuleCacheTest::SetUpTestCase() { |
| HostInfo::Initialize(); |
| ObjectFileELF::Initialize(); |
| |
| s_cache_dir = HostInfo::GetProcessTempDir(); |
| s_test_executable = GetInputFilePath(module_name); |
| } |
| |
| void ModuleCacheTest::TearDownTestCase() { |
| ObjectFileELF::Terminate(); |
| HostInfo::Terminate(); |
| } |
| |
| static void VerifyDiskState(const FileSpec &cache_dir, const char *hostname) { |
| FileSpec uuid_view = GetUuidView(cache_dir); |
| EXPECT_TRUE(uuid_view.Exists()) << "uuid_view is: " << uuid_view.GetCString(); |
| EXPECT_EQ(module_size, uuid_view.GetByteSize()); |
| |
| FileSpec sysroot_view = GetSysrootView(cache_dir, hostname); |
| EXPECT_TRUE(sysroot_view.Exists()) << "sysroot_view is: " |
| << sysroot_view.GetCString(); |
| EXPECT_EQ(module_size, sysroot_view.GetByteSize()); |
| } |
| |
| void ModuleCacheTest::TryGetAndPut(const FileSpec &cache_dir, |
| const char *hostname, bool expect_download) { |
| ModuleCache mc; |
| ModuleSpec module_spec; |
| module_spec.GetFileSpec() = GetDummyRemotePath(); |
| module_spec.GetUUID().SetFromStringRef(module_uuid, uuid_bytes); |
| module_spec.SetObjectSize(module_size); |
| ModuleSP module_sp; |
| bool did_create; |
| bool download_called = false; |
| |
| Status error = mc.GetAndPut( |
| cache_dir, hostname, module_spec, |
| [&download_called](const ModuleSpec &module_spec, |
| const FileSpec &tmp_download_file_spec) { |
| download_called = true; |
| EXPECT_STREQ(GetDummyRemotePath().GetCString(), |
| module_spec.GetFileSpec().GetCString()); |
| std::error_code ec = llvm::sys::fs::copy_file( |
| s_test_executable, tmp_download_file_spec.GetCString()); |
| EXPECT_FALSE(ec); |
| return Status(); |
| }, |
| [](const ModuleSP &module_sp, const FileSpec &tmp_download_file_spec) { |
| return Status("Not supported."); |
| }, |
| module_sp, &did_create); |
| EXPECT_EQ(expect_download, download_called); |
| |
| EXPECT_TRUE(error.Success()) << "Error was: " << error.AsCString(); |
| EXPECT_TRUE(did_create); |
| ASSERT_TRUE(bool(module_sp)); |
| |
| SymbolContextList sc_list; |
| EXPECT_EQ(1u, module_sp->FindFunctionSymbols(ConstString("boom"), |
| eFunctionNameTypeFull, sc_list)); |
| EXPECT_STREQ(GetDummyRemotePath().GetCString(), |
| module_sp->GetPlatformFileSpec().GetCString()); |
| EXPECT_STREQ(module_uuid, module_sp->GetUUID().GetAsString().c_str()); |
| } |
| |
| TEST_F(ModuleCacheTest, GetAndPut) { |
| FileSpec test_cache_dir = s_cache_dir; |
| test_cache_dir.AppendPathComponent("GetAndPut"); |
| |
| const bool expect_download = true; |
| TryGetAndPut(test_cache_dir, dummy_hostname, expect_download); |
| VerifyDiskState(test_cache_dir, dummy_hostname); |
| } |
| |
| TEST_F(ModuleCacheTest, GetAndPutUuidExists) { |
| FileSpec test_cache_dir = s_cache_dir; |
| test_cache_dir.AppendPathComponent("GetAndPutUuidExists"); |
| |
| FileSpec uuid_view = GetUuidView(test_cache_dir); |
| std::error_code ec = |
| llvm::sys::fs::create_directories(uuid_view.GetDirectory().GetCString()); |
| ASSERT_FALSE(ec); |
| ec = llvm::sys::fs::copy_file(s_test_executable, uuid_view.GetCString()); |
| ASSERT_FALSE(ec); |
| |
| const bool expect_download = false; |
| TryGetAndPut(test_cache_dir, dummy_hostname, expect_download); |
| VerifyDiskState(test_cache_dir, dummy_hostname); |
| } |
| |
| TEST_F(ModuleCacheTest, GetAndPutStrangeHostname) { |
| FileSpec test_cache_dir = s_cache_dir; |
| test_cache_dir.AppendPathComponent("GetAndPutStrangeHostname"); |
| |
| const bool expect_download = true; |
| TryGetAndPut(test_cache_dir, "tab\tcolon:asterisk*", expect_download); |
| VerifyDiskState(test_cache_dir, "tab_colon_asterisk_"); |
| } |