Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 /** | 5 /** |
| 6 * Classes and methods for executing tests. | 6 * Classes and methods for executing tests. |
| 7 * | 7 * |
| 8 * This module includes: | 8 * This module includes: |
| 9 * - Managing parallel execution of tests, including timeout checks. | 9 * - Managing parallel execution of tests, including timeout checks. |
| 10 * - Evaluating the output of each test as pass/fail/crash/timeout. | 10 * - Evaluating the output of each test as pass/fail/crash/timeout. |
| 11 */ | 11 */ |
| 12 #library("test_runner"); | 12 #library("test_runner"); |
| 13 | 13 |
| 14 #import("dart:io"); | 14 #import("dart:io"); |
| 15 #import("dart:isolate"); | 15 #import("dart:isolate"); |
| 16 #import("dart:uri"); | |
| 16 #import("status_file_parser.dart"); | 17 #import("status_file_parser.dart"); |
| 17 #import("test_progress.dart"); | 18 #import("test_progress.dart"); |
| 18 #import("test_suite.dart"); | 19 #import("test_suite.dart"); |
| 19 | 20 |
| 20 const int NO_TIMEOUT = 0; | 21 const int NO_TIMEOUT = 0; |
| 21 const int SLOW_TIMEOUT_MULTIPLIER = 4; | 22 const int SLOW_TIMEOUT_MULTIPLIER = 4; |
| 22 | 23 |
| 23 typedef void TestCaseEvent(TestCase testCase); | 24 typedef void TestCaseEvent(TestCase testCase); |
| 24 typedef void ExitCodeEvent(int exitCode); | 25 typedef void ExitCodeEvent(int exitCode); |
| 25 typedef void EnqueueMoreWork(ProcessQueue queue); | 26 typedef void EnqueueMoreWork(ProcessQueue queue); |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 39 if (Platform.operatingSystem == 'windows') { | 40 if (Platform.operatingSystem == 'windows') { |
| 40 // Windows can't handle the first command if it is a .bat file or the like | 41 // Windows can't handle the first command if it is a .bat file or the like |
| 41 // with the slashes going the other direction. | 42 // with the slashes going the other direction. |
| 42 // TODO(efortuna): Remove this when fixed (Issue 1306). | 43 // TODO(efortuna): Remove this when fixed (Issue 1306). |
| 43 executable = executable.replaceAll('/', '\\'); | 44 executable = executable.replaceAll('/', '\\'); |
| 44 } | 45 } |
| 45 commandLine = "$executable ${Strings.join(arguments, ' ')}"; | 46 commandLine = "$executable ${Strings.join(arguments, ' ')}"; |
| 46 } | 47 } |
| 47 | 48 |
| 48 String toString() => commandLine; | 49 String toString() => commandLine; |
| 50 | |
| 51 Future<bool> get outputIsUpToDate => new Future.immediate(false); | |
| 52 } | |
| 53 | |
| 54 class Dart2JsCommand extends Command { | |
|
ricow1
2012/11/19 08:19:17
We could generalize this to not be dart2js specifi
kustermann
2012/11/19 10:26:04
I agree with you, that we should generalize this.
| |
| 55 String _jsOutputFile; | |
| 56 bool _neverSkipCompilation; | |
| 57 List<Uri> _bootstrapDependencies; | |
| 58 | |
| 59 Dart2JsCommand(this._jsOutputFile, | |
| 60 this._neverSkipCompilation, | |
| 61 this._bootstrapDependencies, | |
| 62 String executable, | |
| 63 List<String> arguments) | |
| 64 : super(executable, arguments); | |
| 65 | |
| 66 Future<bool> get outputIsUpToDate { | |
| 67 if (_neverSkipCompilation) return new Future.immediate(false); | |
| 68 | |
| 69 Future<List<Uri>> readDepsFile(String path) { | |
| 70 var file = new File(path); | |
| 71 if (!file.existsSync()) { | |
| 72 return new Future.immediate(null); | |
| 73 } | |
| 74 return file.readAsLines().transform((List<String> lines) { | |
| 75 var dependencies = new List<Uri>(); | |
| 76 for (var line in lines) { | |
| 77 line = line.trim(); | |
| 78 if (line.length > 0) { | |
| 79 dependencies.add(new Uri(line)); | |
| 80 } | |
| 81 } | |
| 82 return dependencies; | |
| 83 }); | |
| 84 } | |
| 85 | |
| 86 return readDepsFile("$_jsOutputFile.deps").transform((dependencies) { | |
| 87 if (dependencies != null) { | |
| 88 dependencies.addAll(_bootstrapDependencies); | |
| 89 var jsOutputLastModified = TestUtils.lastModifiedCache.getLastModified( | |
| 90 new Uri.fromComponents(scheme: 'file', path: _jsOutputFile)); | |
| 91 if (jsOutputLastModified != null) { | |
| 92 for (var dependency in dependencies) { | |
| 93 var dependencyLastModified = | |
| 94 TestUtils.lastModifiedCache.getLastModified(dependency); | |
| 95 if (dependencyLastModified == null || | |
| 96 dependencyLastModified > jsOutputLastModified) { | |
| 97 return false; | |
| 98 } | |
| 99 } | |
| 100 return true; | |
| 101 } | |
| 102 } | |
| 103 return false; | |
| 104 }); | |
| 105 } | |
| 49 } | 106 } |
| 50 | 107 |
| 51 /** | 108 /** |
| 52 * TestCase contains all the information needed to run a test and evaluate | 109 * TestCase contains all the information needed to run a test and evaluate |
| 53 * its output. Running a test involves starting a separate process, with | 110 * its output. Running a test involves starting a separate process, with |
| 54 * the executable and arguments given by the TestCase, and recording its | 111 * the executable and arguments given by the TestCase, and recording its |
| 55 * stdout and stderr output streams, and its exit code. TestCase only | 112 * stdout and stderr output streams, and its exit code. TestCase only |
| 56 * contains static information about the test; actually running the test is | 113 * contains static information about the test; actually running the test is |
| 57 * performed by [ProcessQueue] using a [RunningProcess] object. | 114 * performed by [ProcessQueue] using a [RunningProcess] object. |
| 58 * | 115 * |
| (...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 255 * [TestCase] this is the output of. | 312 * [TestCase] this is the output of. |
| 256 */ | 313 */ |
| 257 abstract class CommandOutput { | 314 abstract class CommandOutput { |
| 258 factory CommandOutput.fromCase(TestCase testCase, | 315 factory CommandOutput.fromCase(TestCase testCase, |
| 259 Command command, | 316 Command command, |
| 260 int exitCode, | 317 int exitCode, |
| 261 bool incomplete, | 318 bool incomplete, |
| 262 bool timedOut, | 319 bool timedOut, |
| 263 List<String> stdout, | 320 List<String> stdout, |
| 264 List<String> stderr, | 321 List<String> stderr, |
| 265 Duration time) { | 322 Duration time, |
| 323 bool compilationSkipped) { | |
| 266 return new CommandOutputImpl.fromCase(testCase, | 324 return new CommandOutputImpl.fromCase(testCase, |
| 267 command, | 325 command, |
| 268 exitCode, | 326 exitCode, |
| 269 incomplete, | 327 incomplete, |
| 270 timedOut, | 328 timedOut, |
| 271 stdout, | 329 stdout, |
| 272 stderr, | 330 stderr, |
| 273 time); | 331 time, |
| 332 compilationSkipped); | |
| 274 } | 333 } |
| 275 | 334 |
| 276 bool get incomplete; | 335 bool get incomplete; |
| 277 | 336 |
| 278 String get result; | 337 String get result; |
| 279 | 338 |
| 280 bool get unexpectedOutput; | 339 bool get unexpectedOutput; |
| 281 | 340 |
| 282 bool get hasCrashed; | 341 bool get hasCrashed; |
| 283 | 342 |
| 284 bool get hasTimedOut; | 343 bool get hasTimedOut; |
| 285 | 344 |
| 286 bool get didFail; | 345 bool get didFail; |
| 287 | 346 |
| 288 bool requestRetry; | 347 bool requestRetry; |
| 289 | 348 |
| 290 Duration get time; | 349 Duration get time; |
| 291 | 350 |
| 292 int get exitCode; | 351 int get exitCode; |
| 293 | 352 |
| 294 List<String> get stdout; | 353 List<String> get stdout; |
| 295 | 354 |
| 296 List<String> get stderr; | 355 List<String> get stderr; |
| 297 | 356 |
| 298 List<String> get diagnostics; | 357 List<String> get diagnostics; |
| 358 | |
| 359 bool get compilationSkipped; | |
| 299 } | 360 } |
| 300 | 361 |
| 301 class CommandOutputImpl implements CommandOutput { | 362 class CommandOutputImpl implements CommandOutput { |
| 302 TestCase testCase; | 363 TestCase testCase; |
| 303 int exitCode; | 364 int exitCode; |
| 304 | 365 |
| 305 /// Records if all commands were run, true if they weren't. | 366 /// Records if all commands were run, true if they weren't. |
| 306 final bool incomplete; | 367 final bool incomplete; |
| 307 | 368 |
| 308 bool timedOut; | 369 bool timedOut; |
| 309 bool failed = false; | 370 bool failed = false; |
| 310 List<String> stdout; | 371 List<String> stdout; |
| 311 List<String> stderr; | 372 List<String> stderr; |
| 312 Duration time; | 373 Duration time; |
| 313 List<String> diagnostics; | 374 List<String> diagnostics; |
| 375 bool compilationSkipped; | |
| 314 | 376 |
| 315 /** | 377 /** |
| 316 * A flag to indicate we have already printed a warning about ignoring the VM | 378 * A flag to indicate we have already printed a warning about ignoring the VM |
| 317 * crash, to limit the amount of output produced per test. | 379 * crash, to limit the amount of output produced per test. |
| 318 */ | 380 */ |
| 319 bool alreadyPrintedWarning = false; | 381 bool alreadyPrintedWarning = false; |
| 320 | 382 |
| 321 /** | 383 /** |
| 322 * Set to true if we encounter a condition in the output that indicates we | 384 * Set to true if we encounter a condition in the output that indicates we |
| 323 * need to rerun this test. | 385 * need to rerun this test. |
| 324 */ | 386 */ |
| 325 bool requestRetry = false; | 387 bool requestRetry = false; |
| 326 | 388 |
| 327 // Don't call this constructor, call CommandOutput.fromCase() to | 389 // Don't call this constructor, call CommandOutput.fromCase() to |
| 328 // get a new TestOutput instance. | 390 // get a new TestOutput instance. |
| 329 CommandOutputImpl(TestCase this.testCase, | 391 CommandOutputImpl(TestCase this.testCase, |
| 330 Command command, | 392 Command command, |
| 331 int this.exitCode, | 393 int this.exitCode, |
| 332 bool this.incomplete, | 394 bool this.incomplete, |
| 333 bool this.timedOut, | 395 bool this.timedOut, |
| 334 List<String> this.stdout, | 396 List<String> this.stdout, |
| 335 List<String> this.stderr, | 397 List<String> this.stderr, |
| 336 Duration this.time) { | 398 Duration this.time, |
| 399 bool this.compilationSkipped) { | |
| 337 testCase.commandOutputs[command] = this; | 400 testCase.commandOutputs[command] = this; |
| 338 diagnostics = []; | 401 diagnostics = []; |
| 339 } | 402 } |
| 340 factory CommandOutputImpl.fromCase(TestCase testCase, | 403 factory CommandOutputImpl.fromCase(TestCase testCase, |
| 341 Command command, | 404 Command command, |
| 342 int exitCode, | 405 int exitCode, |
| 343 bool incomplete, | 406 bool incomplete, |
| 344 bool timedOut, | 407 bool timedOut, |
| 345 List<String> stdout, | 408 List<String> stdout, |
| 346 List<String> stderr, | 409 List<String> stderr, |
| 347 Duration time) { | 410 Duration time, |
| 411 bool compilationSkipped) { | |
| 348 if (testCase is BrowserTestCase) { | 412 if (testCase is BrowserTestCase) { |
| 349 return new BrowserCommandOutputImpl(testCase, | 413 return new BrowserCommandOutputImpl(testCase, |
| 350 command, | 414 command, |
| 351 exitCode, | 415 exitCode, |
| 352 incomplete, | 416 incomplete, |
| 353 timedOut, | 417 timedOut, |
| 354 stdout, | 418 stdout, |
| 355 stderr, | 419 stderr, |
| 356 time); | 420 time, |
| 421 compilationSkipped); | |
| 357 } else if (testCase.configuration['compiler'] == 'dartc') { | 422 } else if (testCase.configuration['compiler'] == 'dartc') { |
| 358 return new AnalysisCommandOutputImpl(testCase, | 423 return new AnalysisCommandOutputImpl(testCase, |
| 359 command, | 424 command, |
| 360 exitCode, | 425 exitCode, |
| 361 timedOut, | 426 timedOut, |
| 362 stdout, | 427 stdout, |
| 363 stderr, | 428 stderr, |
| 364 time); | 429 time, |
| 430 compilationSkipped); | |
| 365 } | 431 } |
| 366 return new CommandOutputImpl(testCase, | 432 return new CommandOutputImpl(testCase, |
| 367 command, | 433 command, |
| 368 exitCode, | 434 exitCode, |
| 369 incomplete, | 435 incomplete, |
| 370 timedOut, | 436 timedOut, |
| 371 stdout, | 437 stdout, |
| 372 stderr, | 438 stderr, |
| 373 time); | 439 time, |
| 440 compilationSkipped); | |
| 374 } | 441 } |
| 375 | 442 |
| 376 String get result => | 443 String get result => |
| 377 hasCrashed ? CRASH : (hasTimedOut ? TIMEOUT : (hasFailed ? FAIL : PASS)); | 444 hasCrashed ? CRASH : (hasTimedOut ? TIMEOUT : (hasFailed ? FAIL : PASS)); |
| 378 | 445 |
| 379 bool get unexpectedOutput => !testCase.expectedOutcomes.contains(result); | 446 bool get unexpectedOutput => !testCase.expectedOutcomes.contains(result); |
| 380 | 447 |
| 381 bool get hasCrashed { | 448 bool get hasCrashed { |
| 382 // The Java dartc runner and dart2js exits with code 253 in case | 449 // The Java dartc runner and dart2js exits with code 253 in case |
| 383 // of unhandled exceptions. | 450 // of unhandled exceptions. |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 412 | 479 |
| 413 class BrowserCommandOutputImpl extends CommandOutputImpl { | 480 class BrowserCommandOutputImpl extends CommandOutputImpl { |
| 414 BrowserCommandOutputImpl( | 481 BrowserCommandOutputImpl( |
| 415 testCase, | 482 testCase, |
| 416 command, | 483 command, |
| 417 exitCode, | 484 exitCode, |
| 418 incomplete, | 485 incomplete, |
| 419 timedOut, | 486 timedOut, |
| 420 stdout, | 487 stdout, |
| 421 stderr, | 488 stderr, |
| 422 time) : | 489 time, |
| 490 compilationSkipped) : | |
| 423 super(testCase, | 491 super(testCase, |
| 424 command, | 492 command, |
| 425 exitCode, | 493 exitCode, |
| 426 incomplete, | 494 incomplete, |
| 427 timedOut, | 495 timedOut, |
| 428 stdout, | 496 stdout, |
| 429 stderr, | 497 stderr, |
| 430 time); | 498 time, |
| 499 compilationSkipped); | |
| 431 | 500 |
| 432 bool get didFail { | 501 bool get didFail { |
| 433 // Browser case: | 502 // Browser case: |
| 434 // If the browser test failed, it may have been because DumpRenderTree | 503 // If the browser test failed, it may have been because DumpRenderTree |
| 435 // and the virtual framebuffer X server didn't hook up, or DRT crashed with | 504 // and the virtual framebuffer X server didn't hook up, or DRT crashed with |
| 436 // a core dump. Sometimes DRT crashes after it has set the stdout to PASS, | 505 // a core dump. Sometimes DRT crashes after it has set the stdout to PASS, |
| 437 // so we have to do this check first. | 506 // so we have to do this check first. |
| 438 for (String line in super.stderr) { | 507 for (String line in super.stderr) { |
| 439 if (line.contains('Gtk-WARNING **: cannot open display: :99') || | 508 if (line.contains('Gtk-WARNING **: cannot open display: :99') || |
| 440 line.contains('Failed to run command. return code=1')) { | 509 line.contains('Failed to run command. return code=1')) { |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 472 // to stderr. | 541 // to stderr. |
| 473 class AnalysisCommandOutputImpl extends CommandOutputImpl { | 542 class AnalysisCommandOutputImpl extends CommandOutputImpl { |
| 474 // An error line has 8 fields that look like: | 543 // An error line has 8 fields that look like: |
| 475 // ERROR|COMPILER|MISSING_SOURCE|file:/tmp/t.dart|15|1|24|Missing source. | 544 // ERROR|COMPILER|MISSING_SOURCE|file:/tmp/t.dart|15|1|24|Missing source. |
| 476 final int ERROR_LEVEL = 0; | 545 final int ERROR_LEVEL = 0; |
| 477 final int ERROR_TYPE = 1; | 546 final int ERROR_TYPE = 1; |
| 478 final int FORMATTED_ERROR = 7; | 547 final int FORMATTED_ERROR = 7; |
| 479 | 548 |
| 480 bool alreadyComputed = false; | 549 bool alreadyComputed = false; |
| 481 bool failResult; | 550 bool failResult; |
| 551 | |
| 482 AnalysisCommandOutputImpl(testCase, | 552 AnalysisCommandOutputImpl(testCase, |
| 483 command, | 553 command, |
| 484 exitCode, | 554 exitCode, |
| 485 timedOut, | 555 timedOut, |
| 486 stdout, | 556 stdout, |
| 487 stderr, | 557 stderr, |
| 488 time) : | 558 time, |
| 489 super(testCase, command, exitCode, false, timedOut, stdout, stderr, time); | 559 compilationSkipped) : |
| 560 super(testCase, | |
| 561 command, | |
| 562 exitCode, | |
| 563 false, | |
| 564 timedOut, | |
| 565 stdout, | |
| 566 stderr, | |
| 567 time, | |
| 568 compilationSkipped); | |
| 490 | 569 |
| 491 bool get didFail { | 570 bool get didFail { |
| 492 if (!alreadyComputed) { | 571 if (!alreadyComputed) { |
| 493 failResult = _didFail(); | 572 failResult = _didFail(); |
| 494 alreadyComputed = true; | 573 alreadyComputed = true; |
| 495 } | 574 } |
| 496 return failResult; | 575 return failResult; |
| 497 } | 576 } |
| 498 | 577 |
| 499 bool _didFail() { | 578 bool _didFail() { |
| (...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 647 */ | 726 */ |
| 648 class RunningProcess { | 727 class RunningProcess { |
| 649 ProcessQueue processQueue; | 728 ProcessQueue processQueue; |
| 650 Process process; | 729 Process process; |
| 651 TestCase testCase; | 730 TestCase testCase; |
| 652 bool timedOut = false; | 731 bool timedOut = false; |
| 653 Date startTime; | 732 Date startTime; |
| 654 Timer timeoutTimer; | 733 Timer timeoutTimer; |
| 655 List<String> stdout; | 734 List<String> stdout; |
| 656 List<String> stderr; | 735 List<String> stderr; |
| 736 bool compilationSkipped; | |
| 657 bool allowRetries; | 737 bool allowRetries; |
| 658 | 738 |
| 659 /** Which command of [testCase.commands] is currently being executed. */ | 739 /** Which command of [testCase.commands] is currently being executed. */ |
| 660 int currentStep; | 740 int currentStep; |
| 661 | 741 |
| 662 RunningProcess(TestCase this.testCase, | 742 RunningProcess(TestCase this.testCase, |
| 663 [this.allowRetries = false, this.processQueue]); | 743 [this.allowRetries = false, this.processQueue]); |
| 664 | 744 |
| 665 /** | 745 /** |
| 666 * Called when all commands are executed. | 746 * Called when all commands are executed. |
| 667 */ | 747 */ |
| 668 void testComplete(CommandOutput lastCommandOutput) { | 748 void testComplete(CommandOutput lastCommandOutput) { |
| 669 timeoutTimer.cancel(); | 749 if (timeoutTimer != null) { |
| 750 timeoutTimer.cancel(); | |
| 751 } | |
| 670 if (lastCommandOutput.unexpectedOutput | 752 if (lastCommandOutput.unexpectedOutput |
| 671 && testCase.configuration['verbose'] != null | 753 && testCase.configuration['verbose'] != null |
| 672 && testCase.configuration['verbose']) { | 754 && testCase.configuration['verbose']) { |
| 673 print(testCase.displayName); | 755 print(testCase.displayName); |
| 674 for (var line in lastCommandOutput.stderr) print(line); | 756 for (var line in lastCommandOutput.stderr) print(line); |
| 675 for (var line in lastCommandOutput.stdout) print(line); | 757 for (var line in lastCommandOutput.stdout) print(line); |
| 676 } | 758 } |
| 677 if (allowRetries && testCase.usesWebDriver | 759 if (allowRetries && testCase.usesWebDriver |
| 678 && lastCommandOutput.unexpectedOutput | 760 && lastCommandOutput.unexpectedOutput |
| 679 && (testCase as BrowserTestCase).numRetries > 0) { | 761 && (testCase as BrowserTestCase).numRetries > 0) { |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 721 // One compilation step successfully completed, move on to the | 803 // One compilation step successfully completed, move on to the |
| 722 // next step. | 804 // next step. |
| 723 stderr.add('test.dart: Compilation finished $suffix\n'); | 805 stderr.add('test.dart: Compilation finished $suffix\n'); |
| 724 stdout.add('test.dart: Compilation finished $suffix\n'); | 806 stdout.add('test.dart: Compilation finished $suffix\n'); |
| 725 if (currentStep == totalSteps - 1 && testCase.usesWebDriver && | 807 if (currentStep == totalSteps - 1 && testCase.usesWebDriver && |
| 726 !testCase.configuration['noBatch']) { | 808 !testCase.configuration['noBatch']) { |
| 727 // Note: processQueue will always be non-null for runtime == ie9, ie10, | 809 // Note: processQueue will always be non-null for runtime == ie9, ie10, |
| 728 // ff, safari, chrome, opera. (It is only null for runtime == vm) | 810 // ff, safari, chrome, opera. (It is only null for runtime == vm) |
| 729 // This RunningProcess object is done, and hands over control to | 811 // This RunningProcess object is done, and hands over control to |
| 730 // BatchRunner.startTest(), which handles reporting, etc. | 812 // BatchRunner.startTest(), which handles reporting, etc. |
| 731 timeoutTimer.cancel(); | 813 if (timeoutTimer != null) { |
| 814 timeoutTimer.cancel(); | |
| 815 } | |
| 732 processQueue._getBatchRunner(testCase).startTest(testCase); | 816 processQueue._getBatchRunner(testCase).startTest(testCase); |
| 733 } else { | 817 } else { |
| 734 runCommand(testCase.commands[currentStep++], commandComplete); | 818 runCommand(testCase.commands[currentStep++], commandComplete); |
| 735 } | 819 } |
| 736 } | 820 } |
| 737 } | 821 } |
| 738 | 822 |
| 739 /** | 823 /** |
| 740 * Called for all executed commands. | 824 * Called for all executed commands. |
| 741 */ | 825 */ |
| 742 CommandOutput createCommandOutput(Command command, | 826 CommandOutput createCommandOutput(Command command, |
| 743 int exitCode, | 827 int exitCode, |
| 744 bool incomplete) { | 828 bool incomplete) { |
| 745 var commandOutput = new CommandOutput.fromCase( | 829 var commandOutput = new CommandOutput.fromCase( |
| 746 testCase, | 830 testCase, |
| 747 command, | 831 command, |
| 748 exitCode, | 832 exitCode, |
| 749 incomplete, | 833 incomplete, |
| 750 timedOut, | 834 timedOut, |
| 751 stdout, | 835 stdout, |
| 752 stderr, | 836 stderr, |
| 753 new Date.now().difference(startTime)); | 837 new Date.now().difference(startTime), |
| 838 compilationSkipped); | |
| 754 resetLocalOutputInformation(); | 839 resetLocalOutputInformation(); |
| 755 return commandOutput; | 840 return commandOutput; |
| 756 } | 841 } |
| 757 | 842 |
| 758 void resetLocalOutputInformation() { | 843 void resetLocalOutputInformation() { |
| 759 stdout = new List<String>(); | 844 stdout = new List<String>(); |
| 760 stderr = new List<String>(); | 845 stderr = new List<String>(); |
| 846 compilationSkipped = false; | |
| 761 } | 847 } |
| 762 | 848 |
| 763 VoidFunction makeReadHandler(StringInputStream source, | 849 VoidFunction makeReadHandler(StringInputStream source, |
| 764 List<String> destination) { | 850 List<String> destination) { |
| 765 void handler () { | 851 void handler () { |
| 766 if (source.closed) return; // TODO(whesse): Remove when bug is fixed. | 852 if (source.closed) return; // TODO(whesse): Remove when bug is fixed. |
| 767 var line = source.readLine(); | 853 var line = source.readLine(); |
| 768 while (null != line) { | 854 while (null != line) { |
| 769 destination.add(line); | 855 destination.add(line); |
| 770 line = source.readLine(); | 856 line = source.readLine(); |
| 771 } | 857 } |
| 772 } | 858 } |
| 773 return handler; | 859 return handler; |
| 774 } | 860 } |
| 775 | 861 |
| 776 void start() { | 862 void start() { |
| 777 Expect.isFalse(testCase.expectedOutcomes.contains(SKIP)); | 863 Expect.isFalse(testCase.expectedOutcomes.contains(SKIP)); |
| 778 resetLocalOutputInformation(); | 864 resetLocalOutputInformation(); |
| 779 currentStep = 0; | 865 currentStep = 0; |
| 780 startTime = new Date.now(); | 866 startTime = new Date.now(); |
| 781 runCommand(testCase.commands[currentStep++], commandComplete); | 867 runCommand(testCase.commands[currentStep++], commandComplete); |
| 782 } | 868 } |
| 783 | 869 |
| 784 void runCommand(Command command, void commandCompleteHandler(Command, int)) { | 870 void runCommand(Command command, void commandCompleteHandler(Command, int)) { |
| 785 void processExitHandler(int returnCode) { | 871 void processExitHandler(int returnCode) { |
| 786 commandCompleteHandler(command, returnCode); | 872 commandCompleteHandler(command, returnCode); |
| 787 } | 873 } |
| 788 | 874 |
| 789 Future processFuture = Process.start(command.executable, command.arguments); | 875 command.outputIsUpToDate.then((bool isUpToDate) { |
| 790 processFuture.then((Process p) { | 876 if (isUpToDate) { |
| 791 process = p; | 877 stdout.add("Skipped dart2js compilation because the old output is " |
|
ricow1
2012/11/19 08:19:17
Skipped dart2js compilation -> Skipped compilation
kustermann
2012/11/19 10:26:04
Done.
| |
| 792 process.onExit = processExitHandler; | 878 "still up to date!"); |
| 793 var stdoutStringStream = new StringInputStream(process.stdout); | 879 compilationSkipped = true; |
| 794 var stderrStringStream = new StringInputStream(process.stderr); | 880 commandComplete(command, 0); |
| 795 stdoutStringStream.onLine = | 881 } else { |
| 796 makeReadHandler(stdoutStringStream, stdout); | 882 Future processFuture = Process.start(command.executable, |
| 797 stderrStringStream.onLine = | 883 command.arguments); |
| 798 makeReadHandler(stderrStringStream, stderr); | 884 processFuture.then((Process p) { |
| 799 if (timeoutTimer == null) { | 885 process = p; |
| 800 // Create one timeout timer when starting test case, remove it at end. | 886 process.onExit = processExitHandler; |
| 801 timeoutTimer = new Timer(1000 * testCase.timeout, timeoutHandler); | 887 var stdoutStringStream = new StringInputStream(process.stdout); |
| 888 var stderrStringStream = new StringInputStream(process.stderr); | |
| 889 stdoutStringStream.onLine = | |
| 890 makeReadHandler(stdoutStringStream, stdout); | |
| 891 stderrStringStream.onLine = | |
| 892 makeReadHandler(stderrStringStream, stderr); | |
| 893 if (timeoutTimer == null) { | |
| 894 // Create one timeout timer when starting test case, remove it at | |
| 895 // the end. | |
| 896 timeoutTimer = new Timer(1000 * testCase.timeout, timeoutHandler); | |
| 897 } | |
| 898 // If the timeout fired in between two commands, kill the just | |
| 899 // started process immediately. | |
| 900 if (timedOut) safeKill(process); | |
| 901 }); | |
| 902 processFuture.handleException((e) { | |
| 903 print("Process error:"); | |
| 904 print(" Command: $command"); | |
| 905 print(" Error: $e"); | |
| 906 testComplete(createCommandOutput(command, -1, false)); | |
| 907 return true; | |
| 908 }); | |
| 802 } | 909 } |
| 803 // If the timeout fired in between two commands, kill the just | |
| 804 // started process immediately. | |
| 805 if (timedOut) safeKill(process); | |
| 806 }); | |
| 807 processFuture.handleException((e) { | |
| 808 print("Process error:"); | |
| 809 print(" Command: $command"); | |
| 810 print(" Error: $e"); | |
| 811 testComplete(createCommandOutput(command, -1, false)); | |
| 812 return true; | |
| 813 }); | 910 }); |
| 814 } | 911 } |
| 815 | 912 |
| 816 void timeoutHandler(Timer unusedTimer) { | 913 void timeoutHandler(Timer unusedTimer) { |
| 817 timedOut = true; | 914 timedOut = true; |
| 818 safeKill(process); | 915 safeKill(process); |
| 819 } | 916 } |
| 820 | 917 |
| 821 void safeKill(Process p) { | 918 void safeKill(Process p) { |
| 822 if (p != null) { | 919 if (p != null) { |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 952 var exitCode = 0; | 1049 var exitCode = 0; |
| 953 if (outcome == "CRASH") exitCode = -10; | 1050 if (outcome == "CRASH") exitCode = -10; |
| 954 if (outcome == "FAIL" || outcome == "TIMEOUT") exitCode = 1; | 1051 if (outcome == "FAIL" || outcome == "TIMEOUT") exitCode = 1; |
| 955 new CommandOutput.fromCase(_currentTest, | 1052 new CommandOutput.fromCase(_currentTest, |
| 956 _command, | 1053 _command, |
| 957 exitCode, | 1054 exitCode, |
| 958 false, | 1055 false, |
| 959 (outcome == "TIMEOUT"), | 1056 (outcome == "TIMEOUT"), |
| 960 _testStdout, | 1057 _testStdout, |
| 961 _testStderr, | 1058 _testStderr, |
| 962 new Date.now().difference(_startTime)); | 1059 new Date.now().difference(_startTime), |
| 1060 false); | |
| 963 var test = _currentTest; | 1061 var test = _currentTest; |
| 964 _currentTest = null; | 1062 _currentTest = null; |
| 965 test.completed(); | 1063 test.completed(); |
| 966 } | 1064 } |
| 967 | 1065 |
| 968 void _stderrDone() { | 1066 void _stderrDone() { |
| 969 _stderrDrained = true; | 1067 _stderrDrained = true; |
| 970 // Move on when both stdout and stderr has been drained. | 1068 // Move on when both stdout and stderr has been drained. |
| 971 if (_stdoutDrained) _reportResult(); | 1069 if (_stdoutDrained) _reportResult(); |
| 972 } | 1070 } |
| (...skipping 444 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1417 // the developer doesn't waste his or her time trying to fix a bunch of | 1515 // the developer doesn't waste his or her time trying to fix a bunch of |
| 1418 // tests that appear to be broken but were actually just flakes that | 1516 // tests that appear to be broken but were actually just flakes that |
| 1419 // didn't get retried because there had already been one failure. | 1517 // didn't get retried because there had already been one failure. |
| 1420 bool allowRetry = _MAX_FAILED_NO_RETRY > _progress.numFailedTests; | 1518 bool allowRetry = _MAX_FAILED_NO_RETRY > _progress.numFailedTests; |
| 1421 new RunningProcess(test, allowRetry, this).start(); | 1519 new RunningProcess(test, allowRetry, this).start(); |
| 1422 } | 1520 } |
| 1423 _numProcesses++; | 1521 _numProcesses++; |
| 1424 } | 1522 } |
| 1425 } | 1523 } |
| 1426 } | 1524 } |
| OLD | NEW |