xref: /aosp_15_r20/development/tools/winscope/src/viewers/viewer_protolog/presenter_test.ts (revision 90c8c64db3049935a07c6143d7fd006e26f8ecca)
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 ANYf 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 {InMemoryStorage} from 'common/in_memory_storage';
19import {TracePositionUpdate} from 'messaging/winscope_event';
20import {PropertyTreeBuilder} from 'test/unit/property_tree_builder';
21import {TimestampConverterUtils} from 'test/unit/timestamp_converter_utils';
22import {TraceBuilder} from 'test/unit/trace_builder';
23import {UnitTestUtils} from 'test/unit/utils';
24import {Trace} from 'trace/trace';
25import {TraceType} from 'trace/trace_type';
26import {
27  DEFAULT_PROPERTY_FORMATTER,
28  TIMESTAMP_NODE_FORMATTER,
29} from 'trace/tree_node/formatters';
30import {PropertyTreeNode} from 'trace/tree_node/property_tree_node';
31import {NotifyLogViewCallbackType} from 'viewers/common/abstract_log_viewer_presenter';
32import {AbstractLogViewerPresenterTest} from 'viewers/common/abstract_log_viewer_presenter_test';
33import {LogSelectFilter, LogTextFilter} from 'viewers/common/log_filters';
34import {TextFilter} from 'viewers/common/text_filter';
35import {LogHeader} from 'viewers/common/ui_data_log';
36import {Presenter} from './presenter';
37import {UiData} from './ui_data';
38
39class PresenterProtologTest extends AbstractLogViewerPresenterTest<UiData> {
40  override readonly expectedHeaders = [
41    {
42      header: new LogHeader(
43        {name: 'Log Level', cssClass: 'log-level'},
44        new LogSelectFilter(Array.from({length: 3}, () => '')),
45      ),
46      options: ['level0', 'level1', 'level2'],
47    },
48    {
49      header: new LogHeader(
50        {name: 'Tag', cssClass: 'tag'},
51        new LogSelectFilter(Array.from({length: 3}, () => '')),
52      ),
53      options: ['tag0', 'tag1', 'tag2'],
54    },
55    {
56      header: new LogHeader(
57        {name: 'Source files', cssClass: 'source-file'},
58        new LogSelectFilter(Array.from({length: 3}, () => '')),
59      ),
60      options: ['sourcefile0', 'sourcefile1', 'sourcefile2'],
61    },
62    {
63      header: new LogHeader(
64        {name: 'Search text', cssClass: 'text'},
65        new LogTextFilter(new TextFilter()),
66      ),
67    },
68  ];
69  private trace: Trace<PropertyTreeNode> | undefined;
70  private positionUpdate: TracePositionUpdate | undefined;
71
72  override async setUpTestEnvironment(): Promise<void> {
73    const time10 = TimestampConverterUtils.makeRealTimestamp(10n);
74    const time11 = TimestampConverterUtils.makeRealTimestamp(11n);
75    const time12 = TimestampConverterUtils.makeRealTimestamp(12n);
76    const elapsedTime10 = TimestampConverterUtils.makeElapsedTimestamp(10n);
77    const elapsedTime20 = TimestampConverterUtils.makeElapsedTimestamp(20n);
78    const elapsedTime30 = TimestampConverterUtils.makeElapsedTimestamp(30n);
79
80    const entries = [
81      new PropertyTreeBuilder()
82        .setRootId('ProtologTrace')
83        .setName('message')
84        .setChildren([
85          {name: 'text', value: 'text0', formatter: DEFAULT_PROPERTY_FORMATTER},
86          {
87            name: 'timestamp',
88            value: elapsedTime10,
89            formatter: TIMESTAMP_NODE_FORMATTER,
90          },
91          {name: 'tag', value: 'tag0', formatter: DEFAULT_PROPERTY_FORMATTER},
92          {
93            name: 'level',
94            value: 'level0',
95            formatter: DEFAULT_PROPERTY_FORMATTER,
96          },
97          {
98            name: 'at',
99            value: 'sourcefile0',
100            formatter: DEFAULT_PROPERTY_FORMATTER,
101          },
102        ])
103        .build(),
104
105      new PropertyTreeBuilder()
106        .setRootId('ProtologTrace')
107        .setName('message')
108        .setChildren([
109          {name: 'text', value: 'text1', formatter: DEFAULT_PROPERTY_FORMATTER},
110          {
111            name: 'timestamp',
112            value: elapsedTime20,
113            formatter: TIMESTAMP_NODE_FORMATTER,
114          },
115          {name: 'tag', value: 'tag1', formatter: DEFAULT_PROPERTY_FORMATTER},
116          {
117            name: 'level',
118            value: 'level1',
119            formatter: DEFAULT_PROPERTY_FORMATTER,
120          },
121          {
122            name: 'at',
123            value: 'sourcefile1',
124            formatter: DEFAULT_PROPERTY_FORMATTER,
125          },
126        ])
127        .build(),
128
129      new PropertyTreeBuilder()
130        .setRootId('ProtologTrace')
131        .setName('message')
132        .setChildren([
133          {name: 'text', value: 'text2', formatter: DEFAULT_PROPERTY_FORMATTER},
134          {
135            name: 'timestamp',
136            value: elapsedTime30,
137            formatter: TIMESTAMP_NODE_FORMATTER,
138          },
139          {name: 'tag', value: 'tag2', formatter: DEFAULT_PROPERTY_FORMATTER},
140          {
141            name: 'level',
142            value: 'level2',
143            formatter: DEFAULT_PROPERTY_FORMATTER,
144          },
145          {
146            name: 'at',
147            value: 'sourcefile2',
148            formatter: DEFAULT_PROPERTY_FORMATTER,
149          },
150        ])
151        .build(),
152    ];
153
154    this.trace = new TraceBuilder<PropertyTreeNode>()
155      .setEntries(entries)
156      .setTimestamps([time10, time11, time12])
157      .build();
158
159    this.positionUpdate = TracePositionUpdate.fromTraceEntry(
160      this.trace.getEntry(0),
161    );
162  }
163
164  override async createPresenterWithEmptyTrace(
165    callback: NotifyLogViewCallbackType<UiData>,
166  ): Promise<Presenter> {
167    const trace = UnitTestUtils.makeEmptyTrace(TraceType.PROTO_LOG);
168    return new Presenter(trace, callback, new InMemoryStorage());
169  }
170
171  override async createPresenter(
172    callback: NotifyLogViewCallbackType<UiData>,
173  ): Promise<Presenter> {
174    const presenter = new Presenter(
175      assertDefined(this.trace),
176      callback,
177      new InMemoryStorage(),
178    );
179    await presenter.onAppEvent(this.getPositionUpdate()); // trigger initialization
180    return presenter;
181  }
182
183  override getPositionUpdate(): TracePositionUpdate {
184    return assertDefined(this.positionUpdate);
185  }
186}
187
188describe('PresenterProtolog', () => {
189  new PresenterProtologTest().execute();
190});
191