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); |
+ } |
+ } |
+} |