You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
219 lines
9.3 KiB
219 lines
9.3 KiB
#!/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
|
|
import signal
|
|
import subprocess
|
|
import sys
|
|
import time
|
|
|
|
from simpleperf_utils import is_windows, remove
|
|
from . app_test import TestExampleBase
|
|
from . test_utils import TestHelper, INFERNO_SCRIPT
|
|
|
|
|
|
class TestExamplePureJava(TestExampleBase):
|
|
@classmethod
|
|
def setUpClass(cls):
|
|
cls.prepare("SimpleperfExamplePureJava",
|
|
"com.example.simpleperf.simpleperfexamplepurejava",
|
|
".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", [
|
|
"com.example.simpleperf.simpleperfexamplepurejava.MainActivity$1.run",
|
|
"__start_thread"])
|
|
|
|
def test_app_profiler_multiprocesses(self):
|
|
self.adb.check_run(['shell', 'am', 'force-stop', self.package_name])
|
|
self.adb.check_run(['shell', 'am', 'start', '-n',
|
|
self.package_name + '/.MultiProcessActivity'])
|
|
# Wait until both MultiProcessActivity and MultiProcessService set up.
|
|
time.sleep(3)
|
|
self.run_app_profiler(start_activity=False)
|
|
self.run_cmd(["report.py", "-o", "report.txt"])
|
|
self.check_strings_in_file("report.txt", ["BusyService", "BusyThread"])
|
|
|
|
def test_app_profiler_with_ctrl_c(self):
|
|
if is_windows():
|
|
return
|
|
self.adb.check_run(['shell', 'am', 'start', '-n', self.package_name + '/.MainActivity'])
|
|
time.sleep(1)
|
|
args = [sys.executable, TestHelper.script_path("app_profiler.py"),
|
|
"--app", self.package_name, "-r", "--duration 10000", "--disable_adb_root"]
|
|
subproc = subprocess.Popen(args)
|
|
time.sleep(3)
|
|
|
|
subproc.send_signal(signal.SIGINT)
|
|
subproc.wait()
|
|
self.assertEqual(subproc.returncode, 0)
|
|
self.run_cmd(["report.py"])
|
|
|
|
def test_app_profiler_stop_after_app_exit(self):
|
|
self.adb.check_run(['shell', 'am', 'start', '-n', self.package_name + '/.MainActivity'])
|
|
time.sleep(1)
|
|
subproc = subprocess.Popen(
|
|
[sys.executable, TestHelper.script_path('app_profiler.py'),
|
|
'--app', self.package_name, '-r', '--duration 10000', '--disable_adb_root'])
|
|
time.sleep(3)
|
|
self.adb.check_run(['shell', 'am', 'force-stop', self.package_name])
|
|
subproc.wait()
|
|
self.assertEqual(subproc.returncode, 0)
|
|
self.run_cmd(["report.py"])
|
|
|
|
def test_app_profiler_with_ndk_path(self):
|
|
# Although we pass an invalid ndk path, it should be able to find tools in default ndk path.
|
|
self.run_cmd(['app_profiler.py', '--app', self.package_name, '-a', self.activity_name,
|
|
'--ndk_path', '.'])
|
|
|
|
def test_report(self):
|
|
self.common_test_report()
|
|
self.run_cmd(["report.py", "-g", "-o", "report.txt"])
|
|
self.check_strings_in_file("report.txt", [
|
|
"com.example.simpleperf.simpleperfexamplepurejava.MainActivity$1.run",
|
|
"__start_thread"])
|
|
|
|
def test_profile_with_process_id(self):
|
|
self.adb.check_run(['shell', 'am', 'start', '-n', self.package_name + '/.MainActivity'])
|
|
time.sleep(1)
|
|
pid = self.adb.check_run_and_return_output([
|
|
'shell', 'pidof', 'com.example.simpleperf.simpleperfexamplepurejava']).strip()
|
|
self.run_app_profiler(start_activity=False, record_arg='-g --duration 10 -p ' + pid)
|
|
self.run_cmd(["report.py", "-g", "-o", "report.txt"])
|
|
self.check_strings_in_file("report.txt", [
|
|
"com.example.simpleperf.simpleperfexamplepurejava.MainActivity$1.run",
|
|
"__start_thread"])
|
|
|
|
def test_annotate(self):
|
|
self.common_test_annotate()
|
|
if not self.use_compiled_java_code:
|
|
# Currently annotating Java code is only supported when the Java code is compiled.
|
|
return
|
|
self.check_file_under_dir("annotated_files", "MainActivity.java")
|
|
summary_file = os.path.join("annotated_files", "summary")
|
|
self.check_annotation_summary(summary_file, [
|
|
("MainActivity.java", 80, 80),
|
|
("run", 80, 0),
|
|
("callFunction", 0, 0),
|
|
("line 23", 80, 0)])
|
|
|
|
def test_report_sample(self):
|
|
self.common_test_report_sample(
|
|
["com.example.simpleperf.simpleperfexamplepurejava.MainActivity$1.run",
|
|
"__start_thread"])
|
|
|
|
def test_pprof_proto_generator(self):
|
|
check_strings_with_lines = []
|
|
if self.use_compiled_java_code:
|
|
check_strings_with_lines = [
|
|
"com/example/simpleperf/simpleperfexamplepurejava/MainActivity.java",
|
|
"run"]
|
|
self.common_test_pprof_proto_generator(
|
|
check_strings_with_lines=check_strings_with_lines,
|
|
check_strings_without_lines=[
|
|
"com.example.simpleperf.simpleperfexamplepurejava.MainActivity$1.run"])
|
|
|
|
def test_inferno(self):
|
|
self.common_test_inferno()
|
|
self.run_app_profiler()
|
|
self.run_cmd([INFERNO_SCRIPT, "-sc"])
|
|
self.check_inferno_report_html(
|
|
[('com.example.simpleperf.simpleperfexamplepurejava.MainActivity$1.run', 80)])
|
|
self.run_cmd([INFERNO_SCRIPT, "-sc", "-o", "report2.html"])
|
|
self.check_inferno_report_html(
|
|
[('com.example.simpleperf.simpleperfexamplepurejava.MainActivity$1.run', 80)],
|
|
"report2.html")
|
|
|
|
def test_inferno_in_another_dir(self):
|
|
test_dir = 'inferno_testdir'
|
|
os.mkdir(test_dir)
|
|
os.chdir(test_dir)
|
|
self.run_cmd(['app_profiler.py', '--app', self.package_name,
|
|
'-r', '-e task-clock:u -g --duration 3'])
|
|
self.check_exist(filename="perf.data")
|
|
self.run_cmd([INFERNO_SCRIPT, "-sc"])
|
|
|
|
def test_report_html(self):
|
|
self.common_test_report_html()
|
|
|
|
def test_run_simpleperf_without_usb_connection(self):
|
|
self.adb.check_run(['shell', 'am', 'start', '-n', self.package_name + '/.MainActivity'])
|
|
self.run_cmd(['run_simpleperf_without_usb_connection.py', 'start', '-p',
|
|
self.package_name, '--size_limit', '1M'])
|
|
self.adb.check_run(['kill-server'])
|
|
time.sleep(3)
|
|
# Start adb process outside self.test_dir. Because it will be removed after testing.
|
|
os.chdir(self.test_dir.parent)
|
|
self.adb.check_run(['devices'])
|
|
os.chdir(self.test_dir)
|
|
self.run_cmd(['run_simpleperf_without_usb_connection.py', 'stop'])
|
|
self.check_exist(filename="perf.data")
|
|
self.run_cmd(["report.py", "-g", "-o", "report.txt"])
|
|
|
|
|
|
class TestExamplePureJavaRoot(TestExampleBase):
|
|
@classmethod
|
|
def setUpClass(cls):
|
|
cls.prepare("SimpleperfExamplePureJava",
|
|
"com.example.simpleperf.simpleperfexamplepurejava",
|
|
".MainActivity",
|
|
adb_root=True)
|
|
|
|
def test_app_profiler(self):
|
|
self.common_test_app_profiler()
|
|
|
|
|
|
class TestExamplePureJavaTraceOffCpu(TestExampleBase):
|
|
@classmethod
|
|
def setUpClass(cls):
|
|
cls.prepare("SimpleperfExamplePureJava",
|
|
"com.example.simpleperf.simpleperfexamplepurejava",
|
|
".SleepActivity")
|
|
|
|
def test_smoke(self):
|
|
self.run_app_profiler(record_arg="-g -f 1000 --duration 10 -e cpu-cycles:u --trace-offcpu")
|
|
self.run_cmd(["report.py", "-g", "-o", "report.txt"])
|
|
self.check_strings_in_file("report.txt", [
|
|
"com.example.simpleperf.simpleperfexamplepurejava.SleepActivity$1.run",
|
|
"com.example.simpleperf.simpleperfexamplepurejava.SleepActivity$1.RunFunction",
|
|
"com.example.simpleperf.simpleperfexamplepurejava.SleepActivity$1.SleepFunction"
|
|
])
|
|
remove("annotated_files")
|
|
self.run_cmd(["annotate.py", "-s", self.example_path])
|
|
self.check_exist(dirname="annotated_files")
|
|
if self.use_compiled_java_code:
|
|
self.check_file_under_dir("annotated_files", "SleepActivity.java")
|
|
summary_file = os.path.join("annotated_files", "summary")
|
|
self.check_annotation_summary(summary_file, [
|
|
("SleepActivity.java", 80, 20),
|
|
("run", 80, 0),
|
|
("RunFunction", 20, 20),
|
|
("SleepFunction", 20, 0),
|
|
("line 24", 1, 0),
|
|
("line 32", 20, 0)])
|
|
self.run_cmd([INFERNO_SCRIPT, "-sc"])
|
|
self.check_inferno_report_html(
|
|
[('com.example.simpleperf.simpleperfexamplepurejava.SleepActivity$1.run', 80),
|
|
('com.example.simpleperf.simpleperfexamplepurejava.SleepActivity$1.RunFunction',
|
|
20),
|
|
('com.example.simpleperf.simpleperfexamplepurejava.SleepActivity$1.SleepFunction',
|
|
20)])
|