Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Send test platforms to the remote listener #694

Merged
merged 1 commit into from
Oct 4, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 43 additions & 11 deletions lib/src/backend/test_platform.dart
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,18 @@ class TestPlatform {
all.firstWhere((platform) => platform.identifier == identifier,
orElse: () => null);

static Set<TestPlatform> _builtIn = new Set.from([
TestPlatform.vm,
TestPlatform.dartium,
TestPlatform.contentShell,
TestPlatform.chrome,
TestPlatform.phantomJS,
TestPlatform.firefox,
TestPlatform.safari,
TestPlatform.internetExplorer,
TestPlatform.nodeJS
]);

/// The human-friendly name of the platform.
final String name;

Expand Down Expand Up @@ -88,20 +100,40 @@ class TestPlatform {
this.isBlink: false,
this.isHeadless: false});

/// Converts a JSON-safe representation generated by [serialize] back into a
/// [TestPlatform].
factory TestPlatform.deserialize(Object serialized) {
if (serialized is String) return find(serialized);

var map = serialized as Map;
return new TestPlatform._(map["name"], map["identifier"],
isDartVM: map["isDartVM"],
isBrowser: map["isBrowser"],
isJS: map["isJS"],
isBlink: map["isBlink"],
isHeadless: map["isHeadless"]);
}

/// Converts [this] into a JSON-safe object that can be converted back to a
/// [TestPlatform] using [new TestPlatform.deserialize].
Object serialize() {
if (_builtIn.contains(this)) return identifier;

return {
"name": name,
"identifier": identifier,
"isDartVM": isDartVM,
"isBrowser": isBrowser,
"isJS": isJS,
"isBlink": isBlink,
"isHeadless": isHeadless
};
}

String toString() => name;
}

final List<TestPlatform> _allPlatforms = [
TestPlatform.vm,
TestPlatform.dartium,
TestPlatform.contentShell,
TestPlatform.chrome,
TestPlatform.phantomJS,
TestPlatform.firefox,
TestPlatform.safari,
TestPlatform.internetExplorer,
TestPlatform.nodeJS
];
final List<TestPlatform> _allPlatforms = TestPlatform._builtIn.toList();

