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 import 'dart:convert' show JSON; |
| 6 import 'dart:io'; |
6 | 7 |
7 import "dart:convert" show JSON; | 8 import 'configuration.dart'; |
8 import "dart:io"; | 9 import 'expectation.dart'; |
9 | 10 import 'path.dart'; |
10 import "expectation.dart"; | 11 import 'summary_report.dart'; |
11 import "http_server.dart"; | 12 import 'test_runner.dart'; |
12 import "path.dart"; | 13 import 'test_suite.dart'; |
13 import "summary_report.dart"; | 14 import 'utils.dart'; |
14 import "test_runner.dart"; | |
15 import "test_suite.dart"; | |
16 import "utils.dart"; | |
17 | 15 |
18 /// Controls how message strings are processed before being displayed. | 16 /// Controls how message strings are processed before being displayed. |
19 class Formatter { | 17 class Formatter { |
20 /// Messages are left as-is. | 18 /// Messages are left as-is. |
21 static const normal = const Formatter._(); | 19 static const normal = const Formatter._(); |
22 | 20 |
23 /// Messages are wrapped in ANSI escape codes to color them for display on a | 21 /// Messages are wrapped in ANSI escape codes to color them for display on a |
24 /// terminal. | 22 /// terminal. |
25 static const color = const _ColorFormatter(); | 23 static const color = const _ColorFormatter(); |
26 | 24 |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
129 * duration: 2400.44, | 127 * duration: 2400.44, |
130 * }, | 128 * }, |
131 * { | 129 * { |
132 * name: 'ff', | 130 * name: 'ff', |
133 * duration: 200.2, | 131 * duration: 200.2, |
134 * }, | 132 * }, |
135 * ], | 133 * ], |
136 * } | 134 * } |
137 * }, | 135 * }, |
138 */ | 136 */ |
139 | |
140 static final INTERESTED_CONFIGURATION_PARAMETERS = [ | |
141 'mode', | |
142 'arch', | |
143 'compiler', | |
144 'runtime', | |
145 'checked', | |
146 'strong', | |
147 'host_checked', | |
148 'minified', | |
149 'csp', | |
150 'system', | |
151 'vm_options', | |
152 'use_sdk', | |
153 'builder_tag' | |
154 ]; | |
155 | |
156 IOSink _sink; | 137 IOSink _sink; |
157 | 138 |
158 void done(TestCase test) { | 139 void done(TestCase test) { |
159 var name = test.displayName; | 140 var name = test.displayName; |
160 var configuration = {}; | 141 var configuration = { |
161 for (var key in INTERESTED_CONFIGURATION_PARAMETERS) { | 142 'mode': test.configuration.mode.name, |
162 configuration[key] = test.configuration[key]; | 143 'arch': test.configuration.architecture.name, |
163 } | 144 'compiler': test.configuration.compiler.name, |
| 145 'runtime': test.configuration.runtime.name, |
| 146 'checked': test.configuration.isChecked, |
| 147 'strong': test.configuration.isStrong, |
| 148 'host_checked': test.configuration.isHostChecked, |
| 149 'minified': test.configuration.isMinified, |
| 150 'csp': test.configuration.isCsp, |
| 151 'system': test.configuration.system.name, |
| 152 'vm_options': test.configuration.vmOptions, |
| 153 'use_sdk': test.configuration.useSdk, |
| 154 'builder_tag': test.configuration.builderTag |
| 155 }; |
| 156 |
164 var outcome = '${test.lastCommandOutput.result(test)}'; | 157 var outcome = '${test.lastCommandOutput.result(test)}'; |
165 var expectations = | 158 var expectations = |
166 test.expectedOutcomes.map((expectation) => "$expectation").toList(); | 159 test.expectedOutcomes.map((expectation) => "$expectation").toList(); |
167 | 160 |
168 var commandResults = []; | 161 var commandResults = []; |
169 double totalDuration = 0.0; | 162 double totalDuration = 0.0; |
170 for (var command in test.commands) { | 163 for (var command in test.commands) { |
171 var output = test.commandOutputs[command]; | 164 var output = test.commandOutputs[command]; |
172 if (output != null) { | 165 if (output != null) { |
173 double duration = output.time.inMicroseconds / 1000.0; | 166 double duration = output.time.inMicroseconds / 1000.0; |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
218 // | 211 // |
219 // For debugging purposes we need to archive the crashed binary as well. | 212 // For debugging purposes we need to archive the crashed binary as well. |
220 // | 213 // |
221 // To simplify the archiving code we simply copy binaries into current | 214 // To simplify the archiving code we simply copy binaries into current |
222 // folder next to core dumps and name them | 215 // folder next to core dumps and name them |
223 // `binary.${mode}_${arch}_${binary_name}`. | 216 // `binary.${mode}_${arch}_${binary_name}`. |
224 var binName = lastCommand.executable; | 217 var binName = lastCommand.executable; |
225 var binFile = new File(binName); | 218 var binFile = new File(binName); |
226 var binBaseName = new Path(binName).filename; | 219 var binBaseName = new Path(binName).filename; |
227 if (!archivedBinaries.containsKey(binName) && binFile.existsSync()) { | 220 if (!archivedBinaries.containsKey(binName) && binFile.existsSync()) { |
228 var mode = test.configuration['mode'] as String; | 221 var mode = test.configuration.mode.name; |
229 var arch = test.configuration['arch'] as String; | 222 var arch = test.configuration.architecture.name; |
230 var archived = "binary.${mode}_${arch}_${binBaseName}"; | 223 var archived = "binary.${mode}_${arch}_${binBaseName}"; |
231 TestUtils.copyFile(new Path(binName), new Path(archived)); | 224 TestUtils.copyFile(new Path(binName), new Path(archived)); |
232 archivedBinaries[binName] = archived; | 225 archivedBinaries[binName] = archived; |
233 } | 226 } |
234 | 227 |
235 if (archivedBinaries.containsKey(binName)) { | 228 if (archivedBinaries.containsKey(binName)) { |
236 // We have found and copied the binary. | 229 // We have found and copied the binary. |
237 RandomAccessFile unexpectedCrashesFile; | 230 RandomAccessFile unexpectedCrashesFile; |
238 try { | 231 try { |
239 unexpectedCrashesFile = | 232 unexpectedCrashesFile = |
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
434 | 427 |
435 print(_buildSummaryEnd(_failedTests)); | 428 print(_buildSummaryEnd(_failedTests)); |
436 } | 429 } |
437 } | 430 } |
438 } | 431 } |
439 } | 432 } |
440 | 433 |
441 class ProgressIndicator extends EventListener { | 434 class ProgressIndicator extends EventListener { |
442 ProgressIndicator(this._startTime); | 435 ProgressIndicator(this._startTime); |
443 | 436 |
444 static EventListener fromName( | 437 static EventListener fromProgress( |
445 String name, DateTime startTime, Formatter formatter) { | 438 Progress progress, DateTime startTime, Formatter formatter) { |
446 switch (name) { | 439 switch (progress) { |
447 case 'compact': | 440 case Progress.compact: |
448 return new CompactProgressIndicator(startTime, formatter); | 441 return new CompactProgressIndicator(startTime, formatter); |
449 case 'line': | 442 case Progress.line: |
450 return new LineProgressIndicator(); | 443 return new LineProgressIndicator(); |
451 case 'verbose': | 444 case Progress.verbose: |
452 return new VerboseProgressIndicator(startTime); | 445 return new VerboseProgressIndicator(startTime); |
453 case 'status': | 446 case Progress.status: |
454 return new ProgressIndicator(startTime); | 447 return new ProgressIndicator(startTime); |
455 case 'buildbot': | 448 case Progress.buildbot: |
456 return new BuildbotProgressIndicator(startTime); | 449 return new BuildbotProgressIndicator(startTime); |
457 default: | |
458 throw new ArgumentError('Unknown progress indicator "$name".'); | |
459 } | 450 } |
| 451 |
| 452 throw "unreachable"; |
460 } | 453 } |
461 | 454 |
462 void testAdded() { | 455 void testAdded() { |
463 _foundTests++; | 456 _foundTests++; |
464 } | 457 } |
465 | 458 |
466 void done(TestCase test) { | 459 void done(TestCase test) { |
467 if (test.unexpectedOutput) { | 460 if (test.unexpectedOutput) { |
468 _failedTests++; | 461 _failedTests++; |
469 } else { | 462 } else { |
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
605 if (test.commandOutputs.length != test.commands.length && | 598 if (test.commandOutputs.length != test.commands.length && |
606 !test.expectCompileError) { | 599 !test.expectCompileError) { |
607 output.add('Unexpected compile-time error.'); | 600 output.add('Unexpected compile-time error.'); |
608 } else { | 601 } else { |
609 if (test.expectCompileError) { | 602 if (test.expectCompileError) { |
610 output.add('Compile-time error expected.'); | 603 output.add('Compile-time error expected.'); |
611 } | 604 } |
612 if (test.hasRuntimeError) { | 605 if (test.hasRuntimeError) { |
613 output.add('Runtime error expected.'); | 606 output.add('Runtime error expected.'); |
614 } | 607 } |
615 if ((test.configuration['checked'] as bool) && test.isNegativeIfChecked) { | 608 if (test.configuration.isChecked && test.isNegativeIfChecked) { |
616 output.add('Dynamic type error expected.'); | 609 output.add('Dynamic type error expected.'); |
617 } | 610 } |
618 } | 611 } |
619 } | 612 } |
620 | 613 |
621 for (var i = 0; i < test.commands.length; i++) { | 614 for (var i = 0; i < test.commands.length; i++) { |
622 var command = test.commands[i]; | 615 var command = test.commands[i]; |
623 var commandOutput = test.commandOutputs[command]; | 616 var commandOutput = test.commandOutputs[command]; |
624 if (commandOutput != null) { | 617 if (commandOutput != null) { |
625 output.add("CommandOutput[${command.displayName}]:"); | 618 output.add("CommandOutput[${command.displayName}]:"); |
(...skipping 12 matching lines...) Expand all Loading... |
638 if (!commandOutput.stderr.isEmpty) { | 631 if (!commandOutput.stderr.isEmpty) { |
639 output.add(''); | 632 output.add(''); |
640 output.add('stderr:'); | 633 output.add('stderr:'); |
641 output.addAll(_linesWithoutCarriageReturn(commandOutput.stderr)); | 634 output.addAll(_linesWithoutCarriageReturn(commandOutput.stderr)); |
642 } | 635 } |
643 } | 636 } |
644 } | 637 } |
645 | 638 |
646 if (test is BrowserTestCase) { | 639 if (test is BrowserTestCase) { |
647 // Additional command for rerunning the steps locally after the fact. | 640 // Additional command for rerunning the steps locally after the fact. |
648 var command = (test.configuration["_servers_"] as TestingServers) | 641 var command = test.configuration.servers.httpServerCommandLine(); |
649 .httpServerCommandLine(); | |
650 output.add(''); | 642 output.add(''); |
651 output.add('To retest, run: $command'); | 643 output.add('To retest, run: $command'); |
652 } | 644 } |
653 | 645 |
654 for (var i = 0; i < test.commands.length; i++) { | 646 for (var i = 0; i < test.commands.length; i++) { |
655 var command = test.commands[i]; | 647 var command = test.commands[i]; |
656 var commandOutput = test.commandOutputs[command]; | 648 var commandOutput = test.commandOutputs[command]; |
657 output.add(''); | 649 output.add(''); |
658 output.add('Command[${command.displayName}]: $command'); | 650 output.add('Command[${command.displayName}]: $command'); |
659 if (commandOutput != null) { | 651 if (commandOutput != null) { |
660 output.add('Took ${commandOutput.time}'); | 652 output.add('Took ${commandOutput.time}'); |
661 } else { | 653 } else { |
662 output.add('Did not run'); | 654 output.add('Did not run'); |
663 } | 655 } |
664 } | 656 } |
665 | 657 |
666 var arguments = ['python', 'tools/test.py']; | 658 var arguments = ['python', 'tools/test.py']; |
667 arguments | 659 arguments.addAll(test.configuration.reproducingArguments); |
668 .addAll(test.configuration['_reproducing_arguments_'] as List<String>); | |
669 arguments.add(test.displayName); | 660 arguments.add(test.displayName); |
670 var testPyCommandline = arguments.map(escapeCommandLineArgument).join(' '); | 661 var testPyCommandline = arguments.map(escapeCommandLineArgument).join(' '); |
671 | 662 |
672 output.add(''); | 663 output.add(''); |
673 output.add('Short reproduction command (experimental):'); | 664 output.add('Short reproduction command (experimental):'); |
674 output.add(" $testPyCommandline"); | 665 output.add(" $testPyCommandline"); |
675 return output; | 666 return output; |
676 } | 667 } |
677 | 668 |
678 String _buildSummaryEnd(int failedTests) { | 669 String _buildSummaryEnd(int failedTests) { |
679 if (failedTests == 0) { | 670 if (failedTests == 0) { |
680 return '\n===\n=== All tests succeeded\n===\n'; | 671 return '\n===\n=== All tests succeeded\n===\n'; |
681 } else { | 672 } else { |
682 var pluralSuffix = failedTests != 1 ? 's' : ''; | 673 var pluralSuffix = failedTests != 1 ? 's' : ''; |
683 return '\n===\n=== ${failedTests} test$pluralSuffix failed\n===\n'; | 674 return '\n===\n=== ${failedTests} test$pluralSuffix failed\n===\n'; |
684 } | 675 } |
685 } | 676 } |
OLD | NEW |