| OLD | NEW |
| 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 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. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 library test.runner.vm.isolate_test; | 5 library test.runner.vm.isolate_test; |
| 6 | 6 |
| 7 import 'dart:async'; |
| 7 import 'dart:isolate'; | 8 import 'dart:isolate'; |
| 8 | 9 |
| 9 import '../../backend/live_test.dart'; | 10 import '../../backend/live_test.dart'; |
| 10 import '../../backend/live_test_controller.dart'; | 11 import '../../backend/live_test_controller.dart'; |
| 11 import '../../backend/metadata.dart'; | 12 import '../../backend/metadata.dart'; |
| 12 import '../../backend/state.dart'; | 13 import '../../backend/state.dart'; |
| 13 import '../../backend/suite.dart'; | 14 import '../../backend/suite.dart'; |
| 14 import '../../backend/test.dart'; | 15 import '../../backend/test.dart'; |
| 15 import '../../util/remote_exception.dart'; | 16 import '../../util/remote_exception.dart'; |
| 16 | 17 |
| 17 /// A test in another isolate. | 18 /// A test in another isolate. |
| 18 class IsolateTest implements Test { | 19 class IsolateTest implements Test { |
| 19 final String name; | 20 final String name; |
| 20 final Metadata metadata; | 21 final Metadata metadata; |
| 21 | 22 |
| 22 /// The port on which to communicate with the remote test. | 23 /// The port on which to communicate with the remote test. |
| 23 final SendPort _sendPort; | 24 final SendPort _sendPort; |
| 24 | 25 |
| 25 IsolateTest(this.name, this.metadata, this._sendPort); | 26 IsolateTest(this.name, this.metadata, this._sendPort); |
| 26 | 27 |
| 27 /// Loads a single runnable instance of this test. | 28 /// Loads a single runnable instance of this test. |
| 28 LiveTest load(Suite suite) { | 29 LiveTest load(Suite suite) { |
| 30 var controller; |
| 31 |
| 32 // We get a new send port for communicating with the live test, since |
| 33 // [_sendPort] is only for communicating with the non-live test. This will |
| 34 // be non-null once the test starts running. |
| 35 var sendPortCompleter; |
| 36 |
| 29 var receivePort; | 37 var receivePort; |
| 30 var controller; | |
| 31 controller = new LiveTestController(suite, this, () { | 38 controller = new LiveTestController(suite, this, () { |
| 32 controller.setState(const State(Status.running, Result.success)); | 39 controller.setState(const State(Status.running, Result.success)); |
| 33 | 40 |
| 41 sendPortCompleter = new Completer(); |
| 34 receivePort = new ReceivePort(); | 42 receivePort = new ReceivePort(); |
| 35 _sendPort.send({ | 43 _sendPort.send({ |
| 36 'command': 'run', | 44 'command': 'run', |
| 37 'reply': receivePort.sendPort | 45 'reply': receivePort.sendPort |
| 38 }); | 46 }); |
| 39 | 47 |
| 40 receivePort.listen((message) { | 48 receivePort.listen((message) { |
| 41 if (message['type'] == 'error') { | 49 if (message['type'] == 'started') { |
| 50 sendPortCompleter.complete(message['reply']); |
| 51 } else if (message['type'] == 'error') { |
| 42 var asyncError = RemoteException.deserialize(message['error']); | 52 var asyncError = RemoteException.deserialize(message['error']); |
| 43 controller.addError(asyncError.error, asyncError.stackTrace); | 53 controller.addError(asyncError.error, asyncError.stackTrace); |
| 44 } else if (message['type'] == 'state-change') { | 54 } else if (message['type'] == 'state-change') { |
| 45 controller.setState( | 55 controller.setState( |
| 46 new State( | 56 new State( |
| 47 new Status.parse(message['status']), | 57 new Status.parse(message['status']), |
| 48 new Result.parse(message['result']))); | 58 new Result.parse(message['result']))); |
| 49 } else if (message['type'] == 'print') { | 59 } else if (message['type'] == 'print') { |
| 50 controller.print(message['line']); | 60 controller.print(message['line']); |
| 51 } else { | 61 } else { |
| 52 assert(message['type'] == 'complete'); | 62 assert(message['type'] == 'complete'); |
| 53 controller.completer.complete(); | 63 controller.completer.complete(); |
| 54 } | 64 } |
| 55 }); | 65 }); |
| 56 }, onClose: () { | 66 }, () { |
| 57 if (receivePort != null) receivePort.close(); | 67 // If the test has finished running, just disconnect the receive port. The |
| 68 // Dart process won't terminate if there are any live receive ports open. |
| 69 if (controller.completer.isCompleted) { |
| 70 receivePort.close(); |
| 71 return; |
| 72 } |
| 73 |
| 74 // If the test is still running, send it a message telling it to shut down |
| 75 // ASAP. This causes the [Invoker] to eagerly throw exceptions whenever |
| 76 // the test touches it. |
| 77 sendPortCompleter.future.then((sendPort) { |
| 78 sendPort.send({'command': 'close'}); |
| 79 return controller.completer.future; |
| 80 }).then((_) => receivePort.close()); |
| 58 }); | 81 }); |
| 59 return controller.liveTest; | 82 return controller.liveTest; |
| 60 } | 83 } |
| 61 } | 84 } |
| OLD | NEW |