1/*
2 * Copyright (C) 2024 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 */
16import {assertDefined} from 'common/assert_utils';
17import {TimestampConverterUtils} from 'test/unit/timestamp_converter_utils';
18import {UnitTestUtils} from 'test/unit/utils';
19import {Parser} from 'trace/parser';
20import {TraceType} from 'trace/trace_type';
21import {PropertyTreeNode} from 'trace/tree_node/property_tree_node';
22
23describe('Perfetto ParserProtolog', () => {
24  let parser: Parser<PropertyTreeNode>;
25
26  beforeAll(async () => {
27    jasmine.addCustomEqualityTester(UnitTestUtils.timestampEqualityTester);
28    parser = await UnitTestUtils.getPerfettoParser(
29      TraceType.PROTO_LOG,
30      'traces/perfetto/protolog.perfetto-trace',
31    );
32  });
33
34  it('has expected trace type', () => {
35    expect(parser.getTraceType()).toEqual(TraceType.PROTO_LOG);
36  });
37
38  it('provides timestamps', () => {
39    const timestamps = assertDefined(parser.getTimestamps());
40
41    expect(timestamps.length).toEqual(3);
42
43    const expected = [
44      TimestampConverterUtils.makeRealTimestamp(1713866817780323315n),
45      TimestampConverterUtils.makeRealTimestamp(1713866817780323415n),
46      TimestampConverterUtils.makeRealTimestamp(1713866817780323445n),
47    ];
48    expect(timestamps.slice(0, 3)).toEqual(expected);
49  });
50
51  it('reconstructs human-readable log message (REAL time)', async () => {
52    const message = await parser.getEntry(0);
53
54    expect(
55      assertDefined(message.getChildByName('text')).formattedValue(),
56    ).toEqual(
57      'Test message with different int formats: 1776, 0o3360, 0x6f0, 888.000000, 8.880000e+02.',
58    );
59    expect(
60      assertDefined(message.getChildByName('timestamp')).formattedValue(),
61    ).toEqual('2024-04-23, 10:06:57.780');
62    expect(
63      assertDefined(message.getChildByName('tag')).formattedValue(),
64    ).toEqual('MySecondGroup');
65    expect(
66      assertDefined(message.getChildByName('level')).formattedValue(),
67    ).toEqual('WARN');
68    expect(
69      assertDefined(message.getChildByName('at')).formattedValue(),
70    ).toEqual('<NO_LOC>');
71  });
72
73  it('messages are ordered by timestamp', async () => {
74    let prevEntryTs = 0n;
75    for (let i = 0; i < parser.getLengthEntries(); i++) {
76      const ts = (await parser.getEntry(i))
77        .getChildByName('timestamp')
78        ?.getValue();
79      expect(ts >= prevEntryTs).toBeTrue();
80      prevEntryTs = ts;
81    }
82  });
83
84  it('timestamps are ordered', () => {
85    let prevEntryTs = 0n;
86    for (const ts of assertDefined(parser.getTimestamps())) {
87      expect(ts.getValueNs() >= prevEntryTs).toBeTrue();
88      prevEntryTs = ts.getValueNs();
89    }
90  });
91});
92