Skip to content

Commit 2d57b61

Browse files
authored
[lldb-dap] Add unit test for breakpoint types (#139792)
- Add unit test for breakpoint types for SourceBreakpoint, FunctionBreakpoint and DataBreakpoint. - Rename DataBreakpointInfo to DataBreakpoint. - Fix some mapOptions for optional fields.
1 parent 7460056 commit 2d57b61

File tree

6 files changed

+131
-22
lines changed

6 files changed

+131
-22
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -693,7 +693,7 @@ llvm::json::Value toJSON(const DataBreakpointInfoResponseBody &);
693693
struct SetDataBreakpointsArguments {
694694
/// The contents of this array replaces all existing data breakpoints. An
695695
/// empty array clears all data breakpoints.
696-
std::vector<DataBreakpointInfo> breakpoints;
696+
std::vector<DataBreakpoint> breakpoints;
697697
};
698698
bool fromJSON(const llvm::json::Value &, SetDataBreakpointsArguments &,
699699
llvm::json::Path);

lldb/tools/lldb-dap/Protocol/ProtocolTypes.cpp

Lines changed: 61 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -446,18 +446,48 @@ bool fromJSON(const llvm::json::Value &Params, Breakpoint &BP,
446446

447447
bool fromJSON(const llvm::json::Value &Params, SourceBreakpoint &SB,
448448
llvm::json::Path P) {
449-
json::ObjectMapper O(Params, P);
450-
return O && O.map("line", SB.line) && O.map("column", SB.column) &&
451-
O.map("condition", SB.condition) &&
452-
O.map("hitCondition", SB.hitCondition) &&
453-
O.map("logMessage", SB.logMessage) && O.map("mode", SB.mode);
449+
llvm::json::ObjectMapper O(Params, P);
450+
return O && O.map("line", SB.line) && O.mapOptional("column", SB.column) &&
451+
O.mapOptional("condition", SB.condition) &&
452+
O.mapOptional("hitCondition", SB.hitCondition) &&
453+
O.mapOptional("logMessage", SB.logMessage) &&
454+
O.mapOptional("mode", SB.mode);
455+
}
456+
457+
llvm::json::Value toJSON(const SourceBreakpoint &SB) {
458+
llvm::json::Object result{{"line", SB.line}};
459+
460+
if (SB.column)
461+
result.insert({"column", *SB.column});
462+
if (SB.condition)
463+
result.insert({"condition", *SB.condition});
464+
if (SB.hitCondition)
465+
result.insert({"hitCondition", *SB.hitCondition});
466+
if (SB.logMessage)
467+
result.insert({"logMessage", *SB.logMessage});
468+
if (SB.mode)
469+
result.insert({"mode", *SB.mode});
470+
471+
return result;
454472
}
455473

456474
bool fromJSON(const llvm::json::Value &Params, FunctionBreakpoint &FB,
457475
llvm::json::Path P) {
458-
json::ObjectMapper O(Params, P);
459-
return O && O.map("name", FB.name) && O.map("condition", FB.condition) &&
460-
O.map("hitCondition", FB.hitCondition);
476+
llvm::json::ObjectMapper O(Params, P);
477+
return O && O.map("name", FB.name) &&
478+
O.mapOptional("condition", FB.condition) &&
479+
O.mapOptional("hitCondition", FB.hitCondition);
480+
}
481+
482+
llvm::json::Value toJSON(const FunctionBreakpoint &FB) {
483+
llvm::json::Object result{{"name", FB.name}};
484+
485+
if (FB.condition)
486+
result.insert({"condition", *FB.condition});
487+
if (FB.hitCondition)
488+
result.insert({"hitCondition", *FB.hitCondition});
489+
490+
return result;
461491
}
462492

463493
bool fromJSON(const llvm::json::Value &Params, DataBreakpointAccessType &DBAT,
@@ -493,21 +523,36 @@ llvm::json::Value toJSON(const DataBreakpointAccessType &DBAT) {
493523
llvm_unreachable("unhandled data breakpoint access type.");
494524
}
495525

496-
bool fromJSON(const llvm::json::Value &Params, DataBreakpointInfo &DBI,
526+
bool fromJSON(const llvm::json::Value &Params, DataBreakpoint &DBI,
497527
llvm::json::Path P) {
498-
json::ObjectMapper O(Params, P);
528+
llvm::json::ObjectMapper O(Params, P);
499529
return O && O.map("dataId", DBI.dataId) &&
500-
O.map("accessType", DBI.accessType) &&
501-
O.map("condition", DBI.condition) &&
502-
O.map("hitCondition", DBI.hitCondition);
530+
O.mapOptional("accessType", DBI.accessType) &&
531+
O.mapOptional("condition", DBI.condition) &&
532+
O.mapOptional("hitCondition", DBI.hitCondition);
533+
}
534+
535+
llvm::json::Value toJSON(const DataBreakpoint &DBI) {
536+
llvm::json::Object result{{"dataId", DBI.dataId}};
537+
538+
if (DBI.accessType)
539+
result.insert({"accessType", *DBI.accessType});
540+
if (DBI.condition)
541+
result.insert({"condition", *DBI.condition});
542+
if (DBI.hitCondition)
543+
result.insert({"hitCondition", *DBI.hitCondition});
544+
545+
return result;
503546
}
504547

505548
bool fromJSON(const llvm::json::Value &Params, InstructionBreakpoint &IB,
506549
llvm::json::Path P) {
507-
json::ObjectMapper O(Params, P);
550+
llvm::json::ObjectMapper O(Params, P);
508551
return O && O.map("instructionReference", IB.instructionReference) &&
509-
O.map("offset", IB.offset) && O.map("condition", IB.condition) &&
510-
O.map("hitCondition", IB.hitCondition) && O.map("mode", IB.mode);
552+
O.mapOptional("offset", IB.offset) &&
553+
O.mapOptional("condition", IB.condition) &&
554+
O.mapOptional("hitCondition", IB.hitCondition) &&
555+
O.mapOptional("mode", IB.mode);
511556
}
512557

513558
} // namespace lldb_dap::protocol

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

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -464,6 +464,7 @@ struct SourceBreakpoint {
464464
std::optional<std::string> mode;
465465
};
466466
bool fromJSON(const llvm::json::Value &, SourceBreakpoint &, llvm::json::Path);
467+
llvm::json::Value toJSON(const SourceBreakpoint &);
467468

468469
/// Properties of a breakpoint passed to the `setFunctionBreakpoints` request.
469470
struct FunctionBreakpoint {
@@ -483,6 +484,7 @@ struct FunctionBreakpoint {
483484
};
484485
bool fromJSON(const llvm::json::Value &, FunctionBreakpoint &,
485486
llvm::json::Path);
487+
llvm::json::Value toJSON(const FunctionBreakpoint &);
486488

487489
/// This enumeration defines all possible access types for data breakpoints.
488490
/// Values: ‘read’, ‘write’, ‘readWrite’
@@ -496,7 +498,7 @@ bool fromJSON(const llvm::json::Value &, DataBreakpointAccessType &,
496498
llvm::json::Value toJSON(const DataBreakpointAccessType &);
497499

498500
/// Properties of a data breakpoint passed to the `setDataBreakpoints` request.
499-
struct DataBreakpointInfo {
501+
struct DataBreakpoint {
500502
/// An id representing the data. This id is returned from the
501503
/// `dataBreakpointInfo` request.
502504
std::string dataId;
@@ -511,8 +513,8 @@ struct DataBreakpointInfo {
511513
/// The debug adapter is expected to interpret the expression as needed.
512514
std::optional<std::string> hitCondition;
513515
};
514-
bool fromJSON(const llvm::json::Value &, DataBreakpointInfo &,
515-
llvm::json::Path);
516+
bool fromJSON(const llvm::json::Value &, DataBreakpoint &, llvm::json::Path);
517+
llvm::json::Value toJSON(const DataBreakpoint &);
516518

517519
/// Properties of a breakpoint passed to the `setInstructionBreakpoints` request
518520
struct InstructionBreakpoint {

lldb/tools/lldb-dap/Watchpoint.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
#include <string>
1818

1919
namespace lldb_dap {
20-
Watchpoint::Watchpoint(DAP &d, const protocol::DataBreakpointInfo &breakpoint)
20+
Watchpoint::Watchpoint(DAP &d, const protocol::DataBreakpoint &breakpoint)
2121
: BreakpointBase(d, breakpoint.condition, breakpoint.hitCondition) {
2222
llvm::StringRef dataId = breakpoint.dataId;
2323
auto [addr_str, size_str] = dataId.split('/');

lldb/tools/lldb-dap/Watchpoint.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ namespace lldb_dap {
2222

2323
class Watchpoint : public BreakpointBase {
2424
public:
25-
Watchpoint(DAP &d, const protocol::DataBreakpointInfo &breakpoint);
25+
Watchpoint(DAP &d, const protocol::DataBreakpoint &breakpoint);
2626
Watchpoint(DAP &d, lldb::SBWatchpoint wp) : BreakpointBase(d), m_wp(wp) {}
2727

2828
void SetCondition() override;

lldb/unittests/DAP/ProtocolTypesTest.cpp

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,3 +132,65 @@ TEST(ProtocolTypesTest, Breakpoint) {
132132
EXPECT_EQ(breakpoint.offset, deserialized_breakpoint->offset);
133133
EXPECT_EQ(breakpoint.reason, deserialized_breakpoint->reason);
134134
}
135+
136+
TEST(ProtocolTypesTest, SourceBreakpoint) {
137+
SourceBreakpoint source_breakpoint;
138+
source_breakpoint.line = 42;
139+
source_breakpoint.column = 5;
140+
source_breakpoint.condition = "x > 10";
141+
source_breakpoint.hitCondition = "5";
142+
source_breakpoint.logMessage = "Breakpoint hit at line 42";
143+
source_breakpoint.mode = "hardware";
144+
145+
llvm::Expected<SourceBreakpoint> deserialized_source_breakpoint =
146+
roundtrip(source_breakpoint);
147+
ASSERT_THAT_EXPECTED(deserialized_source_breakpoint, llvm::Succeeded());
148+
149+
EXPECT_EQ(source_breakpoint.line, deserialized_source_breakpoint->line);
150+
EXPECT_EQ(source_breakpoint.column, deserialized_source_breakpoint->column);
151+
EXPECT_EQ(source_breakpoint.condition,
152+
deserialized_source_breakpoint->condition);
153+
EXPECT_EQ(source_breakpoint.hitCondition,
154+
deserialized_source_breakpoint->hitCondition);
155+
EXPECT_EQ(source_breakpoint.logMessage,
156+
deserialized_source_breakpoint->logMessage);
157+
EXPECT_EQ(source_breakpoint.mode, deserialized_source_breakpoint->mode);
158+
}
159+
160+
TEST(ProtocolTypesTest, FunctionBreakpoint) {
161+
FunctionBreakpoint function_breakpoint;
162+
function_breakpoint.name = "myFunction";
163+
function_breakpoint.condition = "x == 0";
164+
function_breakpoint.hitCondition = "3";
165+
166+
llvm::Expected<FunctionBreakpoint> deserialized_function_breakpoint =
167+
roundtrip(function_breakpoint);
168+
ASSERT_THAT_EXPECTED(deserialized_function_breakpoint, llvm::Succeeded());
169+
170+
EXPECT_EQ(function_breakpoint.name, deserialized_function_breakpoint->name);
171+
EXPECT_EQ(function_breakpoint.condition,
172+
deserialized_function_breakpoint->condition);
173+
EXPECT_EQ(function_breakpoint.hitCondition,
174+
deserialized_function_breakpoint->hitCondition);
175+
}
176+
177+
TEST(ProtocolTypesTest, DataBreakpoint) {
178+
DataBreakpoint data_breakpoint_info;
179+
data_breakpoint_info.dataId = "variable1";
180+
data_breakpoint_info.accessType = eDataBreakpointAccessTypeReadWrite;
181+
data_breakpoint_info.condition = "x > 100";
182+
data_breakpoint_info.hitCondition = "10";
183+
184+
llvm::Expected<DataBreakpoint> deserialized_data_breakpoint_info =
185+
roundtrip(data_breakpoint_info);
186+
ASSERT_THAT_EXPECTED(deserialized_data_breakpoint_info, llvm::Succeeded());
187+
188+
EXPECT_EQ(data_breakpoint_info.dataId,
189+
deserialized_data_breakpoint_info->dataId);
190+
EXPECT_EQ(data_breakpoint_info.accessType,
191+
deserialized_data_breakpoint_info->accessType);
192+
EXPECT_EQ(data_breakpoint_info.condition,
193+
deserialized_data_breakpoint_info->condition);
194+
EXPECT_EQ(data_breakpoint_info.hitCondition,
195+
deserialized_data_breakpoint_info->hitCondition);
196+
}

0 commit comments

Comments
 (0)