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