| Index: lib/src/runner/vm/platform.dart
|
| diff --git a/lib/src/runner/vm/platform.dart b/lib/src/runner/vm/platform.dart
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..d6ab6ef0ad7b5aa7bafc4ee82af657c2e682b8c3
|
| --- /dev/null
|
| +++ b/lib/src/runner/vm/platform.dart
|
| @@ -0,0 +1,97 @@
|
| +// Copyright (c) 2016, 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:isolate';
|
| +
|
| +import 'package:path/path.dart' as p;
|
| +import 'package:stream_channel/stream_channel.dart';
|
| +
|
| +import '../../backend/test_platform.dart';
|
| +import '../../util/dart.dart' as dart;
|
| +import '../configuration.dart';
|
| +import '../load_exception.dart';
|
| +import '../plugin/platform.dart';
|
| +
|
| +/// A platform that loads tests in isolates spawned within this Dart process.
|
| +class VMPlatform extends PlatformPlugin {
|
| + final platforms = [TestPlatform.vm];
|
| +
|
| + /// The test runner configuration.
|
| + final Configuration _config;
|
| +
|
| + VMPlatform(this._config);
|
| +
|
| + StreamChannel loadChannel(String path, TestPlatform platform) {
|
| + assert(platform == TestPlatform.vm);
|
| +
|
| + var isolate;
|
| + var channel = StreamChannelCompleter.fromFuture(() async {
|
| + var receivePort = new ReceivePort();
|
| +
|
| + try {
|
| + isolate = await _spawnIsolate(path, receivePort.sendPort);
|
| + } catch (error) {
|
| + receivePort.close();
|
| + rethrow;
|
| + }
|
| +
|
| + return new IsolateChannel.connectReceive(receivePort);
|
| + }());
|
| +
|
| + // Once the connection is closed by either end, kill the isolate.
|
| + return channel.transformStream(
|
| + new StreamTransformer.fromHandlers(handleDone: (sink) {
|
| + if (isolate != null) isolate.kill();
|
| + sink.close();
|
| + }));
|
| + }
|
| +
|
| + /// Spawns an isolate and passes it [message].
|
| + ///
|
| + /// This isolate connects an [IsolateChannel] to [message] and sends the
|
| + /// serialized tests over that channel.
|
| + Future<Isolate> _spawnIsolate(String path, SendPort message) async {
|
| + if (_config.pubServeUrl == null) {
|
| + return await dart.runInIsolate('''
|
| + import "dart:isolate";
|
| +
|
| + import "package:stream_channel/stream_channel.dart";
|
| +
|
| + import "package:test/src/runner/plugin/remote_platform_helpers.dart";
|
| + import "package:test/src/runner/vm/catch_isolate_errors.dart";
|
| +
|
| + import "${p.toUri(p.absolute(path))}" as test;
|
| +
|
| + void main(_, SendPort message) {
|
| + var channel = serializeSuite(() {
|
| + catchIsolateErrors();
|
| + return test.main;
|
| + });
|
| + new IsolateChannel.connectSend(message).pipe(channel);
|
| + }
|
| + ''', message, packageRoot: p.toUri(_config.packageRoot), checked: true);
|
| + }
|
| +
|
| + var url = _config.pubServeUrl.resolveUri(
|
| + p.toUri(p.relative(path, from: 'test') + '.vm_test.dart'));
|
| +
|
| + try {
|
| + return await Isolate.spawnUri(url, [], message, checked: true);
|
| + } on IsolateSpawnException catch (error) {
|
| + if (error.message.contains("OS Error: Connection refused") ||
|
| + error.message.contains("The remote computer refused")) {
|
| + throw new LoadException(path,
|
| + "Error getting $url: Connection refused\n"
|
| + 'Make sure "pub serve" is running.');
|
| + } else if (error.message.contains("404 Not Found")) {
|
| + throw new LoadException(path,
|
| + "Error getting $url: 404 Not Found\n"
|
| + 'Make sure "pub serve" is serving the test/ directory.');
|
| + }
|
| +
|
| + throw new LoadException(path, error);
|
| + }
|
| + }
|
| +}
|
|
|