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, + }); + }); }