OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 /** | 5 /** |
6 * Classes and methods for executing tests. | 6 * Classes and methods for executing tests. |
7 * | 7 * |
8 * This module includes: | 8 * This module includes: |
9 * - Managing parallel execution of tests, including timeout checks. | 9 * - Managing parallel execution of tests, including timeout checks. |
10 * - Evaluating the output of each test as pass/fail/crash/timeout. | 10 * - Evaluating the output of each test as pass/fail/crash/timeout. |
11 */ | 11 */ |
12 library test_runner; | 12 library test_runner; |
13 | 13 |
14 import "dart:async"; | 14 import "dart:async"; |
15 import "dart:collection" show Queue; | 15 import "dart:collection" show Queue; |
16 import "dart:convert" show LineSplitter, UTF8, JSON; | 16 import "dart:convert" show LineSplitter, UTF8, JSON; |
17 // We need to use the 'io' prefix here, otherwise io.exitCode will shadow | 17 // We need to use the 'io' prefix here, otherwise io.exitCode will shadow |
18 // CommandOutput.exitCode in subclasses of CommandOutput. | 18 // CommandOutput.exitCode in subclasses of CommandOutput. |
19 import "dart:io" as io; | 19 import "dart:io" as io; |
20 import "dart:math" as math; | 20 import "dart:math" as math; |
21 | 21 |
22 import 'package:yaml/yaml.dart'; | |
23 | |
24 import 'android.dart'; | 22 import 'android.dart'; |
25 import "browser_controller.dart"; | 23 import "browser_controller.dart"; |
26 import 'dependency_graph.dart' as dgraph; | 24 import 'dependency_graph.dart' as dgraph; |
27 import "path.dart"; | 25 import "path.dart"; |
28 import 'record_and_replay.dart'; | 26 import 'record_and_replay.dart'; |
29 import "runtime_configuration.dart"; | 27 import "runtime_configuration.dart"; |
30 import "status_file_parser.dart"; | 28 import "status_file_parser.dart"; |
31 import "test_progress.dart"; | 29 import "test_progress.dart"; |
32 import "test_suite.dart"; | 30 import "test_suite.dart"; |
33 import "utils.dart"; | 31 import "utils.dart"; |
(...skipping 484 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
518 builder.addJson(_sourceDirectory); | 516 builder.addJson(_sourceDirectory); |
519 builder.addJson(_destinationDirectory); | 517 builder.addJson(_destinationDirectory); |
520 } | 518 } |
521 | 519 |
522 bool _equal(CleanDirectoryCopyCommand other) => | 520 bool _equal(CleanDirectoryCopyCommand other) => |
523 super._equal(other) && | 521 super._equal(other) && |
524 _sourceDirectory == other._sourceDirectory && | 522 _sourceDirectory == other._sourceDirectory && |
525 _destinationDirectory == other._destinationDirectory; | 523 _destinationDirectory == other._destinationDirectory; |
526 } | 524 } |
527 | 525 |
528 class ModifyPubspecYamlCommand extends ScriptCommand { | |
529 String _pubspecYamlFile; | |
530 String _destinationFile; | |
531 Map<String, Map> _dependencyOverrides; | |
532 | |
533 ModifyPubspecYamlCommand._( | |
534 this._pubspecYamlFile, this._destinationFile, this._dependencyOverrides) | |
535 : super._("modify_pubspec") { | |
536 assert(_pubspecYamlFile.endsWith("pubspec.yaml")); | |
537 assert(_destinationFile.endsWith("pubspec.yaml")); | |
538 } | |
539 | |
540 static Map<String, Map> _filterOverrides( | |
541 String pubspec, Map<String, Map> overrides) { | |
542 if (overrides.isEmpty) return overrides; | |
543 var yaml = loadYaml(pubspec); | |
544 var deps = yaml['dependencies']; | |
545 var filteredOverrides = <String, Map>{}; | |
546 if (deps != null) { | |
547 for (var d in deps.keys) { | |
548 if (!overrides.containsKey(d)) { | |
549 // pub depends on compiler_unsupported instead of compiler | |
550 // The dependency is so hackish that we currently ignore it here. | |
551 if (d == 'compiler_unsupported') continue; | |
552 throw "Repo doesn't have package $d used in $pubspec"; | |
553 } | |
554 filteredOverrides[d] = overrides[d]; | |
555 } | |
556 } | |
557 return filteredOverrides; | |
558 } | |
559 | |
560 String get reproductionCommand => | |
561 "Adding necessary dependency overrides to '$_pubspecYamlFile' " | |
562 "(destination = $_destinationFile)."; | |
563 | |
564 Future<ScriptCommandOutputImpl> run() { | |
565 var watch = new Stopwatch()..start(); | |
566 | |
567 var pubspecLockFile = _destinationFile.substring( | |
568 0, _destinationFile.length - ".yaml".length) + | |
569 ".lock"; | |
570 | |
571 var file = new io.File(_pubspecYamlFile); | |
572 var destinationFile = new io.File(_destinationFile); | |
573 var lockfile = new io.File(pubspecLockFile); | |
574 return file.readAsString().then((String yamlString) { | |
575 var overrides = _filterOverrides(yamlString, _dependencyOverrides); | |
576 var dependencyOverrideSection = new StringBuffer(); | |
577 if (_dependencyOverrides.isNotEmpty) { | |
578 dependencyOverrideSection.write("\n" | |
579 "# This section was autogenerated by test.py!\n" | |
580 "dependency_overrides:\n"); | |
581 overrides.forEach((String packageName, Map override) { | |
582 dependencyOverrideSection.write(" $packageName:\n"); | |
583 override.forEach((overrideKey, overrideValue) { | |
584 dependencyOverrideSection | |
585 .write(" $overrideKey: $overrideValue\n"); | |
586 }); | |
587 }); | |
588 } | |
589 var modifiedYamlString = "$yamlString\n$dependencyOverrideSection"; | |
590 return destinationFile.writeAsString(modifiedYamlString).then((_) { | |
591 lockfile.exists().then((bool lockfileExists) { | |
592 if (lockfileExists) { | |
593 return lockfile.delete(); | |
594 } | |
595 }); | |
596 }); | |
597 }).then((_) { | |
598 return new ScriptCommandOutputImpl( | |
599 this, Expectation.PASS, "", watch.elapsed); | |
600 }).catchError((error) { | |
601 return new ScriptCommandOutputImpl( | |
602 this, Expectation.FAIL, "An error occured: $error.", watch.elapsed); | |
603 }); | |
604 } | |
605 | |
606 void _buildHashCode(HashCodeBuilder builder) { | |
607 super._buildHashCode(builder); | |
608 builder.addJson(_pubspecYamlFile); | |
609 builder.addJson(_destinationFile); | |
610 builder.addJson(_dependencyOverrides); | |
611 } | |
612 | |
613 bool _equal(ModifyPubspecYamlCommand other) => | |
614 super._equal(other) && | |
615 _pubspecYamlFile == other._pubspecYamlFile && | |
616 _destinationFile == other._destinationFile && | |
617 deepJsonCompare(_dependencyOverrides, other._dependencyOverrides); | |
618 } | |
619 | |
620 /* | 526 /* |
621 * [MakeSymlinkCommand] makes a symbolic link to another directory. | 527 * [MakeSymlinkCommand] makes a symbolic link to another directory. |
622 */ | 528 */ |
623 class MakeSymlinkCommand extends ScriptCommand { | 529 class MakeSymlinkCommand extends ScriptCommand { |
624 String _link; | 530 String _link; |
625 String _target; | 531 String _target; |
626 | 532 |
627 MakeSymlinkCommand._(this._link, this._target) : super._('make_symlink'); | 533 MakeSymlinkCommand._(this._link, this._target) : super._('make_symlink'); |
628 | 534 |
629 String get reproductionCommand => | 535 String get reproductionCommand => |
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
792 String pubspecYamlDirectory, String pubCacheDirectory) { | 698 String pubspecYamlDirectory, String pubCacheDirectory) { |
793 var command = new PubCommand._( | 699 var command = new PubCommand._( |
794 pubCommand, pubExecutable, pubspecYamlDirectory, pubCacheDirectory); | 700 pubCommand, pubExecutable, pubspecYamlDirectory, pubCacheDirectory); |
795 return _getUniqueCommand(command); | 701 return _getUniqueCommand(command); |
796 } | 702 } |
797 | 703 |
798 Command getMakeSymlinkCommand(String link, String target) { | 704 Command getMakeSymlinkCommand(String link, String target) { |
799 return _getUniqueCommand(new MakeSymlinkCommand._(link, target)); | 705 return _getUniqueCommand(new MakeSymlinkCommand._(link, target)); |
800 } | 706 } |
801 | 707 |
802 Command getModifyPubspecCommand(String pubspecYamlFile, Map depsOverrides, | |
803 {String destinationFile: null}) { | |
804 if (destinationFile == null) destinationFile = pubspecYamlFile; | |
805 return _getUniqueCommand(new ModifyPubspecYamlCommand._( | |
806 pubspecYamlFile, destinationFile, depsOverrides)); | |
807 } | |
808 | |
809 Command _getUniqueCommand(Command command) { | 708 Command _getUniqueCommand(Command command) { |
810 // All Command classes implement hashCode and operator==. | 709 // All Command classes implement hashCode and operator==. |
811 // We check if this command has already been built. | 710 // We check if this command has already been built. |
812 // If so, we return the cached one. Otherwise we | 711 // If so, we return the cached one. Otherwise we |
813 // store the one given as [command] argument. | 712 // store the one given as [command] argument. |
814 if (_cleared) { | 713 if (_cleared) { |
815 throw new Exception( | 714 throw new Exception( |
816 "CommandBuilder.get[type]Command called after cache cleared"); | 715 "CommandBuilder.get[type]Command called after cache cleared"); |
817 } | 716 } |
818 var cachedCommand = _cachedCommands[command]; | 717 var cachedCommand = _cachedCommands[command]; |
(...skipping 2525 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3344 } | 3243 } |
3345 } | 3244 } |
3346 | 3245 |
3347 void eventAllTestsDone() { | 3246 void eventAllTestsDone() { |
3348 for (var listener in _eventListener) { | 3247 for (var listener in _eventListener) { |
3349 listener.allDone(); | 3248 listener.allDone(); |
3350 } | 3249 } |
3351 _allDone(); | 3250 _allDone(); |
3352 } | 3251 } |
3353 } | 3252 } |
OLD | NEW |