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. |
| (...skipping 1408 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1419 * and counters to determine when all of the tests in all of the test suites | 1419 * and counters to determine when all of the tests in all of the test suites |
| 1420 * have completed. | 1420 * have completed. |
| 1421 * | 1421 * |
| 1422 * Because multiple configurations may be run on each test suite, the | 1422 * Because multiple configurations may be run on each test suite, the |
| 1423 * ProcessQueue contains a cache in which a test suite may record information | 1423 * ProcessQueue contains a cache in which a test suite may record information |
| 1424 * about its list of tests, and may retrieve that information when it is called | 1424 * about its list of tests, and may retrieve that information when it is called |
| 1425 * upon to enqueue its tests again. | 1425 * upon to enqueue its tests again. |
| 1426 */ | 1426 */ |
| 1427 class ProcessQueue { | 1427 class ProcessQueue { |
| 1428 int _numProcesses = 0; | 1428 int _numProcesses = 0; |
| 1429 int _activeTestListers = 0; | |
| 1430 int _maxProcesses; | 1429 int _maxProcesses; |
| 1430 bool _allTestsWereEnqueued = false; | |
| 1431 | 1431 |
| 1432 /** The number of tests we allow to actually fail before we stop retrying. */ | 1432 /** The number of tests we allow to actually fail before we stop retrying. */ |
| 1433 int _MAX_FAILED_NO_RETRY = 4; | 1433 int _MAX_FAILED_NO_RETRY = 4; |
| 1434 bool _verbose; | 1434 bool _verbose; |
| 1435 bool _listTests; | 1435 bool _listTests; |
| 1436 Function _allDone; | 1436 Function _allDone; |
| 1437 EnqueueMoreWork _enqueueMoreWork; | |
| 1438 Queue<TestCase> _tests; | 1437 Queue<TestCase> _tests; |
| 1439 ProgressIndicator _progress; | 1438 ProgressIndicator _progress; |
| 1440 | 1439 |
| 1441 // For dartc/selenium batch processing we keep a list of batch processes. | 1440 // For dartc/selenium batch processing we keep a list of batch processes. |
| 1442 Map<String, List<BatchRunnerProcess>> _batchProcesses; | 1441 Map<String, List<BatchRunnerProcess>> _batchProcesses; |
| 1443 | 1442 |
| 1444 // Cache information about test cases per test suite. For multiple | 1443 // Cache information about test cases per test suite. For multiple |
| 1445 // configurations there is no need to repeatedly search the file | 1444 // configurations there is no need to repeatedly search the file |
| 1446 // system, generate tests, and search test files for options. | 1445 // system, generate tests, and search test files for options. |
| 1447 Map<String, List<TestInformation>> _testCache; | 1446 Map<String, List<TestInformation>> _testCache; |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 1461 /** True if we are in the process of starting the server. */ | 1460 /** True if we are in the process of starting the server. */ |
| 1462 bool _startingServer = false; | 1461 bool _startingServer = false; |
| 1463 | 1462 |
| 1464 /** True if we find that there is already a selenium jar running. */ | 1463 /** True if we find that there is already a selenium jar running. */ |
| 1465 bool _seleniumAlreadyRunning = false; | 1464 bool _seleniumAlreadyRunning = false; |
| 1466 | 1465 |
| 1467 ProcessQueue(int this._maxProcesses, | 1466 ProcessQueue(int this._maxProcesses, |
| 1468 String progress, | 1467 String progress, |
| 1469 Date startTime, | 1468 Date startTime, |
| 1470 bool printTiming, | 1469 bool printTiming, |
| 1471 this._enqueueMoreWork, | 1470 testSuites, |
| 1472 this._allDone, | 1471 this._allDone, |
| 1473 [bool verbose = false, | 1472 [bool verbose = false, |
| 1474 bool listTests = false]) | 1473 bool listTests = false]) |
| 1475 : _verbose = verbose, | 1474 : _verbose = verbose, |
| 1476 _listTests = listTests, | 1475 _listTests = listTests, |
| 1477 _tests = new Queue<TestCase>(), | 1476 _tests = new Queue<TestCase>(), |
| 1478 _progress = new ProgressIndicator.fromName(progress, | 1477 _progress = new ProgressIndicator.fromName(progress, |
| 1479 startTime, | 1478 startTime, |
| 1480 printTiming), | 1479 printTiming), |
| 1481 _batchProcesses = new Map<String, List<BatchRunnerProcess>>(), | 1480 _batchProcesses = new Map<String, List<BatchRunnerProcess>>(), |
| 1482 _testCache = new Map<String, List<TestInformation>>() { | 1481 _testCache = new Map<String, List<TestInformation>>() { |
| 1483 _checkDone(); | 1482 _runTests(testSuites); |
| 1484 } | 1483 } |
| 1485 | 1484 |
| 1486 /** | 1485 /** |
| 1487 * Registers a TestSuite so that all of its tests will be run. | |
| 1488 */ | |
| 1489 void addTestSuite(TestSuite testSuite) { | |
| 1490 _activeTestListers++; | |
| 1491 testSuite.forEachTest(_runTest, _testCache, _testListerDone); | |
| 1492 } | |
| 1493 | |
| 1494 void _testListerDone() { | |
| 1495 _activeTestListers--; | |
| 1496 _checkDone(); | |
| 1497 } | |
| 1498 | |
| 1499 /** | |
| 1500 * Perform any cleanup needed once all tests in a TestSuite have completed | 1486 * Perform any cleanup needed once all tests in a TestSuite have completed |
| 1501 * and notify our progress indicator that we are done. | 1487 * and notify our progress indicator that we are done. |
| 1502 */ | 1488 */ |
| 1503 void _cleanupAndMarkDone() { | 1489 void _cleanupAndMarkDone() { |
| 1504 _allDone(); | 1490 _allDone(); |
| 1505 if (browserUsed != '' && _seleniumServer != null) { | 1491 if (browserUsed != '' && _seleniumServer != null) { |
| 1506 _seleniumServer.kill(); | 1492 _seleniumServer.kill(); |
| 1507 } else { | 1493 } else { |
| 1508 _progress.allDone(); | 1494 _progress.allDone(); |
| 1509 } | 1495 } |
| 1510 } | 1496 } |
| 1511 | 1497 |
| 1512 void _checkDone() { | 1498 void _runTests(List<TestSuite> testSuites) { |
| 1513 // When there are no more active test listers ask for more work | 1499 var numberOfTestSuitesFinished = 0; |
| 1514 // from process queue users. | 1500 |
| 1515 if (_activeTestListers == 0) { | 1501 void testSuiteFinished() { |
|
ricow1
2013/01/15 12:38:44
how about making this:
void _runTests(List<TestSui
kustermann
2013/01/16 09:09:09
Done.
| |
| 1516 _enqueueMoreWork(this); | 1502 numberOfTestSuitesFinished++; |
| 1517 } | 1503 if (numberOfTestSuitesFinished == testSuites.length) { |
| 1518 // If there is still no work, we are done. | 1504 _allTestsWereEnqueued = true; |
| 1519 if (_activeTestListers == 0) { | 1505 _progress.allTestsKnown(); |
| 1520 _progress.allTestsKnown(); | 1506 } else { |
| 1521 if (_tests.isEmpty && _numProcesses == 0) { | 1507 testSuites[numberOfTestSuitesFinished].forEachTest(_runTest, |
| 1522 _terminateBatchRunners().then((_) => _cleanupAndMarkDone()); | 1508 _testCache, |
| 1509 testSuiteFinished); | |
| 1523 } | 1510 } |
| 1524 } | 1511 } |
| 1512 // FIXME: For some reason we cannot call this method on all test suites | |
|
ricow1
2013/01/15 12:38:44
could we file a bug for this
kustermann
2013/01/16 09:09:09
Done.
| |
| 1513 // in parallel. | |
| 1514 // If we do, not all tests get enqueued (if --arch=all was specified, | |
| 1515 // we don't get twice the number of tests [tested on -rvm -cnone]) | |
| 1516 testSuites[0].forEachTest(_runTest, | |
| 1517 _testCache, | |
| 1518 testSuiteFinished); | |
| 1525 } | 1519 } |
| 1526 | 1520 |
| 1527 /** | 1521 /** |
| 1528 * True if we are using a browser + platform combination that needs the | 1522 * True if we are using a browser + platform combination that needs the |
| 1529 * Selenium server jar. | 1523 * Selenium server jar. |
| 1530 */ | 1524 */ |
| 1531 bool get _needsSelenium => (io.Platform.operatingSystem == 'macos' && | 1525 bool get _needsSelenium => (io.Platform.operatingSystem == 'macos' && |
| 1532 browserUsed == 'safari') || browserUsed == 'opera'; | 1526 browserUsed == 'safari') || browserUsed == 'opera'; |
| 1533 | 1527 |
| 1534 /** True if the Selenium Server is ready to be used. */ | 1528 /** True if the Selenium Server is ready to be used. */ |
| (...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1682 _batchProcesses[compiler] = runners; | 1676 _batchProcesses[compiler] = runners; |
| 1683 } | 1677 } |
| 1684 | 1678 |
| 1685 for (var runner in runners) { | 1679 for (var runner in runners) { |
| 1686 if (!runner.active) return runner; | 1680 if (!runner.active) return runner; |
| 1687 } | 1681 } |
| 1688 throw new Exception('Unable to find inactive batch runner.'); | 1682 throw new Exception('Unable to find inactive batch runner.'); |
| 1689 } | 1683 } |
| 1690 | 1684 |
| 1691 void _tryRunTest() { | 1685 void _tryRunTest() { |
| 1692 _checkDone(); | 1686 if (_allTestsWereEnqueued && _tests.isEmpty && _numProcesses == 0) { |
| 1687 _terminateBatchRunners().then((_) => _cleanupAndMarkDone()); | |
| 1688 } | |
| 1693 if (_numProcesses < _maxProcesses && !_tests.isEmpty) { | 1689 if (_numProcesses < _maxProcesses && !_tests.isEmpty) { |
| 1694 TestCase test = _tests.removeFirst(); | 1690 TestCase test = _tests.removeFirst(); |
| 1695 if (_listTests) { | 1691 if (_listTests) { |
| 1696 var fields = [test.displayName, | 1692 var fields = [test.displayName, |
| 1697 Strings.join(new List.from(test.expectedOutcomes), ','), | 1693 Strings.join(new List.from(test.expectedOutcomes), ','), |
| 1698 test.isNegative.toString()]; | 1694 test.isNegative.toString()]; |
| 1699 fields.addAll(test.commands.last.arguments); | 1695 fields.addAll(test.commands.last.arguments); |
| 1700 print(Strings.join(fields, '\t')); | 1696 print(Strings.join(fields, '\t')); |
| 1701 return; | 1697 return; |
| 1702 } | 1698 } |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1751 // the developer doesn't waste his or her time trying to fix a bunch of | 1747 // the developer doesn't waste his or her time trying to fix a bunch of |
| 1752 // tests that appear to be broken but were actually just flakes that | 1748 // tests that appear to be broken but were actually just flakes that |
| 1753 // didn't get retried because there had already been one failure. | 1749 // didn't get retried because there had already been one failure. |
| 1754 bool allowRetry = _MAX_FAILED_NO_RETRY > _progress.numFailedTests; | 1750 bool allowRetry = _MAX_FAILED_NO_RETRY > _progress.numFailedTests; |
| 1755 new RunningProcess(test, allowRetry, this).start(); | 1751 new RunningProcess(test, allowRetry, this).start(); |
| 1756 } | 1752 } |
| 1757 _numProcesses++; | 1753 _numProcesses++; |
| 1758 } | 1754 } |
| 1759 } | 1755 } |
| 1760 } | 1756 } |
| OLD | NEW |