195 lines
7.6 KiB
Python
195 lines
7.6 KiB
Python
#!/usr/bin/env python3
|
|
#
|
|
# Copyright (C) 2021 The Android Open Source Project
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
# you may not use this file except in compliance with the License.
|
|
# You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
# See the License for the specific language governing permissions and
|
|
# limitations under the License.
|
|
|
|
import os
|
|
|
|
from simpleperf_utils import remove
|
|
from . app_test import TestExampleBase
|
|
from . test_utils import INFERNO_SCRIPT, TestHelper
|
|
|
|
|
|
class TestExampleCpp(TestExampleBase):
|
|
@classmethod
|
|
def setUpClass(cls):
|
|
cls.prepare("SimpleperfExampleCpp", "simpleperf.example.cpp", ".MainActivity")
|
|
|
|
def test_app_profiler(self):
|
|
self.common_test_app_profiler()
|
|
|
|
def test_app_profiler_profile_from_launch(self):
|
|
self.run_app_profiler(start_activity=True, build_binary_cache=False)
|
|
self.run_cmd(["report.py", "-g", "-o", "report.txt"])
|
|
self.check_strings_in_file("report.txt", ["BusyLoopThread", "__start_thread"])
|
|
|
|
def test_report(self):
|
|
self.common_test_report()
|
|
self.run_cmd(["report.py", "-g", "-o", "report.txt"])
|
|
self.check_strings_in_file("report.txt", ["BusyLoopThread", "__start_thread"])
|
|
|
|
def test_annotate(self):
|
|
self.common_test_annotate()
|
|
self.check_file_under_dir("annotated_files", "native-lib.cpp")
|
|
summary_file = os.path.join("annotated_files", "summary")
|
|
self.check_annotation_summary(summary_file, [
|
|
("native-lib.cpp", 20, 0),
|
|
("BusyLoopThread", 20, 0),
|
|
("line 43", 20, 0)])
|
|
|
|
def test_report_sample(self):
|
|
self.common_test_report_sample(
|
|
["BusyLoopThread",
|
|
"__start_thread"])
|
|
|
|
def test_pprof_proto_generator(self):
|
|
check_strings_with_lines = [
|
|
"native-lib.cpp",
|
|
"BusyLoopThread",
|
|
# Check if dso name in perf.data is replaced by binary path in binary_cache.
|
|
'filename: binary_cache']
|
|
self.common_test_pprof_proto_generator(
|
|
check_strings_with_lines,
|
|
check_strings_without_lines=["BusyLoopThread"])
|
|
|
|
def test_inferno(self):
|
|
self.common_test_inferno()
|
|
self.run_app_profiler()
|
|
self.run_cmd([INFERNO_SCRIPT, "-sc"])
|
|
self.check_inferno_report_html([('BusyLoopThread', 20)])
|
|
|
|
def test_report_html(self):
|
|
self.common_test_report_html()
|
|
self.run_cmd(['report_html.py', '--add_source_code', '--source_dirs', 'testdata',
|
|
'--add_disassembly', '--binary_filter', "libnative-lib.so"])
|
|
|
|
|
|
class TestExampleCppRoot(TestExampleBase):
|
|
@classmethod
|
|
def setUpClass(cls):
|
|
cls.prepare("SimpleperfExampleCpp",
|
|
"simpleperf.example.cpp",
|
|
".MainActivity",
|
|
adb_root=True)
|
|
|
|
def test_app_profiler(self):
|
|
self.common_test_app_profiler()
|
|
|
|
|
|
class TestExampleCppTraceOffCpu(TestExampleBase):
|
|
@classmethod
|
|
def setUpClass(cls):
|
|
cls.prepare("SimpleperfExampleCpp", "simpleperf.example.cpp", ".SleepActivity")
|
|
|
|
def test_smoke(self):
|
|
self.run_app_profiler(record_arg="-g -f 1000 --duration 10 -e cpu-clock:u --trace-offcpu")
|
|
self.run_cmd(["report.py", "-g", "--comms", "SleepThread", "-o", "report.txt"])
|
|
self.check_strings_in_file("report.txt", [
|
|
"SleepThread(void*)",
|
|
"RunFunction()",
|
|
"SleepFunction(unsigned long long)"])
|
|
if (self.adb.get_device_arch() in ['x86', 'x86_64'] and
|
|
TestHelper.get_kernel_version() < (4, 19)):
|
|
# Skip on x86 and kernel < 4.19, which doesn't have patch
|
|
# "perf/x86: Store user space frame-pointer value on a sample" and may fail to unwind
|
|
# system call.
|
|
TestHelper.log('Skip annotation test on x86 for kernel < 4.19.')
|
|
return
|
|
remove("annotated_files")
|
|
self.run_cmd(["annotate.py", "-s", self.example_path, "--comm",
|
|
"SleepThread", '--summary-width', '1000'])
|
|
self.check_exist(dirname="annotated_files")
|
|
self.check_file_under_dir("annotated_files", "native-lib.cpp")
|
|
summary_file = os.path.join("annotated_files", "summary")
|
|
self.check_annotation_summary(summary_file, [
|
|
("native-lib.cpp", 80, 20),
|
|
("SleepThread", 80, 0),
|
|
("RunFunction", 20, 20),
|
|
("SleepFunction", 20, 0),
|
|
("line 70", 20, 0),
|
|
("line 80", 20, 0)])
|
|
self.run_cmd([INFERNO_SCRIPT, "-sc"])
|
|
self.check_inferno_report_html([('SleepThread', 80),
|
|
('RunFunction', 20),
|
|
('SleepFunction', 20)])
|
|
|
|
|
|
class TestExampleCppJniCall(TestExampleBase):
|
|
@classmethod
|
|
def setUpClass(cls):
|
|
cls.prepare("SimpleperfExampleCpp", "simpleperf.example.cpp", ".MixActivity")
|
|
|
|
def test_smoke(self):
|
|
if self.adb.get_android_version() == 8:
|
|
TestHelper.log(
|
|
"Android O needs wrap.sh to use compiled java code. But cpp example doesn't use wrap.sh.")
|
|
return
|
|
self.run_app_profiler()
|
|
self.run_cmd(["report.py", "-g", "--comms", "BusyThread", "-o", "report.txt"])
|
|
self.check_strings_in_file("report.txt", [
|
|
"simpleperf.example.cpp.MixActivity$1.run",
|
|
"Java_simpleperf_example_cpp_MixActivity_callFunction"])
|
|
remove("annotated_files")
|
|
self.run_cmd(["annotate.py", "-s", self.example_path, "--comm",
|
|
"BusyThread", '--summary-width', '1000'])
|
|
self.check_exist(dirname="annotated_files")
|
|
self.check_file_under_dir("annotated_files", "native-lib.cpp")
|
|
summary_file = os.path.join("annotated_files", "summary")
|
|
self.check_annotation_summary(summary_file, [("native-lib.cpp", 5, 0), ("line 37", 5, 0)])
|
|
if self.use_compiled_java_code:
|
|
self.check_file_under_dir("annotated_files", "MixActivity.java")
|
|
self.check_annotation_summary(summary_file, [
|
|
("MixActivity.java", 80, 0),
|
|
("run", 80, 0),
|
|
("line 27", 20, 0),
|
|
("native-lib.cpp", 5, 0),
|
|
("line 37", 5, 0)])
|
|
|
|
self.run_cmd([INFERNO_SCRIPT, "-sc"])
|
|
|
|
|
|
class TestExampleCppForce32Bit(TestExampleCpp):
|
|
@classmethod
|
|
def setUpClass(cls):
|
|
cls.prepare("SimpleperfExampleCpp",
|
|
"simpleperf.example.cpp",
|
|
".MainActivity",
|
|
abi=TestHelper.get_32bit_abi())
|
|
|
|
|
|
class TestExampleCppRootForce32Bit(TestExampleCppRoot):
|
|
@classmethod
|
|
def setUpClass(cls):
|
|
cls.prepare("SimpleperfExampleCpp",
|
|
"simpleperf.example.cpp",
|
|
".MainActivity",
|
|
abi=TestHelper.get_32bit_abi(),
|
|
adb_root=False)
|
|
|
|
|
|
class TestExampleCppTraceOffCpuForce32Bit(TestExampleCppTraceOffCpu):
|
|
@classmethod
|
|
def setUpClass(cls):
|
|
cls.prepare("SimpleperfExampleCpp",
|
|
"simpleperf.example.cpp",
|
|
".SleepActivity",
|
|
abi=TestHelper.get_32bit_abi())
|
|
|
|
def test_smoke(self):
|
|
if (self.adb.get_device_arch() in ['x86', 'x86_64'] and
|
|
self.adb.get_android_version() in [10, 11]):
|
|
TestHelper.log("Skip test on x86. Because simpleperf can't unwind 32bit vdso.")
|
|
return
|
|
super().test_smoke()
|