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 MemoryMetrics(TestSuite): 23 # Contains test for Android memory metrics. ION metric 24 def test_android_ion(self): 25 return DiffTestBlueprint( 26 trace=Path('android_ion.py'), 27 query=Metric('android_ion'), 28 out=TextProto(r""" 29 android_ion { 30 buffer { 31 name: "adsp" 32 avg_size_bytes: 1000.0 33 min_size_bytes: 1000.0 34 max_size_bytes: 1100.0 35 total_alloc_size_bytes: 1100.0 36 } 37 buffer { 38 name: "system" 39 avg_size_bytes: 1497.4874371859296 40 min_size_bytes: 1000.0 41 max_size_bytes: 2000.0 42 total_alloc_size_bytes: 2000.0 43 } 44 } 45 """)) 46 47 def test_android_ion_stat(self): 48 return DiffTestBlueprint( 49 trace=TextProto(r""" 50 packet { 51 ftrace_events { 52 cpu: 0 53 event { 54 timestamp: 100 55 pid: 1 56 ion_stat { 57 buffer_id: 123 58 len: 1000 59 total_allocated: 2000 60 } 61 } 62 } 63 } 64 packet { 65 ftrace_events { 66 cpu: 0 67 event { 68 timestamp: 200 69 pid: 1 70 ion_stat { 71 buffer_id: 123 72 len: -1000 73 total_allocated: 1000 74 } 75 } 76 } 77 } 78 """), 79 query=Metric('android_ion'), 80 out=TextProto(r""" 81 android_ion { 82 buffer { 83 name: "all" 84 avg_size_bytes: 2000.0 85 min_size_bytes: 1000.0 86 max_size_bytes: 2000.0 87 total_alloc_size_bytes: 1000.0 88 } 89 } 90 """)) 91 92 # DMA-BUF heap Metric 93 def test_android_dma_heap_stat(self): 94 return DiffTestBlueprint( 95 trace=TextProto(r""" 96 packet { 97 ftrace_events { 98 cpu: 0 99 event { 100 timestamp: 100 101 pid: 1 102 dma_heap_stat { 103 inode: 123 104 len: 1024 105 total_allocated: 2048 106 } 107 } 108 } 109 } 110 packet { 111 ftrace_events { 112 cpu: 0 113 event { 114 timestamp: 200 115 pid: 1 116 dma_heap_stat { 117 inode: 123 118 len: -1024 119 total_allocated: 1024 120 } 121 } 122 } 123 } 124 """), 125 query=Metric('android_dma_heap'), 126 out=TextProto(r""" 127 android_dma_heap { 128 avg_size_bytes: 2048.0 129 min_size_bytes: 1024.0 130 max_size_bytes: 2048.0 131 total_alloc_size_bytes: 1024.0 132 } 133 """)) 134 135 # fastrpc metric 136 def test_android_fastrpc_dma_stat(self): 137 return DiffTestBlueprint( 138 trace=TextProto(r""" 139 packet { 140 ftrace_events { 141 cpu: 0 142 event { 143 timestamp: 100 144 pid: 1 145 fastrpc_dma_stat { 146 cid: 1 147 len: 1000 148 total_allocated: 2000 149 } 150 } 151 } 152 } 153 packet { 154 ftrace_events { 155 cpu: 0 156 event { 157 timestamp: 200 158 pid: 1 159 fastrpc_dma_stat { 160 cid: 1 161 len: -1000 162 total_allocated: 1000 163 } 164 } 165 } 166 } 167 """), 168 query=Metric('android_fastrpc'), 169 out=TextProto(r""" 170 android_fastrpc { 171 subsystem { 172 name: "MDSP" 173 avg_size_bytes: 2000.0 174 min_size_bytes: 1000.0 175 max_size_bytes: 2000.0 176 total_alloc_size_bytes: 1000.0 177 } 178 } 179 """)) 180 181 def test_android_mem_counters(self): 182 return DiffTestBlueprint( 183 trace=DataPath('memory_counters.pb'), 184 query=Metric('android_mem'), 185 out=Path('android_mem_counters.out')) 186 187 def test_trace_metadata(self): 188 return DiffTestBlueprint( 189 trace=DataPath('memory_counters.pb'), 190 query=Metric('trace_metadata'), 191 out=Path('trace_metadata.out')) 192 193 def test_android_mem_by_priority(self): 194 return DiffTestBlueprint( 195 trace=Path('android_mem_by_priority.py'), 196 query=Metric('android_mem'), 197 out=Path('android_mem_by_priority.out')) 198 199 def test_android_mem_lmk(self): 200 return DiffTestBlueprint( 201 trace=Path('android_systrace_lmk.py'), 202 query=Metric('android_lmk'), 203 out=TextProto(r""" 204 android_lmk { 205 total_count: 1 206 by_oom_score { 207 oom_score_adj: 900 208 count: 1 209 } 210 oom_victim_count: 0 211 } 212 """)) 213 214 def test_android_lmk_oom(self): 215 return DiffTestBlueprint( 216 trace=TextProto(r""" 217 packet { 218 process_tree { 219 processes { 220 pid: 1000 221 ppid: 1 222 cmdline: "com.google.android.gm" 223 } 224 threads { 225 tid: 1001 226 tgid: 1000 227 } 228 } 229 } 230 packet { 231 ftrace_events { 232 cpu: 4 233 event { 234 timestamp: 1234 235 pid: 4321 236 mark_victim { 237 pid: 1001 238 } 239 } 240 } 241 } 242 """), 243 query=Metric('android_lmk'), 244 out=TextProto(r""" 245 android_lmk { 246 total_count: 0 247 oom_victim_count: 1 248 } 249 """)) 250 251 def test_android_lmk_reason(self): 252 return DiffTestBlueprint( 253 trace=DataPath('lmk_userspace.pb'), 254 query=Metric('android_lmk_reason'), 255 # TODO(mayzner): Find a trace that returns results. This is still 256 # beneficial though, as at least this metric is run. 257 out=TextProto(r""" 258 android_lmk_reason { 259 } 260 """)) 261 262 def test_android_mem_delta(self): 263 return DiffTestBlueprint( 264 trace=Path('android_mem_delta.py'), 265 query=Metric('android_mem'), 266 out=TextProto(r""" 267 android_mem { 268 process_metrics { 269 process_name: "com.my.pkg" 270 total_counters { 271 file_rss { 272 min: 2000.0 273 max: 10000.0 274 avg: 6666.666666666667 275 delta: 7000.0 276 } 277 } 278 } 279 } 280 """)) 281 282 # cma alloc 283 def test_cma(self): 284 return DiffTestBlueprint( 285 trace=TextProto(r""" 286 packet { 287 system_info { 288 utsname { 289 sysname: "Linux" 290 release: "5.10.0" 291 } 292 } 293 } 294 packet { 295 ftrace_events { 296 cpu: 4 297 event { 298 timestamp: 74288080958099 299 pid: 537 300 cma_alloc_start { 301 align: 4 302 count: 6592 303 name: "farawimg" 304 } 305 } 306 event { 307 timestamp: 74288191109751 308 pid: 537 309 cma_alloc_info { 310 align: 4 311 count: 6592 312 err_iso: 0 313 err_mig: 0 314 err_test: 0 315 name: "farawimg" 316 nr_mapped: 832596 317 nr_migrated: 6365 318 nr_reclaimed: 7 319 pfn: 10365824 320 } 321 } 322 } 323 } 324 """), 325 query=""" 326 SELECT ts, dur, name FROM slice WHERE name = 'mm_cma_alloc'; 327 """, 328 out=Csv(""" 329 "ts","dur","name" 330 74288080958099,110151652,"mm_cma_alloc" 331 """)) 332 333 def test_android_dma_buffer_tracks(self): 334 return DiffTestBlueprint( 335 trace=TextProto(r""" 336 packet { 337 ftrace_events { 338 cpu: 0 339 event { 340 timestamp: 100 341 pid: 1 342 dma_heap_stat { 343 inode: 123 344 len: 1024 345 total_allocated: 2048 346 } 347 } 348 } 349 } 350 packet { 351 ftrace_events { 352 cpu: 0 353 event { 354 timestamp: 200 355 pid: 1 356 dma_heap_stat { 357 inode: 123 358 len: -1024 359 total_allocated: 1024 360 } 361 } 362 } 363 } 364 """), 365 query=""" 366 SELECT track.name, slice.ts, slice.dur, slice.name 367 FROM slice JOIN track ON slice.track_id = track.id 368 WHERE track.name = 'mem.dma_buffer'; 369 """, 370 out=Csv(""" 371 "name","ts","dur","name" 372 "mem.dma_buffer",100,100,"1 kB" 373 """)) 374