android_device_discovery_test.dart 8.31 KB
Newer Older
1 2 3 4
// Copyright 2014 The Flutter 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
import 'package:file/memory.dart';
6 7 8 9
import 'package:flutter_tools/src/android/android_device_discovery.dart';
import 'package:flutter_tools/src/android/android_sdk.dart';
import 'package:flutter_tools/src/android/android_workflow.dart';
import 'package:flutter_tools/src/base/logger.dart';
10
import 'package:flutter_tools/src/base/platform.dart';
11
import 'package:flutter_tools/src/base/user_messages.dart';
12
import 'package:flutter_tools/src/device.dart';
13
import 'package:test/fake.dart';
14 15

import '../../src/common.dart';
16
import '../../src/fake_process_manager.dart';
17
import '../../src/fakes.dart';
18 19

void main() {
20
  late AndroidWorkflow androidWorkflow;
21 22 23 24 25

  setUp(() {
    androidWorkflow = AndroidWorkflow(
      androidSdk: FakeAndroidSdk(),
      featureFlags: TestFeatureFlags(),
26
      operatingSystemUtils: FakeOperatingSystemUtils(),
27 28 29
    );
  });

30
  testWithoutContext('AndroidDevices returns empty device list and diagnostics on null adb', () async {
31
    final AndroidDevices androidDevices = AndroidDevices(
32
      androidSdk: FakeAndroidSdk(null),
33
      logger: BufferLogger.test(),
34
      androidWorkflow: AndroidWorkflow(
35
        androidSdk: FakeAndroidSdk(null),
36
        featureFlags: TestFeatureFlags(),
37
        operatingSystemUtils: FakeOperatingSystemUtils(),
38
      ),
39
      processManager: FakeProcessManager.empty(),
40 41
      fileSystem: MemoryFileSystem.test(),
      platform: FakePlatform(),
42
      userMessages: UserMessages(),
43 44 45
    );

    expect(await androidDevices.pollingGetDevices(), isEmpty);
46 47 48
    expect(await androidDevices.getDiagnostics(), isEmpty);
  });

49
  testWithoutContext('AndroidDevices returns empty device list and diagnostics when adb cannot be run', () async {
50
    final FakeProcessManager fakeProcessManager = FakeProcessManager.empty();
51
    fakeProcessManager.excludedExecutables.add('adb');
52
    final AndroidDevices androidDevices = AndroidDevices(
53
      androidSdk: FakeAndroidSdk(),
54 55
      logger: BufferLogger.test(),
      androidWorkflow: AndroidWorkflow(
56
        androidSdk: FakeAndroidSdk(),
57
        featureFlags: TestFeatureFlags(),
58
        operatingSystemUtils: FakeOperatingSystemUtils(),
59
      ),
60
      processManager: fakeProcessManager,
61 62 63 64 65 66 67
      fileSystem: MemoryFileSystem.test(),
      platform: FakePlatform(),
      userMessages: UserMessages(),
    );

    expect(await androidDevices.pollingGetDevices(), isEmpty);
    expect(await androidDevices.getDiagnostics(), isEmpty);
68
    expect(fakeProcessManager, hasNoRemainingExpectations);
69 70
  });

71 72 73 74
  testWithoutContext('AndroidDevices returns empty device list and diagnostics on null Android SDK', () async {
    final AndroidDevices androidDevices = AndroidDevices(
      logger: BufferLogger.test(),
      androidWorkflow: AndroidWorkflow(
75
        androidSdk: FakeAndroidSdk(null),
76
        featureFlags: TestFeatureFlags(),
77
        operatingSystemUtils: FakeOperatingSystemUtils(),
78
      ),
79
      processManager: FakeProcessManager.empty(),
80 81
      fileSystem: MemoryFileSystem.test(),
      platform: FakePlatform(),
82
      userMessages: UserMessages(),
83 84 85 86 87
    );

    expect(await androidDevices.pollingGetDevices(), isEmpty);
    expect(await androidDevices.getDiagnostics(), isEmpty);
  });
88 89 90 91 92 93

  testWithoutContext('AndroidDevices throwsToolExit on failing adb', () {
    final ProcessManager processManager = FakeProcessManager.list(<FakeCommand>[
      const FakeCommand(
        command: <String>['adb', 'devices', '-l'],
        exitCode: 1,
94
      ),
95 96
    ]);
    final AndroidDevices androidDevices = AndroidDevices(
97
      androidSdk: FakeAndroidSdk(),
98
      logger: BufferLogger.test(),
99
      androidWorkflow: androidWorkflow,
100
      processManager: processManager,
101 102
      fileSystem: MemoryFileSystem.test(),
      platform: FakePlatform(),
103
      userMessages: UserMessages(),
104 105 106 107 108 109
    );

    expect(androidDevices.pollingGetDevices(),
      throwsToolExit(message: RegExp('Unable to run "adb"')));
  });

110 111
  testWithoutContext('AndroidDevices is disabled if feature is disabled', () {
    final AndroidDevices androidDevices = AndroidDevices(
112
      androidSdk: FakeAndroidSdk(),
113 114
      logger: BufferLogger.test(),
      androidWorkflow: AndroidWorkflow(
115
        androidSdk: FakeAndroidSdk(),
116 117 118
        featureFlags: TestFeatureFlags(
          isAndroidEnabled: false,
        ),
119
        operatingSystemUtils: FakeOperatingSystemUtils(),
120 121
      ),
      processManager: FakeProcessManager.any(),
122 123
      fileSystem: MemoryFileSystem.test(),
      platform: FakePlatform(),
124
      userMessages: UserMessages(),
125 126 127 128 129
    );

    expect(androidDevices.supportsPlatform, false);
  });

130 131 132 133 134 135 136 137 138 139
  testWithoutContext('AndroidDevices can parse output for physical devices', () async {
    final AndroidDevices androidDevices = AndroidDevices(
      userMessages: UserMessages(),
      androidWorkflow: androidWorkflow,
      androidSdk: FakeAndroidSdk(),
      logger: BufferLogger.test(),
      processManager: FakeProcessManager.list(<FakeCommand>[
        const FakeCommand(
          command: <String>['adb', 'devices', '-l'],
          stdout: '''
140 141 142
List of devices attached
05a02bac               device usb:336592896X product:razor model:Nexus_7 device:flo

143
  ''',
144
        ),
145 146 147 148 149 150
      ]),
      platform: FakePlatform(),
      fileSystem: MemoryFileSystem.test(),
    );

    final List<Device> devices = await androidDevices.pollingGetDevices();
151 152 153 154 155 156

    expect(devices, hasLength(1));
    expect(devices.first.name, 'Nexus 7');
    expect(devices.first.category, Category.mobile);
  });

157 158 159 160 161 162 163 164 165 166
  testWithoutContext('AndroidDevices can parse output for emulators and short listings', () async {
    final AndroidDevices androidDevices = AndroidDevices(
      userMessages: UserMessages(),
      androidWorkflow: androidWorkflow,
      androidSdk: FakeAndroidSdk(),
      logger: BufferLogger.test(),
      processManager: FakeProcessManager.list(<FakeCommand>[
        const FakeCommand(
          command: <String>['adb', 'devices', '-l'],
          stdout: '''
167 168 169 170 171
List of devices attached
localhost:36790        device
0149947A0D01500C       device usb:340787200X
emulator-5612          host features:shell_2

172
  ''',
173
        ),
174 175 176 177 178 179
      ]),
      platform: FakePlatform(),
      fileSystem: MemoryFileSystem.test(),
    );

    final List<Device> devices = await androidDevices.pollingGetDevices();
180 181

    expect(devices, hasLength(3));
182 183 184
    expect(devices[0].name, 'localhost:36790');
    expect(devices[1].name, '0149947A0D01500C');
    expect(devices[2].name, 'emulator-5612');
185 186
  });

187 188 189 190 191 192 193 194 195 196
  testWithoutContext('AndroidDevices can parse output from android n', () async {
    final AndroidDevices androidDevices = AndroidDevices(
      userMessages: UserMessages(),
      androidWorkflow: androidWorkflow,
      androidSdk: FakeAndroidSdk(),
      logger: BufferLogger.test(),
      processManager: FakeProcessManager.list(<FakeCommand>[
        const FakeCommand(
          command: <String>['adb', 'devices', '-l'],
          stdout: '''
197 198
List of devices attached
ZX1G22JJWR             device usb:3-3 product:shamu model:Nexus_6 device:shamu features:cmd,shell_v2
199

200
''',
201
        ),
202 203 204 205 206 207
      ]),
      platform: FakePlatform(),
      fileSystem: MemoryFileSystem.test(),
    );

    final List<Device> devices = await androidDevices.pollingGetDevices();
208 209 210 211 212

    expect(devices, hasLength(1));
    expect(devices.first.name, 'Nexus 6');
  });

213 214 215 216 217 218 219 220 221 222
  testWithoutContext('AndroidDevices provides adb error message as diagnostics', () async {
    final AndroidDevices androidDevices = AndroidDevices(
      userMessages: UserMessages(),
      androidWorkflow: androidWorkflow,
      androidSdk: FakeAndroidSdk(),
      logger: BufferLogger.test(),
      processManager: FakeProcessManager.list(<FakeCommand>[
        const FakeCommand(
          command: <String>['adb', 'devices', '-l'],
          stdout: '''
223 224 225
It appears you do not have 'Android SDK Platform-tools' installed.
Use the 'android' tool to install them:
  android update sdk --no-ui --filter 'platform-tools'
226
''',
227
        ),
228 229 230
      ]),
      platform: FakePlatform(),
      fileSystem: MemoryFileSystem.test(),
231
    );
232

233 234
    final List<String> diagnostics = await androidDevices.getDiagnostics();

235 236 237 238 239
    expect(diagnostics, hasLength(1));
    expect(diagnostics.first, contains('you do not have'));
  });
}

240 241
class FakeAndroidSdk extends Fake implements AndroidSdk {
  FakeAndroidSdk([this.adbPath = 'adb']);
242 243

  @override
244
  final String? adbPath;
245
}