1 //===-- LocateModuleCallbackTest.cpp --------------------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #include "Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.h"
10 #include "Plugins/ObjectFile/ELF/ObjectFileELF.h"
11 #include "Plugins/Platform/Android/PlatformAndroid.h"
12 #include "Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h"
13 #include "Plugins/SymbolFile/Symtab/SymbolFileSymtab.h"
14 #include "TestingSupport/SubsystemRAII.h"
15 #include "TestingSupport/TestUtilities.h"
16 #include "lldb/Core/Debugger.h"
17 #include "lldb/Core/PluginManager.h"
18 #include "lldb/Host/HostInfo.h"
19 #include "lldb/Target/Target.h"
20 #include "gmock/gmock.h"
23 using namespace lldb_private
;
24 using namespace lldb_private::platform_android
;
25 using namespace lldb_private::platform_linux
;
26 using namespace lldb_private::breakpad
;
27 using namespace testing
;
31 constexpr llvm::StringLiteral
k_process_plugin("mock-process-plugin");
32 constexpr llvm::StringLiteral
k_platform_dir("remote-android");
33 constexpr llvm::StringLiteral
k_cache_dir(".cache");
34 constexpr llvm::StringLiteral
k_module_file("AndroidModule.so");
35 constexpr llvm::StringLiteral
k_symbol_file("AndroidModule.unstripped.so");
36 constexpr llvm::StringLiteral
k_breakpad_symbol_file("AndroidModule.so.sym");
37 constexpr llvm::StringLiteral
k_arch("aarch64-none-linux");
38 constexpr llvm::StringLiteral
39 k_module_uuid("80008338-82A0-51E5-5922-C905D23890DA-BDDEFECC");
40 constexpr llvm::StringLiteral
k_function_symbol("boom");
41 constexpr llvm::StringLiteral
k_hidden_function_symbol("boom_hidden");
42 const size_t k_module_size
= 3784;
44 ModuleSpec
GetTestModuleSpec();
46 class MockProcess
: public Process
{
48 MockProcess(TargetSP target_sp
, ListenerSP listener_sp
)
49 : Process(target_sp
, listener_sp
) {}
51 llvm::StringRef
GetPluginName() override
{ return k_process_plugin
; };
53 bool CanDebug(TargetSP target
, bool plugin_specified_by_name
) override
{
57 Status
DoDestroy() override
{ return Status(); }
59 void RefreshStateAfterStop() override
{}
61 bool DoUpdateThreadList(ThreadList
&old_thread_list
,
62 ThreadList
&new_thread_list
) override
{
66 size_t DoReadMemory(addr_t vm_addr
, void *buf
, size_t size
,
67 Status
&error
) override
{
71 bool GetModuleSpec(const FileSpec
&module_file_spec
, const ArchSpec
&arch
,
72 ModuleSpec
&module_spec
) override
{
73 module_spec
= GetTestModuleSpec();
78 FileSpec
GetTestDir() {
79 const auto *info
= UnitTest::GetInstance()->current_test_info();
80 FileSpec test_dir
= HostInfo::GetProcessTempDir();
81 test_dir
.AppendPathComponent(std::string(info
->test_case_name()) + "-" +
83 std::error_code ec
= llvm::sys::fs::create_directory(test_dir
.GetPath());
88 FileSpec
GetRemotePath() {
89 FileSpec
fs("/", FileSpec::Style::posix
);
90 fs
.AppendPathComponent("bin");
91 fs
.AppendPathComponent(k_module_file
);
95 FileSpec
GetUuidView(FileSpec spec
) {
96 spec
.AppendPathComponent(k_platform_dir
);
97 spec
.AppendPathComponent(k_cache_dir
);
98 spec
.AppendPathComponent(k_module_uuid
);
99 spec
.AppendPathComponent(k_module_file
);
103 void BuildEmptyCacheDir(const FileSpec
&test_dir
) {
104 FileSpec
cache_dir(test_dir
);
105 cache_dir
.AppendPathComponent(k_platform_dir
);
106 cache_dir
.AppendPathComponent(k_cache_dir
);
107 std::error_code ec
= llvm::sys::fs::create_directories(cache_dir
.GetPath());
111 FileSpec
BuildCacheDir(const FileSpec
&test_dir
) {
112 FileSpec uuid_view
= GetUuidView(test_dir
);
114 llvm::sys::fs::create_directories(uuid_view
.GetDirectory().GetCString());
116 ec
= llvm::sys::fs::copy_file(GetInputFilePath(k_module_file
),
117 uuid_view
.GetPath().c_str());
122 FileSpec
GetSymFileSpec(const FileSpec
&uuid_view
) {
123 return FileSpec(uuid_view
.GetPath() + ".sym");
126 FileSpec
BuildCacheDirWithSymbol(const FileSpec
&test_dir
) {
127 FileSpec uuid_view
= BuildCacheDir(test_dir
);
129 llvm::sys::fs::copy_file(GetInputFilePath(k_symbol_file
),
130 GetSymFileSpec(uuid_view
).GetPath().c_str());
135 FileSpec
BuildCacheDirWithBreakpadSymbol(const FileSpec
&test_dir
) {
136 FileSpec uuid_view
= BuildCacheDir(test_dir
);
138 llvm::sys::fs::copy_file(GetInputFilePath(k_breakpad_symbol_file
),
139 GetSymFileSpec(uuid_view
).GetPath().c_str());
144 ModuleSpec
GetTestModuleSpec() {
145 ModuleSpec
module_spec(GetRemotePath(), ArchSpec(k_arch
));
146 module_spec
.GetUUID().SetFromStringRef(k_module_uuid
);
147 module_spec
.SetObjectSize(k_module_size
);
151 void CheckModule(const ModuleSP
&module_sp
) {
152 ASSERT_TRUE(module_sp
);
153 ASSERT_EQ(module_sp
->GetUUID().GetAsString(), k_module_uuid
);
154 ASSERT_EQ(module_sp
->GetObjectOffset(), 0U);
155 ASSERT_EQ(module_sp
->GetPlatformFileSpec(), GetRemotePath());
158 SymbolContextList
FindFunctions(const ModuleSP
&module_sp
,
159 const llvm::StringRef
&name
) {
160 SymbolContextList sc_list
;
161 ModuleFunctionSearchOptions function_options
;
162 function_options
.include_symbols
= true;
163 function_options
.include_inlines
= true;
164 FunctionNameType type
= static_cast<FunctionNameType
>(eSymbolTypeCode
);
165 module_sp
->FindFunctions(ConstString(name
), CompilerDeclContext(), type
,
166 function_options
, sc_list
);
170 void CheckStrippedSymbol(const ModuleSP
&module_sp
) {
171 SymbolContextList sc_list
= FindFunctions(module_sp
, k_function_symbol
);
172 EXPECT_EQ(1U, sc_list
.GetSize());
174 sc_list
= FindFunctions(module_sp
, k_hidden_function_symbol
);
175 EXPECT_EQ(0U, sc_list
.GetSize());
178 void CheckUnstrippedSymbol(const ModuleSP
&module_sp
) {
179 SymbolContextList sc_list
= FindFunctions(module_sp
, k_function_symbol
);
180 EXPECT_EQ(1U, sc_list
.GetSize());
182 sc_list
= FindFunctions(module_sp
, k_hidden_function_symbol
);
183 EXPECT_EQ(1U, sc_list
.GetSize());
186 ProcessSP
MockProcessCreateInstance(TargetSP target_sp
, ListenerSP listener_sp
,
187 const FileSpec
*crash_file_path
,
189 return std::make_shared
<MockProcess
>(target_sp
, listener_sp
);
192 class LocateModuleCallbackTest
: public testing::Test
{
193 SubsystemRAII
<FileSystem
, HostInfo
, ObjectFileBreakpad
, ObjectFileELF
,
194 PlatformAndroid
, PlatformLinux
, SymbolFileBreakpad
,
199 void SetUp() override
{
200 m_test_dir
= GetTestDir();
202 // Set module cache directory for PlatformAndroid.
203 PlatformAndroid::GetGlobalPlatformProperties().SetModuleCacheDirectory(
207 ArchSpec
host_arch("i386-pc-linux");
208 Platform::SetHostPlatform(
209 platform_linux::PlatformLinux::CreateInstance(true, &host_arch
));
210 m_debugger_sp
= Debugger::CreateInstance();
211 EXPECT_TRUE(m_debugger_sp
);
213 // Create PlatformAndroid.
214 ArchSpec
arch(k_arch
);
215 m_platform_sp
= PlatformAndroid::CreateInstance(true, &arch
);
216 EXPECT_TRUE(m_platform_sp
);
219 m_debugger_sp
->GetTargetList().CreateTarget(*m_debugger_sp
, "", arch
,
221 m_platform_sp
, m_target_sp
);
222 EXPECT_TRUE(m_target_sp
);
224 // Create MockProcess.
225 PluginManager::RegisterPlugin(k_process_plugin
, "",
226 MockProcessCreateInstance
);
228 m_target_sp
->CreateProcess(Listener::MakeListener("test-listener"),
229 k_process_plugin
, /*crash_file=*/nullptr,
230 /*can_connect=*/true);
231 EXPECT_TRUE(m_process_sp
);
233 m_module_spec
= GetTestModuleSpec();
236 void CheckNoCallback() {
237 EXPECT_FALSE(m_platform_sp
->GetLocateModuleCallback());
238 EXPECT_EQ(m_callback_call_count
, 0);
241 void CheckCallbackArgs(const ModuleSpec
&module_spec
,
242 FileSpec
&module_file_spec
,
243 FileSpec
&symbol_file_spec
) {
244 EXPECT_TRUE(m_module_spec
.Matches(module_spec
,
245 /*exact_arch_match=*/true));
246 EXPECT_FALSE(module_file_spec
);
247 EXPECT_FALSE(symbol_file_spec
);
249 EXPECT_EQ(m_callback_call_count
, 0);
250 m_callback_call_count
++;
255 DebuggerSP m_debugger_sp
;
256 PlatformSP m_platform_sp
;
257 TargetSP m_target_sp
;
258 ProcessSP m_process_sp
;
259 ModuleSpec m_module_spec
;
260 int m_callback_call_count
= 0;
265 TEST_F(LocateModuleCallbackTest
, GetOrCreateModuleWithCachedModule
) {
266 // The module file is cached, and the locate module callback is not set.
267 // GetOrCreateModule should succeed to return the module from the cache.
268 FileSpec uuid_view
= BuildCacheDir(m_test_dir
);
273 m_target_sp
->GetOrCreateModule(m_module_spec
, /*notify=*/false);
274 CheckModule(module_sp
);
275 ASSERT_EQ(module_sp
->GetFileSpec(), uuid_view
);
276 ASSERT_FALSE(module_sp
->GetSymbolFileFileSpec());
277 CheckStrippedSymbol(module_sp
);
280 TEST_F(LocateModuleCallbackTest
, GetOrCreateModuleWithCachedModuleAndSymbol
) {
281 // The module and symbol files are cached, and the locate module callback is
282 // not set. GetOrCreateModule should succeed to return the module from the
283 // cache with the symbol.
284 FileSpec uuid_view
= BuildCacheDirWithSymbol(m_test_dir
);
289 m_target_sp
->GetOrCreateModule(m_module_spec
, /*notify=*/false);
290 CheckModule(module_sp
);
291 ASSERT_EQ(module_sp
->GetFileSpec(), uuid_view
);
292 ASSERT_EQ(module_sp
->GetSymbolFileFileSpec(), GetSymFileSpec(uuid_view
));
293 CheckUnstrippedSymbol(module_sp
);
296 TEST_F(LocateModuleCallbackTest
,
297 GetOrCreateModuleWithCachedModuleAndBreakpadSymbol
) {
298 // The module file and breakpad symbol file are cached, and the locate module
299 // callback is not set. GetOrCreateModule should succeed to return the module
300 // from the cache with the symbol.
301 FileSpec uuid_view
= BuildCacheDirWithBreakpadSymbol(m_test_dir
);
306 m_target_sp
->GetOrCreateModule(m_module_spec
, /*notify=*/false);
307 CheckModule(module_sp
);
308 ASSERT_EQ(module_sp
->GetFileSpec(), uuid_view
);
309 ASSERT_EQ(module_sp
->GetSymbolFileFileSpec(), GetSymFileSpec(uuid_view
));
310 CheckUnstrippedSymbol(module_sp
);
313 TEST_F(LocateModuleCallbackTest
, GetOrCreateModuleFailure
) {
314 // The cache dir is empty, and the locate module callback is not set.
315 // GetOrCreateModule should fail because PlatformAndroid tries to download the
317 BuildEmptyCacheDir(m_test_dir
);
322 m_target_sp
->GetOrCreateModule(m_module_spec
, /*notify=*/false);
323 ASSERT_FALSE(module_sp
);
326 TEST_F(LocateModuleCallbackTest
, GetOrCreateModuleCallbackFailureNoCache
) {
327 // The cache dir is empty, also the locate module callback fails for some
328 // reason. GetOrCreateModule should fail because PlatformAndroid tries to
329 // download the module and fails.
330 BuildEmptyCacheDir(m_test_dir
);
332 m_platform_sp
->SetLocateModuleCallback([this](const ModuleSpec
&module_spec
,
333 FileSpec
&module_file_spec
,
334 FileSpec
&symbol_file_spec
) {
335 CheckCallbackArgs(module_spec
, module_file_spec
, symbol_file_spec
);
336 return Status("The locate module callback failed");
340 m_target_sp
->GetOrCreateModule(m_module_spec
, /*notify=*/false);
341 ASSERT_FALSE(module_sp
);
344 TEST_F(LocateModuleCallbackTest
, GetOrCreateModuleCallbackFailureCached
) {
345 // The module file is cached, so GetOrCreateModule should succeed to return
346 // the module from the cache even though the locate module callback fails for
348 FileSpec uuid_view
= BuildCacheDir(m_test_dir
);
350 m_platform_sp
->SetLocateModuleCallback([this](const ModuleSpec
&module_spec
,
351 FileSpec
&module_file_spec
,
352 FileSpec
&symbol_file_spec
) {
353 CheckCallbackArgs(module_spec
, module_file_spec
, symbol_file_spec
);
354 return Status("The locate module callback failed");
358 m_target_sp
->GetOrCreateModule(m_module_spec
, /*notify=*/false);
359 CheckModule(module_sp
);
360 ASSERT_EQ(module_sp
->GetFileSpec(), uuid_view
);
361 ASSERT_FALSE(module_sp
->GetSymbolFileFileSpec());
362 CheckStrippedSymbol(module_sp
);
365 TEST_F(LocateModuleCallbackTest
, GetOrCreateModuleCallbackNoFiles
) {
366 // The module file is cached, so GetOrCreateModule should succeed to return
367 // the module from the cache even though the locate module callback returns
369 FileSpec uuid_view
= BuildCacheDir(m_test_dir
);
371 m_platform_sp
->SetLocateModuleCallback([this](const ModuleSpec
&module_spec
,
372 FileSpec
&module_file_spec
,
373 FileSpec
&symbol_file_spec
) {
374 CheckCallbackArgs(module_spec
, module_file_spec
, symbol_file_spec
);
375 // The locate module callback succeeds but it does not set
376 // module_file_spec nor symbol_file_spec.
381 m_target_sp
->GetOrCreateModule(m_module_spec
, /*notify=*/false);
382 CheckModule(module_sp
);
383 ASSERT_EQ(module_sp
->GetFileSpec(), uuid_view
);
384 ASSERT_FALSE(module_sp
->GetSymbolFileFileSpec());
385 CheckStrippedSymbol(module_sp
);
388 TEST_F(LocateModuleCallbackTest
, GetOrCreateModuleCallbackNonExistentModule
) {
389 // The module file is cached, so GetOrCreateModule should succeed to return
390 // the module from the cache even though the locate module callback returns
391 // non-existent module file.
392 FileSpec uuid_view
= BuildCacheDir(m_test_dir
);
394 m_platform_sp
->SetLocateModuleCallback([this](const ModuleSpec
&module_spec
,
395 FileSpec
&module_file_spec
,
396 FileSpec
&symbol_file_spec
) {
397 CheckCallbackArgs(module_spec
, module_file_spec
, symbol_file_spec
);
398 module_file_spec
.SetPath("/this path does not exist");
403 m_target_sp
->GetOrCreateModule(m_module_spec
, /*notify=*/false);
404 CheckModule(module_sp
);
405 ASSERT_EQ(module_sp
->GetFileSpec(), uuid_view
);
406 ASSERT_FALSE(module_sp
->GetSymbolFileFileSpec());
407 CheckStrippedSymbol(module_sp
);
410 TEST_F(LocateModuleCallbackTest
, GetOrCreateModuleCallbackNonExistentSymbol
) {
411 // The module file is cached, so GetOrCreateModule should succeed to return
412 // the module from the cache even though the locate module callback returns
413 // non-existent symbol file.
414 FileSpec uuid_view
= BuildCacheDir(m_test_dir
);
416 m_platform_sp
->SetLocateModuleCallback([this](const ModuleSpec
&module_spec
,
417 FileSpec
&module_file_spec
,
418 FileSpec
&symbol_file_spec
) {
419 CheckCallbackArgs(module_spec
, module_file_spec
, symbol_file_spec
);
420 // The locate module callback returns a right module file.
421 module_file_spec
.SetPath(GetInputFilePath(k_module_file
));
422 // But it returns non-existent symbols file.
423 symbol_file_spec
.SetPath("/this path does not exist");
428 m_target_sp
->GetOrCreateModule(m_module_spec
, /*notify=*/false);
429 CheckModule(module_sp
);
430 ASSERT_EQ(module_sp
->GetFileSpec(), uuid_view
);
431 ASSERT_TRUE(module_sp
->GetSymbolFileFileSpec().GetPath().empty());
432 CheckStrippedSymbol(module_sp
);
435 TEST_F(LocateModuleCallbackTest
, GetOrCreateModuleCallbackSuccessWithModule
) {
436 // The locate module callback returns a module file, GetOrCreateModule should
437 // succeed to return the module from the Inputs directory.
438 BuildEmptyCacheDir(m_test_dir
);
440 m_platform_sp
->SetLocateModuleCallback([this](const ModuleSpec
&module_spec
,
441 FileSpec
&module_file_spec
,
442 FileSpec
&symbol_file_spec
) {
443 CheckCallbackArgs(module_spec
, module_file_spec
, symbol_file_spec
);
444 module_file_spec
.SetPath(GetInputFilePath(k_module_file
));
449 m_target_sp
->GetOrCreateModule(m_module_spec
, /*notify=*/false);
450 CheckModule(module_sp
);
451 ASSERT_EQ(module_sp
->GetFileSpec(),
452 FileSpec(GetInputFilePath(k_module_file
)));
453 ASSERT_FALSE(module_sp
->GetSymbolFileFileSpec());
454 CheckStrippedSymbol(module_sp
);
457 TEST_F(LocateModuleCallbackTest
,
458 GetOrCreateModuleCallbackSuccessWithSymbolAsModule
) {
459 // The locate module callback returns the symbol file as a module file. It
460 // should work since the sections and UUID of the symbol file are the exact
461 // same with the module file, GetOrCreateModule should succeed to return the
462 // module with the symbol file from Inputs directory.
463 BuildEmptyCacheDir(m_test_dir
);
465 m_platform_sp
->SetLocateModuleCallback([this](const ModuleSpec
&module_spec
,
466 FileSpec
&module_file_spec
,
467 FileSpec
&symbol_file_spec
) {
468 CheckCallbackArgs(module_spec
, module_file_spec
, symbol_file_spec
);
469 module_file_spec
.SetPath(GetInputFilePath(k_symbol_file
));
474 m_target_sp
->GetOrCreateModule(m_module_spec
, /*notify=*/false);
475 CheckModule(module_sp
);
476 ASSERT_EQ(module_sp
->GetFileSpec(),
477 FileSpec(GetInputFilePath(k_symbol_file
)));
478 ASSERT_FALSE(module_sp
->GetSymbolFileFileSpec());
479 CheckUnstrippedSymbol(module_sp
);
482 TEST_F(LocateModuleCallbackTest
,
483 GetOrCreateModuleCallbackSuccessWithSymbolAsModuleAndSymbol
) {
484 // The locate module callback returns a symbol file as both a module file and
485 // a symbol file. It should work since the sections and UUID of the symbol
486 // file are the exact same with the module file, GetOrCreateModule should
487 // succeed to return the module with the symbol file from Inputs directory.
488 BuildEmptyCacheDir(m_test_dir
);
490 m_platform_sp
->SetLocateModuleCallback([this](const ModuleSpec
&module_spec
,
491 FileSpec
&module_file_spec
,
492 FileSpec
&symbol_file_spec
) {
493 CheckCallbackArgs(module_spec
, module_file_spec
, symbol_file_spec
);
494 module_file_spec
.SetPath(GetInputFilePath(k_symbol_file
));
495 symbol_file_spec
.SetPath(GetInputFilePath(k_symbol_file
));
500 m_target_sp
->GetOrCreateModule(m_module_spec
, /*notify=*/false);
501 CheckModule(module_sp
);
502 ASSERT_EQ(module_sp
->GetFileSpec(),
503 FileSpec(GetInputFilePath(k_symbol_file
)));
504 ASSERT_EQ(module_sp
->GetSymbolFileFileSpec(),
505 FileSpec(GetInputFilePath(k_symbol_file
)));
506 CheckUnstrippedSymbol(module_sp
);
509 TEST_F(LocateModuleCallbackTest
,
510 GetOrCreateModuleCallbackSuccessWithModuleAndSymbol
) {
511 // The locate module callback returns a module file and a symbol file,
512 // GetOrCreateModule should succeed to return the module from Inputs
513 // directory, along with the symbol file.
514 BuildEmptyCacheDir(m_test_dir
);
516 m_platform_sp
->SetLocateModuleCallback([this](const ModuleSpec
&module_spec
,
517 FileSpec
&module_file_spec
,
518 FileSpec
&symbol_file_spec
) {
519 CheckCallbackArgs(module_spec
, module_file_spec
, symbol_file_spec
);
520 module_file_spec
.SetPath(GetInputFilePath(k_module_file
));
521 symbol_file_spec
.SetPath(GetInputFilePath(k_symbol_file
));
526 m_target_sp
->GetOrCreateModule(m_module_spec
, /*notify=*/false);
527 CheckModule(module_sp
);
528 ASSERT_EQ(module_sp
->GetFileSpec(),
529 FileSpec(GetInputFilePath(k_module_file
)));
530 ASSERT_EQ(module_sp
->GetSymbolFileFileSpec(),
531 FileSpec(GetInputFilePath(k_symbol_file
)));
532 CheckUnstrippedSymbol(module_sp
);
535 TEST_F(LocateModuleCallbackTest
,
536 GetOrCreateModuleCallbackSuccessWithModuleAndBreakpadSymbol
) {
537 // The locate module callback returns a module file and a breakpad symbol
538 // file, GetOrCreateModule should succeed to return the module with the symbol
539 // file from Inputs directory.
540 BuildEmptyCacheDir(m_test_dir
);
542 m_platform_sp
->SetLocateModuleCallback([this](const ModuleSpec
&module_spec
,
543 FileSpec
&module_file_spec
,
544 FileSpec
&symbol_file_spec
) {
545 CheckCallbackArgs(module_spec
, module_file_spec
, symbol_file_spec
);
546 module_file_spec
.SetPath(GetInputFilePath(k_module_file
));
547 symbol_file_spec
.SetPath(GetInputFilePath(k_breakpad_symbol_file
));
552 m_target_sp
->GetOrCreateModule(m_module_spec
, /*notify=*/false);
553 CheckModule(module_sp
);
554 ASSERT_EQ(module_sp
->GetFileSpec(),
555 FileSpec(GetInputFilePath(k_module_file
)));
556 ASSERT_EQ(module_sp
->GetSymbolFileFileSpec(),
557 FileSpec(GetInputFilePath(k_breakpad_symbol_file
)));
558 CheckUnstrippedSymbol(module_sp
);
561 TEST_F(LocateModuleCallbackTest
,
562 GetOrCreateModuleCallbackSuccessWithOnlySymbol
) {
563 // The get callback returns only a symbol file, and the module is cached,
564 // GetOrCreateModule should succeed to return the module from the cache
565 // along with the symbol file from the Inputs directory.
566 FileSpec uuid_view
= BuildCacheDir(m_test_dir
);
568 m_platform_sp
->SetLocateModuleCallback([this](const ModuleSpec
&module_spec
,
569 FileSpec
&module_file_spec
,
570 FileSpec
&symbol_file_spec
) {
571 CheckCallbackArgs(module_spec
, module_file_spec
, symbol_file_spec
);
572 symbol_file_spec
.SetPath(GetInputFilePath(k_symbol_file
));
577 m_target_sp
->GetOrCreateModule(m_module_spec
, /*notify=*/false);
578 CheckModule(module_sp
);
579 ASSERT_EQ(module_sp
->GetFileSpec(), uuid_view
);
580 ASSERT_EQ(module_sp
->GetSymbolFileFileSpec(),
581 FileSpec(GetInputFilePath(k_symbol_file
)));
582 CheckUnstrippedSymbol(module_sp
);
585 TEST_F(LocateModuleCallbackTest
,
586 GetOrCreateModuleCallbackSuccessWithOnlyBreakpadSymbol
) {
587 // The get callback returns only a breakpad symbol file, and the module is
588 // cached, GetOrCreateModule should succeed to return the module from the
589 // cache along with the symbol file from the Inputs directory.
590 FileSpec uuid_view
= BuildCacheDir(m_test_dir
);
592 m_platform_sp
->SetLocateModuleCallback([this](const ModuleSpec
&module_spec
,
593 FileSpec
&module_file_spec
,
594 FileSpec
&symbol_file_spec
) {
595 CheckCallbackArgs(module_spec
, module_file_spec
, symbol_file_spec
);
596 symbol_file_spec
.SetPath(GetInputFilePath(k_breakpad_symbol_file
));
601 m_target_sp
->GetOrCreateModule(m_module_spec
, /*notify=*/false);
602 CheckModule(module_sp
);
603 ASSERT_EQ(module_sp
->GetFileSpec(), uuid_view
);
604 ASSERT_EQ(module_sp
->GetSymbolFileFileSpec(),
605 FileSpec(GetInputFilePath(k_breakpad_symbol_file
)));
606 CheckUnstrippedSymbol(module_sp
);
609 TEST_F(LocateModuleCallbackTest
,
610 GetOrCreateModuleNoCacheWithCallbackOnlySymbol
) {
611 // The get callback returns only a symbol file, but the module is not
612 // cached, GetOrCreateModule should fail because of the missing module.
613 BuildEmptyCacheDir(m_test_dir
);
615 m_platform_sp
->SetLocateModuleCallback([this](const ModuleSpec
&module_spec
,
616 FileSpec
&module_file_spec
,
617 FileSpec
&symbol_file_spec
) {
618 CheckCallbackArgs(module_spec
, module_file_spec
, symbol_file_spec
);
619 symbol_file_spec
.SetPath(GetInputFilePath(k_symbol_file
));
624 m_target_sp
->GetOrCreateModule(m_module_spec
, /*notify=*/false);
625 ASSERT_FALSE(module_sp
);
628 TEST_F(LocateModuleCallbackTest
,
629 GetOrCreateModuleNoCacheWithCallbackOnlyBreakpadSymbol
) {
630 // The get callback returns only a breakpad symbol file, but the module is not
631 // cached, GetOrCreateModule should fail because of the missing module.
632 BuildEmptyCacheDir(m_test_dir
);
634 m_platform_sp
->SetLocateModuleCallback([this](const ModuleSpec
&module_spec
,
635 FileSpec
&module_file_spec
,
636 FileSpec
&symbol_file_spec
) {
637 CheckCallbackArgs(module_spec
, module_file_spec
, symbol_file_spec
);
638 symbol_file_spec
.SetPath(GetInputFilePath(k_breakpad_symbol_file
));
643 m_target_sp
->GetOrCreateModule(m_module_spec
, /*notify=*/false);
644 ASSERT_FALSE(module_sp
);