• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env python3
2# Copyright (C) 2024 The Android Open Source Project
3#
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License a
7#
8#      http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15
16from python.generators.diff_tests.testing import Csv, Path, DataPath
17from python.generators.diff_tests.testing import DiffTestBlueprint
18from python.generators.diff_tests.testing import TestSuite
19
20
21# These diff tests are based on the same test data simpleperf uses for its
22# testing
23# (https://android.googlesource.com/platform/system/extras/+/refs/heads/main/simpleperf/testdata).
24# Basically we load these perf files and make sure we can get the same data we
25# would get via `simpleperf report`
26class Simpleperf(TestSuite):
27  # simpleperf report -i perf.data --print-event-count --csv --cpu 2,6,7
28  def test_perf(self):
29    return DiffTestBlueprint(
30        trace=DataPath('simpleperf/perf.data'),
31        query=Path('perf_test.sql'),
32        out=Csv('''
33        "event_count","command","pid","tid","shared_object","symbol"
34        130707953,"t2",26130,26130,"/t2","t2[+51c]"
35        126249237,"elf",26083,26083,"/elf","elf[+51c]"
36        109687208,"t1",26124,26124,"/t1","t1[+523]"
37        107027760,"t1",26124,26124,"/t1","t1[+51c]"
38        101887409,"t2",26130,26130,"/t2","t2[+523]"
39        92421568,"elf",26083,26083,"/elf","elf[+523]"
40        61539363,"t1",26124,26124,"/t1","t1[+518]"
41        60355129,"elf",26083,26083,"/elf","elf[+513]"
42        54840659,"t1",26124,26124,"/t1","t1[+4ed]"
43        52233968,"elf",26083,26083,"/elf","elf[+4ed]"
44        50833094,"t1",26124,26124,"/t1","t1[+4f7]"
45        50746374,"t2",26130,26130,"/t2","t2[+4ed]"
46        49185691,"elf",26083,26083,"/elf","elf[+4f7]"
47        47520901,"t2",26130,26130,"/t2","t2[+513]"
48        45979652,"elf",26083,26083,"/elf","elf[+518]"
49        44834371,"t2",26130,26130,"/t2","t2[+4f7]"
50        42928068,"t2",26130,26130,"/t2","t2[+518]"
51        39608138,"t1",26124,26124,"/t1","t1[+513]"
52        1390415,"t1",26124,26124,"/t1","t1[+4fa]"
53        1390305,"t2",26130,26130,"/t2","t2[+4fa]"
54        1390173,"elf",26083,26083,"/elf","elf[+500]"
55        1389030,"t2",26130,26130,"/t2","t2[+500]"
56        693786,"t2",26130,26130,"/lib/modules/3.13.0-76-generic/kernel/drivers/ata/pata_acpi.ko","pata_acpi.ko[+ffffffffa05c4da4]"
57        '''))
58
59  def test_perf_tracks(self):
60    return DiffTestBlueprint(
61        trace=DataPath('simpleperf/perf.data'),
62        query='''
63        SELECT
64          name,
65          unit,
66          description,
67          cpu,
68          is_timebase
69        FROM perf_counter_track
70        ORDER BY perf_session_id, name, cpu;
71        ''',
72        out=Csv('''
73          "name","unit","description","cpu","is_timebase"
74          "","[NULL]","[NULL]",2,1
75          "","[NULL]","[NULL]",6,1
76          "","[NULL]","[NULL]",7,1
77          "","[NULL]","[NULL]",16,1
78        '''))
79
80  def test_perf_with_add_counter_tracks(self):
81    return DiffTestBlueprint(
82        trace=DataPath('simpleperf/perf_with_add_counter.data'),
83        query='''
84        SELECT
85          name,
86          unit,
87          description,
88          cpu,
89          is_timebase
90        FROM perf_counter_track
91        ORDER BY perf_session_id, name, cpu;
92        ''',
93        out=Csv('''
94          "name","unit","description","cpu","is_timebase"
95          "cpu-cycles","[NULL]","[NULL]",40,1
96          "instructions","[NULL]","[NULL]",40,0
97        '''))
98
99  # simpleperf report -i perf.data --print-event-count --csv
100  # The thread name in this trace changes over time. simpleperf shows samples
101  # with the old and new name. Perfetto does not support threads changing names,
102  # it only keeps the last name, thus there is a slight mismatch in the outputs.
103  def test_perf_with_add_counter(self):
104    return DiffTestBlueprint(
105        trace=DataPath('simpleperf/perf_with_add_counter.data'),
106        query=Path('perf_with_add_counter_test.sql'),
107        out=Csv('''
108        "cpu_cycles","instructions","others","command","pid","tid","shared_object","symbol"
109        1011567,1188389,0,"sleep",689664,689664,"[kernel.kallsyms]","[kernel.kallsyms][+ffffffffa8cc9d30]"
110        219490,233619,0,"sleep",689664,689664,"[kernel.kallsyms]","[kernel.kallsyms][+ffffffffa8e498c6]"
111        191017,157031,0,"sleep",689664,689664,"[kernel.kallsyms]","[kernel.kallsyms][+ffffffffa94d0901]"
112        175099,140443,0,"sleep",689664,689664,"/lib/x86_64-linux-gnu/libc-2.32.so","_dl_addr"
113        152310,130151,0,"sleep",689664,689664,"[kernel.kallsyms]","[kernel.kallsyms][+ffffffffa8e30c70]"
114        122439,87058,0,"sleep",689664,689664,"[kernel.kallsyms]","[kernel.kallsyms][+ffffffffa960015d]"
115        89368,68332,0,"sleep",689664,689664,"[kernel.kallsyms]","[kernel.kallsyms][+ffffffffa8e03757]"
116        40272,30457,0,"sleep",689664,689664,"/lib/x86_64-linux-gnu/ld-2.32.so","ld-2.32.so[+1767b]"
117        14742,7858,0,"sleep",689664,689664,"[kernel.kallsyms]","[kernel.kallsyms][+ffffffffa8ce7a78]"
118        7551,1953,0,"sleep",689664,689664,"[kernel.kallsyms]","[kernel.kallsyms][+ffffffffa8cc90c5]"
119        7080,2940,0,"sleep",689664,689664,"[kernel.kallsyms]","[kernel.kallsyms][+ffffffffa8cc8119]"
120        3520,295,0,"sleep",689664,689664,"[kernel.kallsyms]","[kernel.kallsyms][+ffffffffa8c6b3e6]"
121        '''))
122
123  def test_build_id_feature(self):
124    return DiffTestBlueprint(
125        trace=DataPath('simpleperf/perf.data'),
126        query='''
127        SELECT build_id, name
128        FROM stack_profile_mapping
129        WHERE build_id <> ""
130        ORDER BY name
131        ''',
132        out=Csv('''
133        "build_id","name"
134        "0b12a384a9f4a3f3659b7171ca615dbec3a81f71","/elf"
135        "0b12a384a9f4a3f3659b7171ca615dbec3a81f71","/elf"
136        "47111a47babdcd27ca2f9ff450dc1897ded761ed","/lib/modules/3.13.0-76-generic/kernel/drivers/ata/pata_acpi.ko"
137        "0b12a384a9f4a3f3659b7171ca615dbec3a81f71","/t1"
138        "0b12a384a9f4a3f3659b7171ca615dbec3a81f71","/t2"
139        '''))
140
141  def test_clocks_align(self):
142    return DiffTestBlueprint(
143        trace=DataPath('zip/perf_track_sym.zip'),
144        query=Path('clocks_align_test.sql'),
145        out=Csv('''
146        "misaligned_count"
147        0
148        '''))
149
150  def test_cmdline(self):
151    return DiffTestBlueprint(
152        trace=DataPath('simpleperf/perf.data'),
153        query='''
154        SELECT cmdline
155        FROM perf_session
156        ''',
157        out=Csv('''
158        "cmdline"
159        "/ssd/android/aosp_master/out/host/linux-x86/bin/simpleperf record -p 26083,26090,26124,26130 sleep 0.0001"
160        '''))
161
162  # Make sure we can parse perf.data files with synthetic events (perf will
163  # write those with an id = 0). This trace file has some synthetic COMM events.
164  def test_perf_with_synthetic_events(self):
165    return DiffTestBlueprint(
166        trace=DataPath('simpleperf/perf_with_synthetic_events.data'),
167        query='''
168        SELECT tid, name
169        FROM thread
170        ORDER BY tid
171        ''',
172        out=Csv('''
173        "tid","name"
174        0,"[NULL]"
175        289003,"trace_processor"
176        '''))
177
178  # Counters are not updated for samples with no CPU (b/352257666)
179  def test_perf_with_no_cpu_in_sample_no_counters(self):
180    return DiffTestBlueprint(
181        trace=DataPath('simpleperf/perf_with_synthetic_events.data'),
182        query='''
183        SELECT
184          (
185            SELECT value AS sample_count
186            FROM stats
187            WHERE name = 'perf_counter_skipped_because_no_cpu'
188          ) AS counter_skipped,
189          (SELECT COUNT(*) FROM perf_sample) AS sample_count
190        ''',
191        out=Csv('''
192        "counter_skipped","sample_count"
193        9126,9126
194        '''))
195
196  def test_perf_with_no_cpu_in_sample(self):
197    return DiffTestBlueprint(
198        trace=DataPath('simpleperf/perf_with_synthetic_events.data'),
199        query='''
200        SELECT cpu, COUNT(*) AS count
201        FROM perf_sample
202        WHERE callsite_id IS NOT NULL
203        GROUP BY cpu ORDER BY cpu
204        ''',
205        out=Csv('''
206        "cpu","count"
207        "[NULL]",9126
208        '''))
209
210  def test_linux_perf_unwinding(self):
211    return DiffTestBlueprint(
212        trace=DataPath('simpleperf/linux_perf_with_symbols.zip'),
213        query=Path('stacks_test.sql'),
214        out=Csv('''
215        "name"
216        "main,A"
217        "main,A,B"
218        "main,A,B,C"
219        "main,A,B,C,D"
220        "main,A,B,C,D,E"
221        "main,A,B,C,E"
222        "main,A,B,D"
223        "main,A,B,D,E"
224        "main,A,B,E"
225        "main,A,C"
226        "main,A,C,D"
227        "main,A,C,D,E"
228        "main,A,C,E"
229        "main,A,D"
230        "main,A,D,E"
231        "main,A,E"
232        "main,B"
233        "main,B,C"
234        "main,B,C,D"
235        "main,B,C,D,E"
236        "main,B,C,E"
237        "main,B,D"
238        "main,B,D,E"
239        "main,B,E"
240        "main,C"
241        "main,C,D"
242        "main,C,D,E"
243        "main,C,E"
244        "main,D"
245        "main,D,E"
246        "main,E"
247        '''))
248
249  def test_spe_operation(self):
250    return DiffTestBlueprint(
251        trace=DataPath('simpleperf/spe.trace.zip'),
252        query='''
253        INCLUDE PERFETTO MODULE linux.perf.spe;
254        SELECT
255          operation,
256          count(*) AS cnt
257        FROM linux_perf_spe_record
258        GROUP BY operation
259        ORDER BY operation
260        ''',
261        out=Csv('''
262        "operation","cnt"
263        "BRANCH",68038
264        "LOAD",54
265        "STORE",47
266        '''))
267
268  def test_spe_pc(self):
269    return DiffTestBlueprint(
270        trace=DataPath('simpleperf/spe.trace.zip'),
271        query='''
272        INCLUDE PERFETTO MODULE linux.perf.spe;
273        SELECT
274          printf('0x%08x', rel_pc + m.start - exact_offset) AS pc,
275          exception_level,
276          COUNT(*) AS cnt
277        FROM linux_perf_spe_record r, stack_profile_frame f
278        ON r.instruction_frame_id = f.id,
279        stack_profile_mapping m
280        ON f.mapping = m.id
281        GROUP BY pc, exception_level
282        HAVING cnt > 1
283        ORDER BY pc, exception_level
284        ''',
285        out=Csv('''
286        "pc","exception_level","cnt"
287        "0x5cfc344464","EL0",2157
288        "0x5cfc344528","EL0",2166
289        "0x5cfc3445c4","EL0",2154
290        "0x5cfc3446c8","EL0",2108
291        "0x5cfc3447a8","EL0",2209
292        "0x5cfc344854","EL0",2178
293        "0x5cfc34492c","EL0",2246
294        "0x5cfc344c14","EL0",4461
295        "0x5cfc344cd0","EL0",4416
296        "0x5cfc344d7c","EL0",4399
297        "0x5cfc344df4","EL0",2
298        "0x5cfc344e90","EL0",4427
299        "0x5cfc3450e8","EL0",8756
300        "0x5cfc345194","EL0",8858
301        "0x5cfc345240","EL0",8776
302        "0x5cfc345354","EL0",8659
303        "0xffffd409990628","EL1",14
304        "0xffffd40999062c","EL1",15
305        "0xffffd40fb0f124","EL1",2
306        '''))
307
308  def test_perf_summary_tree(self):
309    return DiffTestBlueprint(
310        trace=DataPath('simpleperf/perf.data'),
311        query='''
312          INCLUDE PERFETTO MODULE linux.perf.samples;
313
314          SELECT *
315          FROM linux_perf_samples_summary_tree
316          LIMIT 10
317        ''',
318        out=Csv('''
319          "id","parent_id","name","mapping_name","source_file","line_number","self_count","cumulative_count"
320          0,"[NULL]","","/elf","[NULL]","[NULL]",84,84
321          1,"[NULL]","","/elf","[NULL]","[NULL]",69,69
322          2,"[NULL]","","/elf","[NULL]","[NULL]",177,177
323          3,"[NULL]","","/elf","[NULL]","[NULL]",89,89
324          4,"[NULL]","","/t1","[NULL]","[NULL]",70,70
325          5,"[NULL]","","/elf","[NULL]","[NULL]",218,218
326          6,"[NULL]","","/elf","[NULL]","[NULL]",65,65
327          7,"[NULL]","","/elf","[NULL]","[NULL]",70,70
328          8,"[NULL]","","/t1","[NULL]","[NULL]",87,87
329          9,"[NULL]","","/elf","[NULL]","[NULL]",64,64
330        '''))
331