From dc5d2937bb14d974da61f9e95aa9c0b9d3efdcfd Mon Sep 17 00:00:00 2001 From: Chris Bracken Date: Wed, 23 Aug 2017 10:50:07 -0700 Subject: [PATCH] Suppress libmobilegestalt noise from iOS device logging (#11745) This patch supports basic filtering of log lines from physical iOS devices, similar to existing functionality for iOS simulator logging. This patch also suppresses the following two log messages which are emitted at app startup on iOS 10.3 devices: libMobileGestalt MobileGestaltSupport.m:153: pid 123 (Runner) does not have sandbox access for frZQaeyWLUvLjeuEK43hmg and IS NOT appropriately entitled libMobileGestalt MobileGestalt.c:550: no access to InverseDeviceID (see ) --- .../flutter_tools/lib/src/ios/devices.dart | 12 +++++- .../flutter_tools/test/ios/devices_test.dart | 38 +++++++++++++++++++ 2 files changed, 48 insertions(+), 2 deletions(-) diff --git a/packages/flutter_tools/lib/src/ios/devices.dart b/packages/flutter_tools/lib/src/ios/devices.dart index 5db8514f057..1ad358cacc9 100644 --- a/packages/flutter_tools/lib/src/ios/devices.dart +++ b/packages/flutter_tools/lib/src/ios/devices.dart @@ -396,11 +396,19 @@ class _IOSDeviceLogReader extends DeviceLogReader { } void _onLine(String line) { + // Lines starting with these strings are suppressed from output as noise. + const List blacklist = const [ + 'libMobileGestalt ', + ]; + final Match match = _lineRegex.firstMatch(line); if (match != null) { - // Only display the log line after the initial device and executable information. - _linesController.add(line.substring(match.end)); + final String logLine = line.substring(match.end); + if (!blacklist.any(logLine.startsWith)) { + // Only display the log line after the initial device and executable information. + _linesController.add(logLine); + } } } diff --git a/packages/flutter_tools/test/ios/devices_test.dart b/packages/flutter_tools/test/ios/devices_test.dart index bb29b0897fa..cfd582af76f 100644 --- a/packages/flutter_tools/test/ios/devices_test.dart +++ b/packages/flutter_tools/test/ios/devices_test.dart @@ -5,7 +5,10 @@ import 'dart:async'; import 'package:file/file.dart'; +import 'package:flutter_tools/src/application_package.dart'; import 'package:flutter_tools/src/base/file_system.dart'; +import 'package:flutter_tools/src/base/io.dart'; +import 'package:flutter_tools/src/device.dart'; import 'package:flutter_tools/src/ios/devices.dart'; import 'package:flutter_tools/src/ios/mac.dart'; import 'package:mockito/mockito.dart'; @@ -15,9 +18,11 @@ import 'package:test/test.dart'; import '../src/context.dart'; +class MockIMobileDevice extends Mock implements IMobileDevice {} class MockProcessManager extends Mock implements ProcessManager {} class MockXcode extends Mock implements Xcode {} class MockFile extends Mock implements File {} +class MockProcess extends Mock implements Process {} void main() { final FakePlatform osx = new FakePlatform.fromPlatform(const LocalPlatform()); @@ -69,4 +74,37 @@ iPhone SE (11.0) [667E8DCD-5DCD-4C80-93A9-60D1D995206F] (Simulator) }); }); + group('logging', () { + MockIMobileDevice mockIMobileDevice; + + setUp(() { + mockIMobileDevice = new MockIMobileDevice(); + }); + + testUsingContext('suppresses blacklisted lines from output', () async { + when(mockIMobileDevice.startLogger()).thenAnswer((_) { + final Process mockProcess = new MockProcess(); + when(mockProcess.stdout).thenReturn(new Stream>.fromIterable(>[''' + Runner(libsystem_asl.dylib)[297] : A is for ari + Runner(libsystem_asl.dylib)[297] : libMobileGestalt MobileGestaltSupport.m:153: pid 123 (Runner) does not have sandbox access for frZQaeyWLUvLjeuEK43hmg and IS NOT appropriately entitled + Runner(libsystem_asl.dylib)[297] : libMobileGestalt MobileGestalt.c:550: no access to InverseDeviceID (see ) + Runner(libsystem_asl.dylib)[297] : I is for ichigo + '''.codeUnits])); + when(mockProcess.stderr).thenReturn(new Stream>.empty()); + // Delay return of exitCode until after stdout stream data, since it terminates the logger. + when(mockProcess.exitCode).thenReturn(new Future.delayed(Duration.ZERO, () => 0)); + return new Future.value(mockProcess); + }); + + final IOSDevice device = new IOSDevice('123456'); + final DeviceLogReader logReader = device.getLogReader( + app: new BuildableIOSApp(projectBundleId: 'bundleId'), + ); + + final List lines = await logReader.logLines.toList(); + expect(lines, ['A is for ari', 'I is for ichigo']); + }, overrides: { + IMobileDevice: () => mockIMobileDevice, + }); + }); }