Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 } |
| OLD | NEW |