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" 846376966SJonas Devlieghere #include "TestingSupport/TestUtilities.h" 901c3243fSZachary Turner #include "lldb/Core/Module.h" 1001c3243fSZachary Turner #include "lldb/Core/ModuleSpec.h" 1146376966SJonas Devlieghere #include "lldb/Host/FileSystem.h" 1201c3243fSZachary Turner #include "lldb/Host/HostInfo.h" 1301c3243fSZachary Turner #include "lldb/Symbol/SymbolContext.h" 1401c3243fSZachary Turner #include "lldb/Target/ModuleCache.h" 1501c3243fSZachary Turner 1601c3243fSZachary Turner using namespace lldb_private; 1701c3243fSZachary Turner using namespace lldb; 1801c3243fSZachary Turner 1901c3243fSZachary Turner namespace { 2001c3243fSZachary Turner 2101c3243fSZachary Turner class ModuleCacheTest : public testing::Test { 2201c3243fSZachary Turner public: 2301c3243fSZachary Turner static void SetUpTestCase(); 2401c3243fSZachary Turner 2501c3243fSZachary Turner static void TearDownTestCase(); 2601c3243fSZachary Turner 2701c3243fSZachary Turner protected: 2801c3243fSZachary Turner static FileSpec s_cache_dir; 297ed3e22fSPavel Labath static std::string s_test_executable; 3001c3243fSZachary Turner 3101c3243fSZachary Turner void TryGetAndPut(const FileSpec &cache_dir, const char *hostname, 3201c3243fSZachary Turner bool expect_download); 3301c3243fSZachary Turner }; 3401c3243fSZachary Turner } 3501c3243fSZachary Turner 3601c3243fSZachary Turner FileSpec ModuleCacheTest::s_cache_dir; 377ed3e22fSPavel Labath std::string ModuleCacheTest::s_test_executable; 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() { 482cb7cf8eSPavel Labath FileSpec fs("/", false, 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 6801c3243fSZachary Turner void ModuleCacheTest::SetUpTestCase() { 6946376966SJonas Devlieghere FileSystem::Initialize(); 7001c3243fSZachary Turner HostInfo::Initialize(); 7101c3243fSZachary Turner ObjectFileELF::Initialize(); 7201c3243fSZachary Turner 7360f028ffSPavel Labath s_cache_dir = HostInfo::GetProcessTempDir(); 747ed3e22fSPavel Labath s_test_executable = GetInputFilePath(module_name); 7501c3243fSZachary Turner } 7601c3243fSZachary Turner 7701c3243fSZachary Turner void ModuleCacheTest::TearDownTestCase() { 7801c3243fSZachary Turner ObjectFileELF::Terminate(); 7901c3243fSZachary Turner HostInfo::Terminate(); 8046376966SJonas Devlieghere FileSystem::Terminate(); 8101c3243fSZachary Turner } 8201c3243fSZachary Turner 8301c3243fSZachary Turner static void VerifyDiskState(const FileSpec &cache_dir, const char *hostname) { 8401c3243fSZachary Turner FileSpec uuid_view = GetUuidView(cache_dir); 85*dbd7fabaSJonas Devlieghere EXPECT_TRUE(FileSystem::Instance().Exists(uuid_view)) 86*dbd7fabaSJonas Devlieghere << "uuid_view is: " << uuid_view.GetCString(); 8759b78bcbSJonas Devlieghere EXPECT_EQ(module_size, FileSystem::Instance().GetByteSize(uuid_view)); 8801c3243fSZachary Turner 8901c3243fSZachary Turner FileSpec sysroot_view = GetSysrootView(cache_dir, hostname); 90*dbd7fabaSJonas Devlieghere EXPECT_TRUE(FileSystem::Instance().Exists(sysroot_view)) 91*dbd7fabaSJonas Devlieghere << "sysroot_view is: " << sysroot_view.GetCString(); 9259b78bcbSJonas Devlieghere EXPECT_EQ(module_size, FileSystem::Instance().GetByteSize(sysroot_view)); 9301c3243fSZachary Turner } 9401c3243fSZachary Turner 9501c3243fSZachary Turner void ModuleCacheTest::TryGetAndPut(const FileSpec &cache_dir, 9601c3243fSZachary Turner const char *hostname, bool expect_download) { 9701c3243fSZachary Turner ModuleCache mc; 9801c3243fSZachary Turner ModuleSpec module_spec; 9901c3243fSZachary Turner module_spec.GetFileSpec() = GetDummyRemotePath(); 100a174bcbfSPavel Labath module_spec.GetUUID().SetFromStringRef(module_uuid, uuid_bytes); 10101c3243fSZachary Turner module_spec.SetObjectSize(module_size); 10201c3243fSZachary Turner ModuleSP module_sp; 10301c3243fSZachary Turner bool did_create; 10401c3243fSZachary Turner bool download_called = false; 10501c3243fSZachary Turner 10697206d57SZachary Turner Status error = mc.GetAndPut( 10701c3243fSZachary Turner cache_dir, hostname, module_spec, 108c7933341SVedant Kumar [&download_called](const ModuleSpec &module_spec, 10901c3243fSZachary Turner const FileSpec &tmp_download_file_spec) { 11001c3243fSZachary Turner download_called = true; 11101c3243fSZachary Turner EXPECT_STREQ(GetDummyRemotePath().GetCString(), 11201c3243fSZachary Turner module_spec.GetFileSpec().GetCString()); 11301c3243fSZachary Turner std::error_code ec = llvm::sys::fs::copy_file( 11401c3243fSZachary Turner s_test_executable, tmp_download_file_spec.GetCString()); 11501c3243fSZachary Turner EXPECT_FALSE(ec); 11697206d57SZachary Turner return Status(); 11701c3243fSZachary Turner }, 11801c3243fSZachary Turner [](const ModuleSP &module_sp, const FileSpec &tmp_download_file_spec) { 11997206d57SZachary Turner return Status("Not supported."); 12001c3243fSZachary Turner }, 12101c3243fSZachary Turner module_sp, &did_create); 12201c3243fSZachary Turner EXPECT_EQ(expect_download, download_called); 12301c3243fSZachary Turner 12401c3243fSZachary Turner EXPECT_TRUE(error.Success()) << "Error was: " << error.AsCString(); 12501c3243fSZachary Turner EXPECT_TRUE(did_create); 12601c3243fSZachary Turner ASSERT_TRUE(bool(module_sp)); 12701c3243fSZachary Turner 12801c3243fSZachary Turner SymbolContextList sc_list; 12901c3243fSZachary Turner EXPECT_EQ(1u, module_sp->FindFunctionSymbols(ConstString("boom"), 13001c3243fSZachary Turner eFunctionNameTypeFull, sc_list)); 13101c3243fSZachary Turner EXPECT_STREQ(GetDummyRemotePath().GetCString(), 13201c3243fSZachary Turner module_sp->GetPlatformFileSpec().GetCString()); 13301c3243fSZachary Turner EXPECT_STREQ(module_uuid, module_sp->GetUUID().GetAsString().c_str()); 13401c3243fSZachary Turner } 13501c3243fSZachary Turner 13601c3243fSZachary Turner TEST_F(ModuleCacheTest, GetAndPut) { 13701c3243fSZachary Turner FileSpec test_cache_dir = s_cache_dir; 13801c3243fSZachary Turner test_cache_dir.AppendPathComponent("GetAndPut"); 13901c3243fSZachary Turner 14001c3243fSZachary Turner const bool expect_download = true; 14101c3243fSZachary Turner TryGetAndPut(test_cache_dir, dummy_hostname, expect_download); 14201c3243fSZachary Turner VerifyDiskState(test_cache_dir, dummy_hostname); 14301c3243fSZachary Turner } 14401c3243fSZachary Turner 14501c3243fSZachary Turner TEST_F(ModuleCacheTest, GetAndPutUuidExists) { 14601c3243fSZachary Turner FileSpec test_cache_dir = s_cache_dir; 14701c3243fSZachary Turner test_cache_dir.AppendPathComponent("GetAndPutUuidExists"); 14801c3243fSZachary Turner 14901c3243fSZachary Turner FileSpec uuid_view = GetUuidView(test_cache_dir); 15001c3243fSZachary Turner std::error_code ec = 15101c3243fSZachary Turner llvm::sys::fs::create_directories(uuid_view.GetDirectory().GetCString()); 15201c3243fSZachary Turner ASSERT_FALSE(ec); 15301c3243fSZachary Turner ec = llvm::sys::fs::copy_file(s_test_executable, uuid_view.GetCString()); 15401c3243fSZachary Turner ASSERT_FALSE(ec); 15501c3243fSZachary Turner 15601c3243fSZachary Turner const bool expect_download = false; 15701c3243fSZachary Turner TryGetAndPut(test_cache_dir, dummy_hostname, expect_download); 15801c3243fSZachary Turner VerifyDiskState(test_cache_dir, dummy_hostname); 15901c3243fSZachary Turner } 16001c3243fSZachary Turner 16101c3243fSZachary Turner TEST_F(ModuleCacheTest, GetAndPutStrangeHostname) { 16201c3243fSZachary Turner FileSpec test_cache_dir = s_cache_dir; 16301c3243fSZachary Turner test_cache_dir.AppendPathComponent("GetAndPutStrangeHostname"); 16401c3243fSZachary Turner 16501c3243fSZachary Turner const bool expect_download = true; 16601c3243fSZachary Turner TryGetAndPut(test_cache_dir, "tab\tcolon:asterisk*", expect_download); 16701c3243fSZachary Turner VerifyDiskState(test_cache_dir, "tab_colon_asterisk_"); 16801c3243fSZachary Turner } 169