OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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_progress; | 5 library test_progress; |
6 | 6 |
7 import "dart:async"; | 7 import "dart:async"; |
8 import "dart:io"; | 8 import "dart:io"; |
9 import "dart:io" as io; | 9 import "dart:io" as io; |
10 import "dart:convert" show JSON; | 10 import "dart:convert" show JSON; |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
54 static String ESCAPE = decodeUtf8([27]); | 54 static String ESCAPE = decodeUtf8([27]); |
55 | 55 |
56 String passed(String msg) => _color(msg, GREEN); | 56 String passed(String msg) => _color(msg, GREEN); |
57 String failed(String msg) => _color(msg, RED); | 57 String failed(String msg) => _color(msg, RED); |
58 | 58 |
59 static String _color(String msg, int color) { | 59 static String _color(String msg, int color) { |
60 return "$ESCAPE[${color}m$msg$ESCAPE[0m"; | 60 return "$ESCAPE[${color}m$msg$ESCAPE[0m"; |
61 } | 61 } |
62 } | 62 } |
63 | 63 |
64 | |
65 List<String> _buildFailureOutput(TestCase test, | 64 List<String> _buildFailureOutput(TestCase test, |
66 [Formatter formatter = const Formatter()]) { | 65 [Formatter formatter = const Formatter()]) { |
67 | |
68 List<String> getLinesWithoutCarriageReturn(List<int> output) { | 66 List<String> getLinesWithoutCarriageReturn(List<int> output) { |
69 return decodeUtf8(output).replaceAll('\r\n', '\n') | 67 return decodeUtf8(output) |
70 .replaceAll('\r', '\n').split('\n'); | 68 .replaceAll('\r\n', '\n') |
| 69 .replaceAll('\r', '\n') |
| 70 .split('\n'); |
71 } | 71 } |
72 | 72 |
73 List<String> output = new List<String>(); | 73 List<String> output = new List<String>(); |
74 output.add(''); | 74 output.add(''); |
75 output.add(formatter.failed('FAILED: ${test.configurationString}' | 75 output.add(formatter.failed('FAILED: ${test.configurationString}' |
76 ' ${test.displayName}')); | 76 ' ${test.displayName}')); |
77 StringBuffer expected = new StringBuffer(); | 77 StringBuffer expected = new StringBuffer(); |
78 expected.write('Expected: '); | 78 expected.write('Expected: '); |
79 for (var expectation in test.expectedOutcomes) { | 79 for (var expectation in test.expectedOutcomes) { |
80 expected.write('$expectation '); | 80 expected.write('$expectation '); |
81 } | 81 } |
82 output.add(expected.toString()); | 82 output.add(expected.toString()); |
83 output.add('Actual: ${test.result}'); | 83 output.add('Actual: ${test.result}'); |
84 if (!test.lastCommandOutput.hasTimedOut) { | 84 if (!test.lastCommandOutput.hasTimedOut) { |
85 if (test.commandOutputs.length != test.commands.length | 85 if (test.commandOutputs.length != test.commands.length && |
86 && !test.expectCompileError) { | 86 !test.expectCompileError) { |
87 output.add('Unexpected compile-time error.'); | 87 output.add('Unexpected compile-time error.'); |
88 } else { | 88 } else { |
89 if (test.expectCompileError) { | 89 if (test.expectCompileError) { |
90 output.add('Compile-time error expected.'); | 90 output.add('Compile-time error expected.'); |
91 } | 91 } |
92 if (test.hasRuntimeError) { | 92 if (test.hasRuntimeError) { |
93 output.add('Runtime error expected.'); | 93 output.add('Runtime error expected.'); |
94 } | 94 } |
95 if (test.configuration['checked'] && test.isNegativeIfChecked) { | 95 if (test.configuration['checked'] && test.isNegativeIfChecked) { |
96 output.add('Dynamic type error expected.'); | 96 output.add('Dynamic type error expected.'); |
(...skipping 19 matching lines...) Expand all Loading... |
116 } | 116 } |
117 if (!commandOutput.stderr.isEmpty) { | 117 if (!commandOutput.stderr.isEmpty) { |
118 output.add(''); | 118 output.add(''); |
119 output.add('stderr:'); | 119 output.add('stderr:'); |
120 output.addAll(getLinesWithoutCarriageReturn(commandOutput.stderr)); | 120 output.addAll(getLinesWithoutCarriageReturn(commandOutput.stderr)); |
121 } | 121 } |
122 } | 122 } |
123 } | 123 } |
124 if (test is BrowserTestCase) { | 124 if (test is BrowserTestCase) { |
125 // Additional command for rerunning the steps locally after the fact. | 125 // Additional command for rerunning the steps locally after the fact. |
126 var command = | 126 var command = test.configuration["_servers_"].httpServerCommandline(); |
127 test.configuration["_servers_"].httpServerCommandline(); | |
128 output.add(''); | 127 output.add(''); |
129 output.add('To retest, run: $command'); | 128 output.add('To retest, run: $command'); |
130 } | 129 } |
131 for (var i = 0; i < test.commands.length; i++) { | 130 for (var i = 0; i < test.commands.length; i++) { |
132 var command = test.commands[i]; | 131 var command = test.commands[i]; |
133 var commandOutput = test.commandOutputs[command]; | 132 var commandOutput = test.commandOutputs[command]; |
134 output.add(''); | 133 output.add(''); |
135 output.add('Command[${command.displayName}]: $command'); | 134 output.add('Command[${command.displayName}]: $command'); |
136 if (commandOutput != null) { | 135 if (commandOutput != null) { |
137 output.add('Took ${commandOutput.time}'); | 136 output.add('Took ${commandOutput.time}'); |
138 } else { | 137 } else { |
139 output.add('Did not run'); | 138 output.add('Did not run'); |
140 } | 139 } |
141 } | 140 } |
142 | 141 |
143 var arguments = ['python', 'tools/test.py']; | 142 var arguments = ['python', 'tools/test.py']; |
144 arguments.addAll(test.configuration['_reproducing_arguments_']); | 143 arguments.addAll(test.configuration['_reproducing_arguments_']); |
145 arguments.add(test.displayName); | 144 arguments.add(test.displayName); |
146 var testPyCommandline = arguments.map(escapeCommandLineArgument).join(' '); | 145 var testPyCommandline = arguments.map(escapeCommandLineArgument).join(' '); |
147 | 146 |
148 output.add(''); | 147 output.add(''); |
149 output.add('Short reproduction command (experimental):'); | 148 output.add('Short reproduction command (experimental):'); |
150 output.add(" $testPyCommandline"); | 149 output.add(" $testPyCommandline"); |
151 return output; | 150 return output; |
152 } | 151 } |
153 | 152 |
154 String _buildSummaryEnd(int failedTests) { | 153 String _buildSummaryEnd(int failedTests) { |
155 if (failedTests == 0) { | 154 if (failedTests == 0) { |
156 return '\n===\n=== All tests succeeded\n===\n'; | 155 return '\n===\n=== All tests succeeded\n===\n'; |
157 } else { | 156 } else { |
158 var pluralSuffix = failedTests != 1 ? 's' : ''; | 157 var pluralSuffix = failedTests != 1 ? 's' : ''; |
159 return '\n===\n=== ${failedTests} test$pluralSuffix failed\n===\n'; | 158 return '\n===\n=== ${failedTests} test$pluralSuffix failed\n===\n'; |
160 } | 159 } |
161 } | 160 } |
162 | 161 |
163 | |
164 class EventListener { | 162 class EventListener { |
165 void testAdded() { } | 163 void testAdded() {} |
166 void done(TestCase test) { } | 164 void done(TestCase test) {} |
167 void allTestsKnown() { } | 165 void allTestsKnown() {} |
168 void allDone() { } | 166 void allDone() {} |
169 } | 167 } |
170 | 168 |
171 class ExitCodeSetter extends EventListener { | 169 class ExitCodeSetter extends EventListener { |
172 void done(TestCase test) { | 170 void done(TestCase test) { |
173 if (test.unexpectedOutput) { | 171 if (test.unexpectedOutput) { |
174 io.exitCode = 1; | 172 io.exitCode = 1; |
175 } | 173 } |
176 } | 174 } |
177 } | 175 } |
178 | 176 |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
219 * }, | 217 * }, |
220 * { | 218 * { |
221 * name: 'ff', | 219 * name: 'ff', |
222 * duration: 200.2, | 220 * duration: 200.2, |
223 * }, | 221 * }, |
224 * ], | 222 * ], |
225 * } | 223 * } |
226 * }, | 224 * }, |
227 */ | 225 */ |
228 | 226 |
229 static final INTERESTED_CONFIGURATION_PARAMETERS = | 227 static final INTERESTED_CONFIGURATION_PARAMETERS = [ |
230 ['mode', 'arch', 'compiler', 'runtime', 'checked', 'host_checked', | 228 'mode', |
231 'minified', 'csp', 'system', 'vm_options', 'use_sdk', | 229 'arch', |
232 'use_repository_packages', 'use_public_packages', 'builder_tag']; | 230 'compiler', |
| 231 'runtime', |
| 232 'checked', |
| 233 'host_checked', |
| 234 'minified', |
| 235 'csp', |
| 236 'system', |
| 237 'vm_options', |
| 238 'use_sdk', |
| 239 'use_repository_packages', |
| 240 'use_public_packages', |
| 241 'builder_tag' |
| 242 ]; |
233 | 243 |
234 IOSink _sink; | 244 IOSink _sink; |
235 | 245 |
236 void done(TestCase test) { | 246 void done(TestCase test) { |
237 var name = test.displayName; | 247 var name = test.displayName; |
238 var configuration = {}; | 248 var configuration = {}; |
239 for (var key in INTERESTED_CONFIGURATION_PARAMETERS) { | 249 for (var key in INTERESTED_CONFIGURATION_PARAMETERS) { |
240 configuration[key] = test.configuration[key]; | 250 configuration[key] = test.configuration[key]; |
241 } | 251 } |
242 var outcome = '${test.lastCommandOutput.result(test)}'; | 252 var outcome = '${test.lastCommandOutput.result(test)}'; |
243 var expectations = | 253 var expectations = |
244 test.expectedOutcomes.map((expectation) => "$expectation").toList(); | 254 test.expectedOutcomes.map((expectation) => "$expectation").toList(); |
245 | 255 |
246 var commandResults = []; | 256 var commandResults = []; |
247 double totalDuration = 0.0; | 257 double totalDuration = 0.0; |
248 for (var command in test.commands) { | 258 for (var command in test.commands) { |
249 var output = test.commandOutputs[command]; | 259 var output = test.commandOutputs[command]; |
250 if (output != null) { | 260 if (output != null) { |
251 double duration = output.time.inMicroseconds/1000.0; | 261 double duration = output.time.inMicroseconds / 1000.0; |
252 totalDuration += duration; | 262 totalDuration += duration; |
253 commandResults.add({ | 263 commandResults |
254 'name': command.displayName, | 264 .add({'name': command.displayName, 'duration': duration,}); |
255 'duration': duration, | |
256 }); | |
257 } | 265 } |
258 } | 266 } |
259 _writeTestOutcomeRecord({ | 267 _writeTestOutcomeRecord({ |
260 'name' : name, | 268 'name': name, |
261 'configuration' : configuration, | 269 'configuration': configuration, |
262 'test_result' : { | 270 'test_result': { |
263 'outcome' : outcome, | 271 'outcome': outcome, |
264 'expected_outcomes' : expectations, | 272 'expected_outcomes': expectations, |
265 'duration' : totalDuration, | 273 'duration': totalDuration, |
266 'command_results' : commandResults, | 274 'command_results': commandResults, |
267 }, | 275 }, |
268 }); | 276 }); |
269 } | 277 } |
270 | 278 |
271 void allDone() { | 279 void allDone() { |
272 if (_sink != null) _sink.close(); | 280 if (_sink != null) _sink.close(); |
273 } | 281 } |
274 | 282 |
275 void _writeTestOutcomeRecord(Map record) { | 283 void _writeTestOutcomeRecord(Map record) { |
276 if (_sink == null) { | 284 if (_sink == null) { |
277 _sink = new File(TestUtils.testOutcomeFileName()) | 285 _sink = new File(TestUtils.testOutcomeFileName()) |
278 .openWrite(mode: FileMode.APPEND); | 286 .openWrite(mode: FileMode.APPEND); |
279 } | 287 } |
280 _sink.write("${JSON.encode(record)}\n"); | 288 _sink.write("${JSON.encode(record)}\n"); |
281 } | 289 } |
282 } | 290 } |
283 | 291 |
284 | |
285 class UnexpectedCrashDumpArchiver extends EventListener { | 292 class UnexpectedCrashDumpArchiver extends EventListener { |
286 void done(TestCase test) { | 293 void done(TestCase test) { |
287 if (test.unexpectedOutput && test.result == Expectation.CRASH) { | 294 if (test.unexpectedOutput && test.result == Expectation.CRASH) { |
288 var name = "core.dart.${test.lastCommandOutput.pid}"; | 295 var name = "core.dart.${test.lastCommandOutput.pid}"; |
289 var file = new File(name); | 296 var file = new File(name); |
290 if (file.existsSync()) { | 297 if (file.existsSync()) { |
291 // Find the binary - we assume this is the first part of the command | 298 // Find the binary - we assume this is the first part of the command |
292 var binName = test.lastCommandExecuted.toString().split(' ').first; | 299 var binName = test.lastCommandExecuted.toString().split(' ').first; |
293 var binFile = new File(binName); | 300 var binFile = new File(binName); |
294 var binBaseName = new Path(binName).filename; | 301 var binBaseName = new Path(binName).filename; |
295 if (binFile.existsSync()) { | 302 if (binFile.existsSync()) { |
296 var tmpPath = new Path(Directory.systemTemp.path); | 303 var tmpPath = new Path(Directory.systemTemp.path); |
297 var dir = new Path(TestUtils.mkdirRecursive(tmpPath, | 304 var dir = new Path(TestUtils |
298 new Path('coredump_${test.lastCommandOutput.pid}')).path); | 305 .mkdirRecursive( |
| 306 tmpPath, new Path('coredump_${test.lastCommandOutput.pid}')) |
| 307 .path); |
299 TestUtils.copyFile(new Path(name), dir.append(name)); | 308 TestUtils.copyFile(new Path(name), dir.append(name)); |
300 TestUtils.copyFile(new Path(binName), dir.append(binBaseName)); | 309 TestUtils.copyFile(new Path(binName), dir.append(binBaseName)); |
301 print("\nCopied core dump and binary for unexpected crash to: " | 310 print("\nCopied core dump and binary for unexpected crash to: " |
302 "$dir"); | 311 "$dir"); |
303 } | 312 } |
304 } | 313 } |
305 } | 314 } |
306 } | 315 } |
307 } | 316 } |
308 | 317 |
309 | |
310 class SummaryPrinter extends EventListener { | 318 class SummaryPrinter extends EventListener { |
311 final bool jsonOnly; | 319 final bool jsonOnly; |
312 | 320 |
313 SummaryPrinter({bool jsonOnly}) | 321 SummaryPrinter({bool jsonOnly}) |
314 : jsonOnly = (jsonOnly == null) ? false : jsonOnly; | 322 : jsonOnly = (jsonOnly == null) ? false : jsonOnly; |
315 | 323 |
316 void allTestsKnown() { | 324 void allTestsKnown() { |
317 if (jsonOnly) { | 325 if (jsonOnly) { |
318 print("JSON:"); | 326 print("JSON:"); |
319 print(JSON.encode(summaryReport.values)); | 327 print(JSON.encode(summaryReport.values)); |
320 } else { | 328 } else { |
321 summaryReport.printReport(); | 329 summaryReport.printReport(); |
322 } | 330 } |
323 } | 331 } |
324 } | 332 } |
325 | 333 |
326 | |
327 class TimingPrinter extends EventListener { | 334 class TimingPrinter extends EventListener { |
328 final _command2testCases = new Map<Command, List<TestCase>>(); | 335 final _command2testCases = new Map<Command, List<TestCase>>(); |
329 final _commandOutputs = new Set<CommandOutput>(); | 336 final _commandOutputs = new Set<CommandOutput>(); |
330 DateTime _startTime; | 337 DateTime _startTime; |
331 | 338 |
332 TimingPrinter(this._startTime); | 339 TimingPrinter(this._startTime); |
333 | 340 |
334 void done(TestCase testCase) { | 341 void done(TestCase testCase) { |
335 for (var commandOutput in testCase.commandOutputs.values) { | 342 for (var commandOutput in testCase.commandOutputs.values) { |
336 var command = commandOutput.command; | 343 var command = commandOutput.command; |
(...skipping 13 matching lines...) Expand all Loading... |
350 for (int i = 0; i < 20 && i < outputs.length; i++) { | 357 for (int i = 0; i < 20 && i < outputs.length; i++) { |
351 var commandOutput = outputs[i]; | 358 var commandOutput = outputs[i]; |
352 var command = commandOutput.command; | 359 var command = commandOutput.command; |
353 var testCases = _command2testCases[command]; | 360 var testCases = _command2testCases[command]; |
354 | 361 |
355 var testCasesDescription = testCases.map((testCase) { | 362 var testCasesDescription = testCases.map((testCase) { |
356 return "${testCase.configurationString}/${testCase.displayName}"; | 363 return "${testCase.configurationString}/${testCase.displayName}"; |
357 }).join(', '); | 364 }).join(', '); |
358 | 365 |
359 print('${commandOutput.time} - ' | 366 print('${commandOutput.time} - ' |
360 '${command.displayName} - ' | 367 '${command.displayName} - ' |
361 '$testCasesDescription'); | 368 '$testCasesDescription'); |
362 } | 369 } |
363 } | 370 } |
364 } | 371 } |
365 | 372 |
366 class StatusFileUpdatePrinter extends EventListener { | 373 class StatusFileUpdatePrinter extends EventListener { |
367 var statusToConfigs = new Map<String, List<String>>(); | 374 var statusToConfigs = new Map<String, List<String>>(); |
368 var _failureSummary = <String>[]; | 375 var _failureSummary = <String>[]; |
369 | 376 |
370 void done(TestCase test) { | 377 void done(TestCase test) { |
371 if (test.unexpectedOutput) { | 378 if (test.unexpectedOutput) { |
372 _printFailureOutput(test); | 379 _printFailureOutput(test); |
373 } | 380 } |
374 } | 381 } |
375 | 382 |
376 void allDone() { | 383 void allDone() { |
377 _printFailureSummary(); | 384 _printFailureSummary(); |
378 } | 385 } |
379 | 386 |
380 | |
381 void _printFailureOutput(TestCase test) { | 387 void _printFailureOutput(TestCase test) { |
382 String status = '${test.displayName}: ${test.result}'; | 388 String status = '${test.displayName}: ${test.result}'; |
383 List<String> configs = | 389 List<String> configs = |
384 statusToConfigs.putIfAbsent(status, () => <String>[]); | 390 statusToConfigs.putIfAbsent(status, () => <String>[]); |
385 configs.add(test.configurationString); | 391 configs.add(test.configurationString); |
386 if (test.lastCommandOutput.hasTimedOut) { | 392 if (test.lastCommandOutput.hasTimedOut) { |
387 print('\n${test.displayName} timed out on ${test.configurationString}'); | 393 print('\n${test.displayName} timed out on ${test.configurationString}'); |
388 } | 394 } |
389 } | 395 } |
390 | 396 |
391 String _extractRuntime(String configuration) { | 397 String _extractRuntime(String configuration) { |
392 // Extract runtime from a configuration, for example, | 398 // Extract runtime from a configuration, for example, |
393 // 'none-vm-checked release_ia32'. | 399 // 'none-vm-checked release_ia32'. |
394 List<String> runtime = configuration.split(' ')[0].split('-'); | 400 List<String> runtime = configuration.split(' ')[0].split('-'); |
395 return '${runtime[0]}-${runtime[1]}'; | 401 return '${runtime[0]}-${runtime[1]}'; |
396 } | 402 } |
397 | 403 |
398 void _printFailureSummary() { | 404 void _printFailureSummary() { |
399 var groupedStatuses = new Map<String, List<String>>(); | 405 var groupedStatuses = new Map<String, List<String>>(); |
400 statusToConfigs.forEach((String status, List<String> configs) { | 406 statusToConfigs.forEach((String status, List<String> configs) { |
401 var runtimeToConfiguration = new Map<String, List<String>>(); | 407 var runtimeToConfiguration = new Map<String, List<String>>(); |
402 for (String config in configs) { | 408 for (String config in configs) { |
403 String runtime = _extractRuntime(config); | 409 String runtime = _extractRuntime(config); |
404 var runtimeConfigs = | 410 var runtimeConfigs = |
405 runtimeToConfiguration.putIfAbsent(runtime, () => <String>[]); | 411 runtimeToConfiguration.putIfAbsent(runtime, () => <String>[]); |
406 runtimeConfigs.add(config); | 412 runtimeConfigs.add(config); |
407 } | 413 } |
408 runtimeToConfiguration.forEach((String runtime, | 414 runtimeToConfiguration |
409 List<String> runtimeConfigs) { | 415 .forEach((String runtime, List<String> runtimeConfigs) { |
410 runtimeConfigs.sort((a, b) => a.compareTo(b)); | 416 runtimeConfigs.sort((a, b) => a.compareTo(b)); |
411 List<String> statuses = | 417 List<String> statuses = groupedStatuses.putIfAbsent( |
412 groupedStatuses.putIfAbsent('$runtime: $runtimeConfigs', | 418 '$runtime: $runtimeConfigs', () => <String>[]); |
413 () => <String>[]); | |
414 statuses.add(status); | 419 statuses.add(status); |
415 }); | 420 }); |
416 }); | 421 }); |
417 | 422 |
418 print('\n\nNecessary status file updates:'); | 423 print('\n\nNecessary status file updates:'); |
419 groupedStatuses.forEach((String config, List<String> statuses) { | 424 groupedStatuses.forEach((String config, List<String> statuses) { |
420 print(''); | 425 print(''); |
421 print('$config:'); | 426 print('$config:'); |
422 statuses.sort((a, b) => a.compareTo(b)); | 427 statuses.sort((a, b) => a.compareTo(b)); |
423 for (String status in statuses) { | 428 for (String status in statuses) { |
424 print(' $status'); | 429 print(' $status'); |
425 } | 430 } |
426 }); | 431 }); |
427 } | 432 } |
428 } | 433 } |
429 | 434 |
430 class SkippedCompilationsPrinter extends EventListener { | 435 class SkippedCompilationsPrinter extends EventListener { |
431 int _skippedCompilations = 0; | 436 int _skippedCompilations = 0; |
432 | 437 |
433 void done(TestCase test) { | 438 void done(TestCase test) { |
434 for (var commandOutput in test.commandOutputs.values) { | 439 for (var commandOutput in test.commandOutputs.values) { |
435 if (commandOutput.compilationSkipped) | 440 if (commandOutput.compilationSkipped) _skippedCompilations++; |
436 _skippedCompilations++; | |
437 } | 441 } |
438 } | 442 } |
439 | 443 |
440 void allDone() { | 444 void allDone() { |
441 if (_skippedCompilations > 0) { | 445 if (_skippedCompilations > 0) { |
442 print('\n$_skippedCompilations compilations were skipped because ' | 446 print('\n$_skippedCompilations compilations were skipped because ' |
443 'the previous output was already up to date\n'); | 447 'the previous output was already up to date\n'); |
444 } | 448 } |
445 } | 449 } |
446 } | 450 } |
447 | 451 |
448 class LeftOverTempDirPrinter extends EventListener { | 452 class LeftOverTempDirPrinter extends EventListener { |
449 final MIN_NUMBER_OF_TEMP_DIRS = 50; | 453 final MIN_NUMBER_OF_TEMP_DIRS = 50; |
450 | 454 |
451 static RegExp _getTemporaryDirectoryRegexp() { | 455 static RegExp _getTemporaryDirectoryRegexp() { |
452 // These are the patterns of temporary directory names created by | 456 // These are the patterns of temporary directory names created by |
453 // 'Directory.systemTemp.createTemp()' on linux/macos and windows. | 457 // 'Directory.systemTemp.createTemp()' on linux/macos and windows. |
454 if (['macos', 'linux'].contains(Platform.operatingSystem)) { | 458 if (['macos', 'linux'].contains(Platform.operatingSystem)) { |
455 return new RegExp(r'^temp_dir1_......$'); | 459 return new RegExp(r'^temp_dir1_......$'); |
456 } else { | 460 } else { |
457 return new RegExp(r'tempdir-........-....-....-....-............$'); | 461 return new RegExp(r'tempdir-........-....-....-....-............$'); |
458 } | 462 } |
459 } | 463 } |
460 | 464 |
461 static Stream<Directory> getLeftOverTemporaryDirectories() { | 465 static Stream<Directory> getLeftOverTemporaryDirectories() { |
462 var regExp = _getTemporaryDirectoryRegexp(); | 466 var regExp = _getTemporaryDirectoryRegexp(); |
463 return Directory.systemTemp.list().where( | 467 return Directory.systemTemp.list().where((FileSystemEntity fse) { |
464 (FileSystemEntity fse) { | 468 if (fse is Directory) { |
465 if (fse is Directory) { | 469 if (regExp.hasMatch(new Path(fse.path).filename)) { |
466 if (regExp.hasMatch(new Path(fse.path).filename)) { | 470 return true; |
467 return true; | 471 } |
468 } | 472 } |
469 } | 473 return false; |
470 return false; | 474 }); |
471 }); | |
472 } | 475 } |
473 | 476 |
474 void allDone() { | 477 void allDone() { |
475 getLeftOverTemporaryDirectories().length.then((int count) { | 478 getLeftOverTemporaryDirectories().length.then((int count) { |
476 if (count > MIN_NUMBER_OF_TEMP_DIRS) { | 479 if (count > MIN_NUMBER_OF_TEMP_DIRS) { |
477 DebugLogger.warning("There are ${count} directories " | 480 DebugLogger.warning("There are ${count} directories " |
478 "in the system tempdir " | 481 "in the system tempdir " |
479 "('${Directory.systemTemp.path}')! " | 482 "('${Directory.systemTemp.path}')! " |
480 "Maybe left over directories?\n"); | 483 "Maybe left over directories?\n"); |
481 } | 484 } |
482 }).catchError((error) { | 485 }).catchError((error) { |
483 DebugLogger.warning("Could not list temp directories, got: $error"); | 486 DebugLogger.warning("Could not list temp directories, got: $error"); |
484 }); | 487 }); |
485 } | 488 } |
486 } | 489 } |
487 | 490 |
488 class LineProgressIndicator extends EventListener { | 491 class LineProgressIndicator extends EventListener { |
489 void done(TestCase test) { | 492 void done(TestCase test) { |
490 var status = 'pass'; | 493 var status = 'pass'; |
491 if (test.unexpectedOutput) { | 494 if (test.unexpectedOutput) { |
492 status = 'fail'; | 495 status = 'fail'; |
493 } | 496 } |
494 print('Done ${test.configurationString} ${test.displayName}: $status'); | 497 print('Done ${test.configurationString} ${test.displayName}: $status'); |
495 } | 498 } |
496 } | 499 } |
497 | 500 |
498 | |
499 class TestFailurePrinter extends EventListener { | 501 class TestFailurePrinter extends EventListener { |
500 bool _printSummary; | 502 bool _printSummary; |
501 var _formatter; | 503 var _formatter; |
502 var _failureSummary = <String>[]; | 504 var _failureSummary = <String>[]; |
503 var _failedTests= 0; | 505 var _failedTests = 0; |
504 | 506 |
505 TestFailurePrinter(this._printSummary, | 507 TestFailurePrinter(this._printSummary, [this._formatter = const Formatter()]); |
506 [this._formatter = const Formatter()]); | |
507 | 508 |
508 void done(TestCase test) { | 509 void done(TestCase test) { |
509 if (test.unexpectedOutput) { | 510 if (test.unexpectedOutput) { |
510 _failedTests++; | 511 _failedTests++; |
511 var lines = _buildFailureOutput(test, _formatter); | 512 var lines = _buildFailureOutput(test, _formatter); |
512 for (var line in lines) { | 513 for (var line in lines) { |
513 print(line); | 514 print(line); |
514 } | 515 } |
515 print(''); | 516 print(''); |
516 if (_printSummary) { | 517 if (_printSummary) { |
(...skipping 14 matching lines...) Expand all Loading... |
531 | 532 |
532 print(_buildSummaryEnd(_failedTests)); | 533 print(_buildSummaryEnd(_failedTests)); |
533 } | 534 } |
534 } | 535 } |
535 } | 536 } |
536 } | 537 } |
537 | 538 |
538 class ProgressIndicator extends EventListener { | 539 class ProgressIndicator extends EventListener { |
539 ProgressIndicator(this._startTime); | 540 ProgressIndicator(this._startTime); |
540 | 541 |
541 | 542 void testAdded() { |
542 void testAdded() { _foundTests++; } | 543 _foundTests++; |
| 544 } |
543 | 545 |
544 void done(TestCase test) { | 546 void done(TestCase test) { |
545 if (test.unexpectedOutput) { | 547 if (test.unexpectedOutput) { |
546 _failedTests++; | 548 _failedTests++; |
547 } else { | 549 } else { |
548 _passedTests++; | 550 _passedTests++; |
549 } | 551 } |
550 _printDoneProgress(test); | 552 _printDoneProgress(test); |
551 } | 553 } |
552 | 554 |
553 void allTestsKnown() { | 555 void allTestsKnown() { |
554 _allTestsKnown = true; | 556 _allTestsKnown = true; |
555 } | 557 } |
556 | 558 |
557 void _printDoneProgress(TestCase test) {} | 559 void _printDoneProgress(TestCase test) {} |
558 | 560 |
559 int _completedTests() => _passedTests + _failedTests; | 561 int _completedTests() => _passedTests + _failedTests; |
560 | 562 |
561 int _foundTests = 0; | 563 int _foundTests = 0; |
562 int _passedTests = 0; | 564 int _passedTests = 0; |
563 int _failedTests = 0; | 565 int _failedTests = 0; |
564 bool _allTestsKnown = false; | 566 bool _allTestsKnown = false; |
565 DateTime _startTime; | 567 DateTime _startTime; |
566 } | 568 } |
567 | 569 |
568 abstract class CompactIndicator extends ProgressIndicator { | 570 abstract class CompactIndicator extends ProgressIndicator { |
569 CompactIndicator(DateTime startTime) | 571 CompactIndicator(DateTime startTime) : super(startTime); |
570 : super(startTime); | |
571 | 572 |
572 void allDone() { | 573 void allDone() { |
573 if (_failedTests > 0) { | 574 if (_failedTests > 0) { |
574 // We may have printed many failure logs, so reprint the summary data. | 575 // We may have printed many failure logs, so reprint the summary data. |
575 _printProgress(); | 576 _printProgress(); |
576 } | 577 } |
577 print(''); | 578 print(''); |
578 } | 579 } |
579 | 580 |
580 void _printDoneProgress(TestCase test) => _printProgress(); | 581 void _printDoneProgress(TestCase test) => _printProgress(); |
581 | 582 |
582 void _printProgress(); | 583 void _printProgress(); |
583 } | 584 } |
584 | 585 |
585 | |
586 class CompactProgressIndicator extends CompactIndicator { | 586 class CompactProgressIndicator extends CompactIndicator { |
587 Formatter _formatter; | 587 Formatter _formatter; |
588 | 588 |
589 CompactProgressIndicator(DateTime startTime, this._formatter) | 589 CompactProgressIndicator(DateTime startTime, this._formatter) |
590 : super(startTime); | 590 : super(startTime); |
591 | 591 |
592 void _printProgress() { | 592 void _printProgress() { |
593 var percent = ((_completedTests() / _foundTests) * 100).toInt().toString(); | 593 var percent = ((_completedTests() / _foundTests) * 100).toInt().toString(); |
594 var progressPadded = _pad(_allTestsKnown ? percent : '--', 3); | 594 var progressPadded = _pad(_allTestsKnown ? percent : '--', 3); |
595 var passedPadded = _pad(_passedTests.toString(), 5); | 595 var passedPadded = _pad(_passedTests.toString(), 5); |
596 var failedPadded = _pad(_failedTests.toString(), 5); | 596 var failedPadded = _pad(_failedTests.toString(), 5); |
597 Duration d = (new DateTime.now()).difference(_startTime); | 597 Duration d = (new DateTime.now()).difference(_startTime); |
598 var progressLine = | 598 var progressLine = '\r[${_timeString(d)} | $progressPadded% | ' |
599 '\r[${_timeString(d)} | $progressPadded% | ' | |
600 '+${_formatter.passed(passedPadded)} | ' | 599 '+${_formatter.passed(passedPadded)} | ' |
601 '-${_formatter.failed(failedPadded)}]'; | 600 '-${_formatter.failed(failedPadded)}]'; |
602 stdout.write(progressLine); | 601 stdout.write(progressLine); |
603 } | 602 } |
604 } | 603 } |
605 | 604 |
606 | |
607 class VerboseProgressIndicator extends ProgressIndicator { | 605 class VerboseProgressIndicator extends ProgressIndicator { |
608 VerboseProgressIndicator(DateTime startTime) | 606 VerboseProgressIndicator(DateTime startTime) : super(startTime); |
609 : super(startTime); | |
610 | 607 |
611 void _printDoneProgress(TestCase test) { | 608 void _printDoneProgress(TestCase test) { |
612 var status = 'pass'; | 609 var status = 'pass'; |
613 if (test.unexpectedOutput) { | 610 if (test.unexpectedOutput) { |
614 status = 'fail'; | 611 status = 'fail'; |
615 } | 612 } |
616 print('Done ${test.configurationString} ${test.displayName}: $status'); | 613 print('Done ${test.configurationString} ${test.displayName}: $status'); |
617 } | 614 } |
618 } | 615 } |
619 | 616 |
620 | |
621 class BuildbotProgressIndicator extends ProgressIndicator { | 617 class BuildbotProgressIndicator extends ProgressIndicator { |
622 static String stepName; | 618 static String stepName; |
623 var _failureSummary = <String>[]; | 619 var _failureSummary = <String>[]; |
624 | 620 |
625 BuildbotProgressIndicator(DateTime startTime) : super(startTime); | 621 BuildbotProgressIndicator(DateTime startTime) : super(startTime); |
626 | 622 |
627 void done(TestCase test) { | 623 void done(TestCase test) { |
628 super.done(test); | 624 super.done(test); |
629 if (test.unexpectedOutput) { | 625 if (test.unexpectedOutput) { |
630 _failureSummary.addAll(_buildFailureOutput(test)); | 626 _failureSummary.addAll(_buildFailureOutput(test)); |
(...skipping 19 matching lines...) Expand all Loading... |
650 } | 646 } |
651 for (String line in _failureSummary) { | 647 for (String line in _failureSummary) { |
652 print(line); | 648 print(line); |
653 } | 649 } |
654 print(''); | 650 print(''); |
655 } | 651 } |
656 print(_buildSummaryEnd(_failedTests)); | 652 print(_buildSummaryEnd(_failedTests)); |
657 } | 653 } |
658 } | 654 } |
659 | 655 |
660 | 656 EventListener progressIndicatorFromName( |
661 EventListener progressIndicatorFromName(String name, | 657 String name, DateTime startTime, Formatter formatter) { |
662 DateTime startTime, | |
663 Formatter formatter) { | |
664 switch (name) { | 658 switch (name) { |
665 case 'compact': | 659 case 'compact': |
666 return new CompactProgressIndicator(startTime, formatter); | 660 return new CompactProgressIndicator(startTime, formatter); |
667 case 'line': | 661 case 'line': |
668 return new LineProgressIndicator(); | 662 return new LineProgressIndicator(); |
669 case 'verbose': | 663 case 'verbose': |
670 return new VerboseProgressIndicator(startTime); | 664 return new VerboseProgressIndicator(startTime); |
671 case 'status': | 665 case 'status': |
672 return new ProgressIndicator(startTime); | 666 return new ProgressIndicator(startTime); |
673 case 'buildbot': | 667 case 'buildbot': |
674 return new BuildbotProgressIndicator(startTime); | 668 return new BuildbotProgressIndicator(startTime); |
675 default: | 669 default: |
676 assert(false); | 670 assert(false); |
677 break; | 671 break; |
678 } | 672 } |
679 } | 673 } |
OLD | NEW |