| 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 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_start, bool pause_on_exit) { | 29 Future<int> launch(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 } | |
| 35 if (pause_on_exit == true) { | 32 if (pause_on_exit == true) { |
| 36 fullArgs.add('--pause-isolates-on-exit'); | 33 fullArgs.add('--pause-isolates-on-exit'); |
| 37 } | 34 } |
| 38 fullArgs.addAll(Platform.executableArguments); | 35 fullArgs.addAll(Platform.executableArguments); |
| 39 fullArgs.addAll(args); | 36 fullArgs.addAll(args); |
| 40 print('** Launching $dartExecutable ${fullArgs.join(' ')}'); | 37 print('** Launching $dartExecutable ${fullArgs.join(' ')}'); |
| 41 return Process.start(dartExecutable, fullArgs).then((p) { | 38 return Process.start(dartExecutable, fullArgs).then((p) { |
| 42 | 39 |
| 43 Completer completer = new Completer(); | 40 Completer completer = new Completer(); |
| 44 process = p; | 41 process = p; |
| 45 var portNumber; | 42 var portNumber; |
| 46 var blank; | 43 var blank; |
| 47 var first = true; | 44 var first = true; |
| 48 process.stdout.transform(UTF8.decoder) | 45 process.stdout.transform(UTF8.decoder) |
| 49 .transform(new LineSplitter()).listen((line) { | 46 .transform(new LineSplitter()).listen((line) { |
| 50 if (line.startsWith('Observatory listening on http://')) { | 47 if (line.startsWith('Observatory listening on http://')) { |
| 51 RegExp portExp = new RegExp(r"\d+.\d+.\d+.\d+:(\d+)"); | 48 RegExp portExp = new RegExp(r"\d+.\d+.\d+.\d+:(\d+)"); |
| 52 var port = portExp.firstMatch(line).group(1); | 49 var port = portExp.firstMatch(line).group(1); |
| 53 portNumber = int.parse(port); | 50 portNumber = int.parse(port); |
| 54 } | 51 } |
| 55 if (pause_on_start || line == '') { | 52 if (line == '') { |
| 56 // Received blank line. | 53 // Received blank line. |
| 57 blank = true; | 54 blank = true; |
| 58 } | 55 } |
| 59 if (portNumber != null && blank == true && first == true) { | 56 if (portNumber != null && blank == true && first == true) { |
| 60 completer.complete(portNumber); | 57 completer.complete(portNumber); |
| 61 // Stop repeat completions. | 58 // Stop repeat completions. |
| 62 first = false; | 59 first = false; |
| 63 print('** Signaled to run test queries on $portNumber'); | 60 print('** Signaled to run test queries on $portNumber'); |
| 64 } | 61 } |
| 65 print(line); | 62 print(line); |
| (...skipping 28 matching lines...) Expand all Loading... |
| 94 String serviceHttpAddress; | 91 String serviceHttpAddress; |
| 95 | 92 |
| 96 /// Runs [tests] in sequence, each of which should take an [Isolate] and | 93 /// Runs [tests] in sequence, each of which should take an [Isolate] and |
| 97 /// return a [Future]. Code for setting up state can run before and/or | 94 /// return a [Future]. Code for setting up state can run before and/or |
| 98 /// concurrently with the tests. Uses [mainArgs] to determine whether | 95 /// concurrently with the tests. Uses [mainArgs] to determine whether |
| 99 /// to run tests or testee in this invokation of the script. | 96 /// to run tests or testee in this invokation of the script. |
| 100 void runIsolateTests(List<String> mainArgs, | 97 void runIsolateTests(List<String> mainArgs, |
| 101 List<IsolateTest> tests, | 98 List<IsolateTest> tests, |
| 102 {void testeeBefore(), | 99 {void testeeBefore(), |
| 103 void testeeConcurrent(), | 100 void testeeConcurrent(), |
| 104 bool pause_on_start, | |
| 105 bool pause_on_exit}) { | 101 bool pause_on_exit}) { |
| 106 assert(!pause_on_start || testeeBefore == null); | |
| 107 if (mainArgs.contains(_TESTEE_MODE_FLAG)) { | 102 if (mainArgs.contains(_TESTEE_MODE_FLAG)) { |
| 108 if (!pause_on_start) { | 103 if (testeeBefore != null) { |
| 109 if (testeeBefore != null) { | 104 testeeBefore(); |
| 110 testeeBefore(); | |
| 111 } | |
| 112 print(''); // Print blank line to signal that we are ready. | |
| 113 } | 105 } |
| 106 print(''); // Print blank line to signal that we are ready. |
| 114 if (testeeConcurrent != null) { | 107 if (testeeConcurrent != null) { |
| 115 testeeConcurrent(); | 108 testeeConcurrent(); |
| 116 } | 109 } |
| 117 // Wait around for the process to be killed. | 110 // Wait around for the process to be killed. |
| 118 stdin.first.then((_) => exit(0)); | 111 stdin.first.then((_) => exit(0)); |
| 119 } else { | 112 } else { |
| 120 var process = new _TestLauncher(); | 113 var process = new _TestLauncher(); |
| 121 process.launch(pause_on_start, pause_on_exit).then((port) { | 114 process.launch(pause_on_exit).then((port) { |
| 122 if (mainArgs.contains("--gdb")) { | 115 if (mainArgs.contains("--gdb")) { |
| 123 port = 8181; | 116 port = 8181; |
| 124 } | 117 } |
| 125 String addr = 'ws://localhost:$port/ws'; | 118 String addr = 'ws://localhost:$port/ws'; |
| 126 serviceHttpAddress = 'http://localhost:$port'; | 119 serviceHttpAddress = 'http://localhost:$port'; |
| 127 var testIndex = 1; | 120 var testIndex = 1; |
| 128 var totalTests = tests.length; | 121 var totalTests = tests.length; |
| 129 var name = Platform.script.pathSegments.last; | 122 var name = Platform.script.pathSegments.last; |
| 130 runZoned(() { | 123 runZoned(() { |
| 131 new WebSocketVM(new WebSocketVMTarget(addr)).load() | 124 new WebSocketVM(new WebSocketVMTarget(addr)).load() |
| (...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 286 | 279 |
| 287 | 280 |
| 288 /// Runs [tests] in sequence, each of which should take an [Isolate] and | 281 /// Runs [tests] in sequence, each of which should take an [Isolate] and |
| 289 /// return a [Future]. Code for setting up state can run before and/or | 282 /// return a [Future]. Code for setting up state can run before and/or |
| 290 /// concurrently with the tests. Uses [mainArgs] to determine whether | 283 /// concurrently with the tests. Uses [mainArgs] to determine whether |
| 291 /// to run tests or testee in this invokation of the script. | 284 /// to run tests or testee in this invokation of the script. |
| 292 Future runVMTests(List<String> mainArgs, | 285 Future runVMTests(List<String> mainArgs, |
| 293 List<VMTest> tests, | 286 List<VMTest> tests, |
| 294 {Future testeeBefore(), | 287 {Future testeeBefore(), |
| 295 Future testeeConcurrent(), | 288 Future testeeConcurrent(), |
| 296 bool pause_on_start, | |
| 297 bool pause_on_exit}) async { | 289 bool pause_on_exit}) async { |
| 298 if (mainArgs.contains(_TESTEE_MODE_FLAG)) { | 290 if (mainArgs.contains(_TESTEE_MODE_FLAG)) { |
| 299 if (testeeBefore != null) { | 291 if (testeeBefore != null) { |
| 300 await testeeBefore(); | 292 await testeeBefore(); |
| 301 } | 293 } |
| 302 print(''); // Print blank line to signal that we are ready. | 294 print(''); // Print blank line to signal that we are ready. |
| 303 if (testeeConcurrent != null) { | 295 if (testeeConcurrent != null) { |
| 304 await testeeConcurrent(); | 296 await testeeConcurrent(); |
| 305 } | 297 } |
| 306 // Wait around for the process to be killed. | 298 // Wait around for the process to be killed. |
| 307 stdin.first.then((_) => exit(0)); | 299 stdin.first.then((_) => exit(0)); |
| 308 } else { | 300 } else { |
| 309 var process = new _TestLauncher(); | 301 var process = new _TestLauncher(); |
| 310 process.launch(pause_on_start, pause_on_exit).then((port) async { | 302 process.launch(pause_on_exit).then((port) async { |
| 311 if (mainArgs.contains("--gdb")) { | 303 if (mainArgs.contains("--gdb")) { |
| 312 port = 8181; | 304 port = 8181; |
| 313 } | 305 } |
| 314 String addr = 'ws://localhost:$port/ws'; | 306 String addr = 'ws://localhost:$port/ws'; |
| 315 serviceHttpAddress = 'http://localhost:$port'; | 307 serviceHttpAddress = 'http://localhost:$port'; |
| 316 var testIndex = 1; | 308 var testIndex = 1; |
| 317 var totalTests = tests.length; | 309 var totalTests = tests.length; |
| 318 var name = Platform.script.pathSegments.last; | 310 var name = Platform.script.pathSegments.last; |
| 319 runZoned(() { | 311 runZoned(() { |
| 320 new WebSocketVM(new WebSocketVMTarget(addr)).load() | 312 new WebSocketVM(new WebSocketVMTarget(addr)).load() |
| 321 .then((VM vm) => Future.forEach(tests, (test) { | 313 .then((VM vm) => Future.forEach(tests, (test) { |
| 322 print('Running $name [$testIndex/$totalTests]'); | 314 print('Running $name [$testIndex/$totalTests]'); |
| 323 testIndex++; | 315 testIndex++; |
| 324 return test(vm); | 316 return test(vm); |
| 325 })).then((_) => process.requestExit()); | 317 })).then((_) => process.requestExit()); |
| 326 }, onError: (e, st) { | 318 }, onError: (e, st) { |
| 327 process.requestExit(); | 319 process.requestExit(); |
| 328 if (!_isWebSocketDisconnect(e)) { | 320 if (!_isWebSocketDisconnect(e)) { |
| 329 print('Unexpected exception in service tests: $e $st'); | 321 print('Unexpected exception in service tests: $e $st'); |
| 330 throw e; | 322 throw e; |
| 331 } | 323 } |
| 332 }); | 324 }); |
| 333 }); | 325 }); |
| 334 } | 326 } |
| 335 } | 327 } |
| OLD | NEW |