Index: mojo/tools/dart_test_runner.dart |
diff --git a/mojo/tools/dart_test_runner.dart b/mojo/tools/dart_test_runner.dart |
new file mode 100644 |
index 0000000000000000000000000000000000000000..679aefdea6af7b47f9d6afd9791312fc5ab963da |
--- /dev/null |
+++ b/mojo/tools/dart_test_runner.dart |
@@ -0,0 +1,130 @@ |
+// Copyright 2014 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+// This script accepts a relative path as a command line argument and |
+// looks for files ending in '_test.dart' under `pwd`/argument/path. Then, |
+// the script runs tests and reports back on the results. |
+// |
+// Example usage from root source directory: |
+// $ dart mojo/tools/dart_test_runner.dart out/Debug/gen |
+// |
+// The argument path is also set to the Dart package root. |
+ |
+import 'dart:async'; |
+import 'dart:convert'; |
+import 'dart:core'; |
+import 'dart:io'; |
+import 'dart:isolate'; |
+ |
+ |
+Future<List<String>> findTests(String path) { |
+ var dir = new Directory(path); |
+ var tests = []; |
+ var completer = new Completer(); |
+ dir.list(recursive: true) // Walk the directory tree. |
+ .asyncMap((fse) { // Stat the entries to filter out non-files. |
+ var completer = new Completer(); |
+ fse.stat().then((info) { |
+ completer.complete([fse, info]); |
+ }); |
+ return completer.future; |
+ }) |
+ .listen((lst) { |
+ var fse = lst[0]; |
+ var info = lst[1]; |
+ if ((info.type == FileSystemEntityType.FILE) && |
+ (fse.path.endsWith('_test.dart'))) { |
+ tests.add(fse.path); |
+ } |
+ }, onDone:() { |
+ completer.complete(tests); |
+ }); |
+ return completer.future; |
+} |
+ |
+ |
+void testRunnerIsolate(List args) { |
+ SendPort sp = args[0]; |
+ String package_root = args[1]; |
+ var rp = new ReceivePort(); |
+ var rsp = rp.sendPort; |
+ var running_tests = 0; |
+ sp.send(rsp); |
+ sp.send("request"); |
+ rp.listen((msg) { |
+ if (msg is String) { |
+ // A new test to run. |
+ String test = msg; |
+ List testargs = ['--checked', '-p', package_root, test]; |
+ Process.start(Platform.executable, testargs).then((process) { |
+ String stderr = ""; |
+ |
+ // Kill the test process after 10 seconds. |
+ var kill_timer = new Timer(const Duration(seconds:10), process.kill); |
+ |
+ // When the test finishes send back the results. |
+ process.exitCode.then((code) { |
+ kill_timer.cancel(); |
+ if (code == 0) { |
+ sp.send([test, "Success"]); |
+ } else { |
+ sp.send([test, stderr]); |
+ } |
+ |
+ // Room for another. |
+ running_tests--; |
+ if (running_tests < Platform.numberOfProcessors) { |
+ sp.send("request"); |
+ } |
+ }); |
+ |
+ // Collect the stderr if there is any. |
+ process.stderr.transform(UTF8.decoder).listen((data) { |
+ stderr = "$stderr$data"; |
+ }); |
+ }); |
+ running_tests++; |
+ if (running_tests < Platform.numberOfProcessors) { |
+ sp.send("request"); |
+ } |
+ } |
+ }); |
+} |
+ |
+ |
+void runTests(List<String> test_paths, String root) { |
+ var rp = new ReceivePort(); |
+ List isolate_args = [rp.sendPort, root]; |
+ Isolate.spawn(testRunnerIsolate, isolate_args).then((isolate) { |
+ SendPort sp; |
+ int test_idx = 0; |
+ int finished = 0; |
+ rp.listen((msg) { |
+ if (msg is SendPort) { |
+ sp = msg; |
+ } else if ((msg is String) && (msg == "request")) { |
+ if (test_idx < test_paths.length) { |
+ sp.send(test_paths[test_idx]); |
+ test_idx++; |
+ } |
+ } else if (msg is List) { |
+ finished++; |
+ print("${msg[0]}: ${msg[1]}"); |
+ if (finished == test_paths.length) { |
+ // We got the final result. |
+ rp.close(); // This should bring everything down. |
+ } |
+ } |
+ }); |
+ }); |
+} |
+ |
+ |
+int main(argv) { |
+ String root = (argv.isEmpty) ? "." : argv[0]; |
+ findTests(root).then((test_paths) { |
+ runTests(test_paths, root); |
+ }); |
+ return 0; |
+} |