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

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

Issue 3005013002: Added json result of test output to output debug directory. (Closed)
Patch Set: Created 3 years, 3 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
OLDNEW
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 import 'dart:convert';
6 import 'dart:io'; 6 import 'dart:io';
7 7
8 import "package:status_file/expectation.dart"; 8 import "package:status_file/expectation.dart";
9 9
10 import 'command.dart'; 10 import 'command.dart';
11 import 'command_output.dart'; 11 import 'command_output.dart';
12 import 'configuration.dart'; 12 import 'configuration.dart';
13 import 'path.dart'; 13 import 'path.dart';
14 import 'summary_report.dart'; 14 import 'summary_report.dart';
15 import 'test_runner.dart'; 15 import 'test_runner.dart';
(...skipping 28 matching lines...) Expand all
44 String failed(String message) => _color(message, _red); 44 String failed(String message) => _color(message, _red);
45 45
46 static String _color(String message, int color) => 46 static String _color(String message, int color) =>
47 "$_escape[${color}m$message$_escape[0m"; 47 "$_escape[${color}m$message$_escape[0m";
48 } 48 }
49 49
50 class EventListener { 50 class EventListener {
51 void testAdded() {} 51 void testAdded() {}
52 void done(TestCase test) {} 52 void done(TestCase test) {}
53 void allTestsKnown() {} 53 void allTestsKnown() {}
54 void allDone() {} 54 void allDone(Configuration configuration) {}
55 } 55 }
56 56
57 class ExitCodeSetter extends EventListener { 57 class ExitCodeSetter extends EventListener {
58 void done(TestCase test) { 58 void done(TestCase test) {
59 if (test.unexpectedOutput) { 59 if (test.unexpectedOutput) {
60 exitCode = 1; 60 exitCode = 1;
61 } 61 }
62 } 62 }
63 } 63 }
64 64
65 class IgnoredTestMonitor extends EventListener { 65 class IgnoredTestMonitor extends EventListener {
66 static final int maxIgnored = 10; 66 static final int maxIgnored = 10;
67 67
68 int countIgnored = 0; 68 int countIgnored = 0;
69 69
70 void done(TestCase test) { 70 void done(TestCase test) {
71 if (test.lastCommandOutput.result(test) == Expectation.ignore) { 71 if (test.lastCommandOutput.result(test) == Expectation.ignore) {
72 countIgnored++; 72 countIgnored++;
73 if (countIgnored > maxIgnored) { 73 if (countIgnored > maxIgnored) {
74 print("/nMore than $maxIgnored tests were ignored due to flakes in"); 74 print("/nMore than $maxIgnored tests were ignored due to flakes in");
75 print("the test infrastructure. Notify whesse@google.com."); 75 print("the test infrastructure. Notify whesse@google.com.");
76 print("Output of the last ignored test was:"); 76 print("Output of the last ignored test was:");
77 print(_buildFailureOutput(test)); 77 print(_buildFailureOutput(test));
78 exit(1); 78 exit(1);
79 } 79 }
80 } 80 }
81 } 81 }
82 82
83 void allDone() { 83 void allDone(Configuration configuration) {
84 if (countIgnored > 0) { 84 if (countIgnored > 0) {
85 print("Ignored $countIgnored tests due to flaky infrastructure"); 85 print("Ignored $countIgnored tests due to flaky infrastructure");
86 } 86 }
87 } 87 }
88 } 88 }
89 89
90 class FlakyLogWriter extends EventListener { 90 class FlakyLogWriter extends EventListener {
91 void done(TestCase test) { 91 void done(TestCase test) {
92 if (test.isFlaky && test.result != Expectation.pass) { 92 if (test.isFlaky && test.result != Expectation.pass) {
93 var buf = new StringBuffer(); 93 var buf = new StringBuffer();
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
133 * duration: 200.2, 133 * duration: 200.2,
134 * }, 134 * },
135 * ], 135 * ],
136 * } 136 * }
137 * }, 137 * },
138 */ 138 */
139 IOSink _sink; 139 IOSink _sink;
140 140
141 void done(TestCase test) { 141 void done(TestCase test) {
142 var name = test.displayName; 142 var name = test.displayName;
143 var configuration = {
144 'mode': test.configuration.mode.name,
145 'arch': test.configuration.architecture.name,
146 'compiler': test.configuration.compiler.name,
147 'runtime': test.configuration.runtime.name,
148 'checked': test.configuration.isChecked,
149 'strong': test.configuration.isStrong,
150 'host_checked': test.configuration.isHostChecked,
151 'minified': test.configuration.isMinified,
152 'csp': test.configuration.isCsp,
153 'system': test.configuration.system.name,
154 'vm_options': test.configuration.vmOptions,
155 'use_sdk': test.configuration.useSdk,
156 'builder_tag': test.configuration.builderTag
157 };
158
159 var outcome = '${test.lastCommandOutput.result(test)}'; 143 var outcome = '${test.lastCommandOutput.result(test)}';
160 var expectations = 144 var expectations =
161 test.expectedOutcomes.map((expectation) => "$expectation").toList(); 145 test.expectedOutcomes.map((expectation) => "$expectation").toList();
162 146
163 var commandResults = []; 147 var commandResults = [];
164 double totalDuration = 0.0; 148 double totalDuration = 0.0;
165 for (var command in test.commands) { 149 for (var command in test.commands) {
166 var output = test.commandOutputs[command]; 150 var output = test.commandOutputs[command];
167 if (output != null) { 151 if (output != null) {
168 double duration = output.time.inMicroseconds / 1000.0; 152 double duration = output.time.inMicroseconds / 1000.0;
169 totalDuration += duration; 153 totalDuration += duration;
170 commandResults.add({ 154 commandResults.add({
171 'name': command.displayName, 155 'name': command.displayName,
172 'duration': duration, 156 'duration': duration,
173 }); 157 });
174 } 158 }
175 } 159 }
176 _writeTestOutcomeRecord({ 160 _writeTestOutcomeRecord({
177 'name': name, 161 'name': name,
178 'configuration': configuration, 162 'configuration': test.configuration.toSummaryMap(),
179 'test_result': { 163 'test_result': {
180 'outcome': outcome, 164 'outcome': outcome,
181 'expected_outcomes': expectations, 165 'expected_outcomes': expectations,
182 'duration': totalDuration, 166 'duration': totalDuration,
183 'command_results': commandResults, 167 'command_results': commandResults,
184 }, 168 },
185 }); 169 });
186 } 170 }
187 171
188 void allDone() { 172 void allDone(Configuration configuration) {
189 if (_sink != null) _sink.close(); 173 if (_sink != null) _sink.close();
190 } 174 }
191 175
192 void _writeTestOutcomeRecord(Map record) { 176 void _writeTestOutcomeRecord(Map record) {
177 // TODO(mkroghj) change the location of this file
178 // to be in the debug_output_directory
179 // if the current location is not used.
193 if (_sink == null) { 180 if (_sink == null) {
194 _sink = new File(TestUtils.testOutcomeFileName) 181 _sink = new File(TestUtils.testOutcomeFileName)
195 .openWrite(mode: FileMode.APPEND); 182 .openWrite(mode: FileMode.APPEND);
196 } 183 }
197 _sink.write("${JSON.encode(record)}\n"); 184 _sink.write("${JSON.encode(record)}\n");
198 } 185 }
199 } 186 }
200 187
201 class UnexpectedCrashLogger extends EventListener { 188 class UnexpectedCrashLogger extends EventListener {
202 final archivedBinaries = <String, String>{}; 189 final archivedBinaries = <String, String>{};
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
276 263
277 void done(TestCase testCase) { 264 void done(TestCase testCase) {
278 for (var commandOutput in testCase.commandOutputs.values) { 265 for (var commandOutput in testCase.commandOutputs.values) {
279 var command = commandOutput.command; 266 var command = commandOutput.command;
280 _commandOutputs.add(commandOutput); 267 _commandOutputs.add(commandOutput);
281 _command2testCases.putIfAbsent(command, () => <TestCase>[]); 268 _command2testCases.putIfAbsent(command, () => <TestCase>[]);
282 _command2testCases[command].add(testCase); 269 _command2testCases[command].add(testCase);
283 } 270 }
284 } 271 }
285 272
286 void allDone() { 273 void allDone(Configuration configuration) {
287 Duration d = (new DateTime.now()).difference(_startTime); 274 Duration d = (new DateTime.now()).difference(_startTime);
288 print('\n--- Total time: ${_timeString(d)} ---'); 275 print('\n--- Total time: ${_timeString(d)} ---');
289 var outputs = _commandOutputs.toList(); 276 var outputs = _commandOutputs.toList();
290 outputs.sort((a, b) { 277 outputs.sort((a, b) {
291 return b.time.inMilliseconds - a.time.inMilliseconds; 278 return b.time.inMilliseconds - a.time.inMilliseconds;
292 }); 279 });
293 for (int i = 0; i < 20 && i < outputs.length; i++) { 280 for (int i = 0; i < 20 && i < outputs.length; i++) {
294 var commandOutput = outputs[i]; 281 var commandOutput = outputs[i];
295 var command = commandOutput.command; 282 var command = commandOutput.command;
296 var testCases = _command2testCases[command]; 283 var testCases = _command2testCases[command];
(...skipping 12 matching lines...) Expand all
309 class StatusFileUpdatePrinter extends EventListener { 296 class StatusFileUpdatePrinter extends EventListener {
310 var statusToConfigs = new Map<String, List<String>>(); 297 var statusToConfigs = new Map<String, List<String>>();
311 var _failureSummary = <String>[]; 298 var _failureSummary = <String>[];
312 299
313 void done(TestCase test) { 300 void done(TestCase test) {
314 if (test.unexpectedOutput) { 301 if (test.unexpectedOutput) {
315 _printFailureOutput(test); 302 _printFailureOutput(test);
316 } 303 }
317 } 304 }
318 305
319 void allDone() { 306 void allDone(Configuration configuration) {
320 _printFailureSummary(); 307 _printFailureSummary();
321 } 308 }
322 309
323 void _printFailureOutput(TestCase test) { 310 void _printFailureOutput(TestCase test) {
324 String status = '${test.displayName}: ${test.result}'; 311 String status = '${test.displayName}: ${test.result}';
325 List<String> configs = 312 List<String> configs =
326 statusToConfigs.putIfAbsent(status, () => <String>[]); 313 statusToConfigs.putIfAbsent(status, () => <String>[]);
327 configs.add(test.configurationString); 314 configs.add(test.configurationString);
328 if (test.lastCommandOutput.hasTimedOut) { 315 if (test.lastCommandOutput.hasTimedOut) {
329 print('\n${test.displayName} timed out on ${test.configurationString}'); 316 print('\n${test.displayName} timed out on ${test.configurationString}');
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
372 359
373 class SkippedCompilationsPrinter extends EventListener { 360 class SkippedCompilationsPrinter extends EventListener {
374 int _skippedCompilations = 0; 361 int _skippedCompilations = 0;
375 362
376 void done(TestCase test) { 363 void done(TestCase test) {
377 for (var commandOutput in test.commandOutputs.values) { 364 for (var commandOutput in test.commandOutputs.values) {
378 if (commandOutput.compilationSkipped) _skippedCompilations++; 365 if (commandOutput.compilationSkipped) _skippedCompilations++;
379 } 366 }
380 } 367 }
381 368
382 void allDone() { 369 void allDone(Configuration configuration) {
383 if (_skippedCompilations > 0) { 370 if (_skippedCompilations > 0) {
384 print('\n$_skippedCompilations compilations were skipped because ' 371 print('\n$_skippedCompilations compilations were skipped because '
385 'the previous output was already up to date.\n'); 372 'the previous output was already up to date.\n');
386 } 373 }
387 } 374 }
388 } 375 }
389 376
390 class LineProgressIndicator extends EventListener { 377 class LineProgressIndicator extends EventListener {
391 void done(TestCase test) { 378 void done(TestCase test) {
392 var status = 'pass'; 379 var status = 'pass';
(...skipping 20 matching lines...) Expand all
413 print(line); 400 print(line);
414 } 401 }
415 print(''); 402 print('');
416 if (_printSummary) { 403 if (_printSummary) {
417 _failureSummary.addAll(lines); 404 _failureSummary.addAll(lines);
418 _failureSummary.add(''); 405 _failureSummary.add('');
419 } 406 }
420 } 407 }
421 } 408 }
422 409
423 void allDone() { 410 void allDone(Configuration configuration) {
424 if (_printSummary) { 411 if (_printSummary) {
425 if (!_failureSummary.isEmpty) { 412 if (!_failureSummary.isEmpty) {
426 print('\n=== Failure summary:\n'); 413 print('\n=== Failure summary:\n');
427 for (var line in _failureSummary) { 414 for (var line in _failureSummary) {
428 print(line); 415 print(line);
429 } 416 }
430 print(''); 417 print('');
431 418
432 print(_buildSummaryEnd(_failedTests)); 419 print(_buildSummaryEnd(_failedTests));
433 } 420 }
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
480 int _foundTests = 0; 467 int _foundTests = 0;
481 int _passedTests = 0; 468 int _passedTests = 0;
482 int _failedTests = 0; 469 int _failedTests = 0;
483 bool _allTestsKnown = false; 470 bool _allTestsKnown = false;
484 DateTime _startTime; 471 DateTime _startTime;
485 } 472 }
486 473
487 abstract class CompactIndicator extends ProgressIndicator { 474 abstract class CompactIndicator extends ProgressIndicator {
488 CompactIndicator(DateTime startTime) : super(startTime); 475 CompactIndicator(DateTime startTime) : super(startTime);
489 476
490 void allDone() { 477 void allDone(Configuration configuration) {
491 if (_failedTests > 0) { 478 if (_failedTests > 0) {
492 // We may have printed many failure logs, so reprint the summary data. 479 // We may have printed many failure logs, so reprint the summary data.
493 _printProgress(); 480 _printProgress();
494 } 481 }
495 print(''); 482 print('');
496 } 483 }
497 484
498 void _printDoneProgress(TestCase test) => _printProgress(); 485 void _printDoneProgress(TestCase test) => _printProgress();
499 486
500 void _printProgress(); 487 void _printProgress();
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
548 var status = 'pass'; 535 var status = 'pass';
549 if (test.unexpectedOutput) { 536 if (test.unexpectedOutput) {
550 status = 'fail'; 537 status = 'fail';
551 } 538 }
552 var percent = ((_completedTests() / _foundTests) * 100).toInt().toString(); 539 var percent = ((_completedTests() / _foundTests) * 100).toInt().toString();
553 print('Done ${test.configurationString} ${test.displayName}: $status'); 540 print('Done ${test.configurationString} ${test.displayName}: $status');
554 print('@@@STEP_CLEAR@@@'); 541 print('@@@STEP_CLEAR@@@');
555 print('@@@STEP_TEXT@ $percent% +$_passedTests -$_failedTests @@@'); 542 print('@@@STEP_TEXT@ $percent% +$_passedTests -$_failedTests @@@');
556 } 543 }
557 544
558 void allDone() { 545 void allDone(Configuration configuration) {
559 if (!_failureSummary.isEmpty) { 546 if (!_failureSummary.isEmpty) {
560 print('@@@STEP_FAILURE@@@'); 547 print('@@@STEP_FAILURE@@@');
561 if (stepName != null) { 548 if (stepName != null) {
562 print('@@@BUILD_STEP $stepName failures@@@'); 549 print('@@@BUILD_STEP $stepName failures@@@');
563 } 550 }
564 for (String line in _failureSummary) { 551 for (String line in _failureSummary) {
565 print(line); 552 print(line);
566 } 553 }
567 print(''); 554 print('');
568 } 555 }
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
671 } 658 }
672 659
673 String _buildSummaryEnd(int failedTests) { 660 String _buildSummaryEnd(int failedTests) {
674 if (failedTests == 0) { 661 if (failedTests == 0) {
675 return '\n===\n=== All tests succeeded\n===\n'; 662 return '\n===\n=== All tests succeeded\n===\n';
676 } else { 663 } else {
677 var pluralSuffix = failedTests != 1 ? 's' : ''; 664 var pluralSuffix = failedTests != 1 ? 's' : '';
678 return '\n===\n=== ${failedTests} test$pluralSuffix failed\n===\n'; 665 return '\n===\n=== ${failedTests} test$pluralSuffix failed\n===\n';
679 } 666 }
680 } 667 }
668
669 class TestResultLogWriter extends EventListener {
670 Map<String, Map> _configurations = {};
671 List<Map> _results = [];
672
673 void done(TestCase test) {
674 // We try to find an existing configuration, so as to not duplicate this
675 // for each test.
676 var thisConf = test.configuration.toSummaryMap();
Bill Hesse 2017/09/01 11:56:13 Make toSummaryMap return a cached object, that onl
mkroghj 2017/09/02 09:40:22 The reason why I chose it was because that is the
Bill Hesse 2017/09/04 07:49:59 Yes. It is tricky to make each configuration retu
677 String key = _configurations.keys.firstWhere(
678 (key) => areSummaryMapsEqual(_configurations[key], thisConf),
679 orElse: () {
680 var newKey = "conf${_configurations.length + 1}";
681 _configurations[newKey] = thisConf;
682 return newKey;
683 });
684 _results.add({
685 'configuration': key,
686 'name': test.displayName,
687 'commands': test.commands.map((command) {
Bill Hesse 2017/09/01 11:56:13 You could move the computation of this list outsid
mkroghj 2017/09/04 10:43:34 Done.
688 var output = test.commandOutputs[command];
689 if (output != null) {
690 var outputMap = {
691 'name': command.displayName,
692 'exitCode': output.exitCode,
693 'compilationSkipped': output.compilationSkipped,
694 'timeout': output.hasTimedOut,
695 'duration': output.time.inMilliseconds
696 };
697 if (test.unexpectedOutput) {
Bill Hesse 2017/09/01 11:56:13 I thought the whole point here was that we wouldn'
mkroghj 2017/09/02 09:40:22 I think unexpectedOutput checks for isCrash or isF
698 if (!output.stdout.isEmpty) {
699 outputMap["stdout"] = encodeStringForJson(
700 _linesWithoutCarriageReturn(output.stdout).join('\n'));
701 }
702 if (!output.stderr.isEmpty) {
703 outputMap["stderr"] = encodeStringForJson(
704 _linesWithoutCarriageReturn(output.stderr).join('\n'));
705 }
706 }
707 return outputMap;
708 } else {
709 return {'name': command.displayName};
Bill Hesse 2017/09/01 11:56:13 Put this up after "if (output == null)", then you
mkroghj 2017/09/02 09:40:22 I don't think I have an output == null test somewh
Bill Hesse 2017/09/04 07:49:59 I meant that you should reverse the test above, pu
710 }
711 }).toList()
712 });
713 }
714
715 String encodeStringForJson(String str) => BASE64.encode(UTF8.encode(str));
716
717 void allDone(Configuration configuration) {
718 var path = new Path(configuration.debugOutputDirectory);
Bill Hesse 2017/09/01 11:56:13 Can you use file URLs here? We don't want new cod
mkroghj 2017/09/02 09:40:22 The test-runner owns a Configuration _globalConfig
719 path = path.append(TestUtils.testResultFileName);
720 String fullPath = path.toNativePath();
721 var file = new File(fullPath);
722 file.createSync(recursive: true);
723 file.writeAsStringSync(
724 JSON.encode({'configurations': _configurations, 'results': _results}));
725 }
726
727 bool areSummaryMapsEqual(Map map1, Map map2) {
Bill Hesse 2017/09/01 11:56:13 Shouldn't be needed.
728 return map1.keys
729 .every((key) => map2.containsKey(key) && map1[key] == map2[key]);
730 }
731 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698