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 |