| 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'; | 10 import 'package:unittest/unittest.dart'; |
| 11 import 'package:observatory/service_io.dart'; | 11 import 'package:observatory/service_io.dart'; |
| 12 | 12 |
| 13 // This invocation should set up the state being tested. | 13 // This invocation should set up the state being tested. |
| 14 const String _TESTEE_MODE_FLAG = "--testee-mode"; | 14 const String _TESTEE_MODE_FLAG = "--testee-mode"; |
| 15 | 15 |
| 16 class _TestLauncher { | 16 class _TestLauncher { |
| 17 Process process; | 17 Process process; |
| 18 final List<String> args; | 18 final List<String> args; |
| 19 | 19 |
| 20 _TestLauncher() : args = ['--enable-vm-service:0', | 20 _TestLauncher() : args = ['--enable-vm-service:0', |
| 21 Platform.script.toFilePath(), | 21 Platform.script.toFilePath(), |
| 22 _TESTEE_MODE_FLAG] {} | 22 _TESTEE_MODE_FLAG] {} |
| 23 | 23 |
| 24 Future<int> launch() { | 24 Future<int> launch(bool pause_on_exit) { |
| 25 String dartExecutable = Platform.executable; | 25 String dartExecutable = Platform.executable; |
| 26 var fullArgs = []; | 26 var fullArgs = []; |
| 27 if (pause_on_exit == true) { |
| 28 fullArgs.add('--pause-isolates-on-exit'); |
| 29 } |
| 27 fullArgs.addAll(Platform.executableArguments); | 30 fullArgs.addAll(Platform.executableArguments); |
| 28 fullArgs.addAll(args); | 31 fullArgs.addAll(args); |
| 29 print('** Launching $fullArgs'); | 32 print('** Launching $dartExecutable ${fullArgs.join(' ')}'); |
| 30 return Process.start(dartExecutable, fullArgs).then((p) { | 33 return Process.start(dartExecutable, fullArgs).then((p) { |
| 31 | 34 |
| 32 Completer completer = new Completer(); | 35 Completer completer = new Completer(); |
| 33 process = p; | 36 process = p; |
| 34 var portNumber; | 37 var portNumber; |
| 35 var blank; | 38 var blank; |
| 36 var first = true; | 39 var first = true; |
| 37 process.stdout.transform(UTF8.decoder) | 40 process.stdout.transform(UTF8.decoder) |
| 38 .transform(new LineSplitter()).listen((line) { | 41 .transform(new LineSplitter()).listen((line) { |
| 39 if (line.startsWith('Observatory listening on http://')) { | 42 if (line.startsWith('Observatory listening on http://')) { |
| (...skipping 24 matching lines...) Expand all Loading... |
| 64 }); | 67 }); |
| 65 } | 68 } |
| 66 | 69 |
| 67 void requestExit() { | 70 void requestExit() { |
| 68 print('** Requesting script to exit.'); | 71 print('** Requesting script to exit.'); |
| 69 process.stdin.add([32, 13, 10]); | 72 process.stdin.add([32, 13, 10]); |
| 70 } | 73 } |
| 71 } | 74 } |
| 72 | 75 |
| 73 typedef Future IsolateTest(Isolate isolate); | 76 typedef Future IsolateTest(Isolate isolate); |
| 77 typedef Future VMTest(VM vm); |
| 74 | 78 |
| 75 /// Runs [tests] in sequence, each of which should take an [Isolate] and | 79 /// 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 | 80 /// return a [Future]. Code for setting up state can run before and/or |
| 77 /// concurrently with the tests. Uses [mainArgs] to determine whether | 81 /// concurrently with the tests. Uses [mainArgs] to determine whether |
| 78 /// to run tests or testee in this invokation of the script. | 82 /// to run tests or testee in this invokation of the script. |
| 79 void runIsolateTests(List<String> mainArgs, | 83 void runIsolateTests(List<String> mainArgs, |
| 80 List<IsolateTest> tests, | 84 List<IsolateTest> tests, |
| 81 {void testeeBefore(), | 85 {void testeeBefore(), |
| 82 void testeeConcurrent()}) { | 86 void testeeConcurrent(), |
| 87 bool pause_on_exit}) { |
| 83 if (mainArgs.contains(_TESTEE_MODE_FLAG)) { | 88 if (mainArgs.contains(_TESTEE_MODE_FLAG)) { |
| 84 if (testeeBefore != null) { | 89 if (testeeBefore != null) { |
| 85 testeeBefore(); | 90 testeeBefore(); |
| 86 } | 91 } |
| 87 print(''); // Print blank line to signal that we are ready. | 92 print(''); // Print blank line to signal that we are ready. |
| 88 if (testeeConcurrent != null) { | 93 if (testeeConcurrent != null) { |
| 89 testeeConcurrent(); | 94 testeeConcurrent(); |
| 90 } | 95 } |
| 91 // Wait until signaled from spawning test. | 96 // Wait until signaled from spawning test. |
| 92 stdin.first.then((_) => exit(0)); | 97 stdin.first.then((_) => exit(0)); |
| 93 } else { | 98 } else { |
| 94 var process = new _TestLauncher(); | 99 var process = new _TestLauncher(); |
| 95 process.launch().then((port) { | 100 process.launch(pause_on_exit).then((port) { |
| 96 String addr = 'ws://localhost:$port/ws'; | 101 String addr = 'ws://localhost:$port/ws'; |
| 102 var testIndex = 0; |
| 103 var totalTests = tests.length - 1; |
| 104 var name = Platform.script.pathSegments.last; |
| 97 new WebSocketVM(new WebSocketVMTarget(addr)).load() | 105 new WebSocketVM(new WebSocketVMTarget(addr)).load() |
| 98 .then((VM vm) => vm.isolates.first.load()) | 106 .then((VM vm) => vm.isolates.first.load()) |
| 99 .then((Isolate isolate) => | 107 .then((Isolate isolate) => Future.forEach(tests, (test) { |
| 100 Future.forEach(tests, (test) => test(isolate))) | 108 print('Running $name [$testIndex/$totalTests]'); |
| 101 .then((_) => exit(0)); | 109 testIndex++; |
| 110 return test(isolate); |
| 111 })).then((_) => exit(0)); |
| 102 }); | 112 }); |
| 103 } | 113 } |
| 104 } | 114 } |
| 115 |
| 116 |
| 117 // Cancel the subscription and complete the completer when finished processing |
| 118 // events. |
| 119 typedef void ServiceEventHandler(ServiceEvent event, |
| 120 StreamSubscription subscription, |
| 121 Completer completer); |
| 122 |
| 123 Future processServiceEvents(VM vm, ServiceEventHandler handler) { |
| 124 Completer completer = new Completer(); |
| 125 var subscription; |
| 126 subscription = vm.events.stream.listen((ServiceEvent event) { |
| 127 handler(event, subscription, completer); |
| 128 }); |
| 129 return completer.future; |
| 130 } |
| 131 |
| 132 |
| 133 /// Runs [tests] in sequence, each of which should take an [Isolate] and |
| 134 /// return a [Future]. Code for setting up state can run before and/or |
| 135 /// concurrently with the tests. Uses [mainArgs] to determine whether |
| 136 /// to run tests or testee in this invokation of the script. |
| 137 Future runVMTests(List<String> mainArgs, |
| 138 List<VMTest> tests, |
| 139 {Future testeeBefore(), |
| 140 Future testeeConcurrent(), |
| 141 bool pause_on_exit}) async { |
| 142 if (mainArgs.contains(_TESTEE_MODE_FLAG)) { |
| 143 if (testeeBefore != null) { |
| 144 await testeeBefore(); |
| 145 } |
| 146 print(''); // Print blank line to signal that we are ready. |
| 147 if (testeeConcurrent != null) { |
| 148 await testeeConcurrent(); |
| 149 } |
| 150 // Wait until signaled from spawning test. |
| 151 stdin.first.then((_) => exit(0)); |
| 152 } else { |
| 153 var process = new _TestLauncher(); |
| 154 process.launch(pause_on_exit).then((port) async { |
| 155 String addr = 'ws://localhost:$port/ws'; |
| 156 var testIndex = 0; |
| 157 var totalTests = tests.length - 1; |
| 158 var name = Platform.script.pathSegments.last; |
| 159 new WebSocketVM(new WebSocketVMTarget(addr)).load() |
| 160 .then((VM vm) => Future.forEach(tests, (test) { |
| 161 print('Running $name [$testIndex/$totalTests]'); |
| 162 testIndex++; |
| 163 return test(vm); |
| 164 })).then((_) => exit(0)); |
| 165 }); |
| 166 } |
| 167 } |
| OLD | NEW |