| OLD | NEW |
| 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 "platform/globals.h" | 5 #include "platform/globals.h" |
| 6 | 6 |
| 7 #include "include/dart_debugger_api.h" | 7 #include "include/dart_debugger_api.h" |
| 8 #include "vm/dart_api_impl.h" | 8 #include "vm/dart_api_impl.h" |
| 9 #include "vm/dart_entry.h" | 9 #include "vm/dart_entry.h" |
| 10 #include "vm/debugger.h" | 10 #include "vm/debugger.h" |
| (...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 206 EXPECT_EQ(reader.Type(), JSONReader::kString); | 206 EXPECT_EQ(reader.Type(), JSONReader::kString); |
| 207 reader.GetDecodedValueChars(buffer, kBufferSize); | 207 reader.GetDecodedValueChars(buffer, kBufferSize); |
| 208 EXPECT_SUBSTRING("isolates/", buffer); | 208 EXPECT_SUBSTRING("isolates/", buffer); |
| 209 | 209 |
| 210 // heap | 210 // heap |
| 211 EXPECT(reader.Seek("heaps")); | 211 EXPECT(reader.Seek("heaps")); |
| 212 EXPECT_EQ(reader.Type(), JSONReader::kObject); | 212 EXPECT_EQ(reader.Type(), JSONReader::kObject); |
| 213 } | 213 } |
| 214 | 214 |
| 215 | 215 |
| 216 TEST_CASE(Service_StackTrace) { | |
| 217 // TODO(turnidge): Extend this test to cover a non-trivial stack trace. | |
| 218 const char* kScript = | |
| 219 "var port;\n" // Set to our mock port by C++. | |
| 220 "\n" | |
| 221 "main() {\n" | |
| 222 "}"; | |
| 223 | |
| 224 Isolate* isolate = Isolate::Current(); | |
| 225 Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL); | |
| 226 EXPECT_VALID(lib); | |
| 227 | |
| 228 // Build a mock message handler and wrap it in a dart port. | |
| 229 ServiceTestMessageHandler handler; | |
| 230 Dart_Port port_id = PortMap::CreatePort(&handler); | |
| 231 Dart_Handle port = Api::NewHandle(isolate, SendPort::New(port_id)); | |
| 232 EXPECT_VALID(port); | |
| 233 EXPECT_VALID(Dart_SetField(lib, NewString("port"), port)); | |
| 234 | |
| 235 Array& service_msg = Array::Handle(); | |
| 236 | |
| 237 // Get the stacktrace. | |
| 238 service_msg = Eval(lib, "[0, port, ['stacktrace'], [], []]"); | |
| 239 Service::HandleIsolateMessage(isolate, service_msg); | |
| 240 handler.HandleNextMessage(); | |
| 241 EXPECT_STREQ( | |
| 242 "{\"type\":\"StackTrace\",\"id\":\"stacktrace\",\"members\":[]}", | |
| 243 handler.msg()); | |
| 244 | |
| 245 // Malformed request. | |
| 246 service_msg = Eval(lib, "[0, port, ['stacktrace', 'jamboree'], [], []]"); | |
| 247 Service::HandleIsolateMessage(isolate, service_msg); | |
| 248 handler.HandleNextMessage(); | |
| 249 EXPECT_STREQ( | |
| 250 "{\"type\":\"Error\",\"id\":\"\",\"message\":\"Command too long\"," | |
| 251 "\"request\":{\"arguments\":[\"stacktrace\",\"jamboree\"]," | |
| 252 "\"option_keys\":[],\"option_values\":[]}}", | |
| 253 handler.msg()); | |
| 254 } | |
| 255 | |
| 256 | |
| 257 TEST_CASE(Service_DebugBreakpoints) { | |
| 258 const char* kScript = | |
| 259 "var port;\n" // Set to our mock port by C++. | |
| 260 "\n" | |
| 261 "main() {\n" // We set breakpoint here. | |
| 262 "}"; | |
| 263 | |
| 264 Isolate* isolate = Isolate::Current(); | |
| 265 Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL); | |
| 266 EXPECT_VALID(lib); | |
| 267 Library& vmlib = Library::Handle(); | |
| 268 vmlib ^= Api::UnwrapHandle(lib); | |
| 269 EXPECT(!vmlib.IsNull()); | |
| 270 | |
| 271 // Build a mock message handler and wrap it in a dart port. | |
| 272 ServiceTestMessageHandler handler; | |
| 273 Dart_Port port_id = PortMap::CreatePort(&handler); | |
| 274 Dart_Handle port = Api::NewHandle(isolate, SendPort::New(port_id)); | |
| 275 EXPECT_VALID(port); | |
| 276 EXPECT_VALID(Dart_SetField(lib, NewString("port"), port)); | |
| 277 | |
| 278 Array& service_msg = Array::Handle(); | |
| 279 | |
| 280 // Add a breakpoint. | |
| 281 service_msg = EvalF(lib, | |
| 282 "[0, port, ['libraries', '%" Pd "', " | |
| 283 "'scripts', 'test-lib', 'setBreakpoint'], " | |
| 284 "['line'], ['3']]", | |
| 285 vmlib.index()); | |
| 286 Service::HandleIsolateMessage(isolate, service_msg); | |
| 287 handler.HandleNextMessage(); | |
| 288 ExpectSubstringF( | |
| 289 handler.msg(), | |
| 290 "{\"type\":\"Breakpoint\",\"id\":\"debug\\/breakpoints\\/1\"," | |
| 291 "\"breakpointNumber\":1,\"enabled\":true,\"resolved\":false," | |
| 292 "\"location\":{\"type\":\"Location\"," | |
| 293 "\"script\":{\"type\":\"@Script\"," | |
| 294 "\"id\":\"libraries\\/%" Pd "\\/scripts\\/test-lib\"," | |
| 295 "\"name\":\"test-lib\",\"kind\":\"script\"}," | |
| 296 "\"tokenPos\":5}}", | |
| 297 vmlib.index()); | |
| 298 | |
| 299 // Get the breakpoint list. | |
| 300 service_msg = Eval(lib, "[0, port, ['debug', 'breakpoints'], [], []]"); | |
| 301 Service::HandleIsolateMessage(isolate, service_msg); | |
| 302 handler.HandleNextMessage(); | |
| 303 ExpectSubstringF( | |
| 304 handler.msg(), | |
| 305 "{\"type\":\"BreakpointList\",\"id\":\"debug\\/breakpoints\"," | |
| 306 "\"breakpoints\":[" | |
| 307 "{\"type\":\"Breakpoint\",\"id\":\"debug\\/breakpoints\\/1\"," | |
| 308 "\"breakpointNumber\":1,\"enabled\":true,\"resolved\":false," | |
| 309 "\"location\":{\"type\":\"Location\"," | |
| 310 "\"script\":{\"type\":\"@Script\"," | |
| 311 "\"id\":\"libraries\\/%" Pd "\\/scripts\\/test-lib\"," | |
| 312 "\"name\":\"test-lib\",\"kind\":\"script\"}," | |
| 313 "\"tokenPos\":5}}]}", | |
| 314 vmlib.index()); | |
| 315 | |
| 316 // Lookup individual breakpoint. | |
| 317 service_msg = Eval(lib, "[0, port, ['debug', 'breakpoints', '1'], [], []]"); | |
| 318 Service::HandleIsolateMessage(isolate, service_msg); | |
| 319 handler.HandleNextMessage(); | |
| 320 ExpectSubstringF( | |
| 321 handler.msg(), | |
| 322 "{\"type\":\"Breakpoint\",\"id\":\"debug\\/breakpoints\\/1\"," | |
| 323 "\"breakpointNumber\":1,\"enabled\":true,\"resolved\":false," | |
| 324 "\"location\":{\"type\":\"Location\"," | |
| 325 "\"script\":{\"type\":\"@Script\"," | |
| 326 "\"id\":\"libraries\\/%" Pd "\\/scripts\\/test-lib\"," | |
| 327 "\"name\":\"test-lib\",\"kind\":\"script\"}," | |
| 328 "\"tokenPos\":5}}", | |
| 329 vmlib.index()); | |
| 330 | |
| 331 // Unrecognized breakpoint subcommand. | |
| 332 service_msg = | |
| 333 Eval(lib, "[0, port, ['debug', 'breakpoints', '1', 'green'], [], []]"); | |
| 334 Service::HandleIsolateMessage(isolate, service_msg); | |
| 335 handler.HandleNextMessage(); | |
| 336 EXPECT_STREQ("{\"type\":\"Error\",\"id\":\"\"," | |
| 337 "\"message\":\"Unrecognized subcommand: green\"," | |
| 338 "\"request\":{\"arguments\":[\"debug\",\"breakpoints\"," | |
| 339 "\"1\",\"green\"]," | |
| 340 "\"option_keys\":[],\"option_values\":[]}}", | |
| 341 handler.msg()); | |
| 342 | |
| 343 // Clear breakpoint. | |
| 344 service_msg = | |
| 345 Eval(lib, "[0, port, ['debug', 'breakpoints', '1', 'clear'], [], []]"); | |
| 346 Service::HandleIsolateMessage(isolate, service_msg); | |
| 347 handler.HandleNextMessage(); | |
| 348 EXPECT_STREQ("{\"type\":\"Success\",\"id\":\"\"}", | |
| 349 handler.msg()); | |
| 350 | |
| 351 // Get the breakpoint list. | |
| 352 service_msg = Eval(lib, "[0, port, ['debug', 'breakpoints'], [], []]"); | |
| 353 Service::HandleIsolateMessage(isolate, service_msg); | |
| 354 handler.HandleNextMessage(); | |
| 355 EXPECT_STREQ( | |
| 356 "{\"type\":\"BreakpointList\",\"id\":\"debug\\/breakpoints\"," | |
| 357 "\"breakpoints\":[]}", | |
| 358 handler.msg()); | |
| 359 | |
| 360 // Missing sub-command. | |
| 361 service_msg = Eval(lib, "[0, port, ['debug'], [], []]"); | |
| 362 Service::HandleIsolateMessage(isolate, service_msg); | |
| 363 handler.HandleNextMessage(); | |
| 364 EXPECT_STREQ( | |
| 365 "{\"type\":\"Error\",\"id\":\"\"," | |
| 366 "\"message\":\"Must specify a subcommand\"," | |
| 367 "\"request\":{\"arguments\":[\"debug\"],\"option_keys\":[]," | |
| 368 "\"option_values\":[]}}", | |
| 369 handler.msg()); | |
| 370 | |
| 371 // Unrecognized breakpoint. | |
| 372 service_msg = Eval(lib, | |
| 373 "[0, port, ['debug', 'breakpoints', '1111'], [], []]"); | |
| 374 Service::HandleIsolateMessage(isolate, service_msg); | |
| 375 handler.HandleNextMessage(); | |
| 376 EXPECT_STREQ("{\"type\":\"Error\",\"id\":\"\"," | |
| 377 "\"message\":\"Unrecognized breakpoint id: 1111\"," | |
| 378 "\"request\":{" | |
| 379 "\"arguments\":[\"debug\",\"breakpoints\",\"1111\"]," | |
| 380 "\"option_keys\":[],\"option_values\":[]}}", | |
| 381 handler.msg()); | |
| 382 | |
| 383 // Unrecognized subcommand. | |
| 384 service_msg = Eval(lib, "[0, port, ['debug', 'nosferatu'], [], []]"); | |
| 385 Service::HandleIsolateMessage(isolate, service_msg); | |
| 386 handler.HandleNextMessage(); | |
| 387 EXPECT_STREQ("{\"type\":\"Error\",\"id\":\"\"," | |
| 388 "\"message\":\"Unrecognized subcommand 'nosferatu'\"," | |
| 389 "\"request\":{\"arguments\":[\"debug\",\"nosferatu\"]," | |
| 390 "\"option_keys\":[],\"option_values\":[]}}", | |
| 391 handler.msg()); | |
| 392 } | |
| 393 | |
| 394 | |
| 395 // Globals used to communicate with HandlerPausedEvent. | |
| 396 static intptr_t pause_line_number = 0; | |
| 397 static Dart_Handle saved_lib; | |
| 398 static ServiceTestMessageHandler* saved_handler = NULL; | |
| 399 | |
| 400 static void HandlePausedEvent(Dart_IsolateId isolate_id, | |
| 401 intptr_t bp_id, | |
| 402 const Dart_CodeLocation& loc) { | |
| 403 Isolate* isolate = Isolate::Current(); | |
| 404 Debugger* debugger = isolate->debugger(); | |
| 405 | |
| 406 // The debugger knows that it is paused, and why. | |
| 407 EXPECT(debugger->IsPaused()); | |
| 408 const DebuggerEvent* event = debugger->PauseEvent(); | |
| 409 EXPECT(event != NULL); | |
| 410 EXPECT(event->type() == DebuggerEvent::kBreakpointReached); | |
| 411 | |
| 412 // Save the last line number seen by this handler. | |
| 413 pause_line_number = event->top_frame()->LineNumber(); | |
| 414 | |
| 415 // Single step | |
| 416 Array& service_msg = Array::Handle(); | |
| 417 service_msg = Eval(saved_lib, | |
| 418 "[0, port, ['debug', 'resume'], " | |
| 419 "['step'], ['into']]"); | |
| 420 Service::HandleIsolateMessage(isolate, service_msg); | |
| 421 saved_handler->HandleNextMessage(); | |
| 422 EXPECT_STREQ("{\"type\":\"Success\",\"id\":\"\"}", | |
| 423 saved_handler->msg()); | |
| 424 } | |
| 425 | |
| 426 | |
| 427 TEST_CASE(Service_Stepping) { | |
| 428 const char* kScript = | |
| 429 "var port;\n" // Set to our mock port by C++. | |
| 430 "var value = 0;\n" | |
| 431 "\n" | |
| 432 "main() {\n" // We set breakpoint here. | |
| 433 " value++;\n" | |
| 434 " value++;\n" | |
| 435 " value++;\n" | |
| 436 "}"; // We step up to here. | |
| 437 | |
| 438 Isolate* isolate = Isolate::Current(); | |
| 439 Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL); | |
| 440 EXPECT_VALID(lib); | |
| 441 Library& vmlib = Library::Handle(); | |
| 442 vmlib ^= Api::UnwrapHandle(lib); | |
| 443 EXPECT(!vmlib.IsNull()); | |
| 444 saved_lib = lib; | |
| 445 | |
| 446 // Build a mock message handler and wrap it in a dart port. | |
| 447 ServiceTestMessageHandler handler; | |
| 448 saved_handler = &handler; | |
| 449 Dart_Port port_id = PortMap::CreatePort(&handler); | |
| 450 Dart_Handle port = Api::NewHandle(isolate, SendPort::New(port_id)); | |
| 451 EXPECT_VALID(port); | |
| 452 EXPECT_VALID(Dart_SetField(lib, NewString("port"), port)); | |
| 453 | |
| 454 Array& service_msg = Array::Handle(); | |
| 455 | |
| 456 // Add a breakpoint. | |
| 457 service_msg = EvalF(lib, | |
| 458 "[0, port, ['libraries', '%" Pd "', " | |
| 459 "'scripts', 'test-lib', 'setBreakpoint'], " | |
| 460 "['line'], ['4']]", | |
| 461 vmlib.index()); | |
| 462 Service::HandleIsolateMessage(isolate, service_msg); | |
| 463 handler.HandleNextMessage(); | |
| 464 ExpectSubstringF( | |
| 465 handler.msg(), | |
| 466 "{\"type\":\"Breakpoint\",\"id\":\"debug\\/breakpoints\\/1\"," | |
| 467 "\"breakpointNumber\":1,\"enabled\":true,\"resolved\":false," | |
| 468 "\"location\":{\"type\":\"Location\"," | |
| 469 "\"script\":{\"type\":\"@Script\"," | |
| 470 "\"id\":\"libraries\\/%" Pd "\\/scripts\\/test-lib\"," | |
| 471 "\"name\":\"test-lib\",\"kind\":\"script\"}," | |
| 472 "\"tokenPos\":11}}", | |
| 473 vmlib.index()); | |
| 474 | |
| 475 pause_line_number = -1; | |
| 476 Dart_SetPausedEventHandler(HandlePausedEvent); | |
| 477 | |
| 478 // Run the program. | |
| 479 Dart_Handle result = Dart_Invoke(lib, NewString("main"), 0, NULL); | |
| 480 EXPECT_VALID(result); | |
| 481 | |
| 482 // We were able to step to the last line in main. | |
| 483 EXPECT_EQ(8, pause_line_number); | |
| 484 } | |
| 485 | |
| 486 | |
| 487 TEST_CASE(Service_Objects) { | 216 TEST_CASE(Service_Objects) { |
| 488 // TODO(turnidge): Extend this test to cover a non-trivial stack trace. | 217 // TODO(turnidge): Extend this test to cover a non-trivial stack trace. |
| 489 const char* kScript = | 218 const char* kScript = |
| 490 "var port;\n" // Set to our mock port by C++. | 219 "var port;\n" // Set to our mock port by C++. |
| 491 "var validId;\n" // Set to a valid object id by C++. | 220 "var validId;\n" // Set to a valid object id by C++. |
| 492 "\n" | 221 "\n" |
| 493 "main() {\n" | 222 "main() {\n" |
| 494 "}"; | 223 "}"; |
| 495 | 224 |
| 496 Isolate* isolate = Isolate::Current(); | 225 Isolate* isolate = Isolate::Current(); |
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 629 // object id ring / invalid => expired | 358 // object id ring / invalid => expired |
| 630 service_msg = Eval(lib, "[0, port, ['objects', '99999999'], [], []]"); | 359 service_msg = Eval(lib, "[0, port, ['objects', '99999999'], [], []]"); |
| 631 Service::HandleIsolateMessage(isolate, service_msg); | 360 Service::HandleIsolateMessage(isolate, service_msg); |
| 632 handler.HandleNextMessage(); | 361 handler.HandleNextMessage(); |
| 633 handler.filterMsg("_vmName"); | 362 handler.filterMsg("_vmName"); |
| 634 EXPECT_STREQ( | 363 EXPECT_STREQ( |
| 635 "{\"type\":\"Sentinel\",\"id\":\"objects\\/expired\"," | 364 "{\"type\":\"Sentinel\",\"id\":\"objects\\/expired\"," |
| 636 "\"valueAsString\":\"<expired>\"}", | 365 "\"valueAsString\":\"<expired>\"}", |
| 637 handler.msg()); | 366 handler.msg()); |
| 638 | 367 |
| 639 // expired/eval => error | 368 // Retained by single instance. |
| 640 service_msg = Eval(lib, "[0, port, ['objects', 'expired', 'eval'], [], []]"); | 369 service_msg = Eval( |
| 370 lib, |
| 371 "[0, port, 'getRetainedSize', " |
| 372 "['targetId'], ['objects/$validId']]"); |
| 641 Service::HandleIsolateMessage(isolate, service_msg); | 373 Service::HandleIsolateMessage(isolate, service_msg); |
| 642 handler.HandleNextMessage(); | 374 handler.HandleNextMessage(); |
| 643 handler.filterMsg("_vmName"); | 375 handler.filterMsg("_vmName"); |
| 644 EXPECT_STREQ( | |
| 645 "{\"type\":\"Error\",\"id\":\"\"," | |
| 646 "\"message\":\"expected at most 2 arguments but found 3\\n\"," | |
| 647 "\"request\":{\"arguments\":[\"objects\",\"expired\",\"eval\"]," | |
| 648 "\"option_keys\":[],\"option_values\":[]}}", | |
| 649 handler.msg()); | |
| 650 | |
| 651 // int/eval => good | |
| 652 service_msg = Eval(lib, | |
| 653 "[0, port, ['objects', 'int-123', 'eval'], " | |
| 654 "['expr'], ['this+99']]"); | |
| 655 Service::HandleIsolateMessage(isolate, service_msg); | |
| 656 handler.HandleNextMessage(); | |
| 657 handler.filterMsg("_vmName"); | |
| 658 EXPECT_STREQ( | |
| 659 "{\"type\":\"@int\",\"_vmType\":\"@Smi\"," | |
| 660 "\"class\":{\"type\":\"@Class\",\"id\":\"classes\\/42\"," | |
| 661 "\"name\":\"_Smi\",}," | |
| 662 "\"id\":\"objects\\/int-222\"," | |
| 663 "\"valueAsString\":\"222\"}", | |
| 664 handler.msg()); | |
| 665 | |
| 666 // eval returning null works | |
| 667 service_msg = Eval(lib, | |
| 668 "[0, port, ['objects', 'int-123', 'eval'], " | |
| 669 "['expr'], ['null']]"); | |
| 670 Service::HandleIsolateMessage(isolate, service_msg); | |
| 671 handler.HandleNextMessage(); | |
| 672 handler.filterMsg("_vmName"); | |
| 673 EXPECT_STREQ( | |
| 674 "{\"type\":\"@null\",\"id\":\"objects\\/null\"," | |
| 675 "\"valueAsString\":\"null\"}", | |
| 676 handler.msg()); | |
| 677 | |
| 678 // object id ring / invalid => expired | |
| 679 service_msg = Eval(lib, "[0, port, ['objects', '99999999', 'eval'], " | |
| 680 "['expr'], ['this']]"); | |
| 681 Service::HandleIsolateMessage(isolate, service_msg); | |
| 682 handler.HandleNextMessage(); | |
| 683 handler.filterMsg("_vmName"); | |
| 684 EXPECT_STREQ( | |
| 685 "{\"type\":\"Error\",\"id\":\"\",\"kind\":\"EvalExpired\"," | |
| 686 "\"message\":\"attempt to evaluate against expired object\\n\"," | |
| 687 "\"request\":{\"arguments\":[\"objects\",\"99999999\",\"eval\"]," | |
| 688 "\"option_keys\":[\"expr\"],\"option_values\":[\"this\"]}}", | |
| 689 handler.msg()); | |
| 690 | |
| 691 // Extra arg to eval. | |
| 692 service_msg = Eval(lib, | |
| 693 "[0, port, ['objects', 'int-123', 'eval', 'foo'], " | |
| 694 "['expr'], ['this+99']]"); | |
| 695 Service::HandleIsolateMessage(isolate, service_msg); | |
| 696 handler.HandleNextMessage(); | |
| 697 handler.filterMsg("_vmName"); | |
| 698 EXPECT_STREQ( | |
| 699 "{\"type\":\"Error\",\"id\":\"\"," | |
| 700 "\"message\":\"expected at most 3 arguments but found 4\\n\"," | |
| 701 "\"request\":{\"arguments\":[\"objects\",\"int-123\",\"eval\",\"foo\"]," | |
| 702 "\"option_keys\":[\"expr\"],\"option_values\":[\"this+99\"]}}", | |
| 703 handler.msg()); | |
| 704 | |
| 705 // Retained by single instance. | |
| 706 service_msg = Eval(lib, | |
| 707 "[0, port, ['objects', '$validId', 'retained'], [], []]"); | |
| 708 Service::HandleIsolateMessage(isolate, service_msg); | |
| 709 handler.HandleNextMessage(); | |
| 710 handler.filterMsg("_vmName"); | |
| 711 ExpectSubstringF(handler.msg(), | 376 ExpectSubstringF(handler.msg(), |
| 712 "\"id\":\"objects\\/int-%" Pd "\"", | 377 "\"id\":\"objects\\/int-%" Pd "\"", |
| 713 arr.raw()->Size() + arr.At(0)->Size()); | 378 arr.raw()->Size() + arr.At(0)->Size()); |
| 714 | 379 |
| 715 // Retaining path to 'arr', limit 1. | 380 // Retaining path to 'arr', limit 1. |
| 716 service_msg = Eval( | 381 service_msg = Eval( |
| 717 lib, | 382 lib, |
| 718 "[0, port, ['objects', '$validId', 'retaining_path'], ['limit'], ['1']]"); | 383 "[0, port, 'getRetainingPath', " |
| 384 "['targetId', 'limit'], ['objects/$validId', '1']]"); |
| 719 Service::HandleIsolateMessage(isolate, service_msg); | 385 Service::HandleIsolateMessage(isolate, service_msg); |
| 720 handler.HandleNextMessage(); | 386 handler.HandleNextMessage(); |
| 721 ExpectSubstringF( | 387 ExpectSubstringF( |
| 722 handler.msg(), | 388 handler.msg(), |
| 723 "{\"type\":\"RetainingPath\",\"id\":\"retaining_path\",\"length\":1," | 389 "{\"type\":\"RetainingPath\",\"length\":1," |
| 724 "\"elements\":[{\"index\":0,\"value\":{\"type\":\"@List\""); | 390 "\"elements\":[{\"index\":0,\"value\":{\"type\":\"@List\""); |
| 725 | 391 |
| 726 // Retaining path missing limit. | 392 // Retaining path missing limit. |
| 727 service_msg = Eval( | 393 service_msg = Eval( |
| 728 lib, | 394 lib, |
| 729 "[0, port, ['objects', '$validId', 'retaining_path'], [], []]"); | 395 "[0, port, 'getRetainingPath', " |
| 396 "['targetId'], ['objects/$validId']]"); |
| 730 Service::HandleIsolateMessage(isolate, service_msg); | 397 Service::HandleIsolateMessage(isolate, service_msg); |
| 731 handler.HandleNextMessage(); | 398 handler.HandleNextMessage(); |
| 732 ExpectSubstringF(handler.msg(), "{\"type\":\"Error\""); | 399 ExpectSubstringF(handler.msg(), "{\"type\":\"Error\""); |
| 733 | |
| 734 // eval against list containing an internal object. | |
| 735 Object& internal_object = Object::Handle(); | |
| 736 internal_object = LiteralToken::New(); | |
| 737 arr.SetAt(0, internal_object); | |
| 738 service_msg = Eval(lib, | |
| 739 "[0, port, ['objects', '$validId', 'eval'], " | |
| 740 "['expr'], ['toString()']]"); | |
| 741 Service::HandleIsolateMessage(isolate, service_msg); | |
| 742 handler.HandleNextMessage(); | |
| 743 ExpectSubstringF(handler.msg(), "\"type\":\"Error\""); | |
| 744 ExpectSubstringF( | |
| 745 handler.msg(), | |
| 746 "\"message\":\"attempt to evaluate against internal VM object\\n\""); | |
| 747 } | 400 } |
| 748 | 401 |
| 749 | 402 |
| 750 TEST_CASE(Service_RetainingPath) { | 403 TEST_CASE(Service_RetainingPath) { |
| 751 const char* kScript = | 404 const char* kScript = |
| 752 "var port;\n" // Set to our mock port by C++. | 405 "var port;\n" // Set to our mock port by C++. |
| 753 "var id0;\n" // Set to an object id by C++. | 406 "var id0;\n" // Set to an object id by C++. |
| 754 "var id1;\n" // Ditto. | 407 "var id1;\n" // Ditto. |
| 755 "var idElem;\n" // Ditto. | 408 "var idElem;\n" // Ditto. |
| 756 "class Foo {\n" | 409 "class Foo {\n" |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 810 ServiceTestMessageHandler handler; | 463 ServiceTestMessageHandler handler; |
| 811 Dart_Port port_id = PortMap::CreatePort(&handler); | 464 Dart_Port port_id = PortMap::CreatePort(&handler); |
| 812 Dart_Handle port = Api::NewHandle(isolate, SendPort::New(port_id)); | 465 Dart_Handle port = Api::NewHandle(isolate, SendPort::New(port_id)); |
| 813 EXPECT_VALID(port); | 466 EXPECT_VALID(port); |
| 814 EXPECT_VALID(Dart_SetField(lib, NewString("port"), port)); | 467 EXPECT_VALID(Dart_SetField(lib, NewString("port"), port)); |
| 815 Array& service_msg = Array::Handle(); | 468 Array& service_msg = Array::Handle(); |
| 816 | 469 |
| 817 // Retaining path to 'foo0', limit 2. | 470 // Retaining path to 'foo0', limit 2. |
| 818 service_msg = Eval( | 471 service_msg = Eval( |
| 819 lib, | 472 lib, |
| 820 "[0, port, ['objects', '$id0', 'retaining_path'], ['limit'], ['2']]"); | 473 "[0, port, 'getRetainingPath', " |
| 474 "['targetId', 'limit'], ['objects/$id0', '2']]"); |
| 821 Service::HandleIsolateMessage(isolate, service_msg); | 475 Service::HandleIsolateMessage(isolate, service_msg); |
| 822 handler.HandleNextMessage(); | 476 handler.HandleNextMessage(); |
| 823 ExpectSubstringF( | 477 ExpectSubstringF( |
| 824 handler.msg(), | 478 handler.msg(), |
| 825 "{\"type\":\"RetainingPath\",\"id\":\"retaining_path\",\"length\":2," | 479 "{\"type\":\"RetainingPath\",\"length\":2," |
| 826 "\"elements\":[{\"index\":0,\"value\":{\"type\":\"@String\""); | 480 "\"elements\":[{\"index\":0,\"value\":{\"type\":\"@String\""); |
| 827 ExpectSubstringF(handler.msg(), "\"parentField\":{\"type\":\"@Field\""); | 481 ExpectSubstringF(handler.msg(), "\"parentField\":{\"type\":\"@Field\""); |
| 828 ExpectSubstringF(handler.msg(), "\"name\":\"f0\""); | 482 ExpectSubstringF(handler.msg(), "\"name\":\"f0\""); |
| 829 ExpectSubstringF(handler.msg(), | 483 ExpectSubstringF(handler.msg(), |
| 830 "{\"index\":1,\"value\":{\"type\":\"@Instance\""); | 484 "{\"index\":1,\"value\":{\"type\":\"@Instance\""); |
| 831 | 485 |
| 832 // Retaining path to 'foo1', limit 2. | 486 // Retaining path to 'foo1', limit 2. |
| 833 service_msg = Eval( | 487 service_msg = Eval( |
| 834 lib, | 488 lib, |
| 835 "[0, port, ['objects', '$id1', 'retaining_path'], ['limit'], ['2']]"); | 489 "[0, port, 'getRetainingPath', " |
| 490 "['targetId', 'limit'], ['objects/$id1', '2']]"); |
| 836 Service::HandleIsolateMessage(isolate, service_msg); | 491 Service::HandleIsolateMessage(isolate, service_msg); |
| 837 handler.HandleNextMessage(); | 492 handler.HandleNextMessage(); |
| 838 ExpectSubstringF( | 493 ExpectSubstringF( |
| 839 handler.msg(), | 494 handler.msg(), |
| 840 "{\"type\":\"RetainingPath\",\"id\":\"retaining_path\",\"length\":2," | 495 "{\"type\":\"RetainingPath\",\"length\":2," |
| 841 "\"elements\":[{\"index\":0,\"value\":{\"type\":\"@String\""); | 496 "\"elements\":[{\"index\":0,\"value\":{\"type\":\"@String\""); |
| 842 ExpectSubstringF(handler.msg(), "\"parentField\":{\"type\":\"@Field\""); | 497 ExpectSubstringF(handler.msg(), "\"parentField\":{\"type\":\"@Field\""); |
| 843 ExpectSubstringF(handler.msg(), "\"name\":\"f1\""); | 498 ExpectSubstringF(handler.msg(), "\"name\":\"f1\""); |
| 844 ExpectSubstringF(handler.msg(), | 499 ExpectSubstringF(handler.msg(), |
| 845 "{\"index\":1,\"value\":{\"type\":\"@Instance\""); | 500 "{\"index\":1,\"value\":{\"type\":\"@Instance\""); |
| 846 | 501 |
| 847 // Retaining path to 'elem', limit 2. | 502 // Retaining path to 'elem', limit 2. |
| 848 service_msg = Eval( | 503 service_msg = Eval( |
| 849 lib, | 504 lib, |
| 850 "[0, port, ['objects', '$idElem', 'retaining_path'], ['limit'], ['2']]"); | 505 "[0, port, 'getRetainingPath', " |
| 506 "['targetId', 'limit'], ['objects/$idElem', '2']]"); |
| 851 Service::HandleIsolateMessage(isolate, service_msg); | 507 Service::HandleIsolateMessage(isolate, service_msg); |
| 852 handler.HandleNextMessage(); | 508 handler.HandleNextMessage(); |
| 853 ExpectSubstringF( | 509 ExpectSubstringF( |
| 854 handler.msg(), | 510 handler.msg(), |
| 855 "{\"type\":\"RetainingPath\",\"id\":\"retaining_path\",\"length\":2," | 511 "{\"type\":\"RetainingPath\",\"length\":2," |
| 856 "\"elements\":[{\"index\":0,\"value\":{\"type\":\"@String\""); | 512 "\"elements\":[{\"index\":0,\"value\":{\"type\":\"@String\""); |
| 857 ExpectSubstringF(handler.msg(), "\"parentListIndex\":%" Pd, kElemIndex); | 513 ExpectSubstringF(handler.msg(), "\"parentListIndex\":%" Pd, kElemIndex); |
| 858 ExpectSubstringF(handler.msg(), | 514 ExpectSubstringF(handler.msg(), |
| 859 "{\"index\":1,\"value\":{\"type\":\"@List\""); | 515 "{\"index\":1,\"value\":{\"type\":\"@List\""); |
| 860 } | 516 } |
| 861 | 517 |
| 862 | 518 |
| 863 TEST_CASE(Service_Libraries) { | 519 TEST_CASE(Service_Libraries) { |
| 864 const char* kScript = | 520 const char* kScript = |
| 865 "var port;\n" // Set to our mock port by C++. | 521 "var port;\n" // Set to our mock port by C++. |
| (...skipping 19 matching lines...) Expand all Loading... |
| 885 Array& service_msg = Array::Handle(); | 541 Array& service_msg = Array::Handle(); |
| 886 | 542 |
| 887 // Request library. | 543 // Request library. |
| 888 service_msg = EvalF(lib, | 544 service_msg = EvalF(lib, |
| 889 "[0, port, ['libraries', '%" Pd "'], [], []]", | 545 "[0, port, ['libraries', '%" Pd "'], [], []]", |
| 890 vmlib.index()); | 546 vmlib.index()); |
| 891 Service::HandleIsolateMessage(isolate, service_msg); | 547 Service::HandleIsolateMessage(isolate, service_msg); |
| 892 handler.HandleNextMessage(); | 548 handler.HandleNextMessage(); |
| 893 EXPECT_SUBSTRING("\"type\":\"Library\"", handler.msg()); | 549 EXPECT_SUBSTRING("\"type\":\"Library\"", handler.msg()); |
| 894 EXPECT_SUBSTRING("\"url\":\"test-lib\"", handler.msg()); | 550 EXPECT_SUBSTRING("\"url\":\"test-lib\"", handler.msg()); |
| 895 | |
| 896 // Evaluate an expression from a library. | |
| 897 service_msg = EvalF(lib, | |
| 898 "[0, port, ['libraries', '%" Pd "', 'eval'], " | |
| 899 "['expr'], ['libVar - 1']]", | |
| 900 vmlib.index()); | |
| 901 Service::HandleIsolateMessage(isolate, service_msg); | |
| 902 handler.HandleNextMessage(); | |
| 903 handler.filterMsg("_vmName"); | |
| 904 EXPECT_STREQ( | |
| 905 "{\"type\":\"@int\",\"_vmType\":\"@Smi\"," | |
| 906 "\"class\":{\"type\":\"@Class\",\"id\":\"classes\\/42\"," | |
| 907 "\"name\":\"_Smi\",},\"id\":\"objects\\/int-54320\"," | |
| 908 "\"valueAsString\":\"54320\"}", | |
| 909 handler.msg()); | |
| 910 } | 551 } |
| 911 | 552 |
| 912 | 553 |
| 913 TEST_CASE(Service_Classes) { | 554 TEST_CASE(Service_Classes) { |
| 914 const char* kScript = | 555 const char* kScript = |
| 915 "var port;\n" // Set to our mock port by C++. | 556 "var port;\n" // Set to our mock port by C++. |
| 916 "\n" | 557 "\n" |
| 917 "class A {\n" | 558 "class A {\n" |
| 918 " var a;\n" | 559 " var a;\n" |
| 919 " static var cobra = 11235;\n" | 560 " static var cobra = 11235;\n" |
| (...skipping 30 matching lines...) Expand all Loading... |
| 950 EXPECT_VALID(port); | 591 EXPECT_VALID(port); |
| 951 EXPECT_VALID(Dart_SetField(lib, NewString("port"), port)); | 592 EXPECT_VALID(Dart_SetField(lib, NewString("port"), port)); |
| 952 | 593 |
| 953 Array& service_msg = Array::Handle(); | 594 Array& service_msg = Array::Handle(); |
| 954 | 595 |
| 955 // Request an invalid class id. | 596 // Request an invalid class id. |
| 956 service_msg = Eval(lib, "[0, port, ['classes', '999999'], [], []]"); | 597 service_msg = Eval(lib, "[0, port, ['classes', '999999'], [], []]"); |
| 957 Service::HandleIsolateMessage(isolate, service_msg); | 598 Service::HandleIsolateMessage(isolate, service_msg); |
| 958 handler.HandleNextMessage(); | 599 handler.HandleNextMessage(); |
| 959 EXPECT_STREQ( | 600 EXPECT_STREQ( |
| 960 "{\"type\":\"Error\",\"id\":\"\"," | 601 "{\"type\":\"Error\"," |
| 961 "\"message\":\"999999 is not a valid class id.\"," | 602 "\"message\":\"999999 is not a valid class id.\"," |
| 962 "\"request\":{\"arguments\":[\"classes\",\"999999\"]," | 603 "\"request\":{\"arguments\":[\"classes\",\"999999\"]," |
| 963 "\"option_keys\":[],\"option_values\":[]}}", handler.msg()); | 604 "\"option_keys\":[],\"option_values\":[]}}", handler.msg()); |
| 964 | 605 |
| 965 // Request the class A over the service. | 606 // Request the class A over the service. |
| 966 service_msg = EvalF(lib, "[0, port, ['classes', '%" Pd "'], [], []]", cid); | 607 service_msg = EvalF(lib, "[0, port, ['classes', '%" Pd "'], [], []]", cid); |
| 967 Service::HandleIsolateMessage(isolate, service_msg); | 608 Service::HandleIsolateMessage(isolate, service_msg); |
| 968 handler.HandleNextMessage(); | 609 handler.HandleNextMessage(); |
| 969 EXPECT_SUBSTRING("\"type\":\"Class\"", handler.msg()); | 610 EXPECT_SUBSTRING("\"type\":\"Class\"", handler.msg()); |
| 970 ExpectSubstringF(handler.msg(), | 611 ExpectSubstringF(handler.msg(), |
| 971 "\"id\":\"classes\\/%" Pd "\",\"name\":\"A\",", cid); | 612 "\"id\":\"classes\\/%" Pd "\",\"name\":\"A\",", cid); |
| 972 ExpectSubstringF(handler.msg(), "\"allocationStats\":"); | 613 ExpectSubstringF(handler.msg(), "\"allocationStats\":"); |
| 973 ExpectSubstringF(handler.msg(), "\"tokenPos\":"); | 614 ExpectSubstringF(handler.msg(), "\"tokenPos\":"); |
| 974 ExpectSubstringF(handler.msg(), "\"endTokenPos\":"); | 615 ExpectSubstringF(handler.msg(), "\"endTokenPos\":"); |
| 975 | 616 |
| 976 // Evaluate an expression from class A. | |
| 977 service_msg = EvalF(lib, | |
| 978 "[0, port, ['classes', '%" Pd "', 'eval'], " | |
| 979 "['expr'], ['cobra + 100000']]", cid); | |
| 980 Service::HandleIsolateMessage(isolate, service_msg); | |
| 981 handler.HandleNextMessage(); | |
| 982 handler.filterMsg("_vmName"); | |
| 983 EXPECT_STREQ( | |
| 984 "{\"type\":\"@int\",\"_vmType\":\"@Smi\"," | |
| 985 "\"class\":{\"type\":\"@Class\",\"id\":\"classes\\/42\"," | |
| 986 "\"name\":\"_Smi\",}," | |
| 987 "\"id\":\"objects\\/int-111235\"," | |
| 988 "\"valueAsString\":\"111235\"}", | |
| 989 handler.msg()); | |
| 990 | |
| 991 // Request function 'b' from class A. | 617 // Request function 'b' from class A. |
| 992 service_msg = EvalF(lib, | 618 service_msg = EvalF(lib, |
| 993 "[0, port, ['classes', '%" Pd "', 'functions', 'b']," | 619 "[0, port, ['classes', '%" Pd "', 'functions', 'b']," |
| 994 "[], []]", cid); | 620 "[], []]", cid); |
| 995 Service::HandleIsolateMessage(isolate, service_msg); | 621 Service::HandleIsolateMessage(isolate, service_msg); |
| 996 handler.HandleNextMessage(); | 622 handler.HandleNextMessage(); |
| 997 EXPECT_SUBSTRING("\"type\":\"Function\"", handler.msg()); | 623 EXPECT_SUBSTRING("\"type\":\"Function\"", handler.msg()); |
| 998 ExpectSubstringF(handler.msg(), | 624 ExpectSubstringF(handler.msg(), |
| 999 "\"id\":\"classes\\/%" Pd "\\/functions\\/b\"," | 625 "\"id\":\"classes\\/%" Pd "\\/functions\\/b\"," |
| 1000 "\"name\":\"b\",", cid); | 626 "\"name\":\"b\",", cid); |
| 1001 | 627 |
| 1002 // Request field 0 from class A. | 628 // Request field 0 from class A. |
| 1003 service_msg = EvalF(lib, "[0, port, ['classes', '%" Pd "', 'fields', '0']," | 629 service_msg = EvalF(lib, "[0, port, ['classes', '%" Pd "', 'fields', '0']," |
| 1004 "[], []]", cid); | 630 "[], []]", cid); |
| 1005 Service::HandleIsolateMessage(isolate, service_msg); | 631 Service::HandleIsolateMessage(isolate, service_msg); |
| 1006 handler.HandleNextMessage(); | 632 handler.HandleNextMessage(); |
| 1007 EXPECT_SUBSTRING("\"type\":\"Field\"", handler.msg()); | 633 EXPECT_SUBSTRING("\"type\":\"Field\"", handler.msg()); |
| 1008 ExpectSubstringF(handler.msg(), | 634 ExpectSubstringF(handler.msg(), |
| 1009 "\"id\":\"classes\\/%" Pd "\\/fields\\/0\"," | 635 "\"id\":\"classes\\/%" Pd "\\/fields\\/0\"," |
| 1010 "\"name\":\"a\",", cid); | 636 "\"name\":\"a\",", cid); |
| 1011 | 637 |
| 1012 // Invalid sub command. | 638 // Invalid sub command. |
| 1013 service_msg = EvalF(lib, "[0, port, ['classes', '%" Pd "', 'huh', '0']," | 639 service_msg = EvalF(lib, "[0, port, ['classes', '%" Pd "', 'huh', '0']," |
| 1014 "[], []]", cid); | 640 "[], []]", cid); |
| 1015 Service::HandleIsolateMessage(isolate, service_msg); | 641 Service::HandleIsolateMessage(isolate, service_msg); |
| 1016 handler.HandleNextMessage(); | 642 handler.HandleNextMessage(); |
| 1017 ExpectSubstringF(handler.msg(), | 643 ExpectSubstringF(handler.msg(), |
| 1018 "{\"type\":\"Error\",\"id\":\"\",\"message\":\"Invalid sub collection huh\"" | 644 "{\"type\":\"Error\",\"message\":\"Invalid sub collection huh\"" |
| 1019 ",\"request\":" | 645 ",\"request\":" |
| 1020 "{\"arguments\":[\"classes\",\"%" Pd "\",\"huh\",\"0\"],\"option_keys\":[]," | 646 "{\"arguments\":[\"classes\",\"%" Pd "\",\"huh\",\"0\"],\"option_keys\":[]," |
| 1021 "\"option_values\":[]}}", cid); | 647 "\"option_values\":[]}}", cid); |
| 1022 | 648 |
| 1023 // Invalid field request. | 649 // Invalid field request. |
| 1024 service_msg = EvalF(lib, "[0, port, ['classes', '%" Pd "', 'fields', '9']," | 650 service_msg = EvalF(lib, "[0, port, ['classes', '%" Pd "', 'fields', '9']," |
| 1025 "[], []]", cid); | 651 "[], []]", cid); |
| 1026 Service::HandleIsolateMessage(isolate, service_msg); | 652 Service::HandleIsolateMessage(isolate, service_msg); |
| 1027 handler.HandleNextMessage(); | 653 handler.HandleNextMessage(); |
| 1028 ExpectSubstringF(handler.msg(), | 654 ExpectSubstringF(handler.msg(), |
| 1029 "{\"type\":\"Error\",\"id\":\"\",\"message\":\"Field 9 not found\"," | 655 "{\"type\":\"Error\",\"message\":\"Field 9 not found\"," |
| 1030 "\"request\":{\"arguments\":[\"classes\",\"%" Pd "\",\"fields\",\"9\"]," | 656 "\"request\":{\"arguments\":[\"classes\",\"%" Pd "\",\"fields\",\"9\"]," |
| 1031 "\"option_keys\":[],\"option_values\":[]}}", cid); | 657 "\"option_keys\":[],\"option_values\":[]}}", cid); |
| 1032 | 658 |
| 1033 // Invalid function request. | 659 // Invalid function request. |
| 1034 service_msg = EvalF(lib, | 660 service_msg = EvalF(lib, |
| 1035 "[0, port, ['classes', '%" Pd "', 'functions', '9']," | 661 "[0, port, ['classes', '%" Pd "', 'functions', '9']," |
| 1036 "[], []]", cid); | 662 "[], []]", cid); |
| 1037 Service::HandleIsolateMessage(isolate, service_msg); | 663 Service::HandleIsolateMessage(isolate, service_msg); |
| 1038 handler.HandleNextMessage(); | 664 handler.HandleNextMessage(); |
| 1039 ExpectSubstringF(handler.msg(), | 665 ExpectSubstringF(handler.msg(), |
| 1040 "{\"type\":\"Error\",\"id\":\"\",\"message\":\"Function 9 not found\"," | 666 "{\"type\":\"Error\",\"message\":\"Function 9 not found\"," |
| 1041 "\"request\":{\"arguments\":[\"classes\",\"%" Pd "\",\"functions\",\"9\"]," | 667 "\"request\":{\"arguments\":[\"classes\",\"%" Pd "\",\"functions\",\"9\"]," |
| 1042 "\"option_keys\":[],\"option_values\":[]}}", cid); | 668 "\"option_keys\":[],\"option_values\":[]}}", cid); |
| 1043 | 669 |
| 1044 | 670 |
| 1045 // Invalid field subcommand. | 671 // Invalid field subcommand. |
| 1046 service_msg = EvalF(lib, | 672 service_msg = EvalF(lib, |
| 1047 "[0, port, ['classes', '%" Pd "', 'fields', '9', 'x']" | 673 "[0, port, ['classes', '%" Pd "', 'fields', '9', 'x']" |
| 1048 ",[], []]", cid); | 674 ",[], []]", cid); |
| 1049 Service::HandleIsolateMessage(isolate, service_msg); | 675 Service::HandleIsolateMessage(isolate, service_msg); |
| 1050 handler.HandleNextMessage(); | 676 handler.HandleNextMessage(); |
| 1051 ExpectSubstringF(handler.msg(), | 677 ExpectSubstringF(handler.msg(), |
| 1052 "{\"type\":\"Error\",\"id\":\"\",\"message\":\"Command too long\"," | 678 "{\"type\":\"Error\",\"message\":\"Command too long\"," |
| 1053 "\"request\":" | 679 "\"request\":" |
| 1054 "{\"arguments\":[\"classes\",\"%" Pd "\",\"fields\",\"9\",\"x\"]," | 680 "{\"arguments\":[\"classes\",\"%" Pd "\",\"fields\",\"9\",\"x\"]," |
| 1055 "\"option_keys\":[],\"option_values\":[]}}", cid); | 681 "\"option_keys\":[],\"option_values\":[]}}", cid); |
| 1056 | 682 |
| 1057 // Invalid function command. | 683 // Invalid function command. |
| 1058 service_msg = EvalF(lib, | 684 service_msg = EvalF(lib, |
| 1059 "[0, port, ['classes', '%" Pd "', 'functions', '0'," | 685 "[0, port, ['classes', '%" Pd "', 'functions', '0'," |
| 1060 "'x', 'y'], [], []]", cid); | 686 "'x', 'y'], [], []]", cid); |
| 1061 Service::HandleIsolateMessage(isolate, service_msg); | 687 Service::HandleIsolateMessage(isolate, service_msg); |
| 1062 handler.HandleNextMessage(); | 688 handler.HandleNextMessage(); |
| 1063 ExpectSubstringF(handler.msg(), | 689 ExpectSubstringF(handler.msg(), |
| 1064 "{\"type\":\"Error\",\"id\":\"\"," | 690 "{\"type\":\"Error\"," |
| 1065 "\"message\":\"Command should have 4 or 5 arguments\"," | 691 "\"message\":\"Command should have 4 or 5 arguments\"," |
| 1066 "\"request\":" | 692 "\"request\":" |
| 1067 "{\"arguments\":[\"classes\",\"%" Pd "\",\"functions\",\"0\",\"x\",\"y\"]," | 693 "{\"arguments\":[\"classes\",\"%" Pd "\",\"functions\",\"0\",\"x\",\"y\"]," |
| 1068 "\"option_keys\":[],\"option_values\":[]}}", cid); | 694 "\"option_keys\":[],\"option_values\":[]}}", cid); |
| 1069 | 695 |
| 1070 // Invalid function subcommand with valid function id. | 696 // Invalid function subcommand with valid function id. |
| 1071 service_msg = EvalF(lib, | 697 service_msg = EvalF(lib, |
| 1072 "[0, port, ['classes', '%" Pd "', 'functions', 'b'," | 698 "[0, port, ['classes', '%" Pd "', 'functions', 'b'," |
| 1073 "'x'], [], []]", cid); | 699 "'x'], [], []]", cid); |
| 1074 Service::HandleIsolateMessage(isolate, service_msg); | 700 Service::HandleIsolateMessage(isolate, service_msg); |
| 1075 handler.HandleNextMessage(); | 701 handler.HandleNextMessage(); |
| 1076 ExpectSubstringF(handler.msg(), | 702 ExpectSubstringF(handler.msg(), |
| 1077 "{\"type\":\"Error\",\"id\":\"\",\"message\":\"Invalid sub command x\"," | 703 "{\"type\":\"Error\",\"message\":\"Invalid sub command x\"," |
| 1078 "\"request\":" | 704 "\"request\":" |
| 1079 "{\"arguments\":[\"classes\",\"%" Pd "\",\"functions\",\"b\",\"x\"]," | 705 "{\"arguments\":[\"classes\",\"%" Pd "\",\"functions\",\"b\",\"x\"]," |
| 1080 "\"option_keys\":[],\"option_values\":[]}}", cid); | 706 "\"option_keys\":[],\"option_values\":[]}}", cid); |
| 1081 | 707 |
| 1082 // Retained size of all instances of class B. | 708 // Retained size of all instances of class B. |
| 1083 const Class& class_b = Class::Handle(GetClass(vmlib, "B")); | 709 const Class& class_b = Class::Handle(GetClass(vmlib, "B")); |
| 1084 EXPECT(!class_b.IsNull()); | 710 EXPECT(!class_b.IsNull()); |
| 1085 const Instance& b0 = Instance::Handle(Instance::New(class_b)); | 711 const Instance& b0 = Instance::Handle(Instance::New(class_b)); |
| 1086 const Instance& b1 = Instance::Handle(Instance::New(class_b)); | 712 const Instance& b1 = Instance::Handle(Instance::New(class_b)); |
| 1087 service_msg = EvalF(lib, "[0, port, ['classes', '%" Pd "', 'retained']," | 713 service_msg = EvalF(lib, "[0, port, 'getRetainedSize', " |
| 1088 "[], []]", class_b.id()); | 714 "['targetId'], ['classes/%" Pd "']]", class_b.id()); |
| 1089 Service::HandleIsolateMessage(isolate, service_msg); | 715 Service::HandleIsolateMessage(isolate, service_msg); |
| 1090 handler.HandleNextMessage(); | 716 handler.HandleNextMessage(); |
| 1091 ExpectSubstringF(handler.msg(), | 717 ExpectSubstringF(handler.msg(), |
| 1092 "\"id\":\"objects\\/int-%" Pd "\"", | 718 "\"id\":\"objects\\/int-%" Pd "\"", |
| 1093 b0.raw()->Size() + b1.raw()->Size()); | 719 b0.raw()->Size() + b1.raw()->Size()); |
| 1094 // ... and list the instances of class B. | 720 // ... and list the instances of class B. |
| 1095 service_msg = EvalF(lib, "[0, port, ['classes', '%" Pd "', 'instances']," | 721 service_msg = EvalF(lib, "[0, port, 'getInstances', " |
| 1096 "['limit'], ['3']]", class_b.id()); | 722 "['classId', 'limit'], ['classes/%" Pd "', '3']]", |
| 723 class_b.id()); |
| 1097 Service::HandleIsolateMessage(isolate, service_msg); | 724 Service::HandleIsolateMessage(isolate, service_msg); |
| 1098 handler.HandleNextMessage(); | 725 handler.HandleNextMessage(); |
| 1099 ExpectSubstringF(handler.msg(), "\"type\":\"InstanceSet\""); | 726 ExpectSubstringF(handler.msg(), "\"type\":\"InstanceSet\""); |
| 1100 ExpectSubstringF(handler.msg(), "\"totalCount\":2"); | 727 ExpectSubstringF(handler.msg(), "\"totalCount\":2"); |
| 1101 ExpectSubstringF(handler.msg(), "\"sampleCount\":2"); | 728 ExpectSubstringF(handler.msg(), "\"sampleCount\":2"); |
| 1102 // TODO(koda): Actually parse the response. | 729 // TODO(koda): Actually parse the response. |
| 1103 static const intptr_t kInstanceListId = 0; | 730 static const intptr_t kInstanceListId = 0; |
| 1104 ExpectSubstringF(handler.msg(), "\"id\":\"objects\\/%" Pd "\",\"length\":2", | 731 ExpectSubstringF(handler.msg(), "\"id\":\"objects\\/%" Pd "\",\"length\":2", |
| 1105 kInstanceListId); | 732 kInstanceListId); |
| 1106 Array& list = Array::Handle(); | 733 Array& list = Array::Handle(); |
| 1107 ObjectIdRing::LookupResult kind; | 734 ObjectIdRing::LookupResult kind; |
| 1108 list ^= isolate->object_id_ring()->GetObjectForId(kInstanceListId, &kind); | 735 list ^= isolate->object_id_ring()->GetObjectForId(kInstanceListId, &kind); |
| 1109 EXPECT_EQ(2, list.Length()); | 736 EXPECT_EQ(2, list.Length()); |
| 1110 // The list should contain {b0, b1}. | 737 // The list should contain {b0, b1}. |
| 1111 EXPECT((list.At(0) == b0.raw() && list.At(1) == b1.raw()) || | 738 EXPECT((list.At(0) == b0.raw() && list.At(1) == b1.raw()) || |
| 1112 (list.At(0) == b1.raw() && list.At(1) == b0.raw())); | 739 (list.At(0) == b1.raw() && list.At(1) == b0.raw())); |
| 1113 // ... and if limit is 1, we one get one of them. | 740 // ... and if limit is 1, we one get one of them. |
| 1114 service_msg = EvalF(lib, "[0, port, ['classes', '%" Pd "', 'instances']," | 741 service_msg = EvalF(lib, "[0, port, 'getInstances', " |
| 1115 "['limit'], ['1']]", class_b.id()); | 742 "['classId', 'limit'], ['classes/%" Pd "', '1']]", |
| 743 class_b.id()); |
| 1116 Service::HandleIsolateMessage(isolate, service_msg); | 744 Service::HandleIsolateMessage(isolate, service_msg); |
| 1117 handler.HandleNextMessage(); | 745 handler.HandleNextMessage(); |
| 1118 ExpectSubstringF(handler.msg(), "\"totalCount\":2"); | 746 ExpectSubstringF(handler.msg(), "\"totalCount\":2"); |
| 1119 ExpectSubstringF(handler.msg(), "\"sampleCount\":1"); | 747 ExpectSubstringF(handler.msg(), "\"sampleCount\":1"); |
| 1120 } | 748 } |
| 1121 | 749 |
| 1122 | 750 |
| 1123 TEST_CASE(Service_SetSource) { | 751 TEST_CASE(Service_SetSource) { |
| 1124 const char* kScript = | 752 const char* kScript = |
| 1125 "var port;\n" // Set to our mock port by C++. | 753 "var port;\n" // Set to our mock port by C++. |
| (...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1300 EXPECT_SUBSTRING("\"name\":\"A<A<bool>>\"", handler.msg()); | 928 EXPECT_SUBSTRING("\"name\":\"A<A<bool>>\"", handler.msg()); |
| 1301 ExpectSubstringF(handler.msg(), | 929 ExpectSubstringF(handler.msg(), |
| 1302 "\"id\":\"classes\\/%" Pd "\\/types\\/1\"", cid); | 930 "\"id\":\"classes\\/%" Pd "\\/types\\/1\"", cid); |
| 1303 | 931 |
| 1304 // Request for non-existent canonical type from class A. | 932 // Request for non-existent canonical type from class A. |
| 1305 service_msg = EvalF(lib, "[0, port, ['classes', '%" Pd "', 'types', '42']," | 933 service_msg = EvalF(lib, "[0, port, ['classes', '%" Pd "', 'types', '42']," |
| 1306 "[], []]", cid); | 934 "[], []]", cid); |
| 1307 Service::HandleIsolateMessage(isolate, service_msg); | 935 Service::HandleIsolateMessage(isolate, service_msg); |
| 1308 handler.HandleNextMessage(); | 936 handler.HandleNextMessage(); |
| 1309 ExpectSubstringF(handler.msg(), | 937 ExpectSubstringF(handler.msg(), |
| 1310 "{\"type\":\"Error\",\"id\":\"\"," | 938 "{\"type\":\"Error\"," |
| 1311 "\"message\":\"Canonical type 42 not found\"" | 939 "\"message\":\"Canonical type 42 not found\"" |
| 1312 ",\"request\":" | 940 ",\"request\":" |
| 1313 "{\"arguments\":[\"classes\",\"%" Pd "\",\"types\",\"42\"]," | 941 "{\"arguments\":[\"classes\",\"%" Pd "\",\"types\",\"42\"]," |
| 1314 "\"option_keys\":[],\"option_values\":[]}}", cid); | 942 "\"option_keys\":[],\"option_values\":[]}}", cid); |
| 1315 | 943 |
| 1316 // Request canonical type arguments. Expect <A<bool>> to be listed. | 944 // Request canonical type arguments. Expect <A<bool>> to be listed. |
| 1317 service_msg = EvalF(lib, "[0, port, ['typearguments']," | 945 service_msg = EvalF(lib, "[0, port, ['typearguments']," |
| 1318 "[], []]"); | 946 "[], []]"); |
| 1319 Service::HandleIsolateMessage(isolate, service_msg); | 947 Service::HandleIsolateMessage(isolate, service_msg); |
| 1320 handler.HandleNextMessage(); | 948 handler.HandleNextMessage(); |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1376 EXPECT_VALID(port); | 1004 EXPECT_VALID(port); |
| 1377 EXPECT_VALID(Dart_SetField(lib, NewString("port"), port)); | 1005 EXPECT_VALID(Dart_SetField(lib, NewString("port"), port)); |
| 1378 | 1006 |
| 1379 Array& service_msg = Array::Handle(); | 1007 Array& service_msg = Array::Handle(); |
| 1380 | 1008 |
| 1381 // Request an invalid code object. | 1009 // Request an invalid code object. |
| 1382 service_msg = Eval(lib, "[0, port, ['code', '0'], [], []]"); | 1010 service_msg = Eval(lib, "[0, port, ['code', '0'], [], []]"); |
| 1383 Service::HandleIsolateMessage(isolate, service_msg); | 1011 Service::HandleIsolateMessage(isolate, service_msg); |
| 1384 handler.HandleNextMessage(); | 1012 handler.HandleNextMessage(); |
| 1385 EXPECT_STREQ( | 1013 EXPECT_STREQ( |
| 1386 "{\"type\":\"Error\",\"id\":\"\",\"message\":\"Malformed code id: 0\"," | 1014 "{\"type\":\"Error\",\"message\":\"Malformed code id: 0\"," |
| 1387 "\"request\":{\"arguments\":[\"code\",\"0\"]," | 1015 "\"request\":{\"arguments\":[\"code\",\"0\"]," |
| 1388 "\"option_keys\":[],\"option_values\":[]}}", handler.msg()); | 1016 "\"option_keys\":[],\"option_values\":[]}}", handler.msg()); |
| 1389 | 1017 |
| 1390 // The following test checks that a code object can be found only | 1018 // The following test checks that a code object can be found only |
| 1391 // at compile_timestamp()-code.EntryPoint(). | 1019 // at compile_timestamp()-code.EntryPoint(). |
| 1392 service_msg = EvalF(lib, "[0, port, ['code', '%" Px64"-%" Px "'], [], []]", | 1020 service_msg = EvalF(lib, "[0, port, ['code', '%" Px64"-%" Px "'], [], []]", |
| 1393 compile_timestamp, | 1021 compile_timestamp, |
| 1394 entry); | 1022 entry); |
| 1395 Service::HandleIsolateMessage(isolate, service_msg); | 1023 Service::HandleIsolateMessage(isolate, service_msg); |
| 1396 handler.HandleNextMessage(); | 1024 handler.HandleNextMessage(); |
| (...skipping 351 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1748 "\"owningLibrary\":{\"type\":\"@Library\"," | 1376 "\"owningLibrary\":{\"type\":\"@Library\"," |
| 1749 "\"id\":\"libraries\\/%" Pd "\",\"name\":\"\"," | 1377 "\"id\":\"libraries\\/%" Pd "\",\"name\":\"\"," |
| 1750 "\"url\":\"test-lib\"}," | 1378 "\"url\":\"test-lib\"}," |
| 1751 "\"source\":\"var port;\\n\\nmain() {\\n}\"," | 1379 "\"source\":\"var port;\\n\\nmain() {\\n}\"," |
| 1752 "\"tokenPosTable\":[[1,0,1,1,5,2,9],[3,5,1,6,5,7,6,8,8],[4,10,1]]}", | 1380 "\"tokenPosTable\":[[1,0,1,1,5,2,9],[3,5,1,6,5,7,6,8,8],[4,10,1]]}", |
| 1753 vmlib.index(), vmlib.index()); | 1381 vmlib.index(), vmlib.index()); |
| 1754 EXPECT_STREQ(buf, handler.msg()); | 1382 EXPECT_STREQ(buf, handler.msg()); |
| 1755 } | 1383 } |
| 1756 | 1384 |
| 1757 | 1385 |
| 1758 // TODO(zra): Remove when tests are ready to enable. | |
| 1759 #if !defined(TARGET_ARCH_ARM64) | |
| 1760 | |
| 1761 TEST_CASE(Service_Coverage) { | |
| 1762 const char* kScript = | |
| 1763 "var port;\n" // Set to our mock port by C++. | |
| 1764 "\n" | |
| 1765 "var x = 7;\n" | |
| 1766 "main() {\n" | |
| 1767 " x = x * x;\n" | |
| 1768 " x = x / 13;\n" | |
| 1769 "}"; | |
| 1770 | |
| 1771 Isolate* isolate = Isolate::Current(); | |
| 1772 Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL); | |
| 1773 EXPECT_VALID(lib); | |
| 1774 Library& vmlib = Library::Handle(); | |
| 1775 vmlib ^= Api::UnwrapHandle(lib); | |
| 1776 EXPECT(!vmlib.IsNull()); | |
| 1777 Dart_Handle result = Dart_Invoke(lib, NewString("main"), 0, NULL); | |
| 1778 EXPECT_VALID(result); | |
| 1779 | |
| 1780 // Build a mock message handler and wrap it in a dart port. | |
| 1781 ServiceTestMessageHandler handler; | |
| 1782 Dart_Port port_id = PortMap::CreatePort(&handler); | |
| 1783 Dart_Handle port = Api::NewHandle(isolate, SendPort::New(port_id)); | |
| 1784 EXPECT_VALID(port); | |
| 1785 EXPECT_VALID(Dart_SetField(lib, NewString("port"), port)); | |
| 1786 | |
| 1787 Array& service_msg = Array::Handle(); | |
| 1788 service_msg = Eval(lib, "[0, port, ['coverage'], [], []]"); | |
| 1789 Service::HandleIsolateMessage(isolate, service_msg); | |
| 1790 handler.HandleNextMessage(); | |
| 1791 | |
| 1792 char buf[1024]; | |
| 1793 OS::SNPrint(buf, sizeof(buf), | |
| 1794 "{\"source\":\"test-lib\",\"script\":{\"type\":\"@Script\"," | |
| 1795 "\"id\":\"libraries\\/%" Pd "\\/scripts\\/test-lib\"," | |
| 1796 "\"name\":\"test-lib\"," | |
| 1797 "\"kind\":\"script\"},\"hits\":" | |
| 1798 "[5,1,6,1]}", | |
| 1799 vmlib.index()); | |
| 1800 EXPECT_SUBSTRING(buf, handler.msg()); | |
| 1801 } | |
| 1802 | |
| 1803 | |
| 1804 TEST_CASE(Service_LibrariesScriptsCoverage) { | |
| 1805 const char* kScript = | |
| 1806 "var port;\n" // Set to our mock port by C++. | |
| 1807 "\n" | |
| 1808 "var x = 7;\n" | |
| 1809 "main() {\n" | |
| 1810 " x = x * x;\n" | |
| 1811 " x = x / 13;\n" | |
| 1812 "}"; | |
| 1813 | |
| 1814 Isolate* isolate = Isolate::Current(); | |
| 1815 Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL); | |
| 1816 EXPECT_VALID(lib); | |
| 1817 Library& vmlib = Library::Handle(); | |
| 1818 vmlib ^= Api::UnwrapHandle(lib); | |
| 1819 EXPECT(!vmlib.IsNull()); | |
| 1820 Dart_Handle result = Dart_Invoke(lib, NewString("main"), 0, NULL); | |
| 1821 EXPECT_VALID(result); | |
| 1822 | |
| 1823 // Build a mock message handler and wrap it in a dart port. | |
| 1824 ServiceTestMessageHandler handler; | |
| 1825 Dart_Port port_id = PortMap::CreatePort(&handler); | |
| 1826 Dart_Handle port = Api::NewHandle(isolate, SendPort::New(port_id)); | |
| 1827 EXPECT_VALID(port); | |
| 1828 EXPECT_VALID(Dart_SetField(lib, NewString("port"), port)); | |
| 1829 | |
| 1830 Array& service_msg = Array::Handle(); | |
| 1831 char buf[1024]; | |
| 1832 OS::SNPrint(buf, sizeof(buf), | |
| 1833 "[0, port, ['libraries', '%" Pd "', 'scripts', 'test-lib', 'coverage'], " | |
| 1834 "[], []]", | |
| 1835 vmlib.index()); | |
| 1836 | |
| 1837 service_msg = Eval(lib, buf); | |
| 1838 Service::HandleIsolateMessage(isolate, service_msg); | |
| 1839 handler.HandleNextMessage(); | |
| 1840 OS::SNPrint(buf, sizeof(buf), | |
| 1841 "{\"type\":\"CodeCoverage\",\"id\":\"coverage\",\"coverage\":[" | |
| 1842 "{\"source\":\"test-lib\",\"script\":{\"type\":\"@Script\"," | |
| 1843 "\"id\":\"libraries\\/%" Pd "\\/scripts\\/test-lib\"," | |
| 1844 "\"name\":\"test-lib\"," | |
| 1845 "\"kind\":\"script\"},\"hits\":[5,1,6,1]}]}", vmlib.index()); | |
| 1846 EXPECT_STREQ(buf, handler.msg()); | |
| 1847 } | |
| 1848 | |
| 1849 | |
| 1850 TEST_CASE(Service_LibrariesCoverage) { | |
| 1851 const char* kScript = | |
| 1852 "var port;\n" // Set to our mock port by C++. | |
| 1853 "\n" | |
| 1854 "var x = 7;\n" | |
| 1855 "main() {\n" | |
| 1856 " x = x * x;\n" | |
| 1857 " x = x / 13;\n" | |
| 1858 "}"; | |
| 1859 | |
| 1860 Isolate* isolate = Isolate::Current(); | |
| 1861 Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL); | |
| 1862 EXPECT_VALID(lib); | |
| 1863 Library& vmlib = Library::Handle(); | |
| 1864 vmlib ^= Api::UnwrapHandle(lib); | |
| 1865 EXPECT(!vmlib.IsNull()); | |
| 1866 Dart_Handle result = Dart_Invoke(lib, NewString("main"), 0, NULL); | |
| 1867 EXPECT_VALID(result); | |
| 1868 | |
| 1869 // Build a mock message handler and wrap it in a dart port. | |
| 1870 ServiceTestMessageHandler handler; | |
| 1871 Dart_Port port_id = PortMap::CreatePort(&handler); | |
| 1872 Dart_Handle port = Api::NewHandle(isolate, SendPort::New(port_id)); | |
| 1873 EXPECT_VALID(port); | |
| 1874 EXPECT_VALID(Dart_SetField(lib, NewString("port"), port)); | |
| 1875 | |
| 1876 char buf[1024]; | |
| 1877 OS::SNPrint(buf, sizeof(buf), | |
| 1878 "[0, port, ['libraries', '%" Pd "', 'coverage'], [], []]", | |
| 1879 vmlib.index()); | |
| 1880 | |
| 1881 Array& service_msg = Array::Handle(); | |
| 1882 service_msg = Eval(lib, buf); | |
| 1883 Service::HandleIsolateMessage(isolate, service_msg); | |
| 1884 handler.HandleNextMessage(); | |
| 1885 OS::SNPrint(buf, sizeof(buf), | |
| 1886 "{\"type\":\"CodeCoverage\",\"id\":\"coverage\",\"coverage\":[" | |
| 1887 "{\"source\":\"test-lib\",\"script\":{\"type\":\"@Script\"," | |
| 1888 "\"id\":\"libraries\\/%" Pd "\\/scripts\\/test-lib\"," | |
| 1889 "\"name\":\"test-lib\"," | |
| 1890 "\"kind\":\"script\"},\"hits\":[5,1,6,1]}]}", | |
| 1891 vmlib.index()); | |
| 1892 EXPECT_STREQ(buf, handler.msg()); | |
| 1893 } | |
| 1894 | |
| 1895 | |
| 1896 TEST_CASE(Service_ClassesCoverage) { | |
| 1897 const char* kScript = | |
| 1898 "var port;\n" // Set to our mock port by C++. | |
| 1899 "\n" | |
| 1900 "class Foo {\n" | |
| 1901 " var x;\n" | |
| 1902 " Foo(this.x);\n" | |
| 1903 " bar() {\n" | |
| 1904 " x = x * x;\n" | |
| 1905 " x = x / 13;\n" | |
| 1906 " }\n" | |
| 1907 "}\n" | |
| 1908 "main() {\n" | |
| 1909 " var foo = new Foo(7);\n" | |
| 1910 " foo.bar();\n" | |
| 1911 "}"; | |
| 1912 | |
| 1913 Isolate* isolate = Isolate::Current(); | |
| 1914 Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL); | |
| 1915 EXPECT_VALID(lib); | |
| 1916 Library& vmlib = Library::Handle(); | |
| 1917 vmlib ^= Api::UnwrapHandle(lib); | |
| 1918 EXPECT(!vmlib.IsNull()); | |
| 1919 Dart_Handle result = Dart_Invoke(lib, NewString("main"), 0, NULL); | |
| 1920 EXPECT_VALID(result); | |
| 1921 | |
| 1922 // Build a mock message handler and wrap it in a dart port. | |
| 1923 ServiceTestMessageHandler handler; | |
| 1924 Dart_Port port_id = PortMap::CreatePort(&handler); | |
| 1925 Dart_Handle port = Api::NewHandle(isolate, SendPort::New(port_id)); | |
| 1926 EXPECT_VALID(port); | |
| 1927 EXPECT_VALID(Dart_SetField(lib, NewString("port"), port)); | |
| 1928 | |
| 1929 // Look up the service id of Foo. | |
| 1930 const Class& cls = Class::Handle( | |
| 1931 vmlib.LookupClass(String::Handle(String::New("Foo")))); | |
| 1932 ASSERT(!cls.IsNull()); | |
| 1933 ClassTable* table = isolate->class_table(); | |
| 1934 intptr_t i; | |
| 1935 for (i = 1; i < table->NumCids(); i++) { | |
| 1936 if (table->HasValidClassAt(i) && table->At(i) == cls.raw()) { | |
| 1937 break; | |
| 1938 } | |
| 1939 } | |
| 1940 ASSERT(i != table->NumCids()); | |
| 1941 char buf[1024]; | |
| 1942 OS::SNPrint(buf, sizeof(buf), | |
| 1943 "[0, port, ['classes', '%" Pd "', 'coverage'], [], []]", i); | |
| 1944 | |
| 1945 Array& service_msg = Array::Handle(); | |
| 1946 service_msg = Eval(lib, buf); | |
| 1947 Service::HandleIsolateMessage(isolate, service_msg); | |
| 1948 handler.HandleNextMessage(); | |
| 1949 OS::SNPrint(buf, sizeof(buf), | |
| 1950 "{\"type\":\"CodeCoverage\",\"id\":\"coverage\",\"coverage\":[" | |
| 1951 "{\"source\":\"test-lib\",\"script\":{\"type\":\"@Script\"," | |
| 1952 "\"id\":\"libraries\\/%" Pd "\\/scripts\\/test-lib\"," | |
| 1953 "\"name\":\"test-lib\"," | |
| 1954 "\"kind\":\"script\"},\"hits\":[5,1,7,4,8,3]}]}", | |
| 1955 vmlib.index()); | |
| 1956 EXPECT_STREQ(buf, handler.msg()); | |
| 1957 } | |
| 1958 | |
| 1959 | |
| 1960 TEST_CASE(Service_ClassesFunctionsCoverage) { | |
| 1961 const char* kScript = | |
| 1962 "var port;\n" // Set to our mock port by C++. | |
| 1963 "\n" | |
| 1964 "class Foo {\n" | |
| 1965 " var x;\n" | |
| 1966 " Foo(this.x);\n" | |
| 1967 " bar() {\n" | |
| 1968 " x = x * x;\n" | |
| 1969 " x = x / 13;\n" | |
| 1970 " }\n" | |
| 1971 " badum(var a) => 4 + a;\n" | |
| 1972 "}\n" | |
| 1973 "main() {\n" | |
| 1974 " var foo = new Foo(7);\n" | |
| 1975 " foo.bar();\n" | |
| 1976 "}"; | |
| 1977 | |
| 1978 Isolate* isolate = Isolate::Current(); | |
| 1979 Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL); | |
| 1980 EXPECT_VALID(lib); | |
| 1981 Library& vmlib = Library::Handle(); | |
| 1982 vmlib ^= Api::UnwrapHandle(lib); | |
| 1983 EXPECT(!vmlib.IsNull()); | |
| 1984 Dart_Handle result = Dart_Invoke(lib, NewString("main"), 0, NULL); | |
| 1985 EXPECT_VALID(result); | |
| 1986 | |
| 1987 // Build a mock message handler and wrap it in a dart port. | |
| 1988 ServiceTestMessageHandler handler; | |
| 1989 Dart_Port port_id = PortMap::CreatePort(&handler); | |
| 1990 Dart_Handle port = Api::NewHandle(isolate, SendPort::New(port_id)); | |
| 1991 EXPECT_VALID(port); | |
| 1992 EXPECT_VALID(Dart_SetField(lib, NewString("port"), port)); | |
| 1993 | |
| 1994 // Look up the service id of Foo. | |
| 1995 const Class& cls = Class::Handle( | |
| 1996 vmlib.LookupClass(String::Handle(String::New("Foo")))); | |
| 1997 ASSERT(!cls.IsNull()); | |
| 1998 ClassTable* table = isolate->class_table(); | |
| 1999 intptr_t i; | |
| 2000 for (i = 1; i < table->NumCids(); i++) { | |
| 2001 if (table->HasValidClassAt(i) && table->At(i) == cls.raw()) { | |
| 2002 break; | |
| 2003 } | |
| 2004 } | |
| 2005 ASSERT(i != table->NumCids()); | |
| 2006 | |
| 2007 // Look up the service if of the function Foo.bar. | |
| 2008 const Function& func = Function::Handle( | |
| 2009 cls.LookupFunction(String::Handle(String::New("bar")))); | |
| 2010 ASSERT(!func.IsNull()); | |
| 2011 | |
| 2012 char buf[1024]; | |
| 2013 OS::SNPrint(buf, sizeof(buf), | |
| 2014 "[0, port, ['classes', '%" Pd "', 'functions'," | |
| 2015 "'bar', 'coverage'], [], []]", i); | |
| 2016 | |
| 2017 Array& service_msg = Array::Handle(); | |
| 2018 service_msg = Eval(lib, buf); | |
| 2019 Service::HandleIsolateMessage(isolate, service_msg); | |
| 2020 handler.HandleNextMessage(); | |
| 2021 OS::SNPrint(buf, sizeof(buf), | |
| 2022 "{\"type\":\"CodeCoverage\",\"id\":\"coverage\",\"coverage\":[" | |
| 2023 "{\"source\":\"test-lib\",\"script\":{\"type\":\"@Script\"," | |
| 2024 "\"id\":\"libraries\\/%" Pd "\\/scripts\\/test-lib\"," | |
| 2025 "\"name\":\"test-lib\"," | |
| 2026 "\"kind\":\"script\"},\"hits\":[7,4,8,3]}]}", vmlib.index()); | |
| 2027 EXPECT_STREQ(buf, handler.msg()); | |
| 2028 } | |
| 2029 | |
| 2030 #endif | |
| 2031 | |
| 2032 | |
| 2033 TEST_CASE(Service_AllocationProfile) { | 1386 TEST_CASE(Service_AllocationProfile) { |
| 2034 const char* kScript = | 1387 const char* kScript = |
| 2035 "var port;\n" // Set to our mock port by C++. | 1388 "var port;\n" // Set to our mock port by C++. |
| 2036 "\n" | 1389 "\n" |
| 2037 "var x = 7;\n" | 1390 "var x = 7;\n" |
| 2038 "main() {\n" | 1391 "main() {\n" |
| 2039 " x = x * x;\n" | 1392 " x = x * x;\n" |
| 2040 " x = x / 13;\n" | 1393 " x = x / 13;\n" |
| 2041 "}"; | 1394 "}"; |
| 2042 | 1395 |
| 2043 Isolate* isolate = Isolate::Current(); | 1396 Isolate* isolate = Isolate::Current(); |
| 2044 Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL); | 1397 Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL); |
| 2045 EXPECT_VALID(lib); | 1398 EXPECT_VALID(lib); |
| 2046 Dart_Handle result = Dart_Invoke(lib, NewString("main"), 0, NULL); | 1399 Dart_Handle result = Dart_Invoke(lib, NewString("main"), 0, NULL); |
| 2047 EXPECT_VALID(result); | 1400 EXPECT_VALID(result); |
| 2048 | 1401 |
| 2049 // Build a mock message handler and wrap it in a dart port. | 1402 // Build a mock message handler and wrap it in a dart port. |
| 2050 ServiceTestMessageHandler handler; | 1403 ServiceTestMessageHandler handler; |
| 2051 Dart_Port port_id = PortMap::CreatePort(&handler); | 1404 Dart_Port port_id = PortMap::CreatePort(&handler); |
| 2052 Dart_Handle port = Api::NewHandle(isolate, SendPort::New(port_id)); | 1405 Dart_Handle port = Api::NewHandle(isolate, SendPort::New(port_id)); |
| 2053 EXPECT_VALID(port); | 1406 EXPECT_VALID(port); |
| 2054 EXPECT_VALID(Dart_SetField(lib, NewString("port"), port)); | 1407 EXPECT_VALID(Dart_SetField(lib, NewString("port"), port)); |
| 2055 | 1408 |
| 2056 Array& service_msg = Array::Handle(); | 1409 Array& service_msg = Array::Handle(); |
| 2057 service_msg = Eval(lib, "[0, port, ['allocationprofile'], [], []]"); | 1410 service_msg = Eval(lib, "[0, port, 'getAllocationProfile', [], []]"); |
| 2058 Service::HandleIsolateMessage(isolate, service_msg); | 1411 Service::HandleIsolateMessage(isolate, service_msg); |
| 2059 handler.HandleNextMessage(); | 1412 handler.HandleNextMessage(); |
| 2060 EXPECT_SUBSTRING("\"type\":\"AllocationProfile\"", handler.msg()); | 1413 EXPECT_SUBSTRING("\"type\":\"AllocationProfile\"", handler.msg()); |
| 2061 | 1414 |
| 2062 // Too long. | |
| 2063 service_msg = Eval(lib, "[0, port, ['allocationprofile', 'foo'], [], []]"); | |
| 2064 Service::HandleIsolateMessage(isolate, service_msg); | |
| 2065 handler.HandleNextMessage(); | |
| 2066 EXPECT_SUBSTRING("\"type\":\"Error\"", handler.msg()); | |
| 2067 | |
| 2068 // Bad gc option. | 1415 // Bad gc option. |
| 2069 service_msg = Eval(lib, | 1416 service_msg = Eval(lib, |
| 2070 "[0, port, ['allocationprofile'], ['gc'], ['cat']]"); | 1417 "[0, port, 'getAllocationProfile', " |
| 1418 "['gc'], ['cat']]"); |
| 2071 Service::HandleIsolateMessage(isolate, service_msg); | 1419 Service::HandleIsolateMessage(isolate, service_msg); |
| 2072 handler.HandleNextMessage(); | 1420 handler.HandleNextMessage(); |
| 2073 EXPECT_SUBSTRING("\"type\":\"Error\"", handler.msg()); | 1421 EXPECT_SUBSTRING("\"type\":\"Error\"", handler.msg()); |
| 2074 | 1422 |
| 2075 // Bad reset option. | 1423 // Bad reset option. |
| 2076 service_msg = Eval(lib, | 1424 service_msg = Eval(lib, "[0, port, 'getAllocationProfile', " |
| 2077 "[0, port, ['allocationprofile'], ['reset'], ['ff']]"); | 1425 "['reset'], ['ff']]"); |
| 2078 Service::HandleIsolateMessage(isolate, service_msg); | 1426 Service::HandleIsolateMessage(isolate, service_msg); |
| 2079 handler.HandleNextMessage(); | 1427 handler.HandleNextMessage(); |
| 2080 EXPECT_SUBSTRING("\"type\":\"Error\"", handler.msg()); | 1428 EXPECT_SUBSTRING("\"type\":\"Error\"", handler.msg()); |
| 2081 | 1429 |
| 2082 // Good reset. | 1430 // Good reset. |
| 2083 service_msg = | 1431 service_msg = |
| 2084 Eval(lib, "[0, port, ['allocationprofile'], ['reset'], ['true']]"); | 1432 Eval(lib, |
| 1433 "[0, port, 'getAllocationProfile', ['reset'], ['true']]"); |
| 2085 Service::HandleIsolateMessage(isolate, service_msg); | 1434 Service::HandleIsolateMessage(isolate, service_msg); |
| 2086 handler.HandleNextMessage(); | 1435 handler.HandleNextMessage(); |
| 2087 EXPECT_SUBSTRING("\"type\":\"AllocationProfile\"", handler.msg()); | 1436 EXPECT_SUBSTRING("\"type\":\"AllocationProfile\"", handler.msg()); |
| 2088 | 1437 |
| 2089 // Good GC. | 1438 // Good GC. |
| 2090 service_msg = | 1439 service_msg = |
| 2091 Eval(lib, "[0, port, ['allocationprofile'], ['gc'], ['full']]"); | 1440 Eval(lib, "[0, port, 'getAllocationProfile', ['gc'], ['full']]"); |
| 2092 Service::HandleIsolateMessage(isolate, service_msg); | 1441 Service::HandleIsolateMessage(isolate, service_msg); |
| 2093 handler.HandleNextMessage(); | 1442 handler.HandleNextMessage(); |
| 2094 EXPECT_SUBSTRING("\"type\":\"AllocationProfile\"", handler.msg()); | 1443 EXPECT_SUBSTRING("\"type\":\"AllocationProfile\"", handler.msg()); |
| 2095 | 1444 |
| 2096 // Good GC and reset. | 1445 // Good GC and reset. |
| 2097 service_msg = Eval(lib, | 1446 service_msg = Eval(lib, "[0, port, 'getAllocationProfile', " |
| 2098 "[0, port, ['allocationprofile'], ['gc', 'reset'], ['full', 'true']]"); | 1447 "['gc', 'reset'], ['full', 'true']]"); |
| 2099 Service::HandleIsolateMessage(isolate, service_msg); | 1448 Service::HandleIsolateMessage(isolate, service_msg); |
| 2100 handler.HandleNextMessage(); | 1449 handler.HandleNextMessage(); |
| 2101 EXPECT_SUBSTRING("\"type\":\"AllocationProfile\"", handler.msg()); | 1450 EXPECT_SUBSTRING("\"type\":\"AllocationProfile\"", handler.msg()); |
| 2102 } | 1451 } |
| 2103 | 1452 |
| 2104 | 1453 |
| 2105 TEST_CASE(Service_HeapMap) { | 1454 TEST_CASE(Service_HeapMap) { |
| 2106 const char* kScript = | 1455 const char* kScript = |
| 2107 "var port;\n" // Set to our mock port by C++. | 1456 "var port;\n" // Set to our mock port by C++. |
| 2108 "\n" | 1457 "\n" |
| 2109 "main() {\n" | 1458 "main() {\n" |
| 2110 "}"; | 1459 "}"; |
| 2111 | 1460 |
| 2112 Isolate* isolate = Isolate::Current(); | 1461 Isolate* isolate = Isolate::Current(); |
| 2113 Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL); | 1462 Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL); |
| 2114 EXPECT_VALID(lib); | 1463 EXPECT_VALID(lib); |
| 2115 | 1464 |
| 2116 // Build a mock message handler and wrap it in a dart port. | 1465 // Build a mock message handler and wrap it in a dart port. |
| 2117 ServiceTestMessageHandler handler; | 1466 ServiceTestMessageHandler handler; |
| 2118 Dart_Port port_id = PortMap::CreatePort(&handler); | 1467 Dart_Port port_id = PortMap::CreatePort(&handler); |
| 2119 Dart_Handle port = Api::NewHandle(isolate, SendPort::New(port_id)); | 1468 Dart_Handle port = Api::NewHandle(isolate, SendPort::New(port_id)); |
| 2120 EXPECT_VALID(port); | 1469 EXPECT_VALID(port); |
| 2121 EXPECT_VALID(Dart_SetField(lib, NewString("port"), port)); | 1470 EXPECT_VALID(Dart_SetField(lib, NewString("port"), port)); |
| 2122 | 1471 |
| 2123 Array& service_msg = Array::Handle(); | 1472 Array& service_msg = Array::Handle(); |
| 2124 service_msg = Eval(lib, "[0, port, ['heapmap'], [], []]"); | 1473 service_msg = Eval(lib, "[0, port, 'getHeapMap', [], []]"); |
| 2125 Service::HandleIsolateMessage(isolate, service_msg); | 1474 Service::HandleIsolateMessage(isolate, service_msg); |
| 2126 handler.HandleNextMessage(); | 1475 handler.HandleNextMessage(); |
| 2127 EXPECT_SUBSTRING("\"type\":\"HeapMap\"", handler.msg()); | 1476 EXPECT_SUBSTRING("\"type\":\"HeapMap\"", handler.msg()); |
| 2128 EXPECT_SUBSTRING("\"pages\":[", handler.msg()); | 1477 EXPECT_SUBSTRING("\"pages\":[", handler.msg()); |
| 2129 } | 1478 } |
| 2130 | 1479 |
| 2131 | 1480 |
| 2132 TEST_CASE(Service_Address) { | 1481 TEST_CASE(Service_Address) { |
| 2133 const char* kScript = | 1482 const char* kScript = |
| 2134 "var port;\n" // Set to our mock port by C++. | 1483 "var port;\n" // Set to our mock port by C++. |
| (...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2299 EXPECT_VALID(result); | 1648 EXPECT_VALID(result); |
| 2300 | 1649 |
| 2301 // Build a mock message handler and wrap it in a dart port. | 1650 // Build a mock message handler and wrap it in a dart port. |
| 2302 ServiceTestMessageHandler handler; | 1651 ServiceTestMessageHandler handler; |
| 2303 Dart_Port port_id = PortMap::CreatePort(&handler); | 1652 Dart_Port port_id = PortMap::CreatePort(&handler); |
| 2304 Dart_Handle port = Api::NewHandle(isolate, SendPort::New(port_id)); | 1653 Dart_Handle port = Api::NewHandle(isolate, SendPort::New(port_id)); |
| 2305 EXPECT_VALID(port); | 1654 EXPECT_VALID(port); |
| 2306 EXPECT_VALID(Dart_SetField(lib, NewString("port"), port)); | 1655 EXPECT_VALID(Dart_SetField(lib, NewString("port"), port)); |
| 2307 | 1656 |
| 2308 Array& service_msg = Array::Handle(); | 1657 Array& service_msg = Array::Handle(); |
| 2309 service_msg = Eval(lib, "[0, port, ['profile'], [], []]"); | 1658 service_msg = Eval(lib, "[0, port, 'getCpuProfile', [], []]"); |
| 2310 Service::HandleIsolateMessage(isolate, service_msg); | 1659 Service::HandleIsolateMessage(isolate, service_msg); |
| 2311 handler.HandleNextMessage(); | 1660 handler.HandleNextMessage(); |
| 2312 // Expect profile | 1661 // Expect profile |
| 2313 EXPECT_SUBSTRING("\"type\":\"Profile\"", handler.msg()); | 1662 EXPECT_SUBSTRING("\"type\":\"CpuProfile\"", handler.msg()); |
| 2314 | 1663 |
| 2315 service_msg = Eval(lib, "[0, port, ['profile'], ['tags'], ['hide']]"); | 1664 service_msg = |
| 1665 Eval(lib, "[0, port, 'getCpuProfile', ['tags'], ['None']]"); |
| 2316 Service::HandleIsolateMessage(isolate, service_msg); | 1666 Service::HandleIsolateMessage(isolate, service_msg); |
| 2317 handler.HandleNextMessage(); | 1667 handler.HandleNextMessage(); |
| 2318 // Expect profile | 1668 // Expect profile |
| 2319 EXPECT_SUBSTRING("\"type\":\"Profile\"", handler.msg()); | 1669 EXPECT_SUBSTRING("\"type\":\"CpuProfile\"", handler.msg()); |
| 2320 | 1670 |
| 2321 service_msg = Eval(lib, "[0, port, ['profile'], ['tags'], ['hidden']]"); | 1671 service_msg = |
| 1672 Eval(lib, "[0, port, 'getCpuProfile', ['tags'], ['Bogus']]"); |
| 2322 Service::HandleIsolateMessage(isolate, service_msg); | 1673 Service::HandleIsolateMessage(isolate, service_msg); |
| 2323 handler.HandleNextMessage(); | 1674 handler.HandleNextMessage(); |
| 2324 // Expect error. | 1675 // Expect error. |
| 2325 EXPECT_SUBSTRING("\"type\":\"Error\"", handler.msg()); | 1676 EXPECT_SUBSTRING("\"type\":\"Error\"", handler.msg()); |
| 2326 } | 1677 } |
| 2327 | 1678 |
| 2328 #endif // !defined(TARGET_ARCH_ARM64) | 1679 #endif // !defined(TARGET_ARCH_ARM64) |
| 2329 | 1680 |
| 2330 } // namespace dart | 1681 } // namespace dart |
| OLD | NEW |