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