• 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 ChromeScrollJank(TestSuite):
23  # Scroll jank metrics
24  def test_scroll_jank_general_validation(self):
25    return DiffTestBlueprint(
26        trace=DataPath('chrome_scroll_without_vsync.pftrace'),
27        query=Path('scroll_jank_general_validation_test.sql'),
28        out=Path('scroll_jank_general_validation.out'))
29
30  def test_scroll_jank(self):
31    return DiffTestBlueprint(
32        trace=DataPath('chrome_scroll_without_vsync.pftrace'),
33        query="""
34        SELECT RUN_METRIC('chrome/scroll_jank.sql');
35
36        SELECT
37          gesture_scroll_id,
38          trace_id,
39          jank,
40          ts,
41          dur,
42          jank_budget
43        FROM scroll_jank;
44        """,
45        out=Path('scroll_jank.out'))
46
47  def test_event_latency_to_breakdowns(self):
48    return DiffTestBlueprint(
49        trace=DataPath('event_latency_with_args.perfetto-trace'),
50        query="""
51        SELECT RUN_METRIC('chrome/event_latency_to_breakdowns.sql');
52
53        SELECT
54          event_latency_ts,
55          event_latency_dur,
56          event_type,
57          GenerationToRendererCompositorNs,
58          GenerationToBrowserMainNs,
59          BrowserMainToRendererCompositorNs,
60          RendererCompositorQueueingDelayNs,
61          unknown_stages_seen
62        FROM event_latency_to_breakdowns
63        ORDER BY event_latency_id
64        LIMIT 30;
65        """,
66        out=Path('event_latency_to_breakdowns.out'))
67
68  def test_event_latency_scroll_jank(self):
69    return DiffTestBlueprint(
70        trace=DataPath('event_latency_with_args.perfetto-trace'),
71        query="""
72        SELECT RUN_METRIC('chrome/event_latency_scroll_jank.sql');
73
74        SELECT
75          jank,
76          next_jank,
77          prev_jank,
78          gesture_begin_ts,
79          gesture_end_ts,
80          ts,
81          dur,
82          event_type,
83          next_ts,
84          next_dur,
85          prev_ts,
86          prev_dur
87        FROM scroll_event_latency_jank
88        ORDER BY jank DESC
89        LIMIT 10;
90        """,
91        out=Path('event_latency_scroll_jank.out'))
92
93  def test_event_latency_scroll_jank_cause(self):
94    return DiffTestBlueprint(
95        trace=DataPath('event_latency_with_args.perfetto-trace'),
96        query="""
97        SELECT RUN_METRIC('chrome/event_latency_scroll_jank_cause.sql');
98
99        SELECT
100          dur,
101          ts,
102          event_type,
103          next_jank,
104          prev_jank,
105          next_delta_dur_ns,
106          prev_delta_dur_ns,
107          cause_of_jank,
108          max_delta_dur_ns,
109          sub_cause_of_jank
110        FROM event_latency_scroll_jank_cause
111        ORDER by ts;
112        """,
113        out=Path('event_latency_scroll_jank_cause.out'))
114
115  def test_scroll_flow_event(self):
116    return DiffTestBlueprint(
117        trace=DataPath('chrome_scroll_without_vsync.pftrace'),
118        query="""
119        SELECT RUN_METRIC('chrome/scroll_flow_event.sql');
120
121        SELECT
122          trace_id,
123          ts,
124          dur,
125          jank,
126          step,
127          ancestor_end,
128          maybe_next_ancestor_ts,
129          next_ts,
130          next_trace_id,
131          next_step
132        FROM scroll_flow_event
133        ORDER BY gesture_scroll_id, trace_id, ts;
134        """,
135        out=Path('scroll_flow_event.out'))
136
137  def test_scroll_flow_event_general_validation(self):
138    return DiffTestBlueprint(
139        trace=DataPath('chrome_scroll_without_vsync.pftrace'),
140        query="""
141        SELECT RUN_METRIC('chrome/scroll_flow_event.sql');
142
143        SELECT
144          -- Each trace_id (in our example trace not true in general) has 8 steps. There
145          -- are 139 scrolls. So we expect 1112 rows in total 72 of which are janky.
146          (
147            SELECT
148              COUNT(*)
149            FROM (
150              SELECT
151                trace_id,
152                COUNT(*)
153              FROM scroll_flow_event
154              GROUP BY trace_id
155            )
156          ) AS total_scroll_updates,
157          (
158            SELECT COUNT(*) FROM scroll_flow_event
159          ) AS total_flow_event_steps,
160          (
161            SELECT COUNT(*) FROM scroll_flow_event WHERE jank
162          ) AS total_janky_flow_event_steps,
163          (
164            SELECT COUNT(*) FROM (SELECT step FROM scroll_flow_event GROUP BY step)
165          ) AS number_of_unique_steps;
166        """,
167        out=Path('scroll_flow_event_general_validation.out'))
168
169  def test_scroll_jank_cause(self):
170    return DiffTestBlueprint(
171        trace=DataPath('chrome_scroll_without_vsync.pftrace'),
172        query="""
173        SELECT RUN_METRIC('chrome/scroll_jank_cause.sql');
174
175        SELECT
176          COUNT(*) AS total,
177          SUM(jank) AS total_jank,
178          SUM(explained_jank + unexplained_jank) AS sum_explained_and_unexplained,
179          SUM(
180            CASE WHEN explained_jank THEN
181              unexplained_jank
182              ELSE
183                CASE WHEN jank AND NOT unexplained_jank THEN
184                  1
185                  ELSE
186                    0
187                END
188            END
189          ) AS error_rows
190        FROM scroll_jank_cause;
191        """,
192        out=Csv("""
193        "total","total_jank","sum_explained_and_unexplained","error_rows"
194        139,7,7,0
195        """))
196
197  def test_scroll_flow_event_queuing_delay(self):
198    return DiffTestBlueprint(
199        trace=DataPath('chrome_scroll_without_vsync.pftrace'),
200        query="""
201        SELECT RUN_METRIC('chrome/scroll_flow_event_queuing_delay.sql');
202
203        SELECT
204          trace_id,
205          jank,
206          step,
207          next_step,
208          ancestor_end,
209          maybe_next_ancestor_ts,
210          queuing_time_ns
211        FROM scroll_flow_event_queuing_delay
212        WHERE trace_id = 2954 OR trace_id = 2956 OR trace_id = 2960
213        ORDER BY trace_id, ts;
214        """,
215        out=Path('scroll_flow_event_queuing_delay.out'))
216
217  def test_scroll_flow_event_general_validation_2(self):
218    return DiffTestBlueprint(
219        trace=DataPath('chrome_scroll_without_vsync.pftrace'),
220        query=Path(
221            'scroll_flow_event_queuing_delay_general_validation_test.sql'),
222        out=Path('scroll_flow_event_general_validation.out'))
223
224  def test_scroll_jank_cause_queuing_delay(self):
225    return DiffTestBlueprint(
226        trace=DataPath('chrome_scroll_without_vsync.pftrace'),
227        query="""
228        SELECT RUN_METRIC('chrome/scroll_jank_cause_queuing_delay.sql');
229
230        SELECT
231          process_name,
232          thread_name,
233          trace_id,
234          jank,
235          dur_overlapping_ns,
236          metric_name
237        FROM scroll_jank_cause_queuing_delay
238        WHERE trace_id = 2918 OR trace_id = 2926
239        ORDER BY trace_id ASC, ts ASC;
240        """,
241        out=Path('scroll_jank_cause_queuing_delay.out'))
242
243  def test_scroll_jank_cause_queuing_delay_restricted(self):
244    return DiffTestBlueprint(
245        trace=DataPath('chrome_scroll_without_vsync.pftrace'),
246        query="""
247        SELECT RUN_METRIC('chrome/scroll_jank_cause_queuing_delay.sql');
248
249        SELECT
250          process_name,
251          thread_name,
252          trace_id,
253          jank,
254          dur_overlapping_ns,
255          restricted_metric_name
256        FROM scroll_jank_cause_queuing_delay
257        WHERE trace_id = 2918 OR trace_id = 2926
258        ORDER BY trace_id ASC, ts ASC;
259        """,
260        out=Path('scroll_jank_cause_queuing_delay_restricted.out'))
261
262  def test_scroll_jank_cause_queuing_delay_general_validation(self):
263    return DiffTestBlueprint(
264        trace=DataPath('chrome_scroll_without_vsync.pftrace'),
265        query="""
266        SELECT RUN_METRIC('chrome/scroll_jank_cause_queuing_delay.sql');
267
268        SELECT
269          COUNT(*) AS total,
270          (
271            SELECT DISTINCT
272              (avg_no_jank_dur_overlapping_ns)
273            FROM scroll_jank_cause_queuing_delay
274            WHERE
275              location = "LatencyInfo.Flow"
276              AND jank
277          ) AS janky_latency_info_non_jank_avg_dur,
278          (
279            SELECT DISTINCT
280              (avg_no_jank_dur_overlapping_ns)
281            FROM scroll_jank_cause_queuing_delay
282            WHERE
283              location = "LatencyInfo.Flow"
284              AND NOT jank
285          ) AS non_janky_latency_info_non_jank_avg_dur
286        FROM (
287          SELECT
288            trace_id
289          FROM scroll_jank_cause_queuing_delay
290          GROUP BY trace_id
291        );
292        """,
293        out=Path('scroll_jank_cause_queuing_delay_general_validation.out'))
294
295  def test_chrome_thread_slice(self):
296    return DiffTestBlueprint(
297        trace=DataPath('chrome_scroll_without_vsync.pftrace'),
298        query="""
299        SELECT RUN_METRIC('chrome/chrome_thread_slice.sql');
300
301        SELECT
302          EXTRACT_ARG(arg_set_id, 'chrome_latency_info.trace_id') AS trace_id,
303          dur,
304          thread_dur
305        FROM chrome_thread_slice
306        WHERE
307          name = 'LatencyInfo.Flow'
308          AND EXTRACT_ARG(arg_set_id, 'chrome_latency_info.trace_id') = 2734;
309        """,
310        out=Csv("""
311        "trace_id","dur","thread_dur"
312        2734,25000,25000
313        2734,1000,2000
314        2734,2000,2000
315        2734,258000,171000
316        2734,1000,1000
317        """))
318
319  def test_chrome_input_to_browser_intervals(self):
320    return DiffTestBlueprint(
321        trace=DataPath('scrolling_with_blocked_nonblocked_frames.pftrace'),
322        query="""
323        SELECT RUN_METRIC('chrome/chrome_input_to_browser_intervals.sql');
324
325        SELECT
326          *
327        FROM chrome_input_to_browser_intervals
328        WHERE window_start_ts >= 60934320005158
329          AND window_start_ts <= 60934338798158;
330        """,
331        out=Path('chrome_input_to_browser_intervals.out'))
332
333  def test_chrome_scroll_jank_caused_by_scheduling(self):
334    return DiffTestBlueprint(
335        trace=DataPath('fling_with_input_delay.pftrace'),
336        query="""
337        SELECT RUN_METRIC('chrome/chrome_scroll_jank_caused_by_scheduling.sql',
338          'dur_causes_jank_ms',
339        /* dur_causes_jank_ms = */ '5');
340
341        SELECT
342          full_name,
343          total_duration_ms,
344          total_thread_duration_ms,
345          count,
346          window_start_ts,
347          window_end_ts,
348          scroll_type
349        FROM chrome_scroll_jank_caused_by_scheduling;
350        """,
351        out=Path('chrome_scroll_jank_caused_by_scheduling_test.out'))
352
353  def test_chrome_tasks_delaying_input_processing(self):
354    return DiffTestBlueprint(
355        trace=DataPath('fling_with_input_delay.pftrace'),
356        query="""
357        SELECT RUN_METRIC('chrome/chrome_tasks_delaying_input_processing.sql',
358          'duration_causing_jank_ms',
359         /* duration_causing_jank_ms = */ '8');
360
361        SELECT
362          full_name,
363          duration_ms,
364          thread_dur_ms
365        FROM chrome_tasks_delaying_input_processing;
366        """,
367        out=Path('chrome_tasks_delaying_input_processing_test.out'))
368
369  def test_long_task_tracking_trace_chrome_long_tasks_delaying_input_processing(
370      self):
371    return DiffTestBlueprint(
372        trace=DataPath('long_task_tracking_trace'),
373        query="""
374        SELECT RUN_METRIC('chrome/chrome_long_tasks_delaying_input_processing.sql');
375
376        SELECT
377          full_name,
378          duration_ms,
379          slice_id
380        FROM chrome_tasks_delaying_input_processing
381        ORDER BY slice_id;
382        """,
383        out=Path(
384            'long_task_tracking_trace_chrome_long_tasks_delaying_input_processing_test.out'
385        ))
386
387  # TODO(b/264520610): Uncomment once fixed
388  # chrome_long_tasks_delaying_input_processing_compare_default_test.sql
389  # long_task_tracking_trace_chrome_long_tasks_delaying_input_processing_compare_default_test.out
390  def test_experimental_reliable_chrome_tasks_delaying_input_processing(self):
391    return DiffTestBlueprint(
392        trace=DataPath('fling_with_input_delay.pftrace'),
393        query="""
394        SELECT RUN_METRIC(
395            'chrome/experimental_reliable_chrome_tasks_delaying_input_processing.sql',
396            'duration_causing_jank_ms', '8');
397
398        SELECT
399          full_name,
400          duration_ms,
401          thread_dur_ms
402        FROM chrome_tasks_delaying_input_processing;
403        """,
404        out=Path(
405            'experimental_reliable_chrome_tasks_delaying_input_processing_test.out'
406        ))
407
408  def test_chrome_scroll_inputs_per_frame(self):
409    return DiffTestBlueprint(
410        trace=DataPath('scrolling_with_blocked_nonblocked_frames.pftrace'),
411        query="""
412        SELECT RUN_METRIC('chrome/chrome_scroll_inputs_per_frame.sql');
413
414        SELECT
415          count_for_frame,
416          ts
417        FROM chrome_scroll_inputs_per_frame
418        WHERE ts = 60934316798158;
419        """,
420        out=Csv("""
421        "count_for_frame","ts"
422        4,60934316798158
423        """))
424
425  def test_chrome_thread_slice_repeated(self):
426    return DiffTestBlueprint(
427        trace=Path('../track_event/track_event_counters.textproto'),
428        query="""
429        SELECT RUN_METRIC('chrome/chrome_thread_slice.sql');
430
431        SELECT
432          name,
433          ts,
434          dur,
435          thread_dur
436        FROM chrome_thread_slice;
437        """,
438        out=Csv("""
439        "name","ts","dur","thread_dur"
440        "event1_on_t1",1000,100,10000
441        "event2_on_t1",2000,200,30000
442        "event3_on_t1",2000,200,10000
443        "event4_on_t1",4000,0,0
444        "float_counter_on_t1",4300,0,"[NULL]"
445        "float_counter_on_t1",4500,0,"[NULL]"
446        "event1_on_t3",4000,100,5000
447        """))
448
449  def test_frame_times_metric(self):
450    return DiffTestBlueprint(
451        trace=DataPath('chrome_rendering_desktop.pftrace'),
452        query=Metric('frame_times'),
453        out=Path('frame_times_metric.out'))
454
455  def test_chrome_dropped_frames_metric(self):
456    return DiffTestBlueprint(
457        trace=DataPath('chrome_rendering_desktop.pftrace'),
458        query=Metric('chrome_dropped_frames'),
459        out=TextProto(r"""
460        [perfetto.protos.chrome_dropped_frames]: {
461          dropped_frame: {
462            ts: 166479338462000
463            process_name: "Renderer"
464            pid: 12743
465          }
466          dropped_frame: {
467            ts: 166479355302000
468            process_name: "Renderer"
469            pid: 12743
470          }
471        }
472        """))
473
474  def test_chrome_long_latency_metric(self):
475    return DiffTestBlueprint(
476        trace=Path('../chrome/long_event_latency.textproto'),
477        query="""
478        SELECT RUN_METRIC('experimental/chrome_long_latency.sql');
479
480        SELECT * FROM long_latency_with_process_info;
481        """,
482        out=Csv("""
483        "ts","event_type","process_name","process_id"
484        200111000,"FirstGestureScrollUpdate,GestureScrollUpdate","Renderer",1001
485        200111000,"GestureScrollUpdate","Renderer",1002
486        280111001,"GestureScrollUpdate","Renderer",1001
487        """))
488
489  def test_scroll_jank_mojo_simple_watcher(self):
490    return DiffTestBlueprint(
491        trace=Path('scroll_jank_mojo_simple_watcher.py'),
492        query="""
493        SELECT RUN_METRIC('chrome/scroll_jank_cause_queuing_delay.sql');
494
495        SELECT
496          trace_id,
497          jank,
498          dur_overlapping_ns,
499          metric_name
500        FROM scroll_jank_cause_queuing_delay
501        ORDER BY trace_id ASC, ts ASC;
502        """,
503        out=Path('scroll_jank_mojo_simple_watcher.out'))
504
505  def test_scroll_jank_gpu_check(self):
506    return DiffTestBlueprint(
507        trace=Path('scroll_jank_gpu_check.py'),
508        query="""
509        SELECT RUN_METRIC('chrome/scroll_jank.sql');
510
511        SELECT ts, jank
512        FROM scroll_jank
513        ORDER BY ts ASC;
514        """,
515        out=Csv("""
516        "ts","jank"
517        15000000,0
518        30000000,1
519        115000000,0
520        """))
521
522  def test_chrome_scrolls(self):
523    return DiffTestBlueprint(
524        trace=Path('chrome_scroll_check.py'),
525        query="""
526        SELECT IMPORT('chrome.chrome_scrolls');
527
528        SELECT
529          id,
530          ts,
531          dur,
532          scroll_start_ts,
533          scroll_end_ts
534        FROM chrome_scrolls
535        ORDER by id;
536        """,
537        out=Csv("""
538        "id","ts","dur","scroll_start_ts","scroll_end_ts"
539        5678,0,55000000,0,45000000
540        5679,60000000,40000000,60000000,90000000
541        5680,120000000,70000000,120000000,-1
542        """))
543