| Index: tools/testing/dart/test_runner.dart
|
| ===================================================================
|
| --- tools/testing/dart/test_runner.dart (revision 4831)
|
| +++ tools/testing/dart/test_runner.dart (working copy)
|
| @@ -128,6 +128,8 @@
|
| List<String> get batchTestArguments() => commands.last().arguments;
|
|
|
| void completed() { completedHandler(this); }
|
| +
|
| + bool get usesWebDriver() => configuration['component'] == 'webdriver';
|
| }
|
|
|
|
|
| @@ -286,8 +288,8 @@
|
| for (var line in testCase.output.stdout) print(line);
|
| }
|
| if (allowRetries != null && allowRetries
|
| - && testCase.configuration['component'] == 'webdriver' &&
|
| - testCase.output.unexpectedOutput && testCase.numRetries > 0) {
|
| + && testCase.usesWebDriver && testCase.output.unexpectedOutput
|
| + && testCase.numRetries > 0) {
|
| // Selenium tests can be flaky. Try rerunning.
|
| testCase.output.requestRetry = true;
|
| }
|
| @@ -321,8 +323,8 @@
|
| } else {
|
| stderr.add('test.dart: Compilion finished $suffix\n');
|
| stdout.add('test.dart: Compilion finished $suffix\n');
|
| - if (currentStep == totalSteps - 1
|
| - && testCase.configuration['component'] == 'webdriver') {
|
| + if (currentStep == totalSteps - 1 && testCase.usesWebDriver &&
|
| + !testCase.configuration['noBatch']) {
|
| // Note: processQueue will always be non-null for component == webdriver
|
| // (It is only null for component == vm)
|
| processQueue._getBatchRunner(testCase).startTest(testCase);
|
| @@ -400,7 +402,7 @@
|
| BatchRunnerProcess(TestCase testCase) {
|
| _executable = testCase.commands.last().executable;
|
| _batchArguments = testCase.batchRunnerArguments;
|
| - _isWebDriver = testCase.configuration['component'] == 'webdriver';
|
| + _isWebDriver = testCase.usesWebDriver;
|
| }
|
|
|
| bool get active() => _currentTest != null;
|
| @@ -605,7 +607,14 @@
|
| * String indicating the browser used to run the tests. Empty if no browser
|
| * used.
|
| */
|
| - String browserUsed;
|
| + String browserUsed = '';
|
| + /**
|
| + * Process running the selenium server .jar (only used for Safari and Opera
|
| + * tests.)
|
| + */
|
| + Process _seleniumServer = null;
|
| + /** True if we are in the process of starting the server. */
|
| + bool _startingServer = false;
|
|
|
| ProcessQueue(int this._maxProcesses,
|
| String progress,
|
| @@ -622,7 +631,6 @@
|
| _batchProcesses = new Map<String, List<BatchRunnerProcess>>(),
|
| _testCache = new Map<String, List<TestInformation>>() {
|
| if (!_enqueueMoreWork(this)) _progress.allDone();
|
| - browserUsed = '';
|
| }
|
|
|
| /**
|
| @@ -698,6 +706,9 @@
|
| void _cleanupAndMarkDone() {
|
| if (browserUsed != '') {
|
| killZombieBrowsers();
|
| + if (_isSeleniumAvailable) {
|
| + _seleniumServer.kill();
|
| + }
|
| } else {
|
| _progress.allDone();
|
| }
|
| @@ -736,16 +747,92 @@
|
| }
|
| }
|
| }
|
| +
|
| + /**
|
| + * True if we are using a browser + platform combination that needs the
|
| + * Selenium server jar.
|
| + */
|
| + bool get _needsSelenium() => new Platform().operatingSystem() == 'macos' &&
|
| + browserUsed == 'safari';
|
|
|
| + /** True if the Selenium Server is ready to be used. */
|
| + bool get _isSeleniumAvailable() => _seleniumServer != null;
|
| +
|
| + /** Start the Selenium Server jar, if appropriate for this platform. */
|
| + void _ensureSeleniumServerRunning() {
|
| + if (!_isSeleniumAvailable && _startingServer == false) {
|
| + _startingServer = true;
|
| + _startSeleniumServer();
|
| + }
|
| + }
|
| +
|
| void _runTest(TestCase test) {
|
| - if (test.configuration['component'] == 'webdriver') {
|
| + if (test.usesWebDriver) {
|
| browserUsed = test.configuration['browser'];
|
| + if (_needsSelenium) _ensureSeleniumServerRunning();
|
| }
|
| _progress.testAdded();
|
| _tests.add(test);
|
| _tryRunTest();
|
| }
|
|
|
| + /**
|
| + * Monitor the output of the Selenium server, to know when we are ready to
|
| + * begin running tests.
|
| + * source: Output(Stream) from the Java server.
|
| + */
|
| + Function makeSeleniumServerHandler(StringInputStream source) {
|
| + return () {
|
| + if (source.closed) return; // TODO(whesse): Remove when bug is fixed.
|
| + var line = source.readLine();
|
| + while (null != line) {
|
| + if (const RegExp(@".*Started.*Server.*").hasMatch(line) ||
|
| + const RegExp(@"Exception.*Selenium is already running.*").hasMatch(
|
| + line)) {
|
| + for (int i = 0; i < _maxProcesses; i++) {
|
| + // Restart all the processes that have been waiting/stopped for
|
| + // the server to start up. If we just call this once we end up
|
| + // with a single-"threaded" run.
|
| + _tryRunTest();
|
| + }
|
| + }
|
| + line = source.readLine();
|
| + }
|
| + };
|
| + }
|
| +
|
| + /**
|
| + * For browser tests using Safari or Opera, we need to use the Selenium 1.0
|
| + * Java server.
|
| + */
|
| + void _startSeleniumServer() {
|
| + // Get the absolute path to the Selenium jar.
|
| + String filePath = new Options().script;
|
| + String pathSep = new Platform().pathSeparator();
|
| + int index = filePath.lastIndexOf(pathSep);
|
| + filePath = filePath.substring(0, index) + '${pathSep}testing${pathSep}';
|
| + var dir = new Directory(filePath);
|
| + dir.onFile = (String file) {
|
| + if (const RegExp(@"selenium-server-standalone-.*\.jar").hasMatch(file)
|
| + && _seleniumServer == null) {
|
| + _seleniumServer = new Process.start('java', ['-jar', file]);
|
| + // Heads up: there seems to an obscure data race of some form in
|
| + // the VM between launching the server process and launching the test
|
| + // tasks that disappears when you read IO (which is convenient, since
|
| + // that is our condition for knowing that the server is ready).
|
| + StringInputStream stdoutStringStream =
|
| + new StringInputStream(_seleniumServer.stdout);
|
| + StringInputStream stderrStringStream =
|
| + new StringInputStream(_seleniumServer.stderr);
|
| + stdoutStringStream.onLine =
|
| + makeSeleniumServerHandler(stdoutStringStream);
|
| + stderrStringStream.onLine =
|
| + makeSeleniumServerHandler(stderrStringStream);
|
| + }
|
| + };
|
| + dir.list();
|
| + }
|
| +
|
| void _terminateBatchRunners() {
|
| for (var runners in _batchProcesses.getValues()) {
|
| for (var runner in runners) {
|
| @@ -785,6 +872,12 @@
|
| tab + Strings.join(test.commands.last().arguments, tab));
|
| return;
|
| }
|
| + if (test.usesWebDriver && _needsSelenium && !_isSeleniumAvailable) {
|
| + // The server is not ready to run Selenium tests. Put them back in the
|
| + // queue.
|
| + _tests.addFirst(test);
|
| + return;
|
| + }
|
| _progress.start(test);
|
| Function oldCallback = test.completedHandler;
|
| Function wrapper = (TestCase test_arg) {
|
|
|