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 |