| OLD | NEW | 
|---|
| (Empty) |  | 
|  | 1 // Copyright (c) 2017, 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 /// Runs the tests in a batch on the various configurations used on the bots. | 
|  | 6 | 
|  | 7 import 'dart:async'; | 
|  | 8 import 'dart:io'; | 
|  | 9 | 
|  | 10 import 'package:args/args.dart'; | 
|  | 11 import 'package:path/path.dart' as p; | 
|  | 12 | 
|  | 13 import 'package:migration/src/fork.dart'; | 
|  | 14 import 'package:migration/src/log.dart'; | 
|  | 15 | 
|  | 16 const appJit = "--compiler=app_jit"; | 
|  | 17 const dart2js = "--compiler=dart2js"; | 
|  | 18 const dartdevc = "--compiler=dartdevc"; | 
|  | 19 const noCompiler = "--compiler=none"; | 
|  | 20 const precompiler = "--compiler=precompiler"; | 
|  | 21 const analyzer = "--compiler=dart2analyzer"; | 
|  | 22 | 
|  | 23 const chrome = "--runtime=chrome"; | 
|  | 24 const precompiled = "--runtime=dart_precompiled"; | 
|  | 25 const noRuntime = "--runtime=none"; | 
|  | 26 const vm = "--runtime=vm"; | 
|  | 27 | 
|  | 28 const checked = "--checked"; | 
|  | 29 const dart2jsBatch = "--dart2js-batch"; | 
|  | 30 const useSdk = "--use-sdk"; | 
|  | 31 const productMode = "--mode=product"; | 
|  | 32 const strong = "--strong"; | 
|  | 33 | 
|  | 34 /// Maps configuration names to a corresponding set of test.dart command line | 
|  | 35 /// arguments. | 
|  | 36 /// | 
|  | 37 /// Each configuration name starts with the name of a column on the buildbot | 
|  | 38 /// waterfall (except for "dartjs-linux" which is just called "dart2js" here) | 
|  | 39 /// possibly followed by some modifier for a specific bot or annotated step on | 
|  | 40 /// a bot. The configs here are ordered the same order as the waterfall. | 
|  | 41 final allConfigs = { | 
|  | 42   "vm": [noCompiler, vm], | 
|  | 43   "vm-checked": [noCompiler, vm, checked], | 
|  | 44   "vm-app": [appJit, vm], | 
|  | 45   "vm-app-product": [productMode, appJit, vm], | 
|  | 46   // TODO(rnystrom): What build target do we need to get this to work? | 
|  | 47 //  "vm-precomp": [precompiler, precompiled], | 
|  | 48   "vm-product": [productMode, noCompiler, vm], | 
|  | 49   // TODO(rnystrom): Add dart2js-d8-hostchecked, dart2js-d8-minified, or | 
|  | 50   // dart2js-jsshell? | 
|  | 51   "analyzer": [analyzer, noRuntime, useSdk], | 
|  | 52   "analyzer-checked": [analyzer, noRuntime, checked, useSdk], | 
|  | 53   "dart2js": [dart2js, chrome, useSdk, dart2jsBatch], | 
|  | 54   // TODO(rnystrom): Is it worth running dart2js on Firefox too? | 
|  | 55   "dartdevc": [dartdevc, chrome, useSdk, strong] | 
|  | 56 }; | 
|  | 57 | 
|  | 58 final buildSteps = [ | 
|  | 59   // The SDK, which also builds the VM. | 
|  | 60   ["--mode=release", "create_sdk"], | 
|  | 61   // Product version of the runtime and precompiled runtime. | 
|  | 62   ["--mode=product", "runtime", "runtime_precompiled"], | 
|  | 63   // Dartdevc and its dependencies. | 
|  | 64   ["--mode=release", "dartdevc_test"], | 
|  | 65 ]; | 
|  | 66 | 
|  | 67 Future<Null> main(List<String> arguments) async { | 
|  | 68   var argParser = new ArgParser(allowTrailingOptions: true); | 
|  | 69   argParser.addFlag("build", help: "Build runtimes before running tests."); | 
|  | 70   argParser.addOption("config", | 
|  | 71       abbr: "c", allowMultiple: true, help: "Which configurations to run."); | 
|  | 72   argParser.addFlag("help"); | 
|  | 73 | 
|  | 74   var argResults = argParser.parse(arguments); | 
|  | 75   if (argResults["help"] as bool) { | 
|  | 76     usage(argParser); | 
|  | 77     return; | 
|  | 78   } | 
|  | 79 | 
|  | 80   if (argResults.rest.length != 2) { | 
|  | 81     usage(argParser); | 
|  | 82     exit(1); | 
|  | 83   } | 
|  | 84 | 
|  | 85   var build = argResults["build"] as bool; | 
|  | 86   var configs = argResults["config"] as List<String>; | 
|  | 87   if (configs.isEmpty) configs = allConfigs.keys.toList(); | 
|  | 88 | 
|  | 89   var tests = scanTests(); | 
|  | 90 | 
|  | 91   var startIndex = findFork(tests, argResults.rest[0]); | 
|  | 92   var endIndex = findFork(tests, argResults.rest[1]); | 
|  | 93 | 
|  | 94   if (startIndex == null || endIndex == null) exit(1); | 
|  | 95 | 
|  | 96   tests = tests.sublist(startIndex, endIndex + 1); | 
|  | 97 | 
|  | 98   if (tests.isEmpty) { | 
|  | 99     print("No tests in range."); | 
|  | 100     return; | 
|  | 101   } | 
|  | 102 | 
|  | 103   // Build any needed targets first. | 
|  | 104   if (build) { | 
|  | 105     for (var steps in buildSteps) { | 
|  | 106       var command = "tools/build.py ${steps.join(' ')}"; | 
|  | 107       print("Building ${bold(command)}:"); | 
|  | 108       var exitCode = await run("tools/build.py", steps); | 
|  | 109       if (exitCode != 0) { | 
|  | 110         print(red("Build failed: $command")); | 
|  | 111       } | 
|  | 112     } | 
|  | 113   } | 
|  | 114 | 
|  | 115   // Splits the tests into selectors and patterns. | 
|  | 116   var selectors = <String, List<String>>{}; | 
|  | 117   for (var test in tests) { | 
|  | 118     var parts = p.split(p.withoutExtension(test.twoPath)); | 
|  | 119     var selector = parts[0]; | 
|  | 120     var path = parts.skip(1).join("/"); | 
|  | 121     selectors.putIfAbsent(selector, () => []).add(path); | 
|  | 122   } | 
|  | 123 | 
|  | 124   var failed = <String>[]; | 
|  | 125   var passed = <String>[]; | 
|  | 126   for (var name in configs) { | 
|  | 127     var configArgs = allConfigs[name]; | 
|  | 128     print("${bold(name)} ${configArgs.join(' ')}:"); | 
|  | 129 | 
|  | 130     var args = [ | 
|  | 131       "--progress=color", | 
|  | 132     ]; | 
|  | 133 | 
|  | 134     args.addAll(configArgs); | 
|  | 135 | 
|  | 136     if (!args.any((arg) => arg.startsWith("--mode"))) { | 
|  | 137       args.add("--mode=release"); | 
|  | 138     } | 
|  | 139 | 
|  | 140     selectors.forEach((selector, paths) { | 
|  | 141       args.add("$selector/${paths.join('|')}"); | 
|  | 142     }); | 
|  | 143 | 
|  | 144     var exitCode = await run("tools/test.py", args); | 
|  | 145     if (exitCode != 0) { | 
|  | 146       print(red("Configuration failed: $name")); | 
|  | 147       failed.add(name); | 
|  | 148     } else { | 
|  | 149       passed.add(name); | 
|  | 150     } | 
|  | 151   } | 
|  | 152 | 
|  | 153   if (failed.length == 0) { | 
|  | 154     var s = passed.length == 1 ? "" : "s"; | 
|  | 155     print("${green('PASSED')} all ${bold(passed.length)} configuration$s!"); | 
|  | 156   } else { | 
|  | 157     if (passed.length > 0) { | 
|  | 158       var s = passed == 1 ? "" : "s"; | 
|  | 159       print("${green('PASSED')} ${bold(passed.length)} configuration$s:"); | 
|  | 160       for (var config in passed) { | 
|  | 161         print("- ${bold(config)}"); | 
|  | 162       } | 
|  | 163     } | 
|  | 164 | 
|  | 165     var s = failed == 1 ? "" : "s"; | 
|  | 166     print("${red("FAILED")} ${bold(failed.length)} configuration$s:"); | 
|  | 167     for (var config in failed) { | 
|  | 168       print("- ${bold(config)}"); | 
|  | 169     } | 
|  | 170   } | 
|  | 171 } | 
|  | 172 | 
|  | 173 void usage(ArgParser parser) { | 
|  | 174   print("Usage: dart run_tests.dart [--build] [--configs=...] " | 
|  | 175       "<first file> <last file>"); | 
|  | 176   print("\n"); | 
|  | 177   print("Example:"); | 
|  | 178   print("\n"); | 
|  | 179   print("    \$ dart run_tests.dart map_to_string queue"); | 
|  | 180   print("\n"); | 
|  | 181   print(parser.usage); | 
|  | 182 } | 
|  | 183 | 
|  | 184 Future<int> run(String executable, List<String> arguments) async { | 
|  | 185   var process = await Process.start(executable, arguments); | 
|  | 186   process.stdout.listen((bytes) { | 
|  | 187     stdout.add(bytes); | 
|  | 188   }); | 
|  | 189 | 
|  | 190   process.stderr.listen((bytes) { | 
|  | 191     stderr.add(bytes); | 
|  | 192   }); | 
|  | 193 | 
|  | 194   return await process.exitCode; | 
|  | 195 } | 
| OLD | NEW | 
|---|