1 /**
2 * Copyright (c) 2023-2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "gmock/gmock.h"
17 #include "gtest/gtest.h"
18
19 #include "common.h"
20 #include "connection/server.h"
21 #include "types/location.h"
22 #include "inspector_server.h"
23 #include "utils/json_builder.h"
24 #include "json_object_matcher.h"
25 #include "runtime.h"
26 #include "assembly-emitter.h"
27 #include "assembly-parser.h"
28
29 // NOLINTBEGIN
30
31 using namespace std::placeholders;
32
33 namespace ark::tooling::inspector::test {
34
35 class TestServer : public Server {
36 public:
OnValidate(std::function<void ()> && handler)37 void OnValidate([[maybe_unused]] std::function<void()> &&handler) override {};
OnOpen(std::function<void ()> && handler)38 void OnOpen([[maybe_unused]] std::function<void()> &&handler) override {};
OnFail(std::function<void ()> && handler)39 void OnFail([[maybe_unused]] std::function<void()> &&handler) override {};
40
Call(const std::string & session,const char * method_call,std::function<void (JsonObjectBuilder &)> && parameters)41 void Call(const std::string &session, const char *method_call,
42 std::function<void(JsonObjectBuilder &)> &¶meters) override
43 {
44 std::string tmp(method_call);
45 CallMock(session, tmp, std::move(parameters));
46 }
47
OnCall(const char * method_call,std::function<void (const std::string &,JsonObjectBuilder &,const JsonObject &)> && handler)48 void OnCall(const char *method_call,
49 std::function<void(const std::string &, JsonObjectBuilder &, const JsonObject &)> &&handler) override
50 {
51 std::string tmp(method_call);
52 OnCallMock(tmp, std::move(handler));
53 }
54
55 MOCK_METHOD(void, CallMock,
56 (const std::string &session, const std::string &method_call,
57 std::function<void(JsonObjectBuilder &)> &¶meters));
58
59 MOCK_METHOD(void, OnCallMock,
60 (const std::string &method_call,
61 std::function<void(const std::string &, JsonObjectBuilder &, const JsonObject &)> &&handler));
62
RunOne()63 bool RunOne() override
64 {
65 return true;
66 };
67 };
68
69 static PtThread g_mthread = PtThread(PtThread::NONE);
70 static const std::string g_sessionId;
71 static const std::string g_sourceFile = "source";
72 static bool g_handlerCalled = false;
73
74 class ServerTest : public testing::Test {
75 public:
SetUp()76 void SetUp() override
77 {
78 RuntimeOptions options;
79 options.SetShouldInitializeIntrinsics(false);
80 options.SetShouldLoadBootPandaFiles(false);
81 Runtime::Create(options);
82 g_mthread = PtThread(ManagedThread::GetCurrent());
83 g_handlerCalled = false;
84 }
TearDown()85 void TearDown() override
86 {
87 Runtime::Destroy();
88 }
89 TestServer server;
90 InspectorServer inspectorServer {server};
91 };
92
TEST_F(ServerTest,CallDebuggerResumed)93 TEST_F(ServerTest, CallDebuggerResumed)
94 {
95 inspectorServer.CallTargetAttachedToTarget(g_mthread);
96 EXPECT_CALL(server, CallMock(g_sessionId, "Debugger.resumed", testing::_)).Times(1);
97
98 inspectorServer.CallDebuggerResumed(g_mthread);
99 }
100
TEST_F(ServerTest,CallDebuggerScriptParsed)101 TEST_F(ServerTest, CallDebuggerScriptParsed)
102 {
103 inspectorServer.CallTargetAttachedToTarget(g_mthread);
104
105 size_t scriptId = 4;
106 EXPECT_CALL(server, CallMock(g_sessionId, "Debugger.scriptParsed", testing::_))
107 .WillOnce([&](testing::Unused, testing::Unused, auto s) {
108 ASSERT_THAT(ToObject(std::move(s)),
109 JsonProperties(JsonProperty<JsonObject::NumT> {"executionContextId", g_mthread.GetId()},
110 JsonProperty<JsonObject::StringT> {"scriptId", std::to_string(scriptId)},
111 JsonProperty<JsonObject::NumT> {"startLine", 0},
112 JsonProperty<JsonObject::NumT> {"startColumn", 0},
113 JsonProperty<JsonObject::NumT> {"endLine", std::numeric_limits<int>::max()},
114 JsonProperty<JsonObject::NumT> {"endColumn", std::numeric_limits<int>::max()},
115 JsonProperty<JsonObject::StringT> {"hash", ""},
116 JsonProperty<JsonObject::StringT> {"url", g_sourceFile.c_str()}));
117 });
118 inspectorServer.CallDebuggerScriptParsed(g_mthread, ScriptId(scriptId), g_sourceFile);
119 }
120
TEST_F(ServerTest,DebuggerEnable)121 TEST_F(ServerTest, DebuggerEnable)
122 {
123 TestServer server1;
124 EXPECT_CALL(server1, OnCallMock("Debugger.enable", testing::_)).WillOnce([&](testing::Unused, auto handler) {
125 JsonObjectBuilder res;
126 JsonObject empty;
127 handler(g_sessionId, res, empty);
128 ASSERT_THAT(JsonObject(std::move(res).Build()),
129 JsonProperties(JsonProperty<JsonObject::StringT> {"debuggerId", "debugger"}));
130 });
131 InspectorServer inspector_server1(server1);
132 }
133
__anond968ae700302(auto unused, auto handler) 134 static auto g_simpleHandler = []([[maybe_unused]] auto unused, auto handler) {
135 JsonObjectBuilder res;
136 JsonObject empty;
137 handler(g_sessionId, res, empty);
138 ASSERT_THAT(JsonObject(std::move(res).Build()), JsonProperties());
139 ASSERT_TRUE(g_handlerCalled);
140 };
141
TEST_F(ServerTest,OnCallDebuggerPause)142 TEST_F(ServerTest, OnCallDebuggerPause)
143 {
144 inspectorServer.CallTargetAttachedToTarget(g_mthread);
145
146 EXPECT_CALL(server, OnCallMock("Debugger.pause", testing::_)).WillOnce(g_simpleHandler);
147 inspectorServer.OnCallDebuggerPause([](PtThread thread) {
148 ASSERT_EQ(thread.GetId(), g_mthread.GetId());
149 g_handlerCalled = true;
150 });
151 }
152
TEST_F(ServerTest,OnCallDebuggerRemoveBreakpoint)153 TEST_F(ServerTest, OnCallDebuggerRemoveBreakpoint)
154 {
155 size_t break_id = 14;
156
157 inspectorServer.CallTargetAttachedToTarget(g_mthread);
158
159 EXPECT_CALL(server, OnCallMock("Debugger.removeBreakpoint", testing::_))
160 .WillOnce([&](testing::Unused, auto handler) {
161 JsonObjectBuilder res;
162 JsonObject empty;
163 handler(g_sessionId, res, empty);
164 ASSERT_THAT(JsonObject(std::move(res).Build()), JsonProperties());
165 ASSERT_FALSE(g_handlerCalled);
166 });
167
168 auto breaks = [break_id](PtThread thread, BreakpointId bid) {
169 ASSERT_EQ(bid, BreakpointId(break_id));
170 ASSERT_EQ(thread.GetId(), g_mthread.GetId());
171 g_handlerCalled = true;
172 };
173 inspectorServer.OnCallDebuggerRemoveBreakpoint(std::move(breaks));
174
175 EXPECT_CALL(server, OnCallMock("Debugger.removeBreakpoint", testing::_))
176 .WillOnce([&](testing::Unused, auto handler) {
177 JsonObjectBuilder res;
178 JsonObjectBuilder params;
179 params.AddProperty("breakpointId", std::to_string(break_id));
180 handler(g_sessionId, res, JsonObject(std::move(params).Build()));
181 ASSERT_THAT(JsonObject(std::move(res).Build()), JsonProperties());
182 ASSERT_TRUE(g_handlerCalled);
183 });
184
185 inspectorServer.OnCallDebuggerRemoveBreakpoint(std::move(breaks));
186 }
187
TEST_F(ServerTest,OnCallDebuggerRestartFrame)188 TEST_F(ServerTest, OnCallDebuggerRestartFrame)
189 {
190 size_t fid = 5;
191
192 inspectorServer.CallTargetAttachedToTarget(g_mthread);
193
194 EXPECT_CALL(server, OnCallMock("Debugger.restartFrame", testing::_)).WillOnce([&](testing::Unused, auto handler) {
195 std::vector<testing::Matcher<JsonObject::JsonObjPointer>> callFrames;
196 JsonObjectBuilder res;
197 JsonObjectBuilder params;
198 handler(g_sessionId, res, JsonObject(std::move(params).Build()));
199 ASSERT_THAT(JsonObject(std::move(res).Build()), JsonProperties());
200 ASSERT_FALSE(g_handlerCalled);
201 });
202
203 inspectorServer.OnCallDebuggerRestartFrame([&](auto, auto) { g_handlerCalled = true; });
204
205 EXPECT_CALL(server, OnCallMock("Debugger.restartFrame", testing::_)).WillOnce([&](testing::Unused, auto handler) {
206 std::vector<testing::Matcher<JsonObject::JsonObjPointer>> callFrames;
207 JsonObjectBuilder res;
208 JsonObjectBuilder params;
209 params.AddProperty("callFrameId", std::to_string(fid));
210 handler(g_sessionId, res, JsonObject(std::move(params).Build()));
211 ASSERT_THAT(JsonObject(std::move(res).Build()),
212 JsonProperties(JsonProperty<JsonObject::ArrayT> {"callFrames", JsonElementsAreArray(callFrames)}));
213 ASSERT_TRUE(g_handlerCalled);
214 });
215
216 inspectorServer.OnCallDebuggerRestartFrame([&](PtThread thread, FrameId id) {
217 ASSERT_EQ(id, FrameId(fid));
218 ASSERT_EQ(thread.GetId(), g_mthread.GetId());
219 g_handlerCalled = true;
220 });
221 }
222
TEST_F(ServerTest,OnCallDebuggerResume)223 TEST_F(ServerTest, OnCallDebuggerResume)
224 {
225 inspectorServer.CallTargetAttachedToTarget(g_mthread);
226
227 EXPECT_CALL(server, OnCallMock("Debugger.resume", testing::_)).WillOnce(g_simpleHandler);
228 inspectorServer.OnCallDebuggerResume([](PtThread thread) {
229 ASSERT_EQ(thread.GetId(), g_mthread.GetId());
230 g_handlerCalled = true;
231 });
232 }
233
CreatePossibleBreakpointsRequest(ScriptId startScriptId,size_t start,ScriptId endScriptId,size_t end,bool restrictToFunction)234 static JsonObject CreatePossibleBreakpointsRequest(ScriptId startScriptId, size_t start, ScriptId endScriptId,
235 size_t end, bool restrictToFunction)
236 {
237 JsonObjectBuilder params;
238 params.AddProperty("start", Location(startScriptId, start).ToJson());
239 params.AddProperty("end", Location(endScriptId, end).ToJson());
240 params.AddProperty("restrictToFunction", restrictToFunction);
241 return JsonObject(std::move(params).Build());
242 }
243
244 static auto g_getPossibleBreakpointsHandler = [](ScriptId scriptId, size_t start, size_t end, bool restrictToFunction,
__anond968ae700d02(ScriptId scriptId, size_t start, size_t end, bool restrictToFunction, testing::Unused, auto handler) 245 testing::Unused, auto handler) {
246 JsonObjectBuilder res;
247 handler(g_sessionId, res, CreatePossibleBreakpointsRequest(scriptId, start, scriptId, end, restrictToFunction));
248 std::vector<testing::Matcher<JsonObject::JsonObjPointer>> locations;
249 for (auto i = start; i < end; i++) {
250 locations.push_back(
251 testing::Pointee(JsonProperties(JsonProperty<JsonObject::StringT> {"scriptId", std::to_string(scriptId)},
252 JsonProperty<JsonObject::NumT> {"lineNumber", i})));
253 }
254 ASSERT_THAT(JsonObject(std::move(res).Build()),
255 JsonProperties(JsonProperty<JsonObject::ArrayT> {"locations", JsonElementsAreArray(locations)}));
256 };
257
DefaultFrameEnumerator(const InspectorServer::FrameInfoHandler & handler)258 static void DefaultFrameEnumerator(const InspectorServer::FrameInfoHandler &handler)
259 {
260 std::optional<RemoteObject> objThis;
261 auto scope_chain = std::vector {Scope(Scope::Type::LOCAL, RemoteObject::Number(72))};
262 handler(FrameId(0), std::to_string(0), g_sourceFile, 0, scope_chain, objThis);
263 }
264
TEST_F(ServerTest,OnCallDebuggerGetPossibleBreakpoints)265 TEST_F(ServerTest, OnCallDebuggerGetPossibleBreakpoints)
266 {
267 auto scriptId = 0;
268 size_t start = 5;
269 size_t end = 5;
270
271 inspectorServer.CallTargetAttachedToTarget(g_mthread);
272 inspectorServer.CallDebuggerPaused(g_mthread, {}, {}, DefaultFrameEnumerator);
273
274 EXPECT_CALL(server, OnCallMock("Debugger.getPossibleBreakpoints", testing::_))
275 .WillOnce(std::bind(g_getPossibleBreakpointsHandler, scriptId, start, end, // NOLINT(modernize-avoid-bind)
276 true, _1, _2));
277 auto getLinesTrue = [](std::string_view source, size_t startLine, size_t endLine, bool restrictToFunction) {
278 std::set<size_t> result;
279 if ((source == g_sourceFile) && restrictToFunction) {
280 for (auto i = startLine; i < endLine; i++) {
281 result.insert(i);
282 }
283 }
284 return result;
285 };
286 inspectorServer.OnCallDebuggerGetPossibleBreakpoints(getLinesTrue);
287
288 EXPECT_CALL(server, OnCallMock("Debugger.getPossibleBreakpoints", testing::_))
289 .WillOnce(std::bind(g_getPossibleBreakpointsHandler, scriptId, start, end, // NOLINT(modernize-avoid-bind)
290 false, _1, _2));
291 auto getLinesFalse = [](std::string_view source, size_t startLine, size_t endLine, bool restrictToFunction) {
292 std::set<size_t> result;
293 if ((source == g_sourceFile) && !restrictToFunction) {
294 for (auto i = startLine; i < endLine; i++) {
295 result.insert(i);
296 }
297 }
298 return result;
299 };
300 inspectorServer.OnCallDebuggerGetPossibleBreakpoints(getLinesFalse);
301
302 EXPECT_CALL(server, OnCallMock("Debugger.getPossibleBreakpoints", testing::_))
303 .WillOnce([&](testing::Unused, auto handler) {
304 JsonObjectBuilder res;
305 handler(g_sessionId, res, CreatePossibleBreakpointsRequest(scriptId, start, scriptId + 1, end, false));
306 std::vector<testing::Matcher<JsonObject::JsonObjPointer>> locations;
307 ASSERT_THAT(JsonObject(std::move(res).Build()), JsonProperties());
308 });
309 inspectorServer.OnCallDebuggerGetPossibleBreakpoints(getLinesFalse);
310 }
311
TEST_F(ServerTest,OnCallDebuggerGetScriptSource)312 TEST_F(ServerTest, OnCallDebuggerGetScriptSource)
313 {
314 auto scriptId = 0;
315
316 EXPECT_CALL(server, CallMock(g_sessionId, "Debugger.paused", testing::_))
317 .WillOnce([&](testing::Unused, testing::Unused, auto s) { ToObject(std::move(s)); });
318 EXPECT_CALL(server, CallMock(g_sessionId, "Debugger.scriptParsed", testing::_)).Times(1);
319
320 inspectorServer.CallTargetAttachedToTarget(g_mthread);
321 inspectorServer.CallDebuggerPaused(g_mthread, {}, {}, DefaultFrameEnumerator);
322
323 EXPECT_CALL(server, OnCallMock("Debugger.getScriptSource", testing::_))
324 .WillOnce([&](testing::Unused, auto handler) {
325 JsonObjectBuilder res;
326 JsonObjectBuilder params;
327 params.AddProperty("scriptId", std::to_string(scriptId));
328 handler(g_sessionId, res, JsonObject(std::move(params).Build()));
329 ASSERT_THAT(JsonObject(std::move(res).Build()),
330 JsonProperties(JsonProperty<JsonObject::StringT> {"scriptSource", g_sourceFile}));
331 });
332 inspectorServer.OnCallDebuggerGetScriptSource([](auto source) {
333 std::string s(source);
334 return s;
335 });
336
337 EXPECT_CALL(server, OnCallMock("Debugger.getScriptSource", testing::_))
338 .WillOnce([&](testing::Unused, auto handler) {
339 JsonObjectBuilder res;
340 JsonObject empty;
341 handler(g_sessionId, res, empty);
342 ASSERT_THAT(JsonObject(std::move(res).Build()), JsonProperties());
343 });
344 inspectorServer.OnCallDebuggerGetScriptSource([](auto) { return "a"; });
345 }
346
TEST_F(ServerTest,OnCallDebuggerStepOut)347 TEST_F(ServerTest, OnCallDebuggerStepOut)
348 {
349 inspectorServer.CallTargetAttachedToTarget(g_mthread);
350
351 EXPECT_CALL(server, OnCallMock("Debugger.stepOut", testing::_)).WillOnce(g_simpleHandler);
352
353 inspectorServer.OnCallDebuggerStepOut([](PtThread thread) {
354 ASSERT_EQ(thread.GetId(), g_mthread.GetId());
355 g_handlerCalled = true;
356 });
357 }
358
TEST_F(ServerTest,OnCallDebuggerStepInto)359 TEST_F(ServerTest, OnCallDebuggerStepInto)
360 {
361 inspectorServer.CallTargetAttachedToTarget(g_mthread);
362
363 EXPECT_CALL(server, OnCallMock("Debugger.stepInto", testing::_)).WillOnce(g_simpleHandler);
364
365 inspectorServer.OnCallDebuggerStepInto([](PtThread thread) {
366 ASSERT_EQ(thread.GetId(), g_mthread.GetId());
367 g_handlerCalled = true;
368 });
369 }
370
TEST_F(ServerTest,OnCallDebuggerStepOver)371 TEST_F(ServerTest, OnCallDebuggerStepOver)
372 {
373 inspectorServer.CallTargetAttachedToTarget(g_mthread);
374
375 EXPECT_CALL(server, OnCallMock("Debugger.stepOver", testing::_)).WillOnce(g_simpleHandler);
376
377 inspectorServer.OnCallDebuggerStepOver([](PtThread thread) {
378 ASSERT_EQ(thread.GetId(), g_mthread.GetId());
379 g_handlerCalled = true;
380 });
381 }
382
handlerForSetBreak(PtThread thread,const std::function<bool (std::string_view)> & comp,size_t line,std::set<std::string_view> & sources)383 std::optional<BreakpointId> handlerForSetBreak([[maybe_unused]] PtThread thread,
384 [[maybe_unused]] const std::function<bool(std::string_view)> &comp,
385 size_t line, [[maybe_unused]] std::set<std::string_view> &sources)
386 {
387 sources.insert("source");
388 return BreakpointId(line);
389 }
390
handlerForSetBreakEmpty(PtThread thread,const std::function<bool (std::string_view)> & comp,size_t line,std::set<std::string_view> & sources)391 std::optional<BreakpointId> handlerForSetBreakEmpty([[maybe_unused]] PtThread thread,
392 [[maybe_unused]] const std::function<bool(std::string_view)> &comp,
393 [[maybe_unused]] size_t line,
394 [[maybe_unused]] std::set<std::string_view> &sources)
395 {
396 sources.insert("source");
397 return {};
398 }
399
TEST_F(ServerTest,OnCallDebuggerSetBreakpoint)400 TEST_F(ServerTest, OnCallDebuggerSetBreakpoint)
401 {
402 auto scriptId = 0;
403 size_t start = 5;
404
405 inspectorServer.CallTargetAttachedToTarget(g_mthread);
406 inspectorServer.CallDebuggerPaused(g_mthread, {}, {}, DefaultFrameEnumerator);
407
408 EXPECT_CALL(server, OnCallMock("Debugger.setBreakpoint", testing::_)).WillOnce([&](testing::Unused, auto handler) {
409 JsonObjectBuilder res;
410 JsonObjectBuilder params;
411 params.AddProperty("location", Location(scriptId, start).ToJson());
412 handler(g_sessionId, res, JsonObject(std::move(params).Build()));
413 ASSERT_THAT(JsonObject(std::move(res).Build()),
414 JsonProperties(JsonProperty<JsonObject::StringT> {"breakpointId", std::to_string(start)},
415 JsonProperty<JsonObject::JsonObjPointer> {
416 "actualLocation",
417 testing::Pointee(JsonProperties(
418 JsonProperty<JsonObject::StringT> {"scriptId", std::to_string(scriptId)},
419 JsonProperty<JsonObject::NumT> {"lineNumber", start - 1}))}));
420 });
421
422 inspectorServer.OnCallDebuggerSetBreakpoint(handlerForSetBreak);
423
424 EXPECT_CALL(server, OnCallMock("Debugger.setBreakpoint", testing::_)).WillOnce([&](testing::Unused, auto handler) {
425 JsonObjectBuilder res;
426 JsonObject empty;
427 handler(g_sessionId, res, empty);
428 ASSERT_THAT(JsonObject(std::move(res).Build()), JsonProperties());
429 });
430
431 inspectorServer.OnCallDebuggerSetBreakpoint(handlerForSetBreak);
432
433 EXPECT_CALL(server, OnCallMock("Debugger.setBreakpoint", testing::_)).WillOnce([&](testing::Unused, auto handler) {
434 JsonObjectBuilder res;
435 JsonObjectBuilder params;
436 params.AddProperty("location", Location(scriptId, start).ToJson());
437 handler(g_sessionId, res, JsonObject(std::move(params).Build()));
438 ASSERT_THAT(JsonObject(std::move(res).Build()), JsonProperties());
439 });
440
441 inspectorServer.OnCallDebuggerSetBreakpoint(handlerForSetBreakEmpty);
442 }
443
TEST_F(ServerTest,OnCallDebuggerSetBreakpointByUrl)444 TEST_F(ServerTest, OnCallDebuggerSetBreakpointByUrl)
445 {
446 auto scriptId = 0;
447 size_t start = 5;
448
449 inspectorServer.CallTargetAttachedToTarget(g_mthread);
450
451 EXPECT_CALL(server, OnCallMock("Debugger.setBreakpointByUrl", testing::_))
452 .WillOnce([&](testing::Unused, auto handler) {
453 JsonObjectBuilder res;
454 JsonObjectBuilder params;
455 params.AddProperty("lineNumber", start);
456 handler(g_sessionId, res, JsonObject(std::move(params).Build()));
457 ASSERT_THAT(JsonObject(std::move(res).Build()), JsonProperties());
458 });
459
460 inspectorServer.OnCallDebuggerSetBreakpointByUrl(handlerForSetBreak);
461
462 EXPECT_CALL(server, OnCallMock("Debugger.setBreakpointByUrl", testing::_))
463 .WillOnce([&](testing::Unused, auto handler) {
464 JsonObjectBuilder res;
465 JsonObjectBuilder params;
466 params.AddProperty("lineNumber", start);
467 params.AddProperty("url", "file://source");
468 handler(g_sessionId, res, JsonObject(std::move(params).Build()));
469 std::vector<testing::Matcher<JsonObject::JsonObjPointer>> locations;
470 locations.push_back(testing::Pointee(
471 JsonProperties(JsonProperty<JsonObject::StringT> {"scriptId", std::to_string(scriptId)},
472 JsonProperty<JsonObject::NumT> {"lineNumber", start})));
473
474 ASSERT_THAT(
475 JsonObject(std::move(res).Build()),
476 JsonProperties(JsonProperty<JsonObject::StringT> {"breakpointId", std::to_string(start + 1)},
477 JsonProperty<JsonObject::ArrayT> {"locations", JsonElementsAreArray(locations)}));
478 });
479
480 inspectorServer.OnCallDebuggerSetBreakpointByUrl(handlerForSetBreak);
481 }
482
TEST_F(ServerTest,OnCallDebuggerSetBreakpointsActive)483 TEST_F(ServerTest, OnCallDebuggerSetBreakpointsActive)
484 {
485 inspectorServer.CallTargetAttachedToTarget(g_mthread);
486
487 EXPECT_CALL(server, OnCallMock("Debugger.setBreakpointsActive", testing::_))
488 .WillOnce([&](testing::Unused, auto handler) {
489 JsonObjectBuilder res;
490 JsonObject empty;
491 handler(g_sessionId, res, empty);
492 ASSERT_THAT(JsonObject(std::move(res).Build()), JsonProperties());
493 ASSERT_FALSE(g_handlerCalled);
494 });
495
496 inspectorServer.OnCallDebuggerSetBreakpointsActive([](auto thread, auto value) {
497 ASSERT_EQ(thread.GetId(), g_mthread.GetId());
498 ASSERT_FALSE(value);
499 g_handlerCalled = true;
500 });
501
502 EXPECT_CALL(server, OnCallMock("Debugger.setBreakpointsActive", testing::_))
503 .WillOnce([&](testing::Unused, auto handler) {
504 JsonObjectBuilder res;
505 JsonObjectBuilder params;
506 params.AddProperty("active", true);
507 handler(g_sessionId, res, JsonObject(std::move(params).Build()));
508 ASSERT_THAT(JsonObject(std::move(res).Build()), JsonProperties());
509 ASSERT_TRUE(g_handlerCalled);
510 g_handlerCalled = false;
511 });
512
513 inspectorServer.OnCallDebuggerSetBreakpointsActive([](auto thread, auto value) {
514 ASSERT_EQ(thread.GetId(), g_mthread.GetId());
515 ASSERT_TRUE(value);
516 g_handlerCalled = true;
517 });
518
519 EXPECT_CALL(server, OnCallMock("Debugger.setBreakpointsActive", testing::_))
520 .WillOnce([&](testing::Unused, auto handler) {
521 JsonObjectBuilder res;
522 JsonObjectBuilder params;
523 params.AddProperty("active", false);
524 handler(g_sessionId, res, JsonObject(std::move(params).Build()));
525 ASSERT_THAT(JsonObject(std::move(res).Build()), JsonProperties());
526 ASSERT_TRUE(g_handlerCalled);
527 });
528
529 inspectorServer.OnCallDebuggerSetBreakpointsActive([](auto thread, auto value) {
530 ASSERT_EQ(thread.GetId(), g_mthread.GetId());
531 ASSERT_FALSE(value);
532 g_handlerCalled = true;
533 });
534 }
535
TEST_F(ServerTest,OnCallDebuggerSetPauseOnExceptions)536 TEST_F(ServerTest, OnCallDebuggerSetPauseOnExceptions)
537 {
538 inspectorServer.CallTargetAttachedToTarget(g_mthread);
539
540 EXPECT_CALL(server, OnCallMock("Debugger.setPauseOnExceptions", testing::_))
541 .WillOnce([&](testing::Unused, auto handler) {
542 JsonObjectBuilder res;
543 JsonObjectBuilder params;
544 params.AddProperty("state", "none");
545 handler(g_sessionId, res, JsonObject(std::move(params).Build()));
546 ASSERT_THAT(JsonObject(std::move(res).Build()), JsonProperties());
547 ASSERT_TRUE(g_handlerCalled);
548 });
549
550 inspectorServer.OnCallDebuggerSetPauseOnExceptions([](PtThread thread, PauseOnExceptionsState state) {
551 ASSERT_EQ(thread.GetId(), g_mthread.GetId());
552 ASSERT_EQ(PauseOnExceptionsState::NONE, state);
553 g_handlerCalled = true;
554 });
555 }
556
TEST_F(ServerTest,OnCallRuntimeEnable)557 TEST_F(ServerTest, OnCallRuntimeEnable)
558 {
559 inspectorServer.CallTargetAttachedToTarget(g_mthread);
560
561 EXPECT_CALL(server, OnCallMock("Runtime.enable", testing::_)).WillOnce([&](testing::Unused, auto handler) {
562 JsonObjectBuilder res;
563 JsonObject empty;
564 handler(g_sessionId, res, empty);
565 ASSERT_THAT(JsonObject(std::move(res).Build()), JsonProperties());
566 ASSERT_TRUE(g_handlerCalled);
567 });
568 inspectorServer.OnCallRuntimeEnable([](PtThread thread) {
569 ASSERT_EQ(thread.GetId(), g_mthread.GetId());
570 g_handlerCalled = true;
571 });
572 }
573
TEST_F(ServerTest,OnCallRuntimeGetProperties)574 TEST_F(ServerTest, OnCallRuntimeGetProperties)
575 {
576 auto object_id = 6;
577 auto preview = true;
578
579 inspectorServer.CallTargetAttachedToTarget(g_mthread);
580
581 EXPECT_CALL(server, OnCallMock("Runtime.getProperties", testing::_)).WillOnce([&](testing::Unused, auto handler) {
582 JsonObjectBuilder res;
583 JsonObjectBuilder params;
584 params.AddProperty("objectId", std::to_string(object_id));
585 params.AddProperty("generatePreview", preview);
586 handler(g_sessionId, res, JsonObject(std::move(params).Build()));
587
588 std::vector<testing::Matcher<JsonObject::JsonObjPointer>> result;
589 result.push_back(testing::Pointee(JsonProperties(
590 JsonProperty<JsonObject::StringT> {"name", "object"},
591 JsonProperty<JsonObject::JsonObjPointer> {
592 "value", testing::Pointee(JsonProperties(JsonProperty<JsonObject::NumT> {"value", object_id},
593 JsonProperty<JsonObject::StringT> {"type", "number"}))},
594 JsonProperty<JsonObject::BoolT> {"writable", testing::_},
595 JsonProperty<JsonObject::BoolT> {"configurable", testing::_},
596 JsonProperty<JsonObject::BoolT> {"enumerable", testing::_})));
597 result.push_back(testing::Pointee(JsonProperties(
598 JsonProperty<JsonObject::StringT> {"name", "preview"},
599 JsonProperty<JsonObject::JsonObjPointer> {
600 "value", testing::Pointee(JsonProperties(JsonProperty<JsonObject::BoolT> {"value", preview},
601 JsonProperty<JsonObject::StringT> {"type", "boolean"}))},
602 JsonProperty<JsonObject::BoolT> {"writable", testing::_},
603 JsonProperty<JsonObject::BoolT> {"configurable", testing::_},
604 JsonProperty<JsonObject::BoolT> {"enumerable", testing::_})));
605 result.push_back(testing::Pointee(JsonProperties(
606 JsonProperty<JsonObject::StringT> {"name", "threadId"},
607 JsonProperty<JsonObject::JsonObjPointer> {
608 "value", testing::Pointee(JsonProperties(JsonProperty<JsonObject::NumT> {"value", g_mthread.GetId()},
609 JsonProperty<JsonObject::StringT> {"type", "number"}))},
610 JsonProperty<JsonObject::BoolT> {"writable", testing::_},
611 JsonProperty<JsonObject::BoolT> {"configurable", testing::_},
612 JsonProperty<JsonObject::BoolT> {"enumerable", testing::_})));
613
614 ASSERT_THAT(JsonObject(std::move(res).Build()),
615 JsonProperties(JsonProperty<JsonObject::ArrayT> {"result", JsonElementsAreArray(result)}));
616 });
617
618 auto getProperties = [](PtThread thread, RemoteObjectId id, bool need_preview) {
619 std::vector<PropertyDescriptor> res;
620 res.push_back(PropertyDescriptor("object", RemoteObject::Number(id)));
621 res.push_back(PropertyDescriptor("preview", RemoteObject::Boolean(need_preview)));
622 res.push_back(PropertyDescriptor("threadId", RemoteObject::Number(thread.GetId())));
623 return res;
624 };
625
626 inspectorServer.OnCallRuntimeGetProperties(getProperties);
627 }
628
TEST_F(ServerTest,OnCallRuntimeRunIfWaitingForDebugger)629 TEST_F(ServerTest, OnCallRuntimeRunIfWaitingForDebugger)
630 {
631 inspectorServer.CallTargetAttachedToTarget(g_mthread);
632
633 EXPECT_CALL(server, OnCallMock("Runtime.runIfWaitingForDebugger", testing::_))
634 .WillOnce([&](testing::Unused, auto handler) {
635 JsonObjectBuilder res;
636 JsonObject empty;
637 handler(g_sessionId, res, empty);
638 ASSERT_THAT(JsonObject(std::move(res).Build()), JsonProperties());
639 ASSERT_TRUE(g_handlerCalled);
640 });
641
642 inspectorServer.OnCallRuntimeRunIfWaitingForDebugger([](PtThread thread) {
643 ASSERT_EQ(thread.GetId(), g_mthread.GetId());
644 g_handlerCalled = true;
645 });
646 }
647
648 } // namespace ark::tooling::inspector::test
649
650 // NOLINTEND
651