Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(461)

Side by Side Diff: dart/runtime/vm/service_test.cc

Issue 119673004: Version 1.1.0-dev.5.2 (Closed) Base URL: http://dart.googlecode.com/svn/trunk/
Patch Set: Created 6 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « dart/runtime/vm/service.cc ('k') | dart/runtime/vm/simulator_arm.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "include/dart_debugger_api.h" 5 #include "include/dart_debugger_api.h"
6 #include "vm/dart_api_impl.h" 6 #include "vm/dart_api_impl.h"
7 #include "vm/dart_entry.h" 7 #include "vm/dart_entry.h"
8 #include "vm/debugger.h" 8 #include "vm/debugger.h"
9 #include "vm/globals.h" 9 #include "vm/globals.h"
10 #include "vm/message_handler.h" 10 #include "vm/message_handler.h"
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
47 47
48 static RawInstance* Eval(Dart_Handle lib, const char* expr) { 48 static RawInstance* Eval(Dart_Handle lib, const char* expr) {
49 Dart_Handle result = Dart_EvaluateExpr(lib, NewString(expr)); 49 Dart_Handle result = Dart_EvaluateExpr(lib, NewString(expr));
50 EXPECT_VALID(result); 50 EXPECT_VALID(result);
51 Isolate* isolate = Isolate::Current(); 51 Isolate* isolate = Isolate::Current();
52 const Instance& instance = Api::UnwrapInstanceHandle(isolate, result); 52 const Instance& instance = Api::UnwrapInstanceHandle(isolate, result);
53 return instance.raw(); 53 return instance.raw();
54 } 54 }
55 55
56 56
57 static RawInstance* EvalF(Dart_Handle lib, const char* fmt, ...) {
58 Isolate* isolate = Isolate::Current();
59
60 va_list args;
61 va_start(args, fmt);
62 intptr_t len = OS::VSNPrint(NULL, 0, fmt, args);
63 va_end(args);
64
65 char* buffer = isolate->current_zone()->Alloc<char>(len + 1);
66 va_list args2;
67 va_start(args2, fmt);
68 OS::VSNPrint(buffer, (len + 1), fmt, args2);
69 va_end(args2);
70
71 return Eval(lib, buffer);
72 }
73
74
75 static RawFunction* GetFunction(const Class& cls, const char* name) {
76 const Function& result = Function::Handle(cls.LookupDynamicFunction(
77 String::Handle(String::New(name))));
78 EXPECT(!result.IsNull());
79 return result.raw();
80 }
81
82
83 static RawClass* GetClass(const Library& lib, const char* name) {
84 const Class& cls = Class::Handle(
85 lib.LookupClass(String::Handle(Symbols::New(name))));
86 EXPECT(!cls.IsNull()); // No ambiguity error expected.
87 return cls.raw();
88 }
89
90
57 TEST_CASE(Service_DebugBreakpoints) { 91 TEST_CASE(Service_DebugBreakpoints) {
58 const char* kScript = 92 const char* kScript =
59 "var port;\n" // Set to our mock port by C++. 93 "var port;\n" // Set to our mock port by C++.
60 "\n" 94 "\n"
61 "main() {\n" // We set breakpoint here. 95 "main() {\n" // We set breakpoint here.
62 "}"; 96 "}";
63 97
64 Isolate* isolate = Isolate::Current(); 98 Isolate* isolate = Isolate::Current();
65 Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL); 99 Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL);
66 EXPECT_VALID(lib); 100 EXPECT_VALID(lib);
(...skipping 13 matching lines...) Expand all
80 isolate->debugger()->SetBreakpointAtLine(url, 3); 114 isolate->debugger()->SetBreakpointAtLine(url, 3);
81 115
82 // Get the breakpoint list. 116 // Get the breakpoint list.
83 service_msg = Eval(lib, "[port, ['debug', 'breakpoints'], [], []]"); 117 service_msg = Eval(lib, "[port, ['debug', 'breakpoints'], [], []]");
84 Service::HandleServiceMessage(isolate, service_msg); 118 Service::HandleServiceMessage(isolate, service_msg);
85 handler.HandleNextMessage(); 119 handler.HandleNextMessage();
86 EXPECT_STREQ( 120 EXPECT_STREQ(
87 "{\"type\":\"BreakpointList\",\"breakpoints\":[{" 121 "{\"type\":\"BreakpointList\",\"breakpoints\":[{"
88 "\"type\":\"Breakpoint\",\"id\":1,\"enabled\":true," 122 "\"type\":\"Breakpoint\",\"id\":1,\"enabled\":true,"
89 "\"resolved\":false," 123 "\"resolved\":false,"
90 "\"location\":{\"type\":\"Location\",\"libId\":12," 124 "\"location\":{\"type\":\"Location\","
91 "\"script\":\"dart:test-lib\",\"tokenPos\":5}}]}", 125 "\"script\":\"dart:test-lib\",\"tokenPos\":5}}]}",
92 handler.msg()); 126 handler.msg());
93 127
94 // Individual breakpoint. 128 // Individual breakpoint.
95 service_msg = Eval(lib, "[port, ['debug', 'breakpoints', '1'], [], []]"); 129 service_msg = Eval(lib, "[port, ['debug', 'breakpoints', '1'], [], []]");
96 Service::HandleServiceMessage(isolate, service_msg); 130 Service::HandleServiceMessage(isolate, service_msg);
97 handler.HandleNextMessage(); 131 handler.HandleNextMessage();
98 EXPECT_STREQ( 132 EXPECT_STREQ(
99 "{\"type\":\"Breakpoint\",\"id\":1,\"enabled\":true," 133 "{\"type\":\"Breakpoint\",\"id\":1,\"enabled\":true,"
100 "\"resolved\":false," 134 "\"resolved\":false,"
101 "\"location\":{\"type\":\"Location\",\"libId\":12," 135 "\"location\":{\"type\":\"Location\","
102 "\"script\":\"dart:test-lib\",\"tokenPos\":5}}", 136 "\"script\":\"dart:test-lib\",\"tokenPos\":5}}",
103 handler.msg()); 137 handler.msg());
104 138
105 // Missing sub-command. 139 // Missing sub-command.
106 service_msg = Eval(lib, "[port, ['debug'], [], []]"); 140 service_msg = Eval(lib, "[port, ['debug'], [], []]");
107 Service::HandleServiceMessage(isolate, service_msg); 141 Service::HandleServiceMessage(isolate, service_msg);
108 handler.HandleNextMessage(); 142 handler.HandleNextMessage();
109 EXPECT_STREQ( 143 EXPECT_STREQ(
110 "{\"type\":\"Error\"," 144 "{\"type\":\"Error\","
111 "\"text\":\"Must specify a subcommand\"," 145 "\"text\":\"Must specify a subcommand\","
(...skipping 27 matching lines...) Expand all
139 service_msg = Eval(lib, "[port, ['debug', 'nosferatu'], [], []]"); 173 service_msg = Eval(lib, "[port, ['debug', 'nosferatu'], [], []]");
140 Service::HandleServiceMessage(isolate, service_msg); 174 Service::HandleServiceMessage(isolate, service_msg);
141 handler.HandleNextMessage(); 175 handler.HandleNextMessage();
142 EXPECT_STREQ("{\"type\":\"Error\"," 176 EXPECT_STREQ("{\"type\":\"Error\","
143 "\"text\":\"Unrecognized subcommand 'nosferatu'\"," 177 "\"text\":\"Unrecognized subcommand 'nosferatu'\","
144 "\"message\":{\"arguments\":[\"debug\",\"nosferatu\"]," 178 "\"message\":{\"arguments\":[\"debug\",\"nosferatu\"],"
145 "\"option_keys\":[],\"option_values\":[]}}", 179 "\"option_keys\":[],\"option_values\":[]}}",
146 handler.msg()); 180 handler.msg());
147 } 181 }
148 182
183
184 TEST_CASE(Service_Classes) {
185 const char* kScript =
186 "var port;\n" // Set to our mock port by C++.
187 "\n"
188 "class A {\n"
189 " var a;\n"
190 " dynamic b() {}\n"
191 " dynamic c() {\n"
192 " var d = () { b(); };\n"
193 " return d;\n"
194 " }\n"
195 "}\n"
196 "main() {\n"
197 " var z = new A();\n"
198 " var x = z.c();\n"
199 " x();\n"
200 "}";
201
202 Isolate* isolate = Isolate::Current();
203 Dart_Handle h_lib = TestCase::LoadTestScript(kScript, NULL);
204 EXPECT_VALID(h_lib);
205 Library& lib = Library::Handle();
206 lib ^= Api::UnwrapHandle(h_lib);
207 EXPECT(!lib.IsNull());
208 Dart_Handle result = Dart_Invoke(h_lib, NewString("main"), 0, NULL);
209 EXPECT_VALID(result);
210 const Class& class_a = Class::Handle(GetClass(lib, "A"));
211 EXPECT(!class_a.IsNull());
212 intptr_t cid = class_a.id();
213
214 // Build a mock message handler and wrap it in a dart port.
215 ServiceTestMessageHandler handler;
216 Dart_Port port_id = PortMap::CreatePort(&handler);
217 Dart_Handle port =
218 Api::NewHandle(isolate, DartLibraryCalls::NewSendPort(port_id));
219 EXPECT_VALID(port);
220 EXPECT_VALID(Dart_SetField(h_lib, NewString("port"), port));
221
222 Instance& service_msg = Instance::Handle();
223
224 // Request an invalid class id.
225 service_msg = Eval(h_lib, "[port, ['classes', '999999'], [], []]");
226 Service::HandleServiceMessage(isolate, service_msg);
227 handler.HandleNextMessage();
228 EXPECT_STREQ(
229 "{\"type\":\"Error\",\"text\":\"999999 is not a valid class id.\","
230 "\"message\":{\"arguments\":[\"classes\",\"999999\"],"
231 "\"option_keys\":[],\"option_values\":[]}}", handler.msg());
232
233 // Request the class A over the service.
234 service_msg = EvalF(h_lib, "[port, ['classes', '%" Pd "'], [], []]", cid);
235 Service::HandleServiceMessage(isolate, service_msg);
236 handler.HandleNextMessage();
237 EXPECT_STREQ(
238 "{\"type\":\"Class\",\"id\":\"classes\\/1009\",\"name\":\"A\","
239 "\"user_name\":\"A\",\"implemented\":false,\"abstract\":false,"
240 "\"patch\":false,\"finalized\":true,\"const\":false,\"super\":"
241 "{\"type\":\"@Class\",\"id\":\"classes\\/35\",\"name\":\"Object\","
242 "\"user_name\":\"Object\"},\"library\":{\"type\":\"@Library\",\"id\":"
243 "\"libraries\\/12\",\"name\":\"\",\"user_name\":\"dart:test-lib\"},"
244 "\"fields\":[{\"type\":\"@Field\",\"id\":\"classes\\/1009\\/fields\\/0\","
245 "\"name\":\"a\",\"user_name\":\"a\",\"owner\":{\"type\":\"@Class\","
246 "\"id\":\"classes\\/1009\",\"name\":\"A\",\"user_name\":\"A\"},"
247 "\"declared_type\":{\"type\":\"@Class\",\"id\":\"classes\\/106\","
248 "\"name\":\"dynamic\",\"user_name\":\"dynamic\"},\"static\":false,"
249 "\"final\":false,\"const\":false}],\"functions\":["
250 "{\"type\":\"@Function\",\"id\":\"classes\\/1009\\/functions\\/0\","
251 "\"name\":\"get:a\",\"user_name\":\"A.a\"},{\"type\":\"@Function\","
252 "\"id\":\"classes\\/1009\\/functions\\/1\",\"name\":\"set:a\","
253 "\"user_name\":\"A.a=\"},{\"type\":\"@Function\",\"id\":"
254 "\"classes\\/1009\\/functions\\/2\",\"name\":\"b\",\"user_name\":\"A.b\"}"
255 ",{\"type\":\"@Function\",\"id\":\"classes\\/1009\\/functions\\/3\","
256 "\"name\":\"c\",\"user_name\":\"A.c\"},{\"type\":\"@Function\",\"id\":"
257 "\"classes\\/1009\\/functions\\/4\",\"name\":\"A.\",\"user_name\":"
258 "\"A.A\"}]}",
259 handler.msg());
260
261 // Request function 0 from class A.
262 service_msg = EvalF(h_lib, "[port, ['classes', '%" Pd "', 'functions', '0'],"
263 "[], []]", cid);
264 Service::HandleServiceMessage(isolate, service_msg);
265 handler.HandleNextMessage();
266 EXPECT_STREQ(
267 "{\"type\":\"Function\",\"id\":\"classes\\/1009\\/functions\\/0\",\"name\":"
268 "\"get:a\",\"user_name\":\"A.a\",\"is_static\":false,\"is_const\":false,"
269 "\"is_optimizable\":true,\"is_inlinable\":false,\"kind\":"
270 "\"kImplicitGetter\",\"unoptimized_code\":{\"type\":\"null\"},"
271 "\"usage_counter\":0,\"optimized_call_site_count\":0,\"code\":"
272 "{\"type\":\"null\"},\"deoptimizations\":0}", handler.msg());
273
274 // Request field 0 from class A.
275 service_msg = EvalF(h_lib, "[port, ['classes', '%" Pd "', 'fields', '0'],"
276 "[], []]", cid);
277 Service::HandleServiceMessage(isolate, service_msg);
278 handler.HandleNextMessage();
279 EXPECT_STREQ(
280 "{\"type\":\"Field\",\"id\":\"classes\\/1009\\/fields\\/0\",\"name\":\"a\","
281 "\"user_name\":\"a\",\"owner\":{\"type\":\"@Class\",\"id\":"
282 "\"classes\\/1009\",\"name\":\"A\",\"user_name\":\"A\"},\"declared_type\":"
283 "{\"type\":\"@Class\",\"id\":\"classes\\/106\",\"name\":\"dynamic\","
284 "\"user_name\":\"dynamic\"},\"static\":false,\"final\":false,\"const\":"
285 "false,\"guard_nullable\":true,\"guard_class\":{\"type\":\"@Class\","
286 "\"id\":\"classes\\/105\",\"name\":\"Null\",\"user_name\":\"Null\"},"
287 "\"guard_length\":\"variable\"}", handler.msg());
288
289 // Invalid sub command.
290 service_msg = EvalF(h_lib, "[port, ['classes', '%" Pd "', 'huh', '0'],"
291 "[], []]", cid);
292 Service::HandleServiceMessage(isolate, service_msg);
293 handler.HandleNextMessage();
294 EXPECT_STREQ(
295 "{\"type\":\"Error\",\"text\":\"Invalid sub collection huh\",\"message\":"
296 "{\"arguments\":[\"classes\",\"1009\",\"huh\",\"0\"],\"option_keys\":[],"
297 "\"option_values\":[]}}", handler.msg());
298
299 // Invalid field request.
300 service_msg = EvalF(h_lib, "[port, ['classes', '%" Pd "', 'fields', '9'],"
301 "[], []]", cid);
302 Service::HandleServiceMessage(isolate, service_msg);
303 handler.HandleNextMessage();
304 EXPECT_STREQ(
305 "{\"type\":\"Error\",\"text\":\"Field 9 not found\","
306 "\"message\":{\"arguments\":[\"classes\",\"1009\",\"fields\",\"9\"],"
307 "\"option_keys\":[],\"option_values\":[]}}", handler.msg());
308
309 // Invalid function request.
310 service_msg = EvalF(h_lib, "[port, ['classes', '%" Pd "', 'functions', '9'],"
311 "[], []]", cid);
312 Service::HandleServiceMessage(isolate, service_msg);
313 handler.HandleNextMessage();
314 EXPECT_STREQ(
315 "{\"type\":\"Error\",\"text\":\"Function 9 not found\","
316 "\"message\":{\"arguments\":[\"classes\",\"1009\",\"functions\",\"9\"],"
317 "\"option_keys\":[],\"option_values\":[]}}", handler.msg());
318
319
320 // Invalid field subcommand.
321 service_msg = EvalF(h_lib, "[port, ['classes', '%" Pd "', 'fields', '9', 'x']"
322 ",[], []]", cid);
323 Service::HandleServiceMessage(isolate, service_msg);
324 handler.HandleNextMessage();
325 EXPECT_STREQ(
326 "{\"type\":\"Error\",\"text\":\"Command too long\",\"message\":"
327 "{\"arguments\":[\"classes\",\"1009\",\"fields\",\"9\",\"x\"],"
328 "\"option_keys\":[],\"option_values\":[]}}",
329 handler.msg());
330
331 // Invalid function request.
332 service_msg = EvalF(h_lib, "[port, ['classes', '%" Pd "', 'functions', '9',"
333 "'x'], [], []]", cid);
334 Service::HandleServiceMessage(isolate, service_msg);
335 handler.HandleNextMessage();
336 EXPECT_STREQ(
337 "{\"type\":\"Error\",\"text\":\"Command too long\",\"message\":"
338 "{\"arguments\":[\"classes\",\"1009\",\"functions\",\"9\",\"x\"],"
339 "\"option_keys\":[],\"option_values\":[]}}",
340 handler.msg());
341 }
342
343
344 TEST_CASE(Service_Code) {
345 const char* kScript =
346 "var port;\n" // Set to our mock port by C++.
347 "\n"
348 "class A {\n"
349 " var a;\n"
350 " dynamic b() {}\n"
351 " dynamic c() {\n"
352 " var d = () { b(); };\n"
353 " return d;\n"
354 " }\n"
355 "}\n"
356 "main() {\n"
357 " var z = new A();\n"
358 " var x = z.c();\n"
359 " x();\n"
360 "}";
361
362 Isolate* isolate = Isolate::Current();
363 Dart_Handle h_lib = TestCase::LoadTestScript(kScript, NULL);
364 EXPECT_VALID(h_lib);
365 Library& lib = Library::Handle();
366 lib ^= Api::UnwrapHandle(h_lib);
367 EXPECT(!lib.IsNull());
368 Dart_Handle result = Dart_Invoke(h_lib, NewString("main"), 0, NULL);
369 EXPECT_VALID(result);
370 const Class& class_a = Class::Handle(GetClass(lib, "A"));
371 EXPECT(!class_a.IsNull());
372 const Function& function_c = Function::Handle(GetFunction(class_a, "c"));
373 EXPECT(!function_c.IsNull());
374 const Code& code_c = Code::Handle(function_c.CurrentCode());
375 EXPECT(!code_c.IsNull());
376 // Use the entry of the code object as it's reference.
377 uword entry = code_c.EntryPoint();
378 EXPECT_GT(code_c.Size(), 16);
379 uword last = entry + code_c.Size();
380
381 // Build a mock message handler and wrap it in a dart port.
382 ServiceTestMessageHandler handler;
383 Dart_Port port_id = PortMap::CreatePort(&handler);
384 Dart_Handle port =
385 Api::NewHandle(isolate, DartLibraryCalls::NewSendPort(port_id));
386 EXPECT_VALID(port);
387 EXPECT_VALID(Dart_SetField(h_lib, NewString("port"), port));
388
389 Instance& service_msg = Instance::Handle();
390
391 // Request an invalid code object.
392 service_msg = Eval(h_lib, "[port, ['code', '0'], [], []]");
393 Service::HandleServiceMessage(isolate, service_msg);
394 handler.HandleNextMessage();
395 EXPECT_STREQ(
396 "{\"type\":\"Error\",\"text\":\"Could not find code at 0\",\"message\":"
397 "{\"arguments\":[\"code\",\"0\"],"
398 "\"option_keys\":[],\"option_values\":[]}}", handler.msg());
399
400 // The following four tests check that a code object can be found
401 // inside the range: [code.EntryPoint(), code.EntryPoint() + code.Size()).
402 // Request code object at code.EntryPoint()
403 // Expect this to succeed as it is inside [entry, entry + size).
404 service_msg = EvalF(h_lib, "[port, ['code', '%" Px "'], [], []]", entry);
405 Service::HandleServiceMessage(isolate, service_msg);
406 handler.HandleNextMessage();
407 {
408 // Only perform a partial match.
409 const intptr_t kBufferSize = 512;
410 char buffer[kBufferSize];
411 OS::SNPrint(buffer, kBufferSize-1,
412 "{\"type\":\"Code\",\"id\":\"code\\/%" Px "\",", entry);
413 EXPECT_SUBSTRING(buffer, handler.msg());
414 }
415
416 // Request code object at code.EntryPoint() + 16.
417 // Expect this to succeed as it is inside [entry, entry + size).
418 uintptr_t address = entry + 16;
419 service_msg = EvalF(h_lib, "[port, ['code', '%" Px "'], [], []]", address);
420 Service::HandleServiceMessage(isolate, service_msg);
421 handler.HandleNextMessage();
422 {
423 // Only perform a partial match.
424 const intptr_t kBufferSize = 512;
425 char buffer[kBufferSize];
426 OS::SNPrint(buffer, kBufferSize-1,
427 "{\"type\":\"Code\",\"id\":\"code\\/%" Px "\",", entry);
428 EXPECT_SUBSTRING(buffer, handler.msg());
429 }
430
431 // Request code object at code.EntryPoint() + code.Size() - 1.
432 // Expect this to succeed as it is inside [entry, entry + size).
433 address = last - 1;
434 service_msg = EvalF(h_lib, "[port, ['code', '%" Px "'], [], []]", address);
435 Service::HandleServiceMessage(isolate, service_msg);
436 handler.HandleNextMessage();
437 {
438 // Only perform a partial match.
439 const intptr_t kBufferSize = 512;
440 char buffer[kBufferSize];
441 OS::SNPrint(buffer, kBufferSize-1,
442 "{\"type\":\"Code\",\"id\":\"code\\/%" Px "\",", entry);
443 EXPECT_SUBSTRING(buffer, handler.msg());
444 }
445
446 // Request code object at code.EntryPoint() + code.Size(). Expect this
447 // to fail as it's outside of [entry, entry + size).
448 address = last;
449 service_msg = EvalF(h_lib, "[port, ['code', '%" Px "'], [], []]", address);
450 Service::HandleServiceMessage(isolate, service_msg);
451 handler.HandleNextMessage();
452 {
453 const intptr_t kBufferSize = 1024;
454 char buffer[kBufferSize];
455 OS::SNPrint(buffer, kBufferSize-1,
456 "{\"type\":\"Error\",\"text\":\"Could not find code at %" Px "\","
457 "\"message\":{\"arguments\":[\"code\",\"%" Px "\"],"
458 "\"option_keys\":[],\"option_values\":[]}}", address, address);
459 EXPECT_STREQ(buffer, handler.msg());
460 }
461 }
462
149 } // namespace dart 463 } // namespace dart
OLDNEW
« no previous file with comments | « dart/runtime/vm/service.cc ('k') | dart/runtime/vm/simulator_arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698