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