blob: 1a7bfcb4dd53465727ef577b64d9d152c6b08557 [file] [log] [blame]
// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
#include "include/dart_debugger_api.h"
#include "vm/dart_api_impl.h"
#include "vm/dart_entry.h"
#include "vm/debugger.h"
#include "vm/globals.h"
#include "vm/message_handler.h"
#include "vm/os.h"
#include "vm/port.h"
#include "vm/service.h"
#include "vm/unit_test.h"
namespace dart {
class ServiceTestMessageHandler : public MessageHandler {
public:
ServiceTestMessageHandler() : _msg(NULL) {}
~ServiceTestMessageHandler() {
free(_msg);
}
bool HandleMessage(Message* message) {
if (_msg != NULL) {
free(_msg);
}
// Parse the message.
SnapshotReader reader(message->data(), message->len(),
Snapshot::kMessage, Isolate::Current());
const Object& response_obj = Object::Handle(reader.ReadObject());
String& response = String::Handle();
response ^= response_obj.raw();
_msg = strdup(response.ToCString());
return true;
}
const char* msg() const { return _msg; }
private:
char* _msg;
};
static RawInstance* Eval(Dart_Handle lib, const char* expr) {
Dart_Handle result = Dart_EvaluateExpr(lib, NewString(expr));
EXPECT_VALID(result);
Isolate* isolate = Isolate::Current();
const Instance& instance = Api::UnwrapInstanceHandle(isolate, result);
return instance.raw();
}
TEST_CASE(Service_DebugBreakpoints) {
const char* kScript =
"var port;\n" // Set to our mock port by C++.
"\n"
"main() {\n" // We set breakpoint here.
"}";
Isolate* isolate = Isolate::Current();
Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL);
EXPECT_VALID(lib);
// Build a mock message handler and wrap it in a dart port.
ServiceTestMessageHandler handler;
Dart_Port port_id = PortMap::CreatePort(&handler);
Dart_Handle port =
Api::NewHandle(isolate, DartLibraryCalls::NewSendPort(port_id));
EXPECT_VALID(port);
EXPECT_VALID(Dart_SetField(lib, NewString("port"), port));
Instance& service_msg = Instance::Handle();
// Add a breakpoint.
const String& url = String::Handle(String::New(TestCase::url()));
isolate->debugger()->SetBreakpointAtLine(url, 3);
// Get the breakpoint list.
service_msg = Eval(lib, "[port, ['debug', 'breakpoints'], [], []]");
Service::HandleServiceMessage(isolate, service_msg);
handler.HandleNextMessage();
EXPECT_STREQ(
"{\"type\":\"BreakpointList\",\"breakpoints\":[{"
"\"type\":\"Breakpoint\",\"id\":1,\"enabled\":true,"
"\"resolved\":false,"
"\"location\":{\"type\":\"Location\",\"libId\":12,"
"\"script\":\"dart:test-lib\",\"tokenPos\":5}}]}",
handler.msg());
// Individual breakpoint.
service_msg = Eval(lib, "[port, ['debug', 'breakpoints', '1'], [], []]");
Service::HandleServiceMessage(isolate, service_msg);
handler.HandleNextMessage();
EXPECT_STREQ(
"{\"type\":\"Breakpoint\",\"id\":1,\"enabled\":true,"
"\"resolved\":false,"
"\"location\":{\"type\":\"Location\",\"libId\":12,"
"\"script\":\"dart:test-lib\",\"tokenPos\":5}}",
handler.msg());
// Missing sub-command.
service_msg = Eval(lib, "[port, ['debug'], [], []]");
Service::HandleServiceMessage(isolate, service_msg);
handler.HandleNextMessage();
EXPECT_STREQ(
"{\"type\":\"Error\","
"\"text\":\"Must specify a subcommand\","
"\"message\":{\"arguments\":[\"debug\"],\"option_keys\":[],"
"\"option_values\":[]}}",
handler.msg());
// Unrecognized breakpoint.
service_msg = Eval(lib, "[port, ['debug', 'breakpoints', '1111'], [], []]");
Service::HandleServiceMessage(isolate, service_msg);
handler.HandleNextMessage();
EXPECT_STREQ("{\"type\":\"Error\","
"\"text\":\"Unrecognized breakpoint id 1111\","
"\"message\":{"
"\"arguments\":[\"debug\",\"breakpoints\",\"1111\"],"
"\"option_keys\":[],\"option_values\":[]}}",
handler.msg());
// Command too long.
service_msg =
Eval(lib, "[port, ['debug', 'breakpoints', '1111', 'green'], [], []]");
Service::HandleServiceMessage(isolate, service_msg);
handler.HandleNextMessage();
EXPECT_STREQ("{\"type\":\"Error\",\"text\":\"Command too long\","
"\"message\":{\"arguments\":[\"debug\",\"breakpoints\","
"\"1111\",\"green\"],"
"\"option_keys\":[],\"option_values\":[]}}",
handler.msg());
// Unrecognized subcommand.
service_msg = Eval(lib, "[port, ['debug', 'nosferatu'], [], []]");
Service::HandleServiceMessage(isolate, service_msg);
handler.HandleNextMessage();
EXPECT_STREQ("{\"type\":\"Error\","
"\"text\":\"Unrecognized subcommand 'nosferatu'\","
"\"message\":{\"arguments\":[\"debug\",\"nosferatu\"],"
"\"option_keys\":[],\"option_values\":[]}}",
handler.msg());
}
} // namespace dart