Unverified Commit 0b321e67 authored by Jenn Magder's avatar Jenn Magder Committed by GitHub

Remove IMobileDevice from globals, hoist to XCDevice constructor (#53144)

* Convert ios_device_logger_test.dart to testWithoutContext

* Remove IMobileDevice from globals, hoist to XCDevice constructor
parent 404bb5a5
......@@ -126,7 +126,6 @@ Future<T> runInContext<T>(
FuchsiaWorkflow: () => FuchsiaWorkflow(),
GradleUtils: () => GradleUtils(),
HotRunnerConfig: () => HotRunnerConfig(),
IMobileDevice: () => IMobileDevice(),
IOSDeploy: () => IOSDeploy(
artifacts: globals.artifacts,
cache: globals.cache,
......@@ -209,6 +208,12 @@ Future<T> runInContext<T>(
XCDevice: () => XCDevice(
processManager: globals.processManager,
logger: globals.logger,
iMobileDevice: IMobileDevice(
artifacts: globals.artifacts,
cache: globals.cache,
logger: globals.logger,
processManager: globals.processManager,
),
xcode: globals.xcode,
),
XcodeProjectInterpreter: () => XcodeProjectInterpreter(
......
......@@ -24,7 +24,6 @@ import 'cache.dart';
import 'fuchsia/fuchsia_sdk.dart';
import 'ios/ios_deploy.dart';
import 'ios/ios_workflow.dart';
import 'ios/mac.dart';
import 'ios/plist_parser.dart';
import 'ios/simulators.dart';
import 'ios/xcodeproj.dart';
......@@ -72,7 +71,6 @@ AndroidStudio get androidStudio => context.get<AndroidStudio>();
AndroidSdk get androidSdk => context.get<AndroidSdk>();
FlutterVersion get flutterVersion => context.get<FlutterVersion>();
FuchsiaArtifacts get fuchsiaArtifacts => context.get<FuchsiaArtifacts>();
IMobileDevice get iMobileDevice => context.get<IMobileDevice>();
IOSDeploy get iosDeploy => context.get<IOSDeploy>();
IOSSimulatorUtils get iosSimulatorUtils => context.get<IOSSimulatorUtils>();
IOSWorkflow get iosWorkflow => context.get<IOSWorkflow>();
......
......@@ -83,13 +83,15 @@ class IOSDevice extends Device {
@required Platform platform,
@required Artifacts artifacts,
@required IOSDeploy iosDeploy,
@required IMobileDevice iMobileDevice,
@required Logger logger,
})
: _sdkVersion = sdkVersion,
_iosDeploy = iosDeploy,
_fileSystem = fileSystem,
_logger = logger,
_platform = platform,
: _sdkVersion = sdkVersion,
_iosDeploy = iosDeploy,
_iMobileDevice = iMobileDevice,
_fileSystem = fileSystem,
_logger = logger,
_platform = platform,
super(
id,
category: Category.mobile,
......@@ -113,6 +115,7 @@ class IOSDevice extends Device {
final FileSystem _fileSystem;
final Logger _logger;
final Platform _platform;
final IMobileDevice _iMobileDevice;
/// May be 0 if version cannot be parsed.
int get majorSdkVersion {
......@@ -374,7 +377,7 @@ class IOSDevice extends Device {
return _logReaders.putIfAbsent(app, () => IOSDeviceLogReader.create(
device: this,
app: app,
iMobileDevice: globals.iMobileDevice,
iMobileDevice: _iMobileDevice,
));
}
......@@ -402,11 +405,11 @@ class IOSDevice extends Device {
void clearLogs() { }
@override
bool get supportsScreenshot => globals.iMobileDevice.isInstalled;
bool get supportsScreenshot => _iMobileDevice.isInstalled;
@override
Future<void> takeScreenshot(File outputFile) async {
await globals.iMobileDevice.takeScreenshot(outputFile);
await _iMobileDevice.takeScreenshot(outputFile);
}
@override
......
......@@ -5,6 +5,7 @@
import 'dart:async';
import 'package:meta/meta.dart';
import 'package:process/process.dart';
import '../application_package.dart';
import '../artifacts.dart';
......@@ -15,6 +16,7 @@ import '../base/logger.dart';
import '../base/process.dart';
import '../base/utils.dart';
import '../build_info.dart';
import '../cache.dart';
import '../flutter_manifest.dart';
import '../globals.dart' as globals;
import '../macos/cocoapod_utils.dart';
......@@ -28,26 +30,36 @@ import 'migrations/xcode_build_system_migration.dart';
import 'xcodeproj.dart';
class IMobileDevice {
IMobileDevice()
: _idevicesyslogPath = globals.artifacts.getArtifactPath(Artifact.idevicesyslog, platform: TargetPlatform.ios),
_idevicescreenshotPath = globals.artifacts.getArtifactPath(Artifact.idevicescreenshot, platform: TargetPlatform.ios);
IMobileDevice({
@required Artifacts artifacts,
@required Cache cache,
@required ProcessManager processManager,
@required Logger logger,
}) : _idevicesyslogPath = artifacts.getArtifactPath(Artifact.idevicesyslog, platform: TargetPlatform.ios),
_idevicescreenshotPath = artifacts.getArtifactPath(Artifact.idevicescreenshot, platform: TargetPlatform.ios),
_dyLdLibEntry = cache.dyLdLibEntry,
_processUtils = ProcessUtils(logger: logger, processManager: processManager),
_processManager = processManager;
final String _idevicesyslogPath;
final String _idevicescreenshotPath;
final MapEntry<String, String> _dyLdLibEntry;
final ProcessManager _processManager;
final ProcessUtils _processUtils;
bool get isInstalled => _isInstalled ??= globals.processManager.canRun(_idevicescreenshotPath);
bool get isInstalled => _isInstalled ??= _processManager.canRun(_idevicescreenshotPath);
bool _isInstalled;
/// Starts `idevicesyslog` and returns the running process.
Future<Process> startLogger(String deviceID) {
return processUtils.start(
return _processUtils.start(
<String>[
_idevicesyslogPath,
'-u',
deviceID,
],
environment: Map<String, String>.fromEntries(
<MapEntry<String, String>>[globals.cache.dyLdLibEntry]
<MapEntry<String, String>>[_dyLdLibEntry]
),
);
}
......@@ -61,7 +73,7 @@ class IMobileDevice {
],
throwOnError: true,
environment: Map<String, String>.fromEntries(
<MapEntry<String, String>>[globals.cache.dyLdLibEntry]
<MapEntry<String, String>>[_dyLdLibEntry]
),
);
}
......
......@@ -17,6 +17,7 @@ import '../build_info.dart';
import '../convert.dart';
import '../globals.dart' as globals;
import '../ios/devices.dart';
import '../ios/mac.dart';
import '../ios/xcodeproj.dart';
import '../reporting/reporting.dart';
......@@ -196,12 +197,15 @@ class XCDevice {
@required ProcessManager processManager,
@required Logger logger,
@required Xcode xcode,
@required IMobileDevice iMobileDevice,
}) : _processUtils = ProcessUtils(logger: logger, processManager: processManager),
_logger = logger,
_iMobileDevice = iMobileDevice,
_xcode = xcode;
final ProcessUtils _processUtils;
final Logger _logger;
final IMobileDevice _iMobileDevice;
final Xcode _xcode;
bool get isInstalled => _xcode.isInstalledAndMeetsVersionCheck && xcdevicePath != null;
......@@ -356,6 +360,7 @@ class XCDevice {
fileSystem: globals.fs,
logger: globals.logger,
iosDeploy: globals.iosDeploy,
iMobileDevice: _iMobileDevice,
platform: globals.platform,
));
}
......
......@@ -51,6 +51,7 @@ void main() {
MockCache mockCache;
Logger logger;
IOSDeploy iosDeploy;
IMobileDevice iMobileDevice;
FileSystem mockFileSystem;
setUp(() {
......@@ -67,6 +68,12 @@ void main() {
platform: macPlatform,
processManager: FakeProcessManager.any(),
);
iMobileDevice = IMobileDevice(
artifacts: mockArtifacts,
cache: mockCache,
logger: logger,
processManager: FakeProcessManager.any(),
);
});
testWithoutContext('successfully instantiates on Mac OS', () {
......@@ -77,6 +84,7 @@ void main() {
logger: logger,
platform: macPlatform,
iosDeploy: iosDeploy,
iMobileDevice: iMobileDevice,
name: 'iPhone 1',
sdkVersion: '13.3',
cpuArchitecture: DarwinArch.arm64
......@@ -91,6 +99,7 @@ void main() {
logger: logger,
platform: macPlatform,
iosDeploy: iosDeploy,
iMobileDevice: iMobileDevice,
name: 'iPhone 1',
cpuArchitecture: DarwinArch.arm64,
sdkVersion: '1.0.0'
......@@ -102,6 +111,7 @@ void main() {
logger: logger,
platform: macPlatform,
iosDeploy: iosDeploy,
iMobileDevice: iMobileDevice,
name: 'iPhone 1',
cpuArchitecture: DarwinArch.arm64,
sdkVersion: '13.1.1'
......@@ -113,6 +123,7 @@ void main() {
logger: logger,
platform: macPlatform,
iosDeploy: iosDeploy,
iMobileDevice: iMobileDevice,
name: 'iPhone 1',
cpuArchitecture: DarwinArch.arm64,
sdkVersion: '10'
......@@ -124,6 +135,7 @@ void main() {
logger: logger,
platform: macPlatform,
iosDeploy: iosDeploy,
iMobileDevice: iMobileDevice,
name: 'iPhone 1',
cpuArchitecture: DarwinArch.arm64,
sdkVersion: '0'
......@@ -135,6 +147,7 @@ void main() {
logger: logger,
platform: macPlatform,
iosDeploy: iosDeploy,
iMobileDevice: iMobileDevice,
name: 'iPhone 1',
cpuArchitecture: DarwinArch.arm64,
sdkVersion: 'bogus'
......@@ -152,6 +165,7 @@ void main() {
logger: logger,
platform: platform,
iosDeploy: iosDeploy,
iMobileDevice: iMobileDevice,
name: 'iPhone 1',
sdkVersion: '13.3',
cpuArchitecture: DarwinArch.arm64,
......@@ -205,6 +219,7 @@ void main() {
logger: logger,
platform: macPlatform,
iosDeploy: iosDeploy,
iMobileDevice: iMobileDevice,
name: 'iPhone 1',
sdkVersion: '13.3',
cpuArchitecture: DarwinArch.arm64,
......@@ -288,6 +303,7 @@ void main() {
logger: logger,
platform: macPlatform,
iosDeploy: iosDeploy,
iMobileDevice: iMobileDevice,
name: 'iPhone 1',
sdkVersion: '13.3',
cpuArchitecture: DarwinArch.arm64,
......@@ -488,6 +504,7 @@ void main() {
logger: testLogger,
platform: macPlatform,
iosDeploy: mockIosDeploy,
iMobileDevice: iMobileDevice,
cpuArchitecture: DarwinArch.arm64,
);
......@@ -573,6 +590,7 @@ void main() {
FakeProcessManager fakeProcessManager;
Logger logger;
IOSDeploy iosDeploy;
IMobileDevice iMobileDevice;
IOSWorkflow mockIosWorkflow;
setUp(() {
......@@ -590,6 +608,12 @@ void main() {
platform: macPlatform,
processManager: fakeProcessManager,
);
iMobileDevice = IMobileDevice(
artifacts: mockArtifacts,
cache: mockCache,
processManager: fakeProcessManager,
logger: logger,
);
});
final List<Platform> unsupportedPlatforms = <Platform>[linuxPlatform, windowsPlatform];
......@@ -623,6 +647,7 @@ void main() {
cpuArchitecture: DarwinArch.arm64,
artifacts: mockArtifacts,
iosDeploy: iosDeploy,
iMobileDevice: iMobileDevice,
logger: logger,
platform: macPlatform,
fileSystem: mockFileSystem,
......
......@@ -12,6 +12,7 @@ import 'package:flutter_tools/src/build_info.dart';
import 'package:flutter_tools/src/cache.dart';
import 'package:flutter_tools/src/ios/devices.dart';
import 'package:flutter_tools/src/ios/ios_deploy.dart';
import 'package:flutter_tools/src/ios/mac.dart';
import 'package:meta/meta.dart';
import 'package:mockito/mockito.dart';
import 'package:platform/platform.dart';
......@@ -171,6 +172,12 @@ IOSDevice setUpIOSDevice({
sdkVersion: '13.3',
cpuArchitecture: DarwinArch.arm64,
platform: platform,
iMobileDevice: IMobileDevice(
logger: BufferLogger.test(),
processManager: processManager,
artifacts: artifacts,
cache: cache,
),
iosDeploy: IOSDeploy(
logger: BufferLogger.test(),
platform: platform,
......
......@@ -3,6 +3,7 @@
// found in the LICENSE file.
import 'package:flutter_tools/src/artifacts.dart';
import 'package:flutter_tools/src/base/logger.dart';
import 'package:flutter_tools/src/build_info.dart';
import 'package:flutter_tools/src/device.dart';
import 'package:flutter_tools/src/ios/devices.dart';
......@@ -11,14 +12,19 @@ import 'package:mockito/mockito.dart';
import '../../src/common.dart';
import '../../src/context.dart';
import '../../src/testbed.dart';
void main() {
FakeProcessManager processManager;
MockArtifacts artifacts;
FakeCache fakeCache;
BufferLogger logger;
setUp(() {
processManager = FakeProcessManager.list(<FakeCommand>[]);
fakeCache = FakeCache();
artifacts = MockArtifacts();
logger = BufferLogger.test();
when(artifacts.getArtifactPath(Artifact.idevicesyslog, platform: TargetPlatform.ios))
.thenReturn('idevice-syslog');
});
......@@ -37,8 +43,7 @@ void main() {
expect(decoded, r'I \M-b\M^O syslog!');
});
// IMobileDevice uses context.
testUsingContext('IOSDeviceLogReader suppresses non-Flutter lines from output with syslog', () async {
testWithoutContext('IOSDeviceLogReader suppresses non-Flutter lines from output with syslog', () async {
processManager.addCommand(
const FakeCommand(
command: <String>[
......@@ -54,18 +59,19 @@ Runner(UIKit)[297] <Notice>: E is for enpitsu"
),
);
final DeviceLogReader logReader = IOSDeviceLogReader.test(
iMobileDevice: IMobileDevice(),
iMobileDevice: IMobileDevice(
artifacts: artifacts,
processManager: processManager,
cache: fakeCache,
logger: logger,
),
);
final List<String> lines = await logReader.logLines.toList();
expect(lines, <String>['A is for ari', 'I is for ichigo']);
}, overrides: <Type, Generator>{
ProcessManager: () => processManager,
Artifacts: () => artifacts,
});
// IMobileDevice uses context.
testUsingContext('IOSDeviceLogReader includes multi-line Flutter logs in the output with syslog', () async {
testWithoutContext('IOSDeviceLogReader includes multi-line Flutter logs in the output with syslog', () async {
processManager.addCommand(
const FakeCommand(
command: <String>[
......@@ -81,7 +87,12 @@ Runner(libsystem_asl.dylib)[297] <Notice>: libMobileGestalt
),
);
final DeviceLogReader logReader = IOSDeviceLogReader.test(
iMobileDevice: IMobileDevice()
iMobileDevice: IMobileDevice(
artifacts: artifacts,
processManager: processManager,
cache: fakeCache,
logger: logger,
),
);
final List<String> lines = await logReader.logLines.toList();
......@@ -91,13 +102,9 @@ Runner(libsystem_asl.dylib)[297] <Notice>: libMobileGestalt
'This is a multi-line message,',
' with a non-Flutter log message following it.',
]);
}, overrides: <Type, Generator>{
ProcessManager: () => processManager,
Artifacts: () => artifacts,
});
// IMobileDevice uses context.
testUsingContext('includes multi-line Flutter logs in the output', () async {
testWithoutContext('includes multi-line Flutter logs in the output', () async {
processManager.addCommand(
const FakeCommand(
command: <String>[
......@@ -114,7 +121,12 @@ Runner(libsystem_asl.dylib)[297] <Notice>: libMobileGestalt
);
final DeviceLogReader logReader = IOSDeviceLogReader.test(
iMobileDevice: IMobileDevice()
iMobileDevice: IMobileDevice(
artifacts: artifacts,
processManager: processManager,
cache: fakeCache,
logger: logger,
),
);
final List<String> lines = await logReader.logLines.toList();
......@@ -124,9 +136,6 @@ Runner(libsystem_asl.dylib)[297] <Notice>: libMobileGestalt
'This is a multi-line message,',
' with a non-Flutter log message following it.',
]);
}, overrides: <Type, Generator>{
ProcessManager: () => processManager,
Artifacts: () => artifacts,
});
}
......
......@@ -83,6 +83,7 @@ IOSDevice setUpIOSDevice(FileSystem fileSystem) {
fileSystem: fileSystem,
logger: BufferLogger.test(),
iosDeploy: null, // not used in this test
iMobileDevice: null, // not used in this test
platform: FakePlatform(operatingSystem: 'macos'),
name: 'iPhone 1',
sdkVersion: '13.3',
......
......@@ -14,6 +14,7 @@ import 'package:flutter_tools/src/cache.dart';
import 'package:flutter_tools/src/device.dart';
import 'package:flutter_tools/src/ios/devices.dart';
import 'package:flutter_tools/src/ios/ios_deploy.dart';
import 'package:flutter_tools/src/ios/mac.dart';
import 'package:flutter_tools/src/mdns_discovery.dart';
import 'package:flutter_tools/src/reporting/reporting.dart';
import 'package:mockito/mockito.dart';
......@@ -390,6 +391,12 @@ IOSDevice setUpIOSDevice({
artifacts: artifacts,
cache: cache,
),
iMobileDevice: IMobileDevice(
logger: logger ?? BufferLogger.test(),
processManager: processManager ?? FakeProcessManager.any(),
artifacts: artifacts,
cache: cache,
),
cpuArchitecture: DarwinArch.arm64,
);
}
......
......@@ -8,6 +8,7 @@ import 'package:file/file.dart';
import 'package:flutter_tools/src/artifacts.dart';
import 'package:flutter_tools/src/base/file_system.dart';
import 'package:flutter_tools/src/base/io.dart' show ProcessResult;
import 'package:flutter_tools/src/base/logger.dart';
import 'package:flutter_tools/src/cache.dart';
import 'package:flutter_tools/src/ios/mac.dart';
import 'package:flutter_tools/src/ios/xcodeproj.dart';
......@@ -36,14 +37,14 @@ class MockIosProject extends Mock implements IosProject {}
void main() {
group('IMobileDevice', () {
final FakePlatform osx = FakePlatform.fromPlatform(const LocalPlatform())
..operatingSystem = 'macos';
final String libimobiledevicePath = globals.fs.path.join('bin', 'cache', 'artifacts', 'libimobiledevice');
final String idevicescreenshotPath = globals.fs.path.join(libimobiledevicePath, 'idevicescreenshot');
MockArtifacts mockArtifacts;
MockCache mockCache;
Logger logger;
setUp(() {
logger = BufferLogger.test();
mockCache = MockCache();
mockArtifacts = MockArtifacts();
when(mockArtifacts.getArtifactPath(Artifact.idevicescreenshot, platform: anyNamed('platform'))).thenReturn(idevicescreenshotPath);
......@@ -63,7 +64,7 @@ void main() {
when(mockArtifacts.getArtifactPath(Artifact.idevicescreenshot, platform: anyNamed('platform'))).thenReturn(idevicescreenshotPath);
});
testUsingContext('error if idevicescreenshot is not installed', () async {
testWithoutContext('error if idevicescreenshot is not installed', () async {
when(mockOutputFile.path).thenReturn(outputPath);
// Let `idevicescreenshot` fail with exit code 1.
......@@ -72,11 +73,14 @@ void main() {
workingDirectory: null,
)).thenAnswer((_) => Future<ProcessResult>.value(ProcessResult(4, 1, '', '')));
expect(() async => await globals.iMobileDevice.takeScreenshot(mockOutputFile), throwsA(anything));
}, overrides: <Type, Generator>{
ProcessManager: () => mockProcessManager,
Platform: () => osx,
Cache: () => mockCache,
final IMobileDevice iMobileDevice = IMobileDevice(
artifacts: mockArtifacts,
cache: mockCache,
processManager: mockProcessManager,
logger: logger,
);
expect(() async => await iMobileDevice.takeScreenshot(mockOutputFile), throwsA(anything));
});
testUsingContext('idevicescreenshot captures and returns screenshot', () async {
......@@ -84,15 +88,20 @@ void main() {
when(mockProcessManager.run(any, environment: anyNamed('environment'), workingDirectory: null)).thenAnswer(
(Invocation invocation) => Future<ProcessResult>.value(ProcessResult(4, 0, '', '')));
await globals.iMobileDevice.takeScreenshot(mockOutputFile);
final IMobileDevice iMobileDevice = IMobileDevice(
artifacts: mockArtifacts,
cache: mockCache,
processManager: mockProcessManager,
logger: logger,
);
await iMobileDevice.takeScreenshot(mockOutputFile);
verify(mockProcessManager.run(<String>[idevicescreenshotPath, outputPath],
environment: <String, String>{'DYLD_LIBRARY_PATH': libimobiledevicePath},
workingDirectory: null,
));
}, overrides: <Type, Generator>{
ProcessManager: () => mockProcessManager,
Cache: () => mockCache,
Artifacts: () => mockArtifacts,
});
});
});
......
......@@ -216,6 +216,7 @@ void main() {
processManager: processManager,
logger: logger,
xcode: mockXcode,
iMobileDevice: null,
);
});
......
......@@ -844,7 +844,7 @@ class FakeCache implements Cache {
String get storageBaseUrl => null;
@override
MapEntry<String, String> get dyLdLibEntry => null;
MapEntry<String, String> get dyLdLibEntry => const MapEntry<String, String>('DYLD_LIBRARY_PATH', '');
@override
String get engineRevision => null;
......
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