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

Side by Side Diff: runtime/observatory/tests/service/test_helper.dart

Issue 1285643004: Allow stepping when paused at isolate start. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 5 years, 4 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
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 library test_helper; 5 library test_helper;
6 6
7 import 'dart:async'; 7 import 'dart:async';
8 import 'dart:convert'; 8 import 'dart:convert';
9 import 'dart:io'; 9 import 'dart:io';
10 import 'package:observatory/service_io.dart'; 10 import 'package:observatory/service_io.dart';
11 import 'package:unittest/unittest.dart'; 11 import 'package:unittest/unittest.dart';
12 12
13 bool _isWebSocketDisconnect(e) { 13 bool _isWebSocketDisconnect(e) {
14 return e is NetworkRpcException; 14 return e is NetworkRpcException;
15 } 15 }
16 16
17 // This invocation should set up the state being tested. 17 // This invocation should set up the state being tested.
18 const String _TESTEE_MODE_FLAG = "--testee-mode"; 18 const String _TESTEE_MODE_FLAG = "--testee-mode";
19 19
20 class _TestLauncher { 20 class _TestLauncher {
21 Process process; 21 Process process;
22 final List<String> args; 22 final List<String> args;
23 bool killedByTester = false; 23 bool killedByTester = false;
24 24
25 _TestLauncher() : args = ['--enable-vm-service:0', 25 _TestLauncher() : args = ['--enable-vm-service:0',
26 Platform.script.toFilePath(), 26 Platform.script.toFilePath(),
27 _TESTEE_MODE_FLAG] {} 27 _TESTEE_MODE_FLAG] {}
28 28
29 Future<int> launch(bool pause_on_exit) { 29 Future<int> launch(bool pause_on_start, bool pause_on_exit) {
30 String dartExecutable = Platform.executable; 30 String dartExecutable = Platform.executable;
31 var fullArgs = []; 31 var fullArgs = [];
32 if (pause_on_start == true) {
33 fullArgs.add('--pause-isolates-on-start');
34 }
32 if (pause_on_exit == true) { 35 if (pause_on_exit == true) {
33 fullArgs.add('--pause-isolates-on-exit'); 36 fullArgs.add('--pause-isolates-on-exit');
34 } 37 }
35 fullArgs.addAll(Platform.executableArguments); 38 fullArgs.addAll(Platform.executableArguments);
36 fullArgs.addAll(args); 39 fullArgs.addAll(args);
37 print('** Launching $dartExecutable ${fullArgs.join(' ')}'); 40 print('** Launching $dartExecutable ${fullArgs.join(' ')}');
38 return Process.start(dartExecutable, fullArgs).then((p) { 41 return Process.start(dartExecutable, fullArgs).then((p) {
39 42
40 Completer completer = new Completer(); 43 Completer completer = new Completer();
41 process = p; 44 process = p;
42 var portNumber; 45 var portNumber;
43 var blank; 46 var blank;
44 var first = true; 47 var first = true;
45 process.stdout.transform(UTF8.decoder) 48 process.stdout.transform(UTF8.decoder)
46 .transform(new LineSplitter()).listen((line) { 49 .transform(new LineSplitter()).listen((line) {
47 if (line.startsWith('Observatory listening on http://')) { 50 if (line.startsWith('Observatory listening on http://')) {
48 RegExp portExp = new RegExp(r"\d+.\d+.\d+.\d+:(\d+)"); 51 RegExp portExp = new RegExp(r"\d+.\d+.\d+.\d+:(\d+)");
49 var port = portExp.firstMatch(line).group(1); 52 var port = portExp.firstMatch(line).group(1);
50 portNumber = int.parse(port); 53 portNumber = int.parse(port);
51 } 54 }
52 if (line == '') { 55 if (pause_on_start || line == '') {
53 // Received blank line. 56 // Received blank line.
54 blank = true; 57 blank = true;
55 } 58 }
56 if (portNumber != null && blank == true && first == true) { 59 if (portNumber != null && blank == true && first == true) {
57 completer.complete(portNumber); 60 completer.complete(portNumber);
58 // Stop repeat completions. 61 // Stop repeat completions.
59 first = false; 62 first = false;
60 print('** Signaled to run test queries on $portNumber'); 63 print('** Signaled to run test queries on $portNumber');
61 } 64 }
62 print(line); 65 print(line);
(...skipping 28 matching lines...) Expand all
91 String serviceHttpAddress; 94 String serviceHttpAddress;
92 95
93 /// Runs [tests] in sequence, each of which should take an [Isolate] and 96 /// Runs [tests] in sequence, each of which should take an [Isolate] and
94 /// return a [Future]. Code for setting up state can run before and/or 97 /// return a [Future]. Code for setting up state can run before and/or
95 /// concurrently with the tests. Uses [mainArgs] to determine whether 98 /// concurrently with the tests. Uses [mainArgs] to determine whether
96 /// to run tests or testee in this invokation of the script. 99 /// to run tests or testee in this invokation of the script.
97 void runIsolateTests(List<String> mainArgs, 100 void runIsolateTests(List<String> mainArgs,
98 List<IsolateTest> tests, 101 List<IsolateTest> tests,
99 {void testeeBefore(), 102 {void testeeBefore(),
100 void testeeConcurrent(), 103 void testeeConcurrent(),
101 bool pause_on_exit}) { 104 bool pause_on_start: false,
105 bool pause_on_exit: false}) {
106 assert(!pause_on_start || testeeBefore == null);
102 if (mainArgs.contains(_TESTEE_MODE_FLAG)) { 107 if (mainArgs.contains(_TESTEE_MODE_FLAG)) {
103 if (testeeBefore != null) { 108 if (!pause_on_start) {
104 testeeBefore(); 109 if (testeeBefore != null) {
110 testeeBefore();
111 }
112 print(''); // Print blank line to signal that we are ready.
105 } 113 }
106 print(''); // Print blank line to signal that we are ready.
107 if (testeeConcurrent != null) { 114 if (testeeConcurrent != null) {
108 testeeConcurrent(); 115 testeeConcurrent();
109 } 116 }
110 // Wait around for the process to be killed. 117 if (!pause_on_exit) {
111 stdin.first.then((_) => exit(0)); 118 // Wait around for the process to be killed.
119 stdin.first.then((_) => exit(0));
120 }
112 } else { 121 } else {
113 var process = new _TestLauncher(); 122 var process = new _TestLauncher();
114 process.launch(pause_on_exit).then((port) { 123 process.launch(pause_on_start, pause_on_exit).then((port) {
115 if (mainArgs.contains("--gdb")) { 124 if (mainArgs.contains("--gdb")) {
116 port = 8181; 125 port = 8181;
117 } 126 }
118 String addr = 'ws://localhost:$port/ws'; 127 String addr = 'ws://localhost:$port/ws';
119 serviceHttpAddress = 'http://localhost:$port'; 128 serviceHttpAddress = 'http://localhost:$port';
120 var testIndex = 1; 129 var testIndex = 1;
121 var totalTests = tests.length; 130 var totalTests = tests.length;
122 var name = Platform.script.pathSegments.last; 131 var name = Platform.script.pathSegments.last;
123 runZoned(() { 132 runZoned(() {
124 new WebSocketVM(new WebSocketVMTarget(addr)).load() 133 new WebSocketVM(new WebSocketVMTarget(addr)).load()
125 .then((VM vm) => vm.isolates.first.load()) 134 .then((VM vm) => vm.isolates.first.load())
126 .then((Isolate isolate) => Future.forEach(tests, (test) { 135 .then((Isolate isolate) => Future.forEach(tests, (test) {
127 print('Running $name [$testIndex/$totalTests]'); 136 print('Running $name [$testIndex/$totalTests]');
128 testIndex++; 137 testIndex++;
129 return test(isolate); 138 return test(isolate);
130 })).then((_) => process.requestExit()); 139 })).then((_) => process.requestExit());
131 }, onError: (e, st) { 140 }, onError: (e, st) {
132 process.requestExit(); 141 process.requestExit();
133 if (!_isWebSocketDisconnect(e)) { 142 if (!_isWebSocketDisconnect(e)) {
134 print('Unexpected exception in service tests: $e $st'); 143 print('Unexpected exception in service tests: $e $st');
135 throw e; 144 throw e;
136 } 145 }
137 }); 146 });
138 }); 147 });
139 } 148 }
140 } 149 }
141 150
142 151
143 // Cancel the subscription and complete the completer when finished processing
144 // events.
145 typedef void ServiceEventHandler(ServiceEvent event,
146 StreamSubscription subscription,
147 Completer completer);
148
149 Future processServiceEvents(VM vm,
150 String streamId,
151 ServiceEventHandler handler) {
152 Completer completer = new Completer();
153 vm.getEventStream(streamId).then((stream) {
154 var subscription;
155 subscription = stream.listen((ServiceEvent event) {
156 handler(event, subscription, completer);
157 });
158 });
159 return completer.future;
160 }
161
162
163 Future<Isolate> hasStoppedAtBreakpoint(Isolate isolate) { 152 Future<Isolate> hasStoppedAtBreakpoint(Isolate isolate) {
164 // Set up a listener to wait for breakpoint events. 153 // Set up a listener to wait for breakpoint events.
165 Completer completer = new Completer(); 154 Completer completer = new Completer();
166 isolate.vm.getEventStream(VM.kDebugStream).then((stream) { 155 isolate.vm.getEventStream(VM.kDebugStream).then((stream) {
167 var subscription; 156 var subscription;
168 subscription = stream.listen((ServiceEvent event) { 157 subscription = stream.listen((ServiceEvent event) {
169 print("Event: $event"); 158 print("Event: $event");
170 if (event.kind == ServiceEvent.kPauseBreakpoint) { 159 if (event.kind == ServiceEvent.kPauseBreakpoint) {
171 print('Breakpoint reached'); 160 print('Breakpoint reached');
172 subscription.cancel(); 161 subscription.cancel();
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
279 268
280 269
281 /// Runs [tests] in sequence, each of which should take an [Isolate] and 270 /// Runs [tests] in sequence, each of which should take an [Isolate] and
282 /// return a [Future]. Code for setting up state can run before and/or 271 /// return a [Future]. Code for setting up state can run before and/or
283 /// concurrently with the tests. Uses [mainArgs] to determine whether 272 /// concurrently with the tests. Uses [mainArgs] to determine whether
284 /// to run tests or testee in this invokation of the script. 273 /// to run tests or testee in this invokation of the script.
285 Future runVMTests(List<String> mainArgs, 274 Future runVMTests(List<String> mainArgs,
286 List<VMTest> tests, 275 List<VMTest> tests,
287 {Future testeeBefore(), 276 {Future testeeBefore(),
288 Future testeeConcurrent(), 277 Future testeeConcurrent(),
289 bool pause_on_exit}) async { 278 bool pause_on_start: false,
279 bool pause_on_exit: false}) async {
290 if (mainArgs.contains(_TESTEE_MODE_FLAG)) { 280 if (mainArgs.contains(_TESTEE_MODE_FLAG)) {
291 if (testeeBefore != null) { 281 if (!pause_on_start) {
292 await testeeBefore(); 282 if (testeeBefore != null) {
283 await testeeBefore();
284 }
285 print(''); // Print blank line to signal that we are ready.
293 } 286 }
294 print(''); // Print blank line to signal that we are ready.
295 if (testeeConcurrent != null) { 287 if (testeeConcurrent != null) {
296 await testeeConcurrent(); 288 await testeeConcurrent();
297 } 289 }
298 // Wait around for the process to be killed. 290 if (!pause_on_exit) {
299 stdin.first.then((_) => exit(0)); 291 // Wait around for the process to be killed.
292 stdin.first.then((_) => exit(0));
293 }
300 } else { 294 } else {
301 var process = new _TestLauncher(); 295 var process = new _TestLauncher();
302 process.launch(pause_on_exit).then((port) async { 296 process.launch(pause_on_start, pause_on_exit).then((port) async {
303 if (mainArgs.contains("--gdb")) { 297 if (mainArgs.contains("--gdb")) {
304 port = 8181; 298 port = 8181;
305 } 299 }
306 String addr = 'ws://localhost:$port/ws'; 300 String addr = 'ws://localhost:$port/ws';
307 serviceHttpAddress = 'http://localhost:$port'; 301 serviceHttpAddress = 'http://localhost:$port';
308 var testIndex = 1; 302 var testIndex = 1;
309 var totalTests = tests.length; 303 var totalTests = tests.length;
310 var name = Platform.script.pathSegments.last; 304 var name = Platform.script.pathSegments.last;
311 runZoned(() { 305 runZoned(() {
312 new WebSocketVM(new WebSocketVMTarget(addr)).load() 306 new WebSocketVM(new WebSocketVMTarget(addr)).load()
313 .then((VM vm) => Future.forEach(tests, (test) { 307 .then((VM vm) => Future.forEach(tests, (test) {
314 print('Running $name [$testIndex/$totalTests]'); 308 print('Running $name [$testIndex/$totalTests]');
315 testIndex++; 309 testIndex++;
316 return test(vm); 310 return test(vm);
317 })).then((_) => process.requestExit()); 311 })).then((_) => process.requestExit());
318 }, onError: (e, st) { 312 }, onError: (e, st) {
319 process.requestExit(); 313 process.requestExit();
320 if (!_isWebSocketDisconnect(e)) { 314 if (!_isWebSocketDisconnect(e)) {
321 print('Unexpected exception in service tests: $e $st'); 315 print('Unexpected exception in service tests: $e $st');
322 throw e; 316 throw e;
323 } 317 }
324 }); 318 });
325 }); 319 });
326 } 320 }
327 } 321 }
OLDNEW
« no previous file with comments | « runtime/observatory/tests/service/pause_on_start_then_step_test.dart ('k') | runtime/vm/debugger.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698