101c3243fSZachary Turner #include "gtest/gtest.h" 201c3243fSZachary Turner 301c3243fSZachary Turner #include "llvm/ADT/SmallString.h" 401c3243fSZachary Turner #include "llvm/Support/FileSystem.h" 501c3243fSZachary Turner #include "llvm/Support/Path.h" 601c3243fSZachary Turner 701c3243fSZachary Turner #include "Plugins/ObjectFile/ELF/ObjectFileELF.h" 884a68569SPavel Labath #include "Plugins/SymbolFile/Symtab/SymbolFileSymtab.h" 9*5dca0596SRaphael Isemann #include "TestingSupport/SubsystemRAII.h" 1046376966SJonas Devlieghere #include "TestingSupport/TestUtilities.h" 1101c3243fSZachary Turner #include "lldb/Core/Module.h" 1201c3243fSZachary Turner #include "lldb/Core/ModuleSpec.h" 1346376966SJonas Devlieghere #include "lldb/Host/FileSystem.h" 1401c3243fSZachary Turner #include "lldb/Host/HostInfo.h" 1501c3243fSZachary Turner #include "lldb/Symbol/SymbolContext.h" 1601c3243fSZachary Turner #include "lldb/Target/ModuleCache.h" 1701c3243fSZachary Turner 1801c3243fSZachary Turner using namespace lldb_private; 1901c3243fSZachary Turner using namespace lldb; 2001c3243fSZachary Turner 2101c3243fSZachary Turner namespace { 2201c3243fSZachary Turner 2301c3243fSZachary Turner class ModuleCacheTest : public testing::Test { 24*5dca0596SRaphael Isemann SubsystemRAII<FileSystem, HostInfo, ObjectFileELF, SymbolFileSymtab> 25*5dca0596SRaphael Isemann subsystems; 2601c3243fSZachary Turner 27*5dca0596SRaphael Isemann public: 28*5dca0596SRaphael Isemann void SetUp() override; 2901c3243fSZachary Turner 3001c3243fSZachary Turner protected: 31*5dca0596SRaphael Isemann FileSpec s_cache_dir; 32*5dca0596SRaphael Isemann std::string s_test_executable; 3301c3243fSZachary Turner 3401c3243fSZachary Turner void TryGetAndPut(const FileSpec &cache_dir, const char *hostname, 3501c3243fSZachary Turner bool expect_download); 3601c3243fSZachary Turner }; 3701c3243fSZachary Turner } 3801c3243fSZachary Turner 3901c3243fSZachary Turner static const char dummy_hostname[] = "dummy_hostname"; 4001c3243fSZachary Turner static const char dummy_remote_dir[] = "bin"; 4101c3243fSZachary Turner static const char module_name[] = "TestModule.so"; 4201c3243fSZachary Turner static const char module_uuid[] = 4301c3243fSZachary Turner "F4E7E991-9B61-6AD4-0073-561AC3D9FA10-C043A476"; 4401c3243fSZachary Turner static const uint32_t uuid_bytes = 20; 4501c3243fSZachary Turner static const size_t module_size = 5602; 4601c3243fSZachary Turner 4701c3243fSZachary Turner static FileSpec GetDummyRemotePath() { 488f3be7a3SJonas Devlieghere FileSpec fs("/", FileSpec::Style::posix); 4901c3243fSZachary Turner fs.AppendPathComponent(dummy_remote_dir); 5001c3243fSZachary Turner fs.AppendPathComponent(module_name); 5101c3243fSZachary Turner return fs; 5201c3243fSZachary Turner } 5301c3243fSZachary Turner 5401c3243fSZachary Turner static FileSpec GetUuidView(FileSpec spec) { 5501c3243fSZachary Turner spec.AppendPathComponent(".cache"); 5601c3243fSZachary Turner spec.AppendPathComponent(module_uuid); 5701c3243fSZachary Turner spec.AppendPathComponent(module_name); 5801c3243fSZachary Turner return spec; 5901c3243fSZachary Turner } 6001c3243fSZachary Turner 6101c3243fSZachary Turner static FileSpec GetSysrootView(FileSpec spec, const char *hostname) { 6201c3243fSZachary Turner spec.AppendPathComponent(hostname); 6301c3243fSZachary Turner spec.AppendPathComponent(dummy_remote_dir); 6401c3243fSZachary Turner spec.AppendPathComponent(module_name); 6501c3243fSZachary Turner return spec; 6601c3243fSZachary Turner } 6701c3243fSZachary Turner 68*5dca0596SRaphael Isemann void ModuleCacheTest::SetUp() { 6960f028ffSPavel Labath s_cache_dir = HostInfo::GetProcessTempDir(); 707ed3e22fSPavel Labath s_test_executable = GetInputFilePath(module_name); 7101c3243fSZachary Turner } 7201c3243fSZachary Turner 7301c3243fSZachary Turner static void VerifyDiskState(const FileSpec &cache_dir, const char *hostname) { 7401c3243fSZachary Turner FileSpec uuid_view = GetUuidView(cache_dir); 75dbd7fabaSJonas Devlieghere EXPECT_TRUE(FileSystem::Instance().Exists(uuid_view)) 76dbd7fabaSJonas Devlieghere << "uuid_view is: " << uuid_view.GetCString(); 7759b78bcbSJonas Devlieghere EXPECT_EQ(module_size, FileSystem::Instance().GetByteSize(uuid_view)); 7801c3243fSZachary Turner 7901c3243fSZachary Turner FileSpec sysroot_view = GetSysrootView(cache_dir, hostname); 80dbd7fabaSJonas Devlieghere EXPECT_TRUE(FileSystem::Instance().Exists(sysroot_view)) 81dbd7fabaSJonas Devlieghere << "sysroot_view is: " << sysroot_view.GetCString(); 8259b78bcbSJonas Devlieghere EXPECT_EQ(module_size, FileSystem::Instance().GetByteSize(sysroot_view)); 8301c3243fSZachary Turner } 8401c3243fSZachary Turner 8501c3243fSZachary Turner void ModuleCacheTest::TryGetAndPut(const FileSpec &cache_dir, 8601c3243fSZachary Turner const char *hostname, bool expect_download) { 8701c3243fSZachary Turner ModuleCache mc; 8801c3243fSZachary Turner ModuleSpec module_spec; 8901c3243fSZachary Turner module_spec.GetFileSpec() = GetDummyRemotePath(); 90a174bcbfSPavel Labath module_spec.GetUUID().SetFromStringRef(module_uuid, uuid_bytes); 9101c3243fSZachary Turner module_spec.SetObjectSize(module_size); 9201c3243fSZachary Turner ModuleSP module_sp; 9301c3243fSZachary Turner bool did_create; 9401c3243fSZachary Turner bool download_called = false; 9501c3243fSZachary Turner 9697206d57SZachary Turner Status error = mc.GetAndPut( 9701c3243fSZachary Turner cache_dir, hostname, module_spec, 98*5dca0596SRaphael Isemann [&download_called, this](const ModuleSpec &module_spec, 9901c3243fSZachary Turner const FileSpec &tmp_download_file_spec) { 10001c3243fSZachary Turner download_called = true; 10101c3243fSZachary Turner EXPECT_STREQ(GetDummyRemotePath().GetCString(), 10201c3243fSZachary Turner module_spec.GetFileSpec().GetCString()); 10301c3243fSZachary Turner std::error_code ec = llvm::sys::fs::copy_file( 10401c3243fSZachary Turner s_test_executable, tmp_download_file_spec.GetCString()); 10501c3243fSZachary Turner EXPECT_FALSE(ec); 10697206d57SZachary Turner return Status(); 10701c3243fSZachary Turner }, 10801c3243fSZachary Turner [](const ModuleSP &module_sp, const FileSpec &tmp_download_file_spec) { 10997206d57SZachary Turner return Status("Not supported."); 11001c3243fSZachary Turner }, 11101c3243fSZachary Turner module_sp, &did_create); 11201c3243fSZachary Turner EXPECT_EQ(expect_download, download_called); 11301c3243fSZachary Turner 11401c3243fSZachary Turner EXPECT_TRUE(error.Success()) << "Error was: " << error.AsCString(); 11501c3243fSZachary Turner EXPECT_TRUE(did_create); 11601c3243fSZachary Turner ASSERT_TRUE(bool(module_sp)); 11701c3243fSZachary Turner 11801c3243fSZachary Turner SymbolContextList sc_list; 1191ad655e2SAdrian Prantl module_sp->FindFunctionSymbols(ConstString("boom"), eFunctionNameTypeFull, 1201ad655e2SAdrian Prantl sc_list); 1211ad655e2SAdrian Prantl EXPECT_EQ(1u, sc_list.GetSize()); 12201c3243fSZachary Turner EXPECT_STREQ(GetDummyRemotePath().GetCString(), 12301c3243fSZachary Turner module_sp->GetPlatformFileSpec().GetCString()); 12401c3243fSZachary Turner EXPECT_STREQ(module_uuid, module_sp->GetUUID().GetAsString().c_str()); 12501c3243fSZachary Turner } 12601c3243fSZachary Turner 12701c3243fSZachary Turner TEST_F(ModuleCacheTest, GetAndPut) { 12801c3243fSZachary Turner FileSpec test_cache_dir = s_cache_dir; 12901c3243fSZachary Turner test_cache_dir.AppendPathComponent("GetAndPut"); 13001c3243fSZachary Turner 13101c3243fSZachary Turner const bool expect_download = true; 13201c3243fSZachary Turner TryGetAndPut(test_cache_dir, dummy_hostname, expect_download); 13301c3243fSZachary Turner VerifyDiskState(test_cache_dir, dummy_hostname); 13401c3243fSZachary Turner } 13501c3243fSZachary Turner 13601c3243fSZachary Turner TEST_F(ModuleCacheTest, GetAndPutUuidExists) { 13701c3243fSZachary Turner FileSpec test_cache_dir = s_cache_dir; 13801c3243fSZachary Turner test_cache_dir.AppendPathComponent("GetAndPutUuidExists"); 13901c3243fSZachary Turner 14001c3243fSZachary Turner FileSpec uuid_view = GetUuidView(test_cache_dir); 14101c3243fSZachary Turner std::error_code ec = 14201c3243fSZachary Turner llvm::sys::fs::create_directories(uuid_view.GetDirectory().GetCString()); 14301c3243fSZachary Turner ASSERT_FALSE(ec); 14401c3243fSZachary Turner ec = llvm::sys::fs::copy_file(s_test_executable, uuid_view.GetCString()); 14501c3243fSZachary Turner ASSERT_FALSE(ec); 14601c3243fSZachary Turner 14701c3243fSZachary Turner const bool expect_download = false; 14801c3243fSZachary Turner TryGetAndPut(test_cache_dir, dummy_hostname, expect_download); 14901c3243fSZachary Turner VerifyDiskState(test_cache_dir, dummy_hostname); 15001c3243fSZachary Turner } 15101c3243fSZachary Turner 15201c3243fSZachary Turner TEST_F(ModuleCacheTest, GetAndPutStrangeHostname) { 15301c3243fSZachary Turner FileSpec test_cache_dir = s_cache_dir; 15401c3243fSZachary Turner test_cache_dir.AppendPathComponent("GetAndPutStrangeHostname"); 15501c3243fSZachary Turner 15601c3243fSZachary Turner const bool expect_download = true; 15701c3243fSZachary Turner TryGetAndPut(test_cache_dir, "tab\tcolon:asterisk*", expect_download); 15801c3243fSZachary Turner VerifyDiskState(test_cache_dir, "tab_colon_asterisk_"); 15901c3243fSZachary Turner } 160