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

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

Issue 256743009: Cache output of dart2js compilations that went wrong on disk. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « tools/testing/dart/multitest.dart ('k') | tools/testing/dart/test_suite.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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.
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
86 86
87 bool _equal(Command other) { 87 bool _equal(Command other) {
88 return hashCode == other.hashCode && 88 return hashCode == other.hashCode &&
89 commandLine == other.commandLine && 89 commandLine == other.commandLine &&
90 displayName == other.displayName; 90 displayName == other.displayName;
91 } 91 }
92 92
93 String toString() => reproductionCommand; 93 String toString() => reproductionCommand;
94 94
95 Future<bool> get outputIsUpToDate => new Future.value(false); 95 Future<bool> get outputIsUpToDate => new Future.value(false);
96
97 Future<String> get cachedOutput => new Future.value(null);
98 Future writeCachedOutput(CommandOutput output) => new Future.value(null);
96 } 99 }
97 100
98 class ProcessCommand extends Command { 101 class ProcessCommand extends Command {
99 /** Path to the executable of this command. */ 102 /** Path to the executable of this command. */
100 String executable; 103 String executable;
101 104
102 /** Command line arguments to the executable. */ 105 /** Command line arguments to the executable. */
103 List<String> arguments; 106 List<String> arguments;
104 107
105 /** Environment for the command */ 108 /** Environment for the command */
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
165 } 168 }
166 169
167 Future<bool> get outputIsUpToDate => new Future.value(false); 170 Future<bool> get outputIsUpToDate => new Future.value(false);
168 } 171 }
169 172
170 class CompilationCommand extends ProcessCommand { 173 class CompilationCommand extends ProcessCommand {
171 String _outputFile; 174 String _outputFile;
172 bool _neverSkipCompilation; 175 bool _neverSkipCompilation;
173 List<Uri> _bootstrapDependencies; 176 List<Uri> _bootstrapDependencies;
174 177
178 Future writeCachedOutput(CommandOutput output) {
179 var file = new io.File(TestUtils.cachedOutputFile(_outputFile));
180 return file.writeAsString(output.json)
181 .catchError((error) {
182 DebugLogger.warning("Could not write cached output: $error");
183 return null;
184 });
185 }
186
187 Future<CommandOutput> get cachedOutput {
188 var file = new io.File(TestUtils.cachedOutputFile(_outputFile));
189 return file.exists().then((exists) {
190 if (exists) return file.readAsString().then((content) {
191 return new CompilationCommandOutputImpl.fromJson(this, content);
192 });;
193 });
194 }
195
175 CompilationCommand._(String displayName, 196 CompilationCommand._(String displayName,
176 this._outputFile, 197 this._outputFile,
177 this._neverSkipCompilation, 198 this._neverSkipCompilation,
178 List<Uri> bootstrapDependencies, 199 List<Uri> bootstrapDependencies,
179 String executable, 200 String executable,
180 List<String> arguments, 201 List<String> arguments,
181 Map<String, String> environmentOverrides) 202 Map<String, String> environmentOverrides)
182 : super._(displayName, executable, arguments, environmentOverrides) { 203 : super._(displayName, executable, arguments, environmentOverrides) {
183 // We sort here, so we can do a fast hashCode/operator== 204 // We sort here, so we can do a fast hashCode/operator==
184 _bootstrapDependencies = new List.from(bootstrapDependencies); 205 _bootstrapDependencies = new List.from(bootstrapDependencies);
(...skipping 13 matching lines...) Expand all
198 for (var line in lines) { 219 for (var line in lines) {
199 line = line.trim(); 220 line = line.trim();
200 if (line.length > 0) { 221 if (line.length > 0) {
201 dependencies.add(Uri.parse(line)); 222 dependencies.add(Uri.parse(line));
202 } 223 }
203 } 224 }
204 return dependencies; 225 return dependencies;
205 }); 226 });
206 } 227 }
207 228
229 bool isUpToDate(lastModified, dependencies) {
230 if (lastModified == null) return false;
231 for (var dependency in dependencies) {
232 var dependencyLastModified =
233 TestUtils.lastModifiedCache.getLastModified(dependency);
234 if (dependencyLastModified == null ||
235 dependencyLastModified.isAfter(lastModified)) {
236 return false;
237 }
238 }
239 return true;
240 }
241
208 return readDepsFile("$_outputFile.deps").then((dependencies) { 242 return readDepsFile("$_outputFile.deps").then((dependencies) {
209 if (dependencies != null) { 243 if (dependencies != null) {
210 dependencies.addAll(_bootstrapDependencies); 244 dependencies.addAll(_bootstrapDependencies);
211 var jsOutputLastModified = TestUtils.lastModifiedCache.getLastModified( 245 // We check if the cached output is up to date, if so we return true
212 new Uri(scheme: 'file', path: _outputFile)); 246 var cachedOutputFile = TestUtils.cachedOutputFile(_outputFile);
213 if (jsOutputLastModified != null) { 247 var cachedOutputUri = new Uri(scheme: 'file', path: cachedOutputFile);
214 for (var dependency in dependencies) { 248 var cachedOutputLastModified =
215 var dependencyLastModified = 249 TestUtils.lastModifiedCache.getLastModified(cachedOutputUri);
216 TestUtils.lastModifiedCache.getLastModified(dependency); 250 return isUpToDate(cachedOutputLastModified, dependencies);
217 if (dependencyLastModified == null ||
218 dependencyLastModified.isAfter(jsOutputLastModified)) {
219 return false;
220 }
221 }
222 return true;
223 }
224 } 251 }
225 return false; 252 return false;
226 }); 253 });
227 } 254 }
228 255
229 void _buildHashCode(HashCodeBuilder builder) { 256 void _buildHashCode(HashCodeBuilder builder) {
230 super._buildHashCode(builder); 257 super._buildHashCode(builder);
231 builder.add(_outputFile); 258 builder.add(_outputFile);
232 builder.add(_neverSkipCompilation); 259 builder.add(_neverSkipCompilation);
233 for (var uri in _bootstrapDependencies) builder.add(uri); 260 for (var uri in _bootstrapDependencies) builder.add(uri);
(...skipping 678 matching lines...) Expand 10 before | Expand all | Expand 10 after
912 939
913 int get pid; 940 int get pid;
914 941
915 List<int> get stdout; 942 List<int> get stdout;
916 943
917 List<int> get stderr; 944 List<int> get stderr;
918 945
919 List<String> get diagnostics; 946 List<String> get diagnostics;
920 947
921 bool get compilationSkipped; 948 bool get compilationSkipped;
949
950 String get json;
922 } 951 }
923 952
924 class CommandOutputImpl extends UniqueObject implements CommandOutput { 953 class CommandOutputImpl extends UniqueObject implements CommandOutput {
925 Command command; 954 Command command;
926 int exitCode; 955 int exitCode;
927 956
928 bool timedOut; 957 bool timedOut;
929 List<int> stdout; 958 List<int> stdout;
930 List<int> stderr; 959 List<int> stderr;
931 Duration time; 960 Duration time;
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
1001 1030
1002 Expectation _negateOutcomeIfNegativeTest(Expectation outcome, 1031 Expectation _negateOutcomeIfNegativeTest(Expectation outcome,
1003 bool isNegative) { 1032 bool isNegative) {
1004 if (!isNegative) return outcome; 1033 if (!isNegative) return outcome;
1005 1034
1006 if (outcome.canBeOutcomeOf(Expectation.FAIL)) { 1035 if (outcome.canBeOutcomeOf(Expectation.FAIL)) {
1007 return Expectation.PASS; 1036 return Expectation.PASS;
1008 } 1037 }
1009 return Expectation.FAIL; 1038 return Expectation.FAIL;
1010 } 1039 }
1040
1041 String get json => null;
1042
1011 } 1043 }
1012 1044
1013 class BrowserCommandOutputImpl extends CommandOutputImpl { 1045 class BrowserCommandOutputImpl extends CommandOutputImpl {
1014 // Although tests are reported as passing, content shell sometimes exits with 1046 // Although tests are reported as passing, content shell sometimes exits with
1015 // a nonzero exitcode which makes our dartium builders extremely falky. 1047 // a nonzero exitcode which makes our dartium builders extremely falky.
1016 // See: http://dartbug.com/15139. 1048 // See: http://dartbug.com/15139.
1017 static int WHITELISTED_CONTENTSHELL_EXITCODE = -1073740022; 1049 static int WHITELISTED_CONTENTSHELL_EXITCODE = -1073740022;
1018 static bool isWindows = io.Platform.operatingSystem == 'windows'; 1050 static bool isWindows = io.Platform.operatingSystem == 'windows';
1019 1051
1020 bool _failedBecauseOfMissingXDisplay; 1052 bool _failedBecauseOfMissingXDisplay;
(...skipping 577 matching lines...) Expand 10 before | Expand all | Expand 10 after
1598 // We expected to run the test, but we got an compile time error. 1630 // We expected to run the test, but we got an compile time error.
1599 // If the compilation succeeded, we wouldn't be in here! 1631 // If the compilation succeeded, we wouldn't be in here!
1600 assert(exitCode != 0); 1632 assert(exitCode != 0);
1601 return Expectation.COMPILETIME_ERROR; 1633 return Expectation.COMPILETIME_ERROR;
1602 } 1634 }
1603 1635
1604 Expectation outcome = 1636 Expectation outcome =
1605 exitCode == 0 ? Expectation.PASS : Expectation.COMPILETIME_ERROR; 1637 exitCode == 0 ? Expectation.PASS : Expectation.COMPILETIME_ERROR;
1606 return _negateOutcomeIfNegativeTest(outcome, testCase.isNegative); 1638 return _negateOutcomeIfNegativeTest(outcome, testCase.isNegative);
1607 } 1639 }
1640
1641 String get json {
1642 var map = {
1643 'stdout': stdout,
1644 'stderr': stderr,
1645 'exitCode': exitCode,
1646 'timedOut': timedOut,
1647 };
1648 return JSON.encode(map);
1649 }
1650
1651 factory CompilationCommandOutputImpl.fromJson(Command command,
1652 String json) {
1653 var obj = JSON.decode(json);
1654 for (var v in ['stdout', 'stderr', 'exitCode', 'timedOut']) {
1655 assert(obj.containsKey(v));
1656 }
1657 return new CompilationCommandOutputImpl(command,
1658 obj['exitCode'],
1659 obj['timedOut'],
1660 obj['stdout'],
1661 obj['stderr'],
1662 const Duration(seconds: 0),
1663 true);
1664
1665 }
1608 } 1666 }
1609 1667
1610 class JsCommandlineOutputImpl extends CommandOutputImpl 1668 class JsCommandlineOutputImpl extends CommandOutputImpl
1611 with UnittestSuiteMessagesMixin { 1669 with UnittestSuiteMessagesMixin {
1612 JsCommandlineOutputImpl(Command command, int exitCode, bool timedOut, 1670 JsCommandlineOutputImpl(Command command, int exitCode, bool timedOut,
1613 List<int> stdout, List<int> stderr, Duration time) 1671 List<int> stdout, List<int> stderr, Duration time)
1614 : super(command, exitCode, timedOut, stdout, stderr, time, false, 0); 1672 : super(command, exitCode, timedOut, stdout, stderr, time, false, 0);
1615 1673
1616 Expectation result(TestCase testCase) { 1674 Expectation result(TestCase testCase) {
1617 // Handle crashes and timeouts first 1675 // Handle crashes and timeouts first
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after
1795 RunningProcess(this.command, this.timeout); 1853 RunningProcess(this.command, this.timeout);
1796 1854
1797 Future<CommandOutput> run() { 1855 Future<CommandOutput> run() {
1798 completer = new Completer<CommandOutput>(); 1856 completer = new Completer<CommandOutput>();
1799 startTime = new DateTime.now(); 1857 startTime = new DateTime.now();
1800 _runCommand(); 1858 _runCommand();
1801 return completer.future; 1859 return completer.future;
1802 } 1860 }
1803 1861
1804 void _runCommand() { 1862 void _runCommand() {
1805 command.outputIsUpToDate.then((bool isUpToDate) { 1863 command.outputIsUpToDate.then((isUpToDate) {
1806 if (isUpToDate) { 1864 if (isUpToDate) {
1807 compilationSkipped = true; 1865 compilationSkipped = true;
1808 _commandComplete(0); 1866 command.cachedOutput.then((cached) {
1867 _commandComplete(cached.exitCode, cachedOutput: cached);
1868 });
1809 } else { 1869 } else {
1810 var processEnvironment = _createProcessEnvironment(); 1870 var processEnvironment = _createProcessEnvironment();
1811 Future processFuture = 1871 Future processFuture =
1812 io.Process.start(command.executable, 1872 io.Process.start(command.executable,
1813 command.arguments, 1873 command.arguments,
1814 environment: processEnvironment, 1874 environment: processEnvironment,
1815 workingDirectory: command.workingDirectory); 1875 workingDirectory: command.workingDirectory);
1816 processFuture.then((io.Process process) { 1876 processFuture.then((io.Process process) {
1817 StreamSubscription stdoutSubscription = 1877 StreamSubscription stdoutSubscription =
1818 _drainStream(process.stdout, stdout); 1878 _drainStream(process.stdout, stdout);
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
1891 print("Process error:"); 1951 print("Process error:");
1892 print(" Command: $command"); 1952 print(" Command: $command");
1893 print(" Error: $e"); 1953 print(" Error: $e");
1894 _commandComplete(-1); 1954 _commandComplete(-1);
1895 return true; 1955 return true;
1896 }); 1956 });
1897 } 1957 }
1898 }); 1958 });
1899 } 1959 }
1900 1960
1901 void _commandComplete(int exitCode) { 1961 void _commandComplete(int exitCode, {cachedOutput: null}) {
1902 if (timeoutTimer != null) { 1962 if (timeoutTimer != null) {
1903 timeoutTimer.cancel(); 1963 timeoutTimer.cancel();
1904 } 1964 }
1905 var commandOutput = _createCommandOutput(command, exitCode); 1965 if (cachedOutput != null) {
1906 completer.complete(commandOutput); 1966 completer.complete(cachedOutput);
1967 } else {
1968 var commandOutput = _createCommandOutput(command, exitCode);
1969 command.writeCachedOutput(commandOutput);
1970 completer.complete(commandOutput);
1971 }
1907 } 1972 }
1908 1973
1909 CommandOutput _createCommandOutput(ProcessCommand command, int exitCode) { 1974 CommandOutput _createCommandOutput(ProcessCommand command, int exitCode) {
1910 var commandOutput = createCommandOutput( 1975 var commandOutput = createCommandOutput(
1911 command, 1976 command,
1912 exitCode, 1977 exitCode,
1913 timedOut, 1978 timedOut,
1914 stdout.toList(), 1979 stdout.toList(),
1915 stderr.toList(), 1980 stderr.toList(),
1916 new DateTime.now().difference(startTime), 1981 new DateTime.now().difference(startTime),
(...skipping 1053 matching lines...) Expand 10 before | Expand all | Expand 10 after
2970 } 3035 }
2971 } 3036 }
2972 3037
2973 void eventAllTestsDone() { 3038 void eventAllTestsDone() {
2974 for (var listener in _eventListener) { 3039 for (var listener in _eventListener) {
2975 listener.allDone(); 3040 listener.allDone();
2976 } 3041 }
2977 _allDone(); 3042 _allDone();
2978 } 3043 }
2979 } 3044 }
OLDNEW
« no previous file with comments | « tools/testing/dart/multitest.dart ('k') | tools/testing/dart/test_suite.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698