Unverified Commit 757b39ba authored by Jenn Magder's avatar Jenn Magder Committed by GitHub

Ignore fuchsia device-finder no device error (#52761)

parent 071d4eb2
...@@ -2,9 +2,12 @@ ...@@ -2,9 +2,12 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
import 'package:meta/meta.dart';
import 'package:process/process.dart';
import '../base/common.dart'; import '../base/common.dart';
import '../base/logger.dart';
import '../base/process.dart'; import '../base/process.dart';
import '../globals.dart' as globals;
import 'fuchsia_sdk.dart'; import 'fuchsia_sdk.dart';
// Usage: device-finder <flags> <subcommand> <subcommand args> // Usage: device-finder <flags> <subcommand> <subcommand args>
...@@ -19,24 +22,42 @@ import 'fuchsia_sdk.dart'; ...@@ -19,24 +22,42 @@ import 'fuchsia_sdk.dart';
/// A simple wrapper for the Fuchsia SDK's 'device-finder' tool. /// A simple wrapper for the Fuchsia SDK's 'device-finder' tool.
class FuchsiaDevFinder { class FuchsiaDevFinder {
FuchsiaDevFinder({
@required FuchsiaArtifacts fuchsiaArtifacts,
@required Logger logger,
@required ProcessManager processManager,
})
: _fuchsiaArtifacts = fuchsiaArtifacts,
_logger = logger,
_processUtils = ProcessUtils(logger: logger, processManager: processManager);
final FuchsiaArtifacts _fuchsiaArtifacts;
final Logger _logger;
final ProcessUtils _processUtils;
/// Returns a list of attached devices as a list of strings with entries /// Returns a list of attached devices as a list of strings with entries
/// formatted as follows: /// formatted as follows:
/// 192.168.42.172 scare-cable-skip-joy /// 192.168.42.172 scare-cable-skip-joy
Future<List<String>> list({ Duration timeout }) async { Future<List<String>> list({ Duration timeout }) async {
if (fuchsiaArtifacts.devFinder == null || if (_fuchsiaArtifacts.devFinder == null ||
!fuchsiaArtifacts.devFinder.existsSync()) { !_fuchsiaArtifacts.devFinder.existsSync()) {
throwToolExit('Fuchsia device-finder tool not found.'); throwToolExit('Fuchsia device-finder tool not found.');
} }
final List<String> command = <String>[ final List<String> command = <String>[
fuchsiaArtifacts.devFinder.path, _fuchsiaArtifacts.devFinder.path,
'list', 'list',
'-full', '-full',
if (timeout != null) if (timeout != null)
...<String>['-timeout', '${timeout.inMilliseconds}ms'] ...<String>['-timeout', '${timeout.inMilliseconds}ms']
]; ];
final RunResult result = await processUtils.run(command); final RunResult result = await _processUtils.run(command);
if (result.exitCode != 0) { if (result.exitCode != 0) {
globals.printError('device-finder failed: ${result.stderr}'); // No devices returns error code 1.
// https://bugs.fuchsia.dev/p/fuchsia/issues/detail?id=48563
if (!result.stderr.contains('no devices found')) {
_logger.printError('device-finder failed: ${result.stderr}');
}
return null; return null;
} }
return result.stdout.split('\n'); return result.stdout.split('\n');
...@@ -50,20 +71,20 @@ class FuchsiaDevFinder { ...@@ -50,20 +71,20 @@ class FuchsiaDevFinder {
/// The string [deviceName] should be the name of the device from the /// The string [deviceName] should be the name of the device from the
/// 'list' command, e.g. 'scare-cable-skip-joy'. /// 'list' command, e.g. 'scare-cable-skip-joy'.
Future<String> resolve(String deviceName, {bool local = false}) async { Future<String> resolve(String deviceName, {bool local = false}) async {
if (fuchsiaArtifacts.devFinder == null || if (_fuchsiaArtifacts.devFinder == null ||
!fuchsiaArtifacts.devFinder.existsSync()) { !_fuchsiaArtifacts.devFinder.existsSync()) {
throwToolExit('Fuchsia device-finder tool not found.'); throwToolExit('Fuchsia device-finder tool not found.');
} }
final List<String> command = <String>[ final List<String> command = <String>[
fuchsiaArtifacts.devFinder.path, _fuchsiaArtifacts.devFinder.path,
'resolve', 'resolve',
if (local) '-local', if (local) '-local',
'-device-limit', '1', '-device-limit', '1',
deviceName, deviceName,
]; ];
final RunResult result = await processUtils.run(command); final RunResult result = await _processUtils.run(command);
if (result.exitCode != 0) { if (result.exitCode != 0) {
globals.printError('device-finder failed: ${result.stderr}'); _logger.printError('device-finder failed: ${result.stderr}');
return null; return null;
} }
return result.stdout.trim(); return result.stdout.trim();
......
...@@ -558,14 +558,14 @@ class FuchsiaDevice extends Device { ...@@ -558,14 +558,14 @@ class FuchsiaDevice extends Device {
/// Run `command` on the Fuchsia device shell. /// Run `command` on the Fuchsia device shell.
Future<RunResult> shell(String command) async { Future<RunResult> shell(String command) async {
if (fuchsiaArtifacts.sshConfig == null) { if (globals.fuchsiaArtifacts.sshConfig == null) {
throwToolExit('Cannot interact with device. No ssh config.\n' throwToolExit('Cannot interact with device. No ssh config.\n'
'Try setting FUCHSIA_SSH_CONFIG or FUCHSIA_BUILD_DIR.'); 'Try setting FUCHSIA_SSH_CONFIG or FUCHSIA_BUILD_DIR.');
} }
return await processUtils.run(<String>[ return await processUtils.run(<String>[
'ssh', 'ssh',
'-F', '-F',
fuchsiaArtifacts.sshConfig.absolute.path, globals.fuchsiaArtifacts.sshConfig.absolute.path,
id, // Device's IP address. id, // Device's IP address.
command, command,
]); ]);
...@@ -573,14 +573,14 @@ class FuchsiaDevice extends Device { ...@@ -573,14 +573,14 @@ class FuchsiaDevice extends Device {
/// Transfer the file [origin] from the device to [destination]. /// Transfer the file [origin] from the device to [destination].
Future<RunResult> scp(String origin, String destination) async { Future<RunResult> scp(String origin, String destination) async {
if (fuchsiaArtifacts.sshConfig == null) { if (globals.fuchsiaArtifacts.sshConfig == null) {
throwToolExit('Cannot interact with device. No ssh config.\n' throwToolExit('Cannot interact with device. No ssh config.\n'
'Try setting FUCHSIA_SSH_CONFIG or FUCHSIA_BUILD_DIR.'); 'Try setting FUCHSIA_SSH_CONFIG or FUCHSIA_BUILD_DIR.');
} }
return await processUtils.run(<String>[ return await processUtils.run(<String>[
'scp', 'scp',
'-F', '-F',
fuchsiaArtifacts.sshConfig.absolute.path, globals.fuchsiaArtifacts.sshConfig.absolute.path,
'$id:$origin', '$id:$origin',
destination, destination,
]); ]);
...@@ -742,7 +742,7 @@ class _FuchsiaPortForwarder extends DevicePortForwarder { ...@@ -742,7 +742,7 @@ class _FuchsiaPortForwarder extends DevicePortForwarder {
'ssh', 'ssh',
'-6', '-6',
'-F', '-F',
fuchsiaArtifacts.sshConfig.absolute.path, globals.fuchsiaArtifacts.sshConfig.absolute.path,
'-nNT', '-nNT',
'-vvv', '-vvv',
'-f', '-f',
...@@ -774,7 +774,7 @@ class _FuchsiaPortForwarder extends DevicePortForwarder { ...@@ -774,7 +774,7 @@ class _FuchsiaPortForwarder extends DevicePortForwarder {
final List<String> command = <String>[ final List<String> command = <String>[
'ssh', 'ssh',
'-F', '-F',
fuchsiaArtifacts.sshConfig.absolute.path, globals.fuchsiaArtifacts.sshConfig.absolute.path,
'-O', '-O',
'cancel', 'cancel',
'-vvv', '-vvv',
......
...@@ -107,14 +107,14 @@ class FuchsiaPM { ...@@ -107,14 +107,14 @@ class FuchsiaPM {
/// [FuchsiaDevFinder.resolve], and [port] should be an unused port for the /// [FuchsiaDevFinder.resolve], and [port] should be an unused port for the
/// http server to bind. /// http server to bind.
Future<Process> serve(String repoPath, String host, int port) async { Future<Process> serve(String repoPath, String host, int port) async {
if (fuchsiaArtifacts.pm == null) { if (globals.fuchsiaArtifacts.pm == null) {
throwToolExit('Fuchsia pm tool not found'); throwToolExit('Fuchsia pm tool not found');
} }
if (isIPv6Address(host.split('%').first)) { if (isIPv6Address(host.split('%').first)) {
host = '[${host.replaceAll('%', '%25')}]'; host = '[${host.replaceAll('%', '%25')}]';
} }
final List<String> command = <String>[ final List<String> command = <String>[
fuchsiaArtifacts.pm.path, globals.fuchsiaArtifacts.pm.path,
'serve', 'serve',
'-repo', '-repo',
repoPath, repoPath,
...@@ -151,10 +151,10 @@ class FuchsiaPM { ...@@ -151,10 +151,10 @@ class FuchsiaPM {
} }
Future<bool> _runPMCommand(List<String> args) async { Future<bool> _runPMCommand(List<String> args) async {
if (fuchsiaArtifacts.pm == null) { if (globals.fuchsiaArtifacts.pm == null) {
throwToolExit('Fuchsia pm tool not found'); throwToolExit('Fuchsia pm tool not found');
} }
final List<String> command = <String>[fuchsiaArtifacts.pm.path, ...args]; final List<String> command = <String>[globals.fuchsiaArtifacts.pm.path, ...args];
final RunResult result = await processUtils.run(command); final RunResult result = await processUtils.run(command);
return result.exitCode == 0; return result.exitCode == 0;
} }
......
...@@ -17,9 +17,6 @@ import 'fuchsia_pm.dart'; ...@@ -17,9 +17,6 @@ import 'fuchsia_pm.dart';
/// The [FuchsiaSdk] instance. /// The [FuchsiaSdk] instance.
FuchsiaSdk get fuchsiaSdk => context.get<FuchsiaSdk>(); FuchsiaSdk get fuchsiaSdk => context.get<FuchsiaSdk>();
/// The [FuchsiaArtifacts] instance.
FuchsiaArtifacts get fuchsiaArtifacts => context.get<FuchsiaArtifacts>();
/// Returns [true] if the current platform supports Fuchsia targets. /// Returns [true] if the current platform supports Fuchsia targets.
bool isFuchsiaSupportedPlatform() { bool isFuchsiaSupportedPlatform() {
return globals.platform.isLinux || globals.platform.isMacOS; return globals.platform.isLinux || globals.platform.isMacOS;
...@@ -37,7 +34,11 @@ class FuchsiaSdk { ...@@ -37,7 +34,11 @@ class FuchsiaSdk {
/// Interface to the 'device-finder' tool. /// Interface to the 'device-finder' tool.
FuchsiaDevFinder _fuchsiaDevFinder; FuchsiaDevFinder _fuchsiaDevFinder;
FuchsiaDevFinder get fuchsiaDevFinder => FuchsiaDevFinder get fuchsiaDevFinder =>
_fuchsiaDevFinder ??= FuchsiaDevFinder(); _fuchsiaDevFinder ??= FuchsiaDevFinder(
fuchsiaArtifacts: globals.fuchsiaArtifacts,
logger: globals.logger,
processManager: globals.processManager
);
/// Interface to the 'kernel_compiler' tool. /// Interface to the 'kernel_compiler' tool.
FuchsiaKernelCompiler _fuchsiaKernelCompiler; FuchsiaKernelCompiler _fuchsiaKernelCompiler;
...@@ -48,8 +49,8 @@ class FuchsiaSdk { ...@@ -48,8 +49,8 @@ class FuchsiaSdk {
/// $ device-finder list -full /// $ device-finder list -full
/// > 192.168.42.56 paper-pulp-bush-angel /// > 192.168.42.56 paper-pulp-bush-angel
Future<String> listDevices({ Duration timeout }) async { Future<String> listDevices({ Duration timeout }) async {
if (fuchsiaArtifacts.devFinder == null || if (globals.fuchsiaArtifacts.devFinder == null ||
!fuchsiaArtifacts.devFinder.existsSync()) { !globals.fuchsiaArtifacts.devFinder.existsSync()) {
return null; return null;
} }
final List<String> devices = await fuchsiaDevFinder.list(timeout: timeout); final List<String> devices = await fuchsiaDevFinder.list(timeout: timeout);
...@@ -67,8 +68,8 @@ class FuchsiaSdk { ...@@ -67,8 +68,8 @@ class FuchsiaSdk {
final StreamController<String> controller = StreamController<String>(onCancel: () { final StreamController<String> controller = StreamController<String>(onCancel: () {
process.kill(); process.kill();
}); });
if (fuchsiaArtifacts.sshConfig == null || if (globals.fuchsiaArtifacts.sshConfig == null ||
!fuchsiaArtifacts.sshConfig.existsSync()) { !globals.fuchsiaArtifacts.sshConfig.existsSync()) {
globals.printError('Cannot read device logs: No ssh config.'); globals.printError('Cannot read device logs: No ssh config.');
globals.printError('Have you set FUCHSIA_SSH_CONFIG or FUCHSIA_BUILD_DIR?'); globals.printError('Have you set FUCHSIA_SSH_CONFIG or FUCHSIA_BUILD_DIR?');
return null; return null;
...@@ -77,7 +78,7 @@ class FuchsiaSdk { ...@@ -77,7 +78,7 @@ class FuchsiaSdk {
final List<String> cmd = <String>[ final List<String> cmd = <String>[
'ssh', 'ssh',
'-F', '-F',
fuchsiaArtifacts.sshConfig.absolute.path, globals.fuchsiaArtifacts.sshConfig.absolute.path,
id, // The device's IP. id, // The device's IP.
remoteCommand, remoteCommand,
]; ];
......
...@@ -5,7 +5,6 @@ ...@@ -5,7 +5,6 @@
import '../base/context.dart'; import '../base/context.dart';
import '../doctor.dart'; import '../doctor.dart';
import '../globals.dart' as globals; import '../globals.dart' as globals;
import 'fuchsia_sdk.dart';
/// The [FuchsiaWorkflow] instance. /// The [FuchsiaWorkflow] instance.
FuchsiaWorkflow get fuchsiaWorkflow => context.get<FuchsiaWorkflow>(); FuchsiaWorkflow get fuchsiaWorkflow => context.get<FuchsiaWorkflow>();
...@@ -21,12 +20,12 @@ class FuchsiaWorkflow implements Workflow { ...@@ -21,12 +20,12 @@ class FuchsiaWorkflow implements Workflow {
@override @override
bool get canListDevices { bool get canListDevices {
return fuchsiaArtifacts.devFinder != null; return globals.fuchsiaArtifacts.devFinder != null;
} }
@override @override
bool get canLaunchDevices { bool get canLaunchDevices {
return fuchsiaArtifacts.devFinder != null && fuchsiaArtifacts.sshConfig != null; return globals.fuchsiaArtifacts.devFinder != null && globals.fuchsiaArtifacts.sshConfig != null;
} }
@override @override
......
...@@ -21,6 +21,7 @@ import 'base/template.dart'; ...@@ -21,6 +21,7 @@ import 'base/template.dart';
import 'base/terminal.dart'; import 'base/terminal.dart';
import 'base/user_messages.dart'; import 'base/user_messages.dart';
import 'cache.dart'; import 'cache.dart';
import 'fuchsia/fuchsia_sdk.dart';
import 'ios/ios_deploy.dart'; import 'ios/ios_deploy.dart';
import 'ios/ios_workflow.dart'; import 'ios/ios_workflow.dart';
import 'ios/mac.dart'; import 'ios/mac.dart';
...@@ -69,6 +70,7 @@ Platform get platform => context.get<Platform>() ?? _kLocalPlatform; ...@@ -69,6 +70,7 @@ Platform get platform => context.get<Platform>() ?? _kLocalPlatform;
AndroidStudio get androidStudio => context.get<AndroidStudio>(); AndroidStudio get androidStudio => context.get<AndroidStudio>();
AndroidSdk get androidSdk => context.get<AndroidSdk>(); AndroidSdk get androidSdk => context.get<AndroidSdk>();
FlutterVersion get flutterVersion => context.get<FlutterVersion>(); FlutterVersion get flutterVersion => context.get<FlutterVersion>();
FuchsiaArtifacts get fuchsiaArtifacts => context.get<FuchsiaArtifacts>();
IMobileDevice get iMobileDevice => context.get<IMobileDevice>(); IMobileDevice get iMobileDevice => context.get<IMobileDevice>();
IOSDeploy get iosDeploy => context.get<IOSDeploy>(); IOSDeploy get iosDeploy => context.get<IOSDeploy>();
IOSSimulatorUtils get iosSimulatorUtils => context.get<IOSSimulatorUtils>(); IOSSimulatorUtils get iosSimulatorUtils => context.get<IOSSimulatorUtils>();
......
// 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.
import 'package:file/file.dart';
import 'package:file/memory.dart';
import 'package:flutter_tools/src/base/file_system.dart';
import 'package:flutter_tools/src/base/logger.dart';
import 'package:flutter_tools/src/fuchsia/fuchsia_dev_finder.dart';
import 'package:flutter_tools/src/fuchsia/fuchsia_sdk.dart';
import 'package:mockito/mockito.dart';
import 'package:process/process.dart';
import '../../src/common.dart';
import '../../src/context.dart';
void main() {
MockFuchsiaArtifacts mockFuchsiaArtifacts;
BufferLogger logger;
MemoryFileSystem memoryFileSystem;
File deviceFinder;
setUp(() {
mockFuchsiaArtifacts = MockFuchsiaArtifacts();
memoryFileSystem = MemoryFileSystem.test();
logger = BufferLogger.test();
deviceFinder = memoryFileSystem.file('device-finder');
when(mockFuchsiaArtifacts.devFinder).thenReturn(deviceFinder);
});
group('device-finder list', () {
testWithoutContext('device-finder not found', () {
final FuchsiaDevFinder fuchsiaDevFinder = FuchsiaDevFinder(
fuchsiaArtifacts: mockFuchsiaArtifacts,
logger: logger,
processManager: FakeProcessManager.any(),
);
expect(() async => await fuchsiaDevFinder.list(),
throwsToolExit(message: 'Fuchsia device-finder tool not found.'));
});
testWithoutContext('no devices', () async {
deviceFinder.createSync();
final ProcessManager processManager = FakeProcessManager.list(<FakeCommand>[
FakeCommand(
command: <String>[ deviceFinder.path, 'list', '-full' ],
exitCode: 1,
stderr: 'list.go:72: no devices found',
),
]);
final FuchsiaDevFinder fuchsiaDevFinder = FuchsiaDevFinder(
fuchsiaArtifacts: mockFuchsiaArtifacts,
logger: logger,
processManager: processManager,
);
expect(await fuchsiaDevFinder.list(), isNull);
expect(logger.errorText, isEmpty);
});
testWithoutContext('error', () async {
deviceFinder.createSync();
final ProcessManager processManager = FakeProcessManager.list(<FakeCommand>[
FakeCommand(
command: <String>[ deviceFinder.path, 'list', '-full' ],
exitCode: 1,
stderr: 'unexpected error',
),
]);
final FuchsiaDevFinder fuchsiaDevFinder = FuchsiaDevFinder(
fuchsiaArtifacts: mockFuchsiaArtifacts,
logger: logger,
processManager: processManager,
);
expect(await fuchsiaDevFinder.list(), isNull);
expect(logger.errorText, contains('unexpected error'));
});
testWithoutContext('devices found', () async {
deviceFinder.createSync();
final ProcessManager processManager = FakeProcessManager.list(<FakeCommand>[
FakeCommand(
command: <String>[ deviceFinder.path, 'list', '-full' ],
exitCode: 0,
stdout: 'device1\ndevice2',
),
]);
final FuchsiaDevFinder fuchsiaDevFinder = FuchsiaDevFinder(
fuchsiaArtifacts: mockFuchsiaArtifacts,
logger: logger,
processManager: processManager,
);
expect(await fuchsiaDevFinder.list(), <String>['device1', 'device2']);
expect(logger.errorText, isEmpty);
});
testWithoutContext('timeout', () async {
deviceFinder.createSync();
final ProcessManager processManager = FakeProcessManager.list(<FakeCommand>[
FakeCommand(
command: <String>[
deviceFinder.path,
'list',
'-full',
'-timeout',
'2000ms',
],
exitCode: 0,
stdout: 'device1',
),
]);
final FuchsiaDevFinder fuchsiaDevFinder = FuchsiaDevFinder(
fuchsiaArtifacts: mockFuchsiaArtifacts,
logger: logger,
processManager: processManager,
);
expect(await fuchsiaDevFinder.list(timeout: const Duration(seconds: 2)), <String>['device1']);
});
});
}
class MockFuchsiaArtifacts extends Mock implements FuchsiaArtifacts {}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment