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], | |
bkonyi
2017/08/01 02:16:30
What's the issue here exactly? Those should be the
Bob Nystrom
2017/08/01 20:52:41
I was getting some "snapshot version mismatch" whe
| |
48 "vm-product": [productMode, noCompiler, vm], | |
49 // TODO(rnystrom): Add dart2js-d8-hostchecked, dart2js-d8-minified, or | |
50 // dart2js-jsshell? | |
bkonyi
2017/08/01 02:16:30
It might be useful to have these, but probably not
Bob Nystrom
2017/08/01 20:52:41
Acknowledged.
| |
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? | |
bkonyi
2017/08/01 02:16:30
There are some tests that I've run into that only
Bob Nystrom
2017/08/01 20:52:41
Did copying over the existing status entries cover
| |
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 |