| // Copyright 2015 The Chromium Authors. 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 'package:stack_trace/stack_trace.dart'; |
| import 'package:test/src/backend/group.dart'; |
| import 'package:test/src/backend/live_test.dart'; |
| import 'package:test/src/backend/live_test_controller.dart'; |
| import 'package:test/src/backend/metadata.dart'; |
| import 'package:test/src/backend/operating_system.dart'; |
| import 'package:test/src/backend/state.dart'; |
| import 'package:test/src/backend/suite.dart'; |
| import 'package:test/src/backend/test.dart'; |
| import 'package:test/src/backend/test_platform.dart'; |
| import 'package:test/src/util/remote_exception.dart'; |
| |
| import 'json_socket.dart'; |
| |
| class RemoteTest extends Test { |
| RemoteTest(this.name, this.metadata, this._socket, this._index); |
| |
| final String name; |
| final Metadata metadata; |
| final JSONSocket _socket; |
| final int _index; |
| |
| LiveTest load(Suite suite, { Iterable<Group> groups }) { |
| LiveTestController controller; |
| StreamSubscription subscription; |
| |
| controller = new LiveTestController(suite, this, () async { |
| |
| controller.setState(const State(Status.running, Result.success)); |
| _socket.send({'command': 'run', 'index': _index}); |
| |
| subscription = _socket.stream.listen((message) { |
| if (message['type'] == 'error') { |
| AsyncError asyncError = RemoteException.deserialize(message['error']); |
| controller.addError(asyncError.error, asyncError.stackTrace); |
| } else if (message['type'] == 'state-change') { |
| controller.setState( |
| new State( |
| new Status.parse(message['status']), |
| new Result.parse(message['result']))); |
| } else if (message['type'] == 'print') { |
| controller.print(message['line']); |
| } else { |
| assert(message['type'] == 'complete'); |
| subscription.cancel(); |
| subscription = null; |
| controller.completer.complete(); |
| } |
| }); |
| |
| _socket.unusualTermination.then((String message) { |
| if (subscription != null) { |
| controller.print('Unexpected subprocess termination: $message'); |
| controller.addError(new Exception('Unexpected subprocess termination.'), new Trace.current()); |
| controller.setState(new State(Status.complete, Result.error)); |
| subscription.cancel(); |
| subscription = null; |
| controller.completer.complete(); |
| } |
| }); |
| |
| }, () async { |
| _socket.send({'command': 'close'}); |
| if (subscription != null) { |
| subscription.cancel(); |
| subscription = null; |
| } |
| }, groups: groups); |
| return controller.liveTest; |
| } |
| |
| Test change({String name, Metadata metadata}) { |
| if (name == name && metadata == this.metadata) return this; |
| if (name == null) name = this.name; |
| if (metadata == null) metadata = this.metadata; |
| return new RemoteTest(name, metadata, _socket, _index); |
| } |
| |
| // TODO(ianh): Implement this if we need it. |
| Test forPlatform(TestPlatform platform, {OperatingSystem os}) { |
| if (!metadata.testOn.evaluate(platform, os: os)) |
| return null; |
| return new RemoteTest( |
| name, |
| metadata.forPlatform(platform, os: os), |
| _socket, |
| _index |
| ); |
| } |
| } |