Skip to content

Commit ac49fd8

Browse files
committed
[lldb-dap] In DAP unit tests, add helpers for loading a CoreFile.
This allows us to have a SBTarget and SBProcess for creating unit tests.
1 parent 21b4059 commit ac49fd8

File tree

7 files changed

+106
-2
lines changed

7 files changed

+106
-2
lines changed

lldb/tools/lldb-dap/Protocol/ProtocolBase.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,11 @@ using Message = std::variant<Request, Response, Event>;
141141
bool fromJSON(const llvm::json::Value &, Message &, llvm::json::Path);
142142
llvm::json::Value toJSON(const Message &);
143143

144+
inline llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const Message &V) {
145+
OS << toJSON(V);
146+
return OS;
147+
}
148+
144149
/// On error (whenever `success` is false), the body can provide more details.
145150
struct ErrorResponseBody {
146151
/// A structured error message.

lldb/unittests/DAP/CMakeLists.txt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,16 @@ add_lldb_unittest(DAPTests
1010
VariablesTest.cpp
1111

1212
LINK_LIBS
13+
liblldb
1314
lldbDAP
15+
lldbUtilityHelpers
1416
LLVMTestingSupport
1517
LINK_COMPONENTS
1618
Support
1719
)
20+
21+
set(test_inputs
22+
linux-x86_64.out
23+
linux-x86_64.core
24+
)
25+
add_unittest_inputs(DAPTests "${test_inputs}")

lldb/unittests/DAP/Handler/DisconnectTest.cpp

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,10 @@
1010
#include "Handler/RequestHandler.h"
1111
#include "Protocol/ProtocolBase.h"
1212
#include "TestBase.h"
13+
#include "lldb/API/SBDefines.h"
14+
#include "lldb/lldb-enumerations.h"
1315
#include "llvm/Testing/Support/Error.h"
16+
#include "gmock/gmock.h"
1417
#include "gtest/gtest.h"
1518
#include <memory>
1619
#include <optional>
@@ -23,13 +26,38 @@ using namespace lldb_dap::protocol;
2326

2427
class DisconnectRequestHandlerTest : public DAPTestBase {};
2528

26-
TEST_F(DisconnectRequestHandlerTest, DisconnectingTriggersTerminated) {
29+
TEST_F(DisconnectRequestHandlerTest, DisconnectTriggersTerminated) {
2730
DisconnectRequestHandler handler(*dap);
2831
EXPECT_FALSE(dap->disconnecting);
2932
ASSERT_THAT_ERROR(handler.Run(std::nullopt), Succeeded());
3033
EXPECT_TRUE(dap->disconnecting);
3134
std::vector<Message> messages = DrainOutput();
3235
EXPECT_THAT(messages,
3336
testing::Contains(testing::VariantWith<Event>(testing::FieldsAre(
34-
/*event=*/"terminated", /*body=*/std::nullopt))));
37+
/*event=*/"terminated", /*body=*/testing::_))));
38+
}
39+
40+
TEST_F(DisconnectRequestHandlerTest, DisconnectTriggersTerminateCommands) {
41+
CreateDebugger();
42+
43+
if (!GetDebuggerSupportsTarget("X86"))
44+
GTEST_SKIP() << "Unsupported platform";
45+
46+
LoadCore(DAPTestBase::k_linux_binary, DAPTestBase::k_linux_core);
47+
48+
DisconnectRequestHandler handler(*dap);
49+
50+
EXPECT_FALSE(dap->disconnecting);
51+
dap->configuration.terminateCommands = {"?script print(1)",
52+
"script print(2)"};
53+
EXPECT_EQ(dap->target.GetProcess().GetState(), lldb::eStateStopped);
54+
ASSERT_THAT_ERROR(handler.Run(std::nullopt), Succeeded());
55+
EXPECT_TRUE(dap->disconnecting);
56+
std::vector<Message> messages = DrainOutput();
57+
EXPECT_THAT(messages, testing::ElementsAre(
58+
OutputMatcher("Running terminateCommands:\n"),
59+
OutputMatcher("(lldb) script print(2)\n"),
60+
OutputMatcher("2\n"),
61+
testing::VariantWith<Event>(testing::FieldsAre(
62+
/*event=*/"terminated", /*body=*/testing::_))));
3563
}
48 KB
Binary file not shown.
2.51 KB
Binary file not shown.

lldb/unittests/DAP/TestBase.cpp

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,16 @@
88

