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