OLD | NEW |
(Empty) | |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 // This script accepts a relative path as a command line argument and |
| 6 // looks for files ending in '_test.dart' under `pwd`/argument/path. Then, |
| 7 // the script runs tests and reports back on the results. |
| 8 // |
| 9 // Example usage from root source directory: |
| 10 // $ dart mojo/tools/dart_test_runner.dart out/Debug/gen |
| 11 // |
| 12 // The argument path is also set to the Dart package root. |
| 13 |
| 14 import 'dart:async'; |
| 15 import 'dart:convert'; |
| 16 import 'dart:core'; |
| 17 import 'dart:io'; |
| 18 import 'dart:isolate'; |
| 19 |
| 20 |
| 21 Future<List<String>> findTests(String path) { |
| 22 var dir = new Directory(path); |
| 23 var tests = []; |
| 24 var completer = new Completer(); |
| 25 dir.list(recursive: true) // Walk the directory tree. |
| 26 .asyncMap((fse) { // Stat the entries to filter out non-files. |
| 27 var completer = new Completer(); |
| 28 fse.stat().then((info) { |
| 29 completer.complete([fse, info]); |
| 30 }); |
| 31 return completer.future; |
| 32 }) |
| 33 .listen((lst) { |
| 34 var fse = lst[0]; |
| 35 var info = lst[1]; |
| 36 if ((info.type == FileSystemEntityType.FILE) && |
| 37 (fse.path.endsWith('_test.dart'))) { |
| 38 tests.add(fse.path); |
| 39 } |
| 40 }, onDone:() { |
| 41 completer.complete(tests); |
| 42 }); |
| 43 return completer.future; |
| 44 } |
| 45 |
| 46 |
| 47 void testRunnerIsolate(List args) { |
| 48 SendPort sp = args[0]; |
| 49 String package_root = args[1]; |
| 50 var rp = new ReceivePort(); |
| 51 var rsp = rp.sendPort; |
| 52 var running_tests = 0; |
| 53 sp.send(rsp); |
| 54 sp.send("request"); |
| 55 rp.listen((msg) { |
| 56 if (msg is String) { |
| 57 // A new test to run. |
| 58 String test = msg; |
| 59 List testargs = ['--checked', '-p', package_root, test]; |
| 60 Process.start(Platform.executable, testargs).then((process) { |
| 61 String stderr = ""; |
| 62 |
| 63 // Kill the test process after 10 seconds. |
| 64 var kill_timer = new Timer(const Duration(seconds:10), process.kill); |
| 65 |
| 66 // When the test finishes send back the results. |
| 67 process.exitCode.then((code) { |
| 68 kill_timer.cancel(); |
| 69 if (code == 0) { |
| 70 sp.send([test, "Success"]); |
| 71 } else { |
| 72 sp.send([test, stderr]); |
| 73 } |
| 74 |
| 75 // Room for another. |
| 76 running_tests--; |
| 77 if (running_tests < Platform.numberOfProcessors) { |
| 78 sp.send("request"); |
| 79 } |
| 80 }); |
| 81 |
| 82 // Collect the stderr if there is any. |
| 83 process.stderr.transform(UTF8.decoder).listen((data) { |
| 84 stderr = "$stderr$data"; |
| 85 }); |
| 86 }); |
| 87 running_tests++; |
| 88 if (running_tests < Platform.numberOfProcessors) { |
| 89 sp.send("request"); |
| 90 } |
| 91 } |
| 92 }); |
| 93 } |
| 94 |
| 95 |
| 96 void runTests(List<String> test_paths, String root) { |
| 97 var rp = new ReceivePort(); |
| 98 List isolate_args = [rp.sendPort, root]; |
| 99 Isolate.spawn(testRunnerIsolate, isolate_args).then((isolate) { |
| 100 SendPort sp; |
| 101 int test_idx = 0; |
| 102 int finished = 0; |
| 103 rp.listen((msg) { |
| 104 if (msg is SendPort) { |
| 105 sp = msg; |
| 106 } else if ((msg is String) && (msg == "request")) { |
| 107 if (test_idx < test_paths.length) { |
| 108 sp.send(test_paths[test_idx]); |
| 109 test_idx++; |
| 110 } |
| 111 } else if (msg is List) { |
| 112 finished++; |
| 113 print("${msg[0]}: ${msg[1]}"); |
| 114 if (finished == test_paths.length) { |
| 115 // We got the final result. |
| 116 rp.close(); // This should bring everything down. |
| 117 } |
| 118 } |
| 119 }); |
| 120 }); |
| 121 } |
| 122 |
| 123 |
| 124 int main(argv) { |
| 125 String root = (argv.isEmpty) ? "." : argv[0]; |
| 126 findTests(root).then((test_paths) { |
| 127 runTests(test_paths, root); |
| 128 }); |
| 129 return 0; |
| 130 } |
OLD | NEW |