/// **Do not call this function without express permission from the test package
/// authors**.
Expand Down
7 changes: 4 additions & 3 deletions lib/src/runner/browser/browser_manager.dart
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,8 @@ class BrowserManager {
///
/// If [mapper] is passed, it's used to map stack traces for errors coming
/// from this test suite.
Future<RunnerSuite> load(String path, Uri url, SuiteConfiguration suiteConfig,
Future<RunnerSuite> load(
String path, Uri url, SuiteConfiguration suiteConfig, Object message,
{StackTraceMapper mapper}) async {
url = url.replace(
fragment: Uri.encodeFull(JSON.encode({
Expand Down Expand Up @@ -236,8 +237,8 @@ class BrowserManager {
});

try {
controller = await deserializeSuite(
path, _platform, suiteConfig, await _environment, suiteChannel,
controller = await deserializeSuite(path, _platform, suiteConfig,
await _environment, suiteChannel, message,
mapper: mapper);
_controllers.add(controller);
return controller.suite;
Expand Down
6 changes: 3 additions & 3 deletions lib/src/runner/browser/platform.dart
Original file line number Diff line number Diff line change
Expand Up @@ -192,8 +192,8 @@ class BrowserPlatform extends PlatformPlugin {
///
/// This will start a browser to load the suite if one isn't already running.
/// Throws an [ArgumentError] if [browser] isn't a browser platform.
Future<RunnerSuite> load(
String path, TestPlatform browser, SuiteConfiguration suiteConfig) async {
Future<RunnerSuite> load(String path, TestPlatform browser,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe this will be breaking for Bolt internally. So again we'll have to be cautious with the next roll.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, and there are more changes coming down that will slightly change the plugin API in other ways. It should all be straightforward to migrate, though.

SuiteConfiguration suiteConfig, Object message) async {
assert(suiteConfig.platforms.contains(browser.identifier));

if (!browser.isBrowser) {
Expand Down Expand Up @@ -271,7 +271,7 @@ class BrowserPlatform extends PlatformPlugin {
var browserManager = await _browserManagerFor(browser);
if (_closed || browserManager == null) return null;

var suite = await browserManager.load(path, suiteUrl, suiteConfig,
var suite = await browserManager.load(path, suiteUrl, suiteConfig, message,
mapper: browser.isJS ? _mappers[path] : null);
if (_closed) return null;
return suite;
Expand Down
17 changes: 16 additions & 1 deletion lib/src/runner/loader.dart
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,20 @@ class Loader {
List<TestPlatform> get allPlatforms =>
new List.unmodifiable(_platformCallbacks.keys);

List<Map<String, Object>> get _allPlatformsSerialized {
if (__allPlatformsSerialized != null &&
__allPlatformsSerialized.length == _platformCallbacks.length) {
return __allPlatformsSerialized;
}

__allPlatformsSerialized = _platformCallbacks.keys
.map((platform) => platform.serialize())
.toList();
return __allPlatformsSerialized;
}

List<Map<String, Object>> __allPlatformsSerialized;

/// Creates a new loader that loads tests on platforms defined in
/// [Configuration.current].
///
Expand Down Expand Up @@ -169,7 +183,8 @@ class Loader {

try {
var plugin = await memo.runOnce(_platformCallbacks[platform]);
var suite = await plugin.load(path, platform, platformConfig);
var suite = await plugin.load(path, platform, platformConfig,
{"testPlatforms": _allPlatformsSerialized});
if (suite != null) _suites.add(suite);
return suite;
} catch (error, stackTrace) {
Expand Down
6 changes: 3 additions & 3 deletions lib/src/runner/node/platform.dart
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,12 @@ class NodePlatform extends PlatformPlugin {
throw new UnimplementedError();

Future<RunnerSuite> load(String path, TestPlatform platform,
SuiteConfiguration suiteConfig) async {
SuiteConfiguration suiteConfig, Object message) async {
assert(platform == TestPlatform.nodeJS);

var pair = await _loadChannel(path, suiteConfig);
var controller = await deserializeSuite(
path, platform, suiteConfig, new PluginEnvironment(), pair.first,
var controller = await deserializeSuite(path, platform, suiteConfig,
new PluginEnvironment(), pair.first, message,
mapper: pair.last);
return controller.suite;
}
Expand Down
14 changes: 7 additions & 7 deletions lib/src/runner/plugin/platform.dart
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ import 'platform_helpers.dart';
/// In order to support interactive debugging, a plugin must override [load] as
/// well, which returns a [RunnerSuite] that can contain a custom [Environment]
/// and control debugging metadata such as [RunnerSuite.isDebugging] and
/// [RunnerSuite.onDebugging]. To make this easier, implementations can call
/// [deserializeSuite] in `platform_helpers.dart`.
/// [RunnerSuite.onDebugging]. The plugin must create this suite by calling the
/// [deserializeSuite] helper function.
///
/// A platform plugin can be registered with [Loader.registerPlatformPlugin].
abstract class PlatformPlugin {
Expand Down Expand Up @@ -52,16 +52,16 @@ abstract class PlatformPlugin {
/// fine-grained control over the [RunnerSuite], including providing a custom
/// implementation of [Environment].
///
/// It's recommended that subclasses overriding this method call
/// [deserializeSuite] in `platform_helpers.dart` to obtain a
/// [RunnerSuiteController].
/// Subclasses overriding this method must call [deserializeSuite] in
/// `platform_helpers.dart` to obtain a [RunnerSuiteController]. They must
/// pass the opaque [message] parameter to the [deserializeSuite] call.
Future<RunnerSuite> load(String path, TestPlatform platform,
SuiteConfiguration suiteConfig) async {
SuiteConfiguration suiteConfig, Object message) async {
// loadChannel may throw an exception. That's fine; it will cause the
// LoadSuite to emit an error, which will be presented to the user.
var channel = loadChannel(path, platform);
var controller = await deserializeSuite(
path, platform, suiteConfig, new PluginEnvironment(), channel);
path, platform, suiteConfig, new PluginEnvironment(), channel, message);
return controller.suite;
}

Expand Down
13 changes: 7 additions & 6 deletions lib/src/runner/plugin/platform_helpers.dart
Original file line number Diff line number Diff line change
Expand Up @@ -33,18 +33,19 @@ final _deserializeTimeout = new Duration(minutes: 8);
///
/// If the suite is closed, this will close [channel].
///
/// If [mapTrace] is passed, it will be used to adjust stack traces for any
/// errors emitted by tests.
/// The [message] parameter is an opaque object passed from the runner to
/// [PlatformPlugin.load]. Plugins shouldn't interact with it other than to pass
/// it on to [deserializeSuite].
///
/// If [asciiSymbols] is passed, it controls whether the `symbol` package is
/// configured to use plain ASCII or Unicode symbols. It defaults to `true` on
/// Windows and `false` elsewhere.
/// If [mapper] is passed, it will be used to adjust stack traces for any errors
/// emitted by tests.
Future<RunnerSuiteController> deserializeSuite(
String path,
TestPlatform platform,
SuiteConfiguration suiteConfig,
Environment environment,
StreamChannel channel,
Object message,
{StackTraceMapper mapper}) async {
var disconnector = new Disconnector();
var suiteChannel = new MultiChannel(channel.transform(disconnector));
Expand All @@ -60,7 +61,7 @@ Future<RunnerSuiteController> deserializeSuite(
'stackTraceMapper': mapper?.serialize(),
'foldTraceExcept': Configuration.current.foldTraceExcept.toList(),
'foldTraceOnly': Configuration.current.foldTraceOnly.toList(),
});
}..addAll(message as Map));

var completer = new Completer();

Expand Down
5 changes: 4 additions & 1 deletion lib/src/runner/remote_listener.dart
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,10 @@ class RemoteListener {
if (message['asciiGlyphs'] ?? false) glyph.ascii = true;
var metadata = new Metadata.deserialize(message['metadata']);
verboseChain = metadata.verboseTrace;
var declarer = new Declarer(TestPlatform.all,
var declarer = new Declarer(
message['testPlatforms']
.map((platform) => new TestPlatform.deserialize(platform))
.toList(),
metadata: metadata,
collectTraces: message['collectTraces'],
noRetry: message['noRetry']);
Expand Down