OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. |
| 4 |
| 5 import 'dart:async'; |
| 6 import 'dart:isolate'; |
| 7 |
| 8 import 'package:path/path.dart' as p; |
| 9 import 'package:stream_channel/stream_channel.dart'; |
| 10 |
| 11 import '../../backend/test_platform.dart'; |
| 12 import '../../util/dart.dart' as dart; |
| 13 import '../configuration.dart'; |
| 14 import '../load_exception.dart'; |
| 15 import '../plugin/platform.dart'; |
| 16 |
| 17 /// A platform that loads tests in isolates spawned within this Dart process. |
| 18 class VMPlatform extends PlatformPlugin { |
| 19 final platforms = [TestPlatform.vm]; |
| 20 |
| 21 /// The test runner configuration. |
| 22 final Configuration _config; |
| 23 |
| 24 VMPlatform(this._config); |
| 25 |
| 26 StreamChannel loadChannel(String path, TestPlatform platform) { |
| 27 assert(platform == TestPlatform.vm); |
| 28 |
| 29 var isolate; |
| 30 var channel = StreamChannelCompleter.fromFuture(() async { |
| 31 var receivePort = new ReceivePort(); |
| 32 |
| 33 try { |
| 34 isolate = await _spawnIsolate(path, receivePort.sendPort); |
| 35 } catch (error) { |
| 36 receivePort.close(); |
| 37 rethrow; |
| 38 } |
| 39 |
| 40 return new IsolateChannel.connectReceive(receivePort); |
| 41 }()); |
| 42 |
| 43 // Once the connection is closed by either end, kill the isolate. |
| 44 return channel.transformStream( |
| 45 new StreamTransformer.fromHandlers(handleDone: (sink) { |
| 46 if (isolate != null) isolate.kill(); |
| 47 sink.close(); |
| 48 })); |
| 49 } |
| 50 |
| 51 /// Spawns an isolate and passes it [message]. |
| 52 /// |
| 53 /// This isolate connects an [IsolateChannel] to [message] and sends the |
| 54 /// serialized tests over that channel. |
| 55 Future<Isolate> _spawnIsolate(String path, SendPort message) async { |
| 56 if (_config.pubServeUrl == null) { |
| 57 return await dart.runInIsolate(''' |
| 58 import "dart:isolate"; |
| 59 |
| 60 import "package:stream_channel/stream_channel.dart"; |
| 61 |
| 62 import "package:test/src/runner/plugin/remote_platform_helpers.dart"; |
| 63 import "package:test/src/runner/vm/catch_isolate_errors.dart"; |
| 64 |
| 65 import "${p.toUri(p.absolute(path))}" as test; |
| 66 |
| 67 void main(_, SendPort message) { |
| 68 var channel = serializeSuite(() { |
| 69 catchIsolateErrors(); |
| 70 return test.main; |
| 71 }); |
| 72 new IsolateChannel.connectSend(message).pipe(channel); |
| 73 } |
| 74 ''', message, packageRoot: p.toUri(_config.packageRoot), checked: true); |
| 75 } |
| 76 |
| 77 var url = _config.pubServeUrl.resolveUri( |
| 78 p.toUri(p.relative(path, from: 'test') + '.vm_test.dart')); |
| 79 |
| 80 try { |
| 81 return await Isolate.spawnUri(url, [], message, checked: true); |
| 82 } on IsolateSpawnException catch (error) { |
| 83 if (error.message.contains("OS Error: Connection refused") || |
| 84 error.message.contains("The remote computer refused")) { |
| 85 throw new LoadException(path, |
| 86 "Error getting $url: Connection refused\n" |
| 87 'Make sure "pub serve" is running.'); |
| 88 } else if (error.message.contains("404 Not Found")) { |
| 89 throw new LoadException(path, |
| 90 "Error getting $url: 404 Not Found\n" |
| 91 'Make sure "pub serve" is serving the test/ directory.'); |
| 92 } |
| 93 |
| 94 throw new LoadException(path, error); |
| 95 } |
| 96 } |
| 97 } |
OLD | NEW |