Chromium Code Reviews| 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. |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 116 executable = executable.replaceAll('/', '\\'); | 116 executable = executable.replaceAll('/', '\\'); |
| 117 } | 117 } |
| 118 var quotedArguments = []; | 118 var quotedArguments = []; |
| 119 quotedArguments.add(escapeCommandLineArgument(executable)); | 119 quotedArguments.add(escapeCommandLineArgument(executable)); |
| 120 quotedArguments.addAll(arguments.map(escapeCommandLineArgument)); | 120 quotedArguments.addAll(arguments.map(escapeCommandLineArgument)); |
| 121 commandLine = quotedArguments.join(' '); | 121 commandLine = quotedArguments.join(' '); |
| 122 } | 122 } |
| 123 | 123 |
| 124 String toString() => commandLine; | 124 String toString() => commandLine; |
| 125 | 125 |
| 126 Future postProcessCommand() => new Future.immediate(null); | |
| 127 | |
| 126 Future<bool> get outputIsUpToDate => new Future.immediate(false); | 128 Future<bool> get outputIsUpToDate => new Future.immediate(false); |
| 127 io.Path get expectedOutputFile => null; | 129 io.Path get expectedOutputFile => null; |
| 128 bool get isPixelTest => false; | 130 bool get isPixelTest => false; |
| 129 } | 131 } |
| 130 | 132 |
| 131 class CompilationCommand extends Command { | 133 class CompilationCommand extends Command { |
| 132 String _outputFile; | 134 String _outputFile; |
| 135 String _shadowFile; | |
| 133 bool _neverSkipCompilation; | 136 bool _neverSkipCompilation; |
| 134 List<Uri> _bootstrapDependencies; | 137 List<Uri> _bootstrapDependencies; |
| 135 | 138 |
| 136 CompilationCommand(this._outputFile, | 139 CompilationCommand(this._outputFile, |
| 140 this._shadowFile, | |
| 137 this._neverSkipCompilation, | 141 this._neverSkipCompilation, |
| 138 this._bootstrapDependencies, | 142 this._bootstrapDependencies, |
| 139 String executable, | 143 String executable, |
| 140 List<String> arguments) | 144 List<String> arguments) |
| 141 : super(executable, arguments); | 145 : super(executable, arguments); |
| 142 | 146 |
| 143 Future<bool> get outputIsUpToDate { | 147 Future<bool> get outputIsUpToDate { |
| 144 if (_neverSkipCompilation) return new Future.immediate(false); | 148 if (_neverSkipCompilation) return new Future.immediate(false); |
| 145 | 149 |
| 146 Future<List<Uri>> readDepsFile(String path) { | 150 Future<List<Uri>> readDepsFile(String path) { |
| 147 var file = new io.File(new io.Path(path).toNativePath()); | 151 var file = new io.File(new io.Path(path).toNativePath()); |
| 148 if (!file.existsSync()) { | 152 if (!file.existsSync()) { |
| 149 return new Future.immediate(null); | 153 return new Future.immediate(null); |
| 150 } | 154 } |
| 151 return file.readAsLines().then((List<String> lines) { | 155 return file.readAsLines().then((List<String> lines) { |
| 152 var dependencies = new List<Uri>(); | 156 var dependencies = new List<Uri>(); |
| 153 for (var line in lines) { | 157 for (var line in lines) { |
| 154 line = line.trim(); | 158 line = line.trim(); |
| 155 if (line.length > 0) { | 159 if (line.length > 0) { |
| 156 dependencies.add(new Uri(line)); | 160 dependencies.add(new Uri(line)); |
| 157 } | 161 } |
| 158 } | 162 } |
| 159 return dependencies; | 163 return dependencies; |
| 160 }); | 164 }); |
| 161 } | 165 } |
| 162 | 166 |
| 163 return readDepsFile("$_outputFile.deps").then((dependencies) { | 167 return readDepsFile("${_shadowFile}.deps").then((dependencies) { |
| 164 if (dependencies != null) { | 168 if (dependencies != null) { |
| 165 dependencies.addAll(_bootstrapDependencies); | 169 dependencies.addAll(_bootstrapDependencies); |
| 166 var jsOutputLastModified = TestUtils.lastModifiedCache.getLastModified( | 170 var jsOutputLastModified = TestUtils.lastModifiedCache.getLastModified( |
| 167 new Uri.fromComponents(scheme: 'file', path: _outputFile)); | 171 new Uri.fromComponents(scheme: 'file', path: _shadowFile)); |
| 168 if (jsOutputLastModified != null) { | 172 if (jsOutputLastModified != null) { |
| 169 for (var dependency in dependencies) { | 173 for (var dependency in dependencies) { |
| 170 var dependencyLastModified = | 174 var dependencyLastModified = |
| 171 TestUtils.lastModifiedCache.getLastModified(dependency); | 175 TestUtils.lastModifiedCache.getLastModified(dependency); |
| 172 if (dependencyLastModified == null || | 176 if (dependencyLastModified == null || |
| 173 dependencyLastModified.isAfter(jsOutputLastModified)) { | 177 dependencyLastModified.isAfter(jsOutputLastModified)) { |
| 174 return false; | 178 return false; |
| 175 } | 179 } |
| 176 } | 180 } |
| 181 // Shadow files are up to date, so copy them. | |
| 182 _copyFilesSync(_shadowFile, _outputFile); | |
| 177 return true; | 183 return true; |
| 178 } | 184 } |
| 179 } | 185 } |
| 180 return false; | 186 return false; |
| 181 }); | 187 }); |
| 182 } | 188 } |
| 189 | |
| 190 Future postProcessCommand() { | |
| 191 // After the actual compile, we synchronously copy the compiled output files | |
| 192 // to shadow files. | |
| 193 _copyFilesSync(_outputFile, _shadowFile); | |
| 194 return new Future.immediate(null); | |
| 195 } | |
| 196 | |
| 197 _copyFilesSync(String from, String to) { | |
| 198 for (var ending in ['', '.deps', '.map']) { | |
| 199 var fromFile = new io.File("${from}${ending}"); | |
| 200 var toFile = new io.File("${to}${ending}"); | |
| 201 toFile.writeAsBytesSync(fromFile.readAsBytesSync()); | |
|
ricow1
2013/06/25 13:10:48
add small comment stating why we do this sync
kustermann
2013/06/25 13:20:11
Done.
| |
| 202 } | |
| 203 } | |
| 183 } | 204 } |
| 184 | 205 |
| 185 class ContentShellCommand extends Command { | 206 class ContentShellCommand extends Command { |
| 186 /** | 207 /** |
| 187 * If [expectedOutputPath] is set, the output of content shell is compared | 208 * If [expectedOutputPath] is set, the output of content shell is compared |
| 188 * with the content of [expectedOutputPath]. | 209 * with the content of [expectedOutputPath]. |
| 189 * This is used for example for pixel tests, where [expectedOutputPath] points | 210 * This is used for example for pixel tests, where [expectedOutputPath] points |
| 190 * to a *png file. | 211 * to a *png file. |
| 191 */ | 212 */ |
| 192 io.Path expectedOutputPath; | 213 io.Path expectedOutputPath; |
| (...skipping 844 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1037 processOptions); | 1058 processOptions); |
| 1038 processFuture.then((io.Process process) { | 1059 processFuture.then((io.Process process) { |
| 1039 // Close stdin so that tests that try to block on input will fail. | 1060 // Close stdin so that tests that try to block on input will fail. |
| 1040 process.stdin.close(); | 1061 process.stdin.close(); |
| 1041 void timeoutHandler() { | 1062 void timeoutHandler() { |
| 1042 timedOut = true; | 1063 timedOut = true; |
| 1043 if (process != null) { | 1064 if (process != null) { |
| 1044 process.kill(); | 1065 process.kill(); |
| 1045 } | 1066 } |
| 1046 } | 1067 } |
| 1047 process.exitCode.then(_commandComplete); | 1068 process.exitCode.then((exitCode) { |
| 1069 if (exitCode == 0) { | |
| 1070 command.postProcessCommand().then((_) { | |
| 1071 _commandComplete(exitCode); | |
| 1072 }); | |
| 1073 } else { | |
| 1074 _commandComplete(exitCode); | |
| 1075 } | |
| 1076 }); | |
| 1048 _drainStream(process.stdout, stdout); | 1077 _drainStream(process.stdout, stdout); |
| 1049 _drainStream(process.stderr, stderr); | 1078 _drainStream(process.stderr, stderr); |
| 1050 timeoutTimer = new Timer(new Duration(seconds: testCase.timeout), | 1079 timeoutTimer = new Timer(new Duration(seconds: testCase.timeout), |
| 1051 timeoutHandler); | 1080 timeoutHandler); |
| 1052 }).catchError((e) { | 1081 }).catchError((e) { |
| 1053 // TODO(floitsch): should we try to report the stacktrace? | 1082 // TODO(floitsch): should we try to report the stacktrace? |
| 1054 print("Process error:"); | 1083 print("Process error:"); |
| 1055 print(" Command: $command"); | 1084 print(" Command: $command"); |
| 1056 print(" Error: $e"); | 1085 print(" Error: $e"); |
| 1057 _commandComplete(-1); | 1086 _commandComplete(-1); |
| (...skipping 853 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1911 } | 1940 } |
| 1912 } | 1941 } |
| 1913 | 1942 |
| 1914 void eventAllTestsDone() { | 1943 void eventAllTestsDone() { |
| 1915 for (var listener in _eventListener) { | 1944 for (var listener in _eventListener) { |
| 1916 listener.allDone(); | 1945 listener.allDone(); |
| 1917 } | 1946 } |
| 1918 } | 1947 } |
| 1919 } | 1948 } |
| 1920 | 1949 |
| OLD | NEW |