| 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:unittest/unittest.dart'; |
| 11 import 'package:observatory/service_io.dart'; |
| 10 | 12 |
| 11 class TestLauncher { | 13 // This invocation should set up the state being tested. |
| 12 final String script; | 14 const String _TESTEE_MODE_FLAG = "--testee-mode"; |
| 15 |
| 16 class _TestLauncher { |
| 13 Process process; | 17 Process process; |
| 18 final List<String> args; |
| 14 | 19 |
| 15 TestLauncher(this.script); | 20 _TestLauncher() : args = ['--enable-vm-service:0', |
| 16 | 21 Platform.script.toFilePath(), |
| 17 String get scriptPath { | 22 _TESTEE_MODE_FLAG] {} |
| 18 var dartScript = Platform.script.toFilePath(); | |
| 19 var splitPoint = dartScript.lastIndexOf(Platform.pathSeparator); | |
| 20 var scriptDirectory = dartScript.substring(0, splitPoint); | |
| 21 return scriptDirectory + Platform.pathSeparator + script; | |
| 22 } | |
| 23 | 23 |
| 24 Future<int> launch() { | 24 Future<int> launch() { |
| 25 String dartExecutable = Platform.executable; | 25 String dartExecutable = Platform.executable; |
| 26 print('** Launching $scriptPath'); | 26 print('** Launching $args'); |
| 27 return Process.start(dartExecutable, | 27 return Process.start(dartExecutable, args).then((p) { |
| 28 ['--enable-vm-service:0', scriptPath]).then((p) { | |
| 29 | 28 |
| 30 Completer completer = new Completer(); | 29 Completer completer = new Completer(); |
| 31 process = p; | 30 process = p; |
| 32 var portNumber; | 31 var portNumber; |
| 33 var blank; | 32 var blank; |
| 34 var first = true; | 33 var first = true; |
| 35 process.stdout.transform(UTF8.decoder) | 34 process.stdout.transform(UTF8.decoder) |
| 36 .transform(new LineSplitter()).listen((line) { | 35 .transform(new LineSplitter()).listen((line) { |
| 37 if (line.startsWith('Observatory listening on http://')) { | 36 if (line.startsWith('Observatory listening on http://')) { |
| 38 RegExp portExp = new RegExp(r"\d+.\d+.\d+.\d+:(\d+)"); | 37 RegExp portExp = new RegExp(r"\d+.\d+.\d+.\d+:(\d+)"); |
| 39 var port = portExp.firstMatch(line).group(1); | 38 var port = portExp.firstMatch(line).group(1); |
| 40 portNumber = int.parse(port); | 39 portNumber = int.parse(port); |
| 41 } | 40 } |
| 42 if (line == '') { | 41 if (line == '') { |
| 43 // Received blank line. | 42 // Received blank line. |
| 44 blank = true; | 43 blank = true; |
| 45 } | 44 } |
| 46 if (portNumber != null && blank == true && first == true) { | 45 if (portNumber != null && blank == true && first == true) { |
| 47 completer.complete(portNumber); | 46 completer.complete(portNumber); |
| 48 // Stop repeat completions. | 47 // Stop repeat completions. |
| 49 first = false; | 48 first = false; |
| 50 print('** Signaled to run test queries on $portNumber'); | 49 print('** Signaled to run test queries on $portNumber'); |
| 51 } | 50 } |
| 52 print(line); | 51 print(line); |
| 53 }); | 52 }); |
| 54 process.stderr.transform(UTF8.decoder) | 53 process.stderr.transform(UTF8.decoder) |
| 55 .transform(new LineSplitter()).listen((line) { | 54 .transform(new LineSplitter()).listen((line) { |
| 56 print(line); | 55 print(line); |
| 57 }); | 56 }); |
| 58 process.exitCode.then((code) { | 57 process.exitCode.then((exitCode) { |
| 59 //Expect.equals(0, code, 'Launched dart executable exited with error.'); | 58 expect(exitCode, equals(0)); |
| 60 }); | 59 }); |
| 61 return completer.future; | 60 return completer.future; |
| 62 }); | 61 }); |
| 63 } | 62 } |
| 64 | 63 |
| 65 void requestExit() { | 64 void requestExit() { |
| 66 print('** Requesting script to exit.'); | 65 print('** Requesting script to exit.'); |
| 67 process.stdin.add([32, 13, 10]); | 66 process.stdin.add([32, 13, 10]); |
| 68 } | 67 } |
| 69 } | 68 } |
| 70 | 69 |
| 70 typedef Future IsolateTest(Isolate isolate); |
| 71 |
| 72 /// Runs [tests] in sequence, each of which should take an [Isolate] and |
| 73 /// return a [Future]. Code for setting up state can run before and/or |
| 74 /// concurrently with the tests. Uses [mainArgs] to determine whether |
| 75 /// to run tests or testee in this invokation of the script. |
| 76 void runIsolateTests(List<String> mainArgs, |
| 77 List<IsolateTest> tests, |
| 78 {void testeeBefore(), |
| 79 void testeeConcurrent()}) { |
| 80 if (mainArgs.contains(_TESTEE_MODE_FLAG)) { |
| 81 if (testeeBefore != null) { |
| 82 testeeBefore(); |
| 83 } |
| 84 print(''); // Print blank line to signal that we are ready. |
| 85 if (testeeConcurrent != null) { |
| 86 testeeConcurrent(); |
| 87 } |
| 88 // Wait until signaled from spawning test. |
| 89 stdin.first.then((_) => exit(0)); |
| 90 } else { |
| 91 var process = new _TestLauncher(); |
| 92 process.launch().then((port) { |
| 93 String addr = 'ws://localhost:$port/ws'; |
| 94 new WebSocketVM(new WebSocketVMTarget(addr)).get('vm') |
| 95 .then((VM vm) => vm.isolates.first.load()) |
| 96 .then((Isolate isolate) => |
| 97 Future.forEach(tests, (test) => test(isolate))) |
| 98 .then((_) => exit(0)); |
| 99 }); |
| 100 } |
| 101 } |
| OLD | NEW |