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" 801c3243fSZachary Turner #include "lldb/Core/Module.h" 901c3243fSZachary Turner #include "lldb/Core/ModuleSpec.h" 1001c3243fSZachary Turner #include "lldb/Host/HostInfo.h" 1101c3243fSZachary Turner #include "lldb/Symbol/SymbolContext.h" 1201c3243fSZachary Turner #include "lldb/Target/ModuleCache.h" 13a6db4167STim Hammerquist #include "TestingSupport/TestUtilities.h" 1401c3243fSZachary Turner 1501c3243fSZachary Turner using namespace lldb_private; 1601c3243fSZachary Turner using namespace lldb; 1701c3243fSZachary Turner 1801c3243fSZachary Turner namespace { 1901c3243fSZachary Turner 2001c3243fSZachary Turner class ModuleCacheTest : public testing::Test { 2101c3243fSZachary Turner public: 2201c3243fSZachary Turner static void SetUpTestCase(); 2301c3243fSZachary Turner 2401c3243fSZachary Turner static void TearDownTestCase(); 2501c3243fSZachary Turner 2601c3243fSZachary Turner protected: 2701c3243fSZachary Turner static FileSpec s_cache_dir; 287ed3e22fSPavel Labath static std::string s_test_executable; 2901c3243fSZachary Turner 3001c3243fSZachary Turner void TryGetAndPut(const FileSpec &cache_dir, const char *hostname, 3101c3243fSZachary Turner bool expect_download); 3201c3243fSZachary Turner }; 3301c3243fSZachary Turner } 3401c3243fSZachary Turner 3501c3243fSZachary Turner FileSpec ModuleCacheTest::s_cache_dir; 367ed3e22fSPavel Labath std::string ModuleCacheTest::s_test_executable; 3701c3243fSZachary Turner 3801c3243fSZachary Turner static const char dummy_hostname[] = "dummy_hostname"; 3901c3243fSZachary Turner static const char dummy_remote_dir[] = "bin"; 4001c3243fSZachary Turner static const char module_name[] = "TestModule.so"; 4101c3243fSZachary Turner static const char module_uuid[] = 4201c3243fSZachary Turner "F4E7E991-9B61-6AD4-0073-561AC3D9FA10-C043A476"; 4301c3243fSZachary Turner static const uint32_t uuid_bytes = 20; 4401c3243fSZachary Turner static const size_t module_size = 5602; 4501c3243fSZachary Turner 4601c3243fSZachary Turner static FileSpec GetDummyRemotePath() { 472cb7cf8eSPavel Labath FileSpec fs("/", false, FileSpec::Style::posix); 4801c3243fSZachary Turner fs.AppendPathComponent(dummy_remote_dir); 4901c3243fSZachary Turner fs.AppendPathComponent(module_name); 5001c3243fSZachary Turner return fs; 5101c3243fSZachary Turner } 5201c3243fSZachary Turner 5301c3243fSZachary Turner static FileSpec GetUuidView(FileSpec spec) { 5401c3243fSZachary Turner spec.AppendPathComponent(".cache"); 5501c3243fSZachary Turner spec.AppendPathComponent(module_uuid); 5601c3243fSZachary Turner spec.AppendPathComponent(module_name); 5701c3243fSZachary Turner return spec; 5801c3243fSZachary Turner } 5901c3243fSZachary Turner 6001c3243fSZachary Turner static FileSpec GetSysrootView(FileSpec spec, const char *hostname) { 6101c3243fSZachary Turner spec.AppendPathComponent(hostname); 6201c3243fSZachary Turner spec.AppendPathComponent(dummy_remote_dir); 6301c3243fSZachary Turner spec.AppendPathComponent(module_name); 6401c3243fSZachary Turner return spec; 6501c3243fSZachary Turner } 6601c3243fSZachary Turner 6701c3243fSZachary Turner void ModuleCacheTest::SetUpTestCase() { 6801c3243fSZachary Turner HostInfo::Initialize(); 6901c3243fSZachary Turner ObjectFileELF::Initialize(); 7001c3243fSZachary Turner 7160f028ffSPavel Labath s_cache_dir = HostInfo::GetProcessTempDir(); 727ed3e22fSPavel Labath s_test_executable = GetInputFilePath(module_name); 7301c3243fSZachary Turner } 7401c3243fSZachary Turner 7501c3243fSZachary Turner void ModuleCacheTest::TearDownTestCase() { 7601c3243fSZachary Turner ObjectFileELF::Terminate(); 7701c3243fSZachary Turner HostInfo::Terminate(); 7801c3243fSZachary Turner } 7901c3243fSZachary Turner 8001c3243fSZachary Turner static void VerifyDiskState(const FileSpec &cache_dir, const char *hostname) { 8101c3243fSZachary Turner FileSpec uuid_view = GetUuidView(cache_dir); 8201c3243fSZachary Turner EXPECT_TRUE(uuid_view.Exists()) << "uuid_view is: " << uuid_view.GetCString(); 8301c3243fSZachary Turner EXPECT_EQ(module_size, uuid_view.GetByteSize()); 8401c3243fSZachary Turner 8501c3243fSZachary Turner FileSpec sysroot_view = GetSysrootView(cache_dir, hostname); 8601c3243fSZachary Turner EXPECT_TRUE(sysroot_view.Exists()) << "sysroot_view is: " 8701c3243fSZachary Turner << sysroot_view.GetCString(); 8801c3243fSZachary Turner EXPECT_EQ(module_size, sysroot_view.GetByteSize()); 8901c3243fSZachary Turner } 9001c3243fSZachary Turner 9101c3243fSZachary Turner void ModuleCacheTest::TryGetAndPut(const FileSpec &cache_dir, 9201c3243fSZachary Turner const char *hostname, bool expect_download) { 9301c3243fSZachary Turner ModuleCache mc; 9401c3243fSZachary Turner ModuleSpec module_spec; 9501c3243fSZachary Turner module_spec.GetFileSpec() = GetDummyRemotePath(); 96*a174bcbfSPavel Labath module_spec.GetUUID().SetFromStringRef(module_uuid, uuid_bytes); 9701c3243fSZachary Turner module_spec.SetObjectSize(module_size); 9801c3243fSZachary Turner ModuleSP module_sp; 9901c3243fSZachary Turner bool did_create; 10001c3243fSZachary Turner bool download_called = false; 10101c3243fSZachary Turner 10297206d57SZachary Turner Status error = mc.GetAndPut( 10301c3243fSZachary Turner cache_dir, hostname, module_spec, 104c7933341SVedant Kumar [&download_called](const ModuleSpec &module_spec, 10501c3243fSZachary Turner const FileSpec &tmp_download_file_spec) { 10601c3243fSZachary Turner download_called = true; 10701c3243fSZachary Turner EXPECT_STREQ(GetDummyRemotePath().GetCString(), 10801c3243fSZachary Turner module_spec.GetFileSpec().GetCString()); 10901c3243fSZachary Turner std::error_code ec = llvm::sys::fs::copy_file( 11001c3243fSZachary Turner s_test_executable, tmp_download_file_spec.GetCString()); 11101c3243fSZachary Turner EXPECT_FALSE(ec); 11297206d57SZachary Turner return Status(); 11301c3243fSZachary Turner }, 11401c3243fSZachary Turner [](const ModuleSP &module_sp, const FileSpec &tmp_download_file_spec) { 11597206d57SZachary Turner return Status("Not supported."); 11601c3243fSZachary Turner }, 11701c3243fSZachary Turner module_sp, &did_create); 11801c3243fSZachary Turner EXPECT_EQ(expect_download, download_called); 11901c3243fSZachary Turner 12001c3243fSZachary Turner EXPECT_TRUE(error.Success()) << "Error was: " << error.AsCString(); 12101c3243fSZachary Turner EXPECT_TRUE(did_create); 12201c3243fSZachary Turner ASSERT_TRUE(bool(module_sp)); 12301c3243fSZachary Turner 12401c3243fSZachary Turner SymbolContextList sc_list; 12501c3243fSZachary Turner EXPECT_EQ(1u, module_sp->FindFunctionSymbols(ConstString("boom"), 12601c3243fSZachary Turner eFunctionNameTypeFull, sc_list)); 12701c3243fSZachary Turner EXPECT_STREQ(GetDummyRemotePath().GetCString(), 12801c3243fSZachary Turner module_sp->GetPlatformFileSpec().GetCString()); 12901c3243fSZachary Turner EXPECT_STREQ(module_uuid, module_sp->GetUUID().GetAsString().c_str()); 13001c3243fSZachary Turner } 13101c3243fSZachary Turner 13201c3243fSZachary Turner TEST_F(ModuleCacheTest, GetAndPut) { 13301c3243fSZachary Turner FileSpec test_cache_dir = s_cache_dir; 13401c3243fSZachary Turner test_cache_dir.AppendPathComponent("GetAndPut"); 13501c3243fSZachary Turner 13601c3243fSZachary Turner const bool expect_download = true; 13701c3243fSZachary Turner TryGetAndPut(test_cache_dir, dummy_hostname, expect_download); 13801c3243fSZachary Turner VerifyDiskState(test_cache_dir, dummy_hostname); 13901c3243fSZachary Turner } 14001c3243fSZachary Turner 14101c3243fSZachary Turner TEST_F(ModuleCacheTest, GetAndPutUuidExists) { 14201c3243fSZachary Turner FileSpec test_cache_dir = s_cache_dir; 14301c3243fSZachary Turner test_cache_dir.AppendPathComponent("GetAndPutUuidExists"); 14401c3243fSZachary Turner 14501c3243fSZachary Turner FileSpec uuid_view = GetUuidView(test_cache_dir); 14601c3243fSZachary Turner std::error_code ec = 14701c3243fSZachary Turner llvm::sys::fs::create_directories(uuid_view.GetDirectory().GetCString()); 14801c3243fSZachary Turner ASSERT_FALSE(ec); 14901c3243fSZachary Turner ec = llvm::sys::fs::copy_file(s_test_executable, uuid_view.GetCString()); 15001c3243fSZachary Turner ASSERT_FALSE(ec); 15101c3243fSZachary Turner 15201c3243fSZachary Turner const bool expect_download = false; 15301c3243fSZachary Turner TryGetAndPut(test_cache_dir, dummy_hostname, expect_download); 15401c3243fSZachary Turner VerifyDiskState(test_cache_dir, dummy_hostname); 15501c3243fSZachary Turner } 15601c3243fSZachary Turner 15701c3243fSZachary Turner TEST_F(ModuleCacheTest, GetAndPutStrangeHostname) { 15801c3243fSZachary Turner FileSpec test_cache_dir = s_cache_dir; 15901c3243fSZachary Turner test_cache_dir.AppendPathComponent("GetAndPutStrangeHostname"); 16001c3243fSZachary Turner 16101c3243fSZachary Turner const bool expect_download = true; 16201c3243fSZachary Turner TryGetAndPut(test_cache_dir, "tab\tcolon:asterisk*", expect_download); 16301c3243fSZachary Turner VerifyDiskState(test_cache_dir, "tab_colon_asterisk_"); 16401c3243fSZachary Turner } 165