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; | 38 var closeCompleter = new Completer(); |
kevmoo
2015/04/03 00:49:45
Is this used?
nweiz
2015/04/03 20:56:21
Done.
| |
31 controller = new LiveTestController(suite, this, () { | 39 controller = new LiveTestController(suite, this, () { |
32 controller.setState(const State(Status.running, Result.success)); | 40 controller.setState(const State(Status.running, Result.success)); |
33 | 41 |
42 sendPortCompleter = new Completer(); | |
34 receivePort = new ReceivePort(); | 43 receivePort = new ReceivePort(); |
35 _sendPort.send({ | 44 _sendPort.send({ |
36 'command': 'run', | 45 'command': 'run', |
37 'reply': receivePort.sendPort | 46 'reply': receivePort.sendPort |
38 }); | 47 }); |
39 | 48 |
40 receivePort.listen((message) { | 49 receivePort.listen((message) { |
41 if (message['type'] == 'error') { | 50 if (message['type'] == 'started') { |
51 sendPortCompleter.complete(message['reply']); | |
52 } else if (message['type'] == 'error') { | |
42 var asyncError = RemoteException.deserialize(message['error']); | 53 var asyncError = RemoteException.deserialize(message['error']); |
43 controller.addError(asyncError.error, asyncError.stackTrace); | 54 controller.addError(asyncError.error, asyncError.stackTrace); |
44 } else if (message['type'] == 'state-change') { | 55 } else if (message['type'] == 'state-change') { |
45 controller.setState( | 56 controller.setState( |
46 new State( | 57 new State( |
47 new Status.parse(message['status']), | 58 new Status.parse(message['status']), |
48 new Result.parse(message['result']))); | 59 new Result.parse(message['result']))); |
49 } else if (message['type'] == 'print') { | 60 } else if (message['type'] == 'print') { |
50 controller.print(message['line']); | 61 controller.print(message['line']); |
51 } else { | 62 } else { |
52 assert(message['type'] == 'complete'); | 63 assert(message['type'] == 'complete'); |
53 controller.completer.complete(); | 64 controller.completer.complete(); |
54 } | 65 } |
55 }); | 66 }); |
56 }, onClose: () { | 67 }, () { |
57 if (receivePort != null) receivePort.close(); | 68 // If the test has finished running, just disconnect the receive port. The |
69 // Dart process won't terminate if there are any live receive ports open. | |
70 if (controller.completer.isCompleted) { | |
71 receivePort.close(); | |
72 return; | |
73 } | |
74 | |
75 // If the test is still running, send it a message telling it to shut down | |
76 // ASAP. This causes the [Invoker] to eagerly throw exceptions whenever | |
77 // the test touches it. | |
78 sendPortCompleter.future.then((sendPort) { | |
79 sendPort.send({'command': 'close'}); | |
80 return controller.completer.future; | |
81 }).then((_) => receivePort.close()); | |
58 }); | 82 }); |
59 return controller.liveTest; | 83 return controller.liveTest; |
60 } | 84 } |
61 } | 85 } |
OLD | NEW |