summaryrefslogtreecommitdiff
path: root/simpleperf/runtest
diff options
context:
space:
mode:
authorYabin Cui <yabinc@google.com>2017-02-10 12:07:29 -0800
committerYabin Cui <yabinc@google.com>2017-02-10 16:40:06 -0800
commitb92bae84b27889b548214bee8d0730ef10da0c6d (patch)
tree7b21c155090f7f39d1533732d7903d63f5a1b497 /simpleperf/runtest
parent264b69316cd385d887a2c7beb289eea5b0a9f05d (diff)
downloadextras-b92bae84b27889b548214bee8d0730ef10da0c6d.tar.gz
simpleperf: build libsimpleperf_inplace_sampler library.
libsimpleperf_inplace_sampler.so is a library linked with user's app. It opens a unix socket server and waits for simpleperf's profiling request. This patch doesn't contain code generating real samples, instead it uses a fake sample for testing. Add runtest for 32bit. Increase runtest duration to 2 seconds and adjust some args in runtest.conf to make test result stable. Fix one tiny error in cmd_report.cpp to report correctly in `report --sort comm,symbol`. Bug: http://b/30974760 Test: run simpleperf_unit_test. Test: run runtest.py. Change-Id: I58163fe47f62e6ba7dd684b33a2ce302feb880f5
Diffstat (limited to 'simpleperf/runtest')
-rw-r--r--simpleperf/runtest/Android.build.mk8
-rw-r--r--simpleperf/runtest/runtest.conf7
-rw-r--r--simpleperf/runtest/runtest.py107
3 files changed, 39 insertions, 83 deletions
diff --git a/simpleperf/runtest/Android.build.mk b/simpleperf/runtest/Android.build.mk
index 8520765e..5a8f92d8 100644
--- a/simpleperf/runtest/Android.build.mk
+++ b/simpleperf/runtest/Android.build.mk
@@ -22,7 +22,11 @@ include $(CLEAR_VARS)
LOCAL_CLANG := true
LOCAL_CPPFLAGS := $(simpleperf_runtest_cppflags)
LOCAL_SRC_FILES := $(module_src_files)
+LOCAL_SHARED_LIBRARIES := libsimpleperf_inplace_sampler
LOCAL_MODULE := $(module)
+LOCAL_MULTILIB := both
+LOCAL_MODULE_STEM_32 := $(module)32
+LOCAL_MODULE_STEM_64 := $(module)64
LOCAL_STRIP_MODULE := false
LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.build.mk
include $(BUILD_EXECUTABLE)
@@ -32,7 +36,11 @@ include $(CLEAR_VARS)
LOCAL_CLANG := true
LOCAL_CPPFLAGS := $(simpleperf_runtest_cppflags)
LOCAL_SRC_FILES := $(module_src_files)
+LOCAL_SHARED_LIBRARIES := libsimpleperf_inplace_sampler
LOCAL_MODULE := $(module)
+LOCAL_MULTILIB := both
+LOCAL_MODULE_STEM_32 := $(module)32
+LOCAL_MODULE_STEM_64 := $(module)64
LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.build.mk
include $(BUILD_HOST_EXECUTABLE)
endif \ No newline at end of file
diff --git a/simpleperf/runtest/runtest.conf b/simpleperf/runtest/runtest.conf
index 863ea996..2fbbd985 100644
--- a/simpleperf/runtest/runtest.conf
+++ b/simpleperf/runtest/runtest.conf
@@ -41,6 +41,7 @@
<test name="function_fork">
<executable name="simpleperf_runtest_function_fork"/>
+ <report option="--sort comm,symbol"/>
<symbol_overhead>
<symbol name="ParentFunction()" min="10" max="90"/>
@@ -48,7 +49,7 @@
</symbol_overhead>
<symbol_children_overhead>
- <symbol name="main" min="10" max="90"/>
+ <symbol name="main" min="10"/>
</symbol_children_overhead>
<symbol_callgraph_relation>
@@ -156,8 +157,8 @@
<executable name="simpleperf_runtest_function_indirect_recursive"/>
<symbol_overhead>
- <symbol name="FunctionRecursiveOne(int)" min="30" max="70"/>
- <symbol name="FunctionRecursiveTwo(int)" min="30" max="70"/>
+ <symbol name="FunctionRecursiveOne(int)" min="20"/>
+ <symbol name="FunctionRecursiveTwo(int)" min="20"/>
</symbol_overhead>
<symbol_children_overhead>
diff --git a/simpleperf/runtest/runtest.py b/simpleperf/runtest/runtest.py
index 77fc5669..a1b4520b 100644
--- a/simpleperf/runtest/runtest.py
+++ b/simpleperf/runtest/runtest.py
@@ -279,18 +279,20 @@ class Runner(object):
def __init__(self, target, perf_path):
self.target = target
+ self.is32 = target.endswith('32')
self.perf_path = perf_path
self.use_callgraph = False
self.sampler = 'cpu-cycles'
def record(self, test_executable_name, record_file, additional_options=[]):
call_args = [self.perf_path, 'record']
- call_args += ['--duration', '1']
+ call_args += ['--duration', '2']
call_args += ['-e', '%s:u' % self.sampler]
if self.use_callgraph:
call_args += ['-f', '1000', '-g']
call_args += ['-o', record_file]
call_args += additional_options
+ test_executable_name += '32' if self.is32 else '64'
call_args += [test_executable_name]
self._call(call_args)
@@ -310,8 +312,9 @@ class HostRunner(Runner):
"""Run perf test on host."""
- def __init__(self, perf_path):
- super(HostRunner, self).__init__('host', perf_path)
+ def __init__(self, target):
+ perf_path = 'simpleperf32' if target.endswith('32') else 'simpleperf'
+ super(HostRunner, self).__init__(target, perf_path)
def _call(self, args, output_file=None):
output_fh = None
@@ -326,17 +329,21 @@ class DeviceRunner(Runner):
"""Run perf test on device."""
- def __init__(self, perf_path):
+ def __init__(self, target):
self.tmpdir = '/data/local/tmp/'
- super(DeviceRunner, self).__init__('device', self.tmpdir + perf_path)
+ perf_path = 'simpleperf32' if target.endswith('32') else 'simpleperf'
+ super(DeviceRunner, self).__init__(target, self.tmpdir + perf_path)
self._download(os.environ['OUT'] + '/system/xbin/' + perf_path, self.tmpdir)
+ lib = 'lib' if self.is32 else 'lib64'
+ self._download(os.environ['OUT'] + '/system/' + lib + '/libsimpleperf_inplace_sampler.so',
+ self.tmpdir)
def _call(self, args, output_file=None):
output_fh = None
if output_file is not None:
output_fh = open(output_file, 'w')
args_with_adb = ['adb', 'shell']
- args_with_adb.extend(args)
+ args_with_adb.append('export LD_LIBRARY_PATH=' + self.tmpdir + ' && ' + ' '.join(args))
subprocess.check_call(args_with_adb, stdout=output_fh)
if output_fh is not None:
output_fh.close()
@@ -346,8 +353,8 @@ class DeviceRunner(Runner):
subprocess.check_call(args)
def record(self, test_executable_name, record_file, additional_options=[]):
- self._download(os.environ['OUT'] + '/system/bin/' + test_executable_name,
- self.tmpdir)
+ self._download(os.environ['OUT'] + '/system/bin/' + test_executable_name +
+ ('32' if self.is32 else '64'), self.tmpdir)
super(DeviceRunner, self).record(self.tmpdir + test_executable_name,
self.tmpdir + record_file,
additional_options)
@@ -528,75 +535,14 @@ class ReportAnalyzer(object):
return result
-def runtest(host, device, normal, callgraph, use_inplace_sampler, selected_tests):
- tests = load_config_file(os.path.dirname(os.path.realpath(__file__)) + \
- '/runtest.conf')
- host_runner = HostRunner('simpleperf')
- device_runner = DeviceRunner('simpleperf')
- report_analyzer = ReportAnalyzer()
- for test in tests:
- if selected_tests is not None:
- if test.test_name not in selected_tests:
- continue
- if host and normal:
- host_runner.record(test.executable_name, 'perf.data')
- host_runner.report('perf.data', 'perf.report',
- additional_options = test.report_options)
- result = report_analyzer.check_report_file(
- test, 'perf.report', False)
- print 'test %s on host %s' % (
- test.test_name, 'Succeeded' if result else 'Failed')
- if not result:
- exit(1)
-
- if device and normal:
- device_runner.record(test.executable_name, 'perf.data')
- device_runner.report('perf.data', 'perf.report',
- additional_options = test.report_options)
- result = report_analyzer.check_report_file(test, 'perf.report', False)
- print 'test %s on device %s' % (
- test.test_name, 'Succeeded' if result else 'Failed')
- if not result:
- exit(1)
-
- if host and callgraph:
- host_runner.record(
- test.executable_name,
- 'perf_g.data',
- additional_options=['-g', '-f', '1000'])
- host_runner.report(
- 'perf_g.data',
- 'perf_g.report',
- additional_options=['-g', 'callee'] + test.report_options)
- result = report_analyzer.check_report_file(test, 'perf_g.report', True)
- print 'call-graph test %s on host %s' % (
- test.test_name, 'Succeeded' if result else 'Failed')
- if not result:
- exit(1)
-
- if device and callgraph:
- # Decrease sampling frequency by -f 1000 to avoid losing records
- # while recording call-graph.
- device_runner.record(
- test.executable_name,
- 'perf_g.data',
- additional_options=['-g', '-f', '1000'])
- device_runner.report(
- 'perf_g.data',
- 'perf_g.report',
- additional_options=['-g', 'callee'] + test.report_options)
- result = report_analyzer.check_report_file(test, 'perf_g.report', True)
- print 'call-graph test %s on device %s' % (
- test.test_name, 'Succeeded' if result else 'Failed')
- if not result:
- exit(1)
-
-
def build_runner(target, use_callgraph, sampler):
- if target == 'host':
- runner = HostRunner('simpleperf')
+ if target == 'host32' and use_callgraph:
+ print "Current 64bit linux host doesn't support `simpleperf32 record -g`"
+ return None
+ if target.startswith('host'):
+ runner = HostRunner(target)
else:
- runner = DeviceRunner('simpleperf')
+ runner = DeviceRunner(target)
runner.use_callgraph = use_callgraph
runner.sampler = sampler
return runner
@@ -611,7 +557,7 @@ def test_with_runner(runner, tests):
runner.report('perf.data', 'perf.report')
symbols = report_analyzer._read_report_file('perf.report', runner.use_callgraph)
result = False
- if len(symbols) == 1 and symbols[0].name == 'fake_elf[+0]':
+ if len(symbols) == 1 and symbols[0].name.find('FakeFunction()') != -1:
result = True
else:
runner.report('perf.data', 'perf.report', additional_options = test.report_options)
@@ -639,20 +585,21 @@ def runtest(target_options, use_callgraph_options, sampler_options, selected_tes
for use_callgraph in use_callgraph_options:
for sampler in sampler_options:
runner = build_runner(target, use_callgraph, sampler)
- test_with_runner(runner, tests)
+ if runner is not None:
+ test_with_runner(runner, tests)
def main():
- target_options = ['host', 'target']
+ target_options = ['host64', 'host32', 'device64', 'device32']
use_callgraph_options = [False, True]
sampler_options = ['cpu-cycles', 'inplace-sampler']
selected_tests = None
i = 1
while i < len(sys.argv):
if sys.argv[i] == '--host':
- use_callgraph_options = ['host']
+ target_options = ['host64', 'host32']
elif sys.argv[i] == '--device':
- use_callgraph_options = ['device']
+ target_options = ['device64', 'device32']
elif sys.argv[i] == '--normal':
use_callgraph_options = [False]
elif sys.argv[i] == '--callgraph':