1/* 2 * Copyright (C) 2022 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17import {assertDefined} from 'common/assert_utils'; 18import { 19 TimestampConverterUtils, 20 timestampEqualityTester, 21} from 'common/time/test_utils'; 22import {Timestamp} from 'common/time/time'; 23import {UnitTestUtils} from 'test/unit/utils'; 24import {CoarseVersion} from 'trace/coarse_version'; 25import {Parser} from 'trace/parser'; 26import {TraceType} from 'trace/trace_type'; 27import {PropertyTreeNode} from 'trace/tree_node/property_tree_node'; 28 29interface ExpectedMessage { 30 'message': string; 31 'ts': string; 32 'at': string; 33 'level': string; 34 'tag': string; 35} 36 37const genProtoLogTest = 38 ( 39 traceFile: string, 40 timestampCount: number, 41 first3ExpectedRealTimestamps: Timestamp[], 42 expectedFirstMessage: ExpectedMessage, 43 ) => 44 () => { 45 let parser: Parser<PropertyTreeNode>; 46 47 beforeAll(async () => { 48 jasmine.addCustomEqualityTester(timestampEqualityTester); 49 parser = (await UnitTestUtils.getParser( 50 traceFile, 51 )) as Parser<PropertyTreeNode>; 52 }); 53 54 it('has expected trace type', () => { 55 expect(parser.getTraceType()).toEqual(TraceType.PROTO_LOG); 56 }); 57 58 it('has expected coarse version', () => { 59 expect(parser.getCoarseVersion()).toEqual(CoarseVersion.LEGACY); 60 }); 61 62 it('has expected length', () => { 63 expect(parser.getLengthEntries()).toEqual(timestampCount); 64 }); 65 66 it('provides timestamps', () => { 67 const timestamps = assertDefined(parser.getTimestamps()); 68 expect(timestamps.length).toEqual(timestampCount); 69 70 expect(timestamps.slice(0, 3)).toEqual(first3ExpectedRealTimestamps); 71 }); 72 73 it('reconstructs human-readable log message', async () => { 74 const message = await parser.getEntry(0); 75 76 expect( 77 assertDefined(message.getChildByName('text')).formattedValue(), 78 ).toEqual(expectedFirstMessage['message']); 79 expect( 80 assertDefined(message.getChildByName('timestamp')).formattedValue(), 81 ).toEqual(expectedFirstMessage['ts']); 82 expect( 83 assertDefined(message.getChildByName('tag')).formattedValue(), 84 ).toEqual(expectedFirstMessage['tag']); 85 expect( 86 assertDefined(message.getChildByName('level')).formattedValue(), 87 ).toEqual(expectedFirstMessage['level']); 88 expect( 89 assertDefined(message.getChildByName('at')).formattedValue(), 90 ).toEqual(expectedFirstMessage['at']); 91 }); 92 93 it('reconstructs human-readable log message (REAL time)', async () => { 94 const message = await parser.getEntry(0); 95 96 expect( 97 assertDefined(message.getChildByName('text')).formattedValue(), 98 ).toEqual(expectedFirstMessage['message']); 99 expect( 100 assertDefined(message.getChildByName('timestamp')).formattedValue(), 101 ).toEqual(expectedFirstMessage['ts']); 102 expect( 103 assertDefined(message.getChildByName('tag')).formattedValue(), 104 ).toEqual(expectedFirstMessage['tag']); 105 expect( 106 assertDefined(message.getChildByName('level')).formattedValue(), 107 ).toEqual(expectedFirstMessage['level']); 108 expect( 109 assertDefined(message.getChildByName('at')).formattedValue(), 110 ).toEqual(expectedFirstMessage['at']); 111 }); 112 }; 113 114describe('ParserProtoLog', () => { 115 describe( 116 '32', 117 genProtoLogTest( 118 'traces/elapsed_and_real_timestamp/ProtoLog32.pb', 119 50, 120 [ 121 TimestampConverterUtils.makeRealTimestamp(1655727125377266486n), 122 TimestampConverterUtils.makeRealTimestamp(1655727125377336718n), 123 TimestampConverterUtils.makeRealTimestamp(1655727125377350430n), 124 ], 125 { 126 'message': 127 'InsetsSource updateVisibility for ITYPE_IME, serverVisible: false clientVisible: false', 128 'ts': '2022-06-20, 12:12:05.377', 129 'tag': 'WindowManager', 130 'level': 'DEBUG', 131 'at': 'com/android/server/wm/InsetsSourceProvider.java', 132 }, 133 ), 134 ); 135 describe( 136 '64', 137 genProtoLogTest( 138 'traces/elapsed_and_real_timestamp/ProtoLog64.pb', 139 4615, 140 [ 141 TimestampConverterUtils.makeRealTimestamp(1709196806399529939n), 142 TimestampConverterUtils.makeRealTimestamp(1709196806399763866n), 143 TimestampConverterUtils.makeRealTimestamp(1709196806400297151n), 144 ], 145 { 146 'message': 'Starting activity when config will change = false', 147 'ts': '2024-02-29, 08:53:26.400', 148 'tag': 'WindowManager', 149 'level': 'VERBOSE', 150 'at': 'com/android/server/wm/ActivityStarter.java', 151 }, 152 ), 153 ); 154 describe( 155 'Missing config message', 156 genProtoLogTest( 157 'traces/elapsed_and_real_timestamp/ProtoLogMissingConfigMessage.pb', 158 7295, 159 [ 160 TimestampConverterUtils.makeRealTimestamp(1669053909777144978n), 161 TimestampConverterUtils.makeRealTimestamp(1669053909778011697n), 162 TimestampConverterUtils.makeRealTimestamp(1669053909778800707n), 163 ], 164 { 165 'message': 'SURFACE isColorSpaceAgnostic=true: NotificationShade', 166 'ts': '2022-11-21, 18:05:09.777', 167 'tag': 'WindowManager', 168 'level': 'INFO', 169 'at': 'com/android/server/wm/WindowSurfaceController.java', 170 }, 171 ), 172 ); 173}); 174