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