1*01c3243fSZachary Turner #include "gtest/gtest.h" 2*01c3243fSZachary Turner 3*01c3243fSZachary Turner #include "llvm/ADT/SmallString.h" 4*01c3243fSZachary Turner #include "llvm/Support/FileSystem.h" 5*01c3243fSZachary Turner #include "llvm/Support/Path.h" 6*01c3243fSZachary Turner 7*01c3243fSZachary Turner #include "Plugins/ObjectFile/ELF/ObjectFileELF.h" 8*01c3243fSZachary Turner #include "lldb/Core/Module.h" 9*01c3243fSZachary Turner #include "lldb/Core/ModuleSpec.h" 10*01c3243fSZachary Turner #include "lldb/Host/HostInfo.h" 11*01c3243fSZachary Turner #include "lldb/Symbol/SymbolContext.h" 12*01c3243fSZachary Turner #include "lldb/Target/ModuleCache.h" 13*01c3243fSZachary Turner 14*01c3243fSZachary Turner extern const char *TestMainArgv0; 15*01c3243fSZachary Turner 16*01c3243fSZachary Turner using namespace lldb_private; 17*01c3243fSZachary Turner using namespace lldb; 18*01c3243fSZachary Turner 19*01c3243fSZachary Turner namespace { 20*01c3243fSZachary Turner 21*01c3243fSZachary Turner class ModuleCacheTest : public testing::Test { 22*01c3243fSZachary Turner public: 23*01c3243fSZachary Turner static void SetUpTestCase(); 24*01c3243fSZachary Turner 25*01c3243fSZachary Turner static void TearDownTestCase(); 26*01c3243fSZachary Turner 27*01c3243fSZachary Turner protected: 28*01c3243fSZachary Turner static FileSpec s_cache_dir; 29*01c3243fSZachary Turner static llvm::SmallString<128> s_test_executable; 30*01c3243fSZachary Turner 31*01c3243fSZachary Turner void TryGetAndPut(const FileSpec &cache_dir, const char *hostname, 32*01c3243fSZachary Turner bool expect_download); 33*01c3243fSZachary Turner }; 34*01c3243fSZachary Turner } 35*01c3243fSZachary Turner 36*01c3243fSZachary Turner FileSpec ModuleCacheTest::s_cache_dir; 37*01c3243fSZachary Turner llvm::SmallString<128> ModuleCacheTest::s_test_executable; 38*01c3243fSZachary Turner 39*01c3243fSZachary Turner static const char dummy_hostname[] = "dummy_hostname"; 40*01c3243fSZachary Turner static const char dummy_remote_dir[] = "bin"; 41*01c3243fSZachary Turner static const char module_name[] = "TestModule.so"; 42*01c3243fSZachary Turner static const char module_uuid[] = 43*01c3243fSZachary Turner "F4E7E991-9B61-6AD4-0073-561AC3D9FA10-C043A476"; 44*01c3243fSZachary Turner static const uint32_t uuid_bytes = 20; 45*01c3243fSZachary Turner static const size_t module_size = 5602; 46*01c3243fSZachary Turner 47*01c3243fSZachary Turner static FileSpec GetDummyRemotePath() { 48*01c3243fSZachary Turner FileSpec fs("/", false, FileSpec::ePathSyntaxPosix); 49*01c3243fSZachary Turner fs.AppendPathComponent(dummy_remote_dir); 50*01c3243fSZachary Turner fs.AppendPathComponent(module_name); 51*01c3243fSZachary Turner return fs; 52*01c3243fSZachary Turner } 53*01c3243fSZachary Turner 54*01c3243fSZachary Turner static FileSpec GetUuidView(FileSpec spec) { 55*01c3243fSZachary Turner spec.AppendPathComponent(".cache"); 56*01c3243fSZachary Turner spec.AppendPathComponent(module_uuid); 57*01c3243fSZachary Turner spec.AppendPathComponent(module_name); 58*01c3243fSZachary Turner return spec; 59*01c3243fSZachary Turner } 60*01c3243fSZachary Turner 61*01c3243fSZachary Turner static FileSpec GetSysrootView(FileSpec spec, const char *hostname) { 62*01c3243fSZachary Turner spec.AppendPathComponent(hostname); 63*01c3243fSZachary Turner spec.AppendPathComponent(dummy_remote_dir); 64*01c3243fSZachary Turner spec.AppendPathComponent(module_name); 65*01c3243fSZachary Turner return spec; 66*01c3243fSZachary Turner } 67*01c3243fSZachary Turner 68*01c3243fSZachary Turner void ModuleCacheTest::SetUpTestCase() { 69*01c3243fSZachary Turner HostInfo::Initialize(); 70*01c3243fSZachary Turner ObjectFileELF::Initialize(); 71*01c3243fSZachary Turner 72*01c3243fSZachary Turner FileSpec tmpdir_spec; 73*01c3243fSZachary Turner HostInfo::GetLLDBPath(lldb::ePathTypeLLDBTempSystemDir, s_cache_dir); 74*01c3243fSZachary Turner 75*01c3243fSZachary Turner llvm::StringRef exe_folder = llvm::sys::path::parent_path(TestMainArgv0); 76*01c3243fSZachary Turner s_test_executable = exe_folder; 77*01c3243fSZachary Turner llvm::sys::path::append(s_test_executable, "Inputs", module_name); 78*01c3243fSZachary Turner } 79*01c3243fSZachary Turner 80*01c3243fSZachary Turner void ModuleCacheTest::TearDownTestCase() { 81*01c3243fSZachary Turner ObjectFileELF::Terminate(); 82*01c3243fSZachary Turner HostInfo::Terminate(); 83*01c3243fSZachary Turner } 84*01c3243fSZachary Turner 85*01c3243fSZachary Turner static void VerifyDiskState(const FileSpec &cache_dir, const char *hostname) { 86*01c3243fSZachary Turner FileSpec uuid_view = GetUuidView(cache_dir); 87*01c3243fSZachary Turner EXPECT_TRUE(uuid_view.Exists()) << "uuid_view is: " << uuid_view.GetCString(); 88*01c3243fSZachary Turner EXPECT_EQ(module_size, uuid_view.GetByteSize()); 89*01c3243fSZachary Turner 90*01c3243fSZachary Turner FileSpec sysroot_view = GetSysrootView(cache_dir, hostname); 91*01c3243fSZachary Turner EXPECT_TRUE(sysroot_view.Exists()) << "sysroot_view is: " 92*01c3243fSZachary Turner << sysroot_view.GetCString(); 93*01c3243fSZachary Turner EXPECT_EQ(module_size, sysroot_view.GetByteSize()); 94*01c3243fSZachary Turner } 95*01c3243fSZachary Turner 96*01c3243fSZachary Turner void ModuleCacheTest::TryGetAndPut(const FileSpec &cache_dir, 97*01c3243fSZachary Turner const char *hostname, bool expect_download) { 98*01c3243fSZachary Turner ModuleCache mc; 99*01c3243fSZachary Turner ModuleSpec module_spec; 100*01c3243fSZachary Turner module_spec.GetFileSpec() = GetDummyRemotePath(); 101*01c3243fSZachary Turner module_spec.GetUUID().SetFromCString(module_uuid, uuid_bytes); 102*01c3243fSZachary Turner module_spec.SetObjectSize(module_size); 103*01c3243fSZachary Turner ModuleSP module_sp; 104*01c3243fSZachary Turner bool did_create; 105*01c3243fSZachary Turner bool download_called = false; 106*01c3243fSZachary Turner 107*01c3243fSZachary Turner Error error = mc.GetAndPut( 108*01c3243fSZachary Turner cache_dir, hostname, module_spec, 109*01c3243fSZachary Turner [this, &download_called](const ModuleSpec &module_spec, 110*01c3243fSZachary Turner const FileSpec &tmp_download_file_spec) { 111*01c3243fSZachary Turner download_called = true; 112*01c3243fSZachary Turner EXPECT_STREQ(GetDummyRemotePath().GetCString(), 113*01c3243fSZachary Turner module_spec.GetFileSpec().GetCString()); 114*01c3243fSZachary Turner std::error_code ec = llvm::sys::fs::copy_file( 115*01c3243fSZachary Turner s_test_executable, tmp_download_file_spec.GetCString()); 116*01c3243fSZachary Turner EXPECT_FALSE(ec); 117*01c3243fSZachary Turner return Error(); 118*01c3243fSZachary Turner }, 119*01c3243fSZachary Turner [](const ModuleSP &module_sp, const FileSpec &tmp_download_file_spec) { 120*01c3243fSZachary Turner return Error("Not supported."); 121*01c3243fSZachary Turner }, 122*01c3243fSZachary Turner module_sp, &did_create); 123*01c3243fSZachary Turner EXPECT_EQ(expect_download, download_called); 124*01c3243fSZachary Turner 125*01c3243fSZachary Turner EXPECT_TRUE(error.Success()) << "Error was: " << error.AsCString(); 126*01c3243fSZachary Turner EXPECT_TRUE(did_create); 127*01c3243fSZachary Turner ASSERT_TRUE(bool(module_sp)); 128*01c3243fSZachary Turner 129*01c3243fSZachary Turner SymbolContextList sc_list; 130*01c3243fSZachary Turner EXPECT_EQ(1u, module_sp->FindFunctionSymbols(ConstString("boom"), 131*01c3243fSZachary Turner eFunctionNameTypeFull, sc_list)); 132*01c3243fSZachary Turner EXPECT_STREQ(GetDummyRemotePath().GetCString(), 133*01c3243fSZachary Turner module_sp->GetPlatformFileSpec().GetCString()); 134*01c3243fSZachary Turner EXPECT_STREQ(module_uuid, module_sp->GetUUID().GetAsString().c_str()); 135*01c3243fSZachary Turner } 136*01c3243fSZachary Turner 137*01c3243fSZachary Turner TEST_F(ModuleCacheTest, GetAndPut) { 138*01c3243fSZachary Turner FileSpec test_cache_dir = s_cache_dir; 139*01c3243fSZachary Turner test_cache_dir.AppendPathComponent("GetAndPut"); 140*01c3243fSZachary Turner 141*01c3243fSZachary Turner const bool expect_download = true; 142*01c3243fSZachary Turner TryGetAndPut(test_cache_dir, dummy_hostname, expect_download); 143*01c3243fSZachary Turner VerifyDiskState(test_cache_dir, dummy_hostname); 144*01c3243fSZachary Turner } 145*01c3243fSZachary Turner 146*01c3243fSZachary Turner TEST_F(ModuleCacheTest, GetAndPutUuidExists) { 147*01c3243fSZachary Turner FileSpec test_cache_dir = s_cache_dir; 148*01c3243fSZachary Turner test_cache_dir.AppendPathComponent("GetAndPutUuidExists"); 149*01c3243fSZachary Turner 150*01c3243fSZachary Turner FileSpec uuid_view = GetUuidView(test_cache_dir); 151*01c3243fSZachary Turner std::error_code ec = 152*01c3243fSZachary Turner llvm::sys::fs::create_directories(uuid_view.GetDirectory().GetCString()); 153*01c3243fSZachary Turner ASSERT_FALSE(ec); 154*01c3243fSZachary Turner ec = llvm::sys::fs::copy_file(s_test_executable, uuid_view.GetCString()); 155*01c3243fSZachary Turner ASSERT_FALSE(ec); 156*01c3243fSZachary Turner 157*01c3243fSZachary Turner const bool expect_download = false; 158*01c3243fSZachary Turner TryGetAndPut(test_cache_dir, dummy_hostname, expect_download); 159*01c3243fSZachary Turner VerifyDiskState(test_cache_dir, dummy_hostname); 160*01c3243fSZachary Turner } 161*01c3243fSZachary Turner 162*01c3243fSZachary Turner TEST_F(ModuleCacheTest, GetAndPutStrangeHostname) { 163*01c3243fSZachary Turner FileSpec test_cache_dir = s_cache_dir; 164*01c3243fSZachary Turner test_cache_dir.AppendPathComponent("GetAndPutStrangeHostname"); 165*01c3243fSZachary Turner 166*01c3243fSZachary Turner const bool expect_download = true; 167*01c3243fSZachary Turner TryGetAndPut(test_cache_dir, "tab\tcolon:asterisk*", expect_download); 168*01c3243fSZachary Turner VerifyDiskState(test_cache_dir, "tab_colon_asterisk_"); 169*01c3243fSZachary Turner } 170