| Index: tools/telemetry/telemetry/core/platform/profiler/android_profiling_helper_unittest.py
|
| diff --git a/tools/telemetry/telemetry/core/platform/profiler/android_profiling_helper_unittest.py b/tools/telemetry/telemetry/core/platform/profiler/android_profiling_helper_unittest.py
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..497ffa9414265ebfaabc6249665a89821de1b467
|
| --- /dev/null
|
| +++ b/tools/telemetry/telemetry/core/platform/profiler/android_profiling_helper_unittest.py
|
| @@ -0,0 +1,91 @@
|
| +# Copyright 2014 The Chromium Authors. All rights reserved.
|
| +# Use of this source code is governed by a BSD-style license that can be
|
| +# found in the LICENSE file.
|
| +import glob
|
| +import logging
|
| +import os
|
| +import re
|
| +import shutil
|
| +import tempfile
|
| +
|
| +from telemetry.core import util
|
| +from telemetry.core.platform.profiler import android_profiling_helper
|
| +from telemetry.unittest import options_for_unittests
|
| +from telemetry.unittest import simple_mock
|
| +from telemetry.unittest import tab_test_case
|
| +
|
| +
|
| +def _GetLibrariesMappedIntoProcesses(device, pids):
|
| + libs = set()
|
| + for pid in pids:
|
| + maps_file = '/proc/%d/maps' % pid
|
| + maps = device.old_interface.GetProtectedFileContents(maps_file)
|
| + for map_line in maps:
|
| + lib = re.match(r'.*\s(/.*[.]so)$', map_line)
|
| + if lib:
|
| + libs.add(lib.group(1))
|
| + return libs
|
| +
|
| +
|
| +class TestAndroidProfilingHelper(tab_test_case.TabTestCase):
|
| + def setUp(self):
|
| + super(TestAndroidProfilingHelper, self).setUp()
|
| +
|
| + def testGetRequiredLibrariesForPerfProfile(self):
|
| + perf_output = os.path.join(
|
| + util.GetUnittestDataDir(), 'sample_perf_report_output.txt')
|
| + with open(perf_output) as f:
|
| + perf_output = f.read()
|
| +
|
| + mock_popen = simple_mock.MockObject()
|
| + mock_popen.ExpectCall('communicate').WillReturn([None, perf_output])
|
| +
|
| + mock_subprocess = simple_mock.MockObject()
|
| + mock_subprocess.ExpectCall(
|
| + 'Popen').WithArgs(simple_mock.DONT_CARE).WillReturn(mock_popen)
|
| + mock_subprocess.SetAttribute('PIPE', simple_mock.MockObject())
|
| +
|
| + real_subprocess = android_profiling_helper.subprocess
|
| + android_profiling_helper.subprocess = mock_subprocess
|
| + try:
|
| + libs = android_profiling_helper.GetRequiredLibrariesForPerfProfile('foo')
|
| + self.assertEqual(libs, set([
|
| + '/data/app-lib/com.google.android.apps.chrome-2/libchrome.2016.0.so',
|
| + '/system/lib/libart.so',
|
| + '/system/lib/libc.so',
|
| + '/system/lib/libm.so']))
|
| + finally:
|
| + android_profiling_helper.subprocess = real_subprocess
|
| +
|
| + def testCreateSymFs(self):
|
| + options = options_for_unittests.GetCopy()
|
| + if not options.browser_type.startswith('android'):
|
| + logging.warning('AndroidProfilingHelper only works on Android. Skipping.')
|
| + return
|
| +
|
| + # pylint: disable=W0212
|
| + browser_backend = self._browser._browser_backend
|
| + pids = ([browser_backend.pid] +
|
| + self._browser._platform_backend.GetChildPids(browser_backend.pid))
|
| + device = browser_backend.adb.device()
|
| + libs = _GetLibrariesMappedIntoProcesses(device, pids)
|
| + assert libs
|
| +
|
| + symfs_dir = tempfile.mkdtemp()
|
| + try:
|
| + kallsyms = android_profiling_helper.CreateSymFs(device, symfs_dir, libs)
|
| +
|
| + # Make sure we found at least one unstripped library.
|
| + unstripped_libs = glob.glob(os.path.join(symfs_dir,
|
| + 'data', 'app-lib', '*', '*.so'))
|
| + assert unstripped_libs
|
| +
|
| + # Check that we have kernel symbols.
|
| + assert os.path.exists(kallsyms)
|
| +
|
| + # Check that all requested libraries are present.
|
| + for lib in libs:
|
| + assert os.path.exists(os.path.join(symfs_dir, lib[1:])), \
|
| + '%s not found in symfs' % lib
|
| + finally:
|
| + shutil.rmtree(symfs_dir)
|
|
|