Check if simctl is installed before trying to list devices or runtimes (#163895)
After https://github.com/flutter/flutter/pull/163785 there was still an unexpected `xcrun simctl` output on a machine with Xcode only half installed https://github.com/flutter/flutter/issues/161655. Check `simctl` is installed before trying to list booted simulator devices or runtimes. Should address https://github.com/flutter/flutter/issues/161655. ## Pre-launch Checklist - [x] I read the [Contributor Guide] and followed the process outlined there for submitting PRs. - [x] I read the [Tree Hygiene] wiki page, which explains my responsibilities. - [x] I read and followed the [Flutter Style Guide], including [Features we expect every widget to implement]. - [x] I signed the [CLA]. - [x] I listed at least one issue that this PR fixes in the description above. - [x] I updated/added relevant documentation (doc comments with `///`). - [x] I added new tests to check the change I am making, or this PR is [test-exempt]. - [x] I followed the [breaking change policy] and added [Data Driven Fixes] where supported. - [x] All existing and new tests are passing. If you need help, consider asking for advice on the #hackers-new channel on [Discord]. <!-- Links --> [Contributor Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview [Tree Hygiene]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md [test-exempt]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests [Flutter Style Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md [Features we expect every widget to implement]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement [CLA]: https://cla.developers.google.com/ [flutter/tests]: https://github.com/flutter/tests [breaking change policy]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes [Discord]: https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md [Data Driven Fixes]: https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
This commit is contained in:
parent
d0e8fa157a
commit
898ab2479e
@ -66,7 +66,7 @@ class IOSSimulatorUtils {
|
||||
final Xcode _xcode;
|
||||
|
||||
Future<List<IOSSimulator>> getAttachedDevices() async {
|
||||
if (!_xcode.isInstalledAndMeetsVersionCheck) {
|
||||
if (!_xcode.isInstalledAndMeetsVersionCheck || !_xcode.isSimctlInstalled) {
|
||||
return <IOSSimulator>[];
|
||||
}
|
||||
|
||||
@ -96,7 +96,7 @@ class IOSSimulatorUtils {
|
||||
}
|
||||
|
||||
Future<List<IOSSimulatorRuntime>> getAvailableIOSRuntimes() async {
|
||||
if (!_xcode.isInstalledAndMeetsVersionCheck) {
|
||||
if (!_xcode.isInstalledAndMeetsVersionCheck || !_xcode.isSimctlInstalled) {
|
||||
return <IOSSimulatorRuntime>[];
|
||||
}
|
||||
|
||||
|
@ -894,7 +894,10 @@ Dec 20 17:04:32 md32-11-vm1 Another App[88374]: Ignore this text''',
|
||||
|
||||
late FakeProcessManager fakeProcessManager;
|
||||
Xcode xcode;
|
||||
Xcode xcodeBadSimctl;
|
||||
late SimControl simControl;
|
||||
late IOSSimulatorUtils simulatorUtils;
|
||||
late IOSSimulatorUtils simulatorUtilsBadSimctl;
|
||||
late BufferLogger logger;
|
||||
const String deviceId = 'smart-phone';
|
||||
const String appId = 'flutterApp';
|
||||
@ -902,8 +905,32 @@ Dec 20 17:04:32 md32-11-vm1 Another App[88374]: Ignore this text''',
|
||||
setUp(() {
|
||||
fakeProcessManager = FakeProcessManager.empty();
|
||||
xcode = Xcode.test(processManager: FakeProcessManager.any());
|
||||
|
||||
final FakeProcessManager fakeProcessManagerBadSimctl = FakeProcessManager.list(<FakeCommand>[
|
||||
const FakeCommand(command: <String>['which', 'sysctl']),
|
||||
const FakeCommand(
|
||||
command: <String>['sysctl', 'hw.optional.arm64'],
|
||||
stdout: 'hw.optional.arm64: 0',
|
||||
),
|
||||
const FakeCommand(
|
||||
command: <String>['xcrun', 'simctl', 'list', 'devices', 'booted'],
|
||||
stderr: 'failed to run',
|
||||
exitCode: 1,
|
||||
),
|
||||
]);
|
||||
xcodeBadSimctl = Xcode.test(processManager: fakeProcessManagerBadSimctl);
|
||||
logger = BufferLogger.test();
|
||||
simControl = SimControl(logger: logger, processManager: fakeProcessManager, xcode: xcode);
|
||||
simulatorUtils = IOSSimulatorUtils(
|
||||
logger: logger,
|
||||
processManager: fakeProcessManager,
|
||||
xcode: xcode,
|
||||
);
|
||||
simulatorUtilsBadSimctl = IOSSimulatorUtils(
|
||||
logger: logger,
|
||||
processManager: fakeProcessManager,
|
||||
xcode: xcodeBadSimctl,
|
||||
);
|
||||
});
|
||||
|
||||
testWithoutContext('getConnectedDevices succeeds', () async {
|
||||
@ -933,6 +960,33 @@ Dec 20 17:04:32 md32-11-vm1 Another App[88374]: Ignore this text''',
|
||||
expect(fakeProcessManager, hasNoRemainingExpectations);
|
||||
});
|
||||
|
||||
testWithoutContext('IOSSimulatorUtils.getAttachedDevices succeeds', () async {
|
||||
fakeProcessManager.addCommand(
|
||||
const FakeCommand(
|
||||
command: <String>['xcrun', 'simctl', 'list', 'devices', 'booted', 'iOS', '--json'],
|
||||
stdout: validSimControlOutput,
|
||||
),
|
||||
);
|
||||
|
||||
final List<IOSSimulator> devices = await simulatorUtils.getAttachedDevices();
|
||||
|
||||
final IOSSimulator phone1 = devices[0];
|
||||
expect(phone1.category, Category.mobile);
|
||||
expect(phone1.name, 'iPhone 11');
|
||||
expect(phone1.simulatorCategory, 'com.apple.CoreSimulator.SimRuntime.iOS-14-0');
|
||||
|
||||
final IOSSimulator phone2 = devices[1];
|
||||
expect(phone2.category, Category.mobile);
|
||||
expect(phone2.name, 'Phone w Watch');
|
||||
expect(phone2.simulatorCategory, 'com.apple.CoreSimulator.SimRuntime.iOS-16-0');
|
||||
|
||||
final IOSSimulator phone3 = devices[2];
|
||||
expect(phone3.category, Category.mobile);
|
||||
expect(phone3.name, 'iPhone 13');
|
||||
expect(phone3.simulatorCategory, 'com.apple.CoreSimulator.SimRuntime.iOS-16-0');
|
||||
expect(fakeProcessManager, hasNoRemainingExpectations);
|
||||
});
|
||||
|
||||
testWithoutContext('getConnectedDevices handles bad simctl output', () async {
|
||||
fakeProcessManager.addCommand(
|
||||
const FakeCommand(
|
||||
@ -947,6 +1001,16 @@ Dec 20 17:04:32 md32-11-vm1 Another App[88374]: Ignore this text''',
|
||||
expect(fakeProcessManager, hasNoRemainingExpectations);
|
||||
});
|
||||
|
||||
testWithoutContext(
|
||||
'IOSSimulatorUtils.getAttachedDevices handles simctl not properly installed',
|
||||
() async {
|
||||
final List<IOSSimulator> devices = await simulatorUtilsBadSimctl.getAttachedDevices();
|
||||
|
||||
expect(devices, isEmpty);
|
||||
expect(fakeProcessManager, hasNoRemainingExpectations);
|
||||
},
|
||||
);
|
||||
|
||||
testWithoutContext('sdkMajorVersion defaults to 11 when sdkNameAndVersion is junk', () async {
|
||||
final IOSSimulator iosSimulatorA = IOSSimulator(
|
||||
'x',
|
||||
@ -1186,6 +1250,17 @@ Dec 20 17:04:32 md32-11-vm1 Another App[88374]: Ignore this text''',
|
||||
expect(logger.errorText, contains('simctl returned non-JSON response:'));
|
||||
expect(fakeProcessManager, hasNoRemainingExpectations);
|
||||
});
|
||||
|
||||
testWithoutContext(
|
||||
'IOSSimulatorUtils.getAvailableIOSRuntimes handles simctl not properly installed',
|
||||
() async {
|
||||
final List<IOSSimulatorRuntime> runtimes =
|
||||
await simulatorUtilsBadSimctl.getAvailableIOSRuntimes();
|
||||
|
||||
expect(runtimes, isEmpty);
|
||||
expect(fakeProcessManager, hasNoRemainingExpectations);
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
group('startApp', () {
|
||||
|
Loading…
x
Reference in New Issue
Block a user