Unverified Commit 46a5c550 authored by Jenn Magder's avatar Jenn Magder Committed by GitHub

Add iOS simulator log parse test (#55808)

parent 7ec50ddd
...@@ -517,13 +517,13 @@ void main() { ...@@ -517,13 +517,13 @@ void main() {
}); });
group('log reader', () { group('log reader', () {
MockProcessManager mockProcessManager; FakeProcessManager fakeProcessManager;
MockIosProject mockIosProject; MockIosProject mockIosProject;
MockSimControl mockSimControl; MockSimControl mockSimControl;
MockXcode mockXcode; MockXcode mockXcode;
setUp(() { setUp(() {
mockProcessManager = MockProcessManager(); fakeProcessManager = FakeProcessManager.list(<FakeCommand>[]);
mockIosProject = MockIosProject(); mockIosProject = MockIosProject();
mockSimControl = MockSimControl(); mockSimControl = MockSimControl();
mockXcode = MockXcode(); mockXcode = MockXcode();
...@@ -535,25 +535,49 @@ void main() { ...@@ -535,25 +535,49 @@ void main() {
osx.environment['IOS_SIMULATOR_LOG_FILE_PATH'] = syslog.path; osx.environment['IOS_SIMULATOR_LOG_FILE_PATH'] = syslog.path;
}); });
testUsingContext('simulator can parse Xcode 8/iOS 10-style logs', () async {
fakeProcessManager
..addCommand(const FakeCommand(
command: <String>['tail', '-n', '0', '-F', 'system.log'],
stdout: 'Dec 20 17:04:32 md32-11-vm1 Runner[88374]: flutter: Observatory listening on http://127.0.0.1:64213/1Uoeu523990=/',
))
..addCommand(const FakeCommand(
command: <String>['tail', '-n', '0', '-F', '/private/var/log/system.log']
));
final IOSSimulator device = IOSSimulator(
'123456',
simulatorCategory: 'iOS 10.0',
simControl: mockSimControl,
xcode: mockXcode,
);
final DeviceLogReader logReader = device.getLogReader(
app: await BuildableIOSApp.fromProject(mockIosProject),
);
final List<String> lines = await logReader.logLines.toList();
expect(lines, <String>[
'flutter: Observatory listening on http://127.0.0.1:64213/1Uoeu523990=/',
]);
expect(fakeProcessManager.hasRemainingExpectations, isFalse);
}, overrides: <Type, Generator>{
ProcessManager: () => fakeProcessManager,
FileSystem: () => fileSystem,
Platform: () => osx,
});
testUsingContext('simulator can output `)`', () async { testUsingContext('simulator can output `)`', () async {
when(mockProcessManager.start(any, environment: null, workingDirectory: null)) fakeProcessManager
.thenAnswer((Invocation invocation) { ..addCommand(const FakeCommand(
final Process mockProcess = MockProcess(); command: <String>['tail', '-n', '0', '-F', 'system.log'],
when(mockProcess.stdout) stdout: '''
.thenAnswer((Invocation invocation) {
return Stream<List<int>>.fromIterable(<List<int>>['''
2017-09-13 15:26:57.228948-0700 localhost Runner[37195]: (Flutter) Observatory listening on http://127.0.0.1:57701/ 2017-09-13 15:26:57.228948-0700 localhost Runner[37195]: (Flutter) Observatory listening on http://127.0.0.1:57701/
2017-09-13 15:26:57.228948-0700 localhost Runner[37195]: (Flutter) )))))))))) 2017-09-13 15:26:57.228948-0700 localhost Runner[37195]: (Flutter) ))))))))))
2017-09-13 15:26:57.228948-0700 localhost Runner[37195]: (Flutter) #0 Object.noSuchMethod (dart:core-patch/dart:core/object_patch.dart:46)''' 2017-09-13 15:26:57.228948-0700 localhost Runner[37195]: (Flutter) #0 Object.noSuchMethod (dart:core-patch/dart:core/object_patch.dart:46)'''
.codeUnits]); ))
}); ..addCommand(const FakeCommand(
when(mockProcess.stderr) command: <String>['tail', '-n', '0', '-F', '/private/var/log/system.log']
.thenAnswer((Invocation invocation) => const Stream<List<int>>.empty()); ));
// Delay return of exitCode until after stdout stream data, since it terminates the logger.
when(mockProcess.exitCode)
.thenAnswer((Invocation invocation) => Future<int>.delayed(Duration.zero, () => 0));
return Future<Process>.value(mockProcess);
});
final IOSSimulator device = IOSSimulator( final IOSSimulator device = IOSSimulator(
'123456', '123456',
...@@ -571,20 +595,18 @@ void main() { ...@@ -571,20 +595,18 @@ void main() {
'))))))))))', '))))))))))',
'#0 Object.noSuchMethod (dart:core-patch/dart:core/object_patch.dart:46)', '#0 Object.noSuchMethod (dart:core-patch/dart:core/object_patch.dart:46)',
]); ]);
expect(fakeProcessManager.hasRemainingExpectations, isFalse);
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
ProcessManager: () => mockProcessManager, ProcessManager: () => fakeProcessManager,
FileSystem: () => fileSystem, FileSystem: () => fileSystem,
Platform: () => osx, Platform: () => osx,
}); });
testUsingContext('log reader handles multiline messages', () async { testUsingContext('multiline messages', () async {
when(mockProcessManager.start(any, environment: null, workingDirectory: null)) fakeProcessManager
.thenAnswer((Invocation invocation) { ..addCommand(const FakeCommand(
final Process mockProcess = MockProcess(); command: <String>['tail', '-n', '0', '-F', 'system.log'],
when(mockProcess.stdout) stdout: '''
.thenAnswer((Invocation invocation) {
// Messages from 2017 should pass through, 2020 message should not
return Stream<List<int>>.fromIterable(<List<int>>['''
2017-09-13 15:26:57.228948-0700 localhost Runner[37195]: (Flutter) Single line message 2017-09-13 15:26:57.228948-0700 localhost Runner[37195]: (Flutter) Single line message
2017-09-13 15:26:57.228948-0700 localhost Runner[37195]: (Flutter) Multi line message 2017-09-13 15:26:57.228948-0700 localhost Runner[37195]: (Flutter) Multi line message
continues... continues...
...@@ -599,15 +621,10 @@ void main() { ...@@ -599,15 +621,10 @@ void main() {
and goes... and goes...
2017-09-13 15:36:57.228948-0700 localhost Runner[37195]: (Flutter) Single line message, not the part of the above 2017-09-13 15:36:57.228948-0700 localhost Runner[37195]: (Flutter) Single line message, not the part of the above
''' '''
.codeUnits]); ))
}); ..addCommand(const FakeCommand(
when(mockProcess.stderr) command: <String>['tail', '-n', '0', '-F', '/private/var/log/system.log']
.thenAnswer((Invocation invocation) => const Stream<List<int>>.empty()); ));
// Delay return of exitCode until after stdout stream data, since it terminates the logger.
when(mockProcess.exitCode)
.thenAnswer((Invocation invocation) => Future<int>.delayed(Duration.zero, () => 0));
return Future<Process>.value(mockProcess);
});
final IOSSimulator device = IOSSimulator( final IOSSimulator device = IOSSimulator(
'123456', '123456',
...@@ -630,8 +647,9 @@ void main() { ...@@ -630,8 +647,9 @@ void main() {
' and goes...', ' and goes...',
'Single line message, not the part of the above' 'Single line message, not the part of the above'
]); ]);
expect(fakeProcessManager.hasRemainingExpectations, isFalse);
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
ProcessManager: () => mockProcessManager, ProcessManager: () => fakeProcessManager,
FileSystem: () => fileSystem, FileSystem: () => fileSystem,
Platform: () => osx, Platform: () => osx,
}); });
...@@ -639,12 +657,25 @@ void main() { ...@@ -639,12 +657,25 @@ void main() {
group('unified logging', () { group('unified logging', () {
testUsingContext('log reader handles escaped multiline messages', () async { testUsingContext('log reader handles escaped multiline messages', () async {
when(mockProcessManager.start(any, environment: null, workingDirectory: null)) const String logPredicate = 'eventType = logEvent AND processImagePath ENDSWITH "Runner" '
.thenAnswer((Invocation invocation) { 'AND (senderImagePath ENDSWITH "/Flutter" OR senderImagePath ENDSWITH "/libswiftCore.dylib" '
final Process mockProcess = MockProcess(); 'OR processImageUUID == senderImageUUID) AND NOT(eventMessage CONTAINS ": could not find icon '
when(mockProcess.stdout) 'for representation -> com.apple.") AND NOT(eventMessage BEGINSWITH "assertion failed: ") '
.thenAnswer((Invocation invocation) { 'AND NOT(eventMessage CONTAINS " libxpc.dylib ")';
return Stream<List<int>>.fromIterable(<List<int>>[''' fakeProcessManager.addCommand(const FakeCommand(
command: <String>[
'/usr/bin/xcrun',
'simctl',
'spawn',
'123456',
'log',
'stream',
'--style',
'json',
'--predicate',
logPredicate,
],
stdout: '''
},{ },{
"traceID" : 37579774151491588, "traceID" : 37579774151491588,
"eventMessage" : "Single line message", "eventMessage" : "Single line message",
...@@ -658,15 +689,7 @@ void main() { ...@@ -658,15 +689,7 @@ void main() {
"eventType" : "logEvent" "eventType" : "logEvent"
},{ },{
''' '''
.codeUnits]); ));
});
when(mockProcess.stderr)
.thenAnswer((Invocation invocation) => const Stream<List<int>>.empty());
// Delay return of exitCode until after stdout stream data, since it terminates the logger.
when(mockProcess.exitCode)
.thenAnswer((Invocation invocation) => Future<int>.delayed(Duration.zero, () => 0));
return Future<Process>.value(mockProcess);
});
final IOSSimulator device = IOSSimulator( final IOSSimulator device = IOSSimulator(
'123456', '123456',
...@@ -683,8 +706,9 @@ void main() { ...@@ -683,8 +706,9 @@ void main() {
'Single line message', 'Multi line message\n continues...\n continues...', 'Single line message', 'Multi line message\n continues...\n continues...',
'Single line message, not the part of the above' 'Single line message, not the part of the above'
]); ]);
expect(fakeProcessManager.hasRemainingExpectations, isFalse);
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
ProcessManager: () => mockProcessManager, ProcessManager: () => fakeProcessManager,
FileSystem: () => fileSystem, FileSystem: () => fileSystem,
}); });
}); });
......
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