xref: /aosp_15_r20/system/extras/simpleperf/scripts/test/stackcollapse_test.py (revision 288bf5226967eb3dac5cce6c939ccc2a7f2b4fe5)
1*288bf522SAndroid Build Coastguard Worker#!/usr/bin/env python3
2*288bf522SAndroid Build Coastguard Worker#
3*288bf522SAndroid Build Coastguard Worker# Copyright (C) 2021 The Android Open Source Project
4*288bf522SAndroid Build Coastguard Worker#
5*288bf522SAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License");
6*288bf522SAndroid Build Coastguard Worker# you may not use this file except in compliance with the License.
7*288bf522SAndroid Build Coastguard Worker# You may obtain a copy of the License at
8*288bf522SAndroid Build Coastguard Worker#
9*288bf522SAndroid Build Coastguard Worker#      http://www.apache.org/licenses/LICENSE-2.0
10*288bf522SAndroid Build Coastguard Worker#
11*288bf522SAndroid Build Coastguard Worker# Unless required by applicable law or agreed to in writing, software
12*288bf522SAndroid Build Coastguard Worker# distributed under the License is distributed on an "AS IS" BASIS,
13*288bf522SAndroid Build Coastguard Worker# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14*288bf522SAndroid Build Coastguard Worker# See the License for the specific language governing permissions and
15*288bf522SAndroid Build Coastguard Worker# limitations under the License.
16*288bf522SAndroid Build Coastguard Worker
17*288bf522SAndroid Build Coastguard Workerimport json
18*288bf522SAndroid Build Coastguard Workerimport os
19*288bf522SAndroid Build Coastguard Workerfrom pathlib import Path
20*288bf522SAndroid Build Coastguard Workerimport re
21*288bf522SAndroid Build Coastguard Workerimport tempfile
22*288bf522SAndroid Build Coastguard Workerfrom typing import List, Optional, Set
23*288bf522SAndroid Build Coastguard Worker
24*288bf522SAndroid Build Coastguard Workerfrom . test_utils import TestBase, TestHelper
25*288bf522SAndroid Build Coastguard Worker
26*288bf522SAndroid Build Coastguard Worker
27*288bf522SAndroid Build Coastguard Workerclass TestStackCollapse(TestBase):
28*288bf522SAndroid Build Coastguard Worker    def get_report(self, testdata_file: str, options: Optional[List[str]] = None) -> str:
29*288bf522SAndroid Build Coastguard Worker        args = ['stackcollapse.py', '-i', TestHelper.testdata_path(testdata_file)]
30*288bf522SAndroid Build Coastguard Worker        if options:
31*288bf522SAndroid Build Coastguard Worker            args.extend(options)
32*288bf522SAndroid Build Coastguard Worker        report = self.run_cmd(args, return_output=True)
33*288bf522SAndroid Build Coastguard Worker        return report.replace('\r', '')
34*288bf522SAndroid Build Coastguard Worker
35*288bf522SAndroid Build Coastguard Worker    def test_jit_annotations(self):
36*288bf522SAndroid Build Coastguard Worker        got = self.get_report('perf_with_jit_symbol.data', ['--jit'])
37*288bf522SAndroid Build Coastguard Worker        golden_path = TestHelper.testdata_path('perf_with_jit_symbol.foldedstack')
38*288bf522SAndroid Build Coastguard Worker        self.assertEqual(got, Path(golden_path).read_text())
39*288bf522SAndroid Build Coastguard Worker
40*288bf522SAndroid Build Coastguard Worker    def test_kernel_annotations(self):
41*288bf522SAndroid Build Coastguard Worker        got = self.get_report('perf_with_jit_symbol.data', ['--kernel'])
42*288bf522SAndroid Build Coastguard Worker        golden_path = TestHelper.testdata_path('perf_with_jit_symbol.foldedstack_with_kernel')
43*288bf522SAndroid Build Coastguard Worker        self.assertEqual(got, Path(golden_path).read_text())
44*288bf522SAndroid Build Coastguard Worker
45*288bf522SAndroid Build Coastguard Worker    def test_with_pid(self):
46*288bf522SAndroid Build Coastguard Worker        got = self.get_report('perf_with_jit_symbol.data', ['--jit', '--pid'])
47*288bf522SAndroid Build Coastguard Worker        golden_path = TestHelper.testdata_path('perf_with_jit_symbol.foldedstack_with_pid')
48*288bf522SAndroid Build Coastguard Worker        self.assertEqual(got, Path(golden_path).read_text())
49*288bf522SAndroid Build Coastguard Worker
50*288bf522SAndroid Build Coastguard Worker    def test_with_tid(self):
51*288bf522SAndroid Build Coastguard Worker        got = self.get_report('perf_with_jit_symbol.data', ['--jit', '--tid'])
52*288bf522SAndroid Build Coastguard Worker        golden_path = TestHelper.testdata_path('perf_with_jit_symbol.foldedstack_with_tid')
53*288bf522SAndroid Build Coastguard Worker        self.assertEqual(got, Path(golden_path).read_text())
54*288bf522SAndroid Build Coastguard Worker
55*288bf522SAndroid Build Coastguard Worker    def test_two_event_types_chooses_first(self):
56*288bf522SAndroid Build Coastguard Worker        got = self.get_report('perf_with_two_event_types.data')
57*288bf522SAndroid Build Coastguard Worker        golden_path = TestHelper.testdata_path('perf_with_two_event_types.foldedstack')
58*288bf522SAndroid Build Coastguard Worker        self.assertEqual(got, Path(golden_path).read_text())
59*288bf522SAndroid Build Coastguard Worker
60*288bf522SAndroid Build Coastguard Worker    def test_two_event_types_chooses_with_event_filter(self):
61*288bf522SAndroid Build Coastguard Worker        got = self.get_report('perf_with_two_event_types.data', ['--event-filter', 'cpu-clock'])
62*288bf522SAndroid Build Coastguard Worker        golden_path = TestHelper.testdata_path('perf_with_two_event_types.foldedstack_cpu_clock')
63*288bf522SAndroid Build Coastguard Worker        self.assertEqual(got, Path(golden_path).read_text())
64*288bf522SAndroid Build Coastguard Worker
65*288bf522SAndroid Build Coastguard Worker    def test_unknown_symbol_addrs(self):
66*288bf522SAndroid Build Coastguard Worker        got = self.get_report('perf_with_jit_symbol.data', ['--addrs'])
67*288bf522SAndroid Build Coastguard Worker        golden_path = TestHelper.testdata_path('perf_with_jit_symbol.foldedstack_addrs')
68*288bf522SAndroid Build Coastguard Worker        self.assertEqual(got, Path(golden_path).read_text())
69*288bf522SAndroid Build Coastguard Worker
70*288bf522SAndroid Build Coastguard Worker    def test_sample_filters(self):
71*288bf522SAndroid Build Coastguard Worker        def get_threads_for_filter(filter: str) -> Set[int]:
72*288bf522SAndroid Build Coastguard Worker            report = self.get_report('perf_display_bitmaps.data', ['--tid'] + filter.split())
73*288bf522SAndroid Build Coastguard Worker            pattern = re.compile(r'-31850/(\d+);')
74*288bf522SAndroid Build Coastguard Worker            threads = set()
75*288bf522SAndroid Build Coastguard Worker            for m in re.finditer(pattern, report):
76*288bf522SAndroid Build Coastguard Worker                threads.add(int(m.group(1)))
77*288bf522SAndroid Build Coastguard Worker            return threads
78*288bf522SAndroid Build Coastguard Worker
79*288bf522SAndroid Build Coastguard Worker        self.assertNotIn(31850, get_threads_for_filter('--exclude-pid 31850'))
80*288bf522SAndroid Build Coastguard Worker        self.assertIn(31850, get_threads_for_filter('--include-pid 31850'))
81*288bf522SAndroid Build Coastguard Worker        self.assertNotIn(31881, get_threads_for_filter('--exclude-tid 31881'))
82*288bf522SAndroid Build Coastguard Worker        self.assertIn(31881, get_threads_for_filter('--include-tid 31881'))
83*288bf522SAndroid Build Coastguard Worker        self.assertNotIn(31881, get_threads_for_filter(
84*288bf522SAndroid Build Coastguard Worker            '--exclude-process-name com.example.android.displayingbitmaps'))
85*288bf522SAndroid Build Coastguard Worker        self.assertIn(31881, get_threads_for_filter(
86*288bf522SAndroid Build Coastguard Worker            '--include-process-name com.example.android.displayingbitmaps'))
87*288bf522SAndroid Build Coastguard Worker        self.assertNotIn(31850, get_threads_for_filter(
88*288bf522SAndroid Build Coastguard Worker            '--exclude-thread-name com.example.android.displayingbitmaps'))
89*288bf522SAndroid Build Coastguard Worker        self.assertIn(31850, get_threads_for_filter(
90*288bf522SAndroid Build Coastguard Worker            '--include-thread-name com.example.android.displayingbitmaps'))
91*288bf522SAndroid Build Coastguard Worker
92*288bf522SAndroid Build Coastguard Worker        with tempfile.NamedTemporaryFile('w', delete=False) as filter_file:
93*288bf522SAndroid Build Coastguard Worker            filter_file.write('GLOBAL_BEGIN 684943449406175\nGLOBAL_END 684943449406176')
94*288bf522SAndroid Build Coastguard Worker            filter_file.flush()
95*288bf522SAndroid Build Coastguard Worker            threads = get_threads_for_filter('--filter-file ' + filter_file.name)
96*288bf522SAndroid Build Coastguard Worker            self.assertIn(31881, threads)
97*288bf522SAndroid Build Coastguard Worker            self.assertNotIn(31850, threads)
98*288bf522SAndroid Build Coastguard Worker        os.unlink(filter_file.name)
99*288bf522SAndroid Build Coastguard Worker
100*288bf522SAndroid Build Coastguard Worker    def test_show_art_frames(self):
101*288bf522SAndroid Build Coastguard Worker        art_frame_str = 'art::interpreter::DoCall'
102*288bf522SAndroid Build Coastguard Worker        report = self.get_report('perf_with_interpreter_frames.data')
103*288bf522SAndroid Build Coastguard Worker        self.assertNotIn(art_frame_str, report)
104*288bf522SAndroid Build Coastguard Worker        report = self.get_report('perf_with_interpreter_frames.data', ['--show-art-frames'])
105*288bf522SAndroid Build Coastguard Worker        self.assertIn(art_frame_str, report)
106