• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env python3
2# Copyright (C) 2023 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 Path, DataPath, Metric
17from python.generators.diff_tests.testing import Csv, Json, TextProto
18from python.generators.diff_tests.testing import DiffTestBlueprint
19from python.generators.diff_tests.testing import TestSuite
20
21
22class ProfilingHeapGraph(TestSuite):
23
24  def test_heap_graph_flamegraph(self):
25    return DiffTestBlueprint(
26        trace=Path('heap_graph_baseapk.textproto'),
27        query="""
28        SELECT
29          id,
30          depth,
31          name,
32          map_name,
33          count,
34          cumulative_count,
35          size,
36          cumulative_size,
37          parent_id
38        FROM experimental_flamegraph
39        WHERE upid = (SELECT max(upid) FROM heap_graph_object)
40          AND profile_type = 'graph'
41          AND ts = (SELECT max(graph_sample_ts) FROM heap_graph_object)
42        LIMIT 10;
43        """,
44        out=Path('heap_graph_flamegraph.out'))
45
46  def test_heap_graph_object(self):
47    return DiffTestBlueprint(
48        trace=Path('heap_graph_baseapk.textproto'),
49        query="""
50        SELECT o.id,
51               o.type,
52               o.upid,
53               o.graph_sample_ts,
54               o.self_size,
55               o.reference_set_id,
56               o.reachable,
57               c.name AS type_name,
58               c.deobfuscated_name AS deobfuscated_type_name,
59               o.root_type
60        FROM heap_graph_object o JOIN heap_graph_class c ON o.type_id = c.id;
61        """,
62        out=Path('heap_graph_object.out'))
63
64  def test_heap_graph_reference(self):
65    return DiffTestBlueprint(
66        trace=Path('heap_graph_baseapk.textproto'),
67        query="""
68        SELECT * FROM heap_graph_reference;
69        """,
70        out=Path('heap_graph_reference.out'))
71
72  def test_heap_graph_object_2(self):
73    return DiffTestBlueprint(
74        trace=Path('heap_graph_deobfuscate_pkg.textproto'),
75        query="""
76        SELECT o.id,
77               o.type,
78               o.upid,
79               o.graph_sample_ts,
80               o.self_size,
81               o.reference_set_id,
82               o.reachable,
83               c.name AS type_name,
84               c.deobfuscated_name AS deobfuscated_type_name,
85               o.root_type
86        FROM heap_graph_object o JOIN heap_graph_class c ON o.type_id = c.id;
87        """,
88        out=Path('heap_graph_object.out'))
89
90  def test_heap_graph_duplicate_flamegraph(self):
91    return DiffTestBlueprint(
92        trace=TextProto(r"""
93        packet {
94          process_tree {
95            processes {
96              pid: 2
97              ppid: 1
98              cmdline: "system_server"
99              uid: 1000
100            }
101          }
102        }
103        packet {
104          timestamp: 10
105          process_stats {
106            processes {
107              pid: 2
108              rss_anon_kb: 1000
109              vm_swap_kb: 3000
110              oom_score_adj: 0
111            }
112          }
113        }
114        packet {
115          trusted_packet_sequence_id: 999
116          timestamp: 10
117          heap_graph {
118            pid: 2
119            types {
120              id: 1
121              class_name: "FactoryProducerDelegateImplActor"
122              location_id: 1
123            }
124            roots {
125              root_type: ROOT_JAVA_FRAME
126              object_ids: 0x01
127              object_ids: 0x01
128            }
129            objects {
130              id: 0x01
131              type_id: 1
132              self_size: 64
133            }
134            continued: false
135            index: 0
136          }
137        }
138        """),
139        query="""
140        SELECT
141          id,
142          depth,
143          name,
144          map_name,
145          count,
146          cumulative_count,
147          size,
148          cumulative_size,
149          parent_id
150        FROM experimental_flamegraph
151        WHERE upid = (SELECT max(upid) FROM heap_graph_object)
152          AND profile_type = 'graph'
153          AND ts = (SELECT max(graph_sample_ts) FROM heap_graph_object)
154        LIMIT 10;
155        """,
156        out=Path('heap_graph_duplicate_flamegraph.out'))
157
158  def test_heap_graph_flamegraph_2(self):
159    return DiffTestBlueprint(
160        trace=Path('heap_graph.textproto'),
161        query="""
162        SELECT
163          id,
164          depth,
165          name,
166          map_name,
167          count,
168          cumulative_count,
169          size,
170          cumulative_size,
171          parent_id
172        FROM experimental_flamegraph
173        WHERE upid = (SELECT max(upid) FROM heap_graph_object)
174          AND profile_type = 'graph'
175          AND ts = (SELECT max(graph_sample_ts) FROM heap_graph_object)
176        LIMIT 10;
177        """,
178        out=Path('heap_graph_flamegraph.out'))
179
180  def test_heap_graph_object_3(self):
181    return DiffTestBlueprint(
182        trace=Path('heap_graph.textproto'),
183        query="""
184        SELECT o.id,
185               o.type,
186               o.upid,
187               o.graph_sample_ts,
188               o.self_size,
189               o.reference_set_id,
190               o.reachable,
191               c.name AS type_name,
192               c.deobfuscated_name AS deobfuscated_type_name,
193               o.root_type
194        FROM heap_graph_object o JOIN heap_graph_class c ON o.type_id = c.id;
195        """,
196        out=Path('heap_graph_object.out'))
197
198  def test_heap_graph_reference_2(self):
199    return DiffTestBlueprint(
200        trace=Path('heap_graph.textproto'),
201        query="""
202        SELECT * FROM heap_graph_reference;
203        """,
204        out=Path('heap_graph_reference.out'))
205
206  def test_heap_graph_two_locations(self):
207    return DiffTestBlueprint(
208        trace=Path('heap_graph_two_locations.textproto'),
209        query="""
210        SELECT o.id,
211               o.type,
212               o.upid,
213               o.graph_sample_ts,
214               o.self_size,
215               o.reference_set_id,
216               o.reachable,
217               c.name AS type_name,
218               c.deobfuscated_name AS deobfuscated_type_name,
219               o.root_type
220        FROM heap_graph_object o JOIN heap_graph_class c ON o.type_id = c.id;
221        """,
222        out=Path('heap_graph_two_locations.out'))
223
224  def test_heap_graph_object_4(self):
225    return DiffTestBlueprint(
226        trace=Path('heap_graph_legacy.textproto'),
227        query="""
228        SELECT o.id,
229               o.type,
230               o.upid,
231               o.graph_sample_ts,
232               o.self_size,
233               o.reference_set_id,
234               o.reachable,
235               c.name AS type_name,
236               c.deobfuscated_name AS deobfuscated_type_name,
237               o.root_type
238        FROM heap_graph_object o JOIN heap_graph_class c ON o.type_id = c.id;
239        """,
240        out=Path('heap_graph_object.out'))
241
242  def test_heap_graph_reference_3(self):
243    return DiffTestBlueprint(
244        trace=Path('heap_graph_legacy.textproto'),
245        query="""
246        SELECT * FROM heap_graph_reference;
247        """,
248        out=Path('heap_graph_reference.out'))
249
250  def test_heap_graph_interleaved_object(self):
251    return DiffTestBlueprint(
252        trace=Path('heap_graph_interleaved.textproto'),
253        query="""
254        SELECT o.id,
255               o.type,
256               o.upid,
257               o.graph_sample_ts,
258               o.self_size,
259               o.reference_set_id,
260               o.reachable,
261               c.name AS type_name,
262               c.deobfuscated_name AS deobfuscated_type_name,
263               o.root_type
264        FROM heap_graph_object o JOIN heap_graph_class c ON o.type_id = c.id;
265        """,
266        out=Path('heap_graph_interleaved_object.out'))
267
268  def test_heap_graph_interleaved_reference(self):
269    return DiffTestBlueprint(
270        trace=Path('heap_graph_interleaved.textproto'),
271        query="""
272        SELECT * FROM heap_graph_reference;
273        """,
274        out=Path('heap_graph_interleaved_reference.out'))
275
276  def test_heap_graph_flamegraph_system_server_heap_graph(self):
277    return DiffTestBlueprint(
278        trace=DataPath('system-server-heap-graph-new.pftrace'),
279        query="""
280        SELECT
281          id,
282          depth,
283          name,
284          map_name,
285          count,
286          cumulative_count,
287          size,
288          cumulative_size,
289          parent_id
290        FROM experimental_flamegraph
291        WHERE upid = (SELECT max(upid) FROM heap_graph_object)
292          AND profile_type = 'graph'
293          AND ts = (SELECT max(graph_sample_ts) FROM heap_graph_object)
294        LIMIT 10;
295        """,
296        out=Path('heap_graph_flamegraph_system-server-heap-graph.out'))
297
298  def test_heap_profile_flamegraph_system_server_native_profile(self):
299    return DiffTestBlueprint(
300        trace=DataPath('system-server-native-profile'),
301        query="""
302        SELECT * FROM experimental_flamegraph
303        WHERE ts = 605908369259172
304          AND upid = 1
305          AND profile_type = 'native'
306        LIMIT 10;
307        """,
308        out=Path('heap_profile_flamegraph_system-server-native-profile.out'))
309
310  def test_heap_profile_tracker_new_stack(self):
311    return DiffTestBlueprint(
312        trace=Path('heap_profile_tracker_new_stack.textproto'),
313        query="""
314        SELECT * FROM heap_profile_allocation;
315        """,
316        out=Csv("""
317        "id","type","ts","upid","heap_name","callsite_id","count","size"
318        0,"heap_profile_allocation",0,0,"malloc",0,1,1
319        1,"heap_profile_allocation",0,0,"malloc",0,-1,-1
320        2,"heap_profile_allocation",1,0,"malloc",0,1,1
321        3,"heap_profile_allocation",1,0,"malloc",0,-1,-1
322        """))
323
324  def test_heap_profile_tracker_twoheaps(self):
325    return DiffTestBlueprint(
326        trace=Path('heap_profile_tracker_twoheaps.textproto'),
327        query="""
328        SELECT * FROM heap_profile_allocation;
329        """,
330        out=Csv("""
331        "id","type","ts","upid","heap_name","callsite_id","count","size"
332        0,"heap_profile_allocation",0,0,"malloc",0,1,1
333        1,"heap_profile_allocation",0,0,"malloc",0,-1,-1
334        2,"heap_profile_allocation",0,0,"custom",0,1,1
335        3,"heap_profile_allocation",0,0,"custom",0,-1,-1
336        """))
337
338  def test_heap_graph_flamegraph_focused(self):
339    return DiffTestBlueprint(
340        trace=Path('heap_graph_branching.textproto'),
341        query="""
342        SELECT
343          id,
344          depth,
345          name,
346          count,
347          cumulative_count,
348          size,
349          cumulative_size,
350          parent_id
351        FROM experimental_flamegraph
352        WHERE upid = (SELECT max(upid) FROM heap_graph_object)
353          AND profile_type = 'graph'
354          AND ts = (SELECT max(graph_sample_ts) FROM heap_graph_object)
355          AND focus_str = 'left'
356        LIMIT 10;
357        """,
358        out=Path('heap_graph_flamegraph_focused.out'))
359
360  def test_heap_graph_superclass(self):
361    return DiffTestBlueprint(
362        trace=Path('heap_graph_superclass.textproto'),
363        query="""
364        SELECT c.id, c.superclass_id, c.name, s.name AS superclass_name, c.location
365        FROM heap_graph_class c LEFT JOIN heap_graph_class s ON c.superclass_id = s.id;
366        """,
367        out=Csv("""
368        "id","superclass_id","name","superclass_name","location"
369        0,"[NULL]","java.lang.Class<java.lang.Object>","[NULL]","l1"
370        1,"[NULL]","java.lang.Class<MySuperClass>","[NULL]","l1"
371        2,"[NULL]","java.lang.Class<MyChildClass>","[NULL]","l2"
372        3,"[NULL]","java.lang.Object","[NULL]","l1"
373        4,3,"MySuperClass","java.lang.Object","l1"
374        5,4,"MyChildClass","MySuperClass","l2"
375        """))
376
377  def test_heap_graph_native_size(self):
378    return DiffTestBlueprint(
379        trace=Path('heap_graph_native_size.textproto'),
380        query="""
381        SELECT c.name AS type_name,
382               o.native_size
383        FROM heap_graph_object o JOIN heap_graph_class c ON o.type_id = c.id
384        WHERE o.root_type = "ROOT_JAVA_FRAME";
385        """,
386        out=Csv("""
387        "type_name","native_size"
388        "android.graphics.Bitmap",123456
389        "android.os.BinderProxy",0
390        """))
391