remote_test.dart 3.26 KB
Newer Older
1 2 3 4
// 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.

5 6
import 'dart:async';

Hixie's avatar
Hixie committed
7
import 'package:stack_trace/stack_trace.dart';
8
import 'package:test/src/backend/group.dart';
9 10 11
import 'package:test/src/backend/live_test.dart';
import 'package:test/src/backend/live_test_controller.dart';
import 'package:test/src/backend/metadata.dart';
12
import 'package:test/src/backend/operating_system.dart';
13 14 15
import 'package:test/src/backend/state.dart';
import 'package:test/src/backend/suite.dart';
import 'package:test/src/backend/test.dart';
16
import 'package:test/src/backend/test_platform.dart';
17 18
import 'package:test/src/util/remote_exception.dart';

19
import 'json_socket.dart';
20

21
class RemoteTest extends Test {
22 23
  RemoteTest(this.name, this.metadata, this._socket, this._index);

24 25
  final String name;
  final Metadata metadata;
26
  final JSONSocket _socket;
27 28
  final int _index;

29
  LiveTest load(Suite suite, { Iterable<Group> groups }) {
30 31
    LiveTestController controller;
    StreamSubscription subscription;
32

33
    controller = new LiveTestController(suite, this, () async {
34

Hixie's avatar
Hixie committed
35
      controller.setState(const State(Status.running, Result.success));
36
      _socket.send({'command': 'run', 'index': _index});
37

38
      subscription = _socket.stream.listen((message) {
39
        if (message['type'] == 'error') {
40
          AsyncError asyncError = RemoteException.deserialize(message['error']);
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
          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();
        }
      });
Hixie's avatar
Hixie committed
56

Hixie's avatar
Hixie committed
57
      _socket.unusualTermination.then((String message) {
Hixie's avatar
Hixie committed
58
        if (subscription != null) {
Hixie's avatar
Hixie committed
59
          controller.print('Unexpected subprocess termination: $message');
Hixie's avatar
Hixie committed
60 61 62 63 64 65 66 67
          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();
        }
      });

68
    }, () async {
69
      _socket.send({'command': 'close'});
70 71 72 73
      if (subscription != null) {
        subscription.cancel();
        subscription = null;
      }
74
    }, groups: groups);
75 76 77 78 79 80 81 82 83
    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);
  }
84 85 86

  // TODO(ianh): Implement this if we need it.
  Test forPlatform(TestPlatform platform, {OperatingSystem os}) {
87 88 89 90 91 92 93 94 95
    if (!metadata.testOn.evaluate(platform, os: os))
      return null;
    return new RemoteTest(
      name,
      metadata.forPlatform(platform, os: os),
      _socket,
      _index
    );
  }
96
}