Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(96)

Side by Side Diff: tools/testing/dart/options.dart

Issue 2901923003: Replace the configuration map with a typed object. (Closed)
Patch Set: Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 import 'dart:io'; 5 import 'dart:io';
6
7 import 'configuration.dart';
6 import 'drt_updater.dart'; 8 import 'drt_updater.dart';
9 import 'path.dart';
7 import 'test_suite.dart'; 10 import 'test_suite.dart';
8 import 'path.dart';
9 import 'compiler_configuration.dart' show CompilerConfiguration;
10 import 'runtime_configuration.dart' show RuntimeConfiguration;
11 11
12 const _defaultTestSelectors = const [ 12 const _defaultTestSelectors = const [
13 'samples', 13 'samples',
14 'standalone', 14 'standalone',
15 'corelib', 15 'corelib',
16 'co19', 16 'co19',
17 'language', 17 'language',
18 'isolate', 18 'isolate',
19 'vm', 19 'vm',
20 'html', 20 'html',
21 'benchmark_smoke', 21 'benchmark_smoke',
22 'utils', 22 'utils',
23 'lib', 23 'lib',
24 'analyze_library', 24 'analyze_library',
25 'service', 25 'service',
26 'kernel', 26 'kernel',
27 'observatory_ui' 27 'observatory_ui'
28 ]; 28 ];
29 29
30 /// Specifies a single command line option. 30 /// Specifies a single command line option.
31 /// 31 ///
32 /// The name of the specification is used as the key for the option in the Map 32 /// The name of the specification is used as the key for the option in the Map
33 /// returned from the [TestOptionParser] parse method. 33 /// returned from the [TestOptionParser] parse method.
34 class _Option { 34 class _Option {
35 // TODO(rnystrom): Some string options use "" to mean "no value" and others 35 // TODO(rnystrom): Some string options use "" to mean "no value" and others
36 // use null. Clean that up. 36 // use null. Clean that up.
37 _Option(this.name, this.description, 37 _Option(this.name, this.description,
38 {String abbr, List<String> values, String defaultsTo = ""}) 38 {String abbr, List<String> values, String defaultsTo})
39 : abbreviation = abbr, 39 : abbreviation = abbr,
40 values = values ?? [], 40 values = values ?? [],
41 defaultValue = defaultsTo, 41 defaultValue = defaultsTo,
42 type = _OptionValueType.string; 42 type = _OptionValueType.string;
43 43
44 _Option.bool(this.name, this.description, [this.abbreviation]) 44 _Option.bool(this.name, this.description, [this.abbreviation])
45 : values = [], 45 : values = [],
46 defaultValue = false, 46 defaultValue = false,
47 type = _OptionValueType.bool; 47 type = _OptionValueType.bool;
48 48
(...skipping 18 matching lines...) Expand all
67 String get command => "--${name.replaceAll('_', '-')}"; 67 String get command => "--${name.replaceAll('_', '-')}";
68 } 68 }
69 69
70 enum _OptionValueType { bool, int, string } 70 enum _OptionValueType { bool, int, string }
71 71
72 /// Parses command line arguments and produces a test runner configuration. 72 /// Parses command line arguments and produces a test runner configuration.
73 class OptionsParser { 73 class OptionsParser {
74 static final List<_Option> _options = [ 74 static final List<_Option> _options = [
75 new _Option('mode', 'Mode in which to run the tests.', 75 new _Option('mode', 'Mode in which to run the tests.',
76 abbr: 'm', 76 abbr: 'm',
77 values: ['all', 'debug', 'release', 'product'], 77 values: ['all']..addAll(Mode.names),
78 defaultsTo: 'debug'), 78 defaultsTo: Mode.debug.name),
79 new _Option( 79 new _Option(
80 'compiler', 80 'compiler',
81 '''Specify any compilation step (if needed). 81 '''Specify any compilation step (if needed).
82 82
83 none: Do not compile the Dart code (run native Dart code 83 none: Do not compile the Dart code (run native Dart code
84 on the VM). 84 on the VM).
85 (Only valid with runtimes vm, flutter, or drt.) 85 (Only valid with runtimes vm, flutter, or drt.)
86 86
87 precompiler: Compile into AOT snapshot before running the test. 87 precompiler: Compile into AOT snapshot before running the test.
88 (Only valid with runtime dart_precompiled.) 88 (Only valid with runtime dart_precompiled.)
(...skipping 11 matching lines...) Expand all
100 running test. 100 running test.
101 (Only valid with dart_app runtime.) 101 (Only valid with dart_app runtime.)
102 102
103 dartk: Compile the Dart source into Kernel before running 103 dartk: Compile the Dart source into Kernel before running
104 test. 104 test.
105 105
106 dartkp: Compile the Dart source into Kernel and then Kernel 106 dartkp: Compile the Dart source into Kernel and then Kernel
107 into AOT snapshot before running the test. 107 into AOT snapshot before running the test.
108 (Only valid with runtime dart_precompiled.)''', 108 (Only valid with runtime dart_precompiled.)''',
109 abbr: 'c', 109 abbr: 'c',
110 values: [ 110 values: Compiler.names,
111 'none', 111 defaultsTo: Compiler.none.name),
112 'precompiler',
113 'dart2js',
114 'dart2analyzer',
115 'app_jit',
116 'dartk',
117 'dartkp'
118 ],
119 defaultsTo: 'none'),
120 new _Option( 112 new _Option(
121 'runtime', 113 'runtime',
122 '''Where the tests should be run. 114 '''Where the tests should be run.
123 vm: Run Dart code on the standalone dart vm. 115 vm: Run Dart code on the standalone dart vm.
124 116
125 flutter: Run Dart code on the flutter engine. 117 flutter: Run Dart code on the flutter engine.
126 118
127 dart_precompiled: Run a precompiled snapshot on a variant of the 119 dart_precompiled: Run a precompiled snapshot on a variant of the
128 standalone dart VM lacking a JIT. 120 standalone dart VM lacking a JIT.
129 121
(...skipping 23 matching lines...) Expand all
153 145
154 self_check: Pass each test or its compiled output to every 146 self_check: Pass each test or its compiled output to every
155 file under `pkg` whose name ends with 147 file under `pkg` whose name ends with
156 `_self_check.dart`. Each test is given to the 148 `_self_check.dart`. Each test is given to the
157 self_check tester as a filename on stdin using 149 self_check tester as a filename on stdin using
158 the batch-mode protocol. 150 the batch-mode protocol.
159 151
160 none: No runtime, compile only. (For example, used 152 none: No runtime, compile only. (For example, used
161 for dart2analyzer static analysis tests).''', 153 for dart2analyzer static analysis tests).''',
162 abbr: 'r', 154 abbr: 'r',
163 values: [ 155 values: Runtime.names,
164 'vm', 156 defaultsTo: Runtime.vm.name),
165 'flutter',
166 'dart_precompiled',
167 'd8',
168 'jsshell',
169 'drt',
170 'dartium',
171 'ff',
172 'firefox',
173 'chrome',
174 'safari',
175 'ie9',
176 'ie10',
177 'ie11',
178 'opera',
179 'chromeOnAndroid',
180 'safarimobilesim',
181 'ContentShellOnAndroid',
182 'DartiumOnAndroid',
183 'self_check',
184 'none'
185 ],
186 defaultsTo: 'vm'),
187 new _Option( 157 new _Option(
188 'arch', 158 'arch',
189 '''The architecture to run tests for. 159 '''The architecture to run tests for.
190 160
191 Allowed values are: 161 Allowed values are:
192 all 162 all
193 ia32, x64 163 ia32, x64
194 arm, armv6, armv5te, arm64, 164 arm, armv6, armv5te, arm64,
195 simarm, simarmv6, simarmv5te, simarm64, 165 simarm, simarmv6, simarmv5te, simarm64,
196 mips, simmips 166 mips, simmips
197 simdbc, simdbc64''', 167 simdbc, simdbc64''',
198 abbr: 'a', 168 abbr: 'a',
199 values: [ 169 values: ['all']..addAll(Architecture.names),
200 'all', 170 defaultsTo: Architecture.x64.name),
201 'ia32',
202 'x64',
203 'arm',
204 'armv6',
205 'armv5te',
206 'arm64',
207 'mips',
208 'simarm',
209 'simarmv6',
210 'simarmv5te',
211 'simarm64',
212 'simmips',
213 'simdbc',
214 'simdbc64',
215 ],
216 defaultsTo: 'x64'),
217 new _Option('system', 'The operating system to run tests on.', 171 new _Option('system', 'The operating system to run tests on.',
218 abbr: 's', 172 abbr: 's', values: System.names, defaultsTo: Platform.operatingSystem),
219 values: ['linux', 'macos', 'windows', 'android'],
220 defaultsTo: Platform.operatingSystem),
221 new _Option.bool('checked', 'Run tests in checked mode.'), 173 new _Option.bool('checked', 'Run tests in checked mode.'),
222 new _Option.bool('strong', 'Run tests in strong mode.'), 174 new _Option.bool('strong', 'Run tests in strong mode.'),
223 new _Option.bool('host_checked', 'Run compiler in checked mode.'), 175 new _Option.bool('host_checked', 'Run compiler in checked mode.'),
224 new _Option.bool('minified', 'Enable minification in the compiler.'), 176 new _Option.bool('minified', 'Enable minification in the compiler.'),
225 new _Option.bool( 177 new _Option.bool(
226 'csp', 'Run tests under Content Security Policy restrictions.'), 178 'csp', 'Run tests under Content Security Policy restrictions.'),
227 new _Option.bool('cps_ir', 'Run the compiler with the cps based backend.'), 179 new _Option.bool('cps_ir', 'Run the compiler with the cps based backend.'),
228 new _Option.bool( 180 new _Option.bool(
229 'fast_startup', 'Pass the --fast-startup flag to dart2js.'), 181 'fast_startup', 'Pass the --fast-startup flag to dart2js.'),
230 new _Option.bool('dart2js_with_kernel', 182 new _Option.bool('dart2js_with_kernel',
231 'Enable the internal pipeline in dart2js to use kernel.'), 183 'Enable the internal pipeline in dart2js to use kernel.'),
232 new _Option.bool('hot_reload', 'Run hot reload stress tests.'), 184 new _Option.bool('hot_reload', 'Run hot reload stress tests.'),
233 new _Option.bool( 185 new _Option.bool(
234 'hot_reload_rollback', 'Run hot reload rollback stress tests.'), 186 'hot_reload_rollback', 'Run hot reload rollback stress tests.'),
235 new _Option.bool('use_blobs', 187 new _Option.bool('use_blobs',
236 'Use mmap instead of shared libraries for precompilation.'), 188 'Use mmap instead of shared libraries for precompilation.'),
237 new _Option.int('timeout', 'Timeout in seconds.', 189 new _Option.int('timeout', 'Timeout in seconds.', abbr: 't'),
238 abbr: 't', defaultsTo: -1),
239 new _Option( 190 new _Option(
240 'progress', 191 'progress',
241 '''Progress indication mode. 192 '''Progress indication mode.
242 193
243 Allowed values are: 194 Allowed values are:
244 compact, color, line, verbose, silent, status, buildbot, diff 195 compact, color, line, verbose, silent, status, buildbot, diff
245 ''', 196 ''',
246 abbr: 'p', 197 abbr: 'p',
247 values: [ 198 values: Progress.names,
248 'compact', 199 defaultsTo: Progress.compact.name),
249 'color', 200 new _Option('step_name', 'Step name for use by -pbuildbot.'),
250 'line',
251 'verbose',
252 'silent',
253 'status',
254 'buildbot',
255 'diff'
256 ],
257 defaultsTo: 'compact'),
258 new _Option('step_name', 'Step name for use by -pbuildbot.',
259 defaultsTo: null),
260 new _Option.bool('report', 201 new _Option.bool('report',
261 'Print a summary report of the number of tests, by expectation.'), 202 'Print a summary report of the number of tests, by expectation.'),
262 new _Option.int('tasks', 'The number of parallel tasks to run.', 203 new _Option.int('tasks', 'The number of parallel tasks to run.',
263 abbr: 'j', defaultsTo: Platform.numberOfProcessors), 204 abbr: 'j', defaultsTo: Platform.numberOfProcessors),
264 new _Option.int('shards', 205 new _Option.int('shards',
265 'The number of instances that the tests will be sharded over.', 206 'The number of instances that the tests will be sharded over.',
266 defaultsTo: 1), 207 defaultsTo: 1),
267 new _Option.int( 208 new _Option.int(
268 'shard', 'The index of this instance when running in sharded mode.', 209 'shard', 'The index of this instance when running in sharded mode.',
269 defaultsTo: 1), 210 defaultsTo: 1),
270 new _Option.bool('help', 'Print list of options.', 'h'), 211 new _Option.bool('help', 'Print list of options.', 'h'),
271 new _Option.bool('verbose', 'Verbose output.', 'v'), 212 new _Option.bool('verbose', 'Verbose output.', 'v'),
272 new _Option.bool('verify-ir', 'Verify kernel IR.'), 213 new _Option.bool('verify-ir', 'Verify kernel IR.'),
273 new _Option.bool('no-tree-shake', 'Disable kernel IR tree shaking.'), 214 new _Option.bool('no-tree-shake', 'Disable kernel IR tree shaking.'),
274 new _Option.bool('list', 'List tests only, do not run them.'), 215 new _Option.bool('list', 'List tests only, do not run them.'),
275 new _Option.bool('report_in_json', 216 new _Option.bool('report_in_json',
276 'When listing with --list, output result summary in JSON.'), 217 'When listing with --list, output result summary in JSON.'),
277 new _Option.bool('time', 'Print timing information after running tests.'), 218 new _Option.bool('time', 'Print timing information after running tests.'),
278 new _Option('dart', 'Path to dart executable.'), 219 new _Option('dart', 'Path to dart executable.'),
279 new _Option('flutter', 'Path to flutter executable.'), 220 new _Option('flutter', 'Path to flutter executable.'),
280 new _Option( 221 new _Option('drt', 'Path to content shell executable.'),
281 'drt', // TODO(antonm): fix the option name.
282 'Path to content shell executable.'),
283 new _Option('dartium', 'Path to Dartium Chrome executable.'), 222 new _Option('dartium', 'Path to Dartium Chrome executable.'),
284 new _Option('firefox', 'Path to firefox browser executable.'), 223 new _Option('firefox', 'Path to firefox browser executable.'),
285 new _Option('chrome', 'Path to chrome browser executable.'), 224 new _Option('chrome', 'Path to chrome browser executable.'),
286 new _Option('safari', 'Path to safari browser executable.'), 225 new _Option('safari', 'Path to safari browser executable.'),
287 new _Option.bool( 226 new _Option.bool(
288 'use_sdk', 227 'use_sdk',
289 '''Use compiler or runtime from the SDK. 228 '''Use compiler or runtime from the SDK.
290 229
291 Normally, the compiler or runtimes in PRODUCT_DIR is tested, with 230 Normally, the compiler or runtimes in PRODUCT_DIR is tested, with
292 this option, the compiler or runtime in PRODUCT_DIR/dart-sdk/bin 231 this option, the compiler or runtime in PRODUCT_DIR/dart-sdk/bin
293 is tested. 232 is tested.
294 233
295 (Note: currently only implemented for dart2js.)'''), 234 (Note: currently only implemented for dart2js.)'''),
235 // TODO(rnystrom): This does not appear to be used. Remove?
296 new _Option('build_directory', 236 new _Option('build_directory',
297 'The name of the build directory, where products are placed.'), 237 'The name of the build directory, where products are placed.'),
298 new _Option.bool('noBatch', 'Do not run tests in batch mode.', 'n'), 238 new _Option.bool('noBatch', 'Do not run tests in batch mode.', 'n'),
299 new _Option.bool('dart2js_batch', 'Run dart2js tests in batch mode.'), 239 new _Option.bool('dart2js_batch', 'Run dart2js tests in batch mode.'),
300 new _Option.bool( 240 new _Option.bool(
301 'append_logs', 'Do not delete old logs but rather append to them.'), 241 'append_logs', 'Do not delete old logs but rather append to them.'),
302 new _Option.bool('write_debug_log', 242 new _Option.bool('write_debug_log',
303 'Don\'t write debug messages to stdout but rather to a logfile.'), 243 'Don\'t write debug messages to stdout but rather to a logfile.'),
304 new _Option.bool('write_test_outcome_log', 244 new _Option.bool('write_test_outcome_log',
305 'Write test outcomes to a "${TestUtils.testOutcomeFileName}" file.'), 245 'Write test outcomes to a "${TestUtils.testOutcomeFileName}" file.'),
(...skipping 16 matching lines...) Expand all
322 defaultsTo: 0), 262 defaultsTo: 0),
323 new _Option.int('test_server_cross_origin_port', 263 new _Option.int('test_server_cross_origin_port',
324 'Port for test http server cross origin.', 264 'Port for test http server cross origin.',
325 defaultsTo: 0), 265 defaultsTo: 0),
326 new _Option.int('test_driver_port', 'Port for http test driver server.', 266 new _Option.int('test_driver_port', 'Port for http test driver server.',
327 defaultsTo: 0), 267 defaultsTo: 0),
328 new _Option.int( 268 new _Option.int(
329 'test_driver_error_port', 'Port for http test driver server errors.', 269 'test_driver_error_port', 'Port for http test driver server errors.',
330 defaultsTo: 0), 270 defaultsTo: 0),
331 new _Option('record_to_file', 271 new _Option('record_to_file',
332 'Records all commands to be executed and writes to a file.', 272 'Records all commands to be executed and writes to a file.'),
333 defaultsTo: null),
334 new _Option( 273 new _Option(
335 'replay_from_file', 'Replays a previously recorded list of commands.', 274 'replay_from_file', 'Replays a previously recorded list of commands.'),
336 defaultsTo: null),
337 new _Option( 275 new _Option(
338 'builder_tag', 276 'builder_tag',
339 '''Machine specific options that is not captured by the regular test 277 '''Machine specific options that is not captured by the regular test
340 options. Used to be able to make sane updates to the status files.'''), 278 options. Used to be able to make sane updates to the status files.'''),
341 new _Option('vm_options', 'Extra options to send to the vm when running.', 279 new _Option('vm_options', 'Extra options to send to the vm when running.'),
342 defaultsTo: null),
343 new _Option( 280 new _Option(
344 'dart2js_options', 'Extra options for dart2js compilation step.', 281 'dart2js_options', 'Extra options for dart2js compilation step.'),
345 defaultsTo: null),
346 new _Option( 282 new _Option(
347 'suite_dir', 'Additional directory to add to the testing matrix.', 283 'suite_dir', 'Additional directory to add to the testing matrix.'),
348 defaultsTo: null), 284 new _Option('package_root', 'The package root to use for testing.'),
349 new _Option('package_root', 'The package root to use for testing.', 285 new _Option('packages', 'The package spec file to use for testing.'),
350 defaultsTo: null),
351 new _Option('packages', 'The package spec file to use for testing.',
352 defaultsTo: null),
353 new _Option( 286 new _Option(
354 'exclude_suite', 287 'exclude_suite',
355 '''Exclude suites from default selector, only works when no selector 288 '''Exclude suites from default selector, only works when no selector
356 has been specified on the command line.''', 289 has been specified on the command line.'''),
357 defaultsTo: null),
358 new _Option.bool( 290 new _Option.bool(
359 'skip-compilation', 291 'skip_compilation',
360 ''' 292 '''
361 Skip the compilation step, using the compilation artifacts left in 293 Skip the compilation step, using the compilation artifacts left in
362 the output folder from a previous run. This flag will often cause 294 the output folder from a previous run. This flag will often cause
363 false positves and negatives, but can be useful for quick and 295 false positves and negatives, but can be useful for quick and
364 dirty offline testing when not making changes that affect the 296 dirty offline testing when not making changes that affect the
365 compiler.''') 297 compiler.''')
366 ]; 298 ];
367 299
368 /// For printing out reproducing command lines, we don't want to add these 300 /// For printing out reproducing command lines, we don't want to add these
369 /// options. 301 /// options.
(...skipping 21 matching lines...) Expand all
391 'write_debug_log', 323 'write_debug_log',
392 'write_test_outcome_log', 324 'write_test_outcome_log',
393 ].toSet(); 325 ].toSet();
394 326
395 /// Parses a list of strings as test options. 327 /// Parses a list of strings as test options.
396 /// 328 ///
397 /// Returns a list of configurations in which to run the tests. 329 /// Returns a list of configurations in which to run the tests.
398 /// Configurations are maps mapping from option keys to values. When 330 /// Configurations are maps mapping from option keys to values. When
399 /// encountering the first non-option string, the rest of the arguments are 331 /// encountering the first non-option string, the rest of the arguments are
400 /// stored in the returned Map under the 'rest' key. 332 /// stored in the returned Map under the 'rest' key.
401 List<Map<String, dynamic>> parse(List<String> arguments) { 333 List<Configuration> parse(List<String> arguments) {
402 var configuration = <String, dynamic>{}; 334 var configuration = <String, dynamic>{};
403 335
404 // Fill in configuration with arguments passed to the test script. 336 // Fill in configuration with arguments passed to the test script.
405 for (var i = 0; i < arguments.length; i++) { 337 for (var i = 0; i < arguments.length; i++) {
406 var arg = arguments[i]; 338 var arg = arguments[i];
407 339
408 // Help supersedes all other arguments. 340 // Help supersedes all other arguments.
409 if (arg == "--help" || arg == "-h") { 341 if (arg == "--help" || arg == "-h") {
410 _printHelp(); 342 _printHelp();
411 return null; 343 return null;
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
503 } 435 }
504 } 436 }
505 437
506 // Apply default values for unspecified options. 438 // Apply default values for unspecified options.
507 for (var option in _options) { 439 for (var option in _options) {
508 if (!configuration.containsKey(option.name)) { 440 if (!configuration.containsKey(option.name)) {
509 configuration[option.name] = option.defaultValue; 441 configuration[option.name] = option.defaultValue;
510 } 442 }
511 } 443 }
512 444
513 var expandedConfigs = _expandConfigurations(configuration); 445 return _createConfigurations(configuration);
514 var result = expandedConfigs.where(_isValidConfig).toList();
515 for (var config in result) {
516 config['_reproducing_arguments_'] = _reproducingCommand(config);
517 }
518
519 return result.isEmpty ? null : result;
520 } 446 }
521 447
522 /// Prints [message] and exits with a non-zero exit code. 448 /// Prints [message] and exits with a non-zero exit code.
523 void _fail(String message) { 449 void _fail(String message) {
524 print(message); 450 print(message);
525 exit(1); 451 exit(1);
526 } 452 }
527 453
528 /// Given a configuration, returns the list of command line arguments that 454 /// Given a set of parsed option values, returns the list of command line
529 /// would reproduce that configuration. 455 /// arguments that would reproduce that configuration.
530 List<String> _reproducingCommand(Map config) { 456 List<String> _reproducingCommand(Map<String, dynamic> data) {
531 var arguments = <String>[]; 457 var arguments = <String>[];
532 458
533 for (var option in _options) { 459 for (var option in _options) {
534 var name = option.name; 460 var name = option.name;
535 if (!config.containsKey(name) || _blacklistedOptions.contains(name)) { 461 if (!data.containsKey(name) || _blacklistedOptions.contains(name)) {
536 continue; 462 continue;
537 } 463 }
538 464
539 var value = config[name]; 465 var value = data[name];
540 if (config[name] == option.defaultValue || 466 if (data[name] == option.defaultValue ||
541 (name == 'packages' && 467 (name == 'packages' &&
542 value == 468 value ==
543 TestUtils.dartDirUri.resolve('.packages').toFilePath())) { 469 TestUtils.dartDirUri.resolve('.packages').toFilePath())) {
544 continue; 470 continue;
545 } 471 }
546 472
547 arguments.add(option.shortCommand); 473 arguments.add(option.shortCommand);
548 if (option.type != _OptionValueType.bool) { 474 if (option.type != _OptionValueType.bool) {
549 arguments.add(value.toString()); 475 arguments.add(value.toString());
550 } 476 }
551 } 477 }
552 478
553 return arguments; 479 return arguments;
554 } 480 }
555 481
556 /// Determines if a particular configuration has a valid combination of 482 List<Configuration> _createConfigurations(
557 /// compiler and runtime elements.
558 bool _isValidConfig(Map config) {
559 var isValid = true;
560 List<String> validRuntimes;
561 switch (config['compiler'] as String) {
562 case 'dart2js':
563 // Note: by adding 'none' as a configuration, if the user
564 // runs test.py -c dart2js -r drt,none the dart2js_none and
565 // dart2js_drt will be duplicating work. If later we don't need 'none'
566 // with dart2js, we should remove it from here.
567 validRuntimes = const [
568 'd8',
569 'jsshell',
570 'drt',
571 'none',
572 'dartium',
573 'ff',
574 'chrome',
575 'safari',
576 'ie9',
577 'ie10',
578 'ie11',
579 'opera',
580 'chromeOnAndroid',
581 'safarimobilesim'
582 ];
583 break;
584 case 'dart2analyzer':
585 validRuntimes = const ['none'];
586 break;
587 case 'app_jit':
588 case 'dartk':
589 validRuntimes = const ['vm', 'self_check', 'none'];
590 break;
591 case 'precompiler':
592 case 'dartkp':
593 validRuntimes = const ['dart_precompiled'];
594 break;
595 case 'none':
596 validRuntimes = const [
597 'vm',
598 'flutter',
599 'drt',
600 'dartium',
601 'ContentShellOnAndroid',
602 'DartiumOnAndroid'
603 ];
604 break;
605 }
606
607 if (!validRuntimes.contains(config['runtime'])) {
608 isValid = false;
609 print("Warning: combination of compiler '${config['compiler']}' and "
610 "runtime '${config['runtime']}' is invalid. "
611 "Skipping this combination.");
612 }
613
614 if ((config['ie'] as bool) && Platform.operatingSystem != 'windows') {
615 isValid = false;
616 print("Warning: cannot run Internet Explorer on non-Windows operating"
617 " system.");
618 }
619
620 if ((config['shard'] as int) < 1 ||
621 (config['shard'] as int) > (config['shards'] as int)) {
622 isValid = false;
623 print("Error: shard index is ${config['shard']} out of "
624 "${config['shards']} shards");
625 }
626
627 if (config['runtime'] == 'flutter' && config['flutter'] == '') {
628 isValid = false;
629 print("-rflutter requires the flutter engine executable to "
630 "be specified using --flutter=");
631 }
632
633 if (config['runtime'] == 'flutter' && config['arch'] != 'x64') {
634 isValid = false;
635 print("-rflutter is applicable only for --arch=x64");
636 }
637
638 return isValid;
639 }
640
641 /// Recursively expands a configuration with multiple values per key into a
642 /// list of configurations with exactly one value per key.
643 List<Map<String, dynamic>> _expandConfigurations(
644 Map<String, dynamic> configuration) { 483 Map<String, dynamic> configuration) {
645 // Expand the pseudo-values such as 'all'. 484 var selectors = _expandSelectors(configuration);
Bill Hesse 2017/05/29 13:08:28 Because our code review and code browsing tools do
Bob Nystrom 2017/05/30 23:29:31 Yeah, I know it can make reviews a little harder s
646 if (configuration['arch'] == 'all') {
647 configuration['arch'] = 'ia32,x64,simarm,simarm64,simmips,simdbc64';
648 }
649
650 if (configuration['mode'] == 'all') {
651 configuration['mode'] = 'debug,release,product';
652 }
653
654 if (configuration['report_in_json'] as bool) {
655 configuration['list'] = true;
656 configuration['report'] = true;
657 }
658
659 // Use verbose progress indication for verbose output unless buildbot
660 // progress indication is requested.
661 if ((configuration['verbose'] as bool) &&
662 (configuration['progress'] as String) != 'buildbot') {
663 configuration['progress'] = 'verbose';
664 }
665
666 // Create the artificial negative options that test status files
667 // expect.
668 configuration['unchecked'] = !(configuration['checked'] as bool);
669 configuration['host_unchecked'] = !(configuration['host_checked'] as bool);
670 configuration['unminified'] = !(configuration['minified'] as bool);
671 configuration['nocsp'] = !(configuration['csp'] as bool);
672
673 var runtime = configuration['runtime'] as String;
674 if (runtime == 'firefox') {
675 configuration['runtime'] == 'ff';
676 }
677
678 var compiler = configuration['compiler'] as String;
679 configuration['browser'] = TestUtils.isBrowserRuntime(runtime);
680 configuration['analyzer'] = TestUtils.isCommandLineAnalyzer(compiler);
681
682 // Set the javascript command line flag for less verbose status files.
683 configuration['jscl'] = TestUtils.isJsCommandLineRuntime(runtime);
684
685 // Allow suppression that is valid for all ie versions
686 configuration['ie'] = runtime.startsWith('ie');
687
688 // Expand the test selectors into a suite name and a simple
689 // regular expressions to be used on the full path of a test file
690 // in that test suite. If no selectors are explicitly given use
691 // the default suite patterns.
692 var selectors = configuration['selectors'];
693 if (selectors is! Map) {
694 if (selectors == null) {
695 if (configuration['suite_dir'] != null) {
696 var suite_path = new Path(configuration['suite_dir'] as String);
697 selectors = [suite_path.filename];
698 } else {
699 selectors = _defaultTestSelectors.toList();
700 }
701
702 var excludeSuites = configuration['exclude_suite'] != null
703 ? configuration['exclude_suite'].split(',')
704 : [];
705 for (var exclude in excludeSuites) {
706 if ((selectors as List).contains(exclude)) {
707 selectors.remove(exclude);
708 } else {
709 print("Warning: default selectors does not contain $exclude");
710 }
711 }
712 }
713 var selectorMap = <String, RegExp>{};
714 for (var i = 0; i < (selectors as List).length; i++) {
715 var pattern = selectors[i] as String;
716 var suite = pattern;
717 var slashLocation = pattern.indexOf('/');
718 if (slashLocation != -1) {
719 suite = pattern.substring(0, slashLocation);
720 pattern = pattern.substring(slashLocation + 1);
721 pattern = pattern.replaceAll('*', '.*');
722 } else {
723 pattern = ".?";
724 }
725 if (selectorMap.containsKey(suite)) {
726 print("Error: '$suite/$pattern'. Only one test selection"
727 " pattern is allowed to start with '$suite/'");
728 exit(1);
729 }
730 selectorMap[suite] = new RegExp(pattern);
731 }
732 configuration['selectors'] = selectorMap;
733 }
734 485
735 // Put observatory_ui in a configuration with its own packages override. 486 // Put observatory_ui in a configuration with its own packages override.
736 // Only one value in the configuration map is mutable: 487 // Only one value in the configuration map is mutable:
737 selectors = configuration['selectors']; 488 if (selectors.containsKey('observatory_ui')) {
738 if ((selectors as Map<String, dynamic>).containsKey('observatory_ui')) {
739 if (selectors.length == 1) { 489 if (selectors.length == 1) {
740 configuration['packages'] = TestUtils.dartDirUri 490 configuration['packages'] = TestUtils.dartDirUri
741 .resolve('runtime/observatory/.packages') 491 .resolve('runtime/observatory/.packages')
742 .toFilePath(); 492 .toFilePath();
743 } else { 493 } else {
744 // Make a new configuration whose selectors map only contains 494 // Make a new configuration whose selectors map only contains
745 // observatory_ui, and remove the key from the original selectors. 495 // observatory_ui, and remove it from the original selectors.
Bill Hesse 2017/05/29 13:08:28 and remove "observatory_ui" from the original sele
Bob Nystrom 2017/05/30 23:29:31 Good point. Done.
746 // The only mutable value in the map is the selectors, so a 496 // The only mutable value in the map is the selectors, so a
747 // shallow copy is safe. 497 // shallow copy is safe.
748 var observatoryConfiguration = 498 var observatoryConfiguration =
749 new Map<String, dynamic>.from(configuration); 499 new Map<String, dynamic>.from(configuration);
750 observatoryConfiguration['selectors'] = { 500 var observatorySelectors = {
751 'observatory_ui': selectors['observatory_ui'] 501 'observatory_ui': selectors['observatory_ui']
752 }; 502 };
753 selectors.remove('observatory_ui'); 503 selectors.remove('observatory_ui');
754 504
755 // Set the packages flag. 505 // Set the packages flag.
756 observatoryConfiguration['packages'] = TestUtils.dartDirUri 506 observatoryConfiguration['packages'] = TestUtils.dartDirUri
757 .resolve('runtime/observatory/.packages') 507 .resolve('runtime/observatory/.packages')
758 .toFilePath(); 508 .toFilePath();
759 509
760 // Return the expansions of both configurations. Neither will reach 510 // Return the expansions of both configurations. Neither will reach
Bill Hesse 2017/05/29 13:08:28 Remove this comment, the call is no longer recursi
Bob Nystrom 2017/05/30 23:29:31 Done. It took me quite a while to wrap my head ar
761 // this line in the recursive call to _expandConfigurations. 511 // this line in the recursive call to _expandConfigurations.
762 return _expandConfigurations(configuration) 512 return _expandConfigurations(configuration, selectors)
763 ..addAll(_expandConfigurations(observatoryConfiguration)); 513 ..addAll(_expandConfigurations(
514 observatoryConfiguration, observatorySelectors));
764 } 515 }
765 } 516 }
766 517
767 // Set the default package spec explicitly. 518 return _expandConfigurations(configuration, selectors);
768 if (configuration['package_root'] == null && 519 }
769 configuration['packages'] == null) { 520
770 configuration['packages'] = 521 /// Recursively expands a configuration with multiple values per key into a
771 TestUtils.dartDirUri.resolve('.packages').toFilePath(); 522 /// list of configurations with exactly one value per key.
523 List<Configuration> _expandConfigurations(
524 Map<String, dynamic> data, Map<String, RegExp> selectors) {
525 var result = <Configuration>[];
526
527 // Handles a string option containing a space-separated list of words.
528 listOption(String name) {
529 var value = data[name] as String;
530 if (value == null) return const <String>[];
531 return value
532 .split(" ")
533 .map((s) => s.trim())
534 .where((s) => s.isNotEmpty)
535 .toList();
772 } 536 }
773 537
774 // Expand the architectures. 538 var dart2jsOptions = listOption("dart2js_options");
775 if ((configuration['arch'] as String).contains(',')) { 539 var vmOptions = listOption("vm_options");
776 return _expandHelper('arch', configuration); 540
541 // JSON reporting implies listing and reporting.
542 if (data['report_in_json'] as bool) {
543 data['list'] = true;
544 data['report'] = true;
777 } 545 }
778 546
779 // Expand modes. 547 // Use verbose progress indication for verbose output unless buildbot
780 if ((configuration['mode'] as String).contains(',')) { 548 // progress indication is requested.
781 return _expandHelper('mode', configuration); 549 if ((data['verbose'] as bool) &&
782 } 550 (data['progress'] as String) != 'buildbot') {
783 551 data['progress'] = 'verbose';
784 // Expand compilers.
785 if ((configuration['compiler'] as String).contains(',')) {
786 return _expandHelper('compiler', configuration);
787 } 552 }
788 553
789 // Expand runtimes. 554 // Expand runtimes.
790 var runtimes = configuration['runtime'] as String; 555 for (var runtimeName in (data["runtime"] as String).split(",")) {
791 if (runtimes.contains(',')) { 556 var runtime = Runtime.find(runtimeName);
792 return _expandHelper('runtime', configuration); 557
793 } else { 558 // Install the runtime if needed.
794 // All runtimes eventually go through this path, after expansion. 559 var updater = runtimeUpdater(
795 var updater = runtimeUpdater(configuration); 560 runtime, data["drt"] as String, data["dartium"] as String);
796 if (updater != null) { 561 if (updater != null) {
797 updater.update(); 562 updater.update();
798 } 563 }
564
565 // Expand architectures.
566 var architectures = data["arch"] as String;
567 if (architectures == "all") {
568 architectures = "ia32,x64,simarm,simarm64,simmips,simdbc64";
569 }
570
571 for (var architectureName in architectures.split(",")) {
572 var architecture = Architecture.find(architectureName);
573
574 // Expand compilers.
575 var compilers = data["compiler"] as String;
576 for (var compilerName in compilers.split(",")) {
577 var compiler = Compiler.find(compilerName);
578
579 // Expand modes.
580 var modes = data["mode"] as String;
581 if (modes == "all") modes = "debug,release,product";
582 for (var modeName in modes.split(",")) {
583 var mode = Mode.find(modeName);
584
585 var configuration = new Configuration(
586 architecture: architecture,
587 compiler: compiler,
588 mode: mode,
589 progress: Progress.find(data["progress"] as String),
590 runtime: runtime,
591 system: System.find(data["system"] as String),
592 selectors: selectors,
593 appendLogs: data["append_logs"] as bool,
594 batch: !(data["noBatch"] as bool),
595 batchDart2JS: data["dart2js_batch"] as bool,
596 copyCoreDumps: data["copy_coredumps"] as bool,
597 hotReload: data["hot_reload"] as bool,
598 hotReloadRollback: data["hot_reload_rollback"] as bool,
599 isChecked: data["checked"] as bool,
600 isStrong: data["strong"] as bool,
601 isHostChecked: data["host_checked"] as bool,
602 isCsp: data["csp"] as bool,
603 isMinified: data["minified"] as bool,
604 isVerbose: data["verbose"] as bool,
605 listTests: data["list"] as bool,
606 printTiming: data["time"] as bool,
607 printReport: data["report"] as bool,
608 reportInJson: data["report_in_json"] as bool,
609 resetBrowser: data["reset_browser_configuration"] as bool,
610 skipCompilation: data["skip_compilation"] as bool,
611 useBlobs: data["use_blobs"] as bool,
612 useSdk: data["use_sdk"] as bool,
613 useCpsIR: data["cps_ir"] as bool,
614 useFastStartup: data["fast_startup"] as bool,
615 useDart2JSWithKernel: data["dart2js_with_kernel"] as bool,
616 writeDebugLog: data["write_debug_log"] as bool,
617 writeTestOutcomeLog: data["write_test_outcome_log"] as bool,
618 drtPath: data["drt"] as String,
619 dartiumPath: data["dartium"] as String,
620 chromePath: data["chrome"] as String,
621 safariPath: data["safari"] as String,
622 firefoxPath: data["firefox"] as String,
623 dartPath: data["dart"] as String,
624 dartPrecompiledPath: data["dart_precompiled"] as String,
625 flutterPath: data["flutter"] as String,
626 recordingPath: data["record_to_file"] as String,
627 replayPath: data["replay_from_file"] as String,
628 taskCount: data["tasks"] as int,
629 timeout: data["timeout"] as int,
630 shardCount: data["shards"] as int,
631 shard: data["shard"] as int,
632 stepName: data["step_name"] as String,
633 testServerPort: data["test_server_port"] as int,
634 testServerCrossOriginPort:
635 data['test_server_cross_origin_port'] as int,
636 testDriverErrorPort: data["test_driver_error_port"] as int,
637 localIP: data["local_ip"] as String,
638 dart2jsOptions: dart2jsOptions,
639 vmOptions: vmOptions,
640 packages: data["packages"] as String,
641 packageRoot: data["package_root"] as String,
642 suiteDirectory: data["suite_dir"] as String,
643 builderTag: data["builder_tag"] as String,
644 reproducingArguments: _reproducingCommand(data));
645
646 if (configuration.validate()) {
647 result.add(configuration);
648 }
649 }
650 }
651 }
799 } 652 }
800 653
801 // Adjust default timeout based on mode, compiler, and sometimes runtime.
802 if (configuration['timeout'] == -1) {
803 var isReload = (configuration['hot_reload'] as bool) ||
804 (configuration['hot_reload_rollback'] as bool);
805 int compilerMulitiplier =
806 new CompilerConfiguration(configuration).computeTimeoutMultiplier();
807 int runtimeMultiplier = new RuntimeConfiguration(configuration)
808 .computeTimeoutMultiplier(
809 mode: configuration['mode'] as String,
810 isChecked: configuration['checked'] as bool,
811 isReload: isReload,
812 arch: configuration['arch'] as String);
813 configuration['timeout'] = 60 * compilerMulitiplier * runtimeMultiplier;
814 }
815
816 return [configuration];
817 }
818
819 /// Helper for _expandConfigurations. Creates a new configuration and adds it
820 /// to a list, for use in a case when a particular configuration has multiple
821 /// results (separated by a ',').
822 /// Arguments:
823 /// option: The particular test option we are expanding.
824 /// configuration: The map containing all test configuration information
825 /// specified.
826 List<Map<String, dynamic>> _expandHelper(
827 String option, Map<String, dynamic> configuration) {
828 var result = <Map<String, dynamic>>[];
829 var configs = configuration[option];
830 for (var config in configs.split(',')) {
831 var newConfiguration = new Map<String, dynamic>.from(configuration);
832 newConfiguration[option] = config;
833 result.addAll(_expandConfigurations(newConfiguration));
834 }
835 return result; 654 return result;
836 } 655 }
837 656
657 /// Expands the test selectors into a suite name and a simple regular
658 /// expression to be used on the full path of a test file in that test suite.
659 ///
660 /// If no selectors are explicitly given, uses the default suite patterns.
661 Map<String, RegExp> _expandSelectors(Map<String, dynamic> configuration) {
662 var selectors = configuration['selectors'];
663
664 if (selectors == null) {
665 if (configuration['suite_dir'] != null) {
666 var suitePath = new Path(configuration['suite_dir'] as String);
667 selectors = [suitePath.filename];
668 } else {
669 selectors = _defaultTestSelectors.toList();
670 }
671
672 var excludeSuites = configuration['exclude_suite'] != null
673 ? configuration['exclude_suite'].split(',')
674 : [];
675 for (var exclude in excludeSuites) {
676 if ((selectors as List).contains(exclude)) {
677 selectors.remove(exclude);
678 } else {
679 print("Warning: default selectors does not contain $exclude");
680 }
681 }
682 }
683
684 var selectorMap = <String, RegExp>{};
685 for (var i = 0; i < (selectors as List).length; i++) {
686 var pattern = selectors[i] as String;
687 var suite = pattern;
688 var slashLocation = pattern.indexOf('/');
689 if (slashLocation != -1) {
690 suite = pattern.substring(0, slashLocation);
691 pattern = pattern.substring(slashLocation + 1);
692 pattern = pattern.replaceAll('*', '.*');
693 } else {
694 pattern = ".?";
695 }
696 if (selectorMap.containsKey(suite)) {
697 print("Error: '$suite/$pattern'. Only one test selection"
698 " pattern is allowed to start with '$suite/'");
699 exit(1);
700 }
701 selectorMap[suite] = new RegExp(pattern);
702 }
703
704 return selectorMap;
705 }
706
838 /// Print out usage information. 707 /// Print out usage information.
839 void _printHelp() { 708 void _printHelp() {
840 var buffer = new StringBuffer(); 709 var buffer = new StringBuffer();
841 710
842 buffer.writeln('''usage: dart test.dart [options] [selector] 711 buffer.writeln('''usage: dart test.dart [options] [selector]
843 712
844 The optional selector limits the tests that will be run. 713 The optional selector limits the tests that will be run.
845 For example, the selector "language/issue", or equivalently 714 For example, the selector "language/issue", or equivalently
846 "language/*issue*", limits to test files matching the regexp 715 "language/*issue*", limits to test files matching the regexp
847 ".*issue.*\\.dart" in the "tests/language" directory. 716 ".*issue.*\\.dart" in the "tests/language" directory.
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
905 if (name == option.name) return option; 774 if (name == option.name) return option;
906 775
907 // Allow hyphens instead of underscores as the separator since they are 776 // Allow hyphens instead of underscores as the separator since they are
908 // more common for command line flags. 777 // more common for command line flags.
909 if (name == option.name.replaceAll("_", "-")) return option; 778 if (name == option.name.replaceAll("_", "-")) return option;
910 } 779 }
911 780
912 return null; 781 return null;
913 } 782 }
914 } 783 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698