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

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

Issue 12302016: Refactoring of ProgressIndicator (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 9 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 | Annotate | Revision Log
« no previous file with comments | « tools/test-runtime.dart ('k') | tools/testing/dart/test_runner.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 library test_progress; 5 library test_progress;
6 6
7 import "dart:io"; 7 import "dart:io";
8 import "dart:io" as io; 8 import "dart:io" as io;
9 import "http_server.dart" as http_server; 9 import "http_server.dart" as http_server;
10 import "status_file_parser.dart"; 10 import "status_file_parser.dart";
11 import "test_runner.dart"; 11 import "test_runner.dart";
12 import "test_suite.dart"; 12 import "test_suite.dart";
13 import "utils.dart"; 13 import "utils.dart";
14 14
15 class ProgressIndicator { 15 String _pad(String s, int length) {
16 ProgressIndicator(this._startTime, this._printTiming) 16 StringBuffer buffer = new StringBuffer();
17 : _tests = [], _failureSummary = []; 17 for (int i = s.length; i < length; i++) {
18 buffer.add(' ');
19 }
20 buffer.add(s);
21 return buffer.toString();
22 }
18 23
19 factory ProgressIndicator.fromName(String name, 24 String _padTime(int time) {
20 Date startTime, 25 if (time == 0) {
21 bool printTiming) { 26 return '00';
22 switch (name) { 27 } else if (time < 10) {
23 case 'compact': 28 return '0$time';
24 return new CompactProgressIndicator(startTime, printTiming); 29 } else {
25 case 'color': 30 return '$time';
26 return new ColorProgressIndicator(startTime, printTiming); 31 }
27 case 'line': 32 }
28 return new LineProgressIndicator(startTime, printTiming); 33
29 case 'verbose': 34 String _timeString(Duration d) {
30 return new VerboseProgressIndicator(startTime, printTiming); 35 var min = d.inMinutes;
31 case 'silent': 36 var sec = d.inSeconds % 60;
32 return new SilentProgressIndicator(startTime, printTiming); 37 return '${_padTime(min)}:${_padTime(sec)}';
33 case 'status': 38 }
34 return new StatusProgressIndicator(startTime, printTiming); 39
35 case 'buildbot': 40 class Formatter {
36 return new BuildbotProgressIndicator(startTime, printTiming); 41 const Formatter();
37 case 'diff': 42 String passed(msg) => msg;
38 return new DiffProgressIndicator(startTime, printTiming); 43 String failed(msg) => msg;
39 default: 44 }
40 assert(false); 45
41 break; 46 class ColorFormatter extends Formatter {
47 static int BOLD = 1;
48 static int GREEN = 32;
49 static int RED = 31;
50 static int NONE = 0;
51 static String ESCAPE = decodeUtf8([27]);
52
53 String passed(String msg) => _color(msg, GREEN);
54 String failed(String msg) => _color(msg, RED);
55
56 static String _color(String msg, int color) {
57 return "$ESCAPE[${color}m$msg$ESCAPE[0m";
58 }
59 }
60
61
62 List<String> _buildFailureOutput(TestCase test,
63 [Formatter formatter = const Formatter()]) {
64 List<String> output = new List<String>();
65 output.add('');
66 output.add(formatter.failed('FAILED: ${test.configurationString}'
67 ' ${test.displayName}'));
68 StringBuffer expected = new StringBuffer();
69 expected.add('Expected: ');
70 for (var expectation in test.expectedOutcomes) {
71 expected.add('$expectation ');
72 }
73 output.add(expected.toString());
74 output.add('Actual: ${test.lastCommandOutput.result}');
75 if (!test.lastCommandOutput.hasTimedOut && test.info != null) {
76 if (test.lastCommandOutput.incomplete && !test.info.hasCompileError) {
77 output.add('Unexpected compile-time error.');
78 } else {
79 if (test.info.hasCompileError) {
80 output.add('Compile-time error expected.');
81 }
82 if (test.info.hasRuntimeError) {
83 output.add('Runtime error expected.');
84 }
42 } 85 }
43 } 86 }
87 if (!test.lastCommandOutput.diagnostics.isEmpty) {
88 String prefix = 'diagnostics:';
89 for (var s in test.lastCommandOutput.diagnostics) {
90 output.add('$prefix ${s}');
91 prefix = ' ';
92 }
93 }
94 if (!test.lastCommandOutput.stdout.isEmpty) {
95 output.add('');
96 output.add('stdout:');
97 if (test.lastCommandOutput.command.isPixelTest) {
98 output.add('DRT pixel test failed! stdout is not printed because it '
99 'contains binary data!');
100 } else {
101 output.add(decodeUtf8(test.lastCommandOutput.stdout));
102 }
103 }
104 if (!test.lastCommandOutput.stderr.isEmpty) {
105 output.add('');
106 output.add('stderr:');
107 output.add(decodeUtf8(test.lastCommandOutput.stderr));
108 }
109 if (test is BrowserTestCase) {
110 // Additional command for rerunning the steps locally after the fact.
111 var command =
112 test.configuration["_servers_"].httpServerCommandline();
113 output.add('To retest, run: $command');
114 }
115 for (Command c in test.commands) {
116 output.add('');
117 String message = (c == test.commands.last
118 ? "Command line" : "Compilation command");
119 output.add('$message: $c');
120 }
121 return output;
122 }
44 123
45 void testAdded() { _foundTests++; }
46 124
47 void start(TestCase test) { 125 class EventListener {
48 _printStartProgress(test); 126 void testAdded() { }
127 void start(TestCase test) { }
128 void done(TestCase test) { }
129 void allTestsKnown() { }
130 void allDone() { }
131 }
132
133 class ExitCodeSetter extends EventListener {
134 void done(TestCase test) {
135 if (test.lastCommandOutput.unexpectedOutput) {
136 io.exitCode = 1;
137 }
49 } 138 }
139 }
50 140
141 class FlakyLogWriter extends EventListener {
51 void done(TestCase test) { 142 void done(TestCase test) {
52 if (test.isFlaky && test.lastCommandOutput.result != PASS) { 143 if (test.isFlaky && test.lastCommandOutput.result != PASS) {
53 var buf = new StringBuffer(); 144 var buf = new StringBuffer();
54 for (var l in _buildFailureOutput(test)) { 145 for (var l in _buildFailureOutput(test)) {
55 buf.add("$l\n"); 146 buf.add("$l\n");
56 } 147 }
57 _appendToFlakyFile(buf.toString()); 148 _appendToFlakyFile(buf.toString());
58 } 149 }
150 }
151
152 void _appendToFlakyFile(String msg) {
153 var file = new File(TestUtils.flakyFileName());
154 var fd = file.openSync(FileMode.APPEND);
155 fd.writeStringSync(msg);
156 fd.closeSync();
157 }
158 }
159
160 class SummaryPrinter extends EventListener {
161 void allTestsKnown() {
162 if (SummaryReport.total > 0) {
163 SummaryReport.printReport();
164 }
165 }
166 }
167
168 class TimingPrinter extends EventListener {
169 List<TestCase> _tests = <TestCase>[];
170 Date _startTime;
171
172 TimingPrinter(this._startTime);
173
174 void done(TestCase testCase) {
175 _tests.add(testCase);
176 }
177
178 void allDone() {
179 // TODO: We should take all the commands into account
180 Duration d = (new Date.now()).difference(_startTime);
181 print('\n--- Total time: ${_timeString(d)} ---');
182 _tests.sort((a, b) {
183 Duration aDuration = a.lastCommandOutput.time;
184 Duration bDuration = b.lastCommandOutput.time;
185 return bDuration.inMilliseconds - aDuration.inMilliseconds;
186 });
187 for (int i = 0; i < 20 && i < _tests.length; i++) {
188 var name = _tests[i].displayName;
189 var duration = _tests[i].lastCommandOutput.time;
190 var configuration = _tests[i].configurationString;
191 print('${duration} - $configuration $name');
192 }
193 }
194 }
195
196 class StatusFileUpdatePrinter extends EventListener {
197 var statusToConfigs = new Map<String, List<String>>();
198 var _failureSummary = <String>[];
199
200 void done(TestCase test) {
201 if (test.lastCommandOutput.unexpectedOutput) {
202 _printFailureOutput(test);
203 }
204 }
205
206 void allDone() {
207 _printFailureSummary();
208 }
209
210
211 void _printFailureOutput(TestCase test) {
212 String status = '${test.displayName}: ${test.lastCommandOutput.result}';
213 List<String> configs =
214 statusToConfigs.putIfAbsent(status, () => <String>[]);
215 configs.add(test.configurationString);
216 if (test.lastCommandOutput.hasTimedOut) {
217 print('\n${test.displayName} timed out on ${test.configurationString}');
218 }
219 }
220
221 String _extractRuntime(String configuration) {
222 // Extract runtime from a configuration, for example,
223 // 'none-vm-checked release_ia32'.
224 List<String> runtime = configuration.split(' ')[0].split('-');
225 return '${runtime[0]}-${runtime[1]}';
226 }
227
228 void _printFailureSummary() {
229 var groupedStatuses = new Map<String, List<String>>();
230 statusToConfigs.forEach((String status, List<String> configs) {
231 var runtimeToConfiguration = new Map<String, List<String>>();
232 for (String config in configs) {
233 String runtime = _extractRuntime(config);
234 var runtimeConfigs =
235 runtimeToConfiguration.putIfAbsent(runtime, () => <String>[]);
236 runtimeConfigs.add(config);
237 }
238 runtimeToConfiguration.forEach((String runtime,
239 List<String> runtimeConfigs) {
240 runtimeConfigs.sort((a, b) => a.compareTo(b));
241 List<String> statuses =
242 groupedStatuses.putIfAbsent('$runtime: $runtimeConfigs',
243 () => <String>[]);
244 statuses.add(status);
245 });
246 });
247
248 print('\n\nNecessary status file updates:');
249 groupedStatuses.forEach((String config, List<String> statuses) {
250 print('');
251 print('$config:');
252 statuses.sort((a, b) => a.compareTo(b));
253 for (String status in statuses) {
254 print(' $status');
255 }
256 });
257 }
258 }
259
260 class SkippedCompilationsPrinter extends EventListener {
261 int _skippedCompilations = 0;
262
263 void done(TestCase test) {
59 for (var commandOutput in test.commandOutputs.values) { 264 for (var commandOutput in test.commandOutputs.values) {
60 if (commandOutput.compilationSkipped) 265 if (commandOutput.compilationSkipped)
61 _skippedCompilations++; 266 _skippedCompilations++;
62 } 267 }
63 268 }
64 if (test.lastCommandOutput.unexpectedOutput) { 269
65 _failedTests++; 270 void allDone() {
66 _printFailureOutput(test);
67 } else {
68 _passedTests++;
69 }
70 _printDoneProgress(test);
71 // If we need to print timing information we hold on to all completed
72 // tests.
73 if (_printTiming) _tests.add(test);
74 }
75
76 void allTestsKnown() {
77 if (!_allTestsKnown) SummaryReport.printReport();
78 _allTestsKnown = true;
79 }
80
81 void _printSkippedCompilationInfo() {
82 if (_skippedCompilations > 0) { 271 if (_skippedCompilations > 0) {
83 print('\n$_skippedCompilations compilations were skipped because ' 272 print('\n$_skippedCompilations compilations were skipped because '
84 'the previous output was already up to date\n'); 273 'the previous output was already up to date\n');
85 } 274 }
86 } 275 }
87 276 }
88 void _printTimingInformation() { 277
89 if (_printTiming) { 278 class LeftOverTempDirPrinter extends EventListener {
90 // TODO: We should take all the commands into account 279 final MIN_NUMBER_OF_TEMP_DIRS = 50;
91 Duration d = (new Date.now()).difference(_startTime); 280
92 print('\n--- Total time: ${_timeString(d)} ---'); 281 Path _tempDir() {
93 _tests.sort((a, b) { 282 // Dir will be located in the system temporary directory.
94 Duration aDuration = a.lastCommandOutput.time; 283 var dir = new Directory('').createTempSync();
95 Duration bDuration = b.lastCommandOutput.time; 284 var path = new Path(dir.path).directoryPath;
96 return bDuration.inMilliseconds - aDuration.inMilliseconds; 285 dir.deleteSync();
97 }); 286 return path;
98 for (int i = 0; i < 20 && i < _tests.length; i++) { 287 }
99 var name = _tests[i].displayName; 288
100 var duration = _tests[i].lastCommandOutput.time; 289 void allDone() {
101 var configuration = _tests[i].configurationString; 290 var tempDirs = [];
102 print('${duration} - $configuration $name'); 291 var systemTempDir = _tempDir();
103 } 292 var lister = new Directory.fromPath(systemTempDir).list();
293 lister.onDir = (path) => tempDirs.add(path);
294 lister.onDone = (_) {
295 if (tempDirs.length > MIN_NUMBER_OF_TEMP_DIRS) {
296 DebugLogger.warning("There are ${tempDirs.length} directories "
297 "in the system tempdir ('$systemTempDir')! "
298 "Maybe left over directories?\n");
299 }
300 };
301 }
302 }
303
304 class LineProgressIndicator extends EventListener {
305 void done(TestCase test) {
306 var status = 'pass';
307 if (test.lastCommandOutput.unexpectedOutput) {
308 status = 'fail';
309 }
310 print('Done ${test.configurationString} ${test.displayName}: $status');
311 }
312 }
313
314 class TestFailurePrinter extends EventListener {
315 var _failureSummary = <String>[];
316 var _formatter;
317
318 TestFailurePrinter([this._formatter = const Formatter()]);
319
320 void done(TestCase test) {
321 if (test.lastCommandOutput.unexpectedOutput) {
322 _printFailureOutput(test);
104 } 323 }
105 } 324 }
106 325
107 void allDone() { 326 void allDone() {
108 _printFailureSummary(); 327 _printFailureSummary();
109 _printStatus(); 328 }
110 _printSkippedCompilationInfo();
111 _printTimingInformation();
112 stdout.close();
113 stderr.close();
114 if (_failedTests > 0) {
115 io.exitCode = 1;
116 }
117 }
118
119 void _printStartProgress(TestCase test) {}
120 void _printDoneProgress(TestCase test) {}
121
122 String _pad(String s, int length) {
123 StringBuffer buffer = new StringBuffer();
124 for (int i = s.length; i < length; i++) {
125 buffer.add(' ');
126 }
127 buffer.add(s);
128 return buffer.toString();
129 }
130
131 String _padTime(int time) {
132 if (time == 0) {
133 return '00';
134 } else if (time < 10) {
135 return '0$time';
136 } else {
137 return '$time';
138 }
139 }
140
141 String _timeString(Duration d) {
142 var min = d.inMinutes;
143 var sec = d.inSeconds % 60;
144 return '${_padTime(min)}:${_padTime(sec)}';
145 }
146
147 String _header(String header) => header;
148 329
149 void _printFailureOutput(TestCase test) { 330 void _printFailureOutput(TestCase test) {
150 var failureOutput = _buildFailureOutput(test); 331 var failureOutput = _buildFailureOutput(test, _formatter);
151 for (var line in failureOutput) { 332 for (var line in failureOutput) {
152 print(line); 333 print(line);
153 } 334 }
335 print('');
154 _failureSummary.addAll(failureOutput); 336 _failureSummary.addAll(failureOutput);
155 } 337 }
156 338
157 List<String> _buildFailureOutput(TestCase test) {
158 List<String> output = new List<String>();
159 output.add('');
160 output.add(_header('FAILED: ${test.configurationString}'
161 ' ${test.displayName}'));
162 StringBuffer expected = new StringBuffer();
163 expected.add('Expected: ');
164 for (var expectation in test.expectedOutcomes) {
165 expected.add('$expectation ');
166 }
167 output.add(expected.toString());
168 output.add('Actual: ${test.lastCommandOutput.result}');
169 if (!test.lastCommandOutput.hasTimedOut && test.info != null) {
170 if (test.lastCommandOutput.incomplete && !test.info.hasCompileError) {
171 output.add('Unexpected compile-time error.');
172 } else {
173 if (test.info.hasCompileError) {
174 output.add('Compile-time error expected.');
175 }
176 if (test.info.hasRuntimeError) {
177 output.add('Runtime error expected.');
178 }
179 }
180 }
181 if (!test.lastCommandOutput.diagnostics.isEmpty) {
182 String prefix = 'diagnostics:';
183 for (var s in test.lastCommandOutput.diagnostics) {
184 output.add('$prefix ${s}');
185 prefix = ' ';
186 }
187 }
188 if (!test.lastCommandOutput.stdout.isEmpty) {
189 output.add('');
190 output.add('stdout:');
191 if (test.lastCommandOutput.command.isPixelTest) {
192 output.add('DRT pixel test failed! stdout is not printed because it '
193 'contains binary data!');
194 } else {
195 output.add(decodeUtf8(test.lastCommandOutput.stdout));
196 }
197 }
198 if (!test.lastCommandOutput.stderr.isEmpty) {
199 output.add('');
200 output.add('stderr:');
201 output.add(decodeUtf8(test.lastCommandOutput.stderr));
202 }
203 if (test is BrowserTestCase) {
204 // Additional command for rerunning the steps locally after the fact.
205 var command =
206 test.configuration["_servers_"].httpServerCommandline();
207 output.add('To retest, run: $command');
208 }
209 for (Command c in test.commands) {
210 output.add('');
211 String message = (c == test.commands.last
212 ? "Command line" : "Compilation command");
213 output.add('$message: $c');
214 }
215 return output;
216 }
217
218 void _printFailureSummary() { 339 void _printFailureSummary() {
219 for (String line in _failureSummary) { 340 for (String line in _failureSummary) {
220 print(line); 341 print(line);
221 } 342 }
222 print(''); 343 print('');
223 } 344 }
345 }
346
347 class ProgressIndicator extends EventListener {
348 ProgressIndicator(this._startTime);
349
350 factory ProgressIndicator.fromName(String name,
351 Date startTime,
352 Formatter formatter) {
353 switch (name) {
354 case 'compact':
355 return new CompactProgressIndicator(startTime, formatter);
356 case 'line':
357 return new LineProgressIndicator();
358 case 'verbose':
359 return new VerboseProgressIndicator(startTime);
360 case 'status':
361 return new ProgressIndicator(startTime);
362 case 'buildbot':
363 return new BuildbotProgressIndicator(startTime);
364 default:
365 assert(false);
366 break;
367 }
368 }
369
370 void testAdded() { _foundTests++; }
371
372 void start(TestCase test) {
373 _printStartProgress(test);
374 }
375
376 void done(TestCase test) {
377 if (test.lastCommandOutput.unexpectedOutput) {
378 _failedTests++;
379 } else {
380 _passedTests++;
381 }
382 _printDoneProgress(test);
383 }
384
385 void allTestsKnown() {
386 _allTestsKnown = true;
387 }
388
389 void allDone() {
390 _printStatus();
391 }
392
393 void _printStartProgress(TestCase test) {}
394 void _printDoneProgress(TestCase test) {}
224 395
225 void _printStatus() { 396 void _printStatus() {
226 if (_failedTests == 0) { 397 if (_failedTests == 0) {
227 print('\n==='); 398 print('\n===');
228 print('=== All tests succeeded'); 399 print('=== All tests succeeded');
229 print('===\n'); 400 print('===\n');
230 } else { 401 } else {
231 var pluralSuffix = _failedTests != 1 ? 's' : ''; 402 var pluralSuffix = _failedTests != 1 ? 's' : '';
232 print('\n==='); 403 print('\n===');
233 print('=== ${_failedTests} test$pluralSuffix failed'); 404 print('=== ${_failedTests} test$pluralSuffix failed');
234 print('===\n'); 405 print('===\n');
235 } 406 }
236 } 407 }
237 408
238 void _appendToFlakyFile(String msg) {
239 var file = new File(TestUtils.flakyFileName());
240 var fd = file.openSync(FileMode.APPEND);
241 fd.writeStringSync(msg);
242 fd.closeSync();
243 }
244
245 int get numFailedTests => _failedTests; 409 int get numFailedTests => _failedTests;
246 410
247 int _completedTests() => _passedTests + _failedTests; 411 int _completedTests() => _passedTests + _failedTests;
248 412
249 int _foundTests = 0; 413 int _foundTests = 0;
250 int _passedTests = 0; 414 int _passedTests = 0;
251 int _failedTests = 0; 415 int _failedTests = 0;
252 int _skippedCompilations = 0;
253 bool _allTestsKnown = false; 416 bool _allTestsKnown = false;
254 Date _startTime; 417 Date _startTime;
255 bool _printTiming;
256 List<TestCase> _tests;
257 List<String> _failureSummary;
258 }
259
260
261 class SilentProgressIndicator extends ProgressIndicator {
262 SilentProgressIndicator(Date startTime, bool printTiming)
263 : super(startTime, printTiming);
264 void testAdded() { }
265 void start(TestCase test) { }
266 void done(TestCase test) { }
267 void _printStartProgress(TestCase test) { }
268 void _printDoneProgress(TestCase test) { }
269 void allTestsKnown() { }
270 void allDone() { }
271 } 418 }
272 419
273 abstract class CompactIndicator extends ProgressIndicator { 420 abstract class CompactIndicator extends ProgressIndicator {
274 CompactIndicator(Date startTime, bool printTiming) 421 CompactIndicator(Date startTime)
275 : super(startTime, printTiming); 422 : super(startTime);
276 423
277 void allDone() { 424 void allDone() {
278 stdout.write('\n'.charCodes); 425 stdout.write('\n'.charCodes);
279 _printFailureSummary();
280 _printSkippedCompilationInfo();
281 _printTimingInformation();
282 if (_failedTests > 0) { 426 if (_failedTests > 0) {
283 // We may have printed many failure logs, so reprint the summary data. 427 // We may have printed many failure logs, so reprint the summary data.
284 _printProgress(); 428 _printProgress();
285 print(''); 429 print('');
286 } 430 }
287 stdout.close(); 431 stdout.close();
288 stderr.close(); 432 stderr.close();
289 if (_failedTests > 0) {
290 io.exitCode = 1;
291 }
292 }
293
294 void allTestsKnown() {
295 if (!_allTestsKnown && SummaryReport.total > 0) {
296 // Clear progress indicator before printing summary report.
297 stdout.write(
298 '\r \r'.charCodes);
299 SummaryReport.printReport();
300 }
301 _allTestsKnown = true;
302 } 433 }
303 434
304 void _printStartProgress(TestCase test) => _printProgress(); 435 void _printStartProgress(TestCase test) => _printProgress();
305 void _printDoneProgress(TestCase test) => _printProgress(); 436 void _printDoneProgress(TestCase test) => _printProgress();
306 437
307 void _printProgress(); 438 void _printProgress();
308 } 439 }
309 440
310 441
311 class CompactProgressIndicator extends CompactIndicator { 442 class CompactProgressIndicator extends CompactIndicator {
312 CompactProgressIndicator(Date startTime, bool printTiming) 443 Formatter _formatter;
313 : super(startTime, printTiming); 444
445 CompactProgressIndicator(Date startTime, this._formatter)
446 : super(startTime);
314 447
315 void _printProgress() { 448 void _printProgress() {
316 var percent = ((_completedTests() / _foundTests) * 100).toInt().toString(); 449 var percent = ((_completedTests() / _foundTests) * 100).toInt().toString();
317 var progressPadded = _pad(_allTestsKnown ? percent : '--', 3); 450 var progressPadded = _pad(_allTestsKnown ? percent : '--', 3);
318 var passedPadded = _pad(_passedTests.toString(), 5); 451 var passedPadded = _pad(_passedTests.toString(), 5);
319 var failedPadded = _pad(_failedTests.toString(), 5); 452 var failedPadded = _pad(_failedTests.toString(), 5);
320 Duration d = (new Date.now()).difference(_startTime); 453 Duration d = (new Date.now()).difference(_startTime);
321 var progressLine = 454 var progressLine =
322 '\r[${_timeString(d)} | $progressPadded% | ' 455 '\r[${_timeString(d)} | $progressPadded% | '
323 '+$passedPadded | -$failedPadded]'; 456 '+${_formatter.passed(passedPadded)} | '
457 '-${_formatter.failed(failedPadded)}]';
324 stdout.write(progressLine.charCodes); 458 stdout.write(progressLine.charCodes);
325 } 459 }
326 } 460 }
327 461
328 462
329 class ColorProgressIndicator extends CompactIndicator {
330 ColorProgressIndicator(Date startTime, bool printTiming)
331 : super(startTime, printTiming);
332
333 static int BOLD = 1;
334 static int GREEN = 32;
335 static int RED = 31;
336 static int NONE = 0;
337
338 addColorWrapped(List<int> codes, String string, int color) {
339 codes.add(27);
340 codes.addAll('[${color}m'.charCodes);
341 codes.addAll(encodeUtf8(string));
342 codes.add(27);
343 codes.addAll('[0m'.charCodes);
344 }
345
346 void _printProgress() {
347 var percent = ((_completedTests() / _foundTests) * 100).toInt().toString();
348 var progressPadded = _pad(_allTestsKnown ? percent : '--', 3);
349 var passedPadded = _pad(_passedTests.toString(), 5);
350 var failedPadded = _pad(_failedTests.toString(), 5);
351 Duration d = (new Date.now()).difference(_startTime);
352 var progressLine = [];
353 progressLine.addAll('\r[${_timeString(d)} | $progressPadded% | '.charCodes);
354 addColorWrapped(progressLine, '+$passedPadded ', GREEN);
355 progressLine.addAll('| '.charCodes);
356 var failedColor = (_failedTests != 0) ? RED : NONE;
357 addColorWrapped(progressLine, '-$failedPadded', failedColor);
358 progressLine.addAll(']'.charCodes);
359 stdout.write(progressLine);
360 }
361
362 String _header(String header) {
363 var result = [];
364 addColorWrapped(result, header, BOLD);
365 return decodeUtf8(result);
366 }
367 }
368
369
370 class LineProgressIndicator extends ProgressIndicator {
371 LineProgressIndicator(Date startTime, bool printTiming)
372 : super(startTime, printTiming);
373
374 void _printStartProgress(TestCase test) {
375 }
376
377 void _printDoneProgress(TestCase test) {
378 var status = 'pass';
379 if (test.lastCommandOutput.unexpectedOutput) {
380 status = 'fail';
381 }
382 print('Done ${test.configurationString} ${test.displayName}: $status');
383 }
384 }
385
386
387 class VerboseProgressIndicator extends ProgressIndicator { 463 class VerboseProgressIndicator extends ProgressIndicator {
388 VerboseProgressIndicator(Date startTime, bool printTiming) 464 VerboseProgressIndicator(Date startTime)
389 : super(startTime, printTiming); 465 : super(startTime);
390 466
391 void _printStartProgress(TestCase test) { 467 void _printStartProgress(TestCase test) {
392 print('Starting ${test.configurationString} ${test.displayName}...'); 468 print('Starting ${test.configurationString} ${test.displayName}...');
393 } 469 }
394 470
395 void _printDoneProgress(TestCase test) { 471 void _printDoneProgress(TestCase test) {
396 var status = 'pass'; 472 var status = 'pass';
397 if (test.lastCommandOutput.unexpectedOutput) { 473 if (test.lastCommandOutput.unexpectedOutput) {
398 status = 'fail'; 474 status = 'fail';
399 } 475 }
400 print('Done ${test.configurationString} ${test.displayName}: $status'); 476 print('Done ${test.configurationString} ${test.displayName}: $status');
401 } 477 }
402 } 478 }
403 479
404 480
405 class StatusProgressIndicator extends ProgressIndicator {
406 StatusProgressIndicator(Date startTime, bool printTiming)
407 : super(startTime, printTiming);
408
409 void _printStartProgress(TestCase test) {
410 }
411
412 void _printDoneProgress(TestCase test) {
413 }
414 }
415
416
417 class BuildbotProgressIndicator extends ProgressIndicator { 481 class BuildbotProgressIndicator extends ProgressIndicator {
418 static String stepName; 482 static String stepName;
419 483
420 BuildbotProgressIndicator(Date startTime, bool printTiming) 484 BuildbotProgressIndicator(Date startTime) : super(startTime);
421 : super(startTime, printTiming);
422
423 void _printStartProgress(TestCase test) {
424 }
425 485
426 void _printDoneProgress(TestCase test) { 486 void _printDoneProgress(TestCase test) {
427 var status = 'pass'; 487 var status = 'pass';
428 if (test.lastCommandOutput.unexpectedOutput) { 488 if (test.lastCommandOutput.unexpectedOutput) {
429 status = 'fail'; 489 status = 'fail';
430 } 490 }
431 var percent = ((_completedTests() / _foundTests) * 100).toInt().toString(); 491 var percent = ((_completedTests() / _foundTests) * 100).toInt().toString();
432 print('Done ${test.configurationString} ${test.displayName}: $status'); 492 print('Done ${test.configurationString} ${test.displayName}: $status');
433 print('@@@STEP_CLEAR@@@'); 493 print('@@@STEP_CLEAR@@@');
434 print('@@@STEP_TEXT@ $percent% +$_passedTests -$_failedTests @@@'); 494 print('@@@STEP_TEXT@ $percent% +$_passedTests -$_failedTests @@@');
435 } 495 }
436 496
437 void _printFailureSummary() { 497 void allDone() {
438 if (!_failureSummary.isEmpty && stepName != null) { 498 if (_failedTests > 0) {
439 print('@@@STEP_FAILURE@@@'); 499 print('@@@STEP_FAILURE@@@');
440 print('@@@BUILD_STEP $stepName failures@@@'); 500 print('@@@BUILD_STEP $stepName failures@@@');
441 } 501 }
442 super._printFailureSummary(); 502 super.allDone();
443 } 503 }
444 } 504 }
445 505
446 class DiffProgressIndicator extends ColorProgressIndicator {
447 Map<String, List<String>> statusToConfigs = new Map<String, List<String>>();
448
449 DiffProgressIndicator(Date startTime, bool printTiming)
450 : super(startTime, printTiming);
451
452 void _printFailureOutput(TestCase test) {
453 String status = '${test.displayName}: ${test.lastCommandOutput.result}';
454 List<String> configs =
455 statusToConfigs.putIfAbsent(status, () => <String>[]);
456 configs.add(test.configurationString);
457 if (test.lastCommandOutput.hasTimedOut) {
458 print('\n${test.displayName} timed out on ${test.configurationString}');
459 }
460 }
461
462 String _extractRuntime(String configuration) {
463 // Extract runtime from a configuration, for example,
464 // 'none-vm-checked release_ia32'.
465 List<String> runtime = configuration.split(' ')[0].split('-');
466 return '${runtime[0]}-${runtime[1]}';
467 }
468
469 void _printFailureSummary() {
470 Map<String, List<String>> groupedStatuses = new Map<String, List<String>>();
471 statusToConfigs.forEach((String status, List<String> configs) {
472 Map<String, List<String>> runtimeToConfiguration =
473 new Map<String, List<String>>();
474 for (String config in configs) {
475 String runtime = _extractRuntime(config);
476 List<String> runtimeConfigs =
477 runtimeToConfiguration.putIfAbsent(runtime, () => <String>[]);
478 runtimeConfigs.add(config);
479 }
480 runtimeToConfiguration.forEach((String runtime,
481 List<String> runtimeConfigs) {
482 runtimeConfigs.sort((a, b) => a.compareTo(b));
483 List<String> statuses =
484 groupedStatuses.putIfAbsent('$runtime: $runtimeConfigs',
485 () => <String>[]);
486 statuses.add(status);
487 });
488 });
489 groupedStatuses.forEach((String config, List<String> statuses) {
490 print('');
491 print('');
492 print('$config:');
493 statuses.sort((a, b) => a.compareTo(b));
494 for (String status in statuses) {
495 print(' $status');
496 }
497 });
498 _printStatus();
499 }
500 }
OLDNEW
« no previous file with comments | « tools/test-runtime.dart ('k') | tools/testing/dart/test_runner.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698