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" 8*84a68569SPavel Labath #include "Plugins/SymbolFile/Symtab/SymbolFileSymtab.h" 946376966SJonas Devlieghere #include "TestingSupport/TestUtilities.h" 1001c3243fSZachary Turner #include "lldb/Core/Module.h" 1101c3243fSZachary Turner #include "lldb/Core/ModuleSpec.h" 1246376966SJonas Devlieghere #include "lldb/Host/FileSystem.h" 1301c3243fSZachary Turner #include "lldb/Host/HostInfo.h" 1401c3243fSZachary Turner #include "lldb/Symbol/SymbolContext.h" 1501c3243fSZachary Turner #include "lldb/Target/ModuleCache.h" 1601c3243fSZachary Turner 1701c3243fSZachary Turner using namespace lldb_private; 1801c3243fSZachary Turner using namespace lldb; 1901c3243fSZachary Turner 2001c3243fSZachary Turner namespace { 2101c3243fSZachary Turner 2201c3243fSZachary Turner class ModuleCacheTest : public testing::Test { 2301c3243fSZachary Turner public: 2401c3243fSZachary Turner static void SetUpTestCase(); 2501c3243fSZachary Turner 2601c3243fSZachary Turner static void TearDownTestCase(); 2701c3243fSZachary Turner 2801c3243fSZachary Turner protected: 2901c3243fSZachary Turner static FileSpec s_cache_dir; 307ed3e22fSPavel Labath static std::string s_test_executable; 3101c3243fSZachary Turner 3201c3243fSZachary Turner void TryGetAndPut(const FileSpec &cache_dir, const char *hostname, 3301c3243fSZachary Turner bool expect_download); 3401c3243fSZachary Turner }; 3501c3243fSZachary Turner } 3601c3243fSZachary Turner 3701c3243fSZachary Turner FileSpec ModuleCacheTest::s_cache_dir; 387ed3e22fSPavel Labath std::string ModuleCacheTest::s_test_executable; 3901c3243fSZachary Turner 4001c3243fSZachary Turner static const char dummy_hostname[] = "dummy_hostname"; 4101c3243fSZachary Turner static const char dummy_remote_dir[] = "bin"; 4201c3243fSZachary Turner static const char module_name[] = "TestModule.so"; 4301c3243fSZachary Turner static const char module_uuid[] = 4401c3243fSZachary Turner "F4E7E991-9B61-6AD4-0073-561AC3D9FA10-C043A476"; 4501c3243fSZachary Turner static const uint32_t uuid_bytes = 20; 4601c3243fSZachary Turner static const size_t module_size = 5602; 4701c3243fSZachary Turner 4801c3243fSZachary Turner static FileSpec GetDummyRemotePath() { 498f3be7a3SJonas Devlieghere FileSpec fs("/", FileSpec::Style::posix); 5001c3243fSZachary Turner fs.AppendPathComponent(dummy_remote_dir); 5101c3243fSZachary Turner fs.AppendPathComponent(module_name); 5201c3243fSZachary Turner return fs; 5301c3243fSZachary Turner } 5401c3243fSZachary Turner 5501c3243fSZachary Turner static FileSpec GetUuidView(FileSpec spec) { 5601c3243fSZachary Turner spec.AppendPathComponent(".cache"); 5701c3243fSZachary Turner spec.AppendPathComponent(module_uuid); 5801c3243fSZachary Turner spec.AppendPathComponent(module_name); 5901c3243fSZachary Turner return spec; 6001c3243fSZachary Turner } 6101c3243fSZachary Turner 6201c3243fSZachary Turner static FileSpec GetSysrootView(FileSpec spec, const char *hostname) { 6301c3243fSZachary Turner spec.AppendPathComponent(hostname); 6401c3243fSZachary Turner spec.AppendPathComponent(dummy_remote_dir); 6501c3243fSZachary Turner spec.AppendPathComponent(module_name); 6601c3243fSZachary Turner return spec; 6701c3243fSZachary Turner } 6801c3243fSZachary Turner 6901c3243fSZachary Turner void ModuleCacheTest::SetUpTestCase() { 7046376966SJonas Devlieghere FileSystem::Initialize(); 7101c3243fSZachary Turner HostInfo::Initialize(); 7201c3243fSZachary Turner ObjectFileELF::Initialize(); 73*84a68569SPavel Labath SymbolFileSymtab::Initialize(); 7401c3243fSZachary Turner 7560f028ffSPavel Labath s_cache_dir = HostInfo::GetProcessTempDir(); 767ed3e22fSPavel Labath s_test_executable = GetInputFilePath(module_name); 7701c3243fSZachary Turner } 7801c3243fSZachary Turner 7901c3243fSZachary Turner void ModuleCacheTest::TearDownTestCase() { 80*84a68569SPavel Labath SymbolFileSymtab::Terminate(); 8101c3243fSZachary Turner ObjectFileELF::Terminate(); 8201c3243fSZachary Turner HostInfo::Terminate(); 8346376966SJonas Devlieghere FileSystem::Terminate(); 8401c3243fSZachary Turner } 8501c3243fSZachary Turner 8601c3243fSZachary Turner static void VerifyDiskState(const FileSpec &cache_dir, const char *hostname) { 8701c3243fSZachary Turner FileSpec uuid_view = GetUuidView(cache_dir); 88dbd7fabaSJonas Devlieghere EXPECT_TRUE(FileSystem::Instance().Exists(uuid_view)) 89dbd7fabaSJonas Devlieghere << "uuid_view is: " << uuid_view.GetCString(); 9059b78bcbSJonas Devlieghere EXPECT_EQ(module_size, FileSystem::Instance().GetByteSize(uuid_view)); 9101c3243fSZachary Turner 9201c3243fSZachary Turner FileSpec sysroot_view = GetSysrootView(cache_dir, hostname); 93dbd7fabaSJonas Devlieghere EXPECT_TRUE(FileSystem::Instance().Exists(sysroot_view)) 94dbd7fabaSJonas Devlieghere << "sysroot_view is: " << sysroot_view.GetCString(); 9559b78bcbSJonas Devlieghere EXPECT_EQ(module_size, FileSystem::Instance().GetByteSize(sysroot_view)); 9601c3243fSZachary Turner } 9701c3243fSZachary Turner 9801c3243fSZachary Turner void ModuleCacheTest::TryGetAndPut(const FileSpec &cache_dir, 9901c3243fSZachary Turner const char *hostname, bool expect_download) { 10001c3243fSZachary Turner ModuleCache mc; 10101c3243fSZachary Turner ModuleSpec module_spec; 10201c3243fSZachary Turner module_spec.GetFileSpec() = GetDummyRemotePath(); 103a174bcbfSPavel Labath module_spec.GetUUID().SetFromStringRef(module_uuid, uuid_bytes); 10401c3243fSZachary Turner module_spec.SetObjectSize(module_size); 10501c3243fSZachary Turner ModuleSP module_sp; 10601c3243fSZachary Turner bool did_create; 10701c3243fSZachary Turner bool download_called = false; 10801c3243fSZachary Turner 10997206d57SZachary Turner Status error = mc.GetAndPut( 11001c3243fSZachary Turner cache_dir, hostname, module_spec, 111c7933341SVedant Kumar [&download_called](const ModuleSpec &module_spec, 11201c3243fSZachary Turner const FileSpec &tmp_download_file_spec) { 11301c3243fSZachary Turner download_called = true; 11401c3243fSZachary Turner EXPECT_STREQ(GetDummyRemotePath().GetCString(), 11501c3243fSZachary Turner module_spec.GetFileSpec().GetCString()); 11601c3243fSZachary Turner std::error_code ec = llvm::sys::fs::copy_file( 11701c3243fSZachary Turner s_test_executable, tmp_download_file_spec.GetCString()); 11801c3243fSZachary Turner EXPECT_FALSE(ec); 11997206d57SZachary Turner return Status(); 12001c3243fSZachary Turner }, 12101c3243fSZachary Turner [](const ModuleSP &module_sp, const FileSpec &tmp_download_file_spec) { 12297206d57SZachary Turner return Status("Not supported."); 12301c3243fSZachary Turner }, 12401c3243fSZachary Turner module_sp, &did_create); 12501c3243fSZachary Turner EXPECT_EQ(expect_download, download_called); 12601c3243fSZachary Turner 12701c3243fSZachary Turner EXPECT_TRUE(error.Success()) << "Error was: " << error.AsCString(); 12801c3243fSZachary Turner EXPECT_TRUE(did_create); 12901c3243fSZachary Turner ASSERT_TRUE(bool(module_sp)); 13001c3243fSZachary Turner 13101c3243fSZachary Turner SymbolContextList sc_list; 13201c3243fSZachary Turner EXPECT_EQ(1u, module_sp->FindFunctionSymbols(ConstString("boom"), 13301c3243fSZachary Turner eFunctionNameTypeFull, sc_list)); 13401c3243fSZachary Turner EXPECT_STREQ(GetDummyRemotePath().GetCString(), 13501c3243fSZachary Turner module_sp->GetPlatformFileSpec().GetCString()); 13601c3243fSZachary Turner EXPECT_STREQ(module_uuid, module_sp->GetUUID().GetAsString().c_str()); 13701c3243fSZachary Turner } 13801c3243fSZachary Turner 13901c3243fSZachary Turner TEST_F(ModuleCacheTest, GetAndPut) { 14001c3243fSZachary Turner FileSpec test_cache_dir = s_cache_dir; 14101c3243fSZachary Turner test_cache_dir.AppendPathComponent("GetAndPut"); 14201c3243fSZachary Turner 14301c3243fSZachary Turner const bool expect_download = true; 14401c3243fSZachary Turner TryGetAndPut(test_cache_dir, dummy_hostname, expect_download); 14501c3243fSZachary Turner VerifyDiskState(test_cache_dir, dummy_hostname); 14601c3243fSZachary Turner } 14701c3243fSZachary Turner 14801c3243fSZachary Turner TEST_F(ModuleCacheTest, GetAndPutUuidExists) { 14901c3243fSZachary Turner FileSpec test_cache_dir = s_cache_dir; 15001c3243fSZachary Turner test_cache_dir.AppendPathComponent("GetAndPutUuidExists"); 15101c3243fSZachary Turner 15201c3243fSZachary Turner FileSpec uuid_view = GetUuidView(test_cache_dir); 15301c3243fSZachary Turner std::error_code ec = 15401c3243fSZachary Turner llvm::sys::fs::create_directories(uuid_view.GetDirectory().GetCString()); 15501c3243fSZachary Turner ASSERT_FALSE(ec); 15601c3243fSZachary Turner ec = llvm::sys::fs::copy_file(s_test_executable, uuid_view.GetCString()); 15701c3243fSZachary Turner ASSERT_FALSE(ec); 15801c3243fSZachary Turner 15901c3243fSZachary Turner const bool expect_download = false; 16001c3243fSZachary Turner TryGetAndPut(test_cache_dir, dummy_hostname, expect_download); 16101c3243fSZachary Turner VerifyDiskState(test_cache_dir, dummy_hostname); 16201c3243fSZachary Turner } 16301c3243fSZachary Turner 16401c3243fSZachary Turner TEST_F(ModuleCacheTest, GetAndPutStrangeHostname) { 16501c3243fSZachary Turner FileSpec test_cache_dir = s_cache_dir; 16601c3243fSZachary Turner test_cache_dir.AppendPathComponent("GetAndPutStrangeHostname"); 16701c3243fSZachary Turner 16801c3243fSZachary Turner const bool expect_download = true; 16901c3243fSZachary Turner TryGetAndPut(test_cache_dir, "tab\tcolon:asterisk*", expect_download); 17001c3243fSZachary Turner VerifyDiskState(test_cache_dir, "tab_colon_asterisk_"); 17101c3243fSZachary Turner } 172