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 {Timestamp} from 'common/time'; 19import {TimestampConverterUtils} from 'test/unit/timestamp_converter_utils'; 20import {UnitTestUtils} from 'test/unit/utils'; 21import {CoarseVersion} from 'trace/coarse_version'; 22import {Parser} from 'trace/parser'; 23import {TraceType} from 'trace/trace_type'; 24import {PropertyTreeNode} from 'trace/tree_node/property_tree_node'; 25 26interface ExpectedMessage { 27 'message': string; 28 'ts': string; 29 'at': string; 30 'level': string; 31 'tag': string; 32} 33 34const genProtoLogTest = 35 ( 36 traceFile: string, 37 timestampCount: number, 38 first3ExpectedRealTimestamps: Timestamp[], 39 expectedFirstMessage: ExpectedMessage, 40 ) => 41 () => { 42 let parser: Parser<PropertyTreeNode>; 43 44 beforeAll(async () => { 45 jasmine.addCustomEqualityTester(UnitTestUtils.timestampEqualityTester); 46 parser = (await UnitTestUtils.getParser( 47 traceFile, 48 )) as Parser<PropertyTreeNode>; 49 }); 50 51 it('has expected trace type', () => { 52 expect(parser.getTraceType()).toEqual(TraceType.PROTO_LOG); 53 }); 54 55 it('has expected coarse version', () => { 56 expect(parser.getCoarseVersion()).toEqual(CoarseVersion.LEGACY); 57 }); 58 59 it('has expected length', () => { 60 expect(parser.getLengthEntries()).toEqual(timestampCount); 61 }); 62 63 it('provides timestamps', () => { 64 const timestamps = assertDefined(parser.getTimestamps()); 65 expect(timestamps.length).toEqual(timestampCount); 66 67 expect(timestamps.slice(0, 3)).toEqual(first3ExpectedRealTimestamps); 68 }); 69 70 it('reconstructs human-readable log message', async () => { 71 const message = await parser.getEntry(0); 72 73 expect( 74 assertDefined(message.getChildByName('text')).formattedValue(), 75 ).toEqual(expectedFirstMessage['message']); 76 expect( 77 assertDefined(message.getChildByName('timestamp')).formattedValue(), 78 ).toEqual(expectedFirstMessage['ts']); 79 expect( 80 assertDefined(message.getChildByName('tag')).formattedValue(), 81 ).toEqual(expectedFirstMessage['tag']); 82 expect( 83 assertDefined(message.getChildByName('level')).formattedValue(), 84 ).toEqual(expectedFirstMessage['level']); 85 expect( 86 assertDefined(message.getChildByName('at')).formattedValue(), 87 ).toEqual(expectedFirstMessage['at']); 88 }); 89 90 it('reconstructs human-readable log message (REAL time)', async () => { 91 const message = await parser.getEntry(0); 92 93 expect( 94 assertDefined(message.getChildByName('text')).formattedValue(), 95 ).toEqual(expectedFirstMessage['message']); 96 expect( 97 assertDefined(message.getChildByName('timestamp')).formattedValue(), 98 ).toEqual(expectedFirstMessage['ts']); 99 expect( 100 assertDefined(message.getChildByName('tag')).formattedValue(), 101 ).toEqual(expectedFirstMessage['tag']); 102 expect( 103 assertDefined(message.getChildByName('level')).formattedValue(), 104 ).toEqual(expectedFirstMessage['level']); 105 expect( 106 assertDefined(message.getChildByName('at')).formattedValue(), 107 ).toEqual(expectedFirstMessage['at']); 108 }); 109 }; 110 111describe('ParserProtoLog', () => { 112 describe( 113 '32', 114 genProtoLogTest( 115 'traces/elapsed_and_real_timestamp/ProtoLog32.pb', 116 50, 117 [ 118 TimestampConverterUtils.makeRealTimestamp(1655727125377266486n), 119 TimestampConverterUtils.makeRealTimestamp(1655727125377336718n), 120 TimestampConverterUtils.makeRealTimestamp(1655727125377350430n), 121 ], 122 { 123 'message': 124 'InsetsSource updateVisibility for ITYPE_IME, serverVisible: false clientVisible: false', 125 'ts': '2022-06-20, 12:12:05.377', 126 'tag': 'WindowManager', 127 'level': 'DEBUG', 128 'at': 'com/android/server/wm/InsetsSourceProvider.java', 129 }, 130 ), 131 ); 132 describe( 133 '64', 134 genProtoLogTest( 135 'traces/elapsed_and_real_timestamp/ProtoLog64.pb', 136 4615, 137 [ 138 TimestampConverterUtils.makeRealTimestamp(1709196806399529939n), 139 TimestampConverterUtils.makeRealTimestamp(1709196806399763866n), 140 TimestampConverterUtils.makeRealTimestamp(1709196806400297151n), 141 ], 142 { 143 'message': 'Starting activity when config will change = false', 144 'ts': '2024-02-29, 08:53:26.399', 145 'tag': 'WindowManager', 146 'level': 'VERBOSE', 147 'at': 'com/android/server/wm/ActivityStarter.java', 148 }, 149 ), 150 ); 151 describe( 152 'Missing config message', 153 genProtoLogTest( 154 'traces/elapsed_and_real_timestamp/ProtoLogMissingConfigMessage.pb', 155 7295, 156 [ 157 TimestampConverterUtils.makeRealTimestamp(1669053909777144978n), 158 TimestampConverterUtils.makeRealTimestamp(1669053909778011697n), 159 TimestampConverterUtils.makeRealTimestamp(1669053909778800707n), 160 ], 161 { 162 'message': 'SURFACE isColorSpaceAgnostic=true: NotificationShade', 163 'ts': '2022-11-21, 18:05:09.777', 164 'tag': 'WindowManager', 165 'level': 'INFO', 166 'at': 'com/android/server/wm/WindowSurfaceController.java', 167 }, 168 ), 169 ); 170}); 171