metrics: Add test for cpu_by_combined_rail_mode table
Adds a simple python generator that creates two processes with main
threads and emits RAILMode slices as well as cpu counters on each to
check that the table is properly populated.
Due to b/175110985, this also increases the trace times for the
combined_rail_modes.py test by a factor of 1000.
Bug: 174764142
Change-Id: I00350879456138f0b503a13d4f9c38e210bdeb61
diff --git a/test/synth_common.py b/test/synth_common.py
index c6a1ad0..a2c9c01 100644
--- a/test/synth_common.py
+++ b/test/synth_common.py
@@ -31,6 +31,17 @@
RAIL_MODE_IDLE = 3
RAIL_MODE_LOAD = 4
+PROCESS_BROWSER = 1
+PROCESS_RENDERER = 2
+PROCESS_GPU = 6
+
+CHROME_THREAD_UNSPECIFIED = 0
+CHROME_THREAD_MAIN = 1
+CHROME_THREAD_IO = 2
+CHROME_THREAD_COMPOSITOR = 8
+
+COUNTER_THREAD_TIME_NS = 1
+
class Trace(object):
@@ -423,42 +434,179 @@
sched_blocked_reason.pid = pid
sched_blocked_reason.io_wait = io_wait
-
- def add_track_event(self, name=None, ts=None, track=None):
+ def add_track_event(self,
+ name=None,
+ ts=None,
+ track=None,
+ trusted_sequence_id=0,
+ cpu_time=None):
packet = self.add_packet(ts=ts)
if name is not None:
packet.track_event.name = name
if track is not None:
packet.track_event.track_uuid = track
- packet.trusted_packet_sequence_id = 0
+ packet.trusted_packet_sequence_id = trusted_sequence_id
+ if cpu_time is not None:
+ packet.track_event.extra_counter_values.append(cpu_time)
return packet
- def add_track_descriptor(self, uuid, name, pid=None, tid=None):
+ def add_track_descriptor(self, uuid, parent=None):
packet = self.add_packet()
track_descriptor = packet.track_descriptor
- track_descriptor.uuid = uuid
- track_descriptor.name = name
- track_descriptor.thread.pid = pid
- track_descriptor.thread.tid = tid
+ if uuid is not None:
+ track_descriptor.uuid = uuid
+ if parent is not None:
+ track_descriptor.parent_uuid = parent
return packet
- def add_track_event_slice_begin(self, name, ts, track=None):
- packet = self.add_track_event(name, ts=ts, track=track)
+ def add_process_track_descriptor(self, process_track, pid=None):
+ packet = self.add_track_descriptor(process_track)
+ packet.track_descriptor.process.pid = pid
+ return packet
+
+ def add_chrome_process_track_descriptor(
+ self,
+ process_track,
+ pid=None,
+ process_type=PROCESS_RENDERER,
+ host_app_package_name="org.chromium.chrome"):
+ packet = self.add_process_track_descriptor(process_track, pid=pid)
+ chrome_process = packet.track_descriptor.chrome_process
+ chrome_process.process_type = process_type
+ chrome_process.host_app_package_name = host_app_package_name
+ return packet
+
+ def add_thread_track_descriptor(self,
+ process_track,
+ thread_track,
+ trusted_packet_sequence_id=None,
+ pid=None,
+ tid=None):
+ packet = self.add_track_descriptor(thread_track, parent=process_track)
+ packet.trusted_packet_sequence_id = trusted_packet_sequence_id
+ packet.track_descriptor.thread.pid = pid
+ packet.track_descriptor.thread.tid = tid
+ return packet
+
+ def add_chrome_thread_track_descriptor(self,
+ process_track,
+ thread_track,
+ trusted_packet_sequence_id=None,
+ pid=None,
+ tid=None,
+ thread_type=CHROME_THREAD_UNSPECIFIED):
+ packet = self.add_thread_track_descriptor(
+ process_track,
+ thread_track,
+ trusted_packet_sequence_id=trusted_packet_sequence_id,
+ pid=pid,
+ tid=tid)
+ return packet
+
+ def add_trace_packet_defaults(self,
+ trusted_packet_sequence_id=None,
+ thread_track=None,
+ counter_track=None):
+ packet = self.add_track_descriptor(None)
+ packet.trusted_packet_sequence_id = trusted_packet_sequence_id
+ track_event_defaults = packet.trace_packet_defaults.track_event_defaults
+ track_event_defaults.track_uuid = thread_track
+ track_event_defaults.extra_counter_track_uuids.append(counter_track)
+ return packet
+
+ def add_counter_track_descriptor(self,
+ trusted_packet_sequence_id=None,
+ thread_track=None,
+ counter_track=None):
+ packet = self.add_track_descriptor(counter_track, parent=thread_track)
+ packet.trusted_packet_sequence_id = trusted_packet_sequence_id
+ packet.track_descriptor.counter.type = COUNTER_THREAD_TIME_NS
+ return packet
+
+ def add_chrome_thread_with_cpu_counter(self,
+ process_track,
+ thread_track,
+ trusted_packet_sequence_id=None,
+ counter_track=None,
+ pid=None,
+ tid=None,
+ thread_type=None):
+ self.add_chrome_thread_track_descriptor(
+ process_track,
+ thread_track,
+ trusted_packet_sequence_id=trusted_packet_sequence_id,
+ pid=pid,
+ tid=tid,
+ thread_type=thread_type)
+ self.add_trace_packet_defaults(
+ trusted_packet_sequence_id=trusted_packet_sequence_id,
+ counter_track=counter_track,
+ thread_track=thread_track)
+
+ self.add_counter_track_descriptor(
+ trusted_packet_sequence_id=trusted_packet_sequence_id,
+ counter_track=counter_track,
+ thread_track=thread_track)
+
+ def add_track_event_slice_begin(self,
+ name,
+ ts,
+ track=None,
+ trusted_sequence_id=0,
+ cpu_time=None):
+ packet = self.add_track_event(
+ name,
+ ts=ts,
+ track=track,
+ trusted_sequence_id=trusted_sequence_id,
+ cpu_time=cpu_time)
packet.track_event.type = TYPE_SLICE_BEGIN
return packet
- def add_track_event_slice_end(self, ts, track=None):
- packet = self.add_track_event(ts=ts, track=track)
+ def add_track_event_slice_end(self,
+ ts,
+ track=None,
+ trusted_sequence_id=0,
+ cpu_time=None):
+ packet = self.add_track_event(
+ ts=ts,
+ track=track,
+ trusted_sequence_id=trusted_sequence_id,
+ cpu_time=cpu_time)
packet.track_event.type = TYPE_SLICE_END
return packet
- def add_rail_mode_slice(self, ts, dur, track, mode):
+ # Returns the start slice packet.
+ def add_track_event_slice(self,
+ name,
+ ts,
+ dur,
+ track=None,
+ trusted_sequence_id=0,
+ cpu_start=None,
+ cpu_delta=None):
+
packet = self.add_track_event_slice_begin(
- "Scheduler.RAILMode", ts=ts, track=track)
- packet.track_event.chrome_renderer_scheduler_state.rail_mode = mode
+ name,
+ ts,
+ track=track,
+ trusted_sequence_id=trusted_sequence_id,
+ cpu_time=cpu_start)
if dur >= 0:
- packet = self.add_track_event_slice_end(ts=ts + dur, track=track)
+ cpu_end = cpu_start + cpu_delta if cpu_start is not None else None
+ self.add_track_event_slice_end(
+ ts + dur,
+ track=track,
+ trusted_sequence_id=trusted_sequence_id,
+ cpu_time=cpu_end)
+
+ return packet
+
+ def add_rail_mode_slice(self, ts, dur, track, mode):
+ packet = self.add_track_event_slice(
+ "Scheduler.RAILMode", ts=ts, dur=dur, track=track)
+ packet.track_event.chrome_renderer_scheduler_state.rail_mode = mode
def create_trace():
diff --git a/test/trace_processor/chrome/combined_rail_modes.out b/test/trace_processor/chrome/combined_rail_modes.out
index 168640a..b1cbbd6 100644
--- a/test/trace_processor/chrome/combined_rail_modes.out
+++ b/test/trace_processor/chrome/combined_rail_modes.out
@@ -1,6 +1,6 @@
"id","ts","dur","rail_mode"
-1,0,10,"response"
-2,10,20,"load"
-3,30,5,"animation"
-4,35,10,"background"
+1,0,10000,"response"
+2,10000,20000,"load"
+3,30000,5000,"animation"
+4,35000,10000,"background"
diff --git a/test/trace_processor/chrome/combined_rail_modes.py b/test/trace_processor/chrome/combined_rail_modes.py
index 55e5062..4d2e26a 100644
--- a/test/trace_processor/chrome/combined_rail_modes.py
+++ b/test/trace_processor/chrome/combined_rail_modes.py
@@ -22,23 +22,23 @@
track1 = 1234
track2 = 4567
-trace.add_track_descriptor(track1, "Renderer Thread 1", pid=0, tid=1)
-trace.add_track_descriptor(track2, "Renderer Thread 2", pid=2, tid=3)
+trace.add_process_track_descriptor(track1, pid=0)
+trace.add_process_track_descriptor(track2, pid=2)
trace.add_rail_mode_slice(
- ts=0, dur=10, track=track1, mode=synth_common.RAIL_MODE_RESPONSE)
+ ts=0, dur=10000, track=track1, mode=synth_common.RAIL_MODE_RESPONSE)
trace.add_rail_mode_slice(
- ts=10, dur=20, track=track1, mode=synth_common.RAIL_MODE_LOAD)
+ ts=10000, dur=20000, track=track1, mode=synth_common.RAIL_MODE_LOAD)
trace.add_rail_mode_slice(
- ts=30, dur=-1, track=track1, mode=synth_common.RAIL_MODE_IDLE)
+ ts=30000, dur=-1, track=track1, mode=synth_common.RAIL_MODE_IDLE)
trace.add_rail_mode_slice(
- ts=0, dur=10, track=track2, mode=synth_common.RAIL_MODE_ANIMATION)
+ ts=0, dur=10000, track=track2, mode=synth_common.RAIL_MODE_ANIMATION)
trace.add_rail_mode_slice(
- ts=10, dur=25, track=track2, mode=synth_common.RAIL_MODE_IDLE)
+ ts=10000, dur=25000, track=track2, mode=synth_common.RAIL_MODE_IDLE)
trace.add_rail_mode_slice(
- ts=25, dur=10, track=track2, mode=synth_common.RAIL_MODE_ANIMATION)
+ ts=25000, dur=10000, track=track2, mode=synth_common.RAIL_MODE_ANIMATION)
trace.add_rail_mode_slice(
- ts=35, dur=10, track=track2, mode=synth_common.RAIL_MODE_IDLE)
+ ts=35000, dur=10000, track=track2, mode=synth_common.RAIL_MODE_IDLE)
sys.stdout.buffer.write(trace.trace.SerializeToString())
diff --git a/test/trace_processor/chrome/cpu_time_by_combined_rail_mode.out b/test/trace_processor/chrome/cpu_time_by_combined_rail_mode.out
new file mode 100644
index 0000000..fd882c5
--- /dev/null
+++ b/test/trace_processor/chrome/cpu_time_by_combined_rail_mode.out
@@ -0,0 +1,7 @@
+
+"id","ts","dur","rail_mode","cpu_dur"
+1,0,10000,"response",26000
+2,10000,20000,"load",20000
+3,30000,5000,"background",8000
+4,35000,10000,"animation",21000
+5,45000,10000,"background",1000
diff --git a/test/trace_processor/chrome/cpu_time_by_combined_rail_mode.py b/test/trace_processor/chrome/cpu_time_by_combined_rail_mode.py
new file mode 100644
index 0000000..194b0ce
--- /dev/null
+++ b/test/trace_processor/chrome/cpu_time_by_combined_rail_mode.py
@@ -0,0 +1,147 @@
+#!/usr/bin/env python3
+# Copyright (C) 2020 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 at
+#
+# 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 os import sys
+
+import synth_common
+
+trace = synth_common.create_trace()
+
+process_track1 = 1234
+process_track2 = 4567
+
+process_pid1 = 2345
+process_pid2 = 5678
+
+thread_track1 = 1235
+thread_track2 = 4568
+
+rail_track1 = 1236
+rail_track2 = 4569
+
+# Main threads have the same ID as the process
+thread_tid1 = process_pid1
+thread_tid2 = process_pid2
+
+seq1 = 9876
+seq2 = 9877
+
+thread1_counter = 60
+thread2_counter = 61
+
+trace.add_chrome_process_track_descriptor(process_track1, process_pid1)
+trace.add_chrome_process_track_descriptor(process_track2, process_pid2)
+
+trace.add_chrome_thread_with_cpu_counter(
+ process_track1,
+ thread_track1,
+ trusted_packet_sequence_id=seq1,
+ counter_track=thread1_counter,
+ pid=process_pid1,
+ tid=thread_tid1,
+ thread_type=synth_common.CHROME_THREAD_MAIN)
+
+trace.add_chrome_thread_with_cpu_counter(
+ process_track2,
+ thread_track2,
+ trusted_packet_sequence_id=seq2,
+ counter_track=thread2_counter,
+ pid=process_pid2,
+ tid=thread_tid2,
+ thread_type=synth_common.CHROME_THREAD_MAIN)
+
+trace.add_track_descriptor(rail_track1, parent=process_track1)
+trace.add_track_descriptor(rail_track2, parent=process_track2)
+
+trace.add_track_event_slice(
+ "task", 0, 5000, trusted_sequence_id=seq1, cpu_start=0, cpu_delta=10000)
+trace.add_track_event_slice(
+ "task",
+ 5000,
+ 5000,
+ trusted_sequence_id=seq1,
+ cpu_start=12000,
+ cpu_delta=4000)
+
+trace.add_track_event_slice(
+ "task",
+ 10000,
+ 6000,
+ trusted_sequence_id=seq1,
+ cpu_start=18000,
+ cpu_delta=2000)
+trace.add_track_event_slice(
+ "task",
+ 16000,
+ 4000,
+ trusted_sequence_id=seq1,
+ cpu_start=20000,
+ cpu_delta=7000)
+
+trace.add_track_event_slice(
+ "task",
+ 30000,
+ 10000,
+ trusted_sequence_id=seq1,
+ cpu_start=30000,
+ cpu_delta=1000)
+
+trace.add_rail_mode_slice(
+ ts=0, dur=10000, track=rail_track1, mode=synth_common.RAIL_MODE_RESPONSE)
+trace.add_rail_mode_slice(
+ ts=10000, dur=20000, track=rail_track1, mode=synth_common.RAIL_MODE_LOAD)
+trace.add_rail_mode_slice(
+ ts=30000, dur=-1, track=rail_track1, mode=synth_common.RAIL_MODE_IDLE)
+
+trace.add_track_event_slice(
+ "task", 0, 10000, trusted_sequence_id=seq2, cpu_start=0, cpu_delta=10000)
+
+trace.add_track_event_slice(
+ "task",
+ 10000,
+ 15000,
+ trusted_sequence_id=seq2,
+ cpu_start=12000,
+ cpu_delta=1000)
+
+trace.add_track_event_slice(
+ "task",
+ 35000,
+ 10000,
+ trusted_sequence_id=seq2,
+ cpu_start=20000,
+ cpu_delta=20000)
+
+trace.add_track_event_slice(
+ "task",
+ 45000,
+ 10000,
+ trusted_sequence_id=seq2,
+ cpu_start=40000,
+ cpu_delta=1000)
+
+trace.add_rail_mode_slice(
+ ts=0, dur=10000, track=rail_track2, mode=synth_common.RAIL_MODE_ANIMATION)
+trace.add_rail_mode_slice(
+ ts=10000, dur=25000, track=rail_track2, mode=synth_common.RAIL_MODE_IDLE)
+trace.add_rail_mode_slice(
+ ts=35000,
+ dur=10000,
+ track=rail_track2,
+ mode=synth_common.RAIL_MODE_ANIMATION)
+trace.add_rail_mode_slice(
+ ts=45000, dur=10000, track=rail_track2, mode=synth_common.RAIL_MODE_IDLE)
+
+sys.stdout.buffer.write(trace.trace.SerializeToString())
diff --git a/test/trace_processor/chrome/cpu_time_by_combined_rail_mode.sql b/test/trace_processor/chrome/cpu_time_by_combined_rail_mode.sql
new file mode 100644
index 0000000..b66726a
--- /dev/null
+++ b/test/trace_processor/chrome/cpu_time_by_combined_rail_mode.sql
@@ -0,0 +1,17 @@
+-- Copyright 2020 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 at
+--
+-- https://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.
+-- SELECT RUN_METRIC('chrome/chrome_processes.sql') AS suppress_query_output;
+-- SELECT * FROM cpu_time_by_rail_mode;
+SELECT RUN_METRIC('chrome/cpu_time_by_rail_mode.sql') AS suppress_query_output;
+SELECT * FROM cpu_time_by_rail_mode;
diff --git a/test/trace_processor/chrome/index b/test/trace_processor/chrome/index
index cd3f278..2af934f 100644
--- a/test/trace_processor/chrome/index
+++ b/test/trace_processor/chrome/index
@@ -24,3 +24,4 @@
# RAIL modes.
combined_rail_modes.py combined_rail_modes.sql combined_rail_modes.out
+cpu_time_by_combined_rail_mode.py cpu_time_by_combined_rail_mode.sql cpu_time_by_combined_rail_mode.out