| # Copyright (c) 2013 The Chromium OS 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 logging |
| import os |
| import StringIO |
| |
| import common |
| from autotest_lib.client.common_lib import error |
| from autotest_lib.server import test |
| from autotest_lib.server import utils |
| from autotest_lib.server.cros import telemetry_runner |
| |
| |
| TELEMETRY_TIMEOUT_MINS = 60 |
| CHROME_SRC_ROOT = '/var/cache/chromeos-cache/distfiles/target/' |
| CLIENT_CHROME_ROOT = '/usr/local/telemetry/src' |
| RUN_BENCHMARK = 'tools/perf/run_benchmark' |
| |
| |
| def _find_chrome_root_dir(): |
| # Look for chrome source root, either externally mounted, or inside |
| # the chroot. Prefer chrome-src-internal source tree to chrome-src. |
| sources_list = ('chrome-src-internal', 'chrome-src') |
| |
| dir_list = [os.path.join(CHROME_SRC_ROOT, x) for x in sources_list] |
| if 'CHROME_ROOT' in os.environ: |
| dir_list.insert(0, os.environ['CHROME_ROOT']) |
| |
| for dir in dir_list: |
| if os.path.exists(dir): |
| chrome_root_dir = dir |
| break |
| else: |
| raise error.TestError('Chrome source directory not found.') |
| |
| logging.info('Using Chrome source tree at %s', chrome_root_dir) |
| return os.path.join(chrome_root_dir, 'src') |
| |
| |
| def _ensure_deps(dut, test_name): |
| """ |
| Ensure the dependencies are locally available on DUT. |
| |
| @param dut: The autotest host object representing DUT. |
| @param test_name: Name of the telemetry test. |
| """ |
| # Get DEPs using host's telemetry. |
| chrome_root_dir = _find_chrome_root_dir() |
| format_string = ('python %s/tools/perf/fetch_benchmark_deps.py %s') |
| command = format_string % (chrome_root_dir, test_name) |
| logging.info('Getting DEPs: %s', command) |
| stdout = StringIO.StringIO() |
| stderr = StringIO.StringIO() |
| try: |
| result = utils.run(command, stdout_tee=stdout, |
| stderr_tee=stderr) |
| except error.CmdError as e: |
| logging.debug('Error occurred getting DEPs: %s\n %s\n', |
| stdout.getvalue(), stderr.getvalue()) |
| raise error.TestFail('Error occurred while getting DEPs.') |
| |
| # Download DEPs to DUT. |
| # send_file() relies on rsync over ssh. Couldn't be better. |
| stdout_str = stdout.getvalue() |
| stdout.close() |
| stderr.close() |
| for dep in stdout_str.split(): |
| src = os.path.join(chrome_root_dir, dep) |
| dst = os.path.join(CLIENT_CHROME_ROOT, dep) |
| if not os.path.isfile(src): |
| raise error.TestFail('Error occurred while saving DEPs.') |
| logging.info('Copying: %s -> %s', src, dst) |
| try: |
| dut.send_file(src, dst) |
| except: |
| raise error.TestFail('Error occurred while sending DEPs to dut.\n') |
| |
| |
| class telemetry_Crosperf(test.test): |
| """Run one or more telemetry benchmarks under the crosperf script.""" |
| version = 1 |
| |
| def run_once(self, args, client_ip='', dut=None): |
| """ |
| Run a single telemetry test. |
| |
| @param args: A dictionary of the arguments that were passed |
| to this test. |
| @param client_ip: The ip address of the DUT |
| @param dut: The autotest host object representing DUT. |
| |
| @returns A TelemetryResult instance with the results of this execution. |
| """ |
| test_name = args['test'] |
| test_args = '' |
| if 'test_args' in args: |
| test_args = args['test_args'] |
| |
| # Decide whether the test will run locally or by a remote server. |
| if 'run_local' in args and args['run_local'].lower() == 'true': |
| # The telemetry scripts will run on DUT. |
| _ensure_deps(dut, test_name) |
| format_string = ('python %s --browser=system %s %s') |
| command = format_string % (os.path.join(CLIENT_CHROME_ROOT, |
| RUN_BENCHMARK), |
| test_args, test_name) |
| runner = dut |
| else: |
| # The telemetry scripts will run on server. |
| format_string = ('python %s --browser=cros-chrome --remote=%s ' |
| '%s %s') |
| command = format_string % (os.path.join(_find_chrome_root_dir(), |
| RUN_BENCHMARK), |
| client_ip, test_args, test_name) |
| runner = utils |
| |
| # Run the test. |
| stdout = StringIO.StringIO() |
| stderr = StringIO.StringIO() |
| try: |
| logging.info('CMD: %s', command) |
| result = runner.run(command, stdout_tee=stdout, stderr_tee=stderr, |
| timeout=TELEMETRY_TIMEOUT_MINS*60) |
| exit_code = result.exit_status |
| except error.CmdError as e: |
| logging.debug('Error occurred executing telemetry.') |
| exit_code = e.result_obj.exit_status |
| raise error.TestFail('An error occurred while executing ' |
| 'telemetry test.') |
| finally: |
| stdout_str = stdout.getvalue() |
| stderr_str = stderr.getvalue() |
| stdout.close() |
| stderr.close() |
| |
| |
| # Parse the result. |
| logging.debug('Telemetry completed with exit code: %d.' |
| '\nstdout:%s\nstderr:%s', exit_code, |
| stdout_str, stderr_str) |
| logging.info('Telemetry completed with exit code: %d.' |
| '\nstdout:%s\nstderr:%s', exit_code, |
| stdout_str, stderr_str) |
| |
| result = telemetry_runner.TelemetryResult(exit_code=exit_code, |
| stdout=stdout_str, |
| stderr=stderr_str) |
| |
| result.parse_benchmark_results() |
| for data in result.perf_data: |
| self.output_perf_value(description=data['trace'], |
| value=data['value'], |
| units=data['units'], |
| graph=data['graph']) |
| |
| return result |