fuchsia_remote_connection_test.dart 5.92 KB
Newer Older
Ian Hickson's avatar
Ian Hickson committed
1
// Copyright 2014 The Flutter Authors. All rights reserved.
2 3 4 5 6 7 8 9 10 11
// 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:mockito/mockito.dart';
import 'package:json_rpc_2/json_rpc_2.dart' as json_rpc;

import 'package:fuchsia_remote_debug_protocol/fuchsia_remote_debug_protocol.dart';

12 13
import 'common.dart';

14 15 16
void main() {
  group('FuchsiaRemoteConnection.connect', () {
    MockSshCommandRunner mockRunner;
17 18 19
    List<MockPortForwarder> forwardedPorts;
    List<MockPeer> mockPeerConnections;
    List<Uri> uriConnections;
20 21

    setUp(() {
22
      mockRunner = MockSshCommandRunner();
23
      // Adds some extra junk to make sure the strings will be cleaned up.
24
      when(mockRunner.run(argThat(startsWith('/bin/find')))).thenAnswer(
25 26
          (_) => Future<List<String>>.value(
              <String>['/hub/blah/blah/blah/vmservice-port\n']));
27
      when(mockRunner.run(argThat(startsWith('/bin/ls')))).thenAnswer(
28 29
          (_) => Future<List<String>>.value(
              <String>['123\n\n\n', '456  ', '789']));
30 31
      const String address = 'fe80::8eae:4cff:fef4:9247';
      const String interface = 'eno1';
32 33
      when(mockRunner.address).thenReturn(address);
      when(mockRunner.interface).thenReturn(interface);
34
      forwardedPorts = <MockPortForwarder>[];
35 36
      int port = 0;
      Future<PortForwarder> mockPortForwardingFunction(
37 38 39 40 41
        String address,
        int remotePort, [
        String interface = '',
        String configFile,
      ]) {
42 43
        return Future<PortForwarder>(() {
          final MockPortForwarder pf = MockPortForwarder();
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
          forwardedPorts.add(pf);
          when(pf.port).thenReturn(port++);
          when(pf.remotePort).thenReturn(remotePort);
          return pf;
        });
      }

      final List<Map<String, dynamic>> flutterViewCannedResponses =
          <Map<String, dynamic>>[
        <String, dynamic>{
          'views': <Map<String, dynamic>>[
            <String, dynamic>{
              'type': 'FlutterView',
              'id': 'flutterView0',
            },
          ],
        },
        <String, dynamic>{
          'views': <Map<String, dynamic>>[
            <String, dynamic>{
              'type': 'FlutterView',
              'id': 'flutterView1',
              'isolate': <String, dynamic>{
                'type': '@Isolate',
                'fixedId': 'true',
                'id': 'isolates/1',
                'name': 'file://flutterBinary1',
                'number': '1',
              },
73
            },
74 75 76 77 78 79 80 81 82 83 84 85 86 87
          ],
        },
        <String, dynamic>{
          'views': <Map<String, dynamic>>[
            <String, dynamic>{
              'type': 'FlutterView',
              'id': 'flutterView2',
              'isolate': <String, dynamic>{
                'type': '@Isolate',
                'fixedId': 'true',
                'id': 'isolates/2',
                'name': 'file://flutterBinary2',
                'number': '2',
              },
88
            },
89 90 91 92
          ],
        },
      ];

93 94
      mockPeerConnections = <MockPeer>[];
      uriConnections = <Uri>[];
95 96 97 98
      Future<json_rpc.Peer> mockVmConnectionFunction(
        Uri uri, {
        Duration timeout,
      }) {
99 100
        return Future<json_rpc.Peer>(() async {
          final MockPeer mp = MockPeer();
101 102
          mockPeerConnections.add(mp);
          uriConnections.add(uri);
103
          when(mp.sendRequest(any, any))
104 105
              // The local ports match the desired indices for now, so get the
              // canned response from the URI port.
106
              .thenAnswer((_) => Future<Map<String, dynamic>>(
107
                  () => flutterViewCannedResponses[uri.port]));
108 109 110 111 112 113
          return mp;
        });
      }

      fuchsiaPortForwardingFunction = mockPortForwardingFunction;
      fuchsiaVmServiceConnectionFunction = mockVmConnectionFunction;
114 115 116 117 118 119 120 121
    });

    tearDown(() {
      /// Most tests will mock out the port forwarding and connection
      /// functions.
      restoreFuchsiaPortForwardingFunction();
      restoreVmServiceConnectionFunction();
    });
122

123
    test('end-to-end with three vm connections and flutter view query', () async {
124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155
      final FuchsiaRemoteConnection connection =
          await FuchsiaRemoteConnection.connectWithSshCommandRunner(mockRunner);

      // [mockPortForwardingFunction] will have returned three different
      // forwarded ports, incrementing the port each time by one. (Just a sanity
      // check that the forwarding port was called).
      expect(forwardedPorts.length, 3);
      expect(forwardedPorts[0].remotePort, 123);
      expect(forwardedPorts[1].remotePort, 456);
      expect(forwardedPorts[2].remotePort, 789);
      expect(forwardedPorts[0].port, 0);
      expect(forwardedPorts[1].port, 1);
      expect(forwardedPorts[2].port, 2);

      final List<FlutterView> views = await connection.getFlutterViews();
      expect(views, isNot(null));
      expect(views.length, 3);
      // Since name can be null, check for the ID on all of them.
      expect(views[0].id, 'flutterView0');
      expect(views[1].id, 'flutterView1');
      expect(views[2].id, 'flutterView2');

      expect(views[0].name, equals(null));
      expect(views[1].name, 'file://flutterBinary1');
      expect(views[2].name, 'file://flutterBinary2');

      // Ensure the ports are all closed after stop was called.
      await connection.stop();
      verify(forwardedPorts[0].stop());
      verify(forwardedPorts[1].stop());
      verify(forwardedPorts[2].stop());
    });
156 157

    test('env variable test without remote addr', () async {
158
      Future<void> failingFunction() async {
159 160 161 162 163
        await FuchsiaRemoteConnection.connect();
      }

      // Should fail as no env variable has been passed.
      expect(failingFunction,
Dan Field's avatar
Dan Field committed
164
          throwsA(isA<FuchsiaRemoteConnectionError>()));
165
    });
166 167 168 169 170 171 172 173
  });
}

class MockSshCommandRunner extends Mock implements SshCommandRunner {}

class MockPortForwarder extends Mock implements PortForwarder {}

class MockPeer extends Mock implements json_rpc.Peer {}