tp: Support trace strings in diff tests
Bug:255535171
Change-Id: I40959ac978f4672e2f526ae4405cba50406605c5
diff --git a/python/generators/diff_tests/runner.py b/python/generators/diff_tests/runner.py
index 7bd706c..dab06d1 100644
--- a/python/generators/diff_tests/runner.py
+++ b/python/generators/diff_tests/runner.py
@@ -146,8 +146,9 @@
trace_descriptor_path: str
colors: ColorFormatter
- def __run_metrics_test(self, gen_trace_path: str,
+ def __run_metrics_test(self, trace_path: str,
metrics_message_factory) -> TestResult:
+
if self.test.blueprint.is_out_file():
with open(self.test.expected_path, 'r') as expected_file:
expected = expected_file.read()
@@ -167,7 +168,7 @@
'--metrics-output=%s' % ('json' if is_json_output else 'binary'),
'--perf-file',
tmp_perf_file.name,
- gen_trace_path,
+ trace_path,
]
tp = subprocess.Popen(
cmd,
@@ -197,12 +198,11 @@
perf_lines = [line.decode('utf8') for line in tmp_perf_file.readlines()]
tmp_perf_file.close()
os.remove(tmp_perf_file.name)
- return TestResult(self.test,
- gen_trace_path, cmd, expected_text, actual_text,
+ return TestResult(self.test, trace_path, cmd, expected_text, actual_text,
stderr.decode('utf8'), tp.returncode, perf_lines)
# Run a query based Diff Test.
- def __run_query_test(self, gen_trace_path: str) -> TestResult:
+ def __run_query_test(self, trace_path: str) -> TestResult:
# Fetch expected text.
if self.test.expected_path:
with open(self.test.expected_path, 'r') as expected_file:
@@ -228,7 +228,7 @@
query,
'--perf-file',
tmp_perf_file.name,
- gen_trace_path,
+ trace_path,
]
tp = subprocess.Popen(
cmd,
@@ -244,43 +244,56 @@
tmp_perf_file.close()
os.remove(tmp_perf_file.name)
- return TestResult(self.test, gen_trace_path, cmd, expected,
- stdout.decode('utf8'), stderr.decode('utf8'),
- tp.returncode, perf_lines)
+ return TestResult(self.test,
+ trace_path, cmd, expected, stdout.decode('utf8'),
+ stderr.decode('utf8'), tp.returncode, perf_lines)
def __run(self, metrics_descriptor_paths: List[str],
extension_descriptor_paths: List[str], keep_input,
rebase) -> Tuple[TestResult, str]:
- is_generated_trace = True
# We can't use delete=True here. When using that on Windows, the
# resulting file is opened in exclusive mode (in turn that's a subtle
# side-effect of the underlying CreateFile(FILE_ATTRIBUTE_TEMPORARY))
# and TP fails to open the passed path.
- if self.test.trace_path.endswith('.py'):
- gen_trace_file = tempfile.NamedTemporaryFile(delete=False)
- serialize_python_trace(ROOT_DIR, self.trace_descriptor_path,
- self.test.trace_path, gen_trace_file)
- gen_trace_path = os.path.realpath(gen_trace_file.name)
+ gen_trace_file = None
+ if self.test.blueprint.is_trace_file():
+ if self.test.trace_path.endswith('.py'):
+ gen_trace_file = tempfile.NamedTemporaryFile(delete=False)
+ serialize_python_trace(ROOT_DIR, self.trace_descriptor_path,
+ self.test.trace_path, gen_trace_file)
- elif self.test.trace_path.endswith('.textproto'):
+ elif self.test.trace_path.endswith('.textproto'):
+ gen_trace_file = tempfile.NamedTemporaryFile(delete=False)
+ serialize_textproto_trace(self.trace_descriptor_path,
+ extension_descriptor_paths,
+ self.test.trace_path, gen_trace_file)
+
+ elif self.test.blueprint.is_trace_textproto():
gen_trace_file = tempfile.NamedTemporaryFile(delete=False)
- serialize_textproto_trace(self.trace_descriptor_path,
- extension_descriptor_paths,
- self.test.trace_path, gen_trace_file)
- gen_trace_path = os.path.realpath(gen_trace_file.name)
+ proto = create_message_factory([self.trace_descriptor_path] +
+ extension_descriptor_paths,
+ 'perfetto.protos.Trace')()
+ text_format.Merge(self.test.blueprint.trace.contents, proto)
+ gen_trace_file.write(proto.SerializeToString())
+ gen_trace_file.flush()
else:
- gen_trace_file = None
- gen_trace_path = self.test.trace_path
- is_generated_trace = False
+ gen_trace_file = tempfile.NamedTemporaryFile(delete=False)
+ with open(gen_trace_file.name, 'w') as trace_file:
+ trace_file.write(self.test.blueprint.trace.contents)
+
+ if gen_trace_file:
+ trace_path = os.path.realpath(gen_trace_file.name)
+ else:
+ trace_path = self.test.trace_path
str = f"{self.colors.yellow('[ RUN ]')} {self.test.name}\n"
if self.test.type == TestType.QUERY:
- result = self.__run_query_test(gen_trace_path)
+ result = self.__run_query_test(trace_path)
elif self.test.type == TestType.METRIC:
result = self.__run_metrics_test(
- gen_trace_path,
+ trace_path,
create_message_factory(metrics_descriptor_paths,
'perfetto.protos.TraceMetrics'))
else:
@@ -288,20 +301,20 @@
if gen_trace_file:
if keep_input:
- str += f"Saving generated input trace: {gen_trace_path}\n"
+ str += f"Saving generated input trace: {trace_path}\n"
else:
gen_trace_file.close()
- os.remove(gen_trace_path)
+ os.remove(trace_path)
def write_cmdlines():
res = ""
- if is_generated_trace:
+ if not gen_trace_file:
res += 'Command to generate trace:\n'
res += 'tools/serialize_test_trace.py '
res += '--descriptor {} {} > {}\n'.format(
os.path.relpath(self.trace_descriptor_path, ROOT_DIR),
os.path.relpath(self.test.trace_path, ROOT_DIR),
- os.path.relpath(gen_trace_path, ROOT_DIR))
+ os.path.relpath(trace_path, ROOT_DIR))
res += f"Command line:\n{' '.join(result.cmd)}\n"
return res
@@ -359,10 +372,9 @@
trace_descriptor_path: str
test_runners: List[TestCaseRunner]
- def __init__(self, query_metric_filter: str, trace_filter: str,
- trace_processor_path: str, trace_descriptor: str,
- no_colors: bool):
- self.tests = read_all_tests(query_metric_filter, trace_filter, ROOT_DIR)
+ def __init__(self, name_filter: str, trace_processor_path: str,
+ trace_descriptor: str, no_colors: bool):
+ self.tests = read_all_tests(name_filter, ROOT_DIR)
self.trace_processor_path = trace_processor_path
out_path = os.path.dirname(self.trace_processor_path)
diff --git a/python/generators/diff_tests/testing.py b/python/generators/diff_tests/testing.py
index 867cdcf..b4e1d65 100644
--- a/python/generators/diff_tests/testing.py
+++ b/python/generators/diff_tests/testing.py
@@ -48,6 +48,11 @@
contents: str
+@dataclass
+class Systrace:
+ contents: str
+
+
class TestType(Enum):
QUERY = 1
METRIC = 2
@@ -66,6 +71,15 @@
def is_trace_file(self):
return isinstance(self.trace, Path)
+ def is_trace_textproto(self):
+ return isinstance(self.trace, TextProto)
+
+ def is_trace_json(self):
+ return isinstance(self.trace, Json)
+
+ def is_trace_systrace(self):
+ return isinstance(self.trace, Systrace)
+
def is_query_file(self):
return isinstance(self.query, Path)
@@ -127,22 +141,9 @@
# Verifies that the test should be in test suite. If False, test will not be
# executed.
- def validate(self, query_metric_filter: str, trace_filter: str):
- # Assertions until string passing is supported
- if not (self.blueprint.is_trace_file()):
- raise AssertionError("Test parameters should be passed as files.")
-
- query_metric_pattern = re.compile(query_metric_filter)
- trace_pattern = re.compile(trace_filter)
- if self.query_path and not query_metric_pattern.match(
- os.path.basename(self.name)):
- return False
-
- if self.trace_path and not trace_pattern.match(
- os.path.basename(self.trace_path)):
- False
-
- return True
+ def validate(self, name_filter: str):
+ query_metric_pattern = re.compile(name_filter)
+ return bool(query_metric_pattern.match(os.path.basename(self.name)))
# Virtual class responsible for fetching diff tests.
diff --git a/python/generators/diff_tests/utils.py b/python/generators/diff_tests/utils.py
index 854e9d7..9f88555 100644
--- a/python/generators/diff_tests/utils.py
+++ b/python/generators/diff_tests/utils.py
@@ -149,8 +149,7 @@
return trace_descriptor_path
-def read_all_tests(query_metric_filter: str, trace_filter: str,
- root_dir: str) -> List[testing.TestCase]:
+def read_all_tests(name_filter: str, root_dir: str) -> List[testing.TestCase]:
# Import
INCLUDE_PATH = os.path.join(root_dir, 'test', 'trace_processor')
sys.path.append(INCLUDE_PATH)
@@ -158,7 +157,4 @@
sys.path.pop()
diff_tests = fetch_all_diff_tests(INCLUDE_PATH)
- return [
- test for test in diff_tests
- if test.validate(query_metric_filter, trace_filter)
- ]
+ return [test for test in diff_tests if test.validate(name_filter)]
diff --git a/test/trace_processor/android/tests.py b/test/trace_processor/android/tests.py
index 7c7d984..37498f1 100644
--- a/test/trace_processor/android/tests.py
+++ b/test/trace_processor/android/tests.py
@@ -23,7 +23,41 @@
def test_android_system_property_counter(self):
return DiffTestBlueprint(
- trace=Path('android_system_property.textproto'),
+ trace=TextProto(r"""
+ packet {
+ timestamp: 1000
+ android_system_property {
+ values {
+ name: "debug.tracing.screen_state"
+ value: "2"
+ }
+ values {
+ name: "debug.tracing.device_state"
+ value: "some_state_from_sysprops"
+ }
+ }
+ }
+ packet {
+ ftrace_events {
+ cpu: 1
+ event {
+ timestamp: 2000
+ pid: 1
+ print {
+ buf: "C|1000|ScreenState|1\n"
+ }
+ }
+ event {
+ timestamp: 3000
+ pid: 1
+ print {
+ buf: "N|1000|DeviceStateChanged|some_state_from_atrace\n"
+ }
+ }
+ }
+ }
+
+ """),
query="""
SELECT t.id, t.type, t.name, c.id, c.ts, c.type, c.value
FROM counter_track t JOIN counter c ON t.id = c.track_id
@@ -37,7 +71,41 @@
def test_android_system_property_slice(self):
return DiffTestBlueprint(
- trace=Path('android_system_property.textproto'),
+ trace=TextProto(r"""
+ packet {
+ timestamp: 1000
+ android_system_property {
+ values {
+ name: "debug.tracing.screen_state"
+ value: "2"
+ }
+ values {
+ name: "debug.tracing.device_state"
+ value: "some_state_from_sysprops"
+ }
+ }
+ }
+ packet {
+ ftrace_events {
+ cpu: 1
+ event {
+ timestamp: 2000
+ pid: 1
+ print {
+ buf: "C|1000|ScreenState|1\n"
+ }
+ }
+ event {
+ timestamp: 3000
+ pid: 1
+ print {
+ buf: "N|1000|DeviceStateChanged|some_state_from_atrace\n"
+ }
+ }
+ }
+ }
+
+ """),
query="""
SELECT t.id, t.type, t.name, s.id, s.ts, s.dur, s.type, s.name
FROM track t JOIN slice s ON s.track_id = t.id
diff --git a/test/trace_processor/android/tests_games.py b/test/trace_processor/android/tests_games.py
index 0211b25..9b674aa 100644
--- a/test/trace_processor/android/tests_games.py
+++ b/test/trace_processor/android/tests_games.py
@@ -20,10 +20,57 @@
class AndroidGames(TestSuite):
-
+ # Ensure Android game intervention list are parsed correctly
def test_game_intervention_list(self):
return DiffTestBlueprint(
- trace=Path('game_intervention_list_test.textproto'),
+ trace=TextProto(r"""
+ packet {
+ android_game_intervention_list {
+ parse_error: false
+ read_error: false
+ game_packages {
+ name: "com.test.game1"
+ uid: 1001
+ current_mode: 1
+ game_mode_info {
+ mode: 1
+ use_angle: true
+ resolution_downscale: 1.0
+ fps: 0.0
+ }
+ game_mode_info {
+ mode: 2
+ use_angle: false
+ resolution_downscale: 1.0
+ fps: 60.0
+ }
+ game_mode_info {
+ mode: 3
+ use_angle: true
+ resolution_downscale: 0.75
+ fps: 120.0
+ }
+ }
+ game_packages {
+ name: "com.test.game2"
+ uid: 1002
+ current_mode: 3
+ game_mode_info {
+ mode: 1
+ use_angle: false
+ resolution_downscale: 1.0
+ fps: 0.0
+ }
+ game_mode_info {
+ mode: 3
+ use_angle: false
+ resolution_downscale: 0.95
+ fps: 45.0
+ }
+ }
+ }
+ }
+ """),
query="""
SELECT
package_name,
diff --git a/test/trace_processor/atrace/tests.py b/test/trace_processor/atrace/tests.py
index 2fa26c0..ad0680e 100644
--- a/test/trace_processor/atrace/tests.py
+++ b/test/trace_processor/atrace/tests.py
@@ -20,7 +20,8 @@
class Atrace(TestSuite):
-
+ # Match legacy Catapult behaviour when we see multiple S events b2b with the
+ # cookie name and upid.
def test_android_b2b_async_begin_list_slices(self):
return DiffTestBlueprint(
trace=Path('android_b2b_async_begin.textproto'),
@@ -35,9 +36,38 @@
1030,20,"multistart"
"""))
+ # Android userspace async slices
def test_process_track_slices_android_async_slice(self):
return DiffTestBlueprint(
- trace=Path('android_async_slice.textproto'),
+ trace=TextProto(r"""
+ packet {
+ ftrace_events {
+ cpu: 3
+ event {
+ timestamp: 74289018336
+ pid: 4064
+ print {
+ ip: 18446743562018522420
+ buf: "S|1204|launching: com.android.chrome|0\n"
+ }
+ }
+ }
+ }
+ packet {
+ ftrace_events {
+ cpu: 2
+ event {
+ timestamp: 74662603008
+ pid: 1257
+ print {
+ ip: 18446743562018522420
+ buf: "F|1204|launching: com.android.chrome|0\n"
+ }
+ }
+ }
+ }
+
+ """),
query="""
SELECT
ts,
@@ -72,6 +102,7 @@
60,5,2,"ev","track"
"""))
+ # Resolving slice nesting issues when tracing both atrace and sys_write
def test_sys_write_and_atrace(self):
return DiffTestBlueprint(
trace=Path('sys_write_and_atrace.py'),
diff --git a/test/trace_processor/atrace/tests_error_handling.py b/test/trace_processor/atrace/tests_error_handling.py
index dd662f1..41f3dca 100644
--- a/test/trace_processor/atrace/tests_error_handling.py
+++ b/test/trace_processor/atrace/tests_error_handling.py
@@ -20,7 +20,7 @@
class AtraceErrorHandling(TestSuite):
-
+ # Check error handling when parsing print events.
def test_bad_print_textproto_list_slices(self):
return DiffTestBlueprint(
trace=Path('bad_print.textproto'),
diff --git a/test/trace_processor/camera/tests.py b/test/trace_processor/camera/tests.py
index 5733369..c9fd353 100644
--- a/test/trace_processor/camera/tests.py
+++ b/test/trace_processor/camera/tests.py
@@ -26,14 +26,14 @@
trace=Path('../../data/camera-ion-mem-trace'),
query=Metric('android_camera'),
out=TextProto(r"""
-android_camera {
- gc_rss_and_dma {
- min: 47779840.0
- max: 2529583104.0
- avg: 1459479416.3297353
- }
-}
-"""))
+ android_camera {
+ gc_rss_and_dma {
+ min: 47779840.0
+ max: 2529583104.0
+ avg: 1459479416.3297353
+ }
+ }
+ """))
def test_camera_ion_mem_trace_android_camera_unagg(self):
return DiffTestBlueprint(
diff --git a/test/trace_processor/chrome/tests b/test/trace_processor/chrome/tests
index 2537798..36a02d9 100644
--- a/test/trace_processor/chrome/tests
+++ b/test/trace_processor/chrome/tests
@@ -34,4 +34,4 @@
# Trace proto content
../../data/chrome_scroll_without_vsync.pftrace proto_content_test.sql proto_content.out
# TODO(mayzner): Uncomment when it works
-# ../../data/chrome_scroll_without_vsync.pftrace proto_content_path_test.sql proto_content_path.out
\ No newline at end of file
+../../data/chrome_scroll_without_vsync.pftrace proto_content_path_test.sql proto_content_path.out
\ No newline at end of file
diff --git a/test/trace_processor/chrome/tests.py b/test/trace_processor/chrome/tests.py
index 7f222f0..0fa836d 100644
--- a/test/trace_processor/chrome/tests.py
+++ b/test/trace_processor/chrome/tests.py
@@ -20,43 +20,134 @@
class Chrome(TestSuite):
-
+ # Tests related to Chrome's use of Perfetto. Chrome histogram hashes
def test_chrome_histogram_hashes(self):
return DiffTestBlueprint(
- trace=Path('chrome_histogram_hashes.textproto'),
+ trace=TextProto(r"""
+ packet {
+ trusted_packet_sequence_id: 1
+ timestamp: 0
+ incremental_state_cleared: true
+ track_event {
+ categories: "cat1"
+ type: 3
+ name_iid: 1
+ chrome_histogram_sample {
+ name_hash: 10
+ sample: 100
+ }
+ }
+ }
+ packet {
+ trusted_packet_sequence_id: 1
+ timestamp: 0
+ incremental_state_cleared: true
+ track_event {
+ categories: "cat2"
+ type: 3
+ name_iid: 2
+ chrome_histogram_sample {
+ name_hash: 20
+ }
+ }
+ }
+
+ """),
query=Metric('chrome_histogram_hashes'),
out=TextProto(r"""
-[perfetto.protos.chrome_histogram_hashes]: {
- hash: 10
- hash: 20
-}
-"""))
+ [perfetto.protos.chrome_histogram_hashes]: {
+ hash: 10
+ hash: 20
+ }
+ """))
+ # Chrome user events
def test_chrome_user_event_hashes(self):
return DiffTestBlueprint(
- trace=Path('chrome_user_event_hashes.textproto'),
+ trace=TextProto(r"""
+ packet {
+ trusted_packet_sequence_id: 1
+ timestamp: 0
+ incremental_state_cleared: true
+ track_event {
+ categories: "cat1"
+ type: 3
+ name_iid: 1
+ chrome_user_event {
+ action_hash: 10
+ }
+ }
+ }
+ packet {
+ trusted_packet_sequence_id: 1
+ timestamp: 0
+ incremental_state_cleared: true
+ track_event {
+ categories: "cat2"
+ type: 3
+ name_iid: 2
+ chrome_user_event {
+ action_hash: 20
+ }
+ }
+ }
+
+
+ """),
query=Metric('chrome_user_event_hashes'),
out=TextProto(r"""
-[perfetto.protos.chrome_user_event_hashes]: {
- action_hash: 10
- action_hash: 20
-}
+ [perfetto.protos.chrome_user_event_hashes]: {
+ action_hash: 10
+ action_hash: 20
+ }
+
+ """))
-"""))
-
+ # Chrome performance mark
def test_chrome_performance_mark_hashes(self):
return DiffTestBlueprint(
- trace=Path('chrome_performance_mark_hashes.textproto'),
+ trace=TextProto(r"""
+ packet {
+ trusted_packet_sequence_id: 1
+ timestamp: 0
+ incremental_state_cleared: true
+ track_event {
+ categories: "cat1"
+ type: 3
+ name: "name1"
+ [perfetto.protos.ChromeTrackEvent.chrome_hashed_performance_mark] {
+ site_hash: 10
+ mark_hash: 100
+ }
+ }
+ }
+ packet {
+ trusted_packet_sequence_id: 1
+ timestamp: 0
+ incremental_state_cleared: true
+ track_event {
+ categories: "cat2"
+ type: 3
+ name: "name2"
+ [perfetto.protos.ChromeTrackEvent.chrome_hashed_performance_mark] {
+ site_hash: 20
+ mark_hash: 200
+ }
+ }
+ }
+
+ """),
query=Metric('chrome_performance_mark_hashes'),
out=TextProto(r"""
-[perfetto.protos.chrome_performance_mark_hashes]: {
- site_hash: 10
- site_hash: 20
- mark_hash: 100
- mark_hash: 200
-}
-"""))
+ [perfetto.protos.chrome_performance_mark_hashes]: {
+ site_hash: 10
+ site_hash: 20
+ mark_hash: 100
+ mark_hash: 200
+ }
+ """))
+ # Chrome reliable range
def test_chrome_reliable_range(self):
return DiffTestBlueprint(
trace=Path('chrome_reliable_range.textproto'),
@@ -84,18 +175,45 @@
1011,"Missing process data for upid=2",2,1
"""))
+ # Chrome slices
def test_chrome_slice_names(self):
return DiffTestBlueprint(
- trace=Path('chrome_slice_names.textproto'),
+ trace=TextProto(r"""
+ packet {
+ trusted_packet_sequence_id: 1
+ timestamp: 1000
+ track_event {
+ categories: "cat"
+ name: "Looper.Dispatch: class1"
+ type: 3
+ }
+ }
+ packet {
+ trusted_packet_sequence_id: 1
+ timestamp: 2000
+ track_event {
+ categories: "cat"
+ name: "name2"
+ type: 3
+ }
+ }
+ packet {
+ chrome_metadata {
+ chrome_version_code: 123
+ }
+ }
+
+ """),
query=Metric('chrome_slice_names'),
out=TextProto(r"""
-[perfetto.protos.chrome_slice_names]: {
- chrome_version_code: 123
- slice_name: "Looper.Dispatch: class1"
- slice_name: "name2"
-}
-"""))
+ [perfetto.protos.chrome_slice_names]: {
+ chrome_version_code: 123
+ slice_name: "Looper.Dispatch: class1"
+ slice_name: "name2"
+ }
+ """))
+ # Chrome tasks.
def test_chrome_tasks(self):
return DiffTestBlueprint(
trace=Path(
@@ -135,6 +253,7 @@
'top_level_java_choreographer_slices_top_level_java_chrome_tasks_test.out'
))
+ # Chrome stack samples.
def test_chrome_stack_samples_for_task(self):
return DiffTestBlueprint(
trace=Path('../../data/chrome_stack_traces_symbolized_trace.pftrace'),
@@ -162,9 +281,54 @@
""",
out=Path('chrome_stack_samples_for_task_test.out'))
+ # Log messages.
def test_chrome_log_message(self):
return DiffTestBlueprint(
- trace=Path('chrome_log_message.textproto'),
+ trace=TextProto(r"""
+ packet {
+ timestamp: 0
+ incremental_state_cleared: true
+ trusted_packet_sequence_id: 1
+ track_descriptor {
+ uuid: 12345
+ thread {
+ pid: 123
+ tid: 345
+ }
+ parent_uuid: 0
+ chrome_thread {
+ thread_type: THREAD_POOL_FG_WORKER
+ }
+ }
+ }
+
+ packet {
+ trusted_packet_sequence_id: 1
+ timestamp: 10
+ track_event {
+ track_uuid: 12345
+ categories: "cat1"
+ type: TYPE_INSTANT
+ name: "slice1"
+ log_message {
+ body_iid: 1
+ source_location_iid: 3
+ }
+ }
+ interned_data {
+ log_message_body {
+ iid: 1
+ body: "log message"
+ }
+ source_locations {
+ iid: 3
+ function_name: "func"
+ file_name: "foo.cc"
+ line_number: 123
+ }
+ }
+ }
+ """),
query="""
SELECT utid, tag, msg FROM android_logs;
""",
@@ -175,13 +339,58 @@
def test_chrome_log_message_args(self):
return DiffTestBlueprint(
- trace=Path('chrome_log_message.textproto'),
+ trace=TextProto(r"""
+ packet {
+ timestamp: 0
+ incremental_state_cleared: true
+ trusted_packet_sequence_id: 1
+ track_descriptor {
+ uuid: 12345
+ thread {
+ pid: 123
+ tid: 345
+ }
+ parent_uuid: 0
+ chrome_thread {
+ thread_type: THREAD_POOL_FG_WORKER
+ }
+ }
+ }
+
+ packet {
+ trusted_packet_sequence_id: 1
+ timestamp: 10
+ track_event {
+ track_uuid: 12345
+ categories: "cat1"
+ type: TYPE_INSTANT
+ name: "slice1"
+ log_message {
+ body_iid: 1
+ source_location_iid: 3
+ }
+ }
+ interned_data {
+ log_message_body {
+ iid: 1
+ body: "log message"
+ }
+ source_locations {
+ iid: 3
+ function_name: "func"
+ file_name: "foo.cc"
+ line_number: 123
+ }
+ }
+ }
+ """),
query=Path('chrome_log_message_args_test.sql'),
out=Csv("""
"log_message","function_name","file_name","line_number"
"log message","func","foo.cc",123
"""))
+ # Chrome custom navigation event names
def test_chrome_custom_navigation_tasks(self):
return DiffTestBlueprint(
trace=Path('../../data/chrome_custom_navigation_trace.gz'),
@@ -206,8 +415,28 @@
"FrameHost::DidCommitProvisionalLoad (SUBFRAME)","navigation_task",1
"""))
+ # Trace proto content
def test_proto_content(self):
return DiffTestBlueprint(
trace=Path('../../data/chrome_scroll_without_vsync.pftrace'),
query=Path('proto_content_test.sql'),
out=Path('proto_content.out'))
+
+ # TODO(mayzner): Uncomment when it works
+ # def test_proto_content_path(self):
+ # return DiffTestBlueprint(
+ # trace=Path('../../data/chrome_scroll_without_vsync.pftrace'),
+ # query=Path('proto_content_path_test.sql'),
+ # out=Csv("""
+ # "total_size","field_type","field_name","parent_id","event_category","event_name"
+ # 137426,"TracePacket","[NULL]","[NULL]","[NULL]","[NULL]"
+ # 59475,"TrackEvent","#track_event",415,"[NULL]","[NULL]"
+ # 37903,"TrackEvent","#track_event",17,"[NULL]","[NULL]"
+ # 35904,"int32","#trusted_uid",17,"[NULL]","[NULL]"
+ # 35705,"TracePacket","[NULL]","[NULL]","input,benchmark","LatencyInfo.Flow"
+ # 29403,"TracePacket","[NULL]","[NULL]","cc,input","[NULL]"
+ # 24703,"ChromeLatencyInfo","#chrome_latency_info",18,"[NULL]","[NULL]"
+ # 22620,"uint64","#time_us",26,"[NULL]","[NULL]"
+ # 18711,"TrackEvent","#track_event",1467,"[NULL]","[NULL]"
+ # 15606,"uint64","#timestamp",17,"[NULL]","[NULL]"
+ # """))
diff --git a/test/trace_processor/chrome/tests_args.py b/test/trace_processor/chrome/tests_args.py
index 4cafcf5..9994d47 100644
--- a/test/trace_processor/chrome/tests_args.py
+++ b/test/trace_processor/chrome/tests_args.py
@@ -20,26 +20,26 @@
class ChromeArgs(TestSuite):
-
+ # Unsymbolized args.
def test_unsymbolized_args(self):
return DiffTestBlueprint(
trace=Path('unsymbolized_args.textproto'),
query=Metric('chrome_unsymbolized_args'),
out=TextProto(r"""
-[perfetto.protos.chrome_unsymbolized_args]: {
- args {
- module: "/liblib.so"
- build_id: "6275696c642d6964"
- address: 123
- google_lookup_id: "6275696c642d6964"
- }
- args {
- module: "/libmonochrome_64.so"
- build_id: "7f0715c286f8b16c10e4ad349cda3b9b56c7a773"
- address: 234
- google_lookup_id: "c215077ff8866cb110e4ad349cda3b9b0"
- }
-}"""))
+ [perfetto.protos.chrome_unsymbolized_args]: {
+ args {
+ module: "/liblib.so"
+ build_id: "6275696c642d6964"
+ address: 123
+ google_lookup_id: "6275696c642d6964"
+ }
+ args {
+ module: "/libmonochrome_64.so"
+ build_id: "7f0715c286f8b16c10e4ad349cda3b9b56c7a773"
+ address: 234
+ google_lookup_id: "c215077ff8866cb110e4ad349cda3b9b0"
+ }
+ }"""))
def test_async_trace_1_count_slices(self):
return DiffTestBlueprint(
@@ -63,18 +63,69 @@
35
"""))
+ # Chrome args class names
def test_chrome_args_class_names(self):
return DiffTestBlueprint(
- trace=Path('chrome_args_class_names.textproto'),
+ trace=TextProto(r"""
+ packet {
+ timestamp: 0
+ incremental_state_cleared: true
+ trusted_packet_sequence_id: 1
+ track_descriptor {
+ uuid: 12345
+ thread {
+ pid: 123
+ tid: 345
+ }
+ parent_uuid: 0
+ chrome_thread {
+ thread_type: THREAD_POOL_FG_WORKER
+ }
+ }
+ }
+
+ packet {
+ trusted_packet_sequence_id: 1
+ timestamp: 0
+ incremental_state_cleared: true
+ track_event {
+ track_uuid: 12345
+ categories: "cat1"
+ type: 3
+ name: "name1"
+ [perfetto.protos.ChromeTrackEvent.android_view_dump] {
+ activity {
+ name: "A"
+ view {
+ class_name: "abc"
+ },
+ view {
+ class_name: "def"
+ },
+ view {
+ class_name: "ghi"
+ }
+ }
+ activity {
+ name: "B"
+ view {
+ class_name: "jkl"
+ }
+ }
+ }
+ }
+ }
+
+ """),
query=Metric('chrome_args_class_names'),
out=TextProto(r"""
-
-[perfetto.protos.chrome_args_class_names] {
- class_names_per_version {
- class_name: "abc"
- class_name: "def"
- class_name: "ghi"
- class_name: "jkl"
- }
-}
-"""))
+
+ [perfetto.protos.chrome_args_class_names] {
+ class_names_per_version {
+ class_name: "abc"
+ class_name: "def"
+ class_name: "ghi"
+ class_name: "jkl"
+ }
+ }
+ """))
diff --git a/test/trace_processor/chrome/tests_processes.py b/test/trace_processor/chrome/tests_processes.py
index 4e1671a..64a1d66 100644
--- a/test/trace_processor/chrome/tests_processes.py
+++ b/test/trace_processor/chrome/tests_processes.py
@@ -105,7 +105,25 @@
def test_track_with_chrome_process(self):
return DiffTestBlueprint(
- trace=Path('track_with_chrome_process.textproto'),
+ trace=TextProto(r"""
+ packet {
+ trusted_packet_sequence_id: 1
+ incremental_state_cleared: true
+ timestamp: 0
+ track_descriptor {
+ uuid: 10
+ process {
+ pid: 5
+ process_name: "p5"
+ }
+ # Empty Chrome process. This is similar to a process descriptor emitted by
+ # Chrome for a process with an unknown Chrome process_type. This process
+ # should still receive a "chrome_process_type" arg in the args table, but
+ # with a NULL value.
+ chrome_process {}
+ }
+ }
+ """),
query="""
SELECT pid, name, string_value AS chrome_process_type
FROM
@@ -121,6 +139,7 @@
5,"p5","[NULL]"
"""))
+ # Missing processes.
def test_chrome_missing_processes_default_trace(self):
return DiffTestBlueprint(
trace=Path('../../data/chrome_scroll_without_vsync.pftrace'),
@@ -139,7 +158,44 @@
def test_chrome_missing_processes(self):
return DiffTestBlueprint(
- trace=Path('chrome_missing_processes.textproto'),
+ trace=TextProto(r"""
+ packet {
+ timestamp: 1
+ incremental_state_cleared: true
+ trusted_packet_sequence_id: 1
+ track_event {
+ type: TYPE_INSTANT
+ name: "ActiveProcesses"
+ chrome_active_processes {
+ pid: 10
+ pid: 100
+ pid: 1000
+ }
+ }
+ }
+ packet {
+ timestamp: 1
+ trusted_packet_sequence_id: 2
+ track_descriptor {
+ uuid: 1
+ process {
+ pid: 10
+ }
+ parent_uuid: 0
+ }
+ }
+ packet {
+ timestamp: 1000000000
+ trusted_packet_sequence_id: 3
+ track_descriptor {
+ uuid: 2
+ process {
+ pid: 100
+ }
+ parent_uuid: 0
+ }
+ }
+ """),
query="""
SELECT upid, pid, reliable_from
FROM
@@ -157,7 +213,44 @@
def test_chrome_missing_processes_args(self):
return DiffTestBlueprint(
- trace=Path('chrome_missing_processes.textproto'),
+ trace=TextProto(r"""
+ packet {
+ timestamp: 1
+ incremental_state_cleared: true
+ trusted_packet_sequence_id: 1
+ track_event {
+ type: TYPE_INSTANT
+ name: "ActiveProcesses"
+ chrome_active_processes {
+ pid: 10
+ pid: 100
+ pid: 1000
+ }
+ }
+ }
+ packet {
+ timestamp: 1
+ trusted_packet_sequence_id: 2
+ track_descriptor {
+ uuid: 1
+ process {
+ pid: 10
+ }
+ parent_uuid: 0
+ }
+ }
+ packet {
+ timestamp: 1000000000
+ trusted_packet_sequence_id: 3
+ track_descriptor {
+ uuid: 2
+ process {
+ pid: 100
+ }
+ parent_uuid: 0
+ }
+ }
+ """),
query="""
SELECT arg_set_id, key, int_value
FROM
@@ -176,7 +269,44 @@
def test_chrome_missing_processes_2(self):
return DiffTestBlueprint(
- trace=Path('chrome_missing_processes_extension.textproto'),
+ trace=TextProto(r"""
+ packet {
+ timestamp: 1
+ incremental_state_cleared: true
+ trusted_packet_sequence_id: 1
+ track_event {
+ type: TYPE_INSTANT
+ name: "ActiveProcesses"
+ [perfetto.protos.ChromeTrackEvent.active_processes]: {
+ pid: 10
+ pid: 100
+ pid: 1000
+ }
+ }
+ }
+ packet {
+ timestamp: 1
+ trusted_packet_sequence_id: 2
+ track_descriptor {
+ uuid: 1
+ process {
+ pid: 10
+ }
+ parent_uuid: 0
+ }
+ }
+ packet {
+ timestamp: 1000000000
+ trusted_packet_sequence_id: 3
+ track_descriptor {
+ uuid: 2
+ process {
+ pid: 100
+ }
+ parent_uuid: 0
+ }
+ }
+ """),
query="""
SELECT upid, pid, reliable_from
FROM
@@ -194,7 +324,44 @@
def test_chrome_missing_processes_extension_args(self):
return DiffTestBlueprint(
- trace=Path('chrome_missing_processes_extension.textproto'),
+ trace=TextProto(r"""
+ packet {
+ timestamp: 1
+ incremental_state_cleared: true
+ trusted_packet_sequence_id: 1
+ track_event {
+ type: TYPE_INSTANT
+ name: "ActiveProcesses"
+ [perfetto.protos.ChromeTrackEvent.active_processes]: {
+ pid: 10
+ pid: 100
+ pid: 1000
+ }
+ }
+ }
+ packet {
+ timestamp: 1
+ trusted_packet_sequence_id: 2
+ track_descriptor {
+ uuid: 1
+ process {
+ pid: 10
+ }
+ parent_uuid: 0
+ }
+ }
+ packet {
+ timestamp: 1000000000
+ trusted_packet_sequence_id: 3
+ track_descriptor {
+ uuid: 2
+ process {
+ pid: 100
+ }
+ parent_uuid: 0
+ }
+ }
+ """),
query="""
SELECT arg_set_id, key, int_value
FROM
diff --git a/test/trace_processor/chrome/tests_scroll_jank.py b/test/trace_processor/chrome/tests_scroll_jank.py
index 3321f38..8300d52 100644
--- a/test/trace_processor/chrome/tests_scroll_jank.py
+++ b/test/trace_processor/chrome/tests_scroll_jank.py
@@ -20,7 +20,7 @@
class ChromeScrollJank(TestSuite):
-
+ # Scroll jank metrics
def test_scroll_jank_general_validation(self):
return DiffTestBlueprint(
trace=Path('../../data/chrome_scroll_without_vsync.pftrace'),
@@ -385,6 +385,9 @@
'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=Path('../../data/fling_with_input_delay.pftrace'),
@@ -456,18 +459,18 @@
trace=Path('../../data/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
- }
-}"""))
+ [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(
diff --git a/test/trace_processor/cros/tests.py b/test/trace_processor/cros/tests.py
index 986c999..9a51f40 100644
--- a/test/trace_processor/cros/tests.py
+++ b/test/trace_processor/cros/tests.py
@@ -20,10 +20,30 @@
class Cros(TestSuite):
-
+ # cros_ec_sensorhub_data
def test_cros_ec_sensorhub_data(self):
return DiffTestBlueprint(
- trace=Path('cros_ec_sensorhub_data.textproto'),
+ trace=TextProto(r"""
+ packet {
+ ftrace_events {
+ cpu: 0
+ event {
+ timestamp: 223951135789653
+ pid: 181
+ cros_ec_sensorhub_data {
+ current_time: 223951135778716
+ current_timestamp: 223951052378946
+ delta: -83399770
+ ec_fifo_timestamp: 2128620968
+ ec_sensor_num: 0
+ fifo_timestamp: 223951132978872
+ }
+ }
+ }
+ }
+
+
+ """),
query="""
SELECT
t.name,
diff --git a/test/trace_processor/dynamic/tests.py b/test/trace_processor/dynamic/tests.py
index abe5af5..945ba66 100644
--- a/test/trace_processor/dynamic/tests.py
+++ b/test/trace_processor/dynamic/tests.py
@@ -20,7 +20,7 @@
class Dynamic(TestSuite):
-
+ # Tests for custom dynamic tables. Ancestor slice table.
def test_ancestor_slice(self):
return DiffTestBlueprint(
trace=Path('relationship_tables.textproto'),
@@ -31,6 +31,7 @@
""",
out=Path('ancestor_slice.out'))
+ # Descendant slice table.
def test_descendant_slice(self):
return DiffTestBlueprint(
trace=Path('relationship_tables.textproto'),
@@ -41,6 +42,7 @@
""",
out=Path('descendant_slice.out'))
+ # Ancestor slice by stack table.
def test_ancestor_slice_by_stack(self):
return DiffTestBlueprint(
trace=Path('slice_stacks.textproto'),
@@ -59,6 +61,7 @@
9000,"event_depth_1"
"""))
+ # Descendant slice by stack table.
def test_descendant_slice_by_stack(self):
return DiffTestBlueprint(
trace=Path('slice_stacks.textproto'),
@@ -77,12 +80,14 @@
10000,"event_depth_2"
"""))
+ # Connected/Following/Perceeding flow table.
def test_connected_flow(self):
return DiffTestBlueprint(
trace=Path('connected_flow_data.json'),
query=Path('connected_flow_test.sql'),
out=Path('connected_flow.out'))
+ # Annotated callstacks.
def test_perf_sample_sc_annotated_callstack(self):
return DiffTestBlueprint(
trace=Path('../../data/perf_sample_sc.pb'),
@@ -98,6 +103,7 @@
""",
out=Path('perf_sample_sc_annotated_callstack.out'))
+ # ABS_TIME_STR function
def test_various_clocks_abs_time_str(self):
return DiffTestBlueprint(
trace=Path('various_clocks.textproto'),
@@ -111,7 +117,9 @@
def test_empty_abs_time_str(self):
return DiffTestBlueprint(
- trace=Path('../common/empty.textproto'),
+ trace=TextProto(r"""
+
+ """),
query="""
SELECT
ABS_TIME_STR(15) AS t15,
@@ -123,6 +131,7 @@
"[NULL]","[NULL]","[NULL]"
"""))
+ # TO_MONOTONIC function
def test_various_clocks_to_monotonic(self):
return DiffTestBlueprint(
trace=Path('various_clocks.textproto'),
@@ -139,7 +148,9 @@
def test_empty_to_monotonic(self):
return DiffTestBlueprint(
- trace=Path('../common/empty.textproto'),
+ trace=TextProto(r"""
+
+ """),
query="""
SELECT
TO_MONOTONIC(25) AS t15,
diff --git a/test/trace_processor/fuchsia/tests.py b/test/trace_processor/fuchsia/tests.py
index 20a616c..bcaccb4 100644
--- a/test/trace_processor/fuchsia/tests.py
+++ b/test/trace_processor/fuchsia/tests.py
@@ -20,7 +20,8 @@
class Fuchsia(TestSuite):
-
+ # Contains tests for parsing Fuchsia traces. Smoke test a bunch of different
+ # types.
def test_fuchsia_smoke(self):
return DiffTestBlueprint(
trace=Path('../../data/fuchsia_trace.fxt'),
@@ -163,6 +164,7 @@
9,"[NULL]","thread_track"
"""))
+ # Smoke test a high-CPU trace.
def test_fuchsia_workstation_smoke_slices(self):
return DiffTestBlueprint(
trace=Path('../../data/fuchsia_workstation.fxt'),
diff --git a/test/trace_processor/functions/tests.py b/test/trace_processor/functions/tests.py
index 73d9f2a..e9e0fbf 100644
--- a/test/trace_processor/functions/tests.py
+++ b/test/trace_processor/functions/tests.py
@@ -23,7 +23,9 @@
def test_first_non_null_frame(self):
return DiffTestBlueprint(
- trace=Path('../common/empty.textproto'),
+ trace=TextProto(r"""
+
+ """),
query="""
CREATE TABLE TEST(id INTEGER, val INTEGER);
@@ -50,7 +52,9 @@
def test_first_non_null_partition(self):
return DiffTestBlueprint(
- trace=Path('../common/empty.textproto'),
+ trace=TextProto(r"""
+
+ """),
query="""
CREATE TABLE TEST(id INTEGER, part TEXT, val INTEGER);
@@ -81,7 +85,9 @@
def test_first_non_null(self):
return DiffTestBlueprint(
- trace=Path('../common/empty.textproto'),
+ trace=TextProto(r"""
+
+ """),
query="""
CREATE TABLE TEST(id INTEGER, val INTEGER);
diff --git a/test/trace_processor/graphics/tests.py b/test/trace_processor/graphics/tests.py
index 957570c..95eaf95 100644
--- a/test/trace_processor/graphics/tests.py
+++ b/test/trace_processor/graphics/tests.py
@@ -20,7 +20,8 @@
class Graphics(TestSuite):
-
+ # Contains tests for graphics related events and tables. Graphics frame
+ # trace tests.
def test_graphics_frame_events(self):
return DiffTestBlueprint(
trace=Path('graphics_frame_events.py'),
@@ -34,6 +35,7 @@
""",
out=Path('graphics_frame_events.out'))
+ # GPU Memory ftrace packets
def test_gpu_mem_total(self):
return DiffTestBlueprint(
trace=Path('gpu_mem_total.py'),
@@ -59,6 +61,7 @@
"GPU Memory","7","Total GPU memory used by this process",10,1,50
"""))
+ # Clock sync
def test_clock_sync(self):
return DiffTestBlueprint(
trace=Path('clock_sync.py'),
@@ -80,6 +83,7 @@
3010,15
"""))
+ # Android SurfaceFlinger metrics
def test_frame_missed_event_frame_missed(self):
return DiffTestBlueprint(
trace=Path('frame_missed.py'),
@@ -101,53 +105,54 @@
trace=Path('frame_missed.py'),
query=Metric('android_surfaceflinger'),
out=TextProto(r"""
-android_surfaceflinger {
- missed_frames: 3
- missed_hwc_frames: 0
- missed_gpu_frames: 0
- missed_frame_rate: 0.42857142857142855 # = 3/7
- gpu_invocations: 0
-}
-"""))
+ android_surfaceflinger {
+ missed_frames: 3
+ missed_hwc_frames: 0
+ missed_gpu_frames: 0
+ missed_frame_rate: 0.42857142857142855 # = 3/7
+ gpu_invocations: 0
+ }
+ """))
def test_surfaceflinger_gpu_invocation(self):
return DiffTestBlueprint(
trace=Path('surfaceflinger_gpu_invocation.py'),
query=Metric('android_surfaceflinger'),
out=TextProto(r"""
-android_surfaceflinger {
- missed_frames: 0
- missed_hwc_frames: 0
- missed_gpu_frames: 0
- gpu_invocations: 4
- avg_gpu_waiting_dur_ms: 4
- total_non_empty_gpu_waiting_dur_ms: 11
-}
-"""))
+ android_surfaceflinger {
+ missed_frames: 0
+ missed_hwc_frames: 0
+ missed_gpu_frames: 0
+ gpu_invocations: 4
+ avg_gpu_waiting_dur_ms: 4
+ total_non_empty_gpu_waiting_dur_ms: 11
+ }
+ """))
+ # GPU metrics
def test_gpu_metric(self):
return DiffTestBlueprint(
trace=Path('gpu_metric.py'),
query=Metric('android_gpu'),
out=TextProto(r"""
-android_gpu {
- processes {
- name: "app_1"
- mem_max: 8
- mem_min: 2
- mem_avg: 3
- }
- processes {
- name: "app_2"
- mem_max: 10
- mem_min: 6
- mem_avg: 8
- }
- mem_max: 4
- mem_min: 1
- mem_avg: 2
-}
-"""))
+ android_gpu {
+ processes {
+ name: "app_1"
+ mem_max: 8
+ mem_min: 2
+ mem_avg: 3
+ }
+ processes {
+ name: "app_2"
+ mem_max: 10
+ mem_min: 6
+ mem_avg: 8
+ }
+ mem_max: 4
+ mem_min: 1
+ mem_avg: 2
+ }
+ """))
def test_gpu_frequency_metric(self):
return DiffTestBlueprint(
@@ -155,6 +160,7 @@
query=Metric('android_gpu'),
out=Path('gpu_frequency_metric.out'))
+ # Android Jank CUJ metric
def test_android_jank_cuj(self):
return DiffTestBlueprint(
trace=Path('android_jank_cuj.py'),
@@ -167,6 +173,7 @@
query=Path('android_jank_cuj_query_test.sql'),
out=Path('android_jank_cuj_query.out'))
+ # Frame Timeline event trace tests
def test_expected_frame_timeline_events(self):
return DiffTestBlueprint(
trace=Path('frame_timeline_events.py'),
@@ -193,6 +200,7 @@
query=Path('actual_frame_timeline_events_test.sql'),
out=Path('actual_frame_timeline_events.out'))
+ # Composition layer
def test_composition_layer_count(self):
return DiffTestBlueprint(
trace=Path('composition_layer.py'),
@@ -207,12 +215,16 @@
3.000000
"""))
+ # G2D metrics TODO(rsavitski): find a real trace and double-check that the
+ # is realistic. One kernel's source I checked had tgid=0 for all counter
+ # Initial support was added/discussed in b/171296908.
def test_g2d_metrics(self):
return DiffTestBlueprint(
trace=Path('g2d_metrics.textproto'),
query=Metric('g2d'),
out=Path('g2d_metrics.out'))
+ # Composer execution
def test_composer_execution(self):
return DiffTestBlueprint(
trace=Path('composer_execution.py'),
@@ -235,64 +247,67 @@
"unskipped_validation",1,200
"""))
+ # Display metrics
def test_display_metrics(self):
return DiffTestBlueprint(
trace=Path('display_metrics.py'),
query=Metric('display_metrics'),
out=TextProto(r"""
-display_metrics {
- total_duplicate_frames: 0
- duplicate_frames_logged: 0
- total_dpu_underrun_count: 0
- refresh_rate_switches: 5
- refresh_rate_stats {
- refresh_rate_fps: 60
- count: 2
- total_dur_ms: 2
- avg_dur_ms: 1
- }
- refresh_rate_stats {
- refresh_rate_fps: 90
- count: 2
- total_dur_ms: 2
- avg_dur_ms: 1
- }
- refresh_rate_stats {
- refresh_rate_fps: 120
- count: 1
- total_dur_ms: 2
- avg_dur_ms: 2
- }
- update_power_state {
- avg_runtime_micro_secs: 4000
- }
-}
-"""))
+ display_metrics {
+ total_duplicate_frames: 0
+ duplicate_frames_logged: 0
+ total_dpu_underrun_count: 0
+ refresh_rate_switches: 5
+ refresh_rate_stats {
+ refresh_rate_fps: 60
+ count: 2
+ total_dur_ms: 2
+ avg_dur_ms: 1
+ }
+ refresh_rate_stats {
+ refresh_rate_fps: 90
+ count: 2
+ total_dur_ms: 2
+ avg_dur_ms: 1
+ }
+ refresh_rate_stats {
+ refresh_rate_fps: 120
+ count: 1
+ total_dur_ms: 2
+ avg_dur_ms: 2
+ }
+ update_power_state {
+ avg_runtime_micro_secs: 4000
+ }
+ }
+ """))
+ # DPU vote clock and bandwidth
def test_dpu_vote_clock_bw(self):
return DiffTestBlueprint(
trace=Path('dpu_vote_clock_bw.textproto'),
query=Metric('android_hwcomposer'),
out=TextProto(r"""
-android_hwcomposer {
- skipped_validation_count: 0
- unskipped_validation_count: 0
- separated_validation_count: 0
- unknown_validation_count: 0
- dpu_vote_metrics {
- tid: 237
- avg_dpu_vote_clock: 206250
- avg_dpu_vote_avg_bw: 210000
- avg_dpu_vote_peak_bw: 205000
- avg_dpu_vote_rt_bw: 271000
- }
- dpu_vote_metrics {
- tid: 299
- avg_dpu_vote_clock: 250000
- }
-}
-"""))
+ android_hwcomposer {
+ skipped_validation_count: 0
+ unskipped_validation_count: 0
+ separated_validation_count: 0
+ unknown_validation_count: 0
+ dpu_vote_metrics {
+ tid: 237
+ avg_dpu_vote_clock: 206250
+ avg_dpu_vote_avg_bw: 210000
+ avg_dpu_vote_peak_bw: 205000
+ avg_dpu_vote_rt_bw: 271000
+ }
+ dpu_vote_metrics {
+ tid: 299
+ avg_dpu_vote_clock: 250000
+ }
+ }
+ """))
+ # Video 4 Linux 2 related tests
def test_v4l2_vidioc_slice(self):
return DiffTestBlueprint(
trace=Path('v4l2_vidioc.textproto'),
@@ -338,6 +353,7 @@
593209502603,100000,"RESOURCE_QUEUE","virtio_video stream #4 Responses"
"""))
+ # virtgpu (drm/virtio) related tests
def test_virtio_gpu(self):
return DiffTestBlueprint(
trace=Path('virtio_gpu.textproto'),
@@ -356,9 +372,50 @@
1345090746311,1167135,"CTX_DETACH_RESOURCE"
"""))
+ # mali GPU events
def test_mali(self):
return DiffTestBlueprint(
- trace=Path('mali.textproto'),
+ trace=TextProto(r"""
+ packet {
+ ftrace_events {
+ cpu: 2
+ event {
+ timestamp: 751796307210
+ pid: 2857
+ mali_mali_KCPU_CQS_WAIT_START {
+ info_val1: 1
+ info_val2: 0
+ kctx_tgid: 2201
+ kctx_id: 10
+ id: 0
+ }
+ }
+ event {
+ timestamp: 751800621175
+ pid: 2857
+ mali_mali_KCPU_CQS_WAIT_END {
+ info_val1: 412313493488
+ info_val2: 0
+ kctx_tgid: 2201
+ kctx_id: 10
+ id: 0
+ }
+ }
+ event {
+ timestamp: 751800638997
+ pid: 2857
+ mali_mali_KCPU_CQS_SET {
+ info_val1: 412313493480
+ info_val2: 0
+ kctx_tgid: 2201
+ kctx_id: 10
+ id: 0
+ }
+ }
+ }
+ }
+
+ """),
query="""
SELECT ts, dur, name FROM slice WHERE name GLOB "mali_KCPU_CQS*";
""",
@@ -370,7 +427,47 @@
def test_mali_fence(self):
return DiffTestBlueprint(
- trace=Path('mali_fence.textproto'),
+ trace=TextProto(r"""
+ packet {
+ ftrace_events {
+ cpu: 2
+ event {
+ timestamp: 751796307210
+ pid: 2857
+ mali_mali_KCPU_FENCE_WAIT_START {
+ info_val1: 1
+ info_val2: 0
+ kctx_tgid: 2201
+ kctx_id: 10
+ id: 0
+ }
+ }
+ event {
+ timestamp: 751800621175
+ pid: 2857
+ mali_mali_KCPU_FENCE_WAIT_END {
+ info_val1: 412313493488
+ info_val2: 0
+ kctx_tgid: 2201
+ kctx_id: 10
+ id: 0
+ }
+ }
+ event {
+ timestamp: 751800638997
+ pid: 2857
+ mali_mali_KCPU_FENCE_SIGNAL {
+ info_val1: 412313493480
+ info_val2: 0
+ kctx_tgid: 2201
+ kctx_id: 10
+ id: 0
+ }
+ }
+ }
+ }
+
+ """),
query="""
SELECT ts, dur, name FROM slice WHERE name GLOB "mali_KCPU_FENCE*";
""",
diff --git a/test/trace_processor/graphics/tests_drm_related_ftrace_events.py b/test/trace_processor/graphics/tests_drm_related_ftrace_events.py
index 4a5c1bd..71e3176 100644
--- a/test/trace_processor/graphics/tests_drm_related_ftrace_events.py
+++ b/test/trace_processor/graphics/tests_drm_related_ftrace_events.py
@@ -23,7 +23,38 @@
def test_drm_vblank_gpu_track(self):
return DiffTestBlueprint(
- trace=Path('drm_vblank.textproto'),
+ trace=TextProto(r"""
+ packet {
+ ftrace_events {
+ cpu: 0
+ event {
+ timestamp: 6159770881976
+ pid: 0
+ drm_vblank_event {
+ crtc: 0
+ high_prec: 1
+ seq: 3551
+ time: 6159771267407
+ }
+ }
+ }
+ }
+ packet {
+ ftrace_events {
+ cpu: 4
+ event {
+ timestamp: 6159770993376
+ pid: 144
+ drm_vblank_event_delivered {
+ crtc: 0
+ file: 18446743526216291840
+ seq: 3551
+ }
+ }
+ }
+ }
+
+ """),
query="""
SELECT
gpu_track.name,
diff --git a/test/trace_processor/include_index.py b/test/trace_processor/include_index.py
index 7432229..38b06e9 100644
--- a/test/trace_processor/include_index.py
+++ b/test/trace_processor/include_index.py
@@ -74,7 +74,6 @@
from track_event.tests import TrackEvent
from translation.tests import Translation
-
def fetch_all_diff_tests(index_path: str) -> List['testing.TestCase']:
return [
*Android(index_path, 'android', 'Android').fetch(),
diff --git a/test/trace_processor/memory/tests.py b/test/trace_processor/memory/tests.py
index 93743cc..5f4c173 100644
--- a/test/trace_processor/memory/tests.py
+++ b/test/trace_processor/memory/tests.py
@@ -20,61 +20,152 @@
class Memory(TestSuite):
-
+ # Contains test for Android memory metrics. ION metric
def test_android_ion(self):
return DiffTestBlueprint(
trace=Path('android_ion.py'),
query=Metric('android_ion'),
out=TextProto(r"""
-android_ion {
- buffer {
- name: "adsp"
- avg_size_bytes: 1000.0
- min_size_bytes: 1000.0
- max_size_bytes: 1100.0
- total_alloc_size_bytes: 1100.0
- }
- buffer {
- name: "system"
- avg_size_bytes: 1497.4874371859296
- min_size_bytes: 1000.0
- max_size_bytes: 2000.0
- total_alloc_size_bytes: 2000.0
- }
-}
-"""))
+ android_ion {
+ buffer {
+ name: "adsp"
+ avg_size_bytes: 1000.0
+ min_size_bytes: 1000.0
+ max_size_bytes: 1100.0
+ total_alloc_size_bytes: 1100.0
+ }
+ buffer {
+ name: "system"
+ avg_size_bytes: 1497.4874371859296
+ min_size_bytes: 1000.0
+ max_size_bytes: 2000.0
+ total_alloc_size_bytes: 2000.0
+ }
+ }
+ """))
def test_android_ion_stat(self):
return DiffTestBlueprint(
- trace=Path('android_ion_stat.textproto'),
+ trace=TextProto(r"""
+ packet {
+ ftrace_events {
+ cpu: 0
+ event {
+ timestamp: 100
+ pid: 1
+ ion_stat {
+ buffer_id: 123
+ len: 1000
+ total_allocated: 2000
+ }
+ }
+ }
+ }
+ packet {
+ ftrace_events {
+ cpu: 0
+ event {
+ timestamp: 200
+ pid: 1
+ ion_stat {
+ buffer_id: 123
+ len: -1000
+ total_allocated: 1000
+ }
+ }
+ }
+ }
+
+ """),
query=Metric('android_ion'),
out=TextProto(r"""
-android_ion {
- buffer {
- name: "all"
- avg_size_bytes: 2000.0
- min_size_bytes: 1000.0
- max_size_bytes: 2000.0
- total_alloc_size_bytes: 1000.0
- }
-}"""))
+ android_ion {
+ buffer {
+ name: "all"
+ avg_size_bytes: 2000.0
+ min_size_bytes: 1000.0
+ max_size_bytes: 2000.0
+ total_alloc_size_bytes: 1000.0
+ }
+ }"""))
+ # DMA-BUF heap Metric
def test_android_dma_heap_stat(self):
return DiffTestBlueprint(
- trace=Path('android_dma_heap_stat.textproto'),
+ trace=TextProto(r"""
+ packet {
+ ftrace_events {
+ cpu: 0
+ event {
+ timestamp: 100
+ pid: 1
+ dma_heap_stat {
+ inode: 123
+ len: 1024
+ total_allocated: 2048
+ }
+ }
+ }
+ }
+ packet {
+ ftrace_events {
+ cpu: 0
+ event {
+ timestamp: 200
+ pid: 1
+ dma_heap_stat {
+ inode: 123
+ len: -1024
+ total_allocated: 1024
+ }
+ }
+ }
+ }
+
+ """),
query=Metric('android_dma_heap'),
out=TextProto(r"""
-android_dma_heap {
- avg_size_bytes: 2048.0
- min_size_bytes: 1024.0
- max_size_bytes: 2048.0
- total_alloc_size_bytes: 1024.0
-}
-"""))
+ android_dma_heap {
+ avg_size_bytes: 2048.0
+ min_size_bytes: 1024.0
+ max_size_bytes: 2048.0
+ total_alloc_size_bytes: 1024.0
+ }
+ """))
def test_android_dma_buffer_tracks(self):
return DiffTestBlueprint(
- trace=Path('android_dma_heap_stat.textproto'),
+ trace=TextProto(r"""
+ packet {
+ ftrace_events {
+ cpu: 0
+ event {
+ timestamp: 100
+ pid: 1
+ dma_heap_stat {
+ inode: 123
+ len: 1024
+ total_allocated: 2048
+ }
+ }
+ }
+ }
+ packet {
+ ftrace_events {
+ cpu: 0
+ event {
+ timestamp: 200
+ pid: 1
+ dma_heap_stat {
+ inode: 123
+ len: -1024
+ total_allocated: 1024
+ }
+ }
+ }
+ }
+
+ """),
query="""
SELECT track.name, slice.ts, slice.dur, slice.name
FROM slice JOIN track ON slice.track_id = track.id
@@ -85,25 +176,96 @@
"mem.dma_buffer",100,100,"1 kB"
"""))
+ # fastrpc metric
def test_android_fastrpc_dma_stat(self):
return DiffTestBlueprint(
- trace=Path('android_fastrpc_dma_stat.textproto'),
+ trace=TextProto(r"""
+ packet {
+ ftrace_events {
+ cpu: 0
+ event {
+ timestamp: 100
+ pid: 1
+ fastrpc_dma_stat {
+ cid: 1
+ len: 1000
+ total_allocated: 2000
+ }
+ }
+ }
+ }
+ packet {
+ ftrace_events {
+ cpu: 0
+ event {
+ timestamp: 200
+ pid: 1
+ fastrpc_dma_stat {
+ cid: 1
+ len: -1000
+ total_allocated: 1000
+ }
+ }
+ }
+ }
+
+ """),
query=Metric('android_fastrpc'),
out=TextProto(r"""
-android_fastrpc {
- subsystem {
- name: "MDSP"
- avg_size_bytes: 2000.0
- min_size_bytes: 1000.0
- max_size_bytes: 2000.0
- total_alloc_size_bytes: 1000.0
- }
-}
-"""))
+ android_fastrpc {
+ subsystem {
+ name: "MDSP"
+ avg_size_bytes: 2000.0
+ min_size_bytes: 1000.0
+ max_size_bytes: 2000.0
+ total_alloc_size_bytes: 1000.0
+ }
+ }
+ """))
+ # shrink slab
def test_shrink_slab(self):
return DiffTestBlueprint(
- trace=Path('shrink_slab.textproto'),
+ trace=TextProto(r"""
+ packet {
+ ftrace_events {
+ cpu: 7
+ event {
+ timestamp: 36448185787847
+ pid: 156
+ mm_shrink_slab_start {
+ cache_items: 1
+ delta: 0
+ gfp_flags: 3264
+ nr_objects_to_shrink: 0
+ shr: 18446743882920355600
+ shrink: 90
+ total_scan: 0
+ nid: 0
+ priority: 12
+ }
+ }
+ }
+ }
+ packet {
+ ftrace_events {
+ cpu: 7
+ event {
+ timestamp: 36448185788539
+ pid: 156
+ mm_shrink_slab_end {
+ new_scan: 0
+ retval: 0
+ shr: 18446743882920355600
+ shrink: 90
+ total_scan: 0
+ unused_scan: 0
+ nid: 0
+ }
+ }
+ }
+ }
+ """),
query="""
SELECT ts, dur, name FROM slice WHERE name = 'mm_vmscan_shrink_slab';
""",
@@ -112,9 +274,49 @@
36448185787847,692,"mm_vmscan_shrink_slab"
"""))
+ # cma alloc
def test_cma(self):
return DiffTestBlueprint(
- trace=Path('cma.textproto'),
+ trace=TextProto(r"""
+ packet {
+ system_info {
+ utsname {
+ sysname: "Linux"
+ release: "5.10.0"
+ }
+ }
+ }
+ packet {
+ ftrace_events {
+ cpu: 4
+ event {
+ timestamp: 74288080958099
+ pid: 537
+ cma_alloc_start {
+ align: 4
+ count: 6592
+ name: "farawimg"
+ }
+ }
+ event {
+ timestamp: 74288191109751
+ pid: 537
+ cma_alloc_info {
+ align: 4
+ count: 6592
+ err_iso: 0
+ err_mig: 0
+ err_test: 0
+ name: "farawimg"
+ nr_mapped: 832596
+ nr_migrated: 6365
+ nr_reclaimed: 7
+ pfn: 10365824
+ }
+ }
+ }
+ }
+ """),
query="""
SELECT ts, dur, name FROM slice WHERE name = 'mm_cma_alloc';
""",
diff --git a/test/trace_processor/memory/tests_metrics.py b/test/trace_processor/memory/tests_metrics.py
index f622d6b..228e7e6 100644
--- a/test/trace_processor/memory/tests_metrics.py
+++ b/test/trace_processor/memory/tests_metrics.py
@@ -44,42 +44,69 @@
trace=Path('android_systrace_lmk.py'),
query=Metric('android_lmk'),
out=TextProto(r"""
-android_lmk {
- total_count: 1
- by_oom_score {
- oom_score_adj: 900
- count: 1
- }
- oom_victim_count: 0
-}
-"""))
+ android_lmk {
+ total_count: 1
+ by_oom_score {
+ oom_score_adj: 900
+ count: 1
+ }
+ oom_victim_count: 0
+ }
+ """))
def test_android_lmk_oom(self):
return DiffTestBlueprint(
- trace=Path('../common/oom_kill.textproto'),
+ trace=TextProto(r"""
+ packet {
+ process_tree {
+ processes {
+ pid: 1000
+ ppid: 1
+ cmdline: "com.google.android.gm"
+ }
+ threads {
+ tid: 1001
+ tgid: 1000
+ }
+ }
+ }
+ packet {
+ ftrace_events {
+ cpu: 4
+ event {
+ timestamp: 1234
+ pid: 4321
+ mark_victim {
+ pid: 1001
+ }
+ }
+ }
+ }
+
+ """),
query=Metric('android_lmk'),
out=TextProto(r"""
-android_lmk {
- total_count: 0
- oom_victim_count: 1
-}"""))
+ android_lmk {
+ total_count: 0
+ oom_victim_count: 1
+ }"""))
def test_android_mem_delta(self):
return DiffTestBlueprint(
trace=Path('android_mem_delta.py'),
query=Metric('android_mem'),
out=TextProto(r"""
-android_mem {
- process_metrics {
- process_name: "com.my.pkg"
- total_counters {
- file_rss {
- min: 2000.0
- max: 10000.0
- avg: 6666.666666666667
- delta: 7000.0
- }
- }
- }
-}
-"""))
+ android_mem {
+ process_metrics {
+ process_name: "com.my.pkg"
+ total_counters {
+ file_rss {
+ min: 2000.0
+ max: 10000.0
+ avg: 6666.666666666667
+ delta: 7000.0
+ }
+ }
+ }
+ }
+ """))
diff --git a/test/trace_processor/network/tests.py b/test/trace_processor/network/tests.py
index 01dd482..abea8c2 100644
--- a/test/trace_processor/network/tests.py
+++ b/test/trace_processor/network/tests.py
@@ -20,7 +20,7 @@
class Network(TestSuite):
-
+ # Network performance
def test_netif_receive_skb(self):
return DiffTestBlueprint(
trace=Path('netif_receive_skb.textproto'),
@@ -109,7 +109,43 @@
def test_tcp_retransmit_skb(self):
return DiffTestBlueprint(
- trace=Path('tcp_retransmit_skb.textproto'),
+ trace=TextProto(r"""
+ packet {
+ ftrace_events {
+ cpu: 1
+ event {
+ timestamp: 110000000
+ pid: 234
+ tcp_retransmit_skb {
+ daddr: 19216801
+ saddr: 127001
+ dport: 5001
+ sport: 56789
+ state: 1
+ skaddr: 77889900
+ }
+ }
+ }
+ }
+ packet {
+ ftrace_events {
+ cpu: 1
+ event {
+ timestamp: 720000000
+ pid: 234
+ tcp_retransmit_skb {
+ daddr: 0
+ saddr: 0
+ dport: 5002
+ sport: 56790
+ state: 2
+ skaddr: 33445566
+ }
+ }
+ }
+ }
+
+ """),
query="""
SELECT
ts,
@@ -159,7 +195,57 @@
def test_kfree_skb(self):
return DiffTestBlueprint(
- trace=Path('kfree_skb.textproto'),
+ trace=TextProto(r"""
+ packet {
+ ftrace_events {
+ cpu: 2
+ event {
+ timestamp: 10000
+ pid: 200
+ kfree_skb {
+ protocol: 2048
+ }
+ }
+ }
+ }
+ packet {
+ ftrace_events {
+ cpu: 2
+ event {
+ timestamp: 10020
+ pid: 300
+ kfree_skb {
+ protocol: 34525
+ }
+ }
+ }
+ }
+ packet {
+ ftrace_events {
+ cpu: 2
+ event {
+ timestamp: 20000
+ pid: 200
+ kfree_skb {
+ protocol: 1536
+ }
+ }
+ }
+ }
+ packet {
+ ftrace_events {
+ cpu: 2
+ event {
+ timestamp: 20020
+ pid: 300
+ kfree_skb {
+ protocol: 2048
+ }
+ }
+ }
+ }
+
+ """),
query="""
SELECT
ts,
diff --git a/test/trace_processor/parsing/tests.py b/test/trace_processor/parsing/tests.py
index b1d4813..1e2b76b 100644
--- a/test/trace_processor/parsing/tests.py
+++ b/test/trace_processor/parsing/tests.py
@@ -20,7 +20,14 @@
class Parsing(TestSuite):
-
+ # Contains tests for parsing events which are applicable to more than one
+ # "area". Generally, events here are of high importance (e.g. sched_switch
+ # tested here is and is used by every embedder of trace processor) Note:
+ # generally *not* advisable to add tests here. Check the guidance provided
+ # http://perfetto/dev/docs/analysis/trace-processor#diff-tests for choosing
+ # folder to add a new test to. TODO(lalitm): some tests here should be moved
+ # of here and into the area folders; they are only here because they predate
+ # modularisation of diff tests. Sched
def test_ts_desc_filter_android_sched_and_ps(self):
return DiffTestBlueprint(
trace=Path('../../data/android_sched_and_ps.pb'),
@@ -46,6 +53,7 @@
81491096076181
"""))
+ # Sched reason
def test_android_sched_and_ps_end_reason_eq(self):
return DiffTestBlueprint(
trace=Path('../../data/android_sched_and_ps.pb'),
@@ -78,12 +86,14 @@
"x",82
"""))
+ # CPU Frequency
def test_cpu_counters_b120487929(self):
return DiffTestBlueprint(
trace=Path('../../data/cpu_counters.pb'),
query=Path('b120487929_test.sql'),
out=Path('cpu_counters_b120487929.out'))
+ # Test the filtering of ftrace events before tracing_start.
def test_ftrace_with_tracing_start_list_sched_slice_spans(self):
return DiffTestBlueprint(
trace=Path('ftrace_with_tracing_start.py'),
@@ -99,6 +109,11 @@
110,-1,2
"""))
+ # Scheduling slices from sched_switch events. There are two tests, one for
+ # typical encoding of sched_switch events, and one for the same trace
+ # in the compact format. The output should be identical apart from the
+ # having one slice fewer for each cpu (the first compact sched_switch event
+ # start a slice). Six slices in this case.
def test_sched_slices_sched_switch_original(self):
return DiffTestBlueprint(
trace=Path('../../data/sched_switch_original.pb'),
@@ -119,6 +134,8 @@
""",
out=Path('sched_slices_sched_switch_compact.out'))
+ # Decoding of sched_waking events from a trace with compact scheduling
+ # Verifies the contents of raw & instants tables.
def test_sched_waking_raw_compact_sched(self):
return DiffTestBlueprint(
trace=Path('../../data/compact_sched.pb'),
@@ -137,6 +154,7 @@
""",
out=Path('sched_waking_instants_compact_sched.out'))
+ # Mm Event
def test_mm_event(self):
return DiffTestBlueprint(
trace=Path('../../data/mm_event.pb'),
@@ -151,6 +169,7 @@
""",
out=Path('mm_event.out'))
+ # Check the systrace conversion code in the raw table. Print events
def test_print_systrace_lmk_userspace(self):
return DiffTestBlueprint(
trace=Path('../../data/lmk_userspace.pb'),
@@ -183,7 +202,55 @@
def test_kernel_dpu_tmw_counter_process_counter_and_track(self):
return DiffTestBlueprint(
- trace=Path('kernel_dpu_tmw_counter.textproto'),
+ trace=TextProto(r"""
+ packet {
+ ftrace_events {
+ cpu: 2
+ event {
+ timestamp: 795572805481
+ pid: 237
+ dpu_tracing_mark_write {
+ pid: 237
+ name: "dpu_vote_clock"
+ type: 67
+ value: 123
+ }
+ }
+ event {
+ timestamp: 795572870504
+ pid: 515
+ dpu_tracing_mark_write {
+ pid: 237
+ name: "dpu_vote_clock"
+ type: 67
+ value: 100
+ }
+ }
+ event {
+ timestamp: 795620516581
+ pid: 237
+ dpu_tracing_mark_write {
+ pid: 237
+ name: "dpu_vote_clock"
+ type: 67
+ value: 125
+ }
+ }
+ event {
+ timestamp: 795620943421
+ pid: 515
+ dpu_tracing_mark_write {
+ pid: 237
+ name: "dpu_vote_clock"
+ type: 67
+ value: 100
+ }
+ }
+ }
+ trusted_uid: 9999
+ trusted_packet_sequence_id: 3
+ }
+ """),
query="""
SELECT ts, pct.name, value, pid
FROM counter c
@@ -199,6 +266,7 @@
795620943421,"dpu_vote_clock",100.000000,237
"""))
+ # Unsigned integers
def test_print_systrace_unsigned(self):
return DiffTestBlueprint(
trace=Path('print_systrace_unsigned.py'),
@@ -208,9 +276,27 @@
""",
out=Path('print_systrace_unsigned.out'))
+ # cgroup_attach_task systrace conversion.
def test_cgroup_attach_task_pre_s_print_systrace(self):
return DiffTestBlueprint(
- trace=Path('cgroup_attach_task_pre_s.textproto'),
+ trace=TextProto(r"""
+ packet {
+ ftrace_events {
+ cpu: 3
+ event {
+ timestamp: 74289018336
+ pid: 1
+ cgroup_attach_task {
+ dst_root: 1
+ dst_id: 2
+ pid: 3
+ comm: "foo"
+ cname: "bar"
+ }
+ }
+ }
+ }
+ """),
query="""
SELECT to_ftrace(id)
FROM raw;
@@ -219,13 +305,32 @@
def test_cgroup_attach_task_post_s_print_systrace(self):
return DiffTestBlueprint(
- trace=Path('cgroup_attach_task_post_s.textproto'),
+ trace=TextProto(r"""
+ packet {
+ ftrace_events {
+ cpu: 3
+ event {
+ timestamp: 74289018336
+ pid: 1
+ cgroup_attach_task {
+ dst_root: 1
+ dst_id: 2
+ pid: 3
+ comm: "foo"
+ dst_level: 4
+ dst_path: "bar"
+ }
+ }
+ }
+ }
+ """),
query="""
SELECT to_ftrace(id)
FROM raw;
""",
out=Path('cgroup_attach_task_post_s_print_systrace.out'))
+ # Parsing systrace files
def test_systrace_html(self):
return DiffTestBlueprint(
trace=Path('../../data/systrace.html'),
@@ -249,6 +354,7 @@
2
"""))
+ # LMK handling
def test_lmk_userspace_lmk(self):
return DiffTestBlueprint(
trace=Path('../../data/lmk_userspace.pb'),
@@ -268,7 +374,34 @@
def test_oom_kill(self):
return DiffTestBlueprint(
- trace=Path('../common/oom_kill.textproto'),
+ trace=TextProto(r"""
+ packet {
+ process_tree {
+ processes {
+ pid: 1000
+ ppid: 1
+ cmdline: "com.google.android.gm"
+ }
+ threads {
+ tid: 1001
+ tgid: 1000
+ }
+ }
+ }
+ packet {
+ ftrace_events {
+ cpu: 4
+ event {
+ timestamp: 1234
+ pid: 4321
+ mark_victim {
+ pid: 1001
+ }
+ }
+ }
+ }
+
+ """),
query="""
SELECT ts, instant.name, process.pid, process.name
FROM instant
@@ -281,6 +414,7 @@
1234,"mem.oom_kill",1000,"com.google.android.gm"
"""))
+ # Logcat
def test_android_log_counts(self):
return DiffTestBlueprint(
trace=Path('../../data/android_log.pb'),
@@ -313,6 +447,7 @@
26
"""))
+ # Oom Score
def test_synth_oom_oom_query(self):
return DiffTestBlueprint(
trace=Path('synth_oom.py'),
@@ -333,6 +468,7 @@
""",
out=Path('process_stats_poll_oom_score.out'))
+ # Stats
def test_android_sched_and_ps_stats(self):
return DiffTestBlueprint(
trace=Path('../../data/android_sched_and_ps.pb'),
@@ -342,6 +478,7 @@
""",
out=Path('android_sched_and_ps_stats.out'))
+ # Syscalls
def test_sys_syscall(self):
return DiffTestBlueprint(
trace=Path('syscall.py'),
@@ -356,6 +493,7 @@
105,5,"sys_io_destroy"
"""))
+ # thread_slice tables.
def test_thread_time_in_thread_slice(self):
return DiffTestBlueprint(
trace=Path('flow_events_json_v2.json'),
@@ -375,9 +513,31 @@
"SomeOtherSliceInstant","[NULL]","[NULL]"
"""))
+ # Initial display state
def test_initial_display_state(self):
return DiffTestBlueprint(
- trace=Path('initial_display_state.textproto'),
+ trace=TextProto(r"""
+ packet: {
+ timestamp: 1
+ initial_display_state: {
+ display_state: 2
+ brightness: 0.5
+ }
+ }
+ packet {
+ ftrace_events {
+ cpu: 0
+ event {
+ timestamp: 1000
+ pid: 1234
+ print {
+ buf: "C|5678|ScreenState|0\n"
+ }
+ }
+ }
+ }
+
+ """),
query="""
SELECT t.name,
c.ts,
@@ -392,9 +552,36 @@
"ScreenState",1000,0.000000
"""))
+ # Config & metadata
def test_config_metadata(self):
return DiffTestBlueprint(
- trace=Path('config_metadata.textproto'),
+ trace=TextProto(r"""
+ packet {
+ clock_snapshot {
+ clocks {
+ clock_id: 6
+ timestamp: 101000002
+ }
+ clocks {
+ clock_id: 128
+ timestamp: 2
+ }
+ }
+ timestamp: 101000002
+ }
+ packet {
+ trace_config {
+ trace_uuid_msb: 1314564453825188563
+ trace_uuid_lsb: -6605018796207623390
+ }
+ }
+ packet {
+ system_info {
+ android_build_fingerprint: "the fingerprint"
+ }
+ }
+
+ """),
query="""
SELECT name, str_value FROM metadata WHERE str_value IS NOT NULL ORDER BY name;
""",
@@ -409,7 +596,25 @@
def test_triggers_packets_trigger_packet_trace(self):
return DiffTestBlueprint(
- trace=Path('trigger_packet_trace.textproto'),
+ trace=TextProto(r"""
+ packet {
+ trigger {
+ trigger_name: "test1"
+ trusted_producer_uid: 3
+ producer_name: "producer1"
+ }
+ timestamp: 101000002
+ }
+ packet {
+ trigger {
+ trigger_name: "test2"
+ trusted_producer_uid: 4
+ producer_name: "producer2"
+ }
+ timestamp: 101000004
+ }
+
+ """),
query=Path('triggers_packets_test.sql'),
out=Csv("""
"ts","name","string_value","int_value"
@@ -419,12 +624,36 @@
def test_chrome_metadata(self):
return DiffTestBlueprint(
- trace=Path('chrome_metadata.textproto'),
+ trace=TextProto(r"""
+ packet {
+ clock_snapshot {
+ clocks {
+ clock_id: 6
+ timestamp: 101000002
+ }
+ }
+ trusted_packet_sequence_id: 1
+ timestamp: 101000002
+ }
+ packet {
+ trusted_packet_sequence_id: 1
+ timestamp: 101000002
+ chrome_metadata {
+ background_tracing_metadata {
+ triggered_rule {}
+ }
+ chrome_version_code: 101
+ enabled_categories: "cat1,cat2,cat3"
+ }
+ }
+
+ """),
query="""
SELECT * FROM metadata;
""",
out=Path('chrome_metadata.out'))
+ # CPU info
def test_cpu(self):
return DiffTestBlueprint(
trace=Path('cpu_info.textproto'),
@@ -460,6 +689,7 @@
""",
out=Path('cpu_freq.out'))
+ # Trace size
def test_android_sched_and_ps_trace_size(self):
return DiffTestBlueprint(
trace=Path('../../data/android_sched_and_ps.pb'),
@@ -471,23 +701,75 @@
18761615
"""))
+ # Package list handling
def test_android_package_list(self):
return DiffTestBlueprint(
trace=Path('android_package_list.py'),
query=Metric('android_package_list'),
out=TextProto(r"""
-android_package_list {
- packages {
- package_name: "com.my.pkg"
- uid: 123
- version_code: 456000
- }
-}
-"""))
+ android_package_list {
+ packages {
+ package_name: "com.my.pkg"
+ uid: 123
+ version_code: 456000
+ }
+ }
+ """))
+ # Ensures process -> package matching works as expected.
def test_process_metadata_matching(self):
return DiffTestBlueprint(
- trace=Path('process_metadata_matching.textproto'),
+ trace=TextProto(r"""
+ packet {
+ process_tree {
+ processes {
+ pid: 1
+ ppid: 0
+ cmdline: "init"
+ uid: 0
+ }
+ processes {
+ pid: 2
+ ppid: 1
+ cmdline: "system_server"
+ uid: 1000
+ }
+ processes {
+ pid: 3
+ ppid: 1
+ cmdline: "com.google.android.gms"
+ uid: 10100
+ }
+ processes {
+ pid: 4
+ ppid: 1
+ cmdline: "com.google.android.gms.persistent"
+ uid: 10100
+ }
+ processes {
+ pid: 5
+ ppid: 1
+ cmdline: "com.google.android.gms"
+ uid: 1010100
+ }
+ }
+ }
+ packet {
+ packages_list {
+ packages {
+ name: "com.google.android.gms"
+ uid: 10100
+ version_code: 1234
+ }
+ packages {
+ name: "com.google.android.gsf"
+ uid: 10100
+ version_code: 1
+ }
+ }
+ }
+
+ """),
query="""
CREATE TABLE TEST_TMP AS
SELECT RUN_METRIC('android/process_metadata.sql');
@@ -507,6 +789,7 @@
5,"com.google.android.gms",10100,1,"com.google.android.gms",1234
"""))
+ # Flow events importing from json
def test_flow_events_json_v1(self):
return DiffTestBlueprint(
trace=Path('flow_events_json_v1.json'),
@@ -538,9 +821,37 @@
"OtherSlice","SomeOtherSlice"
"""))
+ # Importing displayTimeUnit
def test_display_time_unit_slices(self):
return DiffTestBlueprint(
- trace=Path('../../data/display_time_unit.json'),
+ trace=Json(r"""
+ {"displayTimeUnit":"ns","traceEvents":[
+ {
+ "name": "process_name",
+ "pid": 1,
+ "ph": "M",
+ "args": {
+ "name": "api-service-65fc94b8c7-68w9w"
+ }
+ },
+ {
+ "name": "add_graph",
+ "pid": 1,
+ "tid": 1,
+ "ph": "B",
+ "ts": 1597071955492308000
+ },
+ {
+ "name": "add_graph",
+ "pid": 1,
+ "tid": 1,
+ "ph": "E",
+ "ts": 1597071955703771000
+ }
+ ]
+ }
+
+ """),
query="""
SELECT ts, dur, name FROM slice ORDER BY ts DESC;
""",
@@ -549,6 +860,7 @@
-7794778920422990592,211463000000,"add_graph"
"""))
+ # Parsing sched_blocked_reason
def test_sched_blocked_proto_sched_blocked_reason(self):
return DiffTestBlueprint(
trace=Path('sched_blocked_proto.py'),
@@ -581,6 +893,7 @@
21123838000,2172,1
"""))
+ # Kernel symbolization
def test_sched_blocked_reason_symbolized_sched_blocked_reason_function(self):
return DiffTestBlueprint(
trace=Path('sched_blocked_reason_symbolized.textproto'),
@@ -614,9 +927,22 @@
""",
out=Path('sched_blocked_reason_symbolized_to_systrace.out'))
+ # Floating point numbers
def test_decimal_timestamp_slices(self):
return DiffTestBlueprint(
- trace=Path('../../data/decimal_timestamp.json'),
+ trace=Json(r"""
+ {
+ "traceEvents": [{
+ "pid": 1234,
+ "tid": 1234,
+ "ts": 5.1,
+ "dur": 500.1,
+ "name": "name.exec",
+ "ph": "XXX",
+ "cat": "aaa"
+ }]
+ }
+ """),
query="""
SELECT ts, dur, name FROM slice ORDER BY ts DESC;
""",
@@ -625,9 +951,18 @@
5100,500100,"name.exec"
"""))
+ # JSON instants and counters
def test_counters_json_counters(self):
return DiffTestBlueprint(
- trace=Path('../../data/counters.json'),
+ trace=Json(r"""
+
+ [
+ {"pid": "1000", "name": "ctr", "ph": "C", "ts": 0, "args": {"cats": 0}},
+ {"pid": "1000", "name": "ctr", "ph": "C", "ts": 10, "args": {"cats": 10}},
+ {"pid": "1000", "name": "ctr", "ph": "C", "ts": 20, "args": {"cats": 0}}
+ ]
+
+ """),
query="""
SELECT
process_counter_track.name,
@@ -670,17 +1005,19 @@
1239523300,"NoneR",6790,"[NULL]"
"""))
+ # Trace quality metric
def test_very_long_sched_android_trace_quality(self):
return DiffTestBlueprint(
trace=Path('very_long_sched.py'),
query=Metric('android_trace_quality'),
out=TextProto(r"""
-android_trace_quality {
- failures {
- name: "sched_slice_too_long"
- }
-}"""))
+ android_trace_quality {
+ failures {
+ name: "sched_slice_too_long"
+ }
+ }"""))
+ # Regression test for b/193721088 (infra prepending " done\n" to atrace)
def test_sched_smoke_trailing_empty_2(self):
return DiffTestBlueprint(
trace=Path('../../data/atrace_b_193721088.atr'),
@@ -693,17 +1030,19 @@
2
"""))
+ # Multiuser
def test_android_multiuser_switch(self):
return DiffTestBlueprint(
trace=Path('android_multiuser_switch.textproto'),
query=Metric('android_multiuser'),
out=TextProto(r"""
-android_multiuser: {
- user_switch: {
- duration_ms: 4900
- }
-}"""))
+ android_multiuser: {
+ user_switch: {
+ duration_ms: 4900
+ }
+ }"""))
+ # Output of atrace -z.
def test_atrace_compressed_sched_count(self):
return DiffTestBlueprint(
trace=Path('../../data/atrace_compressed.ctrace'),
@@ -716,6 +1055,8 @@
1120
"""))
+ # Output of adb shell "atrace -t 1 sched" > out.txt". It has extra garbage
+ # from stderr before the TRACE: marker. See b/208691037.
def test_atrace_uncompressed_sched_count(self):
return DiffTestBlueprint(
trace=Path('../../data/atrace_uncompressed_b_208691037'),
@@ -733,45 +1074,48 @@
trace=Path('otheruuids.textproto'),
query=Metric('android_other_traces'),
out=TextProto(r"""
-android_other_traces {
- finalized_traces_uuid: "75e4c6d0-d8f6-4f82-fa4b-9e09c5512288"
- finalized_traces_uuid: "ad836701-3113-3fb1-be4f-f7731e23fbbf"
- finalized_traces_uuid: "0de1a010-efa1-a081-2345-969b1186a6ab"
-}
-"""))
+ android_other_traces {
+ finalized_traces_uuid: "75e4c6d0-d8f6-4f82-fa4b-9e09c5512288"
+ finalized_traces_uuid: "ad836701-3113-3fb1-be4f-f7731e23fbbf"
+ finalized_traces_uuid: "0de1a010-efa1-a081-2345-969b1186a6ab"
+ }
+ """))
+ # Per-process Binder transaction metrics
def test_android_binder(self):
return DiffTestBlueprint(
trace=Path('android_binder.py'),
query=Metric('android_binder'),
out=TextProto(r"""
-android_binder {
- process_breakdown {
- process_name: "test_process_a"
- pid: 1
- slice_name: "binder transaction"
- count: 2
- }
- process_breakdown {
- process_name: "test_process_b"
- pid: 2
- slice_name: "binder reply"
- count: 1
- }
- process_breakdown {
- process_name: "test_process_c"
- pid: 3
- slice_name: "binder reply"
- count: 1
- }
-}"""))
+ android_binder {
+ process_breakdown {
+ process_name: "test_process_a"
+ pid: 1
+ slice_name: "binder transaction"
+ count: 2
+ }
+ process_breakdown {
+ process_name: "test_process_b"
+ pid: 2
+ slice_name: "binder reply"
+ count: 1
+ }
+ process_breakdown {
+ process_name: "test_process_c"
+ pid: 3
+ slice_name: "binder reply"
+ count: 1
+ }
+ }"""))
+ # Statsd Atoms
def test_statsd_atoms_all_atoms(self):
return DiffTestBlueprint(
trace=Path('../../data/statsd_atoms.pb'),
query=Path('all_atoms_test.sql'),
out=Path('statsd_atoms_all_atoms.out'))
+ # Kernel function tracing.
def test_funcgraph_trace_funcgraph(self):
return DiffTestBlueprint(
trace=Path('funcgraph_trace.textproto'),
diff --git a/test/trace_processor/parsing/tests_memory_counters.py b/test/trace_processor/parsing/tests_memory_counters.py
index 4b266ce..1aa0bc8 100644
--- a/test/trace_processor/parsing/tests_memory_counters.py
+++ b/test/trace_processor/parsing/tests_memory_counters.py
@@ -114,7 +114,23 @@
def test_ion_stat(self):
return DiffTestBlueprint(
- trace=Path('ion_stat.textproto'),
+ trace=TextProto(r"""
+ packet {
+ ftrace_events {
+ cpu: 4
+ event {
+ timestamp: 1234
+ pid: 4321
+ ion_stat {
+ buffer_id: 101010
+ len: 100
+ total_allocated: 200
+ }
+ }
+ }
+ }
+
+ """),
query="""
SELECT t.name, c.ts, c.value
FROM counter c
diff --git a/test/trace_processor/performance/tests.py b/test/trace_processor/performance/tests.py
index d2effc2..b6a0c1c 100644
--- a/test/trace_processor/performance/tests.py
+++ b/test/trace_processor/performance/tests.py
@@ -20,13 +20,14 @@
class Performance(TestSuite):
-
+ # IRQ max runtime and count over 1ms
def test_irq_runtime_metric(self):
return DiffTestBlueprint(
trace=Path('irq_runtime_metric.textproto'),
query=Metric('android_irq_runtime'),
out=Path('irq_runtime_metric.out'))
+ # CPU frequency maximum & minimum limits change
def test_cpu_frequency_limits(self):
return DiffTestBlueprint(
trace=Path('cpu_frequency_limits.textproto'),
@@ -60,6 +61,7 @@
130000000,800000.000000,"Cpu 4 Min"
"""))
+ # frame_timeline_metric collects App_Deadline_Missed metrics
def test_frame_timeline_metric(self):
return DiffTestBlueprint(
trace=Path('frame_timeline_metric.py'),
diff --git a/test/trace_processor/power/tests.py b/test/trace_processor/power/tests.py
index a51c37d..1884753 100644
--- a/test/trace_processor/power/tests.py
+++ b/test/trace_processor/power/tests.py
@@ -20,7 +20,7 @@
class Power(TestSuite):
-
+ # Power states
def test_cpu_counters_p_state(self):
return DiffTestBlueprint(
trace=Path('../../data/cpu_counters.pb'),
@@ -31,6 +31,7 @@
""",
out=Path('cpu_counters_p_state_test.out'))
+ # CPU power ups
def test_cpu_powerups(self):
return DiffTestBlueprint(
trace=Path('../../data/cpu_powerups_1.pb'),
diff --git a/test/trace_processor/power/tests_energy_breakdown.py b/test/trace_processor/power/tests_energy_breakdown.py
index 667744c..ec11f9a 100644
--- a/test/trace_processor/power/tests_energy_breakdown.py
+++ b/test/trace_processor/power/tests_energy_breakdown.py
@@ -20,7 +20,7 @@
class PowerEnergyBreakdown(TestSuite):
-
+ # Energy Estimation Breakdown
def test_energy_breakdown_table(self):
return DiffTestBlueprint(
trace=Path('energy_breakdown.textproto'),
diff --git a/test/trace_processor/power/tests_power_rails.py b/test/trace_processor/power/tests_power_rails.py
index 7a40acc..fc53b75 100644
--- a/test/trace_processor/power/tests_power_rails.py
+++ b/test/trace_processor/power/tests_power_rails.py
@@ -74,7 +74,53 @@
def test_power_rails_well_known_power_rails(self):
return DiffTestBlueprint(
- trace=Path('power_rails_well_known.textproto'),
+ trace=TextProto(r"""
+ packet {
+ power_rails {
+ rail_descriptor {
+ index: 4
+ rail_name: "S3M_VDD_CPUCL1"
+ subsys_name: "cpu"
+ sampling_rate: 1023
+ }
+ }
+ }
+ packet {
+ timestamp: 3000003
+ power_rails {
+ energy_data {
+ index: 4
+ timestamp_ms: 3
+ energy: 333
+ }
+ }
+ }
+ packet {
+ timestamp: 3000005
+ power_rails {
+ rail_descriptor {
+ index: 3
+ rail_name: "S2S_VDD_G3D"
+ subsys_name: "gpu"
+ sampling_rate: 1022
+ }
+ energy_data {
+ index: 4
+ timestamp_ms: 5
+ energy: 666
+ }
+ energy_data {
+ index: 3
+ energy: 999
+ }
+ energy_data {
+ index: 4
+ timestamp_ms: 3
+ energy: 0
+ }
+ }
+ }
+ """),
query="""
SELECT name, AVG(value), COUNT(*)
FROM counters
diff --git a/test/trace_processor/power/tests_voltage_and_scaling.py b/test/trace_processor/power/tests_voltage_and_scaling.py
index 9ee1c0f..226c4b2 100644
--- a/test/trace_processor/power/tests_voltage_and_scaling.py
+++ b/test/trace_processor/power/tests_voltage_and_scaling.py
@@ -74,17 +74,17 @@
trace=Path('suspend_period.textproto'),
query=Metric('android_batt'),
out=TextProto(r"""
-android_batt {
- battery_aggregates {
- sleep_ns: 20000
- }
- suspend_period {
- timestamp_ns: 30000
- duration_ns: 10000
- }
- suspend_period {
- timestamp_ns: 50000
- duration_ns: 10000
- }
-}
-"""))
+ android_batt {
+ battery_aggregates {
+ sleep_ns: 20000
+ }
+ suspend_period {
+ timestamp_ns: 30000
+ duration_ns: 10000
+ }
+ suspend_period {
+ timestamp_ns: 50000
+ duration_ns: 10000
+ }
+ }
+ """))
diff --git a/test/trace_processor/process_tracking/tests.py b/test/trace_processor/process_tracking/tests.py
index 32fdce9..58dfb20 100644
--- a/test/trace_processor/process_tracking/tests.py
+++ b/test/trace_processor/process_tracking/tests.py
@@ -20,7 +20,7 @@
class ProcessTracking(TestSuite):
-
+ # Tests for the core process and thread tracking logic. Smoke tests
def test_process_tracking(self):
return DiffTestBlueprint(
trace=Path('synth_process_tracking.py'),
@@ -48,6 +48,7 @@
40,40,"process_4","p4-t0"
"""))
+ # Short lived threads/processes
def test_process_tracking_process_tracking_short_lived_1(self):
return DiffTestBlueprint(
trace=Path('process_tracking_short_lived_1.py'),
@@ -80,6 +81,7 @@
11,11,"true_name","true_name"
"""))
+ # Process uid handling
def test_process_tracking_uid(self):
return DiffTestBlueprint(
trace=Path('synth_process_tracking.py'),
@@ -97,6 +99,7 @@
40,"[NULL]"
"""))
+ # Tracking across execs
def test_process_tracking_process_tracking_exec(self):
return DiffTestBlueprint(
trace=Path('process_tracking_exec.py'),
@@ -113,6 +116,7 @@
11,11,"true_process_name","true_name"
"""))
+ # Tracking parent threads
def test_process_parent_pid_process_parent_pid_tracking_1(self):
return DiffTestBlueprint(
trace=Path('process_parent_pid_tracking_1.py'),
@@ -149,6 +153,7 @@
20,10
"""))
+ # Tracking thread reuse
def test_process_tracking_reused_thread_print(self):
return DiffTestBlueprint(
trace=Path('reused_thread_print.py'),
@@ -166,9 +171,35 @@
11,10,"parent","true_name"
"""))
+ # TODO(lalitm): move this out of this folder.
def test_slice_with_pid_sde_tracing_mark_write(self):
return DiffTestBlueprint(
- trace=Path('sde_tracing_mark_write.textproto'),
+ trace=TextProto(r"""
+ packet {
+ ftrace_events {
+ cpu: 0
+ event {
+ timestamp: 100
+ pid: 403
+ sde_tracing_mark_write {
+ pid: 403
+ trace_name: "test_event"
+ trace_begin: 1
+ }
+ }
+ event {
+ timestamp: 101
+ pid: 403
+ sde_tracing_mark_write {
+ pid: 403
+ trace_name: "test_event"
+ trace_begin: 0
+ }
+ }
+ }
+ }
+
+ """),
query="""
SELECT s.name, dur, tid, pid
FROM slice s
@@ -181,6 +212,7 @@
"test_event",1,403,403
"""))
+ # Check that a <...> thread name doesn't overwrite a useful thread name
def test_unknown_thread_name_tracking(self):
return DiffTestBlueprint(
trace=Path('unknown_thread_name.systrace'),
diff --git a/test/trace_processor/profiling/tests.py b/test/trace_processor/profiling/tests.py
index 71fab38..e82fdbf 100644
--- a/test/trace_processor/profiling/tests.py
+++ b/test/trace_processor/profiling/tests.py
@@ -20,10 +20,47 @@
class Profiling(TestSuite):
-
+ # Perf profiling tests.
def test_profiler_smaps(self):
return DiffTestBlueprint(
- trace=Path('profiler_smaps.textproto'),
+ trace=TextProto(r"""
+ packet {
+ process_tree {
+ processes {
+ pid: 1
+ ppid: 0
+ cmdline: "init"
+ uid: 0
+ }
+ processes {
+ pid: 2
+ ppid: 1
+ cmdline: "system_server"
+ uid: 1000
+ }
+ }
+ }
+ packet {
+ trusted_packet_sequence_id: 999
+ timestamp: 10
+ smaps_packet {
+ pid: 2
+ entries {
+ path: "/system/lib64/libc.so"
+ size_kb: 20
+ private_dirty_kb: 4
+ swap_kb: 4
+ }
+ entries {
+ path: "[anon: libc_malloc]"
+ size_kb: 30
+ private_dirty_kb: 10
+ swap_kb: 10
+ }
+ }
+ }
+
+ """),
query="""
SELECT id, type, upid, ts, path, size_kb, private_dirty_kb, swap_kb
FROM profiler_smaps;
@@ -36,31 +73,70 @@
def test_profiler_smaps_metric(self):
return DiffTestBlueprint(
- trace=Path('profiler_smaps.textproto'),
+ trace=TextProto(r"""
+ packet {
+ process_tree {
+ processes {
+ pid: 1
+ ppid: 0
+ cmdline: "init"
+ uid: 0
+ }
+ processes {
+ pid: 2
+ ppid: 1
+ cmdline: "system_server"
+ uid: 1000
+ }
+ }
+ }
+ packet {
+ trusted_packet_sequence_id: 999
+ timestamp: 10
+ smaps_packet {
+ pid: 2
+ entries {
+ path: "/system/lib64/libc.so"
+ size_kb: 20
+ private_dirty_kb: 4
+ swap_kb: 4
+ }
+ entries {
+ path: "[anon: libc_malloc]"
+ size_kb: 30
+ private_dirty_kb: 10
+ swap_kb: 10
+ }
+ }
+ }
+
+ """),
query=Metric('profiler_smaps'),
out=TextProto(r"""
-profiler_smaps {
- instance {
- process {
- name: "system_server"
- uid: 1000
- }
- mappings {
- path: "[anon: libc_malloc]"
- size_kb: 30
- private_dirty_kb: 10
- swap_kb: 10
- }
- mappings {
- path: "/system/lib64/libc.so"
- size_kb: 20
- private_dirty_kb: 4
- swap_kb: 4
- }
- }
-}
-"""))
+ profiler_smaps {
+ instance {
+ process {
+ name: "system_server"
+ uid: 1000
+ }
+ mappings {
+ path: "[anon: libc_malloc]"
+ size_kb: 30
+ private_dirty_kb: 10
+ swap_kb: 10
+ }
+ mappings {
+ path: "/system/lib64/libc.so"
+ size_kb: 20
+ private_dirty_kb: 4
+ swap_kb: 4
+ }
+ }
+ }
+ """))
+ # Regression test for b/222297079: when cumulative size in a flamegraph
+ # a signed 32-bit integer.
def test_heap_graph_flamegraph_matches_objects(self):
return DiffTestBlueprint(
trace=Path('heap_graph_huge_size.textproto'),
@@ -88,6 +164,8 @@
1,10,3000000036,3000000036
"""))
+ # TODO(b/153552977): Stop supporting legacy heap graphs. These never made it
+ # a public release, so we should eventually stop supporting workarounds for
def test_heap_graph_flamegraph(self):
return DiffTestBlueprint(
trace=Path('heap_graph_legacy.textproto'),
@@ -112,7 +190,54 @@
def test_stack_profile_tracker_empty_callstack(self):
return DiffTestBlueprint(
- trace=Path('stack_profile_tracker_empty_callstack.textproto'),
+ trace=TextProto(r"""
+ packet {
+ clock_snapshot {
+ clocks: {
+ clock_id: 6 # BOOTTIME
+ timestamp: 0
+ }
+ clocks: {
+ clock_id: 4 # MONOTONIC_COARSE
+ timestamp: 0
+ }
+ }
+ }
+
+ packet {
+ previous_packet_dropped: true
+ incremental_state_cleared: true
+ trusted_packet_sequence_id: 1
+ timestamp: 0
+ interned_data {
+ callstacks {
+ iid: 1
+ }
+ }
+ }
+
+ packet {
+ trusted_packet_sequence_id: 1
+ timestamp: 0
+ profile_packet {
+ index: 0
+ continued: false
+ process_dumps {
+ samples {
+ callstack_id: 1
+ self_allocated: 1
+ alloc_count: 1
+ }
+ samples {
+ callstack_id: 1
+ self_allocated: 1
+ alloc_count: 1
+ }
+ }
+ }
+ }
+
+ """),
query="""
SELECT count(1) AS count FROM heap_profile_allocation;
""",
@@ -121,6 +246,7 @@
0
"""))
+ # perf_sample table (traced_perf) with android R and S trace inputs.
def test_perf_sample_rvc(self):
return DiffTestBlueprint(
trace=Path('../../data/perf_sample.pb'),
diff --git a/test/trace_processor/profiling/tests_heap_graph.py b/test/trace_processor/profiling/tests_heap_graph.py
index b93605b..6877bb1 100644
--- a/test/trace_processor/profiling/tests_heap_graph.py
+++ b/test/trace_processor/profiling/tests_heap_graph.py
@@ -89,7 +89,54 @@
def test_heap_graph_duplicate_flamegraph(self):
return DiffTestBlueprint(
- trace=Path('heap_graph_duplicate.textproto'),
+ trace=TextProto(r"""
+ packet {
+ process_tree {
+ processes {
+ pid: 2
+ ppid: 1
+ cmdline: "system_server"
+ uid: 1000
+ }
+ }
+ }
+ packet {
+ timestamp: 10
+ process_stats {
+ processes {
+ pid: 2
+ rss_anon_kb: 1000
+ vm_swap_kb: 3000
+ oom_score_adj: 0
+ }
+ }
+ }
+ packet {
+ trusted_packet_sequence_id: 999
+ timestamp: 10
+ heap_graph {
+ pid: 2
+ types {
+ id: 1
+ class_name: "FactoryProducerDelegateImplActor"
+ location_id: 1
+ }
+ roots {
+ root_type: ROOT_JAVA_FRAME
+ object_ids: 0x01
+ object_ids: 0x01
+ }
+ objects {
+ id: 0x01
+ type_id: 1
+ self_size: 64
+ }
+ continued: false
+ index: 0
+ }
+ }
+
+ """),
query="""
SELECT
id,
diff --git a/test/trace_processor/profiling/tests_llvm_symbolizer.py b/test/trace_processor/profiling/tests_llvm_symbolizer.py
index dca2126..bc01454 100644
--- a/test/trace_processor/profiling/tests_llvm_symbolizer.py
+++ b/test/trace_processor/profiling/tests_llvm_symbolizer.py
@@ -20,7 +20,7 @@
class ProfilingLlvmSymbolizer(TestSuite):
-
+ # this uses llvm-symbolizer to test the offline symbolization built into
def test_stack_profile_symbols(self):
return DiffTestBlueprint(
trace=Path('../../data/heapprofd_standalone_client_example-trace'),
diff --git a/test/trace_processor/profiling/tests_metrics.py b/test/trace_processor/profiling/tests_metrics.py
index 166b936..c4456e6 100644
--- a/test/trace_processor/profiling/tests_metrics.py
+++ b/test/trace_processor/profiling/tests_metrics.py
@@ -26,33 +26,33 @@
trace=Path('heap_profile_no_symbols.textproto'),
query=Metric('unsymbolized_frames'),
out=TextProto(r"""
-unsymbolized_frames {
- frames {
- module: "/liblib.so"
- build_id: "6275696c642d6964"
- address: 4096
- google_lookup_id: "6275696c642d6964"
- }
- frames {
- module: "/liblib.so"
- build_id: "6275696c642d6964"
- address: 8192
- google_lookup_id: "6275696c642d6964"
- }
- frames {
- module: "/libmonochrome_64.so"
- build_id: "7f0715c286f8b16c10e4ad349cda3b9b56c7a773"
- address: 4096
- google_lookup_id: "c215077ff8866cb110e4ad349cda3b9b0"
- }
- frames {
- module: "/libmonochrome_64.so"
- build_id: "7f0715c286f8b16c10e4ad349cda3b9b56c7a773"
- address: 8192
- google_lookup_id: "c215077ff8866cb110e4ad349cda3b9b0"
- }
-}
-"""))
+ unsymbolized_frames {
+ frames {
+ module: "/liblib.so"
+ build_id: "6275696c642d6964"
+ address: 4096
+ google_lookup_id: "6275696c642d6964"
+ }
+ frames {
+ module: "/liblib.so"
+ build_id: "6275696c642d6964"
+ address: 8192
+ google_lookup_id: "6275696c642d6964"
+ }
+ frames {
+ module: "/libmonochrome_64.so"
+ build_id: "7f0715c286f8b16c10e4ad349cda3b9b56c7a773"
+ address: 4096
+ google_lookup_id: "c215077ff8866cb110e4ad349cda3b9b0"
+ }
+ frames {
+ module: "/libmonochrome_64.so"
+ build_id: "7f0715c286f8b16c10e4ad349cda3b9b56c7a773"
+ address: 8192
+ google_lookup_id: "c215077ff8866cb110e4ad349cda3b9b0"
+ }
+ }
+ """))
def test_simpleperf_event(self):
return DiffTestBlueprint(
@@ -65,36 +65,36 @@
trace=Path('heap_graph.textproto'),
query=Metric('java_heap_stats'),
out=TextProto(r"""
-java_heap_stats {
- instance_stats {
- upid: 2
- process {
- name: "system_server"
- uid: 1000
- }
- samples {
- ts: 10
- heap_size: 1760
- heap_native_size: 0
- reachable_heap_size: 352
- reachable_heap_native_size: 0
- obj_count: 6
- reachable_obj_count: 3
- anon_rss_and_swap_size: 4096000
- roots {
- root_type: "ROOT_JAVA_FRAME"
- type_name: "DeobfuscatedA[]"
- obj_count: 1
- }
- roots {
- root_type: "ROOT_JAVA_FRAME"
- type_name: "FactoryProducerDelegateImplActor"
- obj_count: 1
- }
- }
- }
-}
-"""))
+ java_heap_stats {
+ instance_stats {
+ upid: 2
+ process {
+ name: "system_server"
+ uid: 1000
+ }
+ samples {
+ ts: 10
+ heap_size: 1760
+ heap_native_size: 0
+ reachable_heap_size: 352
+ reachable_heap_native_size: 0
+ obj_count: 6
+ reachable_obj_count: 3
+ anon_rss_and_swap_size: 4096000
+ roots {
+ root_type: "ROOT_JAVA_FRAME"
+ type_name: "DeobfuscatedA[]"
+ obj_count: 1
+ }
+ roots {
+ root_type: "ROOT_JAVA_FRAME"
+ type_name: "FactoryProducerDelegateImplActor"
+ obj_count: 1
+ }
+ }
+ }
+ }
+ """))
def test_heap_stats_closest_proc(self):
return DiffTestBlueprint(
diff --git a/test/trace_processor/scheduler/tests.py b/test/trace_processor/scheduler/tests.py
index 330a49e..b55e607 100644
--- a/test/trace_processor/scheduler/tests.py
+++ b/test/trace_processor/scheduler/tests.py
@@ -20,7 +20,7 @@
class Scheduler(TestSuite):
-
+ # Scheduler
def test_sched_cpu_util_cfs(self):
return DiffTestBlueprint(
trace=Path('sched_cpu_util_cfs.textproto'),
diff --git a/test/trace_processor/smoke/tests.py b/test/trace_processor/smoke/tests.py
index 448f66a..9b3f2e8 100644
--- a/test/trace_processor/smoke/tests.py
+++ b/test/trace_processor/smoke/tests.py
@@ -20,7 +20,9 @@
class Smoke(TestSuite):
-
+ # Contains smoke tests which test the most fundamentally important features
+ # trace processor Note: new tests here should only be added by the Perfetto
+ # Compresesed traces
def test_compressed_smoke(self):
return DiffTestBlueprint(
trace=Path('../../data/compressed.pb'),
diff --git a/test/trace_processor/smoke/tests_compute_metrics.py b/test/trace_processor/smoke/tests_compute_metrics.py
index 3e258d1..c07c3a0 100644
--- a/test/trace_processor/smoke/tests_compute_metrics.py
+++ b/test/trace_processor/smoke/tests_compute_metrics.py
@@ -20,7 +20,9 @@
class SmokeComputeMetrics(TestSuite):
-
+ # Contains smoke tests which test the most fundamentally important features
+ # trace processor Note: new tests here should only be added by the Perfetto
+ # Compute CPU time metric testing several core tables.
def test_thread_cpu_time_example_android_trace_30s(self):
return DiffTestBlueprint(
trace=Path('../../data/example_android_trace_30s.pb'),
@@ -45,6 +47,7 @@
""",
out=Path('thread_cpu_time_example_android_trace_30s.out'))
+ # Compute power proxy metric
def test_proxy_power(self):
return DiffTestBlueprint(
trace=Path('../../data/cpu_counters.pb'),
diff --git a/test/trace_processor/smoke/tests_json.py b/test/trace_processor/smoke/tests_json.py
index 86af489..01ca11b 100644
--- a/test/trace_processor/smoke/tests_json.py
+++ b/test/trace_processor/smoke/tests_json.py
@@ -20,7 +20,9 @@
class SmokeJson(TestSuite):
-
+ # Contains smoke tests which test the most fundamentally important features
+ # trace processor Note: new tests here should only be added by the Perfetto
+ # JSON trace parsing
def test_sfgate_smoke(self):
return DiffTestBlueprint(
trace=Path('../../data/sfgate.json'),
diff --git a/test/trace_processor/smoke/tests_sched_events.py b/test/trace_processor/smoke/tests_sched_events.py
index 8141aa9..04f588a 100644
--- a/test/trace_processor/smoke/tests_sched_events.py
+++ b/test/trace_processor/smoke/tests_sched_events.py
@@ -20,7 +20,9 @@
class SmokeSchedEvents(TestSuite):
-
+ # Contains smoke tests which test the most fundamentally important features
+ # trace processor Note: new tests here should only be added by the Perfetto
+ # Sched events
def test_android_sched_and_ps_smoke(self):
return DiffTestBlueprint(
trace=Path('../../data/android_sched_and_ps.pb'),
@@ -51,6 +53,7 @@
81473010352792,2,32917,"S",120,26208
"""))
+ # Sched events from sythetic trace
def test_synth_1_smoke(self):
return DiffTestBlueprint(
trace=Path('../common/synth_1.py'),
diff --git a/test/trace_processor/startup/tests.py b/test/trace_processor/startup/tests.py
index 80a281f..af0d184 100644
--- a/test/trace_processor/startup/tests.py
+++ b/test/trace_processor/startup/tests.py
@@ -20,7 +20,8 @@
class Startup(TestSuite):
-
+ # Contains tests related to the startup of Android apps. Test that
+ # running in parallel are flagged.
def test_android_startup_installd_dex2oat(self):
return DiffTestBlueprint(
trace=Path('android_startup_installd_dex2oat.py'),
@@ -33,6 +34,7 @@
query=Metric('android_startup'),
out=Path('android_startup_installd_dex2oat_slow.out'))
+ # Test that unlocks running in parallel are flagged.
def test_android_startup_unlock(self):
return DiffTestBlueprint(
trace=Path('android_startup_unlock.py'),
diff --git a/test/trace_processor/startup/tests_broadcasts.py b/test/trace_processor/startup/tests_broadcasts.py
index bee39be..16dd96b 100644
--- a/test/trace_processor/startup/tests_broadcasts.py
+++ b/test/trace_processor/startup/tests_broadcasts.py
@@ -20,7 +20,7 @@
class StartupBroadcasts(TestSuite):
-
+ # Test that broadcasts are correctly counted.
def test_android_startup_broadcast(self):
return DiffTestBlueprint(
trace=Path('android_startup_broadcast.py'),
diff --git a/test/trace_processor/startup/tests_lock_contention.py b/test/trace_processor/startup/tests_lock_contention.py
index 80b6184..a3e3cd0 100644
--- a/test/trace_processor/startup/tests_lock_contention.py
+++ b/test/trace_processor/startup/tests_lock_contention.py
@@ -20,7 +20,7 @@
class StartupLockContention(TestSuite):
-
+ # Test lock contention is correctly attributed.
def test_android_startup_lock_contention(self):
return DiffTestBlueprint(
trace=Path('android_startup_lock_contention.py'),
diff --git a/test/trace_processor/startup/tests_metrics.py b/test/trace_processor/startup/tests_metrics.py
index 4460815..ae011dd 100644
--- a/test/trace_processor/startup/tests_metrics.py
+++ b/test/trace_processor/startup/tests_metrics.py
@@ -69,40 +69,41 @@
query=Metric('android_startup'),
out=Path('android_startup_attribution_slow.out'))
+ # Other metrics associated with startup.
def test_android_batt_counters(self):
return DiffTestBlueprint(
trace=Path('android_startup_battery.py'),
query=Metric('android_batt'),
out=TextProto(r"""
-android_batt{
- battery_counters{
- timestamp_ns: 20
- charge_counter_uah: 52
- capacity_percent: 0.2
- current_ua: 10
- current_avg_ua: 12
- }
- battery_counters {
- timestamp_ns: 52
- charge_counter_uah: 32
- capacity_percent: 0.8
- current_ua: 8
- current_avg_ua: 93
- }
- battery_counters {
- timestamp_ns: 80
- charge_counter_uah: 15
- capacity_percent: 0.5
- current_ua: 9
- current_avg_ua: 5
- }
- battery_counters {
- timestamp_ns: 92
- charge_counter_uah: 21
- capacity_percent: 0.3
- current_avg_ua: 25
- }
-}"""))
+ android_batt{
+ battery_counters{
+ timestamp_ns: 20
+ charge_counter_uah: 52
+ capacity_percent: 0.2
+ current_ua: 10
+ current_avg_ua: 12
+ }
+ battery_counters {
+ timestamp_ns: 52
+ charge_counter_uah: 32
+ capacity_percent: 0.8
+ current_ua: 8
+ current_avg_ua: 93
+ }
+ battery_counters {
+ timestamp_ns: 80
+ charge_counter_uah: 15
+ capacity_percent: 0.5
+ current_ua: 9
+ current_avg_ua: 5
+ }
+ battery_counters {
+ timestamp_ns: 92
+ charge_counter_uah: 21
+ capacity_percent: 0.3
+ current_avg_ua: 25
+ }
+ }"""))
def test_android_startup_cpu(self):
return DiffTestBlueprint(
diff --git a/test/trace_processor/tables/tests.py b/test/trace_processor/tables/tests.py
index 6917330..8928446 100644
--- a/test/trace_processor/tables/tests.py
+++ b/test/trace_processor/tables/tests.py
@@ -20,7 +20,11 @@
class Tables(TestSuite):
-
+ # Contains tests for the handling of tables by trace processor. The focus of
+ # here is to check that trace processor is correctly returning and handling
+ # on the really important tables in trace processor. Note: It's generally
+ # advisable to add tests here. Check the guidance provided by
+ # for choosing which folder to add a new test to. Window table
def test_android_sched_and_ps_smoke_window(self):
return DiffTestBlueprint(
trace=Path('../../data/android_sched_and_ps.pb'),
@@ -32,6 +36,7 @@
0,9223372036854775807,0
"""))
+ # Null printing
def test_nulls(self):
return DiffTestBlueprint(
trace=Path('../common/synth_1.py'),
@@ -66,9 +71,59 @@
""",
out=Path('nulls.out'))
+ # Thread table
def test_thread_main_thread(self):
return DiffTestBlueprint(
- trace=Path('thread_main_thread.textproto'),
+ trace=TextProto(r"""
+ packet {
+ timestamp: 1
+ process_tree {
+ processes {
+ pid: 5
+ ppid: 1
+ cmdline: "com.google.pid5"
+ }
+ threads {
+ tid: 5
+ tgid: 5
+ }
+ threads {
+ tid: 7
+ tgid: 5
+ name: "tid7"
+ }
+ processes {
+ pid: 11
+ ppid: 1
+ cmdline: "com.google.pid11"
+ }
+ threads {
+ tid: 11
+ tgid: 11
+ name: "tid11"
+ }
+ threads {
+ tid: 12
+ tgid: 11
+ name: "tid12"
+ }
+ }
+ }
+ packet {
+ timestamp: 2
+ ftrace_events {
+ cpu: 0
+ event {
+ timestamp: 2
+ pid: 99
+ lowmemory_kill {
+ pid: 99
+ }
+ }
+ }
+ }
+
+ """),
query="""
SELECT
tid,
@@ -86,32 +141,61 @@
99,"[NULL]"
"""))
+ # Json output
def test_trace_metadata(self):
return DiffTestBlueprint(
trace=Path('../../data/memory_counters.pb'),
query=Metric('trace_metadata'),
out=Path('trace_metadata.json.out'))
+ # Processes as a metric
def test_android_task_names(self):
return DiffTestBlueprint(
- trace=Path('process_uids.textproto'),
+ trace=TextProto(r"""
+ packet {
+ process_tree {
+ processes {
+ pid: 1
+ ppid: 0
+ cmdline: "init"
+ uid: 0
+ }
+ processes {
+ pid: 2
+ ppid: 1
+ cmdline: "com.google.android.gm:process"
+ uid: 10001
+ }
+ }
+ }
+ packet {
+ packages_list {
+ packages {
+ name: "com.google.android.gm"
+ uid: 10001
+ }
+ }
+ }
+
+ """),
query=Metric('android_task_names'),
out=TextProto(r"""
-android_task_names {
- process {
- pid: 1
- process_name: "init"
- uid: 0
- }
- process {
- pid: 2
- process_name: "com.google.android.gm:process"
- uid: 10001
- uid_package_name: "com.google.android.gm"
- }
-}
-"""))
+ android_task_names {
+ process {
+ pid: 1
+ process_name: "init"
+ uid: 0
+ }
+ process {
+ pid: 2
+ process_name: "com.google.android.gm:process"
+ uid: 10001
+ uid_package_name: "com.google.android.gm"
+ }
+ }
+ """))
+ # Ftrace stats imports in metadata and stats tables
def test_ftrace_setup_errors(self):
return DiffTestBlueprint(
trace=Path('../../data/ftrace_error_stats.pftrace'),
diff --git a/test/trace_processor/tables/tests_counters.py b/test/trace_processor/tables/tests_counters.py
index e9bd0e6..c011a92 100644
--- a/test/trace_processor/tables/tests_counters.py
+++ b/test/trace_processor/tables/tests_counters.py
@@ -20,7 +20,7 @@
class TablesCounters(TestSuite):
-
+ # Counters table
def test_synth_1_filter_counter(self):
return DiffTestBlueprint(
trace=Path('../common/synth_1.py'),
diff --git a/test/trace_processor/tables/tests_sched.py b/test/trace_processor/tables/tests_sched.py
index 2c29b81..98af57a 100644
--- a/test/trace_processor/tables/tests_sched.py
+++ b/test/trace_processor/tables/tests_sched.py
@@ -20,7 +20,7 @@
class TablesSched(TestSuite):
-
+ # Sched table
def test_synth_1_filter_sched(self):
return DiffTestBlueprint(
trace=Path('../common/synth_1.py'),
diff --git a/test/trace_processor/track_event/tests.py b/test/trace_processor/track_event/tests.py
index 2ef0b56..3ee3cf9 100644
--- a/test/trace_processor/track_event/tests.py
+++ b/test/trace_processor/track_event/tests.py
@@ -20,10 +20,58 @@
class TrackEvent(TestSuite):
-
+ # Contains tests on the parsing and ingestion of TrackEvent packets. Same
+ # handling
def test_track_event_same_tids_threads(self):
return DiffTestBlueprint(
- trace=Path('track_event_same_tids.textproto'),
+ trace=TextProto(r"""
+ packet {
+ trusted_packet_sequence_id: 1
+ timestamp: 0
+ incremental_state_cleared: true
+ track_descriptor {
+ uuid: 1
+ thread {
+ pid: 5
+ tid: 1
+ thread_name: "t1"
+ }
+ }
+ }
+ packet {
+ trusted_packet_sequence_id: 1
+ timestamp: 0
+ track_descriptor {
+ uuid: 2
+ thread {
+ pid: 10
+ tid: 1
+ thread_name: "t2"
+ }
+ }
+ }
+ packet {
+ trusted_packet_sequence_id: 1
+ timestamp: 1000
+ track_event {
+ track_uuid: 1
+ categories: "cat"
+ name: "name1"
+ type: 3
+ }
+ }
+ packet {
+ trusted_packet_sequence_id: 1
+ timestamp: 2000
+ track_event {
+ track_uuid: 2
+ categories: "cat"
+ name: "name2"
+ type: 3
+ }
+ }
+
+ """),
query="""
SELECT tid, pid, process.name AS pname, thread.name AS tname
FROM thread
@@ -41,7 +89,54 @@
def test_track_event_same_tids_slices(self):
return DiffTestBlueprint(
- trace=Path('track_event_same_tids.textproto'),
+ trace=TextProto(r"""
+ packet {
+ trusted_packet_sequence_id: 1
+ timestamp: 0
+ incremental_state_cleared: true
+ track_descriptor {
+ uuid: 1
+ thread {
+ pid: 5
+ tid: 1
+ thread_name: "t1"
+ }
+ }
+ }
+ packet {
+ trusted_packet_sequence_id: 1
+ timestamp: 0
+ track_descriptor {
+ uuid: 2
+ thread {
+ pid: 10
+ tid: 1
+ thread_name: "t2"
+ }
+ }
+ }
+ packet {
+ trusted_packet_sequence_id: 1
+ timestamp: 1000
+ track_event {
+ track_uuid: 1
+ categories: "cat"
+ name: "name1"
+ type: 3
+ }
+ }
+ packet {
+ trusted_packet_sequence_id: 1
+ timestamp: 2000
+ track_event {
+ track_uuid: 2
+ categories: "cat"
+ name: "name2"
+ type: 3
+ }
+ }
+
+ """),
query="""
SELECT
track.name AS track,
@@ -67,6 +162,7 @@
"[NULL]","[NULL]","t2","[NULL]",2000,0,"cat","name2"
"""))
+ # Typed args
def test_track_event_typed_args_slices(self):
return DiffTestBlueprint(
trace=Path('track_event_typed_args.textproto'),
@@ -105,6 +201,7 @@
query=Path('track_event_args_test.sql'),
out=Path('track_event_typed_args_args.out'))
+ # Track handling
def test_track_event_tracks_slices(self):
return DiffTestBlueprint(
trace=Path('track_event_tracks.textproto'),
@@ -191,9 +288,61 @@
"tid=1","[NULL]","[NULL]"
"""))
+ # Instant events
def test_track_event_instant_slices(self):
return DiffTestBlueprint(
- trace=Path('track_event_instant.textproto'),
+ trace=TextProto(r"""
+ packet {
+ trusted_packet_sequence_id: 1
+ timestamp: 0
+ incremental_state_cleared: true
+ track_descriptor {
+ uuid: 1
+ thread {
+ pid: 5
+ tid: 1
+ thread_name: "t1"
+ }
+ }
+ trace_packet_defaults {
+ track_event_defaults {
+ track_uuid: 1
+ }
+ }
+ }
+ packet {
+ trusted_packet_sequence_id: 1
+ timestamp: 1000
+ track_event {
+ categories: "cat"
+ name: "instant_on_t1"
+ type: 3
+ }
+ }
+ packet {
+ trusted_packet_sequence_id: 1
+ timestamp: 2000
+ track_event {
+ categories: "cat"
+ name: "legacy_instant_on_t1"
+ legacy_event {
+ phase: 73 # 'I'
+ }
+ }
+ }
+ packet {
+ trusted_packet_sequence_id: 1
+ timestamp: 3000
+ track_event {
+ categories: "cat"
+ name: "legacy_mark_on_t1"
+ legacy_event {
+ phase: 82 # 'R'
+ }
+ }
+ }
+
+ """),
query="""
SELECT
track.name AS track,
@@ -220,6 +369,7 @@
"[NULL]","[NULL]","t1","[NULL]",3000,0,"cat","legacy_mark_on_t1"
"""))
+ # Legacy async events
def test_legacy_async_event(self):
return DiffTestBlueprint(
trace=Path('legacy_async_event.textproto'),
@@ -248,6 +398,7 @@
""",
out=Path('legacy_async_event.out'))
+ # Legacy atrace
def test_track_event_with_atrace(self):
return DiffTestBlueprint(
trace=Path('track_event_with_atrace.textproto'),
@@ -277,12 +428,14 @@
"[NULL]","[NULL]","t1","[NULL]",21000,7000,"[NULL]","atrace"
"""))
+ # Debug annotations
def test_track_event_merged_debug_annotations_args(self):
return DiffTestBlueprint(
trace=Path('track_event_merged_debug_annotations.textproto'),
query=Path('track_event_args_test.sql'),
out=Path('track_event_merged_debug_annotations_args.out'))
+ # Counters
def test_track_event_counters_slices(self):
return DiffTestBlueprint(
trace=Path('track_event_counters.textproto'),
@@ -339,9 +492,48 @@
""",
out=Path('track_event_counters_counters.out'))
+ # Clock handling
def test_track_event_monotonic_trace_clock_slices(self):
return DiffTestBlueprint(
- trace=Path('track_event_monotonic_trace_clock.textproto'),
+ trace=TextProto(r"""
+ packet {
+ trusted_packet_sequence_id: 1
+ timestamp: 0
+ clock_snapshot {
+ primary_trace_clock: 3 # BUILTIN_CLOCK_MONOTONIC
+ clocks {
+ clock_id: 3 # BUILTIN_CLOCK_MONOTONIC
+ timestamp: 1000
+ }
+ clocks {
+ clock_id: 6 # BUILTIN_CLOCK_BOOTTIME
+ timestamp: 11000
+ }
+ }
+ }
+ packet {
+ trusted_packet_sequence_id: 1
+ timestamp: 1000
+ timestamp_clock_id: 3 # BUILTIN_CLOCK_MONOTONIC
+ track_event {
+ track_uuid: 1
+ categories: "cat"
+ name: "name1"
+ type: 3
+ }
+ }
+ packet {
+ trusted_packet_sequence_id: 1
+ timestamp: 12000
+ timestamp_clock_id: 6 # BUILTIN_CLOCK_BOOTTIME
+ track_event {
+ track_uuid: 1
+ categories: "cat"
+ name: "name2"
+ type: 3
+ }
+ }
+ """),
query="""
SELECT
track.name AS track,
@@ -367,12 +559,14 @@
"name1","[NULL]","[NULL]","[NULL]",2000,0,"cat","name2"
"""))
+ # HistogramName interning
def test_track_event_chrome_histogram_sample_args(self):
return DiffTestBlueprint(
trace=Path('track_event_chrome_histogram_sample.textproto'),
query=Path('track_event_args_test.sql'),
out=Path('track_event_chrome_histogram_sample_args.out'))
+ # Flow events importing from proto
def test_flow_events_track_event(self):
return DiffTestBlueprint(
trace=Path('flow_events_track_event.textproto'),
@@ -422,6 +616,7 @@
"FlowStepSlice","FlowEndSlice_2"
"""))
+ # Async slices starting and ending at the same time
def test_experimental_slice_layout_depth(self):
return DiffTestBlueprint(
trace=Path('experimental_slice_layout_depth.py'),
@@ -436,6 +631,7 @@
0
"""))
+ # Descriptor merging regression test (bug: b/197203390)
def test_merging_regression(self):
return DiffTestBlueprint(
trace=Path('../../data/trace_with_descriptor.pftrace'),
@@ -456,6 +652,7 @@
605361035040000
"""))
+ # Range of interest
def test_range_of_interest(self):
return DiffTestBlueprint(
trace=Path('range_of_interest.textproto'),
diff --git a/test/trace_processor/translation/tests.py b/test/trace_processor/translation/tests.py
index 0f6a704..ac062be 100644
--- a/test/trace_processor/translation/tests.py
+++ b/test/trace_processor/translation/tests.py
@@ -41,7 +41,56 @@
def test_chrome_performance_mark(self):
return DiffTestBlueprint(
- trace=Path('chrome_performance_mark.textproto'),
+ trace=TextProto(r"""
+ packet {
+ translation_table {
+ chrome_performance_mark {
+ site_hash_to_name { key: 10 value: "site1" }
+ mark_hash_to_name { key: 20 value: "mark2" }
+ }
+ }
+ }
+ packet {
+ timestamp: 0
+ trusted_packet_sequence_id: 1
+ track_descriptor {
+ uuid: 12345
+ thread {
+ pid: 123
+ tid: 345
+ }
+ parent_uuid: 0
+ chrome_thread {
+ thread_type: THREAD_POOL_FG_WORKER
+ }
+ }
+ }
+ packet {
+ trusted_packet_sequence_id: 1
+ timestamp: 1
+ track_event {
+ categories: "cat1"
+ track_uuid: 12345
+ type: 1
+ name: "slice1"
+ [perfetto.protos.ChromeTrackEvent.chrome_hashed_performance_mark] {
+ site_hash: 10
+ mark_hash: 20
+ }
+ }
+ }
+ packet {
+ trusted_packet_sequence_id: 1
+ timestamp: 6000
+ track_event {
+ track_uuid: 12345
+ categories: "cat1"
+ name: "slice1"
+ type: 2
+ }
+ }
+
+ """),
query=Path('chrome_args_test.sql'),
out=Path('chrome_performance_mark.out'))
diff --git a/test/trace_processor/ufs/tests.py b/test/trace_processor/ufs/tests.py
index 892ffd1..0e79732 100644
--- a/test/trace_processor/ufs/tests.py
+++ b/test/trace_processor/ufs/tests.py
@@ -20,7 +20,7 @@
class Ufs(TestSuite):
-
+ # UFS command
def test_ufshcd_command(self):
return DiffTestBlueprint(
trace=Path('ufshcd_command.textproto'),
diff --git a/tools/diff_test_trace_processor.py b/tools/diff_test_trace_processor.py
index e9e7f31..e505258 100755
--- a/tools/diff_test_trace_processor.py
+++ b/tools/diff_test_trace_processor.py
@@ -41,15 +41,10 @@
parser.add_argument('--metrics-descriptor', type=str)
parser.add_argument('--perf-file', type=str)
parser.add_argument(
- '--query-metric-filter',
+ '--name-filter',
default='.*',
type=str,
- help='Filter the name of query files or metrics to test (regex syntax)')
- parser.add_argument(
- '--trace-filter',
- default='.*',
- type=str,
- help='Filter the name of trace files to test (regex syntax)')
+ help='Filter the name of the tests to run (regex syntax)')
parser.add_argument(
'--keep-input',
action='store_true',
@@ -64,9 +59,8 @@
'trace_processor', type=str, help='location of trace processor binary')
args = parser.parse_args()
- test_runner = DiffTestsRunner(args.query_metric_filter, args.trace_filter,
- args.trace_processor, args.trace_descriptor,
- args.no_colors)
+ test_runner = DiffTestsRunner(args.name_filter, args.trace_processor,
+ args.trace_descriptor, args.no_colors)
sys.stderr.write(f"[==========] Running {len(test_runner.tests)} tests.\n")
results = test_runner.run_all_tests(args.metrics_descriptor, args.keep_input,