blob: c5fd3bcb8a0759f0afa394850b886e669d07e673 [file] [log] [blame]
#!/usr/bin/env python3
# Copyright (C) 2023 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License a
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from python.generators.diff_tests.testing import Path, DataPath, Metric
from python.generators.diff_tests.testing import Csv, Json, TextProto
from python.generators.diff_tests.testing import DiffTestBlueprint
from python.generators.diff_tests.testing import TestSuite
class ChromeScrollJank(TestSuite):
# Scroll jank metrics
def test_scroll_jank_general_validation(self):
return DiffTestBlueprint(
trace=DataPath('chrome_scroll_without_vsync.pftrace'),
query=Path('scroll_jank_general_validation_test.sql'),
out=Path('scroll_jank_general_validation.out'))
def test_scroll_jank(self):
return DiffTestBlueprint(
trace=DataPath('chrome_scroll_without_vsync.pftrace'),
query="""
SELECT RUN_METRIC('chrome/scroll_jank.sql');
SELECT
gesture_scroll_id,
trace_id,
jank,
ts,
dur,
jank_budget
FROM scroll_jank;
""",
out=Path('scroll_jank.out'))
def test_event_latency_to_breakdowns(self):
return DiffTestBlueprint(
trace=DataPath('event_latency_with_args.perfetto-trace'),
query="""
SELECT RUN_METRIC('chrome/event_latency_to_breakdowns.sql');
SELECT
event_latency_ts,
event_latency_dur,
event_type,
GenerationToRendererCompositorNs,
GenerationToBrowserMainNs,
BrowserMainToRendererCompositorNs,
RendererCompositorQueueingDelayNs,
unknown_stages_seen
FROM event_latency_to_breakdowns
ORDER BY event_latency_id
LIMIT 30;
""",
out=Path('event_latency_to_breakdowns.out'))
def test_event_latency_scroll_jank(self):
return DiffTestBlueprint(
trace=DataPath('event_latency_with_args.perfetto-trace'),
query="""
SELECT RUN_METRIC('chrome/event_latency_scroll_jank.sql');
SELECT
jank,
next_jank,
prev_jank,
gesture_begin_ts,
gesture_end_ts,
ts,
dur,
event_type,
next_ts,
next_dur,
prev_ts,
prev_dur
FROM scroll_event_latency_jank
ORDER BY jank DESC
LIMIT 10;
""",
out=Path('event_latency_scroll_jank.out'))
def test_event_latency_scroll_jank_cause(self):
return DiffTestBlueprint(
trace=DataPath('event_latency_with_args.perfetto-trace'),
query="""
SELECT RUN_METRIC('chrome/event_latency_scroll_jank_cause.sql');
SELECT
dur,
ts,
event_type,
next_jank,
prev_jank,
next_delta_dur_ns,
prev_delta_dur_ns,
cause_of_jank,
max_delta_dur_ns,
sub_cause_of_jank
FROM event_latency_scroll_jank_cause
ORDER by ts;
""",
out=Path('event_latency_scroll_jank_cause.out'))
def test_scroll_flow_event(self):
return DiffTestBlueprint(
trace=DataPath('chrome_scroll_without_vsync.pftrace'),
query="""
SELECT RUN_METRIC('chrome/scroll_flow_event.sql');
SELECT
trace_id,
ts,
dur,
jank,
step,
ancestor_end,
maybe_next_ancestor_ts,
next_ts,
next_trace_id,
next_step
FROM scroll_flow_event
ORDER BY gesture_scroll_id, trace_id, ts;
""",
out=Path('scroll_flow_event.out'))
def test_scroll_flow_event_general_validation(self):
return DiffTestBlueprint(
trace=DataPath('chrome_scroll_without_vsync.pftrace'),
query="""
SELECT RUN_METRIC('chrome/scroll_flow_event.sql');
SELECT
-- Each trace_id (in our example trace not true in general) has 8 steps. There
-- are 139 scrolls. So we expect 1112 rows in total 72 of which are janky.
(
SELECT
COUNT(*)
FROM (
SELECT
trace_id,
COUNT(*)
FROM scroll_flow_event
GROUP BY trace_id
)
) AS total_scroll_updates,
(
SELECT COUNT(*) FROM scroll_flow_event
) AS total_flow_event_steps,
(
SELECT COUNT(*) FROM scroll_flow_event WHERE jank
) AS total_janky_flow_event_steps,
(
SELECT COUNT(*) FROM (SELECT step FROM scroll_flow_event GROUP BY step)
) AS number_of_unique_steps;
""",
out=Path('scroll_flow_event_general_validation.out'))
def test_scroll_jank_cause(self):
return DiffTestBlueprint(
trace=DataPath('chrome_scroll_without_vsync.pftrace'),
query="""
SELECT RUN_METRIC('chrome/scroll_jank_cause.sql');
SELECT
COUNT(*) AS total,
SUM(jank) AS total_jank,
SUM(explained_jank + unexplained_jank) AS sum_explained_and_unexplained,
SUM(
CASE WHEN explained_jank THEN
unexplained_jank
ELSE
CASE WHEN jank AND NOT unexplained_jank THEN
1
ELSE
0
END
END
) AS error_rows
FROM scroll_jank_cause;
""",
out=Csv("""
"total","total_jank","sum_explained_and_unexplained","error_rows"
139,7,7,0
"""))
def test_scroll_flow_event_queuing_delay(self):
return DiffTestBlueprint(
trace=DataPath('chrome_scroll_without_vsync.pftrace'),
query="""
SELECT RUN_METRIC('chrome/scroll_flow_event_queuing_delay.sql');
SELECT
trace_id,
jank,
step,
next_step,
ancestor_end,
maybe_next_ancestor_ts,
queuing_time_ns
FROM scroll_flow_event_queuing_delay
WHERE trace_id = 2954 OR trace_id = 2956 OR trace_id = 2960
ORDER BY trace_id, ts;
""",
out=Path('scroll_flow_event_queuing_delay.out'))
def test_scroll_flow_event_general_validation_2(self):
return DiffTestBlueprint(
trace=DataPath('chrome_scroll_without_vsync.pftrace'),
query=Path(
'scroll_flow_event_queuing_delay_general_validation_test.sql'),
out=Path('scroll_flow_event_general_validation.out'))
def test_scroll_jank_cause_queuing_delay(self):
return DiffTestBlueprint(
trace=DataPath('chrome_scroll_without_vsync.pftrace'),
query="""
SELECT RUN_METRIC('chrome/scroll_jank_cause_queuing_delay.sql');
SELECT
process_name,
thread_name,
trace_id,
jank,
dur_overlapping_ns,
metric_name
FROM scroll_jank_cause_queuing_delay
WHERE trace_id = 2918 OR trace_id = 2926
ORDER BY trace_id ASC, ts ASC;
""",
out=Path('scroll_jank_cause_queuing_delay.out'))
def test_scroll_jank_cause_queuing_delay_restricted(self):
return DiffTestBlueprint(
trace=DataPath('chrome_scroll_without_vsync.pftrace'),
query="""
SELECT RUN_METRIC('chrome/scroll_jank_cause_queuing_delay.sql');
SELECT
process_name,
thread_name,
trace_id,
jank,
dur_overlapping_ns,
restricted_metric_name
FROM scroll_jank_cause_queuing_delay
WHERE trace_id = 2918 OR trace_id = 2926
ORDER BY trace_id ASC, ts ASC;
""",
out=Path('scroll_jank_cause_queuing_delay_restricted.out'))
def test_scroll_jank_cause_queuing_delay_general_validation(self):
return DiffTestBlueprint(
trace=DataPath('chrome_scroll_without_vsync.pftrace'),
query="""
SELECT RUN_METRIC('chrome/scroll_jank_cause_queuing_delay.sql');
SELECT
COUNT(*) AS total,
(
SELECT DISTINCT
(avg_no_jank_dur_overlapping_ns)
FROM scroll_jank_cause_queuing_delay
WHERE
location = "LatencyInfo.Flow"
AND jank
) AS janky_latency_info_non_jank_avg_dur,
(
SELECT DISTINCT
(avg_no_jank_dur_overlapping_ns)
FROM scroll_jank_cause_queuing_delay
WHERE
location = "LatencyInfo.Flow"
AND NOT jank
) AS non_janky_latency_info_non_jank_avg_dur
FROM (
SELECT
trace_id
FROM scroll_jank_cause_queuing_delay
GROUP BY trace_id
);
""",
out=Path('scroll_jank_cause_queuing_delay_general_validation.out'))
def test_chrome_thread_slice(self):
return DiffTestBlueprint(
trace=DataPath('chrome_scroll_without_vsync.pftrace'),
query="""
SELECT RUN_METRIC('chrome/chrome_thread_slice.sql');
SELECT
EXTRACT_ARG(arg_set_id, 'chrome_latency_info.trace_id') AS trace_id,
dur,
thread_dur
FROM chrome_thread_slice
WHERE
name = 'LatencyInfo.Flow'
AND EXTRACT_ARG(arg_set_id, 'chrome_latency_info.trace_id') = 2734;
""",
out=Csv("""
"trace_id","dur","thread_dur"
2734,25000,25000
2734,1000,2000
2734,2000,2000
2734,258000,171000
2734,1000,1000
"""))
def test_chrome_input_to_browser_intervals(self):
return DiffTestBlueprint(
trace=DataPath('scrolling_with_blocked_nonblocked_frames.pftrace'),
query="""
SELECT RUN_METRIC('chrome/chrome_input_to_browser_intervals.sql');
SELECT
*
FROM chrome_input_to_browser_intervals
WHERE window_start_ts >= 60934320005158
AND window_start_ts <= 60934338798158;
""",
out=Path('chrome_input_to_browser_intervals.out'))
def test_chrome_scroll_jank_caused_by_scheduling(self):
return DiffTestBlueprint(
trace=DataPath('fling_with_input_delay.pftrace'),
query="""
SELECT RUN_METRIC('chrome/chrome_scroll_jank_caused_by_scheduling.sql',
'dur_causes_jank_ms',
/* dur_causes_jank_ms = */ '5');
SELECT
full_name,
total_duration_ms,
total_thread_duration_ms,
count,
window_start_ts,
window_end_ts,
scroll_type
FROM chrome_scroll_jank_caused_by_scheduling;
""",
out=Path('chrome_scroll_jank_caused_by_scheduling_test.out'))
def test_chrome_tasks_delaying_input_processing(self):
return DiffTestBlueprint(
trace=DataPath('fling_with_input_delay.pftrace'),
query="""
SELECT RUN_METRIC('chrome/chrome_tasks_delaying_input_processing.sql',
'duration_causing_jank_ms',
/* duration_causing_jank_ms = */ '8');
SELECT
full_name,
duration_ms,
thread_dur_ms
FROM chrome_tasks_delaying_input_processing;
""",
out=Path('chrome_tasks_delaying_input_processing_test.out'))
def test_long_task_tracking_trace_chrome_long_tasks_delaying_input_processing(
self):
return DiffTestBlueprint(
trace=DataPath('long_task_tracking_trace'),
query="""
SELECT RUN_METRIC('chrome/chrome_long_tasks_delaying_input_processing.sql');
SELECT
full_name,
duration_ms,
slice_id
FROM chrome_tasks_delaying_input_processing
ORDER BY slice_id;
""",
out=Path(
'long_task_tracking_trace_chrome_long_tasks_delaying_input_processing_test.out'
))
# TODO(b/264520610): Uncomment once fixed
# chrome_long_tasks_delaying_input_processing_compare_default_test.sql
# long_task_tracking_trace_chrome_long_tasks_delaying_input_processing_compare_default_test.out
def test_experimental_reliable_chrome_tasks_delaying_input_processing(self):
return DiffTestBlueprint(
trace=DataPath('fling_with_input_delay.pftrace'),
query="""
SELECT RUN_METRIC(
'chrome/experimental_reliable_chrome_tasks_delaying_input_processing.sql',
'duration_causing_jank_ms', '8');
SELECT
full_name,
duration_ms,
thread_dur_ms
FROM chrome_tasks_delaying_input_processing;
""",
out=Path(
'experimental_reliable_chrome_tasks_delaying_input_processing_test.out'
))
def test_chrome_scroll_inputs_per_frame(self):
return DiffTestBlueprint(
trace=DataPath('scrolling_with_blocked_nonblocked_frames.pftrace'),
query="""
SELECT RUN_METRIC('chrome/chrome_scroll_inputs_per_frame.sql');
SELECT
count_for_frame,
ts
FROM chrome_scroll_inputs_per_frame
WHERE ts = 60934316798158;
""",
out=Csv("""
"count_for_frame","ts"
4,60934316798158
"""))
def test_chrome_thread_slice_repeated(self):
return DiffTestBlueprint(
trace=Path('../track_event/track_event_counters.textproto'),
query="""
SELECT RUN_METRIC('chrome/chrome_thread_slice.sql');
SELECT
name,
ts,
dur,
thread_dur
FROM chrome_thread_slice;
""",
out=Csv("""
"name","ts","dur","thread_dur"
"event1_on_t1",1000,100,10000
"event2_on_t1",2000,200,30000
"event3_on_t1",2000,200,10000
"event4_on_t1",4000,0,0
"float_counter_on_t1",4300,0,"[NULL]"
"float_counter_on_t1",4500,0,"[NULL]"
"event1_on_t3",4000,100,5000
"""))
def test_frame_times_metric(self):
return DiffTestBlueprint(
trace=DataPath('chrome_rendering_desktop.pftrace'),
query=Metric('frame_times'),
out=Path('frame_times_metric.out'))
def test_chrome_dropped_frames_metric(self):
return DiffTestBlueprint(
trace=DataPath('chrome_rendering_desktop.pftrace'),
query=Metric('chrome_dropped_frames'),
out=TextProto(r"""
[perfetto.protos.chrome_dropped_frames]: {
dropped_frame: {
ts: 166479338462000
process_name: "Renderer"
pid: 12743
}
dropped_frame: {
ts: 166479355302000
process_name: "Renderer"
pid: 12743
}
}
"""))
def test_chrome_long_latency_metric(self):
return DiffTestBlueprint(
trace=Path('../chrome/long_event_latency.textproto'),
query="""
SELECT RUN_METRIC('experimental/chrome_long_latency.sql');
SELECT * FROM long_latency_with_process_info;
""",
out=Csv("""
"ts","event_type","process_name","process_id"
200111000,"FirstGestureScrollUpdate,GestureScrollUpdate","Renderer",1001
200111000,"GestureScrollUpdate","Renderer",1002
280111001,"GestureScrollUpdate","Renderer",1001
"""))
def test_scroll_jank_mojo_simple_watcher(self):
return DiffTestBlueprint(
trace=Path('scroll_jank_mojo_simple_watcher.py'),
query="""
SELECT RUN_METRIC('chrome/scroll_jank_cause_queuing_delay.sql');
SELECT
trace_id,
jank,
dur_overlapping_ns,
metric_name
FROM scroll_jank_cause_queuing_delay
ORDER BY trace_id ASC, ts ASC;
""",
out=Path('scroll_jank_mojo_simple_watcher.out'))
def test_scroll_jank_gpu_check(self):
return DiffTestBlueprint(
trace=Path('scroll_jank_gpu_check.py'),
query="""
SELECT RUN_METRIC('chrome/scroll_jank.sql');
SELECT ts, jank
FROM scroll_jank
ORDER BY ts ASC;
""",
out=Csv("""
"ts","jank"
15000000,0
30000000,1
115000000,0
"""))