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 |