| Index: tools/testing/dart/test_runner.dart
|
| diff --git a/tools/testing/dart/test_runner.dart b/tools/testing/dart/test_runner.dart
|
| index 4c7498d849336a91554987b3db40bf4456f8bd1a..cf54160f755cc1e648d3e0ca9988f400738e3f7e 100644
|
| --- a/tools/testing/dart/test_runner.dart
|
| +++ b/tools/testing/dart/test_runner.dart
|
| @@ -13,6 +13,7 @@
|
|
|
| #import("dart:io");
|
| #import("dart:isolate");
|
| +#import("dart:uri");
|
| #import("status_file_parser.dart");
|
| #import("test_progress.dart");
|
| #import("test_suite.dart");
|
| @@ -46,6 +47,62 @@ class Command {
|
| }
|
|
|
| String toString() => commandLine;
|
| +
|
| + Future<bool> get outputIsUpToDate => new Future.immediate(false);
|
| +}
|
| +
|
| +class Dart2JsCommand extends Command {
|
| + String _jsOutputFile;
|
| + bool _neverSkipCompilation;
|
| + List<Uri> _bootstrapDependencies;
|
| +
|
| + Dart2JsCommand(this._jsOutputFile,
|
| + this._neverSkipCompilation,
|
| + this._bootstrapDependencies,
|
| + String executable,
|
| + List<String> arguments)
|
| + : super(executable, arguments);
|
| +
|
| + Future<bool> get outputIsUpToDate {
|
| + if (_neverSkipCompilation) return new Future.immediate(false);
|
| +
|
| + Future<List<Uri>> readDepsFile(String path) {
|
| + var file = new File(new Path(path).toNativePath());
|
| + if (!file.existsSync()) {
|
| + return new Future.immediate(null);
|
| + }
|
| + return file.readAsLines().transform((List<String> lines) {
|
| + var dependencies = new List<Uri>();
|
| + for (var line in lines) {
|
| + line = line.trim();
|
| + if (line.length > 0) {
|
| + dependencies.add(new Uri(line));
|
| + }
|
| + }
|
| + return dependencies;
|
| + });
|
| + }
|
| +
|
| + return readDepsFile("$_jsOutputFile.deps").transform((dependencies) {
|
| + if (dependencies != null) {
|
| + dependencies.addAll(_bootstrapDependencies);
|
| + var jsOutputLastModified = TestUtils.lastModifiedCache.getLastModified(
|
| + new Uri.fromComponents(scheme: 'file', path: _jsOutputFile));
|
| + if (jsOutputLastModified != null) {
|
| + for (var dependency in dependencies) {
|
| + var dependencyLastModified =
|
| + TestUtils.lastModifiedCache.getLastModified(dependency);
|
| + if (dependencyLastModified == null ||
|
| + dependencyLastModified > jsOutputLastModified) {
|
| + return false;
|
| + }
|
| + }
|
| + return true;
|
| + }
|
| + }
|
| + return false;
|
| + });
|
| + }
|
| }
|
|
|
| /**
|
| @@ -262,15 +319,17 @@ abstract class CommandOutput {
|
| bool timedOut,
|
| List<String> stdout,
|
| List<String> stderr,
|
| - Duration time) {
|
| - return new CommandOutputImpl.fromCase(testCase,
|
| + Duration time,
|
| + bool compilationSkipped) {
|
| + return new CommandOutputImpl.fromCase(testCase,
|
| command,
|
| exitCode,
|
| incomplete,
|
| timedOut,
|
| stdout,
|
| stderr,
|
| - time);
|
| + time,
|
| + compilationSkipped);
|
| }
|
|
|
| bool get incomplete;
|
| @@ -296,6 +355,8 @@ abstract class CommandOutput {
|
| List<String> get stderr;
|
|
|
| List<String> get diagnostics;
|
| +
|
| + bool get compilationSkipped;
|
| }
|
|
|
| class CommandOutputImpl implements CommandOutput {
|
| @@ -311,6 +372,7 @@ class CommandOutputImpl implements CommandOutput {
|
| List<String> stderr;
|
| Duration time;
|
| List<String> diagnostics;
|
| + bool compilationSkipped;
|
|
|
| /**
|
| * A flag to indicate we have already printed a warning about ignoring the VM
|
| @@ -333,7 +395,8 @@ class CommandOutputImpl implements CommandOutput {
|
| bool this.timedOut,
|
| List<String> this.stdout,
|
| List<String> this.stderr,
|
| - Duration this.time) {
|
| + Duration this.time,
|
| + bool this.compilationSkipped) {
|
| testCase.commandOutputs[command] = this;
|
| diagnostics = [];
|
| }
|
| @@ -344,16 +407,18 @@ class CommandOutputImpl implements CommandOutput {
|
| bool timedOut,
|
| List<String> stdout,
|
| List<String> stderr,
|
| - Duration time) {
|
| + Duration time,
|
| + bool compilationSkipped) {
|
| if (testCase is BrowserTestCase) {
|
| return new BrowserCommandOutputImpl(testCase,
|
| command,
|
| - exitCode,
|
| + exitCode,
|
| incomplete,
|
| timedOut,
|
| stdout,
|
| stderr,
|
| - time);
|
| + time,
|
| + compilationSkipped);
|
| } else if (testCase.configuration['compiler'] == 'dartc') {
|
| return new AnalysisCommandOutputImpl(testCase,
|
| command,
|
| @@ -361,16 +426,18 @@ class CommandOutputImpl implements CommandOutput {
|
| timedOut,
|
| stdout,
|
| stderr,
|
| - time);
|
| + time,
|
| + compilationSkipped);
|
| }
|
| return new CommandOutputImpl(testCase,
|
| command,
|
| exitCode,
|
| - incomplete,
|
| + incomplete,
|
| timedOut,
|
| stdout,
|
| stderr,
|
| - time);
|
| + time,
|
| + compilationSkipped);
|
| }
|
|
|
| String get result =>
|
| @@ -419,7 +486,8 @@ class BrowserCommandOutputImpl extends CommandOutputImpl {
|
| timedOut,
|
| stdout,
|
| stderr,
|
| - time) :
|
| + time,
|
| + compilationSkipped) :
|
| super(testCase,
|
| command,
|
| exitCode,
|
| @@ -427,7 +495,8 @@ class BrowserCommandOutputImpl extends CommandOutputImpl {
|
| timedOut,
|
| stdout,
|
| stderr,
|
| - time);
|
| + time,
|
| + compilationSkipped);
|
|
|
| bool get didFail {
|
| // Browser case:
|
| @@ -479,14 +548,24 @@ class AnalysisCommandOutputImpl extends CommandOutputImpl {
|
|
|
| bool alreadyComputed = false;
|
| bool failResult;
|
| +
|
| AnalysisCommandOutputImpl(testCase,
|
| command,
|
| exitCode,
|
| timedOut,
|
| - stdout,
|
| + stdout,
|
| stderr,
|
| - time) :
|
| - super(testCase, command, exitCode, false, timedOut, stdout, stderr, time);
|
| + time,
|
| + compilationSkipped) :
|
| + super(testCase,
|
| + command,
|
| + exitCode,
|
| + false,
|
| + timedOut,
|
| + stdout,
|
| + stderr,
|
| + time,
|
| + compilationSkipped);
|
|
|
| bool get didFail {
|
| if (!alreadyComputed) {
|
| @@ -654,6 +733,7 @@ class RunningProcess {
|
| Timer timeoutTimer;
|
| List<String> stdout;
|
| List<String> stderr;
|
| + bool compilationSkipped;
|
| bool allowRetries;
|
|
|
| /** Which command of [testCase.commands] is currently being executed. */
|
| @@ -663,10 +743,12 @@ class RunningProcess {
|
| [this.allowRetries = false, this.processQueue]);
|
|
|
| /**
|
| - * Called when all commands are executed.
|
| + * Called when all commands are executed.
|
| */
|
| void testComplete(CommandOutput lastCommandOutput) {
|
| - timeoutTimer.cancel();
|
| + if (timeoutTimer != null) {
|
| + timeoutTimer.cancel();
|
| + }
|
| if (lastCommandOutput.unexpectedOutput
|
| && testCase.configuration['verbose'] != null
|
| && testCase.configuration['verbose']) {
|
| @@ -728,7 +810,9 @@ class RunningProcess {
|
| // ff, safari, chrome, opera. (It is only null for runtime == vm)
|
| // This RunningProcess object is done, and hands over control to
|
| // BatchRunner.startTest(), which handles reporting, etc.
|
| - timeoutTimer.cancel();
|
| + if (timeoutTimer != null) {
|
| + timeoutTimer.cancel();
|
| + }
|
| processQueue._getBatchRunner(testCase).startTest(testCase);
|
| } else {
|
| runCommand(testCase.commands[currentStep++], commandComplete);
|
| @@ -750,7 +834,8 @@ class RunningProcess {
|
| timedOut,
|
| stdout,
|
| stderr,
|
| - new Date.now().difference(startTime));
|
| + new Date.now().difference(startTime),
|
| + compilationSkipped);
|
| resetLocalOutputInformation();
|
| return commandOutput;
|
| }
|
| @@ -758,8 +843,9 @@ class RunningProcess {
|
| void resetLocalOutputInformation() {
|
| stdout = new List<String>();
|
| stderr = new List<String>();
|
| + compilationSkipped = false;
|
| }
|
| -
|
| +
|
| VoidFunction makeReadHandler(StringInputStream source,
|
| List<String> destination) {
|
| void handler () {
|
| @@ -785,36 +871,48 @@ class RunningProcess {
|
| void processExitHandler(int returnCode) {
|
| commandCompleteHandler(command, returnCode);
|
| }
|
| - ProcessOptions options = new ProcessOptions();
|
| - options.environment = new Map<String, String>.from(Platform.environment);
|
| - options.environment['DART_CONFIGURATION'] =
|
| - TestUtils.configurationDir(testCase.configuration);
|
| - Future processFuture = Process.start(command.executable,
|
| - command.arguments,
|
| - options);
|
| - processFuture.then((Process p) {
|
| - process = p;
|
| - process.onExit = processExitHandler;
|
| - var stdoutStringStream = new StringInputStream(process.stdout);
|
| - var stderrStringStream = new StringInputStream(process.stderr);
|
| - stdoutStringStream.onLine =
|
| - makeReadHandler(stdoutStringStream, stdout);
|
| - stderrStringStream.onLine =
|
| - makeReadHandler(stderrStringStream, stderr);
|
| - if (timeoutTimer == null) {
|
| - // Create one timeout timer when starting test case, remove it at end.
|
| - timeoutTimer = new Timer(1000 * testCase.timeout, timeoutHandler);
|
| +
|
| + command.outputIsUpToDate.then((bool isUpToDate) {
|
| + if (isUpToDate) {
|
| + stdout.add("Skipped compilation because the old output is "
|
| + "still up to date!");
|
| + compilationSkipped = true;
|
| + commandComplete(command, 0);
|
| + } else {
|
| + ProcessOptions options = new ProcessOptions();
|
| + options.environment =
|
| + new Map<String, String>.from(Platform.environment);
|
| + options.environment['DART_CONFIGURATION'] =
|
| + TestUtils.configurationDir(testCase.configuration);
|
| + Future processFuture = Process.start(command.executable,
|
| + command.arguments,
|
| + options);
|
| + processFuture.then((Process p) {
|
| + process = p;
|
| + process.onExit = processExitHandler;
|
| + var stdoutStringStream = new StringInputStream(process.stdout);
|
| + var stderrStringStream = new StringInputStream(process.stderr);
|
| + stdoutStringStream.onLine =
|
| + makeReadHandler(stdoutStringStream, stdout);
|
| + stderrStringStream.onLine =
|
| + makeReadHandler(stderrStringStream, stderr);
|
| + if (timeoutTimer == null) {
|
| + // Create one timeout timer when starting test case, remove it at
|
| + // the end.
|
| + timeoutTimer = new Timer(1000 * testCase.timeout, timeoutHandler);
|
| + }
|
| + // If the timeout fired in between two commands, kill the just
|
| + // started process immediately.
|
| + if (timedOut) safeKill(process);
|
| + });
|
| + processFuture.handleException((e) {
|
| + print("Process error:");
|
| + print(" Command: $command");
|
| + print(" Error: $e");
|
| + testComplete(createCommandOutput(command, -1, false));
|
| + return true;
|
| + });
|
| }
|
| - // If the timeout fired in between two commands, kill the just
|
| - // started process immediately.
|
| - if (timedOut) safeKill(process);
|
| - });
|
| - processFuture.handleException((e) {
|
| - print("Process error:");
|
| - print(" Command: $command");
|
| - print(" Error: $e");
|
| - testComplete(createCommandOutput(command, -1, false));
|
| - return true;
|
| });
|
| }
|
|
|
| @@ -964,7 +1062,8 @@ class BatchRunnerProcess {
|
| (outcome == "TIMEOUT"),
|
| _testStdout,
|
| _testStderr,
|
| - new Date.now().difference(_startTime));
|
| + new Date.now().difference(_startTime),
|
| + false);
|
| var test = _currentTest;
|
| _currentTest = null;
|
| test.completed();
|
|
|