| 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. |
| (...skipping 330 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 341 | 341 |
| 342 void runCommand(Command command, | 342 void runCommand(Command command, |
| 343 void exitHandler(int exitCode)) { | 343 void exitHandler(int exitCode)) { |
| 344 if (new Platform().operatingSystem() == 'windows') { | 344 if (new Platform().operatingSystem() == 'windows') { |
| 345 // Windows can't handle the first command if it is a .bat file or the like | 345 // Windows can't handle the first command if it is a .bat file or the like |
| 346 // with the slashes going the other direction. | 346 // with the slashes going the other direction. |
| 347 // TODO(efortuna): Remove this when fixed (Issue 1306). | 347 // TODO(efortuna): Remove this when fixed (Issue 1306). |
| 348 command.executable = command.executable.replaceAll('/', '\\'); | 348 command.executable = command.executable.replaceAll('/', '\\'); |
| 349 } | 349 } |
| 350 process = new Process.start(command.executable, command.arguments); | 350 process = new Process.start(command.executable, command.arguments); |
| 351 process.exitHandler = exitHandler; | 351 process.onExit = exitHandler; |
| 352 startTime = new Date.now(); | 352 startTime = new Date.now(); |
| 353 InputStream stdoutStream = process.stdout; | 353 InputStream stdoutStream = process.stdout; |
| 354 InputStream stderrStream = process.stderr; | 354 InputStream stderrStream = process.stderr; |
| 355 StringInputStream stdoutStringStream = new StringInputStream(stdoutStream); | 355 StringInputStream stdoutStringStream = new StringInputStream(stdoutStream); |
| 356 StringInputStream stderrStringStream = new StringInputStream(stderrStream); | 356 StringInputStream stderrStringStream = new StringInputStream(stderrStream); |
| 357 stdoutStringStream.lineHandler = | 357 stdoutStringStream.onLine = |
| 358 _makeReadHandler(stdoutStringStream, stdout); | 358 _makeReadHandler(stdoutStringStream, stdout); |
| 359 stderrStringStream.lineHandler = | 359 stderrStringStream.onLine = |
| 360 _makeReadHandler(stderrStringStream, stderr); | 360 _makeReadHandler(stderrStringStream, stderr); |
| 361 timeoutTimer = new Timer(timeoutHandler, 1000 * testCase.timeout); | 361 timeoutTimer = new Timer(timeoutHandler, 1000 * testCase.timeout); |
| 362 } | 362 } |
| 363 | 363 |
| 364 void timeoutHandler(Timer unusedTimer) { | 364 void timeoutHandler(Timer unusedTimer) { |
| 365 timedOut = true; | 365 timedOut = true; |
| 366 process.kill(); | 366 process.kill(); |
| 367 } | 367 } |
| 368 } | 368 } |
| 369 | 369 |
| (...skipping 27 matching lines...) Expand all Loading... |
| 397 // Start process if not yet started. | 397 // Start process if not yet started. |
| 398 _executable = testCase.commands.last().executable; | 398 _executable = testCase.commands.last().executable; |
| 399 _startProcess(() { | 399 _startProcess(() { |
| 400 doStartTest(testCase); | 400 doStartTest(testCase); |
| 401 }); | 401 }); |
| 402 } else if (testCase.commands.last().executable != _executable) { | 402 } else if (testCase.commands.last().executable != _executable) { |
| 403 // Restart this runner with the right executable for this test | 403 // Restart this runner with the right executable for this test |
| 404 // if needed. | 404 // if needed. |
| 405 _executable = testCase.commands.last().executable; | 405 _executable = testCase.commands.last().executable; |
| 406 _batchArguments = testCase.batchRunnerArguments; | 406 _batchArguments = testCase.batchRunnerArguments; |
| 407 _process.exitHandler = (exitCode) { | 407 _process.onExit = (exitCode) { |
| 408 _process.close(); | 408 _process.close(); |
| 409 _startProcess(() { | 409 _startProcess(() { |
| 410 doStartTest(testCase); | 410 doStartTest(testCase); |
| 411 }); | 411 }); |
| 412 }; | 412 }; |
| 413 _process.kill(); | 413 _process.kill(); |
| 414 } else { | 414 } else { |
| 415 doStartTest(testCase); | 415 doStartTest(testCase); |
| 416 } | 416 } |
| 417 } | 417 } |
| 418 | 418 |
| 419 void terminate() { | 419 void terminate() { |
| 420 if (_process !== null) { | 420 if (_process !== null) { |
| 421 bool closed = false; | 421 bool closed = false; |
| 422 _process.exitHandler = (exitCode) { | 422 _process.onExit = (exitCode) { |
| 423 closed = true; | 423 closed = true; |
| 424 _process.close(); | 424 _process.close(); |
| 425 }; | 425 }; |
| 426 if (_isWebDriver) { | 426 if (_isWebDriver) { |
| 427 // Use a graceful shutdown so our Selenium script can close | 427 // Use a graceful shutdown so our Selenium script can close |
| 428 // the open browser processes. TODO(jmesserly): Send a signal once | 428 // the open browser processes. TODO(jmesserly): Send a signal once |
| 429 // that's supported, see dartbug.com/1756. | 429 // that's supported, see dartbug.com/1756. |
| 430 _process.stdin.write('--terminate\n'.charCodes()); | 430 _process.stdin.write('--terminate\n'.charCodes()); |
| 431 | 431 |
| 432 // In case the run_selenium process didn't close, kill it after 30s | 432 // In case the run_selenium process didn't close, kill it after 30s |
| 433 bool shutdownMillisecs = 30000; | 433 bool shutdownMillisecs = 30000; |
| 434 new Timer((e) { if (!closed) _process.kill(); }, shutdownMillisecs); | 434 new Timer((e) { if (!closed) _process.kill(); }, shutdownMillisecs); |
| 435 } else { | 435 } else { |
| 436 _process.kill(); | 436 _process.kill(); |
| 437 } | 437 } |
| 438 } | 438 } |
| 439 } | 439 } |
| 440 | 440 |
| 441 void doStartTest(TestCase testCase) { | 441 void doStartTest(TestCase testCase) { |
| 442 _startTime = new Date.now(); | 442 _startTime = new Date.now(); |
| 443 _testStdout = []; | 443 _testStdout = []; |
| 444 _testStderr = []; | 444 _testStderr = []; |
| 445 _stdoutStream.lineHandler = _readStdout(_stdoutStream, _testStdout); | 445 _stdoutStream.onLine = _readStdout(_stdoutStream, _testStdout); |
| 446 _stderrStream.lineHandler = _makeReadHandler(_stderrStream, _testStderr); | 446 _stderrStream.onLine = _makeReadHandler(_stderrStream, _testStderr); |
| 447 _timer = new Timer(_timeoutHandler, testCase.timeout * 1000); | 447 _timer = new Timer(_timeoutHandler, testCase.timeout * 1000); |
| 448 var line = _createArgumentsLine(testCase.batchTestArguments); | 448 var line = _createArgumentsLine(testCase.batchTestArguments); |
| 449 _process.stdin.write(line.charCodes()); | 449 _process.stdin.write(line.charCodes()); |
| 450 } | 450 } |
| 451 | 451 |
| 452 String _createArgumentsLine(List<String> arguments) { | 452 String _createArgumentsLine(List<String> arguments) { |
| 453 return Strings.join(arguments, ' ') + '\n'; | 453 return Strings.join(arguments, ' ') + '\n'; |
| 454 } | 454 } |
| 455 | 455 |
| 456 // This removes the line handler from stderr and reads all | 456 // This removes the line handler from stderr and reads all |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 528 } | 528 } |
| 529 | 529 |
| 530 void _exitHandler(exitCode) { | 530 void _exitHandler(exitCode) { |
| 531 if (_timer != null) _timer.cancel(); | 531 if (_timer != null) _timer.cancel(); |
| 532 _reportResult(">>> TEST CRASH"); | 532 _reportResult(">>> TEST CRASH"); |
| 533 _process.close(); | 533 _process.close(); |
| 534 _startProcess(); | 534 _startProcess(); |
| 535 } | 535 } |
| 536 | 536 |
| 537 void _timeoutHandler(ignore) { | 537 void _timeoutHandler(ignore) { |
| 538 _process.exitHandler = (exitCode) {_ | 538 _process.onExit = (exitCode) { |
| 539 reportResult(">>> TEST TIMEOUT"); | 539 reportResult(">>> TEST TIMEOUT"); |
| 540 _process.close(); | 540 _process.close(); |
| 541 _startProcess(); | 541 _startProcess(); |
| 542 }; | 542 }; |
| 543 _process.kill(); | 543 _process.kill(); |
| 544 } | 544 } |
| 545 | 545 |
| 546 void _startProcess([Function then = null]) { | 546 void _startProcess([Function then = null]) { |
| 547 _process = new Process.start(_executable, _batchArguments); | 547 _process = new Process.start(_executable, _batchArguments); |
| 548 _stdoutStream = new StringInputStream(_process.stdout); | 548 _stdoutStream = new StringInputStream(_process.stdout); |
| 549 _stderrStream = new StringInputStream(_process.stderr); | 549 _stderrStream = new StringInputStream(_process.stderr); |
| 550 _testStdout = []; | 550 _testStdout = []; |
| 551 _testStderr = []; | 551 _testStderr = []; |
| 552 _stdoutStream.lineHandler = _readStdout(_stdoutStream, _testStdout); | 552 _stdoutStream.onLine = _readStdout(_stdoutStream, _testStdout); |
| 553 _stderrStream.lineHandler =_makeReadHandler(_stderrStream, _testStderr); | 553 _stderrStream.onLine =_makeReadHandler(_stderrStream, _testStderr); |
| 554 _process.exitHandler = _exitHandler; | 554 _process.onExit = _exitHandler; |
| 555 _process.startHandler = then; | 555 _process.onStart = then; |
| 556 } | 556 } |
| 557 } | 557 } |
| 558 | 558 |
| 559 /** | 559 /** |
| 560 * ProcessQueue is the master control class, responsible for running all | 560 * ProcessQueue is the master control class, responsible for running all |
| 561 * the tests in all the TestSuites that have been registered. It includes | 561 * the tests in all the TestSuites that have been registered. It includes |
| 562 * a rate-limited queue to run a limited number of tests in parallel, | 562 * a rate-limited queue to run a limited number of tests in parallel, |
| 563 * a ProgressIndicator which prints output when tests are started and | 563 * a ProgressIndicator which prints output when tests are started and |
| 564 * and completed, and a summary report when all tests are completed, | 564 * and completed, and a summary report when all tests are completed, |
| 565 * and counters to determine when all of the tests in all of the test suites | 565 * and counters to determine when all of the tests in all of the test suites |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 658 Process process = null; | 658 Process process = null; |
| 659 if (new Platform().operatingSystem() == 'windows') { | 659 if (new Platform().operatingSystem() == 'windows') { |
| 660 process = new Process.start( | 660 process = new Process.start( |
| 661 'C:\\Windows\\System32\\taskkill.exe', ['/F', '/IM', name + '.exe', | 661 'C:\\Windows\\System32\\taskkill.exe', ['/F', '/IM', name + '.exe', |
| 662 '/T']); | 662 '/T']); |
| 663 } else { | 663 } else { |
| 664 process = new Process.start('killall', ['-9', name]); | 664 process = new Process.start('killall', ['-9', name]); |
| 665 } | 665 } |
| 666 | 666 |
| 667 if (name == processNames[browserUsed].last()) { | 667 if (name == processNames[browserUsed].last()) { |
| 668 process.exitHandler = (exitCode) { | 668 process.onExit = (exitCode) { |
| 669 process.close(); | 669 process.close(); |
| 670 _progress.allDone(); | 670 _progress.allDone(); |
| 671 }; | 671 }; |
| 672 process.errorHandler = (error) { | 672 process.onError = (error) { |
| 673 _progress.allDone(); | 673 _progress.allDone(); |
| 674 }; | 674 }; |
| 675 } else { | 675 } else { |
| 676 process.exitHandler = (exitCode) { | 676 process.onExit = (exitCode) { |
| 677 process.close(); | 677 process.close(); |
| 678 }; | 678 }; |
| 679 } | 679 } |
| 680 } | 680 } |
| 681 } | 681 } |
| 682 | 682 |
| 683 /** | 683 /** |
| 684 * Perform any cleanup needed once all tests in a TestSuite have completed | 684 * Perform any cleanup needed once all tests in a TestSuite have completed |
| 685 * and notify our progress indicator that we are done. | 685 * and notify our progress indicator that we are done. |
| 686 */ | 686 */ |
| (...skipping 17 matching lines...) Expand all Loading... |
| 704 } else if (!_temporaryDirectory.startsWith('/tmp/') || | 704 } else if (!_temporaryDirectory.startsWith('/tmp/') || |
| 705 _temporaryDirectory.contains('/../')) { | 705 _temporaryDirectory.contains('/../')) { |
| 706 // Let's be extra careful, since rm -rf is so dangerous. | 706 // Let's be extra careful, since rm -rf is so dangerous. |
| 707 print('Temporary directory $_temporaryDirectory unsafe to delete!'); | 707 print('Temporary directory $_temporaryDirectory unsafe to delete!'); |
| 708 _cleanupAndMarkDone(); | 708 _cleanupAndMarkDone(); |
| 709 } else { | 709 } else { |
| 710 // TODO(dart:1211): Use delete(recursive=true) in Dart when it is | 710 // TODO(dart:1211): Use delete(recursive=true) in Dart when it is |
| 711 // implemented, and add Windows support. | 711 // implemented, and add Windows support. |
| 712 var deletion = | 712 var deletion = |
| 713 new Process.start('/bin/rm', ['-rf', _temporaryDirectory]); | 713 new Process.start('/bin/rm', ['-rf', _temporaryDirectory]); |
| 714 deletion.exitHandler = (int exitCode) { | 714 deletion.onExit = (int exitCode) { |
| 715 if (exitCode == 0) { | 715 if (exitCode == 0) { |
| 716 if (!_listTests) { // Output of --list option is used by scripts. | 716 if (!_listTests) { // Output of --list option is used by scripts. |
| 717 print('\nTemporary directory $_temporaryDirectory deleted.'); | 717 print('\nTemporary directory $_temporaryDirectory deleted.'); |
| 718 } | 718 } |
| 719 } else { | 719 } else { |
| 720 print('\nDeletion of temp dir $_temporaryDirectory failed.'); | 720 print('\nDeletion of temp dir $_temporaryDirectory failed.'); |
| 721 } | 721 } |
| 722 _cleanupAndMarkDone(); | 722 _cleanupAndMarkDone(); |
| 723 }; | 723 }; |
| 724 } | 724 } |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 807 if (source.closed) return; // TODO(whesse): Remove when bug is fixed. | 807 if (source.closed) return; // TODO(whesse): Remove when bug is fixed. |
| 808 var line = source.readLine(); | 808 var line = source.readLine(); |
| 809 while (null != line) { | 809 while (null != line) { |
| 810 destination.add(line); | 810 destination.add(line); |
| 811 line = source.readLine(); | 811 line = source.readLine(); |
| 812 } | 812 } |
| 813 }; | 813 }; |
| 814 } | 814 } |
| 815 | 815 |
| 816 | 816 |
| OLD | NEW |