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"
884a68569SPavel Labath #include "Plugins/SymbolFile/Symtab/SymbolFileSymtab.h"
95dca0596SRaphael Isemann #include "TestingSupport/SubsystemRAII.h"
1046376966SJonas Devlieghere #include "TestingSupport/TestUtilities.h"
1101c3243fSZachary Turner #include "lldb/Core/Module.h"
1201c3243fSZachary Turner #include "lldb/Core/ModuleSpec.h"
1346376966SJonas Devlieghere #include "lldb/Host/FileSystem.h"
1401c3243fSZachary Turner #include "lldb/Host/HostInfo.h"
1501c3243fSZachary Turner #include "lldb/Symbol/SymbolContext.h"
1601c3243fSZachary Turner #include "lldb/Target/ModuleCache.h"
1701c3243fSZachary Turner
1801c3243fSZachary Turner using namespace lldb_private;
1901c3243fSZachary Turner using namespace lldb;
2001c3243fSZachary Turner
2101c3243fSZachary Turner namespace {
2201c3243fSZachary Turner
2301c3243fSZachary Turner class ModuleCacheTest : public testing::Test {
245dca0596SRaphael Isemann SubsystemRAII<FileSystem, HostInfo, ObjectFileELF, SymbolFileSymtab>
255dca0596SRaphael Isemann subsystems;
2601c3243fSZachary Turner
275dca0596SRaphael Isemann public:
285dca0596SRaphael Isemann void SetUp() override;
2901c3243fSZachary Turner
3001c3243fSZachary Turner protected:
315dca0596SRaphael Isemann FileSpec s_cache_dir;
325dca0596SRaphael Isemann std::string s_test_executable;
3301c3243fSZachary Turner
3401c3243fSZachary Turner void TryGetAndPut(const FileSpec &cache_dir, const char *hostname,
3501c3243fSZachary Turner bool expect_download);
3601c3243fSZachary Turner };
3701c3243fSZachary Turner }
3801c3243fSZachary Turner
3901c3243fSZachary Turner static const char dummy_hostname[] = "dummy_hostname";
4001c3243fSZachary Turner static const char dummy_remote_dir[] = "bin";
4101c3243fSZachary Turner static const char module_name[] = "TestModule.so";
4201c3243fSZachary Turner static const char module_uuid[] =
4301c3243fSZachary Turner "F4E7E991-9B61-6AD4-0073-561AC3D9FA10-C043A476";
4401c3243fSZachary Turner static const size_t module_size = 5602;
4501c3243fSZachary Turner
GetDummyRemotePath()4601c3243fSZachary Turner static FileSpec GetDummyRemotePath() {
478f3be7a3SJonas Devlieghere FileSpec fs("/", FileSpec::Style::posix);
4801c3243fSZachary Turner fs.AppendPathComponent(dummy_remote_dir);
4901c3243fSZachary Turner fs.AppendPathComponent(module_name);
5001c3243fSZachary Turner return fs;
5101c3243fSZachary Turner }
5201c3243fSZachary Turner
GetUuidView(FileSpec spec)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
GetSysrootView(FileSpec spec,const char * hostname)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
SetUp()675dca0596SRaphael Isemann void ModuleCacheTest::SetUp() {
6860f028ffSPavel Labath s_cache_dir = HostInfo::GetProcessTempDir();
697ed3e22fSPavel Labath s_test_executable = GetInputFilePath(module_name);
7001c3243fSZachary Turner }
7101c3243fSZachary Turner
VerifyDiskState(const FileSpec & cache_dir,const char * hostname)7201c3243fSZachary Turner static void VerifyDiskState(const FileSpec &cache_dir, const char *hostname) {
7301c3243fSZachary Turner FileSpec uuid_view = GetUuidView(cache_dir);
74dbd7fabaSJonas Devlieghere EXPECT_TRUE(FileSystem::Instance().Exists(uuid_view))
75*1b4b12a3SNico Weber << "uuid_view is: " << uuid_view.GetCString();
7659b78bcbSJonas Devlieghere EXPECT_EQ(module_size, FileSystem::Instance().GetByteSize(uuid_view));
7701c3243fSZachary Turner
7801c3243fSZachary Turner FileSpec sysroot_view = GetSysrootView(cache_dir, hostname);
79dbd7fabaSJonas Devlieghere EXPECT_TRUE(FileSystem::Instance().Exists(sysroot_view))
80*1b4b12a3SNico Weber << "sysroot_view is: " << sysroot_view.GetCString();
8159b78bcbSJonas Devlieghere EXPECT_EQ(module_size, FileSystem::Instance().GetByteSize(sysroot_view));
8201c3243fSZachary Turner }
8301c3243fSZachary Turner
TryGetAndPut(const FileSpec & cache_dir,const char * hostname,bool expect_download)8401c3243fSZachary Turner void ModuleCacheTest::TryGetAndPut(const FileSpec &cache_dir,
8501c3243fSZachary Turner const char *hostname, bool expect_download) {
8601c3243fSZachary Turner ModuleCache mc;
8701c3243fSZachary Turner ModuleSpec module_spec;
8801c3243fSZachary Turner module_spec.GetFileSpec() = GetDummyRemotePath();
891beffc18SJaroslav Sevcik module_spec.GetUUID().SetFromStringRef(module_uuid);
9001c3243fSZachary Turner module_spec.SetObjectSize(module_size);
9101c3243fSZachary Turner ModuleSP module_sp;
9201c3243fSZachary Turner bool did_create;
9301c3243fSZachary Turner bool download_called = false;
9401c3243fSZachary Turner
9597206d57SZachary Turner Status error = mc.GetAndPut(
9601c3243fSZachary Turner cache_dir, hostname, module_spec,
975dca0596SRaphael Isemann [&download_called, this](const ModuleSpec &module_spec,
9801c3243fSZachary Turner const FileSpec &tmp_download_file_spec) {
9901c3243fSZachary Turner download_called = true;
100*1b4b12a3SNico Weber EXPECT_STREQ(GetDummyRemotePath().GetCString(),
101*1b4b12a3SNico Weber module_spec.GetFileSpec().GetCString());
10201c3243fSZachary Turner std::error_code ec = llvm::sys::fs::copy_file(
103*1b4b12a3SNico Weber s_test_executable, tmp_download_file_spec.GetCString());
10401c3243fSZachary Turner EXPECT_FALSE(ec);
10597206d57SZachary Turner return Status();
10601c3243fSZachary Turner },
10701c3243fSZachary Turner [](const ModuleSP &module_sp, const FileSpec &tmp_download_file_spec) {
10897206d57SZachary Turner return Status("Not supported.");
10901c3243fSZachary Turner },
11001c3243fSZachary Turner module_sp, &did_create);
11101c3243fSZachary Turner EXPECT_EQ(expect_download, download_called);
11201c3243fSZachary Turner
11301c3243fSZachary Turner EXPECT_TRUE(error.Success()) << "Error was: " << error.AsCString();
11401c3243fSZachary Turner EXPECT_TRUE(did_create);
11501c3243fSZachary Turner ASSERT_TRUE(bool(module_sp));
11601c3243fSZachary Turner
11701c3243fSZachary Turner SymbolContextList sc_list;
1181ad655e2SAdrian Prantl module_sp->FindFunctionSymbols(ConstString("boom"), eFunctionNameTypeFull,
1191ad655e2SAdrian Prantl sc_list);
1201ad655e2SAdrian Prantl EXPECT_EQ(1u, sc_list.GetSize());
121*1b4b12a3SNico Weber EXPECT_STREQ(GetDummyRemotePath().GetCString(),
122*1b4b12a3SNico Weber module_sp->GetPlatformFileSpec().GetCString());
12301c3243fSZachary Turner EXPECT_STREQ(module_uuid, module_sp->GetUUID().GetAsString().c_str());
12401c3243fSZachary Turner }
12501c3243fSZachary Turner
TEST_F(ModuleCacheTest,GetAndPut)12601c3243fSZachary Turner TEST_F(ModuleCacheTest, GetAndPut) {
12701c3243fSZachary Turner FileSpec test_cache_dir = s_cache_dir;
12801c3243fSZachary Turner test_cache_dir.AppendPathComponent("GetAndPut");
12901c3243fSZachary Turner
13001c3243fSZachary Turner const bool expect_download = true;
13101c3243fSZachary Turner TryGetAndPut(test_cache_dir, dummy_hostname, expect_download);
13201c3243fSZachary Turner VerifyDiskState(test_cache_dir, dummy_hostname);
13301c3243fSZachary Turner }
13401c3243fSZachary Turner
TEST_F(ModuleCacheTest,GetAndPutUuidExists)13501c3243fSZachary Turner TEST_F(ModuleCacheTest, GetAndPutUuidExists) {
13601c3243fSZachary Turner FileSpec test_cache_dir = s_cache_dir;
13701c3243fSZachary Turner test_cache_dir.AppendPathComponent("GetAndPutUuidExists");
13801c3243fSZachary Turner
13901c3243fSZachary Turner FileSpec uuid_view = GetUuidView(test_cache_dir);
14001c3243fSZachary Turner std::error_code ec =
14101c3243fSZachary Turner llvm::sys::fs::create_directories(uuid_view.GetDirectory().GetCString());
14201c3243fSZachary Turner ASSERT_FALSE(ec);
143*1b4b12a3SNico Weber ec = llvm::sys::fs::copy_file(s_test_executable, uuid_view.GetCString());
14401c3243fSZachary Turner ASSERT_FALSE(ec);
14501c3243fSZachary Turner
14601c3243fSZachary Turner const bool expect_download = false;
14701c3243fSZachary Turner TryGetAndPut(test_cache_dir, dummy_hostname, expect_download);
14801c3243fSZachary Turner VerifyDiskState(test_cache_dir, dummy_hostname);
14901c3243fSZachary Turner }
15001c3243fSZachary Turner
TEST_F(ModuleCacheTest,GetAndPutStrangeHostname)15101c3243fSZachary Turner TEST_F(ModuleCacheTest, GetAndPutStrangeHostname) {
15201c3243fSZachary Turner FileSpec test_cache_dir = s_cache_dir;
15301c3243fSZachary Turner test_cache_dir.AppendPathComponent("GetAndPutStrangeHostname");
15401c3243fSZachary Turner
15501c3243fSZachary Turner const bool expect_download = true;
15601c3243fSZachary Turner TryGetAndPut(test_cache_dir, "tab\tcolon:asterisk*", expect_download);
15701c3243fSZachary Turner VerifyDiskState(test_cache_dir, "tab_colon_asterisk_");
15801c3243fSZachary Turner }
159