• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env python3
2# Copyright (C) 2023 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 a
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
16from python.generators.diff_tests.testing import Path, DataPath, Metric
17from python.generators.diff_tests.testing import Csv, Json, TextProto
18from python.generators.diff_tests.testing import DiffTestBlueprint
19from python.generators.diff_tests.testing import TestSuite
20
21
22class ChromeMetrics(TestSuite):
23  # Tests related to Chrome's use of Perfetto. Chrome histogram hashes
24  def test_chrome_histogram_hashes(self):
25    return DiffTestBlueprint(
26        trace=TextProto(r"""
27        packet {
28          trusted_packet_sequence_id: 1
29          timestamp: 0
30          incremental_state_cleared: true
31          track_event {
32            categories: "cat1"
33            type: 3
34            name_iid: 1
35            chrome_histogram_sample {
36              name_hash: 10
37              sample: 100
38            }
39          }
40        }
41        packet {
42          trusted_packet_sequence_id: 1
43          timestamp: 0
44          incremental_state_cleared: true
45          track_event {
46            categories: "cat2"
47            type: 3
48            name_iid: 2
49            chrome_histogram_sample {
50              name_hash: 20
51            }
52          }
53        }
54        """),
55        query=Metric('chrome_histogram_hashes'),
56        out=TextProto(r"""
57        [perfetto.protos.chrome_histogram_hashes]: {
58          hash: 10
59          hash: 20
60        }
61        """))
62
63  # Chrome user events
64  def test_chrome_user_event_hashes(self):
65    return DiffTestBlueprint(
66        trace=TextProto(r"""
67        packet {
68          trusted_packet_sequence_id: 1
69          timestamp: 0
70          incremental_state_cleared: true
71          track_event {
72            categories: "cat1"
73            type: 3
74            name_iid: 1
75            chrome_user_event {
76              action_hash: 10
77            }
78          }
79        }
80        packet {
81          trusted_packet_sequence_id: 1
82          timestamp: 0
83          incremental_state_cleared: true
84          track_event {
85            categories: "cat2"
86            type: 3
87            name_iid: 2
88            chrome_user_event {
89              action_hash: 20
90            }
91          }
92        }
93        """),
94        query=Metric('chrome_user_event_hashes'),
95        out=TextProto(r"""
96        [perfetto.protos.chrome_user_event_hashes]: {
97          action_hash: 10
98          action_hash: 20
99        }
100        """))
101
102  # Chrome performance mark
103  def test_chrome_performance_mark_hashes(self):
104    return DiffTestBlueprint(
105        trace=TextProto(r"""
106        packet {
107          trusted_packet_sequence_id: 1
108          timestamp: 0
109          incremental_state_cleared: true
110          track_event {
111            categories: "cat1"
112            type: 3
113            name: "name1"
114            [perfetto.protos.ChromeTrackEvent.chrome_hashed_performance_mark] {
115              site_hash: 10
116              mark_hash: 100
117            }
118          }
119        }
120        packet {
121          trusted_packet_sequence_id: 1
122          timestamp: 0
123          incremental_state_cleared: true
124          track_event {
125            categories: "cat2"
126            type: 3
127            name: "name2"
128            [perfetto.protos.ChromeTrackEvent.chrome_hashed_performance_mark] {
129              site_hash: 20
130              mark_hash: 200
131            }
132          }
133        }
134        """),
135        query=Metric('chrome_performance_mark_hashes'),
136        out=TextProto(r"""
137        [perfetto.protos.chrome_performance_mark_hashes]: {
138          site_hash: 10
139          site_hash: 20
140          mark_hash: 100
141          mark_hash: 200
142        }
143        """))
144
145  # Chrome study
146  def test_chrome_study_hashes(self):
147    return DiffTestBlueprint(
148        trace=TextProto(r"""
149        packet {
150          trusted_packet_sequence_id: 1
151          timestamp: 0
152          incremental_state_cleared: true
153          chrome_trigger {
154            trigger_name_hash: 10
155          }
156        }
157        packet {
158          trusted_packet_sequence_id: 1
159          timestamp: 0
160          incremental_state_cleared: true
161          chrome_trigger {
162            trigger_name_hash: 20
163          }
164        }
165        """),
166        query=Metric('chrome_study_hashes'),
167        out=TextProto(r"""
168        [perfetto.protos.chrome_study_hashes]: {
169          hash: 10
170          hash: 20
171        }
172        """))
173
174  # Chrome reliable range
175  def test_chrome_reliable_range(self):
176    return DiffTestBlueprint(
177        trace=Path('chrome_reliable_range.textproto'),
178        query=Path('chrome_reliable_range_test.sql'),
179        out=Csv("""
180        "start","reason","debug_limiting_upid","debug_limiting_utid"
181        12,"First slice for utid=2","[NULL]",2
182        """))
183
184  def test_chrome_reliable_range_cropping(self):
185    return DiffTestBlueprint(
186        trace=Path('chrome_reliable_range_cropping.textproto'),
187        query=Path('chrome_reliable_range_test.sql'),
188        out=Csv("""
189        "start","reason","debug_limiting_upid","debug_limiting_utid"
190        10000,"Range of interest packet","[NULL]",2
191        """))
192
193  def test_chrome_reliable_range_missing_processes(self):
194    return DiffTestBlueprint(
195        trace=Path('chrome_reliable_range_missing_processes.textproto'),
196        query=Path('chrome_reliable_range_test.sql'),
197        out=Csv("""
198        "start","reason","debug_limiting_upid","debug_limiting_utid"
199        1011,"Missing process data for upid=2",2,1
200        """))
201
202  def test_chrome_reliable_range_missing_browser_main(self):
203    return DiffTestBlueprint(
204        trace=Path('chrome_reliable_range_missing_browser_main.textproto'),
205        query=Path('chrome_reliable_range_test.sql'),
206        out=Csv("""
207        "start","reason","debug_limiting_upid","debug_limiting_utid"
208        1011,"Missing main thread for upid=1",1,1
209        """))
210
211  def test_chrome_reliable_range_missing_gpu_main(self):
212    return DiffTestBlueprint(
213        trace=Path('chrome_reliable_range_missing_gpu_main.textproto'),
214        query=Path('chrome_reliable_range_test.sql'),
215        out=Csv("""
216        "start","reason","debug_limiting_upid","debug_limiting_utid"
217        1011,"Missing main thread for upid=1",1,1
218        """))
219
220  def test_chrome_reliable_range_missing_renderer_main(self):
221    return DiffTestBlueprint(
222        trace=Path('chrome_reliable_range_missing_renderer_main.textproto'),
223        query=Path('chrome_reliable_range_test.sql'),
224        out=Csv("""
225        "start","reason","debug_limiting_upid","debug_limiting_utid"
226        1011,"Missing main thread for upid=1",1,1
227        """))
228
229  def test_chrome_reliable_range_non_chrome_process(self):
230    return DiffTestBlueprint(
231        # We need a trace with a large number of non-chrome slices, so that the
232        # reliable range is affected by their filtering.
233        trace=DataPath('example_android_trace_30s.pb'),
234        query=Path('chrome_reliable_range_test.sql'),
235        out=Csv("""
236        "start","reason","debug_limiting_upid","debug_limiting_utid"
237        0,"[NULL]","[NULL]","[NULL]"
238        """))
239
240  # Chrome slices
241  def test_chrome_slice_names(self):
242    return DiffTestBlueprint(
243        trace=TextProto(r"""
244        packet {
245          trusted_packet_sequence_id: 1
246          timestamp: 1000
247          track_event {
248            categories: "cat"
249            name: "Looper.Dispatch: class1"
250            type: 3
251          }
252        }
253        packet {
254          trusted_packet_sequence_id: 1
255          timestamp: 2000
256          track_event {
257            categories: "cat"
258            name: "name2"
259            type: 3
260          }
261        }
262        packet {
263          chrome_metadata {
264            chrome_version_code: 123
265          }
266        }
267        """),
268        query=Metric('chrome_slice_names'),
269        out=TextProto(r"""
270        [perfetto.protos.chrome_slice_names]: {
271          chrome_version_code: 123
272          slice_name: "Looper.Dispatch: class1"
273          slice_name: "name2"
274        }
275        """))
276
277  # Chrome stack samples.
278  def test_chrome_stack_samples_for_task(self):
279    return DiffTestBlueprint(
280        trace=DataPath('chrome_stack_traces_symbolized_trace.pftrace'),
281        query="""
282        SELECT RUN_METRIC('chrome/chrome_stack_samples_for_task.sql',
283            'target_duration_ms', '0.000001',
284            'thread_name', '"CrBrowserMain"',
285            'task_name', '"sendTouchEvent"');
286
287        SELECT
288          sample.description,
289          sample.ts,
290          sample.depth
291        FROM chrome_stack_samples_for_task sample
292        JOIN (
293            SELECT
294              ts,
295              dur
296            FROM slice
297            WHERE ts = 696373965001470
298        ) test_slice
299        ON sample.ts >= test_slice.ts
300          AND sample.ts <= test_slice.ts + test_slice.dur
301        ORDER BY sample.ts, sample.depth;
302        """,
303        out=Path('chrome_stack_samples_for_task_test.out'))
304
305  # Trace proto content
306  def test_proto_content(self):
307    return DiffTestBlueprint(
308        trace=DataPath('chrome_scroll_without_vsync.pftrace'),
309        query=Path('proto_content_test.sql'),
310        out=Path('proto_content.out'))
311
312  # TODO(mayzner): Uncomment when it works
313  # def test_proto_content_path(self):
314  #   return DiffTestBlueprint(
315  #       trace=DataPath('chrome_scroll_without_vsync.pftrace'),
316  #       query=Path('proto_content_path_test.sql'),
317  #       out=Csv("""
318  #       "total_size","field_type","field_name","parent_id","event_category","event_name"
319  #       137426,"TracePacket","[NULL]","[NULL]","[NULL]","[NULL]"
320  #       59475,"TrackEvent","#track_event",415,"[NULL]","[NULL]"
321  #       37903,"TrackEvent","#track_event",17,"[NULL]","[NULL]"
322  #       35904,"int32","#trusted_uid",17,"[NULL]","[NULL]"
323  #       35705,"TracePacket","[NULL]","[NULL]","input,benchmark","LatencyInfo.Flow"
324  #       29403,"TracePacket","[NULL]","[NULL]","cc,input","[NULL]"
325  #       24703,"ChromeLatencyInfo","#chrome_latency_info",18,"[NULL]","[NULL]"
326  #       22620,"uint64","#time_us",26,"[NULL]","[NULL]"
327  #       18711,"TrackEvent","#track_event",1467,"[NULL]","[NULL]"
328  #       15606,"uint64","#timestamp",17,"[NULL]","[NULL]"
329  #       """))
330