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 */
16import {assertDefined} from 'common/assert_utils';
17import {TimestampConverterUtils} from 'test/unit/timestamp_converter_utils';
18import {TraceBuilder} from 'test/unit/trace_builder';
19import {UnitTestUtils} from 'test/unit/utils';
20import {CoarseVersion} from 'trace/coarse_version';
21import {CustomQueryType} from 'trace/custom_query';
22import {Parser} from 'trace/parser';
23import {TraceType} from 'trace/trace_type';
24import {PropertyTreeNode} from 'trace/tree_node/property_tree_node';
25
26describe('ParserTransactions', () => {
27  describe('trace with real timestamps', () => {
28    let parser: Parser<PropertyTreeNode>;
29
30    beforeAll(async () => {
31      jasmine.addCustomEqualityTester(UnitTestUtils.timestampEqualityTester);
32      parser = (await UnitTestUtils.getParser(
33        'traces/elapsed_and_real_timestamp/Transactions.pb',
34      )) as Parser<PropertyTreeNode>;
35    });
36
37    it('has expected trace type', () => {
38      expect(parser.getTraceType()).toEqual(TraceType.TRANSACTIONS);
39    });
40
41    it('has expected coarse version', () => {
42      expect(parser.getCoarseVersion()).toEqual(CoarseVersion.LEGACY);
43    });
44
45    it('provides timestamps', () => {
46      const timestamps = assertDefined(parser.getTimestamps());
47
48      expect(timestamps.length).toEqual(712);
49
50      const expected = [
51        TimestampConverterUtils.makeRealTimestamp(1659507541051480997n),
52        TimestampConverterUtils.makeRealTimestamp(1659507541118452067n),
53        TimestampConverterUtils.makeRealTimestamp(1659507542621651001n),
54      ];
55      expect(timestamps.slice(0, 3)).toEqual(expected);
56    });
57
58    it('retrieves trace entry from timestamp', async () => {
59      const entry = await parser.getEntry(1);
60      expect(entry.id).toEqual('TransactionsTraceEntry entry');
61    });
62
63    it("decodes 'what' field in proto", async () => {
64      {
65        const entry = await parser.getEntry(0);
66        const transactions = assertDefined(
67          entry.getChildByName('transactions'),
68        );
69
70        expect(
71          transactions
72            .getChildByName('0')
73            ?.getChildByName('layerChanges')
74            ?.getChildByName('0')
75            ?.getChildByName('what')
76            ?.formattedValue(),
77        ).toEqual('eLayerChanged');
78
79        expect(
80          transactions
81            .getChildByName('1')
82            ?.getChildByName('layerChanges')
83            ?.getChildByName('0')
84            ?.getChildByName('what')
85            ?.formattedValue(),
86        ).toEqual('eFlagsChanged | eDestinationFrameChanged');
87      }
88      {
89        const entry = await parser.getEntry(222);
90        const transactions = assertDefined(
91          entry.getChildByName('transactions'),
92        );
93
94        expect(
95          transactions
96            .getChildByName('1')
97            ?.getChildByName('displayChanges')
98            ?.getChildByName('0')
99            ?.getChildByName('what')
100            ?.formattedValue(),
101        ).toEqual(
102          'eLayerStackChanged | eDisplayProjectionChanged | eFlagsChanged',
103        );
104      }
105    });
106
107    it('supports VSYNCID custom query', async () => {
108      const trace = new TraceBuilder()
109        .setType(TraceType.TRANSACTIONS)
110        .setParser(parser)
111        .build();
112      const entries = await trace
113        .sliceEntries(0, 3)
114        .customQuery(CustomQueryType.VSYNCID);
115      const values = entries.map((entry) => entry.getValue());
116      expect(values).toEqual([1n, 2n, 3n]);
117    });
118  });
119
120  describe('trace with only elapsed timestamps', () => {
121    let parser: Parser<PropertyTreeNode>;
122
123    beforeAll(async () => {
124      parser = (await UnitTestUtils.getParser(
125        'traces/elapsed_timestamp/Transactions.pb',
126      )) as Parser<PropertyTreeNode>;
127    });
128
129    it('has expected trace type', () => {
130      expect(parser.getTraceType()).toEqual(TraceType.TRANSACTIONS);
131    });
132
133    it('provides timestamps', () => {
134      const timestamps = assertDefined(parser.getTimestamps());
135
136      expect(timestamps.length).toEqual(4997);
137
138      const expected = [
139        TimestampConverterUtils.makeElapsedTimestamp(14862317023n),
140        TimestampConverterUtils.makeElapsedTimestamp(14873423549n),
141        TimestampConverterUtils.makeElapsedTimestamp(14884850511n),
142      ];
143      expect(timestamps.slice(0, 3)).toEqual(expected);
144    });
145  });
146});
147