Home | History | Annotate | Download | only in telemetry_Crosperf
      1 # Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
      2 # Use of this source code is governed by a BSD-style license that can be
      3 # found in the LICENSE file.
      4 import logging
      5 import os
      6 import StringIO
      7 
      8 import common
      9 from autotest_lib.client.common_lib import error
     10 from autotest_lib.server import test
     11 from autotest_lib.server import utils
     12 from autotest_lib.server.cros import telemetry_runner
     13 
     14 
     15 TELEMETRY_TIMEOUT_MINS = 60
     16 CHROME_SRC_ROOT = '/var/cache/chromeos-cache/distfiles/target/'
     17 CLIENT_CHROME_ROOT = '/usr/local/telemetry/src'
     18 RUN_BENCHMARK  = 'tools/perf/run_benchmark'
     19 
     20 
     21 def _find_chrome_root_dir():
     22     # Look for chrome source root, either externally mounted, or inside
     23     # the chroot.  Prefer chrome-src-internal source tree to chrome-src.
     24     sources_list = ('chrome-src-internal', 'chrome-src')
     25 
     26     dir_list = [os.path.join(CHROME_SRC_ROOT, x) for x in sources_list]
     27     if 'CHROME_ROOT' in os.environ:
     28         dir_list.insert(0, os.environ['CHROME_ROOT'])
     29 
     30     for dir in dir_list:
     31         if os.path.exists(dir):
     32             chrome_root_dir = dir
     33             break
     34     else:
     35         raise error.TestError('Chrome source directory not found.')
     36 
     37     logging.info('Using Chrome source tree at %s', chrome_root_dir)
     38     return os.path.join(chrome_root_dir, 'src')
     39 
     40 
     41 def _ensure_deps(dut, test_name):
     42     """
     43     Ensure the dependencies are locally available on DUT.
     44 
     45     @param dut: The autotest host object representing DUT.
     46     @param test_name: Name of the telemetry test.
     47     """
     48     # Get DEPs using host's telemetry.
     49     chrome_root_dir = _find_chrome_root_dir()
     50     format_string = ('python %s/tools/perf/fetch_benchmark_deps.py %s')
     51     command = format_string % (chrome_root_dir, test_name)
     52     logging.info('Getting DEPs: %s', command)
     53     stdout = StringIO.StringIO()
     54     stderr = StringIO.StringIO()
     55     try:
     56         result = utils.run(command, stdout_tee=stdout,
     57                            stderr_tee=stderr)
     58     except error.CmdError as e:
     59         logging.debug('Error occurred getting DEPs: %s\n %s\n',
     60                       stdout.getvalue(), stderr.getvalue())
     61         raise error.TestFail('Error occurred while getting DEPs.')
     62 
     63     # Download DEPs to DUT.
     64     # send_file() relies on rsync over ssh. Couldn't be better.
     65     stdout_str = stdout.getvalue()
     66     stdout.close()
     67     stderr.close()
     68     for dep in stdout_str.split():
     69         src = os.path.join(chrome_root_dir, dep)
     70         dst = os.path.join(CLIENT_CHROME_ROOT, dep)
     71         if not os.path.isfile(src):
     72             raise error.TestFail('Error occurred while saving DEPs.')
     73         logging.info('Copying: %s -> %s', src, dst)
     74         try:
     75             dut.send_file(src, dst)
     76         except:
     77             raise error.TestFail('Error occurred while sending DEPs to dut.\n')
     78 
     79 
     80 class telemetry_Crosperf(test.test):
     81     """Run one or more telemetry benchmarks under the crosperf script."""
     82     version = 1
     83 
     84     def run_once(self, args, client_ip='', dut=None):
     85         """
     86         Run a single telemetry test.
     87 
     88         @param args: A dictionary of the arguments that were passed
     89                 to this test.
     90         @param client_ip: The ip address of the DUT
     91         @param dut: The autotest host object representing DUT.
     92 
     93         @returns A TelemetryResult instance with the results of this execution.
     94         """
     95         test_name = args['test']
     96         test_args = ''
     97         if 'test_args' in args:
     98             test_args = args['test_args']
     99 
    100         # Decide whether the test will run locally or by a remote server.
    101         if 'run_local' in args and args['run_local'].lower() == 'true':
    102             # The telemetry scripts will run on DUT.
    103             _ensure_deps(dut, test_name)
    104             format_string = ('python %s --browser=system %s %s')
    105             command = format_string % (os.path.join(CLIENT_CHROME_ROOT,
    106                                                     RUN_BENCHMARK),
    107                                        test_args, test_name)
    108             runner = dut
    109         else:
    110             # The telemetry scripts will run on server.
    111             format_string = ('python %s --browser=cros-chrome --remote=%s '
    112                              '%s %s')
    113             command = format_string % (os.path.join(_find_chrome_root_dir(),
    114                                                     RUN_BENCHMARK),
    115                                        client_ip, test_args, test_name)
    116             runner = utils
    117 
    118         # Run the test.
    119         stdout = StringIO.StringIO()
    120         stderr = StringIO.StringIO()
    121         try:
    122             logging.info('CMD: %s', command)
    123             result = runner.run(command, stdout_tee=stdout, stderr_tee=stderr,
    124                                 timeout=TELEMETRY_TIMEOUT_MINS*60)
    125             exit_code = result.exit_status
    126         except error.CmdError as e:
    127             logging.debug('Error occurred executing telemetry.')
    128             exit_code = e.result_obj.exit_status
    129             raise error.TestFail('An error occurred while executing '
    130                                  'telemetry test.')
    131         finally:
    132             stdout_str = stdout.getvalue()
    133             stderr_str = stderr.getvalue()
    134             stdout.close()
    135             stderr.close()
    136 
    137 
    138         # Parse the result.
    139         logging.debug('Telemetry completed with exit code: %d.'
    140                       '\nstdout:%s\nstderr:%s', exit_code,
    141                       stdout_str, stderr_str)
    142         logging.info('Telemetry completed with exit code: %d.'
    143                      '\nstdout:%s\nstderr:%s', exit_code,
    144                      stdout_str, stderr_str)
    145 
    146         result = telemetry_runner.TelemetryResult(exit_code=exit_code,
    147                                                   stdout=stdout_str,
    148                                                   stderr=stderr_str)
    149 
    150         result.parse_benchmark_results()
    151         for data in result.perf_data:
    152             self.output_perf_value(description=data['trace'],
    153                                    value=data['value'],
    154                                    units=data['units'],
    155                                    graph=data['graph'])
    156 
    157         return result
    158