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