Catch the test_runner codebase up to somewhat modern practices.

- Run dartfmt --fix. This converts JavaDoc comments to "///", removes
  "new" and extraneous "const", and a couple of other things.
- Fix SCREAMING_CAPS constants to lowerCamelCase.
- Use collection literals where possible.
- Use UI-as-code in a couple of places where it seemed obvious.
- Use "var" for more local variables.
- Use "const" instead of "final" when possible.
- Make members private when possible. Deleted a few that then became
  obviously unused.
- ".length > 0" -> ".isNotEmpty".

There are no meaningful changes.

Change-Id: Ic6c5a74b2af9b3ebcbe881dbed69f65488bdef09
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/105880
Commit-Queue: Bob Nystrom <rnystrom@google.com>
Reviewed-by: William Hesse <whesse@google.com>
This commit is contained in:
Robert Nystrom 2019-06-15 01:02:50 +00:00 committed by commit-bot@chromium.org
parent 99e8a9fba5
commit c1b56a9ea0
35 changed files with 2447 additions and 2640 deletions

View file

@ -8,7 +8,7 @@ import 'package:test_runner/src/utils.dart';
import 'package:test_runner/src/vendored_pkg/args/args.dart';
void main(List<String> arguments) {
var parser = new ArgParser();
var parser = ArgParser();
parser.addOption('port',
abbr: 'p',
help: 'The main server port we wish to respond to requests.',
@ -33,7 +33,7 @@ void main(List<String> arguments) {
if (args['help'] as bool) {
print(parser.getUsage());
} else {
var servers = new TestingServers(
var servers = TestingServers(
args['build-directory'] as String,
args['csp'] as bool,
Runtime.find(args['runtime'] as String),

View file

@ -2,13 +2,11 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
/**
* Simple command line interface to launching browsers.
* Uses the browser_controller framework.
* The usage is:
* DARTBIN launch_browser.dart BROWSER_NAME URL
* DARTBIN should be the checked in stable binary.
*/
/// Simple command line interface to launching browsers.
/// Uses the browser_controller framework.
/// The usage is:
/// DARTBIN launch_browser.dart BROWSER_NAME URL
/// DARTBIN should be the checked in stable binary.
import 'package:test_runner/src/browser_controller.dart';
import 'package:test_runner/src/configuration.dart';
@ -16,7 +14,7 @@ import 'package:test_runner/src/configuration.dart';
void printHelp() {
print("Usage pattern:");
print("launch_browser.dart browser url");
print("Supported browsers: ${Browser.SUPPORTED_BROWSERS}");
print("Supported browsers: ${Browser.supportedBrowsers}");
}
void main(List<String> arguments) {
@ -34,10 +32,10 @@ void main(List<String> arguments) {
}
var runtime = Runtime.find(name);
var configuration = new TestConfiguration(
configuration: new Configuration(
var configuration = TestConfiguration(
configuration: Configuration(
"dummy configuration", null, null, null, runtime, null));
var executable = configuration.browserLocation;
var browser = new Browser.byRuntime(runtime, executable);
var browser = Browser.byRuntime(runtime, executable);
browser.start(arguments[1]);
}

View file

@ -11,7 +11,7 @@ void main(List<String> arguments) {
Repository.uri = Uri.base;
var configurations = <TestConfiguration>[];
for (var argument in arguments) {
configurations.addAll(new OptionsParser().parse(argument.split(" ")));
configurations.addAll(OptionsParser().parse(argument.split(" ")));
}
testConfigurations(configurations);
}

View file

@ -27,7 +27,7 @@ import "package:test_runner/src/test_configurations.dart";
/// Runs all of the tests specified by the given command line [arguments].
void main(List<String> arguments) {
// Parse the command line arguments to a configuration.
var parser = new OptionsParser();
var parser = OptionsParser();
var configurations = parser.parse(arguments);
if (configurations == null || configurations.isEmpty) return;

View file

@ -1,9 +1,6 @@
// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
library android;
import "dart:async";
import "dart:convert" show LineSplitter, utf8;
import "dart:core";
@ -30,18 +27,16 @@ class AdbCommandResult {
"stderr:\n ${stderr.trim()}\n"
"exitCode: $exitCode\n"
"timedOut: $timedOut";
throw new Exception(error);
throw Exception(error);
}
}
}
/**
* [_executeCommand] will write [stdin] to the standard input of the created
* process and will return a tuple (stdout, stderr).
*
* If the exit code of the process was nonzero it will complete with an error.
* If starting the process failed, it will complete with an error as well.
*/
/// [_executeCommand] will write [stdin] to the standard input of the created
/// process and will return a tuple (stdout, stderr).
///
/// If the exit code of the process was nonzero it will complete with an error.
/// If starting the process failed, it will complete with an error as well.
Future<AdbCommandResult> _executeCommand(String executable, List<String> args,
{String stdin, Duration timeout}) {
Future<String> getOutput(Stream<List<int>> stream) {
@ -61,7 +56,7 @@ Future<AdbCommandResult> _executeCommand(String executable, List<String> args,
Timer timer;
bool timedOut = false;
if (timeout != null) {
timer = new Timer(timeout, () {
timer = Timer(timeout, () {
timedOut = true;
process.kill(ProcessSignal.sigterm);
timer = null;
@ -76,40 +71,36 @@ Future<AdbCommandResult> _executeCommand(String executable, List<String> args,
if (timer != null) timer.cancel();
String command = "$executable ${args.join(' ')}";
return new AdbCommandResult(command, results[0] as String,
results[1] as String, results[2] as int, timedOut);
return AdbCommandResult(command, results[0] as String, results[1] as String,
results[2] as int, timedOut);
});
}
/**
* Helper class to loop through all adb ports.
*
* The ports come in pairs:
* - even number: console connection
* - odd number: adb connection
* Note that this code doesn't check if the ports are used.
*/
/// Helper class to loop through all adb ports.
///
/// The ports come in pairs:
/// - even number: console connection
/// - odd number: adb connection
/// Note that this code doesn't check if the ports are used.
class AdbServerPortPool {
static int MIN_PORT = 5554;
static int MAX_PORT = 5584;
static const _minPort = 5554;
static const _maxPort = 5584;
static int _nextPort = MIN_PORT;
static int _nextPort = _minPort;
static int next() {
var port = _nextPort;
if (port > MAX_PORT) {
throw new Exception("All ports are used.");
}
if (port > _maxPort) throw Exception("All ports are used.");
_nextPort += 2;
return port;
}
}
/**
* Represents the interface to the emulator.
* New emulators can be launched by calling the static [launchNewEmulator]
* method.
*/
/// Represents the interface to the emulator.
///
/// New emulators can be launched by calling the static [launchNewEmulator]
/// method.
class AndroidEmulator {
int _port;
Process _emulatorProcess;
@ -123,14 +114,14 @@ class AndroidEmulator {
var portNumber = AdbServerPortPool.next();
var args = ['-avd', '$avdName', '-port', "$portNumber" /*, '-gpu', 'on'*/];
return Process.start("emulator64-arm", args).then((Process process) {
var adbDevice = new AdbDevice('emulator-$portNumber');
return new AndroidEmulator._private(portNumber, adbDevice, process);
var adbDevice = AdbDevice('emulator-$portNumber');
return AndroidEmulator._private(portNumber, adbDevice, process);
});
}
AndroidEmulator._private(this._port, this._adbDevice, this._emulatorProcess) {
Stream<String> getLines(Stream s) {
return s.transform(utf8.decoder).transform(new LineSplitter());
return s.transform(utf8.decoder).transform(LineSplitter());
}
getLines(_emulatorProcess.stdout).listen((line) {
@ -145,7 +136,7 @@ class AndroidEmulator {
}
Future<bool> kill() {
var completer = new Completer<bool>();
var completer = Completer<bool>();
if (_emulatorProcess.kill()) {
_emulatorProcess.exitCode.then((exitCode) {
// TODO: Should we use exitCode to do something clever?
@ -163,9 +154,7 @@ class AndroidEmulator {
}
}
/**
* Helper class to create avd device configurations.
*/
/// Helper class to create avd device configurations.
class AndroidHelper {
static Future createAvd(String name, String target) async {
var args = [
@ -186,29 +175,23 @@ class AndroidHelper {
}
}
/**
* Used for communicating with an emulator or with a real device.
*/
/// Used for communicating with an emulator or with a real device.
class AdbDevice {
static const _adbServerStartupTime = const Duration(seconds: 3);
static const _adbServerStartupTime = Duration(seconds: 3);
String _deviceId;
Map<String, String> _cachedData = new Map<String, String>();
Map<String, String> _cachedData = {};
String get deviceId => _deviceId;
AdbDevice(this._deviceId);
/**
* Blocks execution until the device is online
*/
/// Blocks execution until the device is online.
Future waitForDevice() {
return _adbCommand(['wait-for-device']);
}
/**
* Polls the 'sys.boot_completed' property. Returns as soon as the property is
* 1.
*/
/// Polls the 'sys.boot_completed' property. Returns as soon as the property
/// is 1.
Future<Null> waitForBootCompleted() async {
while (true) {
try {
@ -216,71 +199,57 @@ class AdbDevice {
await _adbCommand(['shell', 'getprop', 'sys.boot_completed']);
if (result.stdout.trim() == '1') return;
} catch (_) {}
await new Future<Null>.delayed(const Duration(seconds: 2));
await Future<Null>.delayed(const Duration(seconds: 2));
}
}
/**
* Put adb in root mode.
*/
/// Put adb in root mode.
Future<bool> adbRoot() {
var adbRootCompleter = new Completer<bool>();
var adbRootCompleter = Completer<bool>();
_adbCommand(['root']).then((_) {
// TODO: Figure out a way to wait until the adb daemon was restarted in
// 'root mode' on the device.
new Timer(_adbServerStartupTime, () => adbRootCompleter.complete(true));
Timer(_adbServerStartupTime, () => adbRootCompleter.complete(true));
}).catchError((error) => adbRootCompleter.completeError(error));
return adbRootCompleter.future;
}
/**
* Download data form the device.
*/
/// Download data from the device.
Future pullData(Path remote, Path local) {
return _adbCommand(['pull', '$remote', '$local']);
}
/**
* Upload data to the device.
*/
/// Upload data to the device.
Future pushData(Path local, Path remote) {
return _adbCommand(['push', '$local', '$remote']);
}
/**
* Upload data to the device, unless [local] is the same as the most recently
* used source for [remote].
*/
/// Upload data to the device, unless [local] is the same as the most recently
/// used source for [remote].
Future<AdbCommandResult> pushCachedData(String local, String remote) {
if (_cachedData[remote] == local) {
return new Future.value(
new AdbCommandResult("Skipped cached push", "", "", 0, false));
return Future.value(
AdbCommandResult("Skipped cached push", "", "", 0, false));
}
_cachedData[remote] = local;
return _adbCommand(['push', local, remote]);
}
/**
* Change permission of directory recursively.
*/
/// Change permission of directory recursively.
Future chmod(String mode, Path directory) {
var arguments = ['shell', 'chmod', '-R', mode, '$directory'];
return _adbCommand(arguments);
}
/**
* Install an application on the device.
*/
/// Install an application on the device.
Future installApk(Path filename) {
return _adbCommand(
['install', '-i', 'com.google.android.feedback', '-r', '$filename']);
}
/**
* Start the given intent on the device.
*/
/// Start the given intent on the device.
Future startActivity(Intent intent) {
var arguments = [
return _adbCommand([
'shell',
'am',
'start',
@ -288,35 +257,24 @@ class AdbDevice {
'-a',
intent.action,
'-n',
"${intent.package}/${intent.activity}"
];
if (intent.dataUri != null) {
arguments.addAll(['-d', intent.dataUri]);
}
return _adbCommand(arguments);
"${intent.package}/${intent.activity}",
if (intent.dataUri != null) ...['-d', intent.dataUri]
]);
}
/**
* Force to stop everything associated with [package].
*/
/// Force to stop everything associated with [package].
Future forceStop(String package) {
var arguments = ['shell', 'am', 'force-stop', package];
return _adbCommand(arguments);
return _adbCommand(['shell', 'am', 'force-stop', package]);
}
/**
* Set system property name to value.
*/
/// Set system property name to value.
Future setProp(String name, String value) {
return _adbCommand(['shell', 'setprop', name, value]);
}
/**
* Kill all background processes.
*/
/// Kill all background processes.
Future killAll() {
var arguments = ['shell', 'am', 'kill-all'];
return _adbCommand(arguments);
return _adbCommand(['shell', 'am', 'kill-all']);
}
Future<AdbCommandResult> runAdbCommand(List<String> adbArgs,
@ -327,28 +285,27 @@ class AdbDevice {
Future<AdbCommandResult> runAdbShellCommand(List<String> shellArgs,
{Duration timeout}) async {
const MARKER = 'AdbShellExitCode: ';
const marker = 'AdbShellExitCode: ';
// The exitcode of 'adb shell ...' can be 0 even though the command failed
// with a non-zero exit code. We therefore explicitly print it to stdout and
// search for it.
var args = ['shell', "${shellArgs.join(' ')} ; echo $MARKER \$?"];
AdbCommandResult result = await _executeCommand(
"adb", _deviceSpecificArgs(args),
var args = ['shell', "${shellArgs.join(' ')} ; echo $marker \$?"];
var result = await _executeCommand("adb", _deviceSpecificArgs(args),
timeout: timeout);
int exitCode = result.exitCode;
var exitCode = result.exitCode;
var lines = result.stdout
.split('\n')
.where((line) => line.trim().length > 0)
.where((line) => line.trim().isNotEmpty)
.toList();
if (lines.length > 0) {
int index = lines.last.indexOf(MARKER);
if (lines.isNotEmpty) {
int index = lines.last.indexOf(marker);
if (index >= 0) {
exitCode =
int.parse(lines.last.substring(index + MARKER.length).trim());
int.parse(lines.last.substring(index + marker.length).trim());
if (exitCode > 128 && exitCode <= 128 + 31) {
// Return negative exit codes for signals 1..31 (128+N for signal N)
// Return negative exit codes for signals 1..31 (128+N for signal N).
exitCode = 128 - exitCode;
}
} else {
@ -369,7 +326,7 @@ class AdbDevice {
assert(result.exitCode != 0);
}
}
return new AdbCommandResult(result.command, result.stdout, result.stderr,
return AdbCommandResult(result.command, result.stdout, result.stderr,
exitCode, result.timedOut);
}
@ -389,17 +346,15 @@ class AdbDevice {
}
}
/**
* Helper to list all adb devices available.
*/
/// Helper to list all adb devices available.
class AdbHelper {
static RegExp _deviceLineRegexp =
new RegExp(r'^([a-zA-Z0-9_-]+)[ \t]+device$', multiLine: true);
RegExp(r'^([a-zA-Z0-9_-]+)[ \t]+device$', multiLine: true);
static Future<List<String>> listDevices() {
return Process.run('adb', ['devices']).then((ProcessResult result) {
if (result.exitCode != 0) {
throw new Exception("Could not list devices [stdout: ${result.stdout},"
throw Exception("Could not list devices [stdout: ${result.stdout},"
"stderr: ${result.stderr}]");
}
return _deviceLineRegexp
@ -410,9 +365,7 @@ class AdbHelper {
}
}
/**
* Represents an android intent.
*/
/// Represents an android intent.
class Intent {
String action;
String package;
@ -422,12 +375,10 @@ class Intent {
Intent(this.action, this.package, this.activity, [this.dataUri]);
}
/**
* Discovers all available devices and supports acquire/release.
*/
/// Discovers all available devices and supports acquire/release.
class AdbDevicePool {
final Queue<AdbDevice> _idleDevices = new Queue<AdbDevice>();
final Queue<Completer> _waiter = new Queue<Completer>();
final Queue<AdbDevice> _idleDevices = Queue();
final Queue<Completer<AdbDevice>> _waiter = Queue();
AdbDevicePool(List<AdbDevice> idleDevices) {
_idleDevices.addAll(idleDevices);
@ -435,28 +386,28 @@ class AdbDevicePool {
static Future<AdbDevicePool> create() async {
var names = await AdbHelper.listDevices();
var devices = names.map((id) => new AdbDevice(id)).toList();
var devices = names.map((id) => AdbDevice(id)).toList();
if (devices.length == 0) {
throw new Exception('No android devices found. '
throw Exception('No android devices found. '
'Please make sure "adb devices" shows your device!');
}
print("Found ${devices.length} Android devices.");
return new AdbDevicePool(devices);
return AdbDevicePool(devices);
}
Future<AdbDevice> acquireDevice() async {
if (_idleDevices.length > 0) {
if (_idleDevices.isNotEmpty) {
return _idleDevices.removeFirst();
} else {
var completer = new Completer<AdbDevice>();
var completer = Completer<AdbDevice>();
_waiter.add(completer);
return completer.future;
}
}
void releaseDevice(AdbDevice device) {
if (_waiter.length > 0) {
Completer completer = _waiter.removeFirst();
if (_waiter.isNotEmpty) {
var completer = _waiter.removeFirst();
completer.complete(device);
} else {
_idleDevices.add(device);

View file

@ -14,59 +14,55 @@ import 'path.dart';
import 'reset_safari.dart';
import 'utils.dart';
typedef void BrowserDoneCallback(BrowserTestOutput output);
typedef void TestChangedCallback(String browserId, String output, int testId);
typedef BrowserTest NextTestCallback(String browserId);
typedef BrowserDoneCallback = void Function(BrowserTestOutput output);
typedef TestChangedCallback = void Function(
String browserId, String output, int testId);
typedef NextTestCallback = BrowserTest Function(String browserId);
class BrowserOutput {
final StringBuffer stdout = new StringBuffer();
final StringBuffer stderr = new StringBuffer();
final StringBuffer eventLog = new StringBuffer();
final StringBuffer stdout = StringBuffer();
final StringBuffer stderr = StringBuffer();
final StringBuffer eventLog = StringBuffer();
}
/** Class describing the interface for communicating with browsers. */
/// Class describing the interface for communicating with browsers.
abstract class Browser {
BrowserOutput _allBrowserOutput = new BrowserOutput();
BrowserOutput _testBrowserOutput = new BrowserOutput();
BrowserOutput _allBrowserOutput = BrowserOutput();
BrowserOutput _testBrowserOutput = BrowserOutput();
// This is called after the process is closed, before the done future
// is completed.
// Subclasses can use this to cleanup any browser specific resources
// (temp directories, profiles, etc). The function is expected to do
// it's work synchronously.
/// This is called after the process is closed, before the done future
/// is completed.
///
/// Subclasses can use this to cleanup any browser specific resources
/// (temp directories, profiles, etc). The function is expected to do
/// it's work synchronously.
Function _cleanup;
/** The version of the browser - normally set when starting a browser */
/// The version of the browser - normally set when starting a browser
String version = "";
// The path to the browser executable.
/// The path to the browser executable.
String _binary;
/**
* The underlying process - don't mess directly with this if you don't
* know what you are doing (this is an interactive process that needs
* special treatment to not leak).
*/
/// The underlying process - don't mess directly with this if you don't
/// know what you are doing (this is an interactive process that needs
/// special treatment to not leak).
Process process;
Function logger;
/**
* Id of the browser
*/
/// Id of the browser.
String id;
/**
* Reset the browser to a known configuration on start-up.
* Browser specific implementations are free to ignore this.
*/
/// Reset the browser to a known configuration on start-up.
/// Browser specific implementations are free to ignore this.
static bool resetBrowserConfiguration = false;
/** Print everything (stdout, stderr, usageLog) whenever we add to it */
/// Print everything (stdout, stderr, usageLog) whenever we add to it
bool debugPrint = false;
// This future returns when the process exits. It is also the return value
// of close()
/// This future returns when the process exits. It is also the return value
/// of close()
Future done;
Browser();
@ -76,18 +72,18 @@ abstract class Browser {
Browser browser;
switch (runtime) {
case Runtime.firefox:
browser = new Firefox();
browser = Firefox();
break;
case Runtime.chrome:
browser = new Chrome();
browser = Chrome();
break;
case Runtime.safari:
browser = new Safari();
browser = Safari();
break;
case Runtime.ie9:
case Runtime.ie10:
case Runtime.ie11:
browser = new IE();
browser = IE();
break;
default:
throw "unreachable";
@ -97,7 +93,7 @@ abstract class Browser {
return browser;
}
static const List<String> SUPPORTED_BROWSERS = const [
static const List<String> supportedBrowsers = [
'safari',
'ff',
'firefox',
@ -113,11 +109,11 @@ abstract class Browser {
// TODO(kustermann): add standard support for chrome on android
static bool supportedBrowser(String name) {
return SUPPORTED_BROWSERS.contains(name);
return supportedBrowsers.contains(name);
}
void _logEvent(String event) {
String toLog = "$this ($id) - $event \n";
var toLog = "$this ($id) - $event \n";
if (debugPrint) print("usageLog: $toLog");
if (logger != null) logger(toLog);
@ -150,14 +146,12 @@ abstract class Browser {
return done;
} else {
_logEvent("The process is already dead.");
return new Future.value(true);
return Future.value(true);
}
}
/**
* Start the browser using the supplied argument.
* This sets up the error handling and usage logging.
*/
/// Start the browser using the supplied argument.
/// This sets up the error handling and usage logging.
Future<bool> startBrowserProcess(String command, List<String> arguments,
{Map<String, String> environment}) {
return Process.start(command, arguments, environment: environment)
@ -166,14 +160,14 @@ abstract class Browser {
process = startedProcess;
// Used to notify when exiting, and as a return value on calls to
// close().
var doneCompleter = new Completer<bool>();
var doneCompleter = Completer<bool>();
done = doneCompleter.future;
Completer stdoutDone = new Completer<Null>();
Completer stderrDone = new Completer<Null>();
var stdoutDone = Completer<Null>();
var stderrDone = Completer<Null>();
bool stdoutIsDone = false;
bool stderrIsDone = false;
var stdoutIsDone = false;
var stderrIsDone = false;
StreamSubscription stdoutSubscription;
StreamSubscription stderrSubscription;
@ -226,9 +220,8 @@ abstract class Browser {
_logEvent("Browser closed with exitcode $exitCode");
if (!stdoutIsDone || !stderrIsDone) {
watchdogTimer = new Timer(MAX_STDIO_DELAY, () {
DebugLogger.warning(
"$MAX_STDIO_DELAY_PASSED_MESSAGE (browser: $this)");
watchdogTimer = Timer(maxStdioDelay, () {
DebugLogger.warning("$maxStdioDelayPassedMessage (browser: $this)");
watchdogTimer = null;
stdoutSubscription.cancel();
stderrSubscription.cancel();
@ -253,26 +246,20 @@ abstract class Browser {
});
}
/**
* Get the output that was written so far to stdout/stderr/eventLog.
*/
/// Get the output that was written so far to stdout/stderr/eventLog.
BrowserOutput get allBrowserOutput => _allBrowserOutput;
BrowserOutput get testBrowserOutput => _testBrowserOutput;
void resetTestBrowserOutput() {
_testBrowserOutput = new BrowserOutput();
_testBrowserOutput = BrowserOutput();
}
/**
* Add useful info about the browser to the _testBrowserOutput.stdout,
* where it will be reported for failing tests. Used to report which
* android device a failing test is running on.
*/
/// Add useful info about the browser to the _testBrowserOutput.stdout,
/// where it will be reported for failing tests. Used to report which
/// android device a failing test is running on.
void logBrowserInfoToTestBrowserOutput() {}
String toString();
/** Starts the browser loading the given url */
/// Starts the browser loading the given url
Future<bool> start(String url);
/// Called when the driver page is requested, that is, when the browser first
@ -280,13 +267,11 @@ abstract class Browser {
/// browser process has started and opened its first window.
///
/// This is used by [Safari] to ensure the browser window has focus.
Future<Null> onDriverPageRequested() => new Future<Null>.value();
Future<Null> onDriverPageRequested() => Future.value();
}
class Safari extends Browser {
/**
* We get the safari version by parsing a version file
*/
/// We get the safari version by parsing a version file
static const String versionFile =
"/Applications/Safari.app/Contents/version.plist";
@ -297,17 +282,17 @@ class Safari extends Browser {
Future<bool> resetConfiguration() async {
if (!Browser.resetBrowserConfiguration) return true;
var completer = new Completer<Null>();
var completer = Completer<Null>();
handleUncaughtError(error, StackTrace stackTrace) {
if (!completer.isCompleted) {
completer.completeError(error, stackTrace);
} else {
throw new AsyncError(error, stackTrace);
throw AsyncError(error, stackTrace);
}
}
Zone parent = Zone.current;
ZoneSpecification specification = new ZoneSpecification(
var parent = Zone.current;
var specification = ZoneSpecification(
print: (Zone self, ZoneDelegate delegate, Zone zone, String line) {
delegate.run(parent, () {
_logEvent(line);
@ -315,7 +300,7 @@ class Safari extends Browser {
});
Future zoneWrapper() {
Uri safariUri = Uri.base.resolve(safariBundleLocation);
return new Future(() => killAndResetSafari(bundle: safariUri))
return Future(() => killAndResetSafari(bundle: safariUri))
.then(completer.complete);
}
@ -335,28 +320,25 @@ class Safari extends Browser {
}
Future<String> getVersion() {
/**
* Example of the file:
* <?xml version="1.0" encoding="UTF-8"?>
* <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
* <plist version="1.0">
* <dict>
* <key>BuildVersion</key>
* <string>2</string>
* <key>CFBundleShortVersionString</key>
* <string>6.0.4</string>
* <key>CFBundleVersion</key>
* <string>8536.29.13</string>
* <key>ProjectName</key>
* <string>WebBrowser</string>
* <key>SourceVersion</key>
* <string>7536029013000000</string>
* </dict>
* </plist>
*/
File f = new File(versionFile);
return f.readAsLines().then((content) {
bool versionOnNextLine = false;
// Example of the file:
// <?xml version="1.0" encoding="UTF-8"?>
// <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
// <plist version="1.0">
// <dict>
// <key>BuildVersion</key>
// <string>2</string>
// <key>CFBundleShortVersionString</key>
// <string>6.0.4</string>
// <key>CFBundleVersion</key>
// <string>8536.29.13</string>
// <key>ProjectName</key>
// <string>WebBrowser</string>
// <key>SourceVersion</key>
// <string>7536029013000000</string>
// </dict>
// </plist>
return File(versionFile).readAsLines().then((content) {
var versionOnNextLine = false;
for (var line in content) {
if (versionOnNextLine) return line;
if (line.contains("CFBundleShortVersionString")) {
@ -368,7 +350,7 @@ class Safari extends Browser {
}
Future<Null> _createLaunchHTML(String path, String url) async {
var file = new File("$path/launch.html");
var file = File("$path/launch.html");
var randomFile = await file.open(mode: FileMode.write);
var content = '<script language="JavaScript">location = "$url"</script>';
await randomFile.writeString(content);
@ -444,7 +426,7 @@ class Chrome extends Browser {
_version = "Can't get version on windows";
// We still validate that the binary exists so that we can give good
// feedback.
return new File(_binary).exists().then((exists) {
return File(_binary).exists().then((exists) {
if (!exists) {
_logEvent("Chrome binary not available.");
_logEvent("Make sure $_binary is a valid program for running chrome");
@ -478,7 +460,7 @@ class Chrome extends Browser {
_logEvent(
"Error: failed to delete Chrome user-data-dir ${userDir.path}"
", will try again in 40 seconds: $e");
new Timer(new Duration(seconds: 40), () {
Timer(Duration(seconds: 40), () {
try {
userDir.deleteSync(recursive: true);
} catch (e) {
@ -556,7 +538,7 @@ class IE extends Browser {
}
var localAppData = Platform.environment['LOCALAPPDATA'];
Directory dir = new Directory("$localAppData\\Microsoft\\"
Directory dir = Directory("$localAppData\\Microsoft\\"
"Internet Explorer\\Recovery");
return dir.delete(recursive: true).then((_) {
return true;
@ -594,22 +576,20 @@ class AndroidChrome extends Browser {
AndroidChrome(this._adbDevice);
Future<bool> start(String url) {
var chromeIntent =
new Intent(viewAction, chromePackage, chromeActivity, url);
var chromeIntent = Intent(viewAction, chromePackage, chromeActivity, url);
var turnScreenOnIntent =
new Intent(mainAction, turnScreenOnPackage, turnScreenOnActivity);
Intent(mainAction, turnScreenOnPackage, turnScreenOnActivity);
var testing_resources_dir =
new Path('third_party/android_testing_resources');
if (!new Directory(testing_resources_dir.toNativePath()).existsSync()) {
DebugLogger.error("$testing_resources_dir doesn't exist. Exiting now.");
var testingResourcesDir = Path('third_party/android_testing_resources');
if (!Directory(testingResourcesDir.toNativePath()).existsSync()) {
DebugLogger.error("$testingResourcesDir doesn't exist. Exiting now.");
exit(1);
}
var chromeAPK = testing_resources_dir.append('com.android.chrome-1.apk');
var turnScreenOnAPK = testing_resources_dir.append('TurnScreenOn.apk');
var chromeConfDir = testing_resources_dir.append('chrome_configuration');
var chromeConfDirRemote = new Path('/data/user/0/com.android.chrome/');
var chromeAPK = testingResourcesDir.append('com.android.chrome-1.apk');
var turnScreenOnAPK = testingResourcesDir.append('TurnScreenOn.apk');
var chromeConfDir = testingResourcesDir.append('chrome_configuration');
var chromeConfDirRemote = Path('/data/user/0/com.android.chrome/');
return _adbDevice.waitForBootCompleted().then((_) {
return _adbDevice.forceStop(chromeIntent.package);
@ -638,7 +618,7 @@ class AndroidChrome extends Browser {
return _adbDevice.killAll().then((_) => true);
});
}
return new Future.value(true);
return Future.value(true);
}
void logBrowserInfoToTestBrowserOutput() {
@ -658,7 +638,7 @@ class Firefox extends Browser {
'user_pref("dom.max_script_run_time", 0);';
void _createPreferenceFile(String path) {
var file = new File("$path/user.js");
var file = File("$path/user.js");
var randomFile = file.openSync(mode: FileMode.write);
randomFile.writeStringSync(enablePopUp);
randomFile.writeStringSync(disableDefaultCheck);
@ -673,7 +653,7 @@ class Firefox extends Browser {
if (versionResult.exitCode != 0) {
_logEvent("Failed to firefox get version");
_logEvent("Make sure $_binary is a valid program for running firefox");
return new Future.value(false);
return Future.value(false);
}
version = versionResult.stdout as String;
_logEvent("Got version: $version");
@ -690,7 +670,7 @@ class Firefox extends Browser {
"-new-instance",
url
];
var environment = new Map<String, String>.from(Platform.environment);
var environment = Map<String, String>.from(Platform.environment);
environment["MOZ_CRASHREPORTER_DISABLE"] = "1";
return startBrowserProcess(_binary, args, environment: environment);
});
@ -703,9 +683,7 @@ class Firefox extends Browser {
String toString() => "Firefox";
}
/**
* Describes the current state of a browser used for testing.
*/
/// Describes the current state of a browser used for testing.
class BrowserStatus {
Browser browser;
BrowserTest currentTest;
@ -716,14 +694,12 @@ class BrowserStatus {
BrowserTest lastTest;
bool timeout = false;
Timer nextTestTimeout;
Stopwatch timeSinceRestart = new Stopwatch()..start();
Stopwatch timeSinceRestart = Stopwatch()..start();
BrowserStatus(Browser this.browser);
}
/**
* Describes a single test to be run in the browser.
*/
/// Describes a single test to be run in the browser.
class BrowserTest {
// TODO(ricow): Add timeout callback instead of the string passing hack.
BrowserDoneCallback doneCallback;
@ -763,7 +739,7 @@ class BrowserTestOutput {
BrowserTestOutput(this.delayUntilTestStarted, this.duration,
this.lastKnownMessage, this.browserOutput,
{this.didTimeout: false});
{this.didTimeout = false});
}
/// Encapsulates all the functionality for running tests in browsers.
@ -776,12 +752,12 @@ class BrowserTestOutput {
/// driver page to the browsers, serves tests, and receives results and
/// requests back from the browsers.
class BrowserTestRunner {
static const int MAX_NEXT_TEST_TIMEOUTS = 10;
static const Duration NEXT_TEST_TIMEOUT = const Duration(seconds: 120);
static const Duration RESTART_BROWSER_INTERVAL = const Duration(seconds: 60);
static const int _maxNextTestTimeouts = 10;
static const Duration _nextTestTimeout = Duration(seconds: 120);
static const Duration _restartBrowserInterval = Duration(seconds: 60);
/// If the queue was recently empty, don't start another browser.
static const Duration MIN_NONEMPTY_QUEUE_TIME = const Duration(seconds: 1);
static const Duration _minNonemptyQueueTime = Duration(seconds: 1);
final TestConfiguration configuration;
final BrowserTestingServer testingServer;
@ -789,7 +765,8 @@ class BrowserTestRunner {
final String localIp;
int maxNumBrowsers;
int numBrowsers = 0;
// Used to send back logs from the browser (start, stop etc)
/// Used to send back logs from the browser (start, stop etc.).
Function logger;
int browserIdCounter = 1;
@ -797,7 +774,7 @@ class BrowserTestRunner {
bool testingServerStarted = false;
bool underTermination = false;
int numBrowserGetTestTimeouts = 0;
DateTime lastEmptyTestQueueTime = new DateTime.now();
DateTime lastEmptyTestQueueTime = DateTime.now();
String _currentStartingBrowserId;
List<BrowserTest> testQueue = [];
Map<String, BrowserStatus> browserStatus = {};
@ -805,26 +782,26 @@ class BrowserTestRunner {
Map<String, AdbDevice> adbDeviceMapping = {};
List<AdbDevice> idleAdbDevices;
// This cache is used to guarantee that we never see double reporting.
// If we do we need to provide developers with this information.
// We don't add urls to the cache until we have run it.
/// This cache is used to guarantee that we never see double reporting.
/// If we do we need to provide developers with this information.
/// We don't add urls to the cache until we have run it.
Map<int, String> testCache = {};
Map<int, String> doubleReportingOutputs = {};
List<String> timedOut = [];
// We will start a new browser when the test queue hasn't been empty
// recently, we have fewer than maxNumBrowsers browsers, and there is
// no other browser instance currently starting up.
/// We will start a new browser when the test queue hasn't been empty
/// recently, we have fewer than maxNumBrowsers browsers, and there is
/// no other browser instance currently starting up.
bool get queueWasEmptyRecently {
return testQueue.isEmpty ||
new DateTime.now().difference(lastEmptyTestQueueTime) <
MIN_NONEMPTY_QUEUE_TIME;
DateTime.now().difference(lastEmptyTestQueueTime) <
_minNonemptyQueueTime;
}
// While a browser is starting, but has not requested its first test, its
// browserId is stored in _currentStartingBrowserId.
// When no browser is currently starting, _currentStartingBrowserId is null.
/// While a browser is starting, but has not requested its first test, its
/// browserId is stored in _currentStartingBrowserId.
/// When no browser is currently starting, _currentStartingBrowserId is null.
bool get aBrowserIsCurrentlyStarting => _currentStartingBrowserId != null;
void markCurrentlyStarting(String id) {
_currentStartingBrowserId = id;
@ -838,7 +815,7 @@ class BrowserTestRunner {
TestConfiguration configuration, String localIp, this.maxNumBrowsers)
: configuration = configuration,
localIp = localIp,
testingServer = new BrowserTestingServer(configuration, localIp,
testingServer = BrowserTestingServer(configuration, localIp,
Browser.requiresFocus(configuration.runtime.name)) {
testingServer.testRunner = this;
}
@ -852,7 +829,7 @@ class BrowserTestRunner {
..nextTestCallBack = getNextTest;
if (configuration.runtime == Runtime.chromeOnAndroid) {
var idbNames = await AdbHelper.listDevices();
idleAdbDevices = new List.from(idbNames.map((id) => new AdbDevice(id)));
idleAdbDevices = List.from(idbNames.map((id) => AdbDevice(id)));
maxNumBrowsers = min(maxNumBrowsers, idleAdbDevices.length);
}
testingServerStarted = true;
@ -861,6 +838,7 @@ class BrowserTestRunner {
/// requestBrowser() is called whenever we might want to start an additional
/// browser instance.
///
/// It is called when starting the BrowserTestRunner, and whenever a browser
/// is killed, whenever a new test is enqueued, or whenever a browser
/// finishes a test.
@ -885,17 +863,17 @@ class BrowserTestRunner {
if (configuration.runtime == Runtime.chromeOnAndroid) {
AdbDevice device = idleAdbDevices.removeLast();
adbDeviceMapping[id] = device;
browser = new AndroidChrome(device);
browser = AndroidChrome(device);
} else {
var path = configuration.browserLocation;
browser = new Browser.byRuntime(
browser = Browser.byRuntime(
configuration.runtime, path, configuration.isChecked);
browser.logger = logger;
}
browser.id = id;
markCurrentlyStarting(id);
var status = new BrowserStatus(browser);
var status = BrowserStatus(browser);
browserStatus[id] = status;
numBrowsers++;
status.nextTestTimeout = createNextTestTimer(status);
@ -928,7 +906,7 @@ class BrowserTestRunner {
testCache[testId] = status.currentTest.url;
// Report that the test is finished now
var browserTestOutput = new BrowserTestOutput(
var browserTestOutput = BrowserTestOutput(
status.currentTest.delayUntilTestStarted,
status.currentTest.stopwatch.elapsed,
output,
@ -987,7 +965,7 @@ class BrowserTestRunner {
await status.browser.close();
var lastKnownMessage =
'Dom could not be fetched, since the test timed out.';
if (status.currentTest.lastKnownMessage.length > 0) {
if (status.currentTest.lastKnownMessage.isNotEmpty) {
lastKnownMessage = status.currentTest.lastKnownMessage;
}
if (status.lastTest != null) {
@ -996,7 +974,7 @@ class BrowserTestRunner {
// Wait until the browser is closed before reporting the test as timeout.
// This will enable us to capture stdout/stderr from the browser
// (which might provide us with information about what went wrong).
var browserTestOutput = new BrowserTestOutput(
var browserTestOutput = BrowserTestOutput(
status.currentTest.delayUntilTestStarted,
status.currentTest.stopwatch.elapsed,
lastKnownMessage,
@ -1041,7 +1019,7 @@ class BrowserTestRunner {
// had flaky timeouts, and this may help.
if ((configuration.runtime == Runtime.ie10 ||
configuration.runtime == Runtime.ie11) &&
status.timeSinceRestart.elapsed > RESTART_BROWSER_INTERVAL) {
status.timeSinceRestart.elapsed > _restartBrowserInterval) {
var id = status.browser.id;
// Reset stopwatch so we don't trigger again before restarting.
status.timeout = true;
@ -1058,7 +1036,7 @@ class BrowserTestRunner {
BrowserTest test = testQueue.removeLast();
// If our queue isn't empty, try starting more browsers
if (testQueue.isEmpty) {
lastEmptyTestQueueTime = new DateTime.now();
lastEmptyTestQueueTime = DateTime.now();
} else {
requestBrowser();
}
@ -1079,7 +1057,7 @@ class BrowserTestRunner {
}
status.currentTest.timeoutTimer = createTimeoutTimer(test, status);
status.currentTest.stopwatch = new Stopwatch()..start();
status.currentTest.stopwatch = Stopwatch()..start();
// Reset the test specific output information (stdout, stderr) on the
// browser, since a new test is being started.
@ -1090,7 +1068,7 @@ class BrowserTestRunner {
/// Creates a timer that is active while a test is running on a browser.
Timer createTimeoutTimer(BrowserTest test, BrowserStatus status) {
return new Timer(new Duration(seconds: test.timeout), () {
return Timer(Duration(seconds: test.timeout), () {
handleTimeout(status);
});
}
@ -1098,7 +1076,7 @@ class BrowserTestRunner {
/// Creates a timer that is active while no test is running on the
/// browser. It has finished one test, and it has not requested a new test.
Timer createNextTestTimer(BrowserStatus status) {
return new Timer(BrowserTestRunner.NEXT_TEST_TIMEOUT, () {
return Timer(BrowserTestRunner._nextTestTimeout, () {
handleNextTestTimeout(status);
});
}
@ -1108,7 +1086,7 @@ class BrowserTestRunner {
"Browser timed out before getting next test. Restarting");
if (status.timeout) return;
numBrowserGetTestTimeouts++;
if (numBrowserGetTestTimeouts >= MAX_NEXT_TEST_TIMEOUTS) {
if (numBrowserGetTestTimeouts >= _maxNextTestTimeouts) {
DebugLogger.error(
"Too many browser timeouts before getting next test. Terminating");
terminate().then((_) => exit(1));
@ -1169,21 +1147,20 @@ class BrowserTestRunner {
}
}
/// Interface of the testing server:
///
/// GET /driver/BROWSER_ID -- This will get the driver page to fetch
/// and run tests ...
/// GET /next_test/BROWSER_ID -- returns "WAIT" "TERMINATE" or "url#id"
/// where url is the test to run, and id is the id of the test.
/// If there are currently no available tests the waitSignal is send
/// back. If we are in the process of terminating the terminateSignal
/// is send back and the browser will stop requesting new tasks.
/// POST /report/BROWSER_ID?id=NUM -- sends back the dom of the executed
/// test
class BrowserTestingServer {
final TestConfiguration configuration;
/// Interface of the testing server:
///
/// GET /driver/BROWSER_ID -- This will get the driver page to fetch
/// and run tests ...
/// GET /next_test/BROWSER_ID -- returns "WAIT" "TERMINATE" or "url#id"
/// where url is the test to run, and id is the id of the test.
/// If there are currently no available tests the waitSignal is send
/// back. If we are in the process of terminating the terminateSignal
/// is send back and the browser will stop requesting new tasks.
/// POST /report/BROWSER_ID?id=NUM -- sends back the dom of the executed
/// test
final String localIp;
final bool requiresFocus;
BrowserTestRunner testRunner;
@ -1216,11 +1193,11 @@ class BrowserTestingServer {
void setupErrorServer(HttpServer server) {
errorReportingServer = server;
void errorReportingHandler(HttpRequest request) {
StringBuffer buffer = new StringBuffer();
var buffer = StringBuffer();
request.transform(utf8.decoder).listen((data) {
buffer.write(data);
}, onDone: () {
String back = buffer.toString();
var back = buffer.toString();
request.response.headers.set("Access-Control-Allow-Origin", "*");
request.response.done.catchError((error) {
DebugLogger.error("Error getting error from browser"
@ -1278,15 +1255,15 @@ class BrowserTestingServer {
textResponse = getDriverPage(browserId(request, driverPath));
request.response.headers.set('Content-Type', 'text/html');
} else if (request.uri.path.startsWith(nextTestPath)) {
textResponse = new Future<String>.value(
getNextTest(browserId(request, nextTestPath)));
textResponse =
Future.value(getNextTest(browserId(request, nextTestPath)));
request.response.headers.set('Content-Type', 'text/plain');
} else {
textResponse = new Future<String>.value("");
textResponse = Future.value("");
}
request.response.done.catchError((error) async {
if (!underTermination) {
String text = await textResponse;
var text = await textResponse;
print("URI ${request.uri}");
print("text $text");
throw "Error returning content to browser: $error";
@ -1307,11 +1284,11 @@ class BrowserTestingServer {
void handleReport(HttpRequest request, String browserId, int testId,
{bool isStatusUpdate}) {
StringBuffer buffer = new StringBuffer();
var buffer = StringBuffer();
request.transform(utf8.decoder).listen((data) {
buffer.write(data);
}, onDone: () {
String back = buffer.toString();
var back = buffer.toString();
request.response.close();
if (isStatusUpdate) {
testStatusUpdateCallBack(browserId, back, testId);
@ -1325,14 +1302,14 @@ class BrowserTestingServer {
}
void handleStarted(HttpRequest request, String browserId, int testId) {
StringBuffer buffer = new StringBuffer();
var buffer = StringBuffer();
// If an error occurs while receiving the data from the request stream,
// we don't handle it specially. We can safely ignore it, since the started
// events are not crucial.
request.transform(utf8.decoder).listen((data) {
buffer.write(data);
}, onDone: () {
String back = buffer.toString();
var back = buffer.toString();
request.response.close();
testStartedCallBack(browserId, back, testId);
}, onError: (error) {
@ -1365,7 +1342,7 @@ class BrowserTestingServer {
await testRunner.browserStatus[browserId].browser.onDriverPageRequested();
var errorReportingUrl =
"http://$localIp:${errorReportingServer.port}/$browserId";
String driverContent = """
var driverContent = """
<!DOCTYPE html><html>
<head>
<title>Driving page</title>

View file

@ -7,10 +7,10 @@ import 'path.dart';
import 'test_suite.dart';
class Co19TestSuite extends StandardTestSuite {
RegExp _testRegExp = new RegExp(r"t[0-9]{2}.dart$");
static final _testRegExp = RegExp(r"t[0-9]{2}.dart$");
Co19TestSuite(TestConfiguration configuration, String selector)
: super(configuration, selector, new Path("tests/$selector/src"), [
: super(configuration, selector, Path("tests/$selector/src"), [
"tests/$selector/$selector-co19.status",
"tests/$selector/$selector-analyzer.status",
"tests/$selector/$selector-runtime.status",

View file

@ -18,7 +18,7 @@ import 'utils.dart';
class Command {
static Command browserTest(String url, TestConfiguration configuration,
{bool retry}) {
return new BrowserTestCommand._(url, configuration, retry);
return BrowserTestCommand._(url, configuration, retry);
}
static Command compilation(
@ -28,9 +28,9 @@ class Command {
String executable,
List<String> arguments,
Map<String, String> environment,
{bool alwaysCompile: false,
{bool alwaysCompile = false,
String workingDirectory}) {
return new CompilationCommand._(displayName, outputFile, alwaysCompile,
return CompilationCommand._(displayName, outputFile, alwaysCompile,
bootstrapDependencies, executable, arguments, environment,
workingDirectory: workingDirectory);
}
@ -43,36 +43,35 @@ class Command {
List<String> arguments,
Map<String, String> environment,
List<String> batchArgs) {
return new VMKernelCompilationCommand._(outputFile, neverSkipCompilation,
return VMKernelCompilationCommand._(outputFile, neverSkipCompilation,
bootstrapDependencies, executable, arguments, environment, batchArgs);
}
static Command analysis(String executable, List<String> arguments,
Map<String, String> environmentOverrides) {
return new AnalysisCommand._(executable, arguments, environmentOverrides);
return AnalysisCommand._(executable, arguments, environmentOverrides);
}
static Command compareAnalyzerCfe(String executable, List<String> arguments,
Map<String, String> environmentOverrides) {
return new CompareAnalyzerCfeCommand._(
return CompareAnalyzerCfeCommand._(
executable, arguments, environmentOverrides);
}
static Command specParse(String executable, List<String> arguments,
Map<String, String> environmentOverrides) {
return new SpecParseCommand._(executable, arguments, environmentOverrides);
return SpecParseCommand._(executable, arguments, environmentOverrides);
}
static Command vm(String executable, List<String> arguments,
Map<String, String> environmentOverrides) {
return new VmCommand._(executable, arguments, environmentOverrides);
return VmCommand._(executable, arguments, environmentOverrides);
}
static Command vmBatch(String executable, String tester,
List<String> arguments, Map<String, String> environmentOverrides,
{bool checked: true}) {
return new VmBatchCommand._(
executable, tester, arguments, environmentOverrides,
{bool checked = true}) {
return VmBatchCommand._(executable, tester, arguments, environmentOverrides,
checked: checked);
}
@ -83,37 +82,36 @@ class Command {
List<String> arguments,
bool useBlobs,
bool useElf) {
return new AdbPrecompilationCommand._(precompiledRunner, processTest,
return AdbPrecompilationCommand._(precompiledRunner, processTest,
testDirectory, arguments, useBlobs, useElf);
}
static Command adbDartk(String precompiledRunner, String processTest,
String script, List<String> arguments, List<String> extraLibraries) {
return new AdbDartkCommand._(
return AdbDartkCommand._(
precompiledRunner, processTest, script, arguments, extraLibraries);
}
static Command jsCommandLine(
String displayName, String executable, List<String> arguments,
[Map<String, String> environment]) {
return new JSCommandlineCommand._(
return JSCommandlineCommand._(
displayName, executable, arguments, environment);
}
static Command process(
String displayName, String executable, List<String> arguments,
[Map<String, String> environment, String workingDirectory]) {
return new ProcessCommand._(
return ProcessCommand._(
displayName, executable, arguments, environment, workingDirectory);
}
static Command copy(String sourceDirectory, String destinationDirectory) {
return new CleanDirectoryCopyCommand._(
sourceDirectory, destinationDirectory);
return CleanDirectoryCopyCommand._(sourceDirectory, destinationDirectory);
}
static Command makeSymlink(String link, String target) {
return new MakeSymlinkCommand._(link, target);
return MakeSymlinkCommand._(link, target);
}
static Command fasta(
@ -124,7 +122,7 @@ class Command {
List<String> arguments,
Map<String, String> environment,
Uri workingDirectory) {
return new FastaCompilationCommand._(
return FastaCompilationCommand._(
compilerLocation,
outputFile.toFilePath(),
bootstrapDependencies,
@ -163,7 +161,7 @@ class Command {
int get hashCode {
if (_cachedHashCode == null) {
var builder = new HashCodeBuilder();
var builder = HashCodeBuilder();
_buildHashCode(builder);
_cachedHashCode = builder.value;
}
@ -234,7 +232,7 @@ class ProcessCommand extends Command {
deepJsonCompare(environmentOverrides, other.environmentOverrides);
String get reproductionCommand {
var env = new StringBuffer();
var env = StringBuffer();
environmentOverrides?.forEach((key, value) =>
(io.Platform.operatingSystem == 'windows')
? env.write('set $key=${escapeCommandLineArgument(value)} & ')
@ -292,7 +290,7 @@ class CompilationCommand extends ProcessCommand {
bool get outputIsUpToDate {
if (_alwaysCompile) return false;
var file = new io.File(new Path("$outputFile.deps").toNativePath());
var file = io.File(Path("$outputFile.deps").toNativePath());
if (!file.existsSync()) return false;
var lines = file.readAsLinesSync();
@ -306,7 +304,7 @@ class CompilationCommand extends ProcessCommand {
dependencies.addAll(_bootstrapDependencies);
var jsOutputLastModified = TestUtils.lastModifiedCache
.getLastModified(new Uri(scheme: 'file', path: outputFile));
.getLastModified(Uri(scheme: 'file', path: outputFile));
if (jsOutputLastModified == null) return false;
for (var dependency in dependencies) {
@ -374,12 +372,12 @@ class FastaCompilationCommand extends CompilationCommand {
String relativizeAndEscape(String argument) {
if (workingDirectory != null) {
argument = argument.replaceAll(
workingDirectory, new Uri.directory(".").toFilePath());
workingDirectory, Uri.directory(".").toFilePath());
}
return escapeCommandLineArgument(argument);
}
StringBuffer buffer = new StringBuffer();
StringBuffer buffer = StringBuffer();
if (workingDirectory != null && !io.Platform.isWindows) {
buffer.write("(cd ");
buffer.write(escapeCommandLineArgument(workingDirectory));
@ -561,7 +559,7 @@ class VmBatchCommand extends ProcessCommand implements VmCommand {
VmBatchCommand._(String executable, String dartFile, List<String> arguments,
Map<String, String> environmentOverrides,
{this.checked: true, int index = 0})
{this.checked = true, int index = 0})
: this.dartFile = dartFile,
super._('vm-batch', executable, arguments, environmentOverrides, null,
index);
@ -705,24 +703,24 @@ class CleanDirectoryCopyCommand extends ScriptCommand {
"Copying '$_sourceDirectory' to '$_destinationDirectory'.";
Future<ScriptCommandOutput> run() {
var watch = new Stopwatch()..start();
var watch = Stopwatch()..start();
var destination = new io.Directory(_destinationDirectory);
var destination = io.Directory(_destinationDirectory);
return destination.exists().then((bool exists) {
Future cleanDirectoryFuture;
if (exists) {
cleanDirectoryFuture = TestUtils.deleteDirectory(_destinationDirectory);
} else {
cleanDirectoryFuture = new Future.value(null);
cleanDirectoryFuture = Future.value(null);
}
return cleanDirectoryFuture.then((_) {
return TestUtils.copyDirectory(_sourceDirectory, _destinationDirectory);
});
}).then((_) {
return new ScriptCommandOutput(this, Expectation.pass, "", watch.elapsed);
return ScriptCommandOutput(this, Expectation.pass, "", watch.elapsed);
}).catchError((error) {
return new ScriptCommandOutput(
return ScriptCommandOutput(
this, Expectation.fail, "An error occured: $error.", watch.elapsed);
});
}
@ -754,21 +752,21 @@ class MakeSymlinkCommand extends ScriptCommand {
"Make symbolic link '$_link' (target: $_target)'.";
Future<ScriptCommandOutput> run() {
var watch = new Stopwatch()..start();
var targetFile = new io.Directory(_target);
var watch = Stopwatch()..start();
var targetFile = io.Directory(_target);
return targetFile.exists().then((bool targetExists) {
if (!targetExists) {
throw new Exception("Target '$_target' does not exist");
throw Exception("Target '$_target' does not exist");
}
var link = new io.Link(_link);
var link = io.Link(_link);
return link.exists().then((bool exists) {
if (exists) link.deleteSync();
}).then((_) => link.create(_target));
}).then((_) {
return new ScriptCommandOutput(this, Expectation.pass, "", watch.elapsed);
return ScriptCommandOutput(this, Expectation.pass, "", watch.elapsed);
}).catchError((error) {
return new ScriptCommandOutput(
return ScriptCommandOutput(
this, Expectation.fail, "An error occured: $error.", watch.elapsed);
});
}

View file

@ -12,6 +12,7 @@ import 'package:status_file/expectation.dart';
import 'browser_controller.dart';
import 'command.dart';
import 'configuration.dart';
import 'process_queue.dart';
import 'test_progress.dart';
import 'test_case.dart';
import 'utils.dart';
@ -149,7 +150,7 @@ class CommandOutput extends UniqueObject {
}
class BrowserTestJsonResult {
static const _allowedTypes = const [
static const _allowedTypes = [
'sync_exception',
'window_onerror',
'script_onerror',
@ -211,7 +212,7 @@ class BrowserTestJsonResult {
dom = '$dom\n';
}
return new BrowserTestJsonResult(
return BrowserTestJsonResult(
_getOutcome(messagesByType), dom, events as List<dynamic>);
}
} catch (error) {
@ -311,7 +312,7 @@ class BrowserCommandOutput extends CommandOutput
}
}
return new BrowserCommandOutput._internal(command, result, outcome,
return BrowserCommandOutput._internal(command, result, outcome,
parsedResult, encodeUtf8(""), encodeUtf8(stderr));
}
@ -528,7 +529,7 @@ class AnalysisCommandOutput extends CommandOutput {
// Parse a line delimited by the | character using \ as an escape character
// like: FOO|BAR|FOO\|BAR|FOO\\BAZ as 4 fields: FOO BAR FOO|BAR FOO\BAZ
List<String> splitMachineError(String line) {
var field = new StringBuffer();
var field = StringBuffer();
var result = <String>[];
var escaped = false;
for (var i = 0; i < line.length; i++) {
@ -540,7 +541,7 @@ class AnalysisCommandOutput extends CommandOutput {
escaped = false;
if (c == '|') {
result.add(field.toString());
field = new StringBuffer();
field = StringBuffer();
continue;
}
field.write(c);
@ -1022,40 +1023,40 @@ CommandOutput createCommandOutput(Command command, int exitCode, bool timedOut,
List<int> stdout, List<int> stderr, Duration time, bool compilationSkipped,
[int pid = 0]) {
if (command is AnalysisCommand) {
return new AnalysisCommandOutput(
return AnalysisCommandOutput(
command, exitCode, timedOut, stdout, stderr, time, compilationSkipped);
} else if (command is CompareAnalyzerCfeCommand) {
return new CompareAnalyzerCfeCommandOutput(
return CompareAnalyzerCfeCommandOutput(
command, exitCode, timedOut, stdout, stderr, time, compilationSkipped);
} else if (command is SpecParseCommand) {
return new SpecParseCommandOutput(
return SpecParseCommandOutput(
command, exitCode, timedOut, stdout, stderr, time, compilationSkipped);
} else if (command is VmCommand) {
return new VMCommandOutput(
return VMCommandOutput(
command, exitCode, timedOut, stdout, stderr, time, pid);
} else if (command is VMKernelCompilationCommand) {
return new VMKernelCompilationCommandOutput(
return VMKernelCompilationCommandOutput(
command, exitCode, timedOut, stdout, stderr, time, compilationSkipped);
} else if (command is AdbPrecompilationCommand) {
return new VMCommandOutput(
return VMCommandOutput(
command, exitCode, timedOut, stdout, stderr, time, pid);
} else if (command is CompilationCommand) {
if (command.displayName == 'precompiler' ||
command.displayName == 'app_jit') {
return new VMCommandOutput(
return VMCommandOutput(
command, exitCode, timedOut, stdout, stderr, time, pid);
} else if (command.displayName == 'dartdevc') {
return new DevCompilerCommandOutput(command, exitCode, timedOut, stdout,
return DevCompilerCommandOutput(command, exitCode, timedOut, stdout,
stderr, time, compilationSkipped, pid);
}
return new CompilationCommandOutput(
return CompilationCommandOutput(
command, exitCode, timedOut, stdout, stderr, time, compilationSkipped);
} else if (command is JSCommandlineCommand) {
return new JSCommandLineOutput(
return JSCommandLineOutput(
command, exitCode, timedOut, stdout, stderr, time);
}
return new CommandOutput(command, exitCode, timedOut, stdout, stderr, time,
return CommandOutput(command, exitCode, timedOut, stdout, stderr, time,
compilationSkipped, pid);
}

View file

@ -53,29 +53,28 @@ abstract class CompilerConfiguration {
factory CompilerConfiguration(TestConfiguration configuration) {
switch (configuration.compiler) {
case Compiler.dart2analyzer:
return new AnalyzerCompilerConfiguration(configuration);
return AnalyzerCompilerConfiguration(configuration);
case Compiler.compareAnalyzerCfe:
return new CompareAnalyzerCfeCompilerConfiguration(configuration);
return CompareAnalyzerCfeCompilerConfiguration(configuration);
case Compiler.dart2js:
return new Dart2jsCompilerConfiguration(configuration);
return Dart2jsCompilerConfiguration(configuration);
case Compiler.dartdevc:
return new DevCompilerConfiguration(configuration);
return DevCompilerConfiguration(configuration);
case Compiler.dartdevk:
return new DevCompilerConfiguration(configuration);
return DevCompilerConfiguration(configuration);
case Compiler.appJit:
return new AppJitCompilerConfiguration(configuration,
previewDart2: false);
return AppJitCompilerConfiguration(configuration, previewDart2: false);
case Compiler.appJitk:
return new AppJitCompilerConfiguration(configuration);
return AppJitCompilerConfiguration(configuration);
case Compiler.precompiler:
return new PrecompilerCompilerConfiguration(configuration,
return PrecompilerCompilerConfiguration(configuration,
previewDart2: false);
case Compiler.dartk:
@ -83,24 +82,24 @@ abstract class CompilerConfiguration {
configuration.architecture == Architecture.simarm ||
configuration.architecture == Architecture.simarm64 ||
configuration.system == System.android) {
return new VMKernelCompilerConfiguration(configuration);
return VMKernelCompilerConfiguration(configuration);
}
return new NoneCompilerConfiguration(configuration);
return NoneCompilerConfiguration(configuration);
case Compiler.dartkb:
return new VMKernelCompilerConfiguration(configuration);
return VMKernelCompilerConfiguration(configuration);
case Compiler.dartkp:
return new PrecompilerCompilerConfiguration(configuration);
return PrecompilerCompilerConfiguration(configuration);
case Compiler.specParser:
return new SpecParserCompilerConfiguration(configuration);
return SpecParserCompilerConfiguration(configuration);
case Compiler.fasta:
return new FastaCompilerConfiguration(configuration);
return FastaCompilerConfiguration(configuration);
case Compiler.none:
return new NoneCompilerConfiguration(configuration);
return NoneCompilerConfiguration(configuration);
}
throw "unreachable";
@ -134,7 +133,7 @@ abstract class CompilerConfiguration {
String tempDir,
List<String> arguments,
Map<String, String> environmentOverrides) {
return new CommandArtifact([], null, null);
return CommandArtifact([], null, null);
}
List<String> computeCompilerArguments(
@ -224,7 +223,7 @@ class VMKernelCompilerConfiguration extends CompilerConfiguration
final commands = <Command>[
computeCompileToKernelCommand(tempDir, arguments, environmentOverrides),
];
return new CommandArtifact(commands, tempKernelFile(tempDir),
return CommandArtifact(commands, tempKernelFile(tempDir),
'application/kernel-ir-fully-linked');
}
@ -274,7 +273,7 @@ class VMKernelCompilerConfiguration extends CompilerConfiguration
}
}
typedef List<String> CompilerArgumentsFunction(
typedef CompilerArgumentsFunction = List<String> Function(
List<String> globalArguments, String previousCompilerOutput);
class PipelineCommand {
@ -285,7 +284,7 @@ class PipelineCommand {
factory PipelineCommand.runWithGlobalArguments(
CompilerConfiguration configuration) {
return new PipelineCommand._(configuration,
return PipelineCommand._(configuration,
(List<String> globalArguments, String previousOutput) {
assert(previousOutput == null);
return globalArguments;
@ -294,7 +293,7 @@ class PipelineCommand {
factory PipelineCommand.runWithDartOrKernelFile(
CompilerConfiguration configuration) {
return new PipelineCommand._(configuration,
return PipelineCommand._(configuration,
(List<String> globalArguments, String previousOutput) {
var filtered = globalArguments
.where((name) => name.endsWith('.dart') || name.endsWith('.dill'))
@ -306,7 +305,7 @@ class PipelineCommand {
factory PipelineCommand.runWithPreviousKernelOutput(
CompilerConfiguration configuration) {
return new PipelineCommand._(configuration,
return PipelineCommand._(configuration,
(List<String> globalArguments, String previousOutput) {
assert(previousOutput.endsWith('.dill'));
return _replaceDartFiles(globalArguments, previousOutput);
@ -349,8 +348,7 @@ class ComposedCompilerConfiguration extends CompilerConfiguration {
allCommands.addAll(artifact.commands);
}
return new CommandArtifact(
allCommands, artifact.filename, artifact.mimeType);
return CommandArtifact(allCommands, artifact.filename, artifact.mimeType);
}
List<String> computeCompilerArguments(
@ -438,7 +436,7 @@ class Dart2xCompilerConfiguration extends CompilerConfiguration {
_configuration.buildDirectory,
() => [
Uri.base
.resolveUri(new Uri.directory(_configuration.buildDirectory))
.resolveUri(Uri.directory(_configuration.buildDirectory))
.resolve('dart-sdk/bin/snapshots/dart2js.dart.snapshot')
]);
}
@ -480,7 +478,7 @@ class Dart2jsCompilerConfiguration extends Dart2xCompilerConfiguration {
// TODO(athom): input filename extraction is copied from DDC. Maybe this
// should be passed to computeCompilationArtifact, instead?
var inputFile = arguments.last;
var inputFilename = (new Uri.file(inputFile)).pathSegments.last;
var inputFilename = (Uri.file(inputFile)).pathSegments.last;
var out = "$tempDir/${inputFilename.replaceAll('.dart', '.js')}";
var babel = _configuration.babel;
var babelOut = out;
@ -494,7 +492,7 @@ class Dart2jsCompilerConfiguration extends Dart2xCompilerConfiguration {
commands.add(computeBabelCommand(out, babelOut, babel));
}
return new CommandArtifact(commands, babelOut, 'application/javascript');
return CommandArtifact(commands, babelOut, 'application/javascript');
}
List<String> computeRuntimeArguments(
@ -506,8 +504,8 @@ class Dart2jsCompilerConfiguration extends Dart2xCompilerConfiguration {
List<String> originalArguments,
CommandArtifact artifact) {
Uri sdk = _useSdk
? new Uri.directory(_configuration.buildDirectory).resolve('dart-sdk/')
: new Uri.directory(Repository.dir.toNativePath()).resolve('sdk/');
? Uri.directory(_configuration.buildDirectory).resolve('dart-sdk/')
: Uri.directory(Repository.dir.toNativePath()).resolve('sdk/');
Uri preambleDir = sdk.resolve('lib/_internal/js_runtime/lib/preambles/');
return runtimeConfiguration.dart2jsPreambles(preambleDir)
..add(artifact.filename);
@ -589,7 +587,7 @@ class DevCompilerConfiguration extends CompilerConfiguration {
// at the built summary file location.
var sdkSummaryFile =
useDillFormat ? 'kernel/ddc_sdk.dill' : 'ddc_sdk.sum';
var sdkSummary = new Path(_configuration.buildDirectory)
var sdkSummary = Path(_configuration.buildDirectory)
.append("/gen/utils/dartdevc/$sdkSummaryFile")
.absolute
.toNativePath();
@ -600,7 +598,7 @@ class DevCompilerConfiguration extends CompilerConfiguration {
if (!useKernel) {
// TODO(jmesserly): library-root needs to be removed.
args.addAll(
["--library-root", new Path(inputFile).directoryPath.toNativePath()]);
["--library-root", Path(inputFile).directoryPath.toNativePath()]);
}
args.addAll([
@ -622,15 +620,14 @@ class DevCompilerConfiguration extends CompilerConfiguration {
// Since the summaries for the packages are not near the tests, we give
// dartdevc explicit module paths for each one. When the test is run, we
// will tell require.js where to find each package's compiled JS.
var summary = new Path(_configuration.buildDirectory)
var summary = Path(_configuration.buildDirectory)
.append("/gen/utils/dartdevc/$pkgDir/$package.$pkgExtension")
.absolute
.toNativePath();
args.add("$summary=$package");
}
var inputDir =
new Path(inputFile).append("..").canonicalize().toNativePath();
var inputDir = Path(inputFile).append("..").canonicalize().toNativePath();
var displayName = useKernel ? 'dartdevk' : 'dartdevc';
return Command.compilation(displayName, outputFile, bootstrapDependencies(),
computeCompilerPath(), args, environment,
@ -646,10 +643,10 @@ class DevCompilerConfiguration extends CompilerConfiguration {
// computeCompilerArguments() to here seems hacky. Is there a cleaner way?
var sharedOptions = arguments.sublist(0, arguments.length - 1);
var inputFile = arguments.last;
var inputFilename = (new Uri.file(inputFile)).pathSegments.last;
var inputFilename = (Uri.file(inputFile)).pathSegments.last;
var outputFile = "$tempDir/${inputFilename.replaceAll('.dart', '.js')}";
return new CommandArtifact(
return CommandArtifact(
[_createCommand(inputFile, outputFile, sharedOptions, environment)],
outputFile,
"application/javascript");
@ -669,7 +666,7 @@ class PrecompilerCompilerConfiguration extends CompilerConfiguration
bool get _isAot => true;
PrecompilerCompilerConfiguration(TestConfiguration configuration,
{this.previewDart2: true})
{this.previewDart2 = true})
: super._subclass(configuration);
int get timeoutMultiplier {
@ -703,7 +700,7 @@ class PrecompilerCompilerConfiguration extends CompilerConfiguration
}
}
return new CommandArtifact(
return CommandArtifact(
commands, '$tempDir', 'application/dart-precompiled');
}
@ -913,7 +910,7 @@ class AppJitCompilerConfiguration extends CompilerConfiguration {
final bool previewDart2;
AppJitCompilerConfiguration(TestConfiguration configuration,
{this.previewDart2: true})
{this.previewDart2 = true})
: super._subclass(configuration);
int get timeoutMultiplier {
@ -926,7 +923,7 @@ class AppJitCompilerConfiguration extends CompilerConfiguration {
CommandArtifact computeCompilationArtifact(String tempDir,
List<String> arguments, Map<String, String> environmentOverrides) {
var snapshot = "$tempDir/out.jitsnapshot";
return new CommandArtifact(
return CommandArtifact(
[computeCompilationCommand(tempDir, arguments, environmentOverrides)],
snapshot,
'application/dart-snapshot');
@ -1013,7 +1010,7 @@ class AnalyzerCompilerConfiguration extends CompilerConfiguration {
List<String> arguments, Map<String, String> environmentOverrides) {
arguments = arguments.toList();
if (!previewDart2) {
throw new ArgumentError('--no-preview-dart-2 not supported');
throw ArgumentError('--no-preview-dart-2 not supported');
}
if (_configuration.useAnalyzerCfe) {
arguments.add('--use-cfe');
@ -1023,7 +1020,7 @@ class AnalyzerCompilerConfiguration extends CompilerConfiguration {
}
// Since this is not a real compilation, no artifacts are produced.
return new CommandArtifact([
return CommandArtifact([
Command.analysis(computeCompilerPath(), arguments, environmentOverrides)
], null, null);
}
@ -1059,11 +1056,11 @@ class CompareAnalyzerCfeCompilerConfiguration extends CompilerConfiguration {
List<String> arguments, Map<String, String> environmentOverrides) {
arguments = arguments.toList();
if (!previewDart2) {
throw new ArgumentError('--no-preview-dart-2 not supported');
throw ArgumentError('--no-preview-dart-2 not supported');
}
// Since this is not a real compilation, no artifacts are produced.
return new CommandArtifact([
return CommandArtifact([
Command.compareAnalyzerCfe(
computeCompilerPath(), arguments, environmentOverrides)
], null, null);
@ -1093,7 +1090,7 @@ class SpecParserCompilerConfiguration extends CompilerConfiguration {
arguments = arguments.toList();
// Since this is not a real compilation, no artifacts are produced.
return new CommandArtifact([
return CommandArtifact([
Command.specParse(computeCompilerPath(), arguments, environmentOverrides)
], null, null);
}
@ -1112,7 +1109,7 @@ class SpecParserCompilerConfiguration extends CompilerConfiguration {
abstract class VMKernelCompilerMixin {
static final noCausalAsyncStacksRegExp =
new RegExp('--no[_-]causal[_-]async[_-]stacks');
RegExp('--no[_-]causal[_-]async[_-]stacks');
TestConfiguration get _configuration;
@ -1127,7 +1124,7 @@ abstract class VMKernelCompilerMixin {
List<Uri> bootstrapDependencies();
String tempKernelFile(String tempDir) =>
new Path('$tempDir/out.dill').toNativePath();
Path('$tempDir/out.dill').toNativePath();
Command computeCompileToKernelCommand(String tempDir, List<String> arguments,
Map<String, String> environmentOverrides) {
@ -1202,7 +1199,7 @@ class FastaCompilerConfiguration extends CompilerConfiguration {
factory FastaCompilerConfiguration(TestConfiguration configuration) {
var buildDirectory =
Uri.base.resolveUri(new Uri.directory(configuration.buildDirectory));
Uri.base.resolveUri(Uri.directory(configuration.buildDirectory));
var dillDir = buildDirectory;
if (configuration.useSdk) {
@ -1214,7 +1211,7 @@ class FastaCompilerConfiguration extends CompilerConfiguration {
var vmExecutable = buildDirectory
.resolve(configuration.useSdk ? "dart-sdk/bin/dart" : "dart");
return new FastaCompilerConfiguration._(
return FastaCompilerConfiguration._(
platformDill, vmExecutable, configuration);
}
@ -1232,7 +1229,7 @@ class FastaCompilerConfiguration extends CompilerConfiguration {
CommandArtifact computeCompilationArtifact(String tempDir,
List<String> arguments, Map<String, String> environmentOverrides) {
var output =
Uri.base.resolveUri(new Uri.directory(tempDir)).resolve("out.dill");
Uri.base.resolveUri(Uri.directory(tempDir)).resolve("out.dill");
var outputFileName = output.toFilePath();
var compilerArguments = <String>['--verify'];
@ -1244,7 +1241,7 @@ class FastaCompilerConfiguration extends CompilerConfiguration {
["-o", outputFileName, "--platform", _platformDill.toFilePath()]);
compilerArguments.addAll(arguments);
return new CommandArtifact([
return CommandArtifact([
Command.fasta(
_compilerLocation,
output,
@ -1264,7 +1261,7 @@ class FastaCompilerConfiguration extends CompilerConfiguration {
List<String> dart2jsOptions,
List<String> ddcOptions,
List<String> args) {
List<String> arguments = new List<String>.from(sharedOptions);
List<String> arguments = List<String>.from(sharedOptions);
arguments.addAll(_configuration.sharedOptions);
for (String argument in args) {
if (argument == "--ignore-unrecognized-flags") continue;

View file

@ -173,7 +173,7 @@ class TestConfiguration {
TestingServers get servers {
if (_servers == null) {
throw new StateError("Servers have not been started yet.");
throw StateError("Servers have not been started yet.");
}
return _servers;
}
@ -255,7 +255,7 @@ class TestConfiguration {
String get windowsSdkPath {
if (!Platform.isWindows) {
throw new StateError(
throw StateError(
"Should not use windowsSdkPath when not running on Windows.");
}
@ -263,8 +263,8 @@ class TestConfiguration {
// When running tests on Windows, use cdb from depot_tools to dump
// stack traces of tests timing out.
try {
var path = new Path("build/win_toolchain.json").toNativePath();
var text = new File(path).readAsStringSync();
var path = Path("build/win_toolchain.json").toNativePath();
var text = File(path).readAsStringSync();
_windowsSdkPath = jsonDecode(text)['win_sdk'] as String;
} on dynamic {
// Ignore errors here. If win_sdk is not found, stack trace dumping
@ -293,29 +293,29 @@ class TestConfiguration {
if (location != null) return location;
const locations = const {
Runtime.firefox: const {
const locations = {
Runtime.firefox: {
System.win: 'C:\\Program Files (x86)\\Mozilla Firefox\\firefox.exe',
System.linux: 'firefox',
System.mac: '/Applications/Firefox.app/Contents/MacOS/firefox'
},
Runtime.chrome: const {
Runtime.chrome: {
System.win:
'C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe',
System.mac:
'/Applications/Google Chrome.app/Contents/MacOS/Google Chrome',
System.linux: 'google-chrome'
},
Runtime.safari: const {
Runtime.safari: {
System.mac: '/Applications/Safari.app/Contents/MacOS/Safari'
},
Runtime.ie9: const {
Runtime.ie9: {
System.win: 'C:\\Program Files\\Internet Explorer\\iexplore.exe'
},
Runtime.ie10: const {
Runtime.ie10: {
System.win: 'C:\\Program Files\\Internet Explorer\\iexplore.exe'
},
Runtime.ie11: const {
Runtime.ie11: {
System.win: 'C:\\Program Files\\Internet Explorer\\iexplore.exe'
}
};
@ -332,12 +332,12 @@ class TestConfiguration {
RuntimeConfiguration _runtimeConfiguration;
RuntimeConfiguration get runtimeConfiguration =>
_runtimeConfiguration ??= new RuntimeConfiguration(this);
_runtimeConfiguration ??= RuntimeConfiguration(this);
CompilerConfiguration _compilerConfiguration;
CompilerConfiguration get compilerConfiguration =>
_compilerConfiguration ??= new CompilerConfiguration(this);
_compilerConfiguration ??= CompilerConfiguration(this);
/// Determines if this configuration has a compatible compiler and runtime
/// and other valid fields.
@ -377,7 +377,7 @@ class TestConfiguration {
/// server for cross-domain tests can be found by calling
/// `getCrossOriginPortNumber()`.
Future startServers() {
_servers = new TestingServers(
_servers = TestingServers(
buildDirectory, isCsp, runtime, null, packageRoot, packages);
var future = servers.startServers(localIP,
port: testServerPort, crossOriginPort: testServerCrossOriginPort);
@ -414,8 +414,8 @@ class TestConfiguration {
var normal = '$modeName$os$arch';
var cross = '$modeName${os}X$arch';
var outDir = system.outputDirectory;
var normalDir = new Directory(new Path('$outDir$normal').toNativePath());
var crossDir = new Directory(new Path('$outDir$cross').toNativePath());
var normalDir = Directory(Path('$outDir$normal').toNativePath());
var crossDir = Directory(Path('$outDir$cross').toNativePath());
if (normalDir.existsSync() && crossDir.existsSync()) {
throw "You can't have both $normalDir and $crossDir. We don't know which"
@ -468,18 +468,18 @@ class TestConfiguration {
}
class Progress {
static const compact = const Progress._('compact');
static const color = const Progress._('color');
static const line = const Progress._('line');
static const verbose = const Progress._('verbose');
static const silent = const Progress._('silent');
static const status = const Progress._('status');
static const buildbot = const Progress._('buildbot');
static const diff = const Progress._('diff');
static const compact = Progress._('compact');
static const color = Progress._('color');
static const line = Progress._('line');
static const verbose = Progress._('verbose');
static const silent = Progress._('silent');
static const status = Progress._('status');
static const buildbot = Progress._('buildbot');
static const diff = Progress._('diff');
static final List<String> names = _all.keys.toList();
static final _all = new Map<String, Progress>.fromIterable(
static final _all = Map<String, Progress>.fromIterable(
[compact, color, line, verbose, silent, status, buildbot, diff],
key: (progress) => (progress as Progress).name);
@ -487,7 +487,7 @@ class Progress {
var progress = _all[name];
if (progress != null) return progress;
throw new ArgumentError('Unknown progress type "$name".');
throw ArgumentError('Unknown progress type "$name".');
}
final String name;

View file

@ -12,7 +12,7 @@ import 'utils.dart';
/// The graph exposes a few broadcast streams that can be subscribed to in
/// order to be notified of modifications to the graph.
class Graph<T> {
final _nodes = new Set<Node<T>>();
final _nodes = <Node<T>>{};
final _stateCounts = <NodeState, int>{};
bool _isSealed = false;
@ -29,11 +29,11 @@ class Graph<T> {
final StreamController<Null> _sealedController;
factory Graph() {
var added = new StreamController<Node<T>>();
var changed = new StreamController<StateChangedEvent<T>>();
var sealed = new StreamController<Null>();
var added = StreamController<Node<T>>();
var changed = StreamController<StateChangedEvent<T>>();
var sealed = StreamController<Null>();
return new Graph._(
return Graph._(
added,
added.stream.asBroadcastStream(),
changed,
@ -74,7 +74,7 @@ class Graph<T> {
{bool timingDependency = false}) {
assert(!_isSealed);
var node = new Node._(userData, timingDependency);
var node = Node._(userData, timingDependency);
_nodes.add(node);
for (var dependency in dependencies) {
@ -99,8 +99,7 @@ class Graph<T> {
_stateCounts.putIfAbsent(state, () => 0);
_stateCounts[state] += 1;
_emitEvent(
_changedController, new StateChangedEvent(node, fromState, state));
_emitEvent(_changedController, StateChangedEvent(node, fromState, state));
}
/// We emit events asynchronously so the graph can be build up in small
@ -117,8 +116,8 @@ class Node<T> extends UniqueObject {
final T data;
final bool timingDependency;
NodeState _state = NodeState.initialized;
final Set<Node<T>> _dependencies = new Set();
final Set<Node<T>> _neededFor = new Set();
final Set<Node<T>> _dependencies = {};
final Set<Node<T>> _neededFor = {};
Node._(this.data, this.timingDependency);
@ -128,13 +127,13 @@ class Node<T> extends UniqueObject {
}
class NodeState {
static const initialized = const NodeState._("Initialized");
static const waiting = const NodeState._("Waiting");
static const enqueuing = const NodeState._("Enqueuing");
static const processing = const NodeState._("Running");
static const successful = const NodeState._("Successful");
static const failed = const NodeState._("Failed");
static const unableToRun = const NodeState._("UnableToRun");
static const initialized = NodeState._("Initialized");
static const waiting = NodeState._("Waiting");
static const enqueuing = NodeState._("Enqueuing");
static const processing = NodeState._("Running");
static const successful = NodeState._("Successful");
static const failed = NodeState._("Failed");
static const unableToRun = NodeState._("UnableToRun");
final String name;

View file

@ -6,38 +6,37 @@ import 'package:status_file/environment.dart';
import 'configuration.dart';
typedef String _LookUpFunction(TestConfiguration configuration);
typedef bool _BoolLookUpFunction(TestConfiguration configuration);
typedef _LookUpFunction = String Function(TestConfiguration configuration);
typedef _BoolLookUpFunction = bool Function(TestConfiguration configuration);
// TODO(29756): Instead of synthesized negated variables like "unchecked",
// consider adding support for "!" to status expressions.
final _variables = {
"analyzer": new _Variable.bool((c) => c.compiler == Compiler.dart2analyzer),
"analyzer_use_fasta_parser":
new _Variable.bool((c) => c.useAnalyzerFastaParser),
"arch": new _Variable((c) => c.architecture.name, Architecture.names),
"browser": new _Variable.bool((c) => c.runtime.isBrowser),
"builder_tag": new _Variable((c) => c.builderTag ?? "", const []),
"checked": new _Variable.bool((c) => c.isChecked),
"compiler": new _Variable((c) => c.compiler.name, Compiler.names),
"csp": new _Variable.bool((c) => c.isCsp),
"enable_asserts": new _Variable.bool((c) => c.useEnableAsserts),
"fasta": new _Variable.bool((c) => c.usesFasta),
"host_checked": new _Variable.bool((c) => c.isHostChecked),
"host_unchecked": new _Variable.bool((c) => !c.isHostChecked),
"hot_reload": new _Variable.bool((c) => c.hotReload),
"hot_reload_rollback": new _Variable.bool((c) => c.hotReloadRollback),
"ie": new _Variable.bool((c) => c.runtime.isIE),
"jscl": new _Variable.bool((c) => c.runtime.isJSCommandLine),
"minified": new _Variable.bool((c) => c.isMinified),
"mode": new _Variable((c) => c.mode.name, Mode.names),
"no_preview_dart_2": new _Variable.bool((c) => c.noPreviewDart2),
"preview_dart_2": new _Variable.bool((c) => !c.noPreviewDart2),
"runtime": new _Variable(_runtimeName, _runtimeNames),
"spec_parser": new _Variable.bool((c) => c.compiler == Compiler.specParser),
"strong": new _Variable.bool((c) => !c.noPreviewDart2),
"system": new _Variable(_systemName, _systemNames),
"use_sdk": new _Variable.bool((c) => c.useSdk)
"analyzer": _Variable.bool((c) => c.compiler == Compiler.dart2analyzer),
"analyzer_use_fasta_parser": _Variable.bool((c) => c.useAnalyzerFastaParser),
"arch": _Variable((c) => c.architecture.name, Architecture.names),
"browser": _Variable.bool((c) => c.runtime.isBrowser),
"builder_tag": _Variable((c) => c.builderTag ?? "", const []),
"checked": _Variable.bool((c) => c.isChecked),
"compiler": _Variable((c) => c.compiler.name, Compiler.names),
"csp": _Variable.bool((c) => c.isCsp),
"enable_asserts": _Variable.bool((c) => c.useEnableAsserts),
"fasta": _Variable.bool((c) => c.usesFasta),
"host_checked": _Variable.bool((c) => c.isHostChecked),
"host_unchecked": _Variable.bool((c) => !c.isHostChecked),
"hot_reload": _Variable.bool((c) => c.hotReload),
"hot_reload_rollback": _Variable.bool((c) => c.hotReloadRollback),
"ie": _Variable.bool((c) => c.runtime.isIE),
"jscl": _Variable.bool((c) => c.runtime.isJSCommandLine),
"minified": _Variable.bool((c) => c.isMinified),
"mode": _Variable((c) => c.mode.name, Mode.names),
"no_preview_dart_2": _Variable.bool((c) => c.noPreviewDart2),
"preview_dart_2": _Variable.bool((c) => !c.noPreviewDart2),
"runtime": _Variable(_runtimeName, _runtimeNames),
"spec_parser": _Variable.bool((c) => c.compiler == Compiler.specParser),
"strong": _Variable.bool((c) => !c.noPreviewDart2),
"system": _Variable(_systemName, _systemNames),
"use_sdk": _Variable.bool((c) => c.useSdk)
};
/// Gets the name of the runtime as it appears in status files.
@ -103,7 +102,7 @@ class ConfigurationEnvironment implements Environment {
if (variable == null) {
// This shouldn't happen since we validate variables before evaluating
// expressions.
throw new ArgumentError('Unknown variable "$variable".');
throw ArgumentError('Unknown variable "$variable".');
}
return variable.lookUp(_configuration);

View file

@ -27,16 +27,16 @@ class ExpectationSet {
final Map<String, RegExp> _globCache = {};
/// The root of the expectation tree.
final _PathNode _tree = new _PathNode();
final _PathNode _tree = _PathNode();
/// Reads the expectations defined by the status files at [statusFilePaths]
/// when in [configuration].
ExpectationSet.read(
List<String> statusFilePaths, TestConfiguration configuration) {
try {
var environment = new ConfigurationEnvironment(configuration);
var environment = ConfigurationEnvironment(configuration);
for (var path in statusFilePaths) {
var file = new StatusFile.read(path);
var file = StatusFile.read(path);
file.validate(environment);
for (var section in file.sections) {
if (section.isEnabled(environment)) {
@ -60,11 +60,11 @@ class ExpectationSet {
for (var part in entry.path.split('/')) {
if (part.contains("*")) {
var regExp = _globCache.putIfAbsent(part, () {
return new RegExp("^" + part.replaceAll("*", ".*") + r"$");
return RegExp("^" + part.replaceAll("*", ".*") + r"$");
});
tree = tree.regExpChildren.putIfAbsent(regExp, () => new _PathNode());
tree = tree.regExpChildren.putIfAbsent(regExp, () => _PathNode());
} else {
tree = tree.stringChildren.putIfAbsent(part, () => new _PathNode());
tree = tree.stringChildren.putIfAbsent(part, () => _PathNode());
}
}
@ -80,7 +80,7 @@ class ExpectationSet {
/// checks that the anchored regular expression "^$keyComponent\$" matches
/// the corresponding filename component.
Set<Expectation> expectations(String path) {
var result = new Set<Expectation>();
var result = <Expectation>{};
_tree.walk(path.split('/'), 0, result);
// If no status files modified the expectation, default to the test passing.
@ -105,7 +105,7 @@ class _PathNode {
/// The test expectatations that any test within this directory should
/// include.
final Set<Expectation> expectations = new Set();
final Set<Expectation> expectations = {};
/// Walks the list of path [parts], starting at [index] adding any
/// expectations to [result] from this node and any of its matching children.

View file

@ -77,7 +77,7 @@ import "test_suite.dart";
import "utils.dart";
/// Until legacy multitests are ported we need to support both /// and //#
final _multitestMarker = new RegExp(r"//[/#]");
final _multitestMarker = RegExp(r"//[/#]");
final _multitestOutcomes = [
'ok',
@ -92,7 +92,7 @@ final _multitestOutcomes = [
void extractTestsFromMultitest(Path filePath, Map<String, String> tests,
Map<String, Set<String>> outcomes) {
var contents = new File(filePath.toNativePath()).readAsStringSync();
var contents = File(filePath.toNativePath()).readAsStringSync();
var firstNewline = contents.indexOf('\n');
var lineSeparator =
@ -105,8 +105,8 @@ void extractTestsFromMultitest(Path filePath, Map<String, String> tests,
var testsAsLines = <String, List<String>>{};
// Add the default case with key "none".
testsAsLines['none'] = <String>[];
outcomes['none'] = new Set<String>();
testsAsLines['none'] = [];
outcomes['none'] = {};
var lineCount = 0;
for (var line in lines) {
@ -114,12 +114,12 @@ void extractTestsFromMultitest(Path filePath, Map<String, String> tests,
var annotation = _Annotation.tryParse(line);
if (annotation != null) {
testsAsLines.putIfAbsent(
annotation.key, () => new List<String>.from(testsAsLines["none"]));
annotation.key, () => List<String>.from(testsAsLines["none"]));
// Add line to test with annotation.key as key, empty line to the rest.
for (var key in testsAsLines.keys) {
testsAsLines[key].add(annotation.key == key ? line : "");
}
outcomes.putIfAbsent(annotation.key, () => new Set<String>());
outcomes.putIfAbsent(annotation.key, () => <String>{});
if (annotation.rest != 'continued') {
for (var nextOutcome in annotation.outcomes) {
if (_multitestOutcomes.contains(nextOutcome)) {
@ -165,8 +165,7 @@ void extractTestsFromMultitest(Path filePath, Map<String, String> tests,
Future doMultitest(Path filePath, String outputDir, Path suiteDir,
CreateTest doTest, bool hotReload) {
void writeFile(String filepath, String content) {
final File file = new File(filepath);
var file = File(filepath);
if (file.existsSync()) {
var oldContent = file.readAsStringSync();
if (oldContent == content) {
@ -190,7 +189,7 @@ Future doMultitest(Path filePath, String outputDir, Path suiteDir,
var importsToCopy = _findAllRelativeImports(filePath);
var futureCopies = <Future>[];
for (var relativeImport in importsToCopy) {
var importPath = new Path(relativeImport);
var importPath = Path(relativeImport);
// Make sure the target directory exists.
var importDir = importPath.directoryPath;
if (!importDir.isEmpty) {
@ -249,12 +248,12 @@ class _Annotation {
.split(_multitestMarker)[1]
.split(':')
.map((s) => s.trim())
.where((s) => s.length > 0)
.where((s) => s.isNotEmpty)
.toList();
if (parts.length <= 1) return null;
return new _Annotation._(parts[0], parts[1]);
return _Annotation._(parts[0], parts[1]);
}
final String key;
@ -272,9 +271,9 @@ class _Annotation {
/// Finds all relative imports and copies them into the directory with the
/// generated tests.
Set<String> _findAllRelativeImports(Path topLibrary) {
var found = new Set<String>();
var found = <String>{};
var libraryDir = topLibrary.directoryPath;
var relativeImportRegExp = new RegExp(
var relativeImportRegExp = RegExp(
'^(?:@.*\\s+)?' // Allow for a meta-data annotation.
'(import|part)'
'\\s+["\']'
@ -283,7 +282,7 @@ Set<String> _findAllRelativeImports(Path topLibrary) {
'["\']');
processFile(Path filePath) {
var file = new File(filePath.toNativePath());
var file = File(filePath.toNativePath());
for (var line in file.readAsLinesSync()) {
var match = relativeImportRegExp.firstMatch(line);
if (match == null) continue;
@ -327,10 +326,10 @@ String _suiteNameFromPath(Path suiteDir) {
Path _createMultitestDirectory(
String outputDir, Path suiteDir, Path sourceDir) {
var relative = sourceDir.relativeTo(suiteDir);
var path = new Path(outputDir)
var path = Path(outputDir)
.append('generated_tests')
.append(_suiteNameFromPath(suiteDir))
.join(relative);
TestUtils.mkdirRecursive(Path.workingDirectory, path);
return new Path(new File(path.toNativePath()).absolute.path);
return Path(File(path.toNativePath()).absolute.path);
}

View file

@ -12,7 +12,7 @@ import 'path.dart';
import 'repository.dart';
import 'utils.dart';
const _defaultTestSelectors = const [
const _defaultTestSelectors = [
'samples',
'standalone',
'standalone_2',
@ -82,9 +82,9 @@ enum _OptionValueType { bool, int, string }
/// Parses command line arguments and produces a test runner configuration.
class OptionsParser {
static final List<_Option> _options = [
new _Option('mode', 'Mode in which to run the tests.',
_Option('mode', 'Mode in which to run the tests.',
abbr: 'm', values: ['all']..addAll(Mode.names)),
new _Option(
_Option(
'compiler',
'''How the Dart code should be compiled or statically processed.
@ -102,7 +102,7 @@ dartkp: Compile the Dart code into Kernel and then Kernel into AOT
spec_parser: Parse Dart code using the specification parser.''',
abbr: 'c',
values: Compiler.names),
new _Option(
_Option(
'runtime',
'''Where the tests should be run.
vm: Run Dart code on the standalone Dart VM.
@ -126,7 +126,7 @@ self_check: Pass each test or its compiled output to every file under
none: No runtime, compile only.''',
abbr: 'r',
values: Runtime.names),
new _Option(
_Option(
'arch',
'''The architecture to run tests for.
@ -140,54 +140,51 @@ simdbc, simdbc64''',
values: ['all']..addAll(Architecture.names),
defaultsTo: Architecture.x64.name,
hide: true),
new _Option('system', 'The operating system to run tests on.',
_Option('system', 'The operating system to run tests on.',
abbr: 's',
values: System.names,
defaultsTo: Platform.operatingSystem,
hide: true),
new _Option(
_Option(
'named_configuration',
'''The named test configuration that supplies the values for all
test options, specifying how tests should be run.''',
abbr: 'n',
hide: true),
new _Option.bool('strong', 'Deprecated, no-op.', hide: true),
_Option.bool('strong', 'Deprecated, no-op.', hide: true),
// TODO(sigmund): rename flag once we migrate all dart2js bots to the test
// matrix.
new _Option.bool('host_checked', 'Run compiler with assertions enabled.',
_Option.bool('host_checked', 'Run compiler with assertions enabled.',
hide: true),
new _Option.bool('minified', 'Enable minification in the compiler.',
_Option.bool('minified', 'Enable minification in the compiler.',
hide: true),
new _Option.bool(
'csp', 'Run tests under Content Security Policy restrictions.',
_Option.bool('csp', 'Run tests under Content Security Policy restrictions.',
hide: true),
new _Option.bool('fast_tests',
_Option.bool('fast_tests',
'Only run tests that are not marked `Slow` or `Timeout`.'),
new _Option.bool('enable_asserts',
_Option.bool('enable_asserts',
'Pass the --enable-asserts flag to dart2js or to the vm.'),
new _Option.bool('no_preview_dart_2',
_Option.bool('no_preview_dart_2',
'Enable legacy Dart 1 behavior for some runtimes and compilers.',
hide: true),
new _Option.bool('use_cfe', 'Pass the --use-cfe flag to analyzer',
hide: true),
new _Option.bool('analyzer_use_fasta_parser',
_Option.bool('use_cfe', 'Pass the --use-cfe flag to analyzer', hide: true),
_Option.bool('analyzer_use_fasta_parser',
'Pass the --use-fasta-parser flag to analyzer',
hide: true),
new _Option.bool('hot_reload', 'Run hot reload stress tests.', hide: true),
new _Option.bool(
'hot_reload_rollback', 'Run hot reload rollback stress tests.',
_Option.bool('hot_reload', 'Run hot reload stress tests.', hide: true),
_Option.bool('hot_reload_rollback', 'Run hot reload rollback stress tests.',
hide: true),
new _Option.bool(
_Option.bool(
'use_blobs', 'Use mmap instead of shared libraries for precompilation.',
hide: true),
new _Option.bool('use_elf',
_Option.bool('use_elf',
'Directly generate an ELF shared libraries for precompilation.',
hide: true),
new _Option.bool('keep_generated_files', 'Keep any generated files.',
_Option.bool('keep_generated_files', 'Keep any generated files.',
abbr: 'k'),
new _Option.int('timeout', 'Timeout in seconds.', abbr: 't'),
new _Option(
_Option.int('timeout', 'Timeout in seconds.', abbr: 't'),
_Option(
'progress',
'''Progress indication mode.
@ -196,130 +193,126 @@ compact, color, line, verbose, silent, status, buildbot, diff''',
abbr: 'p',
values: Progress.names,
defaultsTo: Progress.compact.name),
new _Option('step_name', 'Step name for use by -pbuildbot.', hide: true),
new _Option.bool('report',
_Option('step_name', 'Step name for use by -pbuildbot.', hide: true),
_Option.bool('report',
'Print a summary report of the number of tests, by expectation.',
hide: true),
new _Option.int('tasks', 'The number of parallel tasks to run.',
_Option.int('tasks', 'The number of parallel tasks to run.',
abbr: 'j', defaultsTo: Platform.numberOfProcessors),
new _Option.int('shards',
_Option.int('shards',
'The number of instances that the tests will be sharded over.',
defaultsTo: 1, hide: true),
new _Option.int(
_Option.int(
'shard', 'The index of this instance when running in sharded mode.',
defaultsTo: 1, hide: true),
new _Option.bool('help', 'Print list of options.', abbr: 'h'),
new _Option.int('repeat', 'How many times each test is run', defaultsTo: 1),
new _Option.bool('verbose', 'Verbose output.', abbr: 'v'),
new _Option.bool('verify-ir', 'Verify kernel IR.', hide: true),
new _Option.bool('no-tree-shake', 'Disable kernel IR tree shaking.',
_Option.bool('help', 'Print list of options.', abbr: 'h'),
_Option.int('repeat', 'How many times each test is run', defaultsTo: 1),
_Option.bool('verbose', 'Verbose output.', abbr: 'v'),
_Option.bool('verify-ir', 'Verify kernel IR.', hide: true),
_Option.bool('no-tree-shake', 'Disable kernel IR tree shaking.',
hide: true),
new _Option.bool('list', 'List tests only, do not run them.'),
new _Option.bool('list-configurations', 'Output list of configurations.'),
new _Option.bool('list_status_files',
_Option.bool('list', 'List tests only, do not run them.'),
_Option.bool('list-configurations', 'Output list of configurations.'),
_Option.bool('list_status_files',
'List status files for test-suites. Do not run any test suites.',
hide: true),
new _Option.bool(
'clean_exit', 'Exit 0 if tests ran and results were output.',
_Option.bool('clean_exit', 'Exit 0 if tests ran and results were output.',
hide: true),
new _Option.bool(
_Option.bool(
'silent_failures',
"Don't complain about failing tests. This is useful when in "
"combination with --write-results.",
hide: true),
new _Option.bool('report_in_json',
_Option.bool('report_in_json',
'When listing with --list, output result summary in JSON.',
hide: true),
new _Option.bool('time', 'Print timing information after running tests.'),
new _Option('dart', 'Path to dart executable.', hide: true),
new _Option('gen-snapshot', 'Path to gen_snapshot executable.', hide: true),
new _Option('firefox', 'Path to firefox browser executable.', hide: true),
new _Option('chrome', 'Path to chrome browser executable.', hide: true),
new _Option('safari', 'Path to safari browser executable.', hide: true),
new _Option.bool('use_sdk', '''Use compiler or runtime from the SDK.'''),
_Option.bool('time', 'Print timing information after running tests.'),
_Option('dart', 'Path to dart executable.', hide: true),
_Option('gen-snapshot', 'Path to gen_snapshot executable.', hide: true),
_Option('firefox', 'Path to firefox browser executable.', hide: true),
_Option('chrome', 'Path to chrome browser executable.', hide: true),
_Option('safari', 'Path to safari browser executable.', hide: true),
_Option.bool('use_sdk', '''Use compiler or runtime from the SDK.'''),
// TODO(rnystrom): This does not appear to be used. Remove?
new _Option('build_directory',
_Option('build_directory',
'The name of the build directory, where products are placed.',
hide: true),
new _Option('output_directory',
_Option('output_directory',
'The name of the output directory for storing log files.',
defaultsTo: "logs", hide: true),
new _Option.bool('noBatch', 'Do not run tests in batch mode.', hide: true),
new _Option.bool('dart2js_batch', 'Run dart2js tests in batch mode.',
_Option.bool('noBatch', 'Do not run tests in batch mode.', hide: true),
_Option.bool('dart2js_batch', 'Run dart2js tests in batch mode.',
hide: true),
new _Option.bool('write_debug_log',
_Option.bool('write_debug_log',
'Don\'t write debug messages to stdout but rather to a logfile.',
hide: true),
new _Option.bool(
_Option.bool(
'write_results',
'Write results to a "${TestUtils.resultsFileName}" json file '
'located at the debug_output_directory.',
hide: true),
new _Option.bool(
_Option.bool(
'write_logs',
'Include the stdout and stderr of tests that don\'t match expectations '
'in the "${TestUtils.logsFileName}" file',
hide: true),
new _Option.bool(
_Option.bool(
'reset_browser_configuration',
'''Browser specific reset of configuration.
Warning: Using this option may remove your bookmarks and other
settings.''',
hide: true),
new _Option.bool(
_Option.bool(
'copy_coredumps',
'''If we see a crash that we did not expect, copy the core dumps to
"/tmp".''',
hide: true),
new _Option(
_Option(
'local_ip',
'''IP address the HTTP servers should listen on. This address is also
used for browsers to connect to.''',
defaultsTo: '127.0.0.1',
hide: true),
new _Option.int('test_server_port', 'Port for test http server.',
_Option.int('test_server_port', 'Port for test http server.',
defaultsTo: 0, hide: true),
new _Option.int('test_server_cross_origin_port',
_Option.int('test_server_cross_origin_port',
'Port for test http server cross origin.',
defaultsTo: 0, hide: true),
new _Option.int('test_driver_port', 'Port for http test driver server.',
_Option.int('test_driver_port', 'Port for http test driver server.',
defaultsTo: 0, hide: true),
new _Option.int(
_Option.int(
'test_driver_error_port', 'Port for http test driver server errors.',
defaultsTo: 0, hide: true),
new _Option('test_list', 'File containing a list of tests to be executed',
_Option('test_list', 'File containing a list of tests to be executed',
hide: true),
new _Option('tests', 'A newline separated list of tests to be executed'),
new _Option(
_Option('tests', 'A newline separated list of tests to be executed'),
_Option(
'builder_tag',
'''Machine specific options that is not captured by the regular test
options. Used to be able to make sane updates to the status files.''',
hide: true),
new _Option('vm_options', 'Extra options to send to the VM when running.',
_Option('vm_options', 'Extra options to send to the VM when running.',
hide: true),
new _Option(
'dart2js_options', 'Extra options for dart2js compilation step.',
_Option('dart2js_options', 'Extra options for dart2js compilation step.',
hide: true),
new _Option('shared_options', 'Extra shared options.', hide: true),
new _Option(
_Option('shared_options', 'Extra shared options.', hide: true),
_Option(
'babel',
'''Transforms dart2js output with Babel. The value must be
Babel options JSON.''',
hide: true),
new _Option(
'suite_dir', 'Additional directory to add to the testing matrix.',
_Option('suite_dir', 'Additional directory to add to the testing matrix.',
hide: true),
new _Option('package_root', 'The package root to use for testing.',
_Option('package_root', 'The package root to use for testing.', hide: true),
_Option('packages', 'The package spec file to use for testing.',
hide: true),
new _Option('packages', 'The package spec file to use for testing.',
hide: true),
new _Option(
_Option(
'exclude_suite',
'''Exclude suites from default selector, only works when no selector
has been specified on the command line.''',
hide: true),
new _Option.bool(
_Option.bool(
'skip_compilation',
'''
Skip the compilation step, using the compilation artifacts left in
@ -328,7 +321,7 @@ false positves and negatives, but can be useful for quick and
dirty offline testing when not making changes that affect the
compiler.''',
hide: true),
new _Option.bool('print_passing_stdout',
_Option.bool('print_passing_stdout',
'Print the stdout of passing, as well as failing, tests.',
hide: true)
];
@ -583,8 +576,7 @@ compiler.''',
// observatory_ui, and remove observatory_ui from the original
// selectors. The only mutable value in the map is the selectors, so a
// shallow copy is safe.
var observatoryConfiguration =
new Map<String, dynamic>.from(configuration);
var observatoryConfiguration = Map<String, dynamic>.from(configuration);
var observatorySelectors = {
'observatory_ui': selectors['observatory_ui']
};
@ -688,8 +680,8 @@ compiler.''',
var namedConfiguration =
getNamedConfiguration(data["named_configuration"] as String);
var innerConfiguration = namedConfiguration ??
new Configuration("custom configuration", architecture,
compiler, mode, runtime, system,
Configuration("custom configuration", architecture, compiler,
mode, runtime, system,
timeout: data["timeout"] as int,
enableAsserts: data["enable_asserts"] as bool,
useAnalyzerCfe: data["use_cfe"] as bool,
@ -708,7 +700,7 @@ compiler.''',
babel: data['babel'] as String,
builderTag: data["builder_tag"] as String,
previewDart2: true);
var configuration = new TestConfiguration(
var configuration = TestConfiguration(
configuration: innerConfiguration,
progress: Progress.find(data["progress"] as String),
selectors: selectors,
@ -817,7 +809,7 @@ compiler.''',
_fail("Error: '$suite/$pattern'. Only one test selection"
" pattern is allowed to start with '$suite/'");
}
selectorMap[suite] = new RegExp(pattern);
selectorMap[suite] = RegExp(pattern);
}
return selectorMap;
@ -825,7 +817,7 @@ compiler.''',
/// Print out usage information.
void _printHelp({bool verbose}) {
var buffer = new StringBuffer();
var buffer = StringBuffer();
buffer.writeln('''The Dart SDK's internal test runner.

View file

@ -0,0 +1,134 @@
// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'dart:async';
import 'dart:convert';
import 'dart:io';
/// An OutputLog records the output from a test, but truncates it if
/// it is longer than [_maxHead] characters, and just keeps the head and
/// the last [_tailLength] characters of the output.
class OutputLog implements StreamConsumer<List<int>> {
static const _maxHead = 500 * 1024;
static const _tailLength = 10 * 1024;
List<int> _head = [];
List<int> _tail;
List<int> complete;
bool _dataDropped = false;
StreamSubscription _subscription;
bool _hasNonUtf8 = false;
bool get hasNonUtf8 => _hasNonUtf8;
void add(List<int> data) {
if (complete != null) {
throw StateError("Cannot add to OutputLog after calling toList");
}
if (_tail == null) {
_head.addAll(data);
if (_head.length > _maxHead) {
_tail = _head.sublist(_maxHead);
_head.length = _maxHead;
}
} else {
_tail.addAll(data);
}
if (_tail != null && _tail.length > 2 * _tailLength) {
_tail = _truncatedTail();
_dataDropped = true;
}
}
List<int> _truncatedTail() => _tail.length > _tailLength
? _tail.sublist(_tail.length - _tailLength)
: _tail;
void _checkUtf8(List<int> data) {
try {
utf8.decode(data, allowMalformed: false);
} on FormatException {
_hasNonUtf8 = true;
var malformed = utf8.decode(data, allowMalformed: true);
data
..clear()
..addAll(utf8.encode(malformed))
..addAll("""
*****************************************************************************
test.dart: The output of this test contained non-UTF8 formatted data.
*****************************************************************************
"""
.codeUnits);
}
}
List<int> toList() {
if (complete == null) {
complete = _head;
if (_dataDropped) {
complete.addAll("""
*****************************************************************************
test.dart: Data was removed due to excessive length. If you need the limit to
be increased, please contact dart-engprod or file an issue.
*****************************************************************************
"""
.codeUnits);
complete.addAll(_truncatedTail());
} else if (_tail != null) {
complete.addAll(_tail);
}
_head = null;
_tail = null;
_checkUtf8(complete);
}
return complete;
}
@override
Future addStream(Stream<List<int>> stream) {
_subscription = stream.listen(this.add);
return _subscription.asFuture();
}
@override
Future close() {
toList();
return _subscription?.cancel();
}
Future cancel() {
return _subscription?.cancel();
}
}
/// An [OutputLog] that tees the output to a file as well.
class FileOutputLog extends OutputLog {
File _outputFile;
IOSink _sink;
FileOutputLog(this._outputFile);
@override
void add(List<int> data) {
super.add(data);
_sink ??= _outputFile.openWrite();
_sink.add(data);
}
@override
Future close() {
return Future.wait([
super.close(),
if (_sink != null) _sink.flush().whenComplete(_sink.close)
]);
}
@override
Future cancel() {
return Future.wait([
super.cancel(),
if (_sink != null) _sink.flush().whenComplete(_sink.close)
]);
}
}

View file

@ -6,7 +6,7 @@ import 'dart:math';
// TODO: Remove this class, and use the URI class for all path manipulation.
class Path {
static Path workingDirectory = new Path(Directory.current.path);
static Path workingDirectory = Path(Directory.current.path);
final String _path;
final bool isWindowsShare;
@ -67,7 +67,7 @@ class Path {
// Throws exception if an impossible case is reached.
if (base.isAbsolute != isAbsolute ||
base.isWindowsShare != isWindowsShare) {
throw new ArgumentError("Invalid case of Path.relativeTo(base):\n"
throw ArgumentError("Invalid case of Path.relativeTo(base):\n"
" Path and base must both be relative, or both absolute.\n"
" Arguments: $_path.relativeTo($base)");
}
@ -87,22 +87,22 @@ class Path {
if (basePath[1] != _path[1]) {
// Replace the drive letter in basePath with that from _path.
basePath = '/${_path[1]}:/${basePath.substring(4)}';
base = new Path(basePath);
base = Path(basePath);
}
} else {
throw new ArgumentError("Invalid case of Path.relativeTo(base):\n"
throw ArgumentError("Invalid case of Path.relativeTo(base):\n"
" Base path and target path are on different Windows drives.\n"
" Arguments: $_path.relativeTo($base)");
}
} else if (baseHasDrive != pathHasDrive) {
throw new ArgumentError("Invalid case of Path.relativeTo(base):\n"
throw ArgumentError("Invalid case of Path.relativeTo(base):\n"
" Base path must start with a drive letter if and "
"only if target path does.\n"
" Arguments: $_path.relativeTo($base)");
}
}
if (_path.startsWith(basePath)) {
if (_path == basePath) return new Path('.');
if (_path == basePath) return Path('.');
// There must be a '/' at the end of the match, or immediately after.
int matchEnd = basePath.length;
if (_path[matchEnd - 1] == '/' || _path[matchEnd] == '/') {
@ -110,7 +110,7 @@ class Path {
while (matchEnd < _path.length && _path[matchEnd] == '/') {
matchEnd++;
}
return new Path(_path.substring(matchEnd)).canonicalize();
return Path(_path.substring(matchEnd)).canonicalize();
}
}
@ -127,10 +127,10 @@ class Path {
while (common < length && pathSegments[common] == baseSegments[common]) {
common++;
}
final segments = new List<String>();
final segments = List<String>();
if (common < baseSegments.length && baseSegments[common] == '..') {
throw new ArgumentError("Invalid case of Path.relativeTo(base):\n"
throw ArgumentError("Invalid case of Path.relativeTo(base):\n"
" Base path has more '..'s than path does.\n"
" Arguments: $_path.relativeTo($base)");
}
@ -146,22 +146,21 @@ class Path {
if (hasTrailingSeparator) {
segments.add('');
}
return new Path(segments.join('/'));
return Path(segments.join('/'));
}
Path join(Path further) {
if (further.isAbsolute) {
throw new ArgumentError(
"Path.join called with absolute Path as argument.");
throw ArgumentError("Path.join called with absolute Path as argument.");
}
if (isEmpty) {
return further.canonicalize();
}
if (hasTrailingSeparator) {
var joined = new Path._internal('$_path${further}', isWindowsShare);
var joined = Path._internal('$_path${further}', isWindowsShare);
return joined.canonicalize();
}
var joined = new Path._internal('$_path/${further}', isWindowsShare);
var joined = Path._internal('$_path/${further}', isWindowsShare);
return joined.canonicalize();
}
@ -250,7 +249,7 @@ class Path {
segmentsToJoin.add('');
}
}
return new Path._internal(segmentsToJoin.join('/'), isWindowsShare);
return Path._internal(segmentsToJoin.join('/'), isWindowsShare);
}
String toNativePath() {
@ -281,11 +280,11 @@ class Path {
Path append(String finalSegment) {
if (isEmpty) {
return new Path._internal(finalSegment, isWindowsShare);
return Path._internal(finalSegment, isWindowsShare);
} else if (hasTrailingSeparator) {
return new Path._internal('$_path$finalSegment', isWindowsShare);
return Path._internal('$_path$finalSegment', isWindowsShare);
} else {
return new Path._internal('$_path/$finalSegment', isWindowsShare);
return Path._internal('$_path/$finalSegment', isWindowsShare);
}
}
@ -304,10 +303,10 @@ class Path {
Path get directoryPath {
int pos = _path.lastIndexOf('/');
if (pos < 0) return new Path('');
if (pos < 0) return Path('');
while (pos > 0 && _path[pos - 1] == '/') --pos;
var dirPath = (pos > 0) ? _path.substring(0, pos) : '/';
return new Path._internal(dirPath, isWindowsShare);
return Path._internal(dirPath, isWindowsShare);
}
String get filename {

File diff suppressed because it is too large Load diff

View file

@ -8,7 +8,7 @@ import 'path.dart';
/// Provides information about the surrounding Dart repository.
class Repository {
/// File path pointing to the root directory of the Dart checkout.
static Path get dir => new Path(uri.toFilePath());
static Path get dir => Path(uri.toFilePath());
/// The URI pointing to the root of the Dart checkout.
///

View file

@ -34,7 +34,7 @@ final List<String> safariSettings = <String>[
"Library/Preferences/$safari.plist",
];
const Duration defaultPollDelay = const Duration(milliseconds: 1);
const Duration defaultPollDelay = Duration(milliseconds: 1);
final String cpgi = "$safari.ContentPageGroupIdentifier";
@ -97,12 +97,12 @@ final String knownSafariPreference = '''
}
''';
Future<Null> get pollDelay => new Future.delayed(defaultPollDelay);
Future<Null> get pollDelay => Future.delayed(defaultPollDelay);
String signalArgument(String defaultSignal,
{bool force: false, bool testOnly: false}) {
{bool force = false, bool testOnly = false}) {
if (force && testOnly) {
throw new ArgumentError("[force] and [testOnly] can't both be true.");
throw ArgumentError("[force] and [testOnly] can't both be true.");
}
if (force) return "-KILL";
if (testOnly) return "-0";
@ -110,7 +110,7 @@ String signalArgument(String defaultSignal,
}
Future<int> kill(List<String> pids,
{bool force: false, bool testOnly: false}) async {
{bool force = false, bool testOnly = false}) async {
var arguments = [signalArgument("-TERM", force: force, testOnly: testOnly)]
..addAll(pids);
var result = await Process.run(killLocation, arguments);
@ -118,7 +118,7 @@ Future<int> kill(List<String> pids,
}
Future<int> pkill(String pattern,
{bool force: false, bool testOnly: false}) async {
{bool force = false, bool testOnly = false}) async {
var arguments = [
signalArgument("-HUP", force: force, testOnly: testOnly),
pattern
@ -130,7 +130,7 @@ Future<int> pkill(String pattern,
Uri validatedBundleName(Uri bundle) {
if (bundle == null) return Uri.base.resolve(defaultSafariBundleLocation);
if (!bundle.path.endsWith("/")) {
throw new ArgumentError("Bundle ('$bundle') must end with a slash ('/').");
throw ArgumentError("Bundle ('$bundle') must end with a slash ('/').");
}
return bundle;
}
@ -144,7 +144,7 @@ Future<Null> killSafari({Uri bundle}) async {
var stdout = result.stdout as String;
var pids =
stdout.split("\n").where((String line) => !line.isEmpty).toList();
var timer = new Timer(const Duration(seconds: 10), () {
var timer = Timer(const Duration(seconds: 10), () {
print("Kill -9 Safari $pids");
kill(pids, force: true);
});
@ -156,7 +156,7 @@ Future<Null> killSafari({Uri bundle}) async {
}
timer.cancel();
}
var timer = new Timer(const Duration(seconds: 10), () {
var timer = Timer(const Duration(seconds: 10), () {
print("Kill -9 $safari");
pkill(safari, force: true);
});
@ -170,12 +170,12 @@ Future<Null> killSafari({Uri bundle}) async {
}
Future<Null> deleteIfExists(Uri uri) async {
var directory = new Directory.fromUri(uri);
var directory = Directory.fromUri(uri);
if (await directory.exists()) {
print("Deleting directory '$uri'.");
await directory.delete(recursive: true);
} else {
var file = new File.fromUri(uri);
var file = File.fromUri(uri);
if (await file.exists()) {
print("Deleting file '$uri'.");
await file.delete();

View file

@ -28,31 +28,31 @@ abstract class RuntimeConfiguration {
case Runtime.ie9:
case Runtime.safari:
// TODO(ahe): Replace this with one or more browser runtimes.
return new DummyRuntimeConfiguration();
return DummyRuntimeConfiguration();
case Runtime.jsshell:
return new JsshellRuntimeConfiguration();
return JsshellRuntimeConfiguration();
case Runtime.d8:
return new D8RuntimeConfiguration();
return D8RuntimeConfiguration();
case Runtime.none:
return new NoneRuntimeConfiguration();
return NoneRuntimeConfiguration();
case Runtime.vm:
if (configuration.system == System.android) {
return new DartkAdbRuntimeConfiguration();
return DartkAdbRuntimeConfiguration();
}
return new StandaloneDartRuntimeConfiguration();
return StandaloneDartRuntimeConfiguration();
case Runtime.dartPrecompiled:
if (configuration.system == System.android) {
return new DartPrecompiledAdbRuntimeConfiguration(
return DartPrecompiledAdbRuntimeConfiguration(
useBlobs: configuration.useBlobs,
useElf: configuration.useElf,
);
} else {
return new DartPrecompiledRuntimeConfiguration(
return DartPrecompiledRuntimeConfiguration(
useBlobs: configuration.useBlobs,
useElf: configuration.useElf,
);
@ -60,7 +60,7 @@ abstract class RuntimeConfiguration {
break;
case Runtime.selfCheck:
return new SelfCheckRuntimeConfiguration();
return SelfCheckRuntimeConfiguration();
}
throw "unreachable";
}
@ -73,8 +73,8 @@ abstract class RuntimeConfiguration {
int timeoutMultiplier(
{Mode mode,
bool isChecked: false,
bool isReload: false,
bool isChecked = false,
bool isReload = false,
Architecture arch}) {
return 1;
}
@ -89,9 +89,7 @@ abstract class RuntimeConfiguration {
throw "Unimplemented runtime '$runtimeType'";
}
/**
* The output directory for this suite's configuration.
*/
/// The output directory for this suite's configuration.
String get buildDir => _configuration.buildDirectory;
List<String> dart2jsPreambles(Uri preambleDir) => [];
@ -237,8 +235,8 @@ class DartVmRuntimeConfiguration extends RuntimeConfiguration {
int timeoutMultiplier(
{Mode mode,
bool isChecked: false,
bool isReload: false,
bool isChecked = false,
bool isReload = false,
Architecture arch}) {
var multiplier = 1;
@ -389,7 +387,7 @@ class SelfCheckRuntimeConfiguration extends DartVmRuntimeConfiguration {
void searchForSelfCheckers() {
Uri pkg = Repository.uri.resolve('pkg');
for (var entry in new Directory.fromUri(pkg).listSync(recursive: true)) {
for (var entry in Directory.fromUri(pkg).listSync(recursive: true)) {
if (entry is File && entry.path.endsWith('_self_check.dart')) {
selfCheckers.add(entry.path);
}

View file

@ -84,13 +84,13 @@ void ensureBuild(Iterable<String> modes, Iterable<String> archs) {
if (result.exitCode != 0) {
print('ERROR');
print(result.stderr);
throw new Exception('Error while building.');
throw Exception('Error while building.');
}
print('Done building.');
}
void sanityCheck(String output) {
var splitter = new LineSplitter();
var splitter = LineSplitter();
var lines = splitter.convert(output);
// Looks like this:
// Total: 15556 tests
@ -104,16 +104,15 @@ void sanityCheck(String output) {
}
if (count != total) {
print('Count: $count, total: $total');
throw new Exception(
'Count and total do not align. Please validate manually.');
throw Exception('Count and total do not align. Please validate manually.');
}
}
void main(List<String> args) {
var combinations = _combinations[Platform.operatingSystem];
var arches = new Set<String>();
var modes = new Set<String>();
var arches = <String>{};
var modes = <String>{};
if (args.contains('--simple')) {
arches = ['ia32'].toSet();
@ -155,7 +154,7 @@ void main(List<String> args) {
if (result.exitCode != 0) {
print(result.stdout);
print(result.stderr);
throw new Exception("Error running: ${args.join(" ")}");
throw Exception("Error running: ${args.join(" ")}");
}
// Find "JSON:"

View file

@ -8,7 +8,7 @@ import "package:status_file/expectation.dart";
import "test_case.dart";
final summaryReport = new SummaryReport();
final summaryReport = SummaryReport();
class SummaryReport {
int _total = 0;

File diff suppressed because it is too large Load diff

View file

@ -12,43 +12,38 @@ import 'co19_test_config.dart';
import 'configuration.dart';
import 'path.dart';
import 'test_progress.dart';
import 'test_case.dart';
import 'process_queue.dart';
import 'test_suite.dart';
import 'utils.dart';
/**
* The directories that contain test suites which follow the conventions
* required by [StandardTestSuite]'s forDirectory constructor.
* New test suites should follow this convention because it makes it much
* simpler to add them to test.dart. Existing test suites should be
* moved to here, if possible.
*/
/// The directories that contain test suites which follow the conventions
/// required by [StandardTestSuite]'s forDirectory constructor.
/// New test suites should follow this convention because it makes it much
/// simpler to add them to test.dart. Existing test suites should be
/// moved to here, if possible.
final TEST_SUITE_DIRECTORIES = [
new Path('third_party/pkg/dartdoc'),
new Path('pkg'),
new Path('third_party/pkg_tested'),
new Path('runtime/tests/vm'),
new Path('runtime/observatory/tests/service'),
new Path('runtime/observatory/tests/observatory_ui'),
new Path('samples'),
new Path('samples-dev'),
new Path('tests/compiler/dart2js'),
new Path('tests/compiler/dart2js_extra'),
new Path('tests/compiler/dart2js_native'),
new Path('tests/compiler/dartdevc_native'),
new Path('tests/corelib_2'),
new Path('tests/kernel'),
new Path('tests/language_2'),
new Path('tests/lib_2'),
new Path('tests/standalone'),
new Path('tests/standalone_2'),
new Path('tests/ffi'),
new Path('utils/tests/peg'),
Path('third_party/pkg/dartdoc'),
Path('pkg'),
Path('third_party/pkg_tested'),
Path('runtime/tests/vm'),
Path('runtime/observatory/tests/service'),
Path('runtime/observatory/tests/observatory_ui'),
Path('samples'),
Path('samples-dev'),
Path('tests/compiler/dart2js'),
Path('tests/compiler/dart2js_extra'),
Path('tests/compiler/dart2js_native'),
Path('tests/compiler/dartdevc_native'),
Path('tests/corelib_2'),
Path('tests/kernel'),
Path('tests/language_2'),
Path('tests/lib_2'),
Path('tests/standalone'),
Path('tests/standalone_2'),
Path('tests/ffi'),
Path('utils/tests/peg'),
];
// This file is created by gclient runhooks.
final VS_TOOLCHAIN_FILE = new Path("build/win_toolchain.json");
Future testConfigurations(List<TestConfiguration> configurations) async {
var startTime = DateTime.now();
var startStopwatch = Stopwatch()..start();
@ -120,20 +115,20 @@ Future testConfigurations(List<TestConfiguration> configurations) async {
// If we specifically pass in a suite only run that.
if (configuration.suiteDirectory != null) {
var suitePath = new Path(configuration.suiteDirectory);
testSuites.add(new PKGTestSuite(configuration, suitePath));
var suitePath = Path(configuration.suiteDirectory);
testSuites.add(PKGTestSuite(configuration, suitePath));
} else {
for (var testSuiteDir in TEST_SUITE_DIRECTORIES) {
var name = testSuiteDir.filename;
if (configuration.selectors.containsKey(name)) {
testSuites.add(
new StandardTestSuite.forDirectory(configuration, testSuiteDir));
testSuites
.add(StandardTestSuite.forDirectory(configuration, testSuiteDir));
}
}
for (var key in configuration.selectors.keys) {
if (key == 'co19_2') {
testSuites.add(new Co19TestSuite(configuration, key));
testSuites.add(Co19TestSuite(configuration, key));
} else if ((configuration.compiler == Compiler.none ||
configuration.compiler == Compiler.dartk ||
configuration.compiler == Compiler.dartkb) &&
@ -141,10 +136,10 @@ Future testConfigurations(List<TestConfiguration> configurations) async {
key == 'vm') {
// vm tests contain both cc tests (added here) and dart tests (added
// in [TEST_SUITE_DIRECTORIES]).
testSuites.add(new VMTestSuite(configuration));
testSuites.add(VMTestSuite(configuration));
} else if (configuration.compiler == Compiler.dart2analyzer) {
if (key == 'analyze_library') {
testSuites.add(new AnalyzeLibraryTestSuite(configuration));
testSuites.add(AnalyzeLibraryTestSuite(configuration));
}
}
}
@ -188,49 +183,49 @@ Future testConfigurations(List<TestConfiguration> configurations) async {
progressIndicator = Progress.compact;
formatter = Formatter.color;
printFailures = false;
eventListener.add(new StatusFileUpdatePrinter());
eventListener.add(StatusFileUpdatePrinter());
}
if (firstConf.silentFailures) {
printFailures = false;
}
eventListener.add(new SummaryPrinter());
eventListener.add(SummaryPrinter());
if (printFailures) {
// The buildbot has it's own failure summary since it needs to wrap it
// into '@@@'-annotated sections.
var printFailureSummary = progressIndicator != Progress.buildbot;
eventListener.add(new TestFailurePrinter(printFailureSummary, formatter));
eventListener.add(TestFailurePrinter(printFailureSummary, formatter));
}
if (firstConf.printPassingStdout) {
eventListener.add(new PassingStdoutPrinter(formatter));
eventListener.add(PassingStdoutPrinter(formatter));
}
eventListener.add(ProgressIndicator.fromProgress(
progressIndicator, startTime, formatter));
if (printTiming) {
eventListener.add(new TimingPrinter(startTime));
eventListener.add(TimingPrinter(startTime));
}
eventListener.add(new SkippedCompilationsPrinter());
eventListener.add(SkippedCompilationsPrinter());
if (progressIndicator == Progress.status) {
eventListener.add(new TimedProgressPrinter());
eventListener.add(TimedProgressPrinter());
}
}
if (firstConf.writeResults) {
eventListener.add(new ResultWriter(firstConf, startTime, startStopwatch));
eventListener.add(ResultWriter(firstConf, startTime, startStopwatch));
}
if (firstConf.copyCoreDumps) {
eventListener.add(new UnexpectedCrashLogger());
eventListener.add(UnexpectedCrashLogger());
}
// The only progress indicator when listing tests should be the
// the summary printer.
if (listTests) {
eventListener.add(new SummaryPrinter(jsonOnly: reportInJson));
eventListener.add(SummaryPrinter(jsonOnly: reportInJson));
} else {
if (!firstConf.cleanExit) {
eventListener.add(new ExitCodeSetter());
eventListener.add(ExitCodeSetter());
}
eventListener.add(new IgnoredTestMonitor());
eventListener.add(IgnoredTestMonitor());
}
// If any of the configurations need to access android devices we'll first
@ -250,6 +245,6 @@ Future testConfigurations(List<TestConfiguration> configurations) async {
// [firstConf] is needed here, since the ProcessQueue needs to know the
// settings of 'noBatch' and 'local_ip'
new ProcessQueue(firstConf, maxProcesses, maxBrowserProcesses, startTime,
ProcessQueue(firstConf, maxProcesses, maxBrowserProcesses, startTime,
testSuites, eventListener, allTestsFinished, verbose, adbDevicePool);
}

View file

@ -19,11 +19,11 @@ import 'utils.dart';
/// Controls how message strings are processed before being displayed.
class Formatter {
/// Messages are left as-is.
static const normal = const Formatter._();
static const normal = Formatter._();
/// Messages are wrapped in ANSI escape codes to color them for display on a
/// terminal.
static const color = const _ColorFormatter();
static const color = _ColorFormatter();
const Formatter._();
@ -143,16 +143,16 @@ class UnexpectedCrashLogger extends EventListener {
// folder next to core dumps and name them
// `binary.${mode}_${arch}_${binary_name}`.
final binName = lastCommand.executable;
final binFile = new File(binName);
final binBaseName = new Path(binName).filename;
final binFile = File(binName);
final binBaseName = Path(binName).filename;
if (!archivedBinaries.containsKey(binName) && binFile.existsSync()) {
final archived = "binary.${mode}_${arch}_${binBaseName}";
TestUtils.copyFile(new Path(binName), new Path(archived));
TestUtils.copyFile(Path(binName), Path(archived));
// On Windows also copy PDB file for the binary.
if (Platform.isWindows) {
final pdbPath = new Path("$binName.pdb");
if (new File(pdbPath.toNativePath()).existsSync()) {
TestUtils.copyFile(pdbPath, new Path("$archived.pdb"));
final pdbPath = Path("$binName.pdb");
if (File(pdbPath.toNativePath()).existsSync()) {
TestUtils.copyFile(pdbPath, Path("$archived.pdb"));
}
}
archivedBinaries[binName] = archived;
@ -160,11 +160,11 @@ class UnexpectedCrashLogger extends EventListener {
final kernelServiceBaseName = 'kernel-service.dart.snapshot';
final kernelService =
new File('${binFile.parent.path}/$kernelServiceBaseName');
File('${binFile.parent.path}/$kernelServiceBaseName');
if (!archivedBinaries.containsKey(kernelService) &&
kernelService.existsSync()) {
final archived = "binary.${mode}_${arch}_${kernelServiceBaseName}";
TestUtils.copyFile(new Path(kernelService.path), new Path(archived));
TestUtils.copyFile(Path(kernelService.path), Path(archived));
archivedBinaries[kernelServiceBaseName] = archived;
}
@ -180,7 +180,7 @@ class UnexpectedCrashLogger extends EventListener {
RandomAccessFile unexpectedCrashesFile;
try {
unexpectedCrashesFile =
new File('unexpected-crashes').openSync(mode: FileMode.append);
File('unexpected-crashes').openSync(mode: FileMode.append);
unexpectedCrashesFile.writeStringSync(
"${test.displayName},${pid},${binaries.join(',')}\n");
} catch (e) {
@ -216,8 +216,8 @@ class SummaryPrinter extends EventListener {
}
class TimingPrinter extends EventListener {
final _command2testCases = new Map<Command, List<TestCase>>();
final _commandOutputs = new Set<CommandOutput>();
final _commandToTestCases = <Command, List<TestCase>>{};
final _commandOutputs = <CommandOutput>{};
DateTime _startTime;
TimingPrinter(this._startTime);
@ -226,22 +226,22 @@ class TimingPrinter extends EventListener {
for (var commandOutput in testCase.commandOutputs.values) {
var command = commandOutput.command;
_commandOutputs.add(commandOutput);
_command2testCases.putIfAbsent(command, () => <TestCase>[]);
_command2testCases[command].add(testCase);
_commandToTestCases.putIfAbsent(command, () => <TestCase>[]);
_commandToTestCases[command].add(testCase);
}
}
void allDone() {
Duration d = (new DateTime.now()).difference(_startTime);
var d = DateTime.now().difference(_startTime);
print('\n--- Total time: ${_timeString(d)} ---');
var outputs = _commandOutputs.toList();
outputs.sort((a, b) {
return b.time.inMilliseconds - a.time.inMilliseconds;
});
for (int i = 0; i < 20 && i < outputs.length; i++) {
for (var i = 0; i < 20 && i < outputs.length; i++) {
var commandOutput = outputs[i];
var command = commandOutput.command;
var testCases = _command2testCases[command];
var testCases = _commandToTestCases[command];
var testCasesDescription = testCases.map((testCase) {
return "${testCase.configurationString}/${testCase.displayName}";
@ -255,7 +255,7 @@ class TimingPrinter extends EventListener {
}
class StatusFileUpdatePrinter extends EventListener {
var statusToConfigs = new Map<String, List<String>>();
var statusToConfigs = <String, List<String>>{};
var _failureSummary = <String>[];
void done(TestCase test) {
@ -399,7 +399,7 @@ class PassingStdoutPrinter extends EventListener {
void done(TestCase test) {
if (!test.unexpectedOutput) {
var lines = <String>[];
var output = new OutputWriter(_formatter, lines);
var output = OutputWriter(_formatter, lines);
for (final command in test.commands) {
var commandOutput = test.commandOutputs[command];
if (commandOutput == null) continue;
@ -422,15 +422,15 @@ class ProgressIndicator extends EventListener {
Progress progress, DateTime startTime, Formatter formatter) {
switch (progress) {
case Progress.compact:
return new CompactProgressIndicator(startTime, formatter);
return CompactProgressIndicator(startTime, formatter);
case Progress.line:
return new LineProgressIndicator();
return LineProgressIndicator();
case Progress.verbose:
return new VerboseProgressIndicator(startTime);
return VerboseProgressIndicator(startTime);
case Progress.status:
return new ProgressIndicator(startTime);
return ProgressIndicator(startTime);
case Progress.buildbot:
return new BuildbotProgressIndicator(startTime);
return BuildbotProgressIndicator(startTime);
}
throw "unreachable";
@ -491,7 +491,7 @@ class CompactProgressIndicator extends CompactIndicator {
var progressPadded = (_allTestsKnown ? percent : '--').padLeft(3);
var passedPadded = _passedTests.toString().padLeft(5);
var failedPadded = _failedTests.toString().padLeft(5);
var elapsed = (new DateTime.now()).difference(_startTime);
var elapsed = (DateTime.now()).difference(_startTime);
var progressLine = '\r[${_timeString(elapsed)} | $progressPadded% | '
'+${_formatter.passed(passedPadded)} | '
'-${_formatter.failed(failedPadded)}]';
@ -604,7 +604,7 @@ class OutputWriter {
List<String> _buildFailureOutput(TestCase test,
[Formatter formatter = Formatter.normal]) {
var lines = <String>[];
var output = new OutputWriter(formatter, lines);
var output = OutputWriter(formatter, lines);
_writeFailureStatus(test, formatter, output);
_writeFailureOutput(test, formatter, output);
_writeFailureReproductionCommands(test, formatter, output);
@ -614,7 +614,7 @@ List<String> _buildFailureOutput(TestCase test,
List<String> _buildFailureLog(TestCase test) {
final formatter = Formatter.normal;
final lines = <String>[];
final output = new OutputWriter(formatter, lines);
final output = OutputWriter(formatter, lines);
_writeFailureOutput(test, formatter, output);
_writeFailureReproductionCommands(test, formatter, output);
return lines;
@ -717,7 +717,7 @@ class ResultWriter extends EventListener {
void done(TestCase test) {
if (_configuration != test.configuration) {
throw new Exception("Two configurations in the same run. "
throw Exception("Two configurations in the same run. "
"Cannot output results for multiple configurations.");
}
final name = test.displayName;

View file

@ -2,16 +2,14 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
/**
* Classes and methods for enumerating and preparing tests.
*
* This library includes:
*
* - Creating tests by listing all the Dart files in certain directories,
* and creating [TestCase]s for those files that meet the relevant criteria.
* - Preparing tests, including copying files and frameworks to temporary
* directories, and computing the command line and arguments to be run.
*/
/// Classes and methods for enumerating and preparing tests.
///
/// This library includes:
///
/// - Creating tests by listing all the Dart files in certain directories,
/// and creating [TestCase]s for those files that meet the relevant criteria.
/// - Preparing tests, including copying files and frameworks to temporary
/// directories, and computing the command line and arguments to be run.
import 'dart:async';
import 'dart:io';
import 'dart:math';
@ -20,7 +18,6 @@ import "package:status_file/expectation.dart";
import 'browser.dart';
import 'command.dart';
import 'compiler_configuration.dart';
import 'configuration.dart';
import 'expectation_set.dart';
import 'multitest.dart';
@ -32,59 +29,54 @@ import 'test_configurations.dart';
import 'testing_servers.dart';
import 'utils.dart';
RegExp multiHtmlTestGroupRegExp = new RegExp(r"\s*[^/]\s*group\('[^,']*");
RegExp multiHtmlTestRegExp = new RegExp(r"useHtmlIndividualConfiguration\(\)");
// Require at least one non-space character before '//[/#]'
RegExp multiTestRegExp = new RegExp(r"\S *"
r"//[#/] \w+:(.*)");
RegExp dartExtension = new RegExp(r'\.dart$');
RegExp _multiHtmlTestGroupRegExp = RegExp(r"\s*[^/]\s*group\('[^,']*");
RegExp _multiHtmlTestRegExp = RegExp(r"useHtmlIndividualConfiguration\(\)");
/**
* A simple function that tests [arg] and returns `true` or `false`.
*/
typedef bool Predicate<T>(T arg);
/// Require at least one non-space character before '//[/#]'.
RegExp _multiTestRegExp = RegExp(r"\S *//[#/] \w+:(.*)");
typedef void CreateTest(Path filePath, Path originTestPath,
typedef TestCaseEvent = void Function(TestCase testCase);
/// A simple function that tests [arg] and returns `true` or `false`.
typedef Predicate<T> = bool Function(T arg);
typedef CreateTest = void Function(Path filePath, Path originTestPath,
{bool hasSyntaxError,
bool hasCompileError,
bool hasRuntimeError,
bool hasStaticWarning,
String multitestKey});
typedef void VoidFunction();
typedef VoidFunction = void Function();
/**
* Calls [function] asynchronously. Returns a future that completes with the
* result of the function. If the function is `null`, returns a future that
* completes immediately with `null`.
*/
/// Calls [function] asynchronously. Returns a future that completes with the
/// result of the function. If the function is `null`, returns a future that
/// completes immediately with `null`.
Future asynchronously<T>(T function()) {
if (function == null) return new Future<T>.value(null);
if (function == null) return Future<T>.value(null);
var completer = new Completer<T>();
var completer = Completer<T>();
Timer.run(() => completer.complete(function()));
return completer.future;
}
/** A completer that waits until all added [Future]s complete. */
/// A completer that waits until all added [Future]s complete.
// TODO(rnystrom): Copied from web_components. Remove from here when it gets
// added to dart:core. (See #6626.)
class FutureGroup {
static const _FINISHED = -1;
static const _finished = -1;
int _pending = 0;
Completer<List> _completer = new Completer<List>();
final List<Future> futures = <Future>[];
Completer<List> _completer = Completer();
final List<Future> futures = [];
bool wasCompleted = false;
/**
* Wait for [task] to complete (assuming this barrier has not already been
* marked as completed, otherwise you'll get an exception indicating that a
* future has already been completed).
*/
/// Wait for [task] to complete (assuming this barrier has not already been
/// marked as completed, otherwise you'll get an exception indicating that a
/// future has already been completed).
void add(Future task) {
if (_pending == _FINISHED) {
throw new Exception("FutureFutureAlreadyCompleteException");
if (_pending == _finished) {
throw Exception("FutureFutureAlreadyCompleteException");
}
_pending++;
var handledTaskFuture = task.catchError((e, StackTrace s) {
@ -95,7 +87,7 @@ class FutureGroup {
}).then((_) {
_pending--;
if (_pending == 0) {
_pending = _FINISHED;
_pending = _finished;
if (!wasCompleted) {
_completer.complete(futures);
wasCompleted = true;
@ -108,18 +100,17 @@ class FutureGroup {
Future<List> get future => _completer.future;
}
/**
* A TestSuite represents a collection of tests. It creates a [TestCase]
* object for each test to be run, and passes the test cases to a callback.
*
* Most TestSuites represent a directory or directory tree containing tests,
* and a status file containing the expected results when these tests are run.
*/
/// A TestSuite represents a collection of tests. It creates a [TestCase]
/// object for each test to be run, and passes the test cases to a callback.
///
/// Most TestSuites represent a directory or directory tree containing tests,
/// and a status file containing the expected results when these tests are run.
abstract class TestSuite {
final TestConfiguration configuration;
final String suiteName;
final List<String> statusFilePaths;
// This function is set by subclasses before enqueueing starts.
/// This function is set by subclasses before enqueueing starts.
Function doTest;
Map<String, String> _environmentOverrides;
@ -131,24 +122,18 @@ abstract class TestSuite {
_environmentOverrides['DART_SUPPRESS_WER'] = '1';
if (configuration.copyCoreDumps) {
_environmentOverrides['DART_CRASHPAD_HANDLER'] =
new Path(buildDir + '/crashpad_handler.exe')
.absolute
.toNativePath();
Path(buildDir + '/crashpad_handler.exe').absolute.toNativePath();
}
}
}
Map<String, String> get environmentOverrides => _environmentOverrides;
/**
* The output directory for this suite's configuration.
*/
/// The output directory for this suite's configuration.
String get buildDir => configuration.buildDirectory;
/**
* The path to the compiler for this suite's configuration. Returns `null` if
* no compiler should be used.
*/
/// The path to the compiler for this suite's configuration. Returns `null` if
/// no compiler should be used.
String get compilerPath {
var compilerConfiguration = configuration.compilerConfiguration;
if (!compilerConfiguration.hasCompiler) return null;
@ -159,25 +144,23 @@ abstract class TestSuite {
return name;
}
/**
* Call the callback function onTest with a [TestCase] argument for each
* test in the suite. When all tests have been processed, call [onDone].
*
* The [testCache] argument provides a persistent store that can be used to
* cache information about the test suite, so that directories do not need
* to be listed each time.
*/
/// Call the callback function onTest with a [TestCase] argument for each
/// test in the suite. When all tests have been processed, call [onDone].
///
/// The [testCache] argument provides a persistent store that can be used to
/// cache information about the test suite, so that directories do not need
/// to be listed each time.
Future forEachTest(
TestCaseEvent onTest, Map<String, List<TestInformation>> testCache,
[VoidFunction onDone]);
// This function will be called for every TestCase of this test suite.
// It will
// - handle sharding
// - update SummaryReport
// - handle SKIP/SKIP_BY_DESIGN markers
// - test if the selector matches
// and will enqueue the test (if necessary).
/// This function will be called for every TestCase of this test suite.
/// It will:
/// - handle sharding
/// - update SummaryReport
/// - handle SKIP/SKIP_BY_DESIGN markers
/// - test if the selector matches
/// and will enqueue the test (if necessary).
void enqueueNewTestCase(
String testName, List<Command> commands, Set<Expectation> expectations,
[TestInformation info]) {
@ -196,8 +179,7 @@ abstract class TestSuite {
}
var negative = info != null ? isNegative(info) : false;
var testCase = new TestCase(
displayName, commands, configuration, expectations,
var testCase = TestCase(displayName, commands, configuration, expectations,
info: info);
if (negative &&
configuration.runtimeConfiguration.shouldSkipNegativeTests) {
@ -264,20 +246,20 @@ abstract class TestSuite {
relative = relative.directoryPath.append(relative.filenameWithoutExtension);
String testUniqueName = TestUtils.getShortName(relative.toString());
Path generatedTestPath = new Path(buildDir)
Path generatedTestPath = Path(buildDir)
.append('generated_$name')
.append(dirname)
.append(testUniqueName);
TestUtils.mkdirRecursive(new Path('.'), generatedTestPath);
return new File(generatedTestPath.toNativePath())
TestUtils.mkdirRecursive(Path('.'), generatedTestPath);
return File(generatedTestPath.toNativePath())
.absolute
.path
.replaceAll('\\', '/');
}
String buildTestCaseDisplayName(Path suiteDir, Path originTestPath,
{String multitestName: ""}) {
{String multitestName = ""}) {
Path testNamePath = originTestPath.relativeTo(suiteDir);
var directory = testNamePath.directoryPath;
var filenameWithoutExt = testNamePath.filenameWithoutExtension;
@ -294,11 +276,8 @@ abstract class TestSuite {
return testName;
}
/**
* Create a directories for generated assets (tests, html files,
* pubspec checkouts ...).
*/
/// Create a directories for generated assets (tests, html files,
/// pubspec checkouts ...).
String createOutputDirectory(Path testPath) {
var checked = configuration.isChecked ? '-checked' : '';
var legacy = configuration.noPreviewDart2 ? '-legacy' : '';
@ -355,7 +334,7 @@ class VMTestSuite extends TestSuite {
// For listing the tests we use the '$runnerName.host' binary if it exists
// and use '$runnerName' if it doesn't.
var hostBinary = '$targetRunnerPath.host$binarySuffix';
if (new File(hostBinary).existsSync()) {
if (File(hostBinary).existsSync()) {
hostRunnerPath = hostBinary;
} else {
hostRunnerPath = targetRunnerPath;
@ -368,10 +347,10 @@ class VMTestSuite extends TestSuite {
var statusFiles =
statusFilePaths.map((statusFile) => "$dartDir/$statusFile").toList();
var expectations = new ExpectationSet.read(statusFiles, configuration);
var expectations = ExpectationSet.read(statusFiles, configuration);
try {
for (VmUnitTest test in await _listTests(hostRunnerPath)) {
for (VMUnitTest test in await _listTests(hostRunnerPath)) {
_addTest(expectations, test);
}
@ -384,7 +363,7 @@ class VMTestSuite extends TestSuite {
}
}
void _addTest(ExpectationSet testExpectations, VmUnitTest test) {
void _addTest(ExpectationSet testExpectations, VMUnitTest test) {
final fullName = 'cc/${test.name}';
var expectations = testExpectations.expectations(fullName);
@ -416,7 +395,7 @@ class VMTestSuite extends TestSuite {
final filename = configuration.architecture == Architecture.x64
? '$buildDir/gen/kernel-service.dart.snapshot'
: '$buildDir/gen/kernel_service.dill';
final dfePath = new Path(filename).absolute.toNativePath();
final dfePath = Path(filename).absolute.toNativePath();
// '--dfe' has to be the first argument for run_vm_test to pick it up.
args.insert(0, '--dfe=$dfePath');
}
@ -431,7 +410,7 @@ class VMTestSuite extends TestSuite {
enqueueNewTestCase(fullName, [command], expectations, testInfo);
}
Future<Iterable<VmUnitTest>> _listTests(String runnerPath) async {
Future<Iterable<VMUnitTest>> _listTests(String runnerPath) async {
var result = await Process.run(runnerPath, ["--list"]);
if (result.exitCode != 0) {
throw "Failed to list tests: '$runnerPath --list'. "
@ -444,16 +423,16 @@ class VMTestSuite extends TestSuite {
.where((name) => name.isNotEmpty)
.map((String line) {
final parts = line.split(' ');
return VmUnitTest(parts[0].trim(), parts.skip(1).single);
return VMUnitTest(parts[0].trim(), parts.skip(1).single);
});
}
}
class VmUnitTest {
class VMUnitTest {
final String name;
final String expectation;
VmUnitTest(this.name, this.expectation);
VMUnitTest(this.name, this.expectation);
}
class TestInformation {
@ -475,16 +454,14 @@ class TestInformation {
this.hasCompileError,
this.hasRuntimeError,
this.hasStaticWarning,
{this.multitestKey: '',
this.hasCrash: false}) {
{this.multitestKey = '',
this.hasCrash = false}) {
assert(filePath.isAbsolute);
}
}
/**
* A standard [TestSuite] implementation that searches for tests in a
* directory, and creates [TestCase]s that compile and/or run them.
*/
/// A standard [TestSuite] implementation that searches for tests in a
/// directory, and creates [TestCase]s that compile and/or run them.
class StandardTestSuite extends TestSuite {
final Path suiteDir;
ExpectationSet testExpectations;
@ -498,26 +475,26 @@ class StandardTestSuite extends TestSuite {
StandardTestSuite(TestConfiguration configuration, String suiteName,
Path suiteDirectory, List<String> statusFilePaths,
{bool recursive: false})
{bool recursive = false})
: dartDir = Repository.dir,
listRecursively = recursive,
suiteDir = Repository.dir.join(suiteDirectory),
extraVmOptions = configuration.vmOptions,
super(configuration, suiteName, statusFilePaths) {
// Initialize _dart2JsBootstrapDependencies
// Initialize _dart2JsBootstrapDependencies.
if (!configuration.useSdk) {
_dart2JsBootstrapDependencies = [];
} else {
_dart2JsBootstrapDependencies = [
Uri.base
.resolveUri(new Uri.directory(buildDir))
.resolveUri(Uri.directory(buildDir))
.resolve('dart-sdk/bin/snapshots/dart2js.dart.snapshot')
];
}
// Initialize _testListPossibleFilenames
// Initialize _testListPossibleFilenames.
if (configuration.testList != null) {
_testListPossibleFilenames = Set<String>();
_testListPossibleFilenames = <String>{};
for (String s in configuration.testList) {
if (s.startsWith("$suiteName/")) {
s = s.substring(s.indexOf('/') + 1);
@ -537,46 +514,44 @@ class StandardTestSuite extends TestSuite {
}
}
// Initialize _selectorFilenameRegExp
String pattern = configuration.selectors[suiteName].pattern;
// Initialize _selectorFilenameRegExp.
var pattern = configuration.selectors[suiteName].pattern;
if (pattern.contains("/")) {
String lastPart = pattern.substring(pattern.lastIndexOf("/") + 1);
var lastPart = pattern.substring(pattern.lastIndexOf("/") + 1);
// If the selector is a multitest name ending in a number or 'none'
// we also accept test file names that don't contain that last part.
if (int.tryParse(lastPart) != null || lastPart == "none") {
pattern = pattern.substring(0, pattern.lastIndexOf("/"));
}
}
_selectorFilenameRegExp = new RegExp(pattern);
_selectorFilenameRegExp = RegExp(pattern);
}
/**
* Creates a test suite whose file organization matches an expected structure.
* To use this, your suite should look like:
*
* dart/
* path/
* to/
* mytestsuite/
* mytestsuite.status
* example1_test.dart
* example2_test.dart
* example3_test.dart
*
* The important parts:
*
* * The leaf directory name is the name of your test suite.
* * The status file uses the same name.
* * Test files are directly in that directory and end in "_test.dart".
*
* If you follow that convention, then you can construct one of these like:
*
* new StandardTestSuite.forDirectory(configuration, 'path/to/mytestsuite');
*
* instead of having to create a custom [StandardTestSuite] subclass. In
* particular, if you add 'path/to/mytestsuite' to [TEST_SUITE_DIRECTORIES]
* in test.dart, this will all be set up for you.
*/
/// Creates a test suite whose file organization matches an expected structure.
/// To use this, your suite should look like:
///
/// dart/
/// path/
/// to/
/// mytestsuite/
/// mytestsuite.status
/// example1_test.dart
/// example2_test.dart
/// example3_test.dart
///
/// The important parts:
///
/// * The leaf directory name is the name of your test suite.
/// * The status file uses the same name.
/// * Test files are directly in that directory and end in "_test.dart".
///
/// If you follow that convention, then you can construct one of these like:
///
/// new StandardTestSuite.forDirectory(configuration, 'path/to/mytestsuite');
///
/// instead of having to create a custom [StandardTestSuite] subclass. In
/// particular, if you add 'path/to/mytestsuite' to [TEST_SUITE_DIRECTORIES]
/// in test.dart, this will all be set up for you.
factory StandardTestSuite.forDirectory(
TestConfiguration configuration, Path directory) {
var name = directory.filename;
@ -594,7 +569,7 @@ class StandardTestSuite extends TestSuite {
'$directory/${name}_vm.status',
];
return new StandardTestSuite(configuration, name, directory, status_paths,
return StandardTestSuite(configuration, name, directory, status_paths,
recursive: true);
}
@ -627,28 +602,26 @@ class StandardTestSuite extends TestSuite {
if (onDone != null) onDone();
}
/**
* Reads the status files and completes with the parsed expectations.
*/
/// Reads the status files and completes with the parsed expectations.
ExpectationSet readExpectations() {
var statusFiles = statusFilePaths.where((String statusFilePath) {
var file = new File(dartDir.append(statusFilePath).toNativePath());
var file = File(dartDir.append(statusFilePath).toNativePath());
return file.existsSync();
}).map((statusFilePath) {
return dartDir.append(statusFilePath).toNativePath();
}).toList();
return new ExpectationSet.read(statusFiles, configuration);
return ExpectationSet.read(statusFiles, configuration);
}
Future enqueueTests() {
Directory dir = new Directory(suiteDir.toNativePath());
Directory dir = Directory(suiteDir.toNativePath());
return dir.exists().then((exists) {
if (!exists) {
print('Directory containing tests missing: ${suiteDir.toNativePath()}');
return new Future.value(null);
return Future.value(null);
} else {
var group = new FutureGroup();
var group = FutureGroup();
enqueueDirectory(dir, group);
return group.future;
}
@ -679,7 +652,7 @@ class StandardTestSuite extends TestSuite {
if (!isTestFile(filename)) return;
var optionsFromFile = readOptionsFromFile(new Uri.file(filename));
var optionsFromFile = readOptionsFromFile(Uri.file(filename));
CreateTest createTestCase = makeTestCaseCreator(optionsFromFile);
if (optionsFromFile['isMultitest'] as bool) {
@ -709,11 +682,11 @@ class StandardTestSuite extends TestSuite {
if (optionsFromFile['packageRoot'] == null &&
optionsFromFile['packages'] == null) {
if (configuration.packageRoot != null) {
packageRoot = new Path(configuration.packageRoot);
packageRoot = Path(configuration.packageRoot);
optionsFromFile['packageRoot'] = packageRoot.toNativePath();
}
if (configuration.packages != null) {
Path packages = new Path(configuration.packages);
Path packages = Path(configuration.packages);
optionsFromFile['packages'] = packages.toNativePath();
}
}
@ -801,23 +774,22 @@ class StandardTestSuite extends TestSuite {
var path = info.filePath;
if (vmOptionsVariant != 0) {
// Ensure a unique directory for each test case.
path = path.join(new Path(vmOptionsVariant.toString()));
path = path.join(Path(vmOptionsVariant.toString()));
}
tempDir = createCompilationOutputDirectory(path);
var otherResources =
info.optionsFromFile['otherResources'] as List<String>;
for (var name in otherResources) {
var namePath = new Path(name);
var namePath = Path(name);
var fromPath = info.filePath.directoryPath.join(namePath);
new File('$tempDir/$name').parent.createSync(recursive: true);
new File(fromPath.toNativePath()).copySync('$tempDir/$name');
File('$tempDir/$name').parent.createSync(recursive: true);
File(fromPath.toNativePath()).copySync('$tempDir/$name');
}
}
CommandArtifact compilationArtifact =
compilerConfiguration.computeCompilationArtifact(
tempDir, compileTimeArguments, environmentOverrides);
var compilationArtifact = compilerConfiguration.computeCompilationArtifact(
tempDir, compileTimeArguments, environmentOverrides);
if (!configuration.skipCompilation) {
commands.addAll(compilationArtifact.commands);
}
@ -835,20 +807,19 @@ class StandardTestSuite extends TestSuite {
s.replaceAll("__RANDOM__", "${Random().nextInt(0x7fffffff)}"))
.toList();
List<String> runtimeArguments =
compilerConfiguration.computeRuntimeArguments(
configuration.runtimeConfiguration,
info,
vmOptions,
sharedOptions,
dartOptions,
args,
compilationArtifact);
var runtimeArguments = compilerConfiguration.computeRuntimeArguments(
configuration.runtimeConfiguration,
info,
vmOptions,
sharedOptions,
dartOptions,
args,
compilationArtifact);
Map<String, String> environment = environmentOverrides;
var environment = environmentOverrides;
var extraEnv = info.optionsFromFile['environment'] as Map<String, String>;
if (extraEnv != null) {
environment = new Map.from(environment)..addAll(extraEnv);
environment = {...environment, ...extraEnv};
}
return commands
@ -865,10 +836,10 @@ class StandardTestSuite extends TestSuite {
{bool hasSyntaxError,
bool hasCompileError,
bool hasRuntimeError,
bool hasStaticWarning: false,
bool hasStaticWarning = false,
String multitestKey}) {
// Cache the test information for each test case.
var info = new TestInformation(filePath, originTestPath, optionsFromFile,
var info = TestInformation(filePath, originTestPath, optionsFromFile,
hasSyntaxError, hasCompileError, hasRuntimeError, hasStaticWarning,
multitestKey: multitestKey);
cachedTests.add(info);
@ -876,30 +847,30 @@ class StandardTestSuite extends TestSuite {
};
}
/**
* _createUrlPathFromFile takes a [file], which is either located in the dart
* or in the build directory, and will return a String representing
* the relative path to either the dart or the build directory.
* Thus, the returned [String] will be the path component of the URL
* corresponding to [file] (the http server serves files relative to the
* dart/build directories).
*/
/// Takes a [file], which is either located in the dart or in the build
/// directory, and returns a String representing the relative path to either
/// the dart or the build directory.
///
/// Thus, the returned [String] will be the path component of the URL
/// corresponding to [file] (the HTTP server serves files relative to the
/// dart/build directories).
String _createUrlPathFromFile(Path file) {
file = file.absolute;
var relativeBuildDir = new Path(configuration.buildDirectory);
var relativeBuildDir = Path(configuration.buildDirectory);
var buildDir = relativeBuildDir.absolute;
var dartDir = Repository.dir.absolute;
var fileString = file.toString();
if (fileString.startsWith(buildDir.toString())) {
var fileRelativeToBuildDir = file.relativeTo(buildDir);
return "/$PREFIX_BUILDDIR/$fileRelativeToBuildDir";
return "/$prefixBuildDir/$fileRelativeToBuildDir";
} else if (fileString.startsWith(dartDir.toString())) {
var fileRelativeToDartDir = file.relativeTo(dartDir);
return "/$PREFIX_DARTDIR/$fileRelativeToDartDir";
return "/$prefixDartDir/$fileRelativeToDartDir";
}
// Unreachable
// Unreachable.
print("Cannot create URL for path $file. Not in build or dart directory.");
exit(1);
return null;
@ -918,7 +889,7 @@ class StandardTestSuite extends TestSuite {
if (subtestName != null) {
parameters['group'] = subtestName;
}
return new Uri(
return Uri(
scheme: 'http',
host: configuration.localIP,
port: serverPort,
@ -954,7 +925,7 @@ class StandardTestSuite extends TestSuite {
// Use existing HTML document if available.
String content;
var customHtml = new File(
var customHtml = File(
info.filePath.directoryPath.append('$nameNoExt.html').toNativePath());
if (customHtml.existsSync()) {
outputDir = tempDir;
@ -963,18 +934,18 @@ class StandardTestSuite extends TestSuite {
} else {
// Synthesize an HTML file for the test.
if (configuration.compiler == Compiler.dart2js) {
var scriptPath = _createUrlPathFromFile(
new Path('$compilationTempDir/$nameNoExt.js'));
var scriptPath =
_createUrlPathFromFile(Path('$compilationTempDir/$nameNoExt.js'));
content = dart2jsHtml(fileName, scriptPath);
} else {
var jsDir =
new Path(compilationTempDir).relativeTo(Repository.dir).toString();
Path(compilationTempDir).relativeTo(Repository.dir).toString();
content = dartdevcHtml(nameNoExt, jsDir, configuration.compiler);
}
}
var htmlPath = '$tempDir/test.html';
new File(htmlPath).writeAsStringSync(content);
File(htmlPath).writeAsStringSync(content);
// Construct the command(s) that compile all the inputs needed by the
// browser test.
@ -1019,7 +990,7 @@ class StandardTestSuite extends TestSuite {
// Construct the command that executes the browser test.
commands = commands.toList();
var htmlPathSubtest = _createUrlPathFromFile(new Path(htmlPath));
var htmlPathSubtest = _createUrlPathFromFile(Path(htmlPath));
var fullHtmlPath = _uriForBrowserTest(htmlPathSubtest, subtestName);
commands.add(Command.browserTest(fullHtmlPath, configuration,
@ -1034,7 +1005,7 @@ class StandardTestSuite extends TestSuite {
Path filePath, Map<String, dynamic> optionsFromFile) {
var args = configuration.standardOptions.toList();
String packages = packagesArgument(optionsFromFile['packageRoot'] as String,
var packages = packagesArgument(optionsFromFile['packageRoot'] as String,
optionsFromFile['packages'] as String);
if (packages != null) {
args.add(packages);
@ -1067,74 +1038,72 @@ class StandardTestSuite extends TestSuite {
}
}
/**
* Special options for individual tests are currently specified in various
* ways: with comments directly in test files, by using certain imports, or by
* creating additional files in the test directories.
*
* Here is a list of options that are used by 'test.dart' today:
* - Flags can be passed to the vm process that runs the test by adding a
* comment to the test file:
*
* // VMOptions=--flag1 --flag2
*
* - Flags can be passed to dart2js, vm or dartdevc by adding a comment to
* the test file:
*
* // SharedOptions=--flag1 --flag2
*
* - Flags can be passed to dart2js by adding a comment to the test file:
*
* // dart2jsOptions=--flag1 --flag2
*
* - Flags can be passed to the dart script that contains the test also
* using comments, as follows:
*
* // DartOptions=--flag1 --flag2
*
* - Extra environment variables can be passed to the process that runs
* the test by adding comment(s) to the test file:
*
* // Environment=ENV_VAR1=foo bar
* // Environment=ENV_VAR2=bazz
*
* - Most tests are not web tests, but can (and will be) wrapped within
* an HTML file and another script file to test them also on browser
* environments (e.g. language and corelib tests are run this way).
* We deduce that if a file with the same name as the test, but ending in
* .html instead of .dart exists, the test was intended to be a web test
* and no wrapping is necessary.
*
* // SharedObjects=foobar
*
* - This test requires libfoobar.so, libfoobar.dylib or foobar.dll to be
* in the system linker path of the VM.
*
* - 'test.dart' assumes tests fail if
* the process returns a non-zero exit code (in the case of web tests, we
* check for PASS/FAIL indications in the test output).
*
* This method is static as the map is cached and shared amongst
* configurations, so it may not use [configuration].
*/
/// Special options for individual tests are currently specified in various
/// ways: with comments directly in test files, by using certain imports, or
/// by creating additional files in the test directories.
///
/// Here is a list of options that are used by 'test.dart' today:
/// - Flags can be passed to the vm process that runs the test by adding a
/// comment to the test file:
///
/// // VMOptions=--flag1 --flag2
///
/// - Flags can be passed to dart2js, vm or dartdevc by adding a comment to
/// the test file:
///
/// // SharedOptions=--flag1 --flag2
///
/// - Flags can be passed to dart2js by adding a comment to the test file:
///
/// // dart2jsOptions=--flag1 --flag2
///
/// - Flags can be passed to the dart script that contains the test also
/// using comments, as follows:
///
/// // DartOptions=--flag1 --flag2
///
/// - Extra environment variables can be passed to the process that runs
/// the test by adding comment(s) to the test file:
///
/// // Environment=ENV_VAR1=foo bar
/// // Environment=ENV_VAR2=bazz
///
/// - Most tests are not web tests, but can (and will be) wrapped within
/// an HTML file and another script file to test them also on browser
/// environments (e.g. language and corelib tests are run this way).
/// We deduce that if a file with the same name as the test, but ending in
/// .html instead of .dart exists, the test was intended to be a web test
/// and no wrapping is necessary.
///
/// // SharedObjects=foobar
///
/// - This test requires libfoobar.so, libfoobar.dylib or foobar.dll to be
/// in the system linker path of the VM.
///
/// - 'test.dart' assumes tests fail if
/// the process returns a non-zero exit code (in the case of web tests, we
/// check for PASS/FAIL indications in the test output).
///
/// This method is static as the map is cached and shared amongst
/// configurations, so it may not use [configuration].
Map<String, dynamic> readOptionsFromFile(Uri uri) {
if (uri.path.endsWith('.dill')) {
return optionsFromKernelFile();
}
RegExp testOptionsRegExp = new RegExp(r"// VMOptions=(.*)");
RegExp environmentRegExp = new RegExp(r"// Environment=(.*)");
RegExp otherResourcesRegExp = new RegExp(r"// OtherResources=(.*)");
RegExp sharedObjectsRegExp = new RegExp(r"// SharedObjects=(.*)");
RegExp packageRootRegExp = new RegExp(r"// PackageRoot=(.*)");
RegExp packagesRegExp = new RegExp(r"// Packages=(.*)");
RegExp isolateStubsRegExp = new RegExp(r"// IsolateStubs=(.*)");
var testOptionsRegExp = RegExp(r"// VMOptions=(.*)");
var environmentRegExp = RegExp(r"// Environment=(.*)");
var otherResourcesRegExp = RegExp(r"// OtherResources=(.*)");
var sharedObjectsRegExp = RegExp(r"// SharedObjects=(.*)");
var packageRootRegExp = RegExp(r"// PackageRoot=(.*)");
var packagesRegExp = RegExp(r"// Packages=(.*)");
var isolateStubsRegExp = RegExp(r"// IsolateStubs=(.*)");
// TODO(gram) Clean these up once the old directives are not supported.
RegExp domImportRegExp = new RegExp(
var domImportRegExp = RegExp(
r"^[#]?import.*dart:(html|web_audio|indexed_db|svg|web_sql)",
multiLine: true);
var bytes = new File.fromUri(uri).readAsBytesSync();
String contents = decodeUtf8(bytes);
var bytes = File.fromUri(uri).readAsBytesSync();
var contents = decodeUtf8(bytes);
bytes = null;
// Find the options in the file.
@ -1151,11 +1120,11 @@ class StandardTestSuite extends TestSuite {
s.split(' ').where((e) => e != '').toList();
List<String> singleListOfOptions(String name) {
var matches = new RegExp('// $name=(.*)').allMatches(contents);
var matches = RegExp('// $name=(.*)').allMatches(contents);
List<String> options;
for (var match in matches) {
if (options != null) {
throw new Exception(
throw Exception(
'More than one "// $name=" line in test ${uri.toFilePath()}');
}
options = wordSplit(match[1]);
@ -1176,10 +1145,10 @@ class StandardTestSuite extends TestSuite {
matches = environmentRegExp.allMatches(contents);
for (var match in matches) {
final String envDef = match[1];
final int pos = envDef.indexOf('=');
final String name = (pos < 0) ? envDef : envDef.substring(0, pos);
final String value = (pos < 0) ? '' : envDef.substring(pos + 1);
var envDef = match[1];
var pos = envDef.indexOf('=');
var name = (pos < 0) ? envDef : envDef.substring(0, pos);
var value = (pos < 0) ? '' : envDef.substring(pos + 1);
environment ??= <String, String>{};
environment[name] = value;
}
@ -1187,7 +1156,7 @@ class StandardTestSuite extends TestSuite {
matches = packageRootRegExp.allMatches(contents);
for (var match in matches) {
if (packageRoot != null || packages != null) {
throw new Exception(
throw Exception(
'More than one "// Package... line in test ${uri.toFilePath()}');
}
packageRoot = match[1];
@ -1195,15 +1164,14 @@ class StandardTestSuite extends TestSuite {
// PackageRoot=none means that no packages or package-root option
// should be given. Any other value overrides package-root and
// removes any packages option. Don't use with // Packages=.
packageRoot =
uri.resolveUri(new Uri.directory(packageRoot)).toFilePath();
packageRoot = uri.resolveUri(Uri.directory(packageRoot)).toFilePath();
}
}
matches = packagesRegExp.allMatches(contents);
for (var match in matches) {
if (packages != null || packageRoot != null) {
throw new Exception(
throw Exception(
'More than one "// Package..." line in test ${uri.toFilePath()}');
}
packages = match[1];
@ -1211,7 +1179,7 @@ class StandardTestSuite extends TestSuite {
// Packages=none means that no packages or package-root option
// should be given. Any other value overrides packages and removes
// any package-root option. Don't use with // PackageRoot=.
packages = uri.resolveUri(new Uri.file(packages)).toFilePath();
packages = uri.resolveUri(Uri.file(packages)).toFilePath();
}
}
@ -1227,14 +1195,14 @@ class StandardTestSuite extends TestSuite {
sharedObjects.addAll(wordSplit(match[1]));
}
var isMultitest = multiTestRegExp.hasMatch(contents);
var isMultiHtmlTest = multiHtmlTestRegExp.hasMatch(contents);
var isMultitest = _multiTestRegExp.hasMatch(contents);
var isMultiHtmlTest = _multiHtmlTestRegExp.hasMatch(contents);
var isolateMatch = isolateStubsRegExp.firstMatch(contents);
var isolateStubs = isolateMatch != null ? isolateMatch[1] : '';
var containsDomImport = domImportRegExp.hasMatch(contents);
var subtestNames = <String>[];
var matchesIter = multiHtmlTestGroupRegExp.allMatches(contents).iterator;
var matchesIter = _multiHtmlTestGroupRegExp.allMatches(contents).iterator;
while (matchesIter.moveNext() && isMultiHtmlTest) {
var fullMatch = matchesIter.current.group(0);
subtestNames.add(fullMatch.substring(fullMatch.indexOf("'") + 1));
@ -1294,10 +1262,10 @@ class StandardTestSuite extends TestSuite {
Map<String, dynamic> optionsFromKernelFile() {
return const {
"vmOptions": const [const <String>[]],
"sharedOptions": const <String>[],
"dart2jsOptions": const <String>[],
"dartOptions": const <String>[],
"vmOptions": [<String>[]],
"sharedOptions": <String>[],
"dart2jsOptions": <String>[],
"dartOptions": <String>[],
"packageRoot": null,
"packages": null,
"hasSyntaxError": false,
@ -1306,14 +1274,14 @@ class StandardTestSuite extends TestSuite {
"hasStaticWarning": false,
"isMultitest": false,
"isMultiHtmlTest": false,
"subtestNames": const [],
"subtestNames": [],
"isolateStubs": '',
"containsDomImport": false,
};
}
List<List<String>> getVmOptions(Map<String, dynamic> optionsFromFile) {
const compilers = const [
const compilers = [
Compiler.none,
Compiler.dartk,
Compiler.dartkb,
@ -1323,7 +1291,7 @@ class StandardTestSuite extends TestSuite {
Compiler.appJitk,
];
const runtimes = const [Runtime.none, Runtime.dartPrecompiled, Runtime.vm];
const runtimes = [Runtime.none, Runtime.dartPrecompiled, Runtime.vm];
var needsVmOptions = compilers.contains(configuration.compiler) &&
runtimes.contains(configuration.runtime);
@ -1346,7 +1314,7 @@ class PKGTestSuite extends StandardTestSuite {
var dir = filePath.directoryPath;
var nameNoExt = filePath.filenameWithoutExtension;
var customHtmlPath = dir.append('$nameNoExt.html');
var customHtml = new File(customHtmlPath.toNativePath());
var customHtml = File(customHtmlPath.toNativePath());
if (!customHtml.existsSync()) {
super._enqueueBrowserTest(
packageRoot, packages, info, testName, expectations);
@ -1361,7 +1329,7 @@ class PKGTestSuite extends StandardTestSuite {
class AnalyzeLibraryTestSuite extends StandardTestSuite {
static Path _libraryPath(TestConfiguration configuration) =>
new Path(configuration.useSdk
Path(configuration.useSdk
? '${configuration.buildDirectory}/dart-sdk'
: 'sdk');
@ -1375,9 +1343,9 @@ class AnalyzeLibraryTestSuite extends StandardTestSuite {
const ['--fatal-warnings', '--fatal-type-errors', '--sdk-warnings'];
Future enqueueTests() {
var group = new FutureGroup();
var group = FutureGroup();
var dir = new Directory(suiteDir.append('lib').toNativePath());
var dir = Directory(suiteDir.append('lib').toNativePath());
if (dir.existsSync()) {
enqueueDirectory(dir, group);
}

View file

@ -14,7 +14,7 @@ import 'package:test_runner/src/utils.dart';
class DispatchingServer {
HttpServer server;
Map<String, Function> _handlers = new Map<String, Function>();
Map<String, Function> _handlers = {};
Function _notFound;
DispatchingServer(
@ -57,16 +57,14 @@ class DispatchingServer {
/// In case a path does not refer to a file but rather to a directory, a
/// directory listing will be displayed.
const PREFIX_BUILDDIR = 'root_build';
const PREFIX_DARTDIR = 'root_dart';
const prefixBuildDir = 'root_build';
const prefixDartDir = 'root_dart';
/**
* Runs a set of servers that are initialized specifically for the needs of our
* test framework, such as dealing with package-root.
*/
/// Runs a set of servers that are initialized specifically for the needs of our
/// test framework, such as dealing with package-root.
class TestingServers {
static final _CACHE_EXPIRATION_IN_SECONDS = 30;
static final _HARMLESS_REQUEST_PATH_ENDINGS = [
static final _cacheExpirationSeconds = 30;
static final _harmlessRequestPathSuffixes = [
"/apple-touch-icon.png",
"/apple-touch-icon-precomposed.png",
"/favicon.ico",
@ -91,20 +89,20 @@ class TestingServers {
String dartDirectory,
String packageRoot,
String packages]) {
_buildDirectory = Uri.base.resolveUri(new Uri.directory(buildDirectory));
_buildDirectory = Uri.base.resolveUri(Uri.directory(buildDirectory));
if (dartDirectory == null) {
_dartDirectory = Repository.uri;
} else {
_dartDirectory = Uri.base.resolveUri(new Uri.directory(dartDirectory));
_dartDirectory = Uri.base.resolveUri(Uri.directory(dartDirectory));
}
if (packageRoot == null) {
if (packages == null) {
_packages = _dartDirectory.resolve('.packages');
} else {
_packages = new Uri.file(packages);
_packages = Uri.file(packages);
}
} else {
_packageRoot = new Uri.directory(packageRoot);
_packageRoot = Uri.directory(packageRoot);
}
}
@ -116,20 +114,19 @@ class TestingServers {
DispatchingServer get server => _server;
/**
* [startServers] will start two Http servers.
* The first server listens on [port] and sets
* "Access-Control-Allow-Origin: *"
* The second server listens on [crossOriginPort] and sets
* "Access-Control-Allow-Origin: client:port1
* "Access-Control-Allow-Credentials: true"
*/
/// [startServers] will start two Http servers.
///
/// The first server listens on [port] and sets
/// "Access-Control-Allow-Origin: *"
/// The second server listens on [crossOriginPort] and sets
/// "Access-Control-Allow-Origin: client:port1
/// "Access-Control-Allow-Credentials: true"
Future startServers(String host,
{int port: 0, int crossOriginPort: 0}) async {
{int port = 0, int crossOriginPort = 0}) async {
if (_packages != null) {
_resolver = await SyncPackageResolver.loadConfig(_packages);
} else {
_resolver = new SyncPackageResolver.root(_packageRoot);
_resolver = SyncPackageResolver.root(_packageRoot);
}
_server = await _startHttpServer(host, port: port);
await _startHttpServer(host,
@ -142,7 +139,7 @@ class TestingServers {
var script = _dartDirectory.resolve('pkg/test_runner/bin/http_server.dart');
var buildDirectory = _buildDirectory.toFilePath();
var command = [
return [
dart,
script.toFilePath(),
'-p',
@ -152,20 +149,13 @@ class TestingServers {
'--network',
network,
'--build-directory=$buildDirectory',
'--runtime=${runtime.name}'
];
if (useContentSecurityPolicy) {
command.add('--csp');
}
if (_packages != null) {
command.add('--packages=${_packages.toFilePath()}');
} else if (_packageRoot != null) {
command.add('--package-root=${_packageRoot.toFilePath()}');
}
return command.join(' ');
'--runtime=${runtime.name}',
if (useContentSecurityPolicy) '--csp',
if (_packages != null)
'--packages=${_packages.toFilePath()}'
else if (_packageRoot != null)
'--package-root=${_packageRoot.toFilePath()}'
].join(' ');
}
void stopServers() {
@ -179,17 +169,17 @@ class TestingServers {
}
Future<DispatchingServer> _startHttpServer(String host,
{int port: 0, int allowedPort: -1}) {
{int port = 0, int allowedPort = -1}) {
return HttpServer.bind(host, port).then((HttpServer httpServer) {
var server = new DispatchingServer(httpServer, _onError, _sendNotFound);
var server = DispatchingServer(httpServer, _onError, _sendNotFound);
server.addHandler('/echo', _handleEchoRequest);
server.addHandler('/ws', _handleWebSocketRequest);
fileHandler(HttpRequest request) {
_handleFileOrDirectoryRequest(request, allowedPort);
}
server.addHandler('/$PREFIX_BUILDDIR', fileHandler);
server.addHandler('/$PREFIX_DARTDIR', fileHandler);
server.addHandler('/$prefixBuildDir', fileHandler);
server.addHandler('/$prefixDartDir', fileHandler);
server.addHandler('/packages', fileHandler);
_serverList.add(httpServer);
return server;
@ -200,13 +190,12 @@ class TestingServers {
HttpRequest request, int allowedPort) async {
// Enable browsers to cache file/directory responses.
var response = request.response;
response.headers
.set("Cache-Control", "max-age=$_CACHE_EXPIRATION_IN_SECONDS");
response.headers.set("Cache-Control", "max-age=$_cacheExpirationSeconds");
try {
var path = _getFileUriFromRequestUri(request.uri);
if (path != null) {
var file = new File.fromUri(path);
var directory = new Directory.fromUri(path);
var file = File.fromUri(path);
var directory = Directory.fromUri(path);
if (await file.exists()) {
_sendFileContent(request, response, allowedPort, file);
} else if (await directory.exists()) {
@ -218,9 +207,9 @@ class TestingServers {
} else {
if (request.uri.path == '/') {
var entries = [
new _Entry('root_dart', 'root_dart/'),
new _Entry('root_build', 'root_build/'),
new _Entry('echo', 'echo')
_Entry('root_dart', 'root_dart/'),
_Entry('root_build', 'root_build/'),
_Entry('echo', 'echo')
];
_sendDirectoryListing(entries, request, response);
} else {
@ -269,32 +258,32 @@ class TestingServers {
if (pathSegments.length == 0) return null;
int packagesIndex = pathSegments.indexOf('packages');
if (packagesIndex != -1) {
var packageUri = new Uri(
var packageUri = Uri(
scheme: 'package',
pathSegments: pathSegments.skip(packagesIndex + 1));
return _resolver.resolveUri(packageUri);
}
if (pathSegments[0] == PREFIX_BUILDDIR) {
if (pathSegments[0] == prefixBuildDir) {
return _buildDirectory.resolve(pathSegments.skip(1).join('/'));
}
if (pathSegments[0] == PREFIX_DARTDIR) {
if (pathSegments[0] == prefixDartDir) {
return _dartDirectory.resolve(pathSegments.skip(1).join('/'));
}
return null;
}
Future<List<_Entry>> _listDirectory(Directory directory) {
var completer = new Completer<List<_Entry>>();
var completer = Completer<List<_Entry>>();
var entries = <_Entry>[];
directory.list().listen((FileSystemEntity fse) {
var segments = fse.uri.pathSegments;
if (fse is File) {
var filename = segments.last;
entries.add(new _Entry(filename, filename));
entries.add(_Entry(filename, filename));
} else if (fse is Directory) {
var dirname = segments[segments.length - 2];
entries.add(new _Entry(dirname, '$dirname/'));
entries.add(_Entry(dirname, '$dirname/'));
}
}, onDone: () {
completer.complete(entries);
@ -392,7 +381,7 @@ class TestingServers {
void _sendNotFound(HttpRequest request) {
bool isHarmlessPath(String path) {
return _HARMLESS_REQUEST_PATH_ENDINGS.any((pattern) {
return _harmlessRequestPathSuffixes.any((pattern) {
return path.contains(pattern);
});
}
@ -431,7 +420,7 @@ class TestingServers {
}
}
// Helper class for displaying directory listings.
/// Helper class for displaying directory listings.
class _Entry implements Comparable<_Entry> {
final String name;
final String displayName;

View file

@ -9,17 +9,17 @@ import 'dart:convert';
import 'configuration.dart';
import 'path.dart';
// This is the maximum time we expect stdout/stderr of subprocesses to deliver
// data after we've got the exitCode.
const Duration MAX_STDIO_DELAY = const Duration(seconds: 30);
/// This is the maximum time we expect stdout/stderr of subprocesses to deliver
/// data after we've got the exitCode.
const Duration maxStdioDelay = Duration(seconds: 30);
String MAX_STDIO_DELAY_PASSED_MESSAGE =
final maxStdioDelayPassedMessage =
"""Not waiting for stdout/stderr from subprocess anymore
($MAX_STDIO_DELAY passed). Please note that this could be an indicator
($maxStdioDelay passed). Please note that this could be an indicator
that there is a hanging process which we were unable to kill.""";
/// The names of the packages that are available for use in tests.
const testPackages = const [
const testPackages = [
"async_helper",
"collection",
"expect",
@ -34,12 +34,10 @@ const testPackages = const [
class DebugLogger {
static IOSink _sink;
/**
* If [path] was null, the DebugLogger will write messages to stdout.
*/
/// If [path] was null, the DebugLogger will write messages to stdout.
static void init(Path path) {
if (path != null) {
_sink = new File(path.toNativePath()).openWrite(mode: FileMode.append);
_sink = File(path.toNativePath()).openWrite(mode: FileMode.append);
}
}
@ -82,18 +80,19 @@ class DebugLogger {
}
}
static String get _datetime => "${new DateTime.now()}";
static String get _datetime => "${DateTime.now()}";
}
String prettifyJson(Object json, {int startIndentation: 0, int shiftWidth: 6}) {
String prettifyJson(Object json,
{int startIndentation = 0, int shiftWidth = 6}) {
int currentIndentation = startIndentation;
var buffer = new StringBuffer();
var buffer = StringBuffer();
String indentationString() {
return new List.filled(currentIndentation, ' ').join('');
return List.filled(currentIndentation, ' ').join('');
}
addString(String s, {bool indentation: true, bool newLine: true}) {
addString(String s, {bool indentation = true, bool newLine = true}) {
if (indentation) {
buffer.write(indentationString());
}
@ -102,7 +101,7 @@ String prettifyJson(Object json, {int startIndentation: 0, int shiftWidth: 6}) {
}
prettifyJsonInternal(Object obj,
{bool indentation: true, bool newLine: true}) {
{bool indentation = true, bool newLine = true}) {
if (obj is List) {
addString("[", indentation: indentation);
currentIndentation += shiftWidth;
@ -132,15 +131,13 @@ String prettifyJson(Object json, {int startIndentation: 0, int shiftWidth: 6}) {
return buffer.toString();
}
/**
* [areByteArraysEqual] compares a range of bytes from [buffer1] with a
* range of bytes from [buffer2].
*
* Returns [true] if the [count] bytes in [buffer1] (starting at
* [offset1]) match the [count] bytes in [buffer2] (starting at
* [offset2]).
* Otherwise [false] is returned.
*/
/// [areByteArraysEqual] compares a range of bytes from [buffer1] with a
/// range of bytes from [buffer2].
///
/// Returns [true] if the [count] bytes in [buffer1] (starting at
/// [offset1]) match the [count] bytes in [buffer2] (starting at
/// [offset2]).
/// Otherwise [false] is returned.
bool areByteArraysEqual(
List<int> buffer1, int offset1, List<int> buffer2, int offset2, int count) {
if ((offset1 + count) > buffer1.length ||
@ -156,12 +153,10 @@ bool areByteArraysEqual(
return true;
}
/**
* [findBytes] searches for [pattern] in [data] beginning at [startPos].
*
* Returns [true] if [pattern] was found in [data].
* Otherwise [false] is returned.
*/
/// [findBytes] searches for [pattern] in [data] beginning at [startPos].
///
/// Returns [true] if [pattern] was found in [data].
/// Otherwise [false] is returned.
int findBytes(List<int> data, List<int> pattern, [int startPos = 0]) {
// TODO(kustermann): Use one of the fast string-matching algorithms!
for (int i = startPos; i < (data.length - pattern.length); i++) {
@ -201,7 +196,7 @@ List<String> decodeLines(List<int> output) {
}
String indent(String string, int numSpaces) {
var spaces = new List.filled(numSpaces, ' ').join('');
var spaces = List.filled(numSpaces, ' ').join('');
return string
.replaceAll('\r\n', '\n')
.split('\n')
@ -232,8 +227,8 @@ String niceTime(Duration duration) {
}
}
// This function is pretty stupid and only puts quotes around an argument if
// it the argument contains a space.
/// This function is pretty stupid and only puts quotes around an argument if
/// it the argument contains a space.
String escapeCommandLineArgument(String argument) {
if (argument.contains(' ')) {
return '"$argument"';
@ -263,7 +258,7 @@ class HashCodeBuilder {
addJson(object[key]);
}
} else {
throw new Exception("Can't build hashcode for non json-like object "
throw Exception("Can't build hashcode for non json-like object "
"(${object.runtimeType})");
}
}
@ -296,7 +291,7 @@ bool deepJsonCompare(Object a, Object b) {
}
return false;
} else {
throw new Exception("Can't compare two non json-like objects "
throw Exception("Can't compare two non json-like objects "
"(a: ${a.runtimeType}, b: ${b.runtimeType})");
}
}
@ -315,57 +310,51 @@ class UniqueObject {
class LastModifiedCache {
Map<String, DateTime> _cache = <String, DateTime>{};
/**
* Returns the last modified date of the given [uri].
*
* The return value will be cached for future queries. If [uri] is a local
* file, it's last modified [Date] will be returned. If the file does not
* exist, null will be returned instead.
* In case [uri] is not a local file, this method will always return
* the current date.
*/
/// Returns the last modified date of the given [uri].
///
/// The return value will be cached for future queries. If [uri] is a local
/// file, it's last modified [Date] will be returned. If the file does not
/// exist, null will be returned instead.
/// In case [uri] is not a local file, this method will always return
/// the current date.
DateTime getLastModified(Uri uri) {
if (uri.scheme == "file") {
if (_cache.containsKey(uri.path)) {
return _cache[uri.path];
}
var file = new File(new Path(uri.path).toNativePath());
var file = File(Path(uri.path).toNativePath());
_cache[uri.path] = file.existsSync() ? file.lastModifiedSync() : null;
return _cache[uri.path];
}
return new DateTime.now();
return DateTime.now();
}
}
class ExistsCache {
Map<String, bool> _cache = <String, bool>{};
/**
* Returns true if the file in [path] exists, false otherwise.
*
* The information will be cached.
*/
/// Returns true if the file in [path] exists, false otherwise.
///
/// The information will be cached.
bool doesFileExist(String path) {
if (!_cache.containsKey(path)) {
_cache[path] = new File(path).existsSync();
_cache[path] = File(path).existsSync();
}
return _cache[path];
}
}
class TestUtils {
static LastModifiedCache lastModifiedCache = new LastModifiedCache();
static ExistsCache existsCache = new ExistsCache();
static LastModifiedCache lastModifiedCache = LastModifiedCache();
static ExistsCache existsCache = ExistsCache();
/**
* Creates a directory using a [relativePath] to an existing
* [base] directory if that [relativePath] does not already exist.
*/
/// Creates a directory using a [relativePath] to an existing
/// [base] directory if that [relativePath] does not already exist.
static Directory mkdirRecursive(Path base, Path relativePath) {
if (relativePath.isAbsolute) {
base = new Path('/');
base = Path('/');
}
Directory dir = new Directory(base.toNativePath());
Directory dir = Directory(base.toNativePath());
assert(dir.existsSync());
var segments = relativePath.segments();
for (String segment in segments) {
@ -376,7 +365,7 @@ class TestUtils {
// Skip the directory creation for a path like "/E:".
continue;
}
dir = new Directory(base.toNativePath());
dir = Directory(base.toNativePath());
if (!dir.existsSync()) {
dir.createSync();
}
@ -385,23 +374,19 @@ class TestUtils {
return dir;
}
/**
* Keep a map of files copied to avoid race conditions.
*/
/// Keep a map of files copied to avoid race conditions.
static Map<String, Future> _copyFilesMap = {};
/**
* Copy a [source] file to a new place.
* Assumes that the directory for [dest] already exists.
*/
/// Copy a [source] file to a new place.
/// Assumes that the directory for [dest] already exists.
static Future copyFile(Path source, Path dest) {
return _copyFilesMap.putIfAbsent(dest.toNativePath(),
() => new File(source.toNativePath()).copy(dest.toNativePath()));
() => File(source.toNativePath()).copy(dest.toNativePath()));
}
static Future copyDirectory(String source, String dest) {
source = new Path(source).toNativePath();
dest = new Path(dest).toNativePath();
source = Path(source).toNativePath();
dest = Path(dest).toNativePath();
var executable = 'cp';
var args = ['-Rp', source, dest];
@ -411,7 +396,7 @@ class TestUtils {
}
return Process.run(executable, args).then((ProcessResult result) {
if (result.exitCode != 0) {
throw new Exception("Failed to execute '$executable "
throw Exception("Failed to execute '$executable "
"${args.join(' ')}'.");
}
});
@ -422,18 +407,18 @@ class TestUtils {
// deleting them. Use the system tools to delete our long paths.
// See issue 16264.
if (Platform.operatingSystem == 'windows') {
var native_path = new Path(path).toNativePath();
var native_path = Path(path).toNativePath();
// Running this in a shell sucks, but rmdir is not part of the standard
// path.
return Process.run('rmdir', ['/s', '/q', native_path], runInShell: true)
.then((ProcessResult result) {
if (result.exitCode != 0) {
throw new Exception('Can\'t delete path $native_path. '
throw Exception('Can\'t delete path $native_path. '
'This path might be too long');
}
});
} else {
var dir = new Directory(path);
var dir = Directory(path);
return dir.delete(recursive: true);
}
}
@ -459,7 +444,7 @@ class TestUtils {
}
}
static final debugLogFilePath = new Path(".debug.log");
static final debugLogFilePath = Path(".debug.log");
/// If test.py was invoked with '--write-results' it will write
/// test outcomes to this file in the '--output-directory'.
@ -479,10 +464,11 @@ class TestUtils {
}
}
static int shortNameCounter = 0; // Make unique short file names on Windows.
/// Make unique short file names on Windows.
static int shortNameCounter = 0;
static String getShortName(String path) {
const pathReplacements = const {
const pathReplacements = {
"tests_co19_src_Language_12_Expressions_14_Function_Invocation_":
"co19_fn_invoke_",
"tests_co19_src_LayoutTests_fast_css_getComputedStyle_getComputedStyle-":

View file

@ -7,7 +7,7 @@ import 'package:expect/expect.dart';
import 'package:test_runner/src/dependency_graph.dart';
main() {
var graph = new Graph<int>();
var graph = Graph<int>();
var numberOfEvents = 0;
var addEventAssertions = [];
var changeEventAssertions = [];

View file

@ -6,6 +6,6 @@ import 'dart:io';
main(List<String> arguments) {
var outputFile = arguments[0];
var file = new File(outputFile);
var file = File(outputFile);
file.createSync();
}

View file

@ -27,10 +27,8 @@ import 'package:test_runner/src/path.dart';
import 'package:test_runner/src/repository.dart';
import 'package:test_runner/src/test_case.dart';
/**
* This class is reponsible for setting up the files necessary for this test
* as well as touching a file.
*/
/// This class is reponsible for setting up the files necessary for this test
/// as well as touching a file.
class FileUtils {
Directory tempDir;
File testJs;
@ -59,7 +57,7 @@ class FileUtils {
}
if (createJsDeps) {
testJsDeps = _createFile(testJsDepsFilePath);
var path = new Path(tempDir.path).append("test.dart").absolute;
var path = Path(tempDir.path).append("test.dart").absolute;
_writeToFile(testJsDeps, "file://$path");
}
}
@ -71,7 +69,7 @@ class FileUtils {
if (testSnapshot != null) testSnapshot.deleteSync();
// if the script did run, it created this file, so we need to delete it
File file = new File(scriptOutputPath.toNativePath());
File file = File(scriptOutputPath.toNativePath());
if (file.existsSync()) {
file.deleteSync();
}
@ -80,25 +78,23 @@ class FileUtils {
}
Path get scriptOutputPath {
return new Path(tempDir.path)
.append('created_if_command_did_run.txt')
.absolute;
return Path(tempDir.path).append('created_if_command_did_run.txt').absolute;
}
Path get testDartFilePath {
return new Path(tempDir.path).append('test.dart').absolute;
return Path(tempDir.path).append('test.dart').absolute;
}
Path get testJsFilePath {
return new Path(tempDir.path).append('test.js').absolute;
return Path(tempDir.path).append('test.js').absolute;
}
Path get testJsDepsFilePath {
return new Path(tempDir.path).append('test.js.deps').absolute;
return Path(tempDir.path).append('test.js.deps').absolute;
}
Path get testSnapshotFilePath {
return new Path(tempDir.path).append('test_dart2js.snapshot').absolute;
return Path(tempDir.path).append('test_dart2js.snapshot').absolute;
}
void touchFile(File file) {
@ -107,8 +103,8 @@ class FileUtils {
void _writeToFile(File file, String content) {
if (content != null) {
var fd = new File(file.resolveSymbolicLinksSync())
.openSync(mode: FileMode.write);
var fd =
File(file.resolveSymbolicLinksSync()).openSync(mode: FileMode.write);
fd.writeStringSync(content);
fd.closeSync();
}
@ -119,7 +115,7 @@ class FileUtils {
}
File _createFile(Path path) {
var file = new File(path.toNativePath());
var file = File(path.toNativePath());
file.createSync();
return file;
}
@ -137,10 +133,10 @@ class CommandCompletedHandler {
if (_shouldHaveRun) {
Expect.equals(0, output.stdout.length);
Expect.isTrue(
new File(fileUtils.scriptOutputPath.toNativePath()).existsSync());
File(fileUtils.scriptOutputPath.toNativePath()).existsSync());
} else {
Expect.isFalse(
new File(fileUtils.scriptOutputPath.toNativePath()).existsSync());
File(fileUtils.scriptOutputPath.toNativePath()).existsSync());
}
}
}
@ -164,37 +160,37 @@ void main() {
// This script is in [sdk]/pkg/test_runner/test.
Repository.uri = Platform.script.resolve('../../..');
var fs_noTestJs = new FileUtils(
var fs_noTestJs = FileUtils(
createJs: false,
createJsDeps: true,
createDart: true,
createSnapshot: true);
var fs_noTestJsDeps = new FileUtils(
var fs_noTestJsDeps = FileUtils(
createJs: true,
createJsDeps: false,
createDart: true,
createSnapshot: true);
var fs_noTestDart = new FileUtils(
var fs_noTestDart = FileUtils(
createJs: true,
createJsDeps: true,
createDart: false,
createSnapshot: true);
var fs_noTestSnapshot = new FileUtils(
var fs_noTestSnapshot = FileUtils(
createJs: true,
createJsDeps: true,
createDart: true,
createSnapshot: false);
var fs_notUpToDate_snapshot = new FileUtils(
var fs_notUpToDate_snapshot = FileUtils(
createJs: true,
createJsDeps: true,
createDart: true,
createSnapshot: true);
var fs_notUpToDate_dart = new FileUtils(
var fs_notUpToDate_dart = FileUtils(
createJs: true,
createJsDeps: true,
createDart: true,
createSnapshot: true);
var fs_upToDate = new FileUtils(
var fs_upToDate = FileUtils(
createJs: true,
createJsDeps: true,
createDart: true,
@ -215,9 +211,9 @@ void main() {
fs_upToDate.touchFile(fs_upToDate.testJs);
Future runTest(String name, FileUtils fileUtils, bool shouldRun) {
var completedHandler = new CommandCompletedHandler(fileUtils, shouldRun);
var completedHandler = CommandCompletedHandler(fileUtils, shouldRun);
var command = makeCompilationCommand(name, fileUtils) as ProcessCommand;
var process = new RunningProcess(command, 60);
var process = RunningProcess(command, 60);
return process.run().then((CommandOutput output) {
completedHandler.processCompletedTest(output);
});
@ -250,5 +246,5 @@ void main() {
// We need to wait some time to make sure that the files we 'touch' get a
// bigger timestamp than the old ones
new Timer(new Duration(seconds: 1), touchFilesAndRunTests);
Timer(Duration(seconds: 1), touchFilesAndRunTests);
}

View file

@ -14,6 +14,7 @@ import "package:status_file/expectation.dart";
import "package:test_runner/src/command.dart";
import "package:test_runner/src/configuration.dart";
import "package:test_runner/src/options.dart";
import "package:test_runner/src/process_queue.dart";
import "package:test_runner/src/repository.dart";
import "package:test_runner/src/test_case.dart";
import "package:test_runner/src/test_suite.dart";
@ -41,10 +42,8 @@ class TestController {
numCompletedTests++;
if (testCase.displayName == "fail-unexpected") {
if (!testCase.unexpectedOutput) {
var stdout =
new String.fromCharCodes(testCase.lastCommandOutput.stdout);
var stderr =
new String.fromCharCodes(testCase.lastCommandOutput.stderr);
var stdout = String.fromCharCodes(testCase.lastCommandOutput.stdout);
var stderr = String.fromCharCodes(testCase.lastCommandOutput.stderr);
print("stdout = [$stdout]");
print("stderr = [$stderr]");
throw "Test case ${testCase.displayName} passed unexpectedly, "
@ -52,10 +51,8 @@ class TestController {
}
} else {
if (testCase.unexpectedOutput) {
var stdout =
new String.fromCharCodes(testCase.lastCommandOutput.stdout);
var stderr =
new String.fromCharCodes(testCase.lastCommandOutput.stderr);
var stdout = String.fromCharCodes(testCase.lastCommandOutput.stdout);
var stderr = String.fromCharCodes(testCase.lastCommandOutput.stderr);
print("stdout = [$stdout]");
print("stderr = [$stderr]");
throw "Test case ${testCase.displayName} failed, "
@ -121,24 +118,18 @@ class CustomTestSuite extends TestSuite {
TestCase _makeTestCase(String name, timeout, Command command,
Iterable<Expectation> expectations) {
var configuration = new OptionsParser().parse(['--timeout', '$timeout'])[0];
return new TestCase(name, [command], configuration,
new Set<Expectation>.from(expectations));
var configuration = OptionsParser().parse(['--timeout', '$timeout'])[0];
return TestCase(
name, [command], configuration, Set<Expectation>.from(expectations));
}
}
void testProcessQueue() {
var maxProcesses = 2;
var maxBrowserProcesses = maxProcesses;
var config = new OptionsParser().parse(['--noBatch'])[0];
new ProcessQueue(
config,
maxProcesses,
maxBrowserProcesses,
new DateTime.now(),
[new CustomTestSuite(config)],
[new EventListener()],
TestController.finished);
var config = OptionsParser().parse(['--noBatch'])[0];
ProcessQueue(config, maxProcesses, maxBrowserProcesses, DateTime.now(),
[CustomTestSuite(config)], [EventListener()], TestController.finished);
}
class EventListener extends progress.EventListener {
@ -165,7 +156,7 @@ void main(List<String> arguments) {
break;
case 'timeout':
// This process should be killed by the test after DEFAULT_TIMEOUT
new Timer(new Duration(hours: 42), () {});
Timer(Duration(hours: 42), () {});
break;
default:
throw "Unknown option ${arguments[0]} passed to test_runner_test";
@ -183,7 +174,7 @@ String getProcessTestFileName() {
var extension = getPlatformExecutableExtension();
var executable = Platform.executable;
var dirIndex = executable.lastIndexOf('dart');
var buffer = new StringBuffer(executable.substring(0, dirIndex));
var buffer = StringBuffer(executable.substring(0, dirIndex));
buffer.write('process_test$extension');
return buffer.toString();
}

View file

@ -15,32 +15,20 @@ import 'package:test_runner/src/configuration.dart';
import 'package:test_runner/src/options.dart';
import 'package:test_runner/src/test_configurations.dart';
const List<String> COMMON_ARGUMENTS = const <String>[
const List<String> _commonArguments = <String>[
'--report',
'--progress=diff',
'co19'
];
const List<List<String>> COMMAND_LINES = const <List<String>>[
const <String>['-mrelease,debug', '-rvm', '-cnone'],
const <String>['-mrelease,debug', '-rvm', '-cnone', '--checked'],
const <String>['-mrelease', '-rnone', '-cdart2analyzer'],
const <String>['-mrelease', '-rd8', '-cdart2js', '--use-sdk'],
const <String>[
'-mrelease',
'-rd8,jsshell',
'-cdart2js',
'--use-sdk',
'--minified'
],
const <String>[
'-mrelease',
'-rd8,jsshell',
'-cdart2js',
'--use-sdk',
'--checked'
],
const <String>[
const List<List<String>> _commandLines = <List<String>>[
<String>['-mrelease,debug', '-rvm', '-cnone'],
<String>['-mrelease,debug', '-rvm', '-cnone', '--checked'],
<String>['-mrelease', '-rnone', '-cdart2analyzer'],
<String>['-mrelease', '-rd8', '-cdart2js', '--use-sdk'],
<String>['-mrelease', '-rd8,jsshell', '-cdart2js', '--use-sdk', '--minified'],
<String>['-mrelease', '-rd8,jsshell', '-cdart2js', '--use-sdk', '--checked'],
<String>[
'-mrelease',
'-rd8,jsshell',
'-cdart2js',
@ -51,17 +39,17 @@ const List<List<String>> COMMAND_LINES = const <List<String>>[
];
void main(List<String> args) {
var optionsParser = new OptionsParser();
var optionsParser = OptionsParser();
var configurations = <TestConfiguration>[];
for (var commandLine in COMMAND_LINES) {
for (var commandLine in _commandLines) {
var arguments = <String>[];
arguments.addAll(COMMON_ARGUMENTS);
arguments.addAll(_commonArguments);
arguments.addAll(args);
arguments.addAll(commandLine);
configurations.addAll(optionsParser.parse(arguments));
}
if (configurations != null || configurations.length > 0) {
if (configurations != null || configurations.isNotEmpty) {
testConfigurations(configurations);
}
}