99
#include "TestBase.h"
1010
#include "Protocol/ProtocolBase.h"
11+
#include "TestingSupport/TestUtilities.h"
12+
#include "lldb/API/SBDefines.h"
13+
#include "lldb/API/SBStructuredData.h"
1114
#include "lldb/Host/File.h"
1215
#include "lldb/Host/Pipe.h"
16+
#include "lldb/lldb-forward.h"
17+
#include "llvm/ADT/StringRef.h"
1318
#include "llvm/Testing/Support/Error.h"
19+
#include "gtest/gtest.h"
20+
#include <memory>
1421

1522
using namespace llvm;
1623
using namespace lldb;
@@ -55,6 +62,43 @@ void DAPTestBase::SetUp() {
5562
/*transport=*/*to_dap);
5663
}
5764

65+
void DAPTestBase::SetUpTestSuite() {
66+
lldb::SBError error = SBDebugger::InitializeWithErrorHandling();
67+
EXPECT_TRUE(error.Success());
68+
}
69+
void DAPTestBase::TeatUpTestSuite() { SBDebugger::Terminate(); }
70+
71+
bool DAPTestBase::GetDebuggerSupportsTarget(llvm::StringRef platform) {
72+
EXPECT_TRUE(dap->debugger);
73+
74+
lldb::SBStructuredData data = dap->debugger.GetBuildConfiguration()
75+
.GetValueForKey("targets")
76+
.GetValueForKey("value");
77+
for (size_t i = 0; i < data.GetSize(); i++) {
78+
char buf[100] = {0};
79+
size_t size = data.GetItemAtIndex(i).GetStringValue(buf, sizeof(buf));
80+
if (llvm::StringRef(buf, size) == platform)
81+
return true;
82+
}
83+
84+
return false;
85+
}
86+
87+
void DAPTestBase::CreateDebugger() {
88+
dap->debugger = lldb::SBDebugger::Create();
89+
ASSERT_TRUE(dap->debugger);
90+
}
91+
92+
void DAPTestBase::LoadCore(llvm::StringRef binary, llvm::StringRef core) {
93+
ASSERT_TRUE(dap->debugger);
94+
dap->target =
95+
dap->debugger.CreateTarget(lldb_private::GetInputFilePath(binary).data());
96+
ASSERT_TRUE(dap->target);
97+
SBProcess process =
98+
dap->target.LoadCore(lldb_private::GetInputFilePath(core).data());
99+
ASSERT_TRUE(process);
100+
}
101+
58102
std::vector<Message> DAPTestBase::DrainOutput() {
59103
std::vector<Message> msgs;
60104
output.CloseWriteFileDescriptor();

lldb/unittests/DAP/TestBase.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
#include "Protocol/ProtocolBase.h"
1111
#include "Transport.h"
1212
#include "lldb/Host/Pipe.h"
13+
#include "llvm/ADT/StringRef.h"
14+
#include "gmock/gmock.h"
1315
#include "gtest/gtest.h"
1416

1517
namespace lldb_dap_tests {
@@ -33,13 +35,30 @@ class TransportBase : public PipeBase {
3335
void SetUp() override;
3436
};
3537

38+
/// Matches an "output" event.
39+
inline auto OutputMatcher(const llvm::StringRef output,
40+
const llvm::StringRef category = "console") {
41+
return testing::VariantWith<lldb_dap::protocol::Event>(testing::FieldsAre(
42+
/*event=*/"output", /*body=*/testing::Optional<llvm::json::Value>(
43+
llvm::json::Object{{"category", category}, {"output", output}})));
44+
}
45+
3646
/// A base class for tests that interact with a `lldb_dap::DAP` instance.
3747
class DAPTestBase : public TransportBase {
3848
protected:
3949
std::unique_ptr<lldb_dap::DAP> dap;
4050

51+
static constexpr llvm::StringLiteral k_linux_binary = "linux-x86_64.out";
52+
static constexpr llvm::StringLiteral k_linux_core = "linux-x86_64.core";
53+
54+
static void SetUpTestSuite();
55+
static void TeatUpTestSuite();
4156
void SetUp() override;
4257

58+
bool GetDebuggerSupportsTarget(llvm::StringRef platform);
59+
void CreateDebugger();
60+
void LoadCore(llvm::StringRef binary, llvm::StringRef core);
61+
4362
/// Closes the DAP output pipe and returns the remaining protocol messages in
4463
/// the buffer.
4564
std::vector<lldb_dap::protocol::Message> DrainOutput();

0 commit comments

Comments
 (0)