| OLD | NEW |
| 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, 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 #library("test_options_parser"); | 5 #library("test_options_parser"); |
| 6 | 6 |
| 7 #import("dart:io"); | 7 #import("dart:io"); |
| 8 #import("dart:builtin"); | 8 #import("dart:builtin"); |
| 9 #import("drt_updater.dart"); | 9 #import("drt_updater.dart"); |
| 10 | 10 |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 55 */ | 55 */ |
| 56 TestOptionsParser() { | 56 TestOptionsParser() { |
| 57 _options = | 57 _options = |
| 58 [ new _TestOptionSpecification( | 58 [ new _TestOptionSpecification( |
| 59 'mode', | 59 'mode', |
| 60 'Mode in which to run the tests', | 60 'Mode in which to run the tests', |
| 61 ['-m', '--mode'], | 61 ['-m', '--mode'], |
| 62 ['all', 'debug', 'release'], | 62 ['all', 'debug', 'release'], |
| 63 'debug'), | 63 'debug'), |
| 64 new _TestOptionSpecification( | 64 new _TestOptionSpecification( |
| 65 'component', | 65 'compiler', |
| 66 ''' | 66 '''Specify any compilation step (if needed). |
| 67 Controls how dart code is compiled and executed. | |
| 68 | 67 |
| 69 vm: Run dart code on the standalone dart vm. | 68 none: Do not compile the Dart code (run native Dart code on the VM). |
| 69 (only valid with the following runtimes: vm, drt) |
| 70 | 70 |
| 71 frog: Compile dart code by running frog on the standalone dart vm, and | 71 frog: Compile dart code to JavaScript by running the frog compiler. |
| 72 run the resulting javascript on D8. | 72 (only valid with the following runtimes: d8, drt, chrome, safari, ie, |
| 73 firefox, opera, none (compile only)) |
| 73 | 74 |
| 74 dart2js: Compile dart code by running dart2js on the standalone | 75 dart2js: Compile dart code to JavaScript by running dart2js (leg). |
| 75 dart vm, and run the resulting javascript on D8. | 76 (only valid with the following runtimes: same as frog) |
| 76 | 77 |
| 77 frogsh: Compile dart code by running frog on node.js, and run the | 78 dartc: Perform static analysis on Dart code by running dartc. |
| 78 resulting javascript on the same instance of node.js. | 79 (only valid with the following runtimes: none) |
| 79 | 80 |
| 80 dartium: Run dart code in a type="application/dart" script tag in a | 81 frogsh: Compile dart code to JavaScript by running the frog compiler on |
| 81 dartium build of DumpRenderTree. | 82 node.js, and run the resulting JavaScript on the same instance of |
| 82 | 83 node.js. |
| 83 frogium: Compile dart code by running frog on the standalone dart vm, | 84 (only valid with the following runtimes: same as frog)''', |
| 84 and run the resulting javascript in a javascript script tag in | 85 ['-c', '--compiler'], |
| 85 a dartium build of DumpRenderTree. | 86 ['none', 'frog', 'dart2js', 'dartc', 'frogsh'], |
| 86 | 87 'none'), |
| 87 legium: Compile dart code by running dart2js on the standalone dart | 88 new _TestOptionSpecification( |
| 88 vm, and run the resulting javascript in a javascript script tag | 89 'runtime', |
| 89 in a dartium build of DumpRenderTree. | 90 '''Where the tests should be run. |
| 90 | 91 vm: Run Dart code on the standalone dart vm. |
| 91 webdriver: Compile dart code by running frog on the standalone dart vm, | 92 |
| 92 and then run the resulting javascript in the browser that is specified | 93 d8: Run JavaScript from the command line using v8. |
| 93 by the --browser switch (e.g. chrome, safari, ff, etc.). | 94 |
| 94 | 95 drt: Run Dart or JavaScript in the headless version of Chrome, |
| 95 dartc: Run dart code through the dartc static analyzer (does not | 96 DumpRenderTree. |
| 96 execute dart code). | 97 |
| 97 ''', | 98 ff or firefox: Run JavaScript in Firefox. |
| 98 ['-c', '--component'], | 99 |
| 99 ['most', 'vm', 'frog', 'dart2js', 'frogsh', 'dartium', 'frogium', | 100 chrome: Run JavaScript in Chrome. |
| 100 'legium', 'webdriver', 'dartc'], | 101 |
| 102 safari: Run JavaScript in Safari. |
| 103 |
| 104 ie: Run JavaScript in Internet Explorer. |
| 105 |
| 106 opera: Run JavaScript in Opera. |
| 107 |
| 108 none: No runtime, compile only (for example, used for dartc static analysis |
| 109 tests).''', |
| 110 ['-r', '--runtime'], |
| 111 ['vm', 'd8', 'drt', 'ff', 'firefox', 'chrome', |
| 112 'safari', 'ie', 'opera', 'none'], |
| 101 'vm'), | 113 'vm'), |
| 102 new _TestOptionSpecification( | 114 new _TestOptionSpecification( |
| 103 'arch', | 115 'arch', |
| 104 'The architecture to run tests for', | 116 'The architecture to run tests for', |
| 105 ['-a', '--arch'], | 117 ['-a', '--arch'], |
| 106 ['all', 'ia32', 'x64', 'simarm'], | 118 ['all', 'ia32', 'x64', 'simarm'], |
| 107 'ia32'), | 119 'ia32'), |
| 108 new _TestOptionSpecification( | 120 new _TestOptionSpecification( |
| 109 'system', | 121 'system', |
| 110 'The operating system to run tests on', | 122 'The operating system to run tests on', |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 195 [], | 207 [], |
| 196 ''), | 208 ''), |
| 197 new _TestOptionSpecification( | 209 new _TestOptionSpecification( |
| 198 'time', | 210 'time', |
| 199 'Print timing information after running tests', | 211 'Print timing information after running tests', |
| 200 ['--time'], | 212 ['--time'], |
| 201 [], | 213 [], |
| 202 false, | 214 false, |
| 203 'bool'), | 215 'bool'), |
| 204 new _TestOptionSpecification( | 216 new _TestOptionSpecification( |
| 205 'browser', | |
| 206 'Web browser to use on webdriver tests', | |
| 207 ['-b', '--browser'], | |
| 208 ['ff', 'chrome', 'safari', 'ie', 'opera'], | |
| 209 'chrome'), | |
| 210 new _TestOptionSpecification( | |
| 211 'frog', | |
| 212 'Path to frog executable', | |
| 213 ['--frog'], | |
| 214 [], | |
| 215 ''), | |
| 216 new _TestOptionSpecification( | |
| 217 'drt', | 217 'drt', |
| 218 'Path to DumpRenderTree executable', | 218 'Path to DumpRenderTree executable', |
| 219 ['--drt'], | 219 ['--drt'], |
| 220 [], | 220 [], |
| 221 ''), | 221 ''), |
| 222 new _TestOptionSpecification( | 222 new _TestOptionSpecification( |
| 223 'froglib', | |
| 224 'Path to frog library', | |
| 225 ['--froglib'], | |
| 226 [], | |
| 227 ''), | |
| 228 new _TestOptionSpecification( | |
| 229 'noBatch', | 223 'noBatch', |
| 230 'Do not run browser tests in batch mode', | 224 'Do not run browser tests in batch mode', |
| 231 ['-n', '--nobatch'], | 225 ['-n', '--nobatch'], |
| 232 [], | 226 [], |
| 233 false, | 227 false, |
| 234 'bool')]; | 228 'bool')]; |
| 235 } | 229 } |
| 236 | 230 |
| 237 | 231 |
| 238 /** | 232 /** |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 342 } | 336 } |
| 343 } | 337 } |
| 344 | 338 |
| 345 // Apply default values for unspecified options. | 339 // Apply default values for unspecified options. |
| 346 for (var option in _options) { | 340 for (var option in _options) { |
| 347 if (!configuration.containsKey(option.name)) { | 341 if (!configuration.containsKey(option.name)) { |
| 348 configuration[option.name] = option.defaultValue; | 342 configuration[option.name] = option.defaultValue; |
| 349 } | 343 } |
| 350 } | 344 } |
| 351 | 345 |
| 352 return _expandConfigurations(configuration); | 346 List<Map> expandedConfigs = _expandConfigurations(configuration); |
| 347 return expandedConfigs.filter(_isValidConfig); |
| 353 } | 348 } |
| 354 | 349 |
| 350 /** |
| 351 * Determine if a particular configuration has a valid combination of compiler |
| 352 * and runtime elements. |
| 353 */ |
| 354 bool _isValidConfig(Map config) { |
| 355 bool isValid = true; |
| 356 switch (config['compiler']) { |
| 357 case 'frog': |
| 358 case 'dart2js': |
| 359 case 'frogsh': |
| 360 // Note: by adding 'none' as a configuration, if the user |
| 361 // runs test.py -c dart2js -r drt,none the dart2js_none and |
| 362 // dart2js_drt will be duplicating work. If later we don't need 'none' |
| 363 // with dart2js, we should remove it from here. |
| 364 isValid = (const ['d8', 'drt', 'ff', 'chrome', 'safari', 'ie', |
| 365 'opera', 'none']).indexOf(config['runtime']) >= 0; |
| 366 break; |
| 367 case 'dartc': |
| 368 isValid = config['runtime'] == 'none'; |
| 369 break; |
| 370 case 'none': |
| 371 isValid = (const ['vm', 'drt']).indexOf(config['runtime']) >= 0; |
| 372 } |
| 373 if (!isValid) { |
| 374 print("Warning: combination of ${config['compiler']} and " + |
| 375 "${config['runtime']} is invalid. Skipping this combination."); |
| 376 } |
| 377 if (config['runtime'] == 'ie' && |
| 378 new Platform().operatingSystem() != 'windows') { |
| 379 isValid = false; |
| 380 print("Warning cannot run Internet Explorer on non-Windows operating" + |
| 381 " systems."); |
| 382 } |
| 383 return isValid; |
| 384 } |
| 355 | 385 |
| 356 /** | 386 /** |
| 357 * Recursively expand a configuration with multiple values per key | 387 * Recursively expand a configuration with multiple values per key |
| 358 * into a list of configurations with exactly one value per key. | 388 * into a list of configurations with exactly one value per key. |
| 359 */ | 389 */ |
| 360 List<Map> _expandConfigurations(Map configuration) { | 390 List<Map> _expandConfigurations(Map configuration) { |
| 361 // Expand the pseudo-values such as 'all'. | 391 // Expand the pseudo-values such as 'all'. |
| 362 if (configuration['arch'] == 'all') { | 392 if (configuration['arch'] == 'all') { |
| 363 configuration['arch'] = 'ia32,x64'; | 393 configuration['arch'] = 'ia32,x64'; |
| 364 } | 394 } |
| 365 if (configuration['mode'] == 'all') { | 395 if (configuration['mode'] == 'all') { |
| 366 configuration['mode'] = 'debug,release'; | 396 configuration['mode'] = 'debug,release'; |
| 367 } | 397 } |
| 368 if (configuration['component'] == 'most') { | |
| 369 configuration['component'] = 'vm,dartc'; | |
| 370 } | |
| 371 if (configuration['valgrind']) { | 398 if (configuration['valgrind']) { |
| 372 // TODO(ager): Get rid of this when there is only one checkout and | 399 // TODO(ager): Get rid of this when there is only one checkout and |
| 373 // we don't have to special case for the runtime checkout. | 400 // we don't have to special case for the runtime checkout. |
| 374 File valgrindFile = new File('runtime/tools/valgrind.py'); | 401 File valgrindFile = new File('runtime/tools/valgrind.py'); |
| 375 if (!valgrindFile.existsSync()) { | 402 if (!valgrindFile.existsSync()) { |
| 376 valgrindFile = new File('../runtime/tools/valgrind.py'); | 403 valgrindFile = new File('../runtime/tools/valgrind.py'); |
| 377 } | 404 } |
| 378 String valgrind = valgrindFile.fullPathSync(); | 405 String valgrind = valgrindFile.fullPathSync(); |
| 379 configuration['special-command'] = 'python -u $valgrind @'; | 406 configuration['special-command'] = 'python -u $valgrind @'; |
| 380 } | 407 } |
| 381 | 408 |
| 382 // Use verbose progress indication for verbose output unless buildbot | 409 // Use verbose progress indication for verbose output unless buildbot |
| 383 // progress indication is requested. | 410 // progress indication is requested. |
| 384 if (configuration['verbose'] && configuration['progress'] != 'buildbot') { | 411 if (configuration['verbose'] && configuration['progress'] != 'buildbot') { |
| 385 configuration['progress'] = 'verbose'; | 412 configuration['progress'] = 'verbose'; |
| 386 } | 413 } |
| 387 | 414 |
| 388 // Create the artificial 'unchecked' options that test status files | 415 // Create the artificial 'unchecked' options that test status files |
| 389 // expect. | 416 // expect. |
| 390 configuration['unchecked'] = !configuration['checked']; | 417 configuration['unchecked'] = !configuration['checked']; |
| 391 configuration['host_unchecked'] = !configuration['host_checked']; | 418 configuration['host_unchecked'] = !configuration['host_checked']; |
| 392 | 419 |
| 420 if (configuration['runtime'] == 'firefox') { |
| 421 configuration['runtime'] == 'ff'; |
| 422 } |
| 423 |
| 393 // Expand the test selectors into a suite name and a simple | 424 // Expand the test selectors into a suite name and a simple |
| 394 // regular expressions to be used on the full path of a test file | 425 // regular expressions to be used on the full path of a test file |
| 395 // in that test suite. If no selectors are explicitly given use | 426 // in that test suite. If no selectors are explicitly given use |
| 396 // the default suite patterns. | 427 // the default suite patterns. |
| 397 var selectors = configuration['selectors']; | 428 var selectors = configuration['selectors']; |
| 398 if (selectors is !Map) { | 429 if (selectors is !Map) { |
| 399 if (selectors == null) { | 430 if (selectors == null) { |
| 400 selectors = new List.from(defaultTestSelectors); | 431 selectors = new List.from(defaultTestSelectors); |
| 401 } | 432 } |
| 402 Map<String, RegExp> selectorMap = new Map<String, RegExp>(); | 433 Map<String, RegExp> selectorMap = new Map<String, RegExp>(); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 416 print("Error: '$suite/$pattern'. Only one test selection" + | 447 print("Error: '$suite/$pattern'. Only one test selection" + |
| 417 " pattern is allowed to start with '$suite/'"); | 448 " pattern is allowed to start with '$suite/'"); |
| 418 exit(1); | 449 exit(1); |
| 419 } | 450 } |
| 420 selectorMap[suite] = new RegExp(pattern); | 451 selectorMap[suite] = new RegExp(pattern); |
| 421 } | 452 } |
| 422 configuration['selectors'] = selectorMap; | 453 configuration['selectors'] = selectorMap; |
| 423 } | 454 } |
| 424 | 455 |
| 425 // Expand the architectures. | 456 // Expand the architectures. |
| 426 var archs = configuration['arch']; | 457 if (configuration['arch'].contains(',')) { |
| 427 if (archs.contains(',')) { | 458 return _expandHelper('arch', configuration); |
| 428 var result = new List<Map>(); | |
| 429 for (var arch in archs.split(',')) { | |
| 430 var newConfiguration = new Map.from(configuration); | |
| 431 newConfiguration['arch'] = arch; | |
| 432 result.addAll(_expandConfigurations(newConfiguration)); | |
| 433 } | |
| 434 return result; | |
| 435 } | 459 } |
| 436 | 460 |
| 437 // Expand modes. | 461 // Expand modes. |
| 438 var modes = configuration['mode']; | 462 if (configuration['mode'].contains(',')) { |
| 439 if (modes.contains(',')) { | 463 return _expandHelper('mode', configuration); |
| 440 var result = new List<Map>(); | 464 } |
| 441 for (var mode in modes.split(',')) { | 465 |
| 442 var newConfiguration = new Map.from(configuration); | 466 // Expand compilers. |
| 443 newConfiguration['mode'] = mode; | 467 if (configuration['compiler'].contains(',')) { |
| 444 result.addAll(_expandConfigurations(newConfiguration)); | 468 return _expandHelper('compiler', configuration); |
| 445 } | |
| 446 return result; | |
| 447 } | 469 } |
| 448 | 470 |
| 449 // Expand components. | 471 // Expand runtimes. |
| 450 var components = configuration['component']; | 472 var runtimes = configuration['runtime']; |
| 451 if (components.contains(',')) { | 473 if (runtimes.contains(',')) { |
| 452 var result = new List<Map>(); | 474 return _expandHelper('runtime', configuration); |
| 453 for (var component in components.split(',')) { | |
| 454 var newConfiguration = new Map.from(configuration); | |
| 455 newConfiguration['component'] = component; | |
| 456 result.addAll(_expandConfigurations(newConfiguration)); | |
| 457 } | |
| 458 return result; | |
| 459 } else { | 475 } else { |
| 460 // All components eventually go through this path, after expansion. | 476 // All runtimes eventually go through this path, after expansion. |
| 461 if (DumpRenderTreeUpdater.componentRequiresDRT(components)) { | 477 if (runtimes == 'drt') { |
| 462 DumpRenderTreeUpdater.update(); | 478 DumpRenderTreeUpdater.update(); |
| 463 } | 479 } |
| 464 } | 480 } |
| 465 | 481 |
| 466 // Adjust default timeout based on mode and component. | 482 // Adjust default timeout based on mode, compiler, and sometimes runtime. |
| 467 if (configuration['timeout'] == -1) { | 483 if (configuration['timeout'] == -1) { |
| 468 var timeout = 60; | 484 var timeout = 60; |
| 469 switch (configuration['component']) { | 485 switch (configuration['compiler']) { |
| 470 case 'dartc': | 486 case 'dartc': |
| 471 case 'dartium': | |
| 472 case 'frogium': | |
| 473 case 'legium': | |
| 474 case 'webdriver': | |
| 475 timeout *= 4; | 487 timeout *= 4; |
| 476 break; | 488 break; |
| 477 case 'dart2js': | 489 case 'dart2js': |
| 478 case 'frog': | 490 case 'frog': |
| 479 if (configuration['mode'] == 'debug') { | 491 if (configuration['mode'] == 'debug') { |
| 480 timeout *= 8; | 492 timeout *= 8; |
| 481 } | 493 } |
| 482 if (configuration['host_checked']) { | 494 if (configuration['host_checked']) { |
| 483 timeout *= 16; | 495 timeout *= 16; |
| 484 } | 496 } |
| 497 if ((const ['ie', 'ff', 'chrome', 'safari', |
| 498 'opera']).indexOf(configuration['runtime']) >= 0) { |
| 499 timeout *= 4; // Allow additional time for browser testing to run. |
| 500 } |
| 485 break; | 501 break; |
| 486 default: | 502 default: |
| 487 if (configuration['mode'] == 'debug') { | 503 if (configuration['mode'] == 'debug') { |
| 488 timeout *= 2; | 504 timeout *= 2; |
| 489 } | 505 } |
| 506 if (configuration['runtime'] == 'drt') { |
| 507 timeout *= 4; |
| 508 } |
| 490 break; | 509 break; |
| 491 } | 510 } |
| 492 configuration['timeout'] = timeout; | 511 configuration['timeout'] = timeout; |
| 493 } | 512 } |
| 494 | 513 |
| 495 return [configuration]; | 514 return [configuration]; |
| 496 } | 515 } |
| 497 | 516 |
| 517 /** |
| 518 * Helper for _expandConfigurations. Creates a new configuration and adds it |
| 519 * to a list, for use in a case when a particular configuration has multiple |
| 520 * results (separated by a ','). |
| 521 * Arguments: |
| 522 * option: The particular test option we are expanding. |
| 523 * configuration: The map containing all test configuration information |
| 524 * specified. |
| 525 */ |
| 526 List<Map> _expandHelper(String option, Map configuration) { |
| 527 var result = new List<Map>(); |
| 528 var configs = configuration[option]; |
| 529 for (var config in configs.split(',')) { |
| 530 var newConfiguration = new Map.from(configuration); |
| 531 newConfiguration[option] = config; |
| 532 result.addAll(_expandConfigurations(newConfiguration)); |
| 533 } |
| 534 return result; |
| 535 } |
| 536 |
| 498 | 537 |
| 499 /** | 538 /** |
| 500 * Print out usage information. | 539 * Print out usage information. |
| 501 */ | 540 */ |
| 502 void _printHelp() { | 541 void _printHelp() { |
| 503 print('usage: dart test.dart [options]\n'); | 542 print('usage: dart test.dart [options]\n'); |
| 504 print('Options:\n'); | 543 print('Options:\n'); |
| 505 for (var option in _options) { | 544 for (var option in _options) { |
| 506 print('${option.name}: ${option.description}.'); | 545 print('${option.name}: ${option.description}.'); |
| 507 for (var name in option.keys) { | 546 for (var name in option.keys) { |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 543 return option; | 582 return option; |
| 544 } | 583 } |
| 545 } | 584 } |
| 546 print('Unknown test option $name'); | 585 print('Unknown test option $name'); |
| 547 exit(1); | 586 exit(1); |
| 548 } | 587 } |
| 549 | 588 |
| 550 | 589 |
| 551 List<_TestOptionSpecification> _options; | 590 List<_TestOptionSpecification> _options; |
| 552 } | 591 } |
| OLD | NEW |