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, BinaryProto 18from python.generators.diff_tests.testing import DiffTestBlueprint 19from python.generators.diff_tests.testing import TestSuite 20from python.generators.diff_tests.testing import PrintProfileProto 21from google.protobuf import text_format 22 23 24class PreludePprofFunctions(TestSuite): 25 26 def test_stacks(self): 27 return DiffTestBlueprint( 28 trace=DataPath("perf_sample.pb"), 29 query=""" 30 SELECT HEX( 31 CAT_STACKS( 32 "A", 33 CAT_STACKS( 34 "B", 35 CAT_STACKS( 36 "C", 37 STACK_FROM_STACK_PROFILE_CALLSITE(5), 38 "D") 39 ), 40 "E", 41 NULL, 42 STACK_FROM_STACK_PROFILE_CALLSITE(14), 43 STACK_FROM_STACK_PROFILE_CALLSITE(NULL), 44 STACK_FROM_STACK_PROFILE_FRAME(4), 45 STACK_FROM_STACK_PROFILE_FRAME(NULL))) 46 """, 47 out=BinaryProto( 48 message_type="perfetto.protos.Stack", 49 contents=""" 50 entries { 51 frame_id: 4 52 } 53 entries { 54 callsite_id: 14 55 } 56 entries { 57 name: "E" 58 } 59 entries { 60 name: "D" 61 } 62 entries { 63 callsite_id: 5 64 } 65 entries { 66 name: "C" 67 } 68 entries { 69 name: "B" 70 } 71 entries { 72 name: "A" 73 } 74 """)) 75 76 def test_profile_no_functions(self): 77 return DiffTestBlueprint( 78 trace=DataPath("perf_sample_no_functions.pb"), 79 query=""" 80 SELECT HEX( 81 EXPERIMENTAL_PROFILE(STACK_FROM_STACK_PROFILE_CALLSITE(callsite_id)) 82 ) 83 FROM perf_sample 84 WHERE callsite_id IS NOT NULL 85 """, 86 out=BinaryProto( 87 message_type="perfetto.third_party.perftools.profiles.Profile", 88 post_processing=PrintProfileProto, 89 contents=""" 90 Sample: 91 Values: 1 92 Stack: 93 (0x7a4167d3f8) 94 (0x783153c8e4) 95 (0x7a4161ef8c) 96 (0x7a42c3d8b0) 97 (0x7a4167d9f4) 98 (0x7a4163bc44) 99 (0x7a4172f330) 100 (0x7a4177a658) 101 (0x7a4162b3a0) 102 103 Sample: 104 Values: 1 105 Stack: 106 (0x7a4167d9f8) 107 (0x7a4163bc44) 108 (0x7a4172f330) 109 (0x7a4177a658) 110 (0x7a4162b3a0) 111 """)) 112 113 def test_profile_default_sample_types(self): 114 return DiffTestBlueprint( 115 trace=DataPath("perf_sample.pb"), 116 query=""" 117 SELECT HEX( 118 EXPERIMENTAL_PROFILE( 119 CAT_STACKS( 120 "A", 121 STACK_FROM_STACK_PROFILE_CALLSITE(2), 122 "B" 123 ))) 124 """, 125 out=BinaryProto( 126 message_type="perfetto.third_party.perftools.profiles.Profile", 127 post_processing=PrintProfileProto, 128 contents=""" 129 Sample: 130 Values: 1 131 Stack: 132 B (0x0) 133 perfetto::base::UnixTaskRunner::Run() (0x7a4172f330) 134 perfetto::ServiceMain(int, char**) (0x7a4177a658) 135 __libc_init (0x7a4162b3a0) 136 A (0x0) 137 """)) 138 139 def test_profile_with_sample_types(self): 140 return DiffTestBlueprint( 141 trace=DataPath("perf_sample.pb"), 142 query=""" 143 SELECT HEX( 144 EXPERIMENTAL_PROFILE( 145 CAT_STACKS("A", "B"), "type", "units", 42)) 146 """, 147 out=BinaryProto( 148 message_type="perfetto.third_party.perftools.profiles.Profile", 149 post_processing=PrintProfileProto, 150 contents=""" 151 Sample: 152 Values: 42 153 Stack: 154 B (0x0) 155 A (0x0) 156 """)) 157 158 def test_profile_aggregates_samples(self): 159 return DiffTestBlueprint( 160 trace=DataPath("perf_sample.pb"), 161 query=""" 162 WITH samples(stack, value) AS ( 163 VALUES 164 (CAT_STACKS("A", "B"), 4), 165 (CAT_STACKS("A", "B"), 8), 166 (CAT_STACKS("A", "B"), 15), 167 (CAT_STACKS("A", "C"), 16), 168 (CAT_STACKS("C", "B"), 23), 169 (CAT_STACKS("C", "B"), 42) 170 ) 171 SELECT HEX( 172 EXPERIMENTAL_PROFILE( 173 stack, "type", "units", value)) 174 FROM samples 175 """, 176 out=BinaryProto( 177 message_type="perfetto.third_party.perftools.profiles.Profile", 178 post_processing=PrintProfileProto, 179 contents=""" 180 Sample: 181 Values: 16 182 Stack: 183 C (0x0) 184 A (0x0) 185 186 Sample: 187 Values: 27 188 Stack: 189 B (0x0) 190 A (0x0) 191 192 Sample: 193 Values: 65 194 Stack: 195 B (0x0) 196 C (0x0) 197 """)) 198 199 def test_annotated_callstack(self): 200 return DiffTestBlueprint( 201 trace=DataPath("perf_sample_annotations.pftrace"), 202 query=""" 203 SELECT HEX(EXPERIMENTAL_PROFILE(STACK_FROM_STACK_PROFILE_CALLSITE(251, TRUE))) 204 """, 205 out=BinaryProto( 206 message_type="perfetto.third_party.perftools.profiles.Profile", 207 post_processing=PrintProfileProto, 208 contents=""" 209 Sample: 210 Values: 1 211 Stack: 212 art::ResolveFieldWithAccessChecks(art::Thread*, art::ClassLinker*, unsigned short, art::ArtMethod*, bool, bool, unsigned long) [common-frame] (0x724da79a74) 213 NterpGetInstanceFieldOffset [common-frame-interp] (0x724da794b0) 214 nterp_get_instance_field_offset [common-frame-interp] (0x724dcfc070) 215 nterp_op_iget_object_slow_path [common-frame-interp] (0x724dcf5884) 216 android.view.ViewRootImpl.notifyDrawStarted [interp] (0x7248f894d2) 217 android.view.ViewRootImpl.performTraversals [aot] (0x71b8d378) 218 android.view.ViewRootImpl.doTraversal [aot] (0x71b93220) 219 android.view.ViewRootImpl$TraversalRunnable.run [aot] (0x71ab0384) 220 android.view.Choreographer.doCallbacks [aot] (0x71a91b6c) 221 android.view.Choreographer.doFrame [aot] (0x71a92550) 222 android.view.Choreographer$FrameDisplayEventReceiver.run [aot] (0x71b26fb0) 223 android.os.Handler.dispatchMessage [aot] (0x71975924) 224 android.os.Looper.loopOnce [aot] (0x71978d6c) 225 android.os.Looper.loop [aot] (0x719788a0) 226 android.app.ActivityThread.main [aot] (0x717454cc) 227 art_quick_invoke_static_stub [common-frame] (0x724db2de00) 228 _jobject* art::InvokeMethod<(art::PointerSize)8>(art::ScopedObjectAccessAlreadyRunnable const&, _jobject*, _jobject*, _jobject*, unsigned long) [common-frame] (0x724db545ec) 229 art::Method_invoke(_JNIEnv*, _jobject*, _jobject*, _jobjectArray*) (0x724db53ad0) 230 art_jni_trampoline [common-frame] (0x6ff5c578) 231 com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run [aot] (0x71c4ab6c) 232 com.android.internal.os.ZygoteInit.main [aot] (0x71c54c7c) 233 art_quick_invoke_static_stub (0x724db2de00) 234 art::JValue art::InvokeWithVarArgs<_jmethodID*>(art::ScopedObjectAccessAlreadyRunnable const&, _jobject*, _jmethodID*, std::__va_list) (0x724dc422a8) 235 art::JNI<true>::CallStaticVoidMethodV(_JNIEnv*, _jclass*, _jmethodID*, std::__va_list) (0x724dcc57c8) 236 _JNIEnv::CallStaticVoidMethod(_jclass*, _jmethodID*, ...) (0x74e1b03ca8) 237 android::AndroidRuntime::start(char const*, android::Vector<android::String8> const&, bool) (0x74e1b0feac) 238 main (0x63da9c354c) 239 __libc_init (0x74ff4a0728) 240 """)) 241