xref: /llvm-project/lldb/unittests/Target/ModuleCacheTest.cpp (revision 84a6856928a27afb463f7ba70dc807dbafc83747)
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