# -*- coding: utf-8 -*-
# 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.

"""Module to deal with result cache."""

from __future__ import division
from __future__ import print_function

import collections
import glob
import hashlib
import heapq
import json
import os
import pickle
import re
import tempfile

from cros_utils import command_executer
from cros_utils import misc

from image_checksummer import ImageChecksummer

import results_report
import test_flag

SCRATCH_DIR = os.path.expanduser('~/cros_scratch')
RESULTS_FILE = 'results.pickle'
MACHINE_FILE = 'machine.txt'
AUTOTEST_TARBALL = 'autotest.tbz2'
RESULTS_TARBALL = 'results.tbz2'
PERF_RESULTS_FILE = 'perf-results.txt'
CACHE_KEYS_FILE = 'cache_keys.txt'


class PidVerificationError(Exception):
  """Error of perf PID verification in per-process mode."""


class PerfDataReadError(Exception):
  """Error of reading a perf.data header."""


class Result(object):
  """Class for holding the results of a single test run.

  This class manages what exactly is stored inside the cache without knowing
  what the key of the cache is. For runs with perf, it stores perf.data,
  perf.report, etc. The key generation is handled by the ResultsCache class.
  """

  def __init__(self, logger, label, log_level, machine, cmd_exec=None):
    self.chromeos_root = label.chromeos_root
    self._logger = logger
    self.ce = cmd_exec or command_executer.GetCommandExecuter(
        self._logger, log_level=log_level)
    self.temp_dir = None
    self.label = label
    self.results_dir = None
    self.log_level = log_level
    self.machine = machine
    self.perf_data_files = []
    self.perf_report_files = []
    self.results_file = []
    self.turbostat_log_file = ''
    self.cpustats_log_file = ''
    self.cpuinfo_file = ''
    self.top_log_file = ''
    self.wait_time_log_file = ''
    self.chrome_version = ''
    self.err = None
    self.chroot_results_dir = ''
    self.test_name = ''
    self.keyvals = None
    self.board = None
    self.suite = None
    self.cwp_dso = ''
    self.retval = None
    self.out = None
    self.top_cmds = []

  def GetTopCmds(self):
    """Get the list of top commands consuming CPU on the machine."""
    return self.top_cmds

  def FormatStringTopCommands(self):
    """Get formatted string of top commands.

    Get the formatted string with top commands consuming CPU on DUT machine.
    Number of "non-chrome" processes in the list is limited to 5.
    """
    format_list = [
        'Top commands with highest CPU usage:',
        # Header.
        '%20s %9s %6s   %s' % ('COMMAND', 'AVG CPU%', 'COUNT', 'HIGHEST 5'),
        '-' * 50,
    ]
    if self.top_cmds:
      # After switching to top processes we have to expand the list since there
      # will be a lot of 'chrome' processes (up to 10, sometimes more) in the
      # top.
      # Let's limit the list size by the number of non-chrome processes.
      limit_of_non_chrome_procs = 5
      num_of_non_chrome_procs = 0
      for topcmd in self.top_cmds:
        print_line = '%20s %9.2f %6s   %s' % (
            topcmd['cmd'], topcmd['cpu_use_avg'], topcmd['count'],
            topcmd['top5_cpu_use'])
        format_list.append(print_line)
        if not topcmd['cmd'].startswith('chrome'):
          num_of_non_chrome_procs += 1
          if num_of_non_chrome_procs >= limit_of_non_chrome_procs:
            break
    else:
      format_list.append('[NO DATA FROM THE TOP LOG]')
    format_list.append('-' * 50)
    return '\n'.join(format_list)

  def CopyFilesTo(self, dest_dir, files_to_copy):
    file_index = 0
    for file_to_copy in files_to_copy:
      if not os.path.isdir(dest_dir):
        command = 'mkdir -p %s' % dest_dir
        self.ce.RunCommand(command)
      dest_file = os.path.join(
          dest_dir, ('%s.%s' % (os.path.basename(file_to_copy), file_index)))
      ret = self.ce.CopyFiles(file_to_copy, dest_file, recursive=False)
      if ret:
        raise IOError('Could not copy results file: %s' % file_to_copy)
      file_index += 1

  def CopyResultsTo(self, dest_dir):
    self.CopyFilesTo(dest_dir, self.results_file)
    self.CopyFilesTo(dest_dir, self.perf_data_files)
    self.CopyFilesTo(dest_dir, self.perf_report_files)
    extra_files = []
    if self.top_log_file:
      extra_files.append(self.top_log_file)
    if self.cpuinfo_file:
      extra_files.append(self.cpuinfo_file)
    if extra_files:
      self.CopyFilesTo(dest_dir, extra_files)
    if self.results_file or self.perf_data_files or self.perf_report_files:
      self._logger.LogOutput('Results files stored in %s.' % dest_dir)

  def CompressResultsTo(self, dest_dir):
    tarball = os.path.join(self.results_dir, RESULTS_TARBALL)
    # Test_that runs hold all output under TEST_NAME_HASHTAG/results/,
    # while tast runs hold output under TEST_NAME/.
    # Both ensure to be unique.
    result_dir_name = self.test_name if self.suite == 'tast' else 'results'
    results_dir = self.FindFilesInResultsDir('-name %s' %
                                             result_dir_name).split('\n')[0]

    if not results_dir:
      self._logger.LogOutput('WARNING: No results dir matching %r found' %
                             result_dir_name)
      return

    self.CreateTarball(results_dir, tarball)
    self.CopyFilesTo(dest_dir, [tarball])
    if results_dir:
      self._logger.LogOutput('Results files compressed into %s.' % dest_dir)

  def GetNewKeyvals(self, keyvals_dict):
    # Initialize 'units' dictionary.
    units_dict = {}
    for k in keyvals_dict:
      units_dict[k] = ''
    results_files = self.GetDataMeasurementsFiles()
    for f in results_files:
      # Make sure we can find the results file
      if os.path.exists(f):
        data_filename = f
      else:
        # Otherwise get the base filename and create the correct
        # path for it.
        _, f_base = misc.GetRoot(f)
        data_filename = os.path.join(self.chromeos_root, 'chroot/tmp',
                                     self.temp_dir, f_base)
      if data_filename.find('.json') > 0:
        raw_dict = dict()
        if os.path.exists(data_filename):
          with open(data_filename, 'r') as data_file:
            raw_dict = json.load(data_file)

        if 'charts' in raw_dict:
          raw_dict = raw_dict['charts']
        for k1 in raw_dict:
          field_dict = raw_dict[k1]
          for k2 in field_dict:
            result_dict = field_dict[k2]
            key = k1 + '__' + k2
            if 'value' in result_dict:
              keyvals_dict[key] = result_dict['value']
            elif 'values' in result_dict:
              values = result_dict['values']
              if ('type' in result_dict
                  and result_dict['type'] == 'list_of_scalar_values' and values
                  and values != 'null'):
                keyvals_dict[key] = sum(values) / float(len(values))
              else:
                keyvals_dict[key] = values
            units_dict[key] = result_dict['units']
      else:
        if os.path.exists(data_filename):
          with open(data_filename, 'r') as data_file:
            lines = data_file.readlines()
            for line in lines:
              tmp_dict = json.loads(line)
              graph_name = tmp_dict['graph']
              graph_str = (graph_name + '__') if graph_name else ''
              key = graph_str + tmp_dict['description']
              keyvals_dict[key] = tmp_dict['value']
              units_dict[key] = tmp_dict['units']

    return keyvals_dict, units_dict

  def AppendTelemetryUnits(self, keyvals_dict, units_dict):
    """keyvals_dict is the dict of key-value used to generate Crosperf reports.

    units_dict is a dictionary of the units for the return values in
    keyvals_dict.  We need to associate the units with the return values,
    for Telemetry tests, so that we can include the units in the reports.
    This function takes each value in keyvals_dict, finds the corresponding
    unit in the units_dict, and replaces the old value with a list of the
    old value and the units.  This later gets properly parsed in the
    ResultOrganizer class, for generating the reports.
    """

    results_dict = {}
    for k in keyvals_dict:
      # We don't want these lines in our reports; they add no useful data.
      if not k or k == 'telemetry_Crosperf':
        continue
      val = keyvals_dict[k]
      units = units_dict[k]
      new_val = [val, units]
      results_dict[k] = new_val
    return results_dict

  def GetKeyvals(self):
    results_in_chroot = os.path.join(self.chromeos_root, 'chroot', 'tmp')
    if not self.temp_dir:
      self.temp_dir = tempfile.mkdtemp(dir=results_in_chroot)
      command = f'cp -r {self.results_dir}/* {self.temp_dir}'
      self.ce.RunCommand(command, print_to_console=False)

    command = ('./generate_test_report --no-color --csv %s' %
               (os.path.join('/tmp', os.path.basename(self.temp_dir))))
    _, out, _ = self.ce.ChrootRunCommandWOutput(self.chromeos_root,
                                                command,
                                                print_to_console=False)
    keyvals_dict = {}
    tmp_dir_in_chroot = misc.GetInsideChrootPath(self.chromeos_root,
                                                 self.temp_dir)
    for line in out.splitlines():
      tokens = re.split('=|,', line)
      key = tokens[-2]
      if key.startswith(tmp_dir_in_chroot):
        key = key[len(tmp_dir_in_chroot) + 1:]
      value = tokens[-1]
      keyvals_dict[key] = value

    # Check to see if there is a perf_measurements file and get the
    # data from it if so.
    keyvals_dict, units_dict = self.GetNewKeyvals(keyvals_dict)
    if self.suite == 'telemetry_Crosperf':
      # For telemtry_Crosperf results, append the units to the return
      # results, for use in generating the reports.
      keyvals_dict = self.AppendTelemetryUnits(keyvals_dict, units_dict)
    return keyvals_dict

  def GetSamples(self):
    actual_samples = 0
    for perf_data_file in self.perf_data_files:
      chroot_perf_data_file = misc.GetInsideChrootPath(self.chromeos_root,
                                                       perf_data_file)
      perf_path = os.path.join(self.chromeos_root, 'chroot', 'usr/bin/perf')
      perf_file = '/usr/sbin/perf'
      if os.path.exists(perf_path):
        perf_file = '/usr/bin/perf'

      # For each perf.data, we want to collect sample count for specific DSO.
      # We specify exact match for known DSO type, and every sample for `all`.
      exact_match = ''
      if self.cwp_dso == 'all':
        exact_match = '""'
      elif self.cwp_dso == 'chrome':
        exact_match = '" chrome "'
      elif self.cwp_dso == 'kallsyms':
        exact_match = '"[kernel.kallsyms]"'
      else:
        # This will need to be updated once there are more DSO types supported,
        # if user want an exact match for the field they want.
        exact_match = '"%s"' % self.cwp_dso

      command = ('%s report -n -s dso -i %s 2> /dev/null | grep %s' %
                 (perf_file, chroot_perf_data_file, exact_match))
      _, result, _ = self.ce.ChrootRunCommandWOutput(self.chromeos_root,
                                                     command)
      # Accumulate the sample count for all matched fields.
      # Each line looks like this:
      #     45.42%        237210  chrome
      # And we want the second number which is the sample count.
      samples = 0
      try:
        for line in result.split('\n'):
          attr = line.split()
          if len(attr) == 3 and '%' in attr[0]:
            samples += int(attr[1])
      except:
        raise RuntimeError('Cannot parse perf dso result')

      actual_samples += samples

      # Remove idle cycles from the accumulated sample count.
      perf_report_file = f'{perf_data_file}.report'
      if not os.path.exists(perf_report_file):
        raise RuntimeError(f'Missing perf report file: {perf_report_file}')

      idle_functions = {
          '[kernel.kallsyms]':
          ('intel_idle', 'arch_cpu_idle', 'intel_idle', 'cpu_startup_entry',
           'default_idle', 'cpu_idle_loop', 'do_idle'),
      }
      idle_samples = 0

      with open(perf_report_file) as f:
        try:
          for line in f:
            line = line.strip()
            if not line or line[0] == '#':
              continue
            # Each line has the following fields,
            # pylint: disable=line-too-long
            # Overhead       Samples  Command          Shared Object         Symbol
            # pylint: disable=line-too-long
            # 1.48%          60       swapper          [kernel.kallsyms]     [k] intel_idle
            # pylint: disable=line-too-long
            # 0.00%          1        shill            libshill-net.so       [.] std::__1::vector<unsigned char, std::__1::allocator<unsigned char> >::vector<unsigned char const*>
            _, samples, _, dso, _, function = line.split(None, 5)

            if dso in idle_functions and function in idle_functions[dso]:
              if self.log_level != 'verbose':
                self._logger.LogOutput('Removing %s samples from %s in %s' %
                                       (samples, function, dso))
              idle_samples += int(samples)
        except:
          raise RuntimeError('Cannot parse perf report')
      actual_samples -= idle_samples
    return [actual_samples, u'samples']

  def GetResultsDir(self):
    if self.suite == 'tast':
      mo = re.search(r'Writing results to (\S+)', self.out)
    else:
      mo = re.search(r'Results placed in (\S+)', self.out)
    if mo:
      result = mo.group(1)
      return result
    raise RuntimeError('Could not find results directory.')

  def FindFilesInResultsDir(self, find_args):
    if not self.results_dir:
      return ''

    command = 'find %s %s' % (self.results_dir, find_args)
    ret, out, _ = self.ce.RunCommandWOutput(command, print_to_console=False)
    if ret:
      raise RuntimeError('Could not run find command!')
    return out

  def GetResultsFile(self):
    if self.suite == 'telemetry_Crosperf':
      return self.FindFilesInResultsDir('-name histograms.json').splitlines()
    return self.FindFilesInResultsDir('-name results-chart.json').splitlines()

  def GetPerfDataFiles(self):
    return self.FindFilesInResultsDir('-name perf.data').splitlines()

  def GetPerfReportFiles(self):
    return self.FindFilesInResultsDir('-name perf.data.report').splitlines()

  def GetDataMeasurementsFiles(self):
    result = self.FindFilesInResultsDir('-name perf_measurements').splitlines()
    if not result:
      if self.suite == 'telemetry_Crosperf':
        result = (
            self.FindFilesInResultsDir('-name histograms.json').splitlines())
      else:
        result = (self.FindFilesInResultsDir(
            '-name results-chart.json').splitlines())
    return result

  def GetTurbostatFile(self):
    """Get turbostat log path string."""
    return self.FindFilesInResultsDir('-name turbostat.log').split('\n')[0]

  def GetCpustatsFile(self):
    """Get cpustats log path string."""
    return self.FindFilesInResultsDir('-name cpustats.log').split('\n')[0]

  def GetCpuinfoFile(self):
    """Get cpustats log path string."""
    return self.FindFilesInResultsDir('-name cpuinfo.log').split('\n')[0]

  def GetTopFile(self):
    """Get cpustats log path string."""
    return self.FindFilesInResultsDir('-name top.log').split('\n')[0]

  def GetWaitTimeFile(self):
    """Get wait time log path string."""
    return self.FindFilesInResultsDir('-name wait_time.log').split('\n')[0]

  def _CheckDebugPath(self, option, path):
    relative_path = path[1:]
    out_chroot_path = os.path.join(self.chromeos_root, 'chroot', relative_path)
    if os.path.exists(out_chroot_path):
      if option == 'kallsyms':
        path = os.path.join(path, 'System.map-*')
      return '--' + option + ' ' + path
    else:
      print('** WARNING **: --%s option not applied, %s does not exist' %
            (option, out_chroot_path))
      return ''

  def GeneratePerfReportFiles(self):
    perf_report_files = []
    for perf_data_file in self.perf_data_files:
      # Generate a perf.report and store it side-by-side with the perf.data
      # file.
      chroot_perf_data_file = misc.GetInsideChrootPath(self.chromeos_root,
                                                       perf_data_file)
      perf_report_file = '%s.report' % perf_data_file
      if os.path.exists(perf_report_file):
        raise RuntimeError('Perf report file already exists: %s' %
                           perf_report_file)
      chroot_perf_report_file = misc.GetInsideChrootPath(
          self.chromeos_root, perf_report_file)
      perf_path = os.path.join(self.chromeos_root, 'chroot', 'usr/bin/perf')

      perf_file = '/usr/sbin/perf'
      if os.path.exists(perf_path):
        perf_file = '/usr/bin/perf'

      debug_path = self.label.debug_path

      if debug_path:
        symfs = '--symfs ' + debug_path
        vmlinux = '--vmlinux ' + os.path.join(debug_path, 'usr', 'lib',
                                              'debug', 'boot', 'vmlinux')
        kallsyms = ''
        print('** WARNING **: --kallsyms option not applied, no System.map-* '
              'for downloaded image.')
      else:
        if self.label.image_type != 'local':
          print('** WARNING **: Using local debug info in /build, this may '
                'not match the downloaded image.')
        build_path = os.path.join('/build', self.board)
        symfs = self._CheckDebugPath('symfs', build_path)
        vmlinux_path = os.path.join(build_path, 'usr/lib/debug/boot/vmlinux')
        vmlinux = self._CheckDebugPath('vmlinux', vmlinux_path)
        kallsyms_path = os.path.join(build_path, 'boot')
        kallsyms = self._CheckDebugPath('kallsyms', kallsyms_path)

      command = ('%s report -n %s %s %s -i %s --stdio > %s' %
                 (perf_file, symfs, vmlinux, kallsyms, chroot_perf_data_file,
                  chroot_perf_report_file))
      if self.log_level != 'verbose':
        self._logger.LogOutput('Generating perf report...\nCMD: %s' % command)
      exit_code = self.ce.ChrootRunCommand(self.chromeos_root, command)
      if exit_code == 0:
        if self.log_level != 'verbose':
          self._logger.LogOutput('Perf report generated successfully.')
      else:
        raise RuntimeError('Perf report not generated correctly. CMD: %s' %
                           command)

      # Add a keyval to the dictionary for the events captured.
      perf_report_files.append(
          misc.GetOutsideChrootPath(self.chromeos_root,
                                    chroot_perf_report_file))
    return perf_report_files

  def GatherPerfResults(self):
    report_id = 0
    for perf_report_file in self.perf_report_files:
      with open(perf_report_file, 'r') as f:
        report_contents = f.read()
        for group in re.findall(r'Events: (\S+) (\S+)', report_contents):
          num_events = group[0]
          event_name = group[1]
          key = 'perf_%s_%s' % (report_id, event_name)
          value = str(misc.UnitToNumber(num_events))
          self.keyvals[key] = value

  def PopulateFromRun(self, out, err, retval, test, suite, cwp_dso):
    self.board = self.label.board
    self.out = out
    self.err = err
    self.retval = retval
    self.test_name = test
    self.suite = suite
    self.cwp_dso = cwp_dso
    self.chroot_results_dir = self.GetResultsDir()
    self.results_dir = misc.GetOutsideChrootPath(self.chromeos_root,
                                                 self.chroot_results_dir)
    self.results_file = self.GetResultsFile()
    self.perf_data_files = self.GetPerfDataFiles()
    # Include all perf.report data in table.
    self.perf_report_files = self.GeneratePerfReportFiles()
    self.turbostat_log_file = self.GetTurbostatFile()
    self.cpustats_log_file = self.GetCpustatsFile()
    self.cpuinfo_file = self.GetCpuinfoFile()
    self.top_log_file = self.GetTopFile()
    self.wait_time_log_file = self.GetWaitTimeFile()
    # TODO(asharif): Do something similar with perf stat.

    # Grab keyvals from the directory.
    self.ProcessResults()

  def ProcessChartResults(self):
    # Open and parse the json results file generated by telemetry/test_that.
    if not self.results_file:
      raise IOError('No results file found.')
    filename = self.results_file[0]
    if not filename.endswith('.json'):
      raise IOError('Attempt to call json on non-json file: %s' % filename)
    if not os.path.exists(filename):
      raise IOError('%s does not exist' % filename)

    keyvals = {}
    with open(filename, 'r') as f:
      raw_dict = json.load(f)
      if 'charts' in raw_dict:
        raw_dict = raw_dict['charts']
      for k, field_dict in raw_dict.items():
        for item in field_dict:
          keyname = k + '__' + item
          value_dict = field_dict[item]
          if 'value' in value_dict:
            result = value_dict['value']
          elif 'values' in value_dict:
            values = value_dict['values']
            if not values:
              continue
            if ('type' in value_dict
                and value_dict['type'] == 'list_of_scalar_values'
                and values != 'null'):
              result = sum(values) / float(len(values))
            else:
              result = values
          else:
            continue
          units = value_dict['units']
          new_value = [result, units]
          keyvals[keyname] = new_value
    return keyvals

  def ProcessTurbostatResults(self):
    """Given turbostat_log_file non-null parse cpu stats from file.

    Returns:
      Dictionary of 'cpufreq', 'cputemp' where each
      includes dictionary 'all': [list_of_values]

    Example of the output of turbostat_log.
    ----------------------
    CPU     Avg_MHz Busy%   Bzy_MHz TSC_MHz IRQ     CoreTmp
    -       329     12.13   2723    2393    10975   77
    0       336     12.41   2715    2393    6328    77
    2       323     11.86   2731    2393    4647    69
    CPU     Avg_MHz Busy%   Bzy_MHz TSC_MHz IRQ     CoreTmp
    -       1940    67.46   2884    2393    39920   83
    0       1827    63.70   2877    2393    21184   83
    """
    cpustats = {}
    read_data = ''
    with open(self.turbostat_log_file) as f:
      read_data = f.readlines()

    if not read_data:
      self._logger.LogOutput('WARNING: Turbostat output file is empty.')
      return {}

    # First line always contains the header.
    stats = read_data[0].split()

    # Mandatory parameters.
    if 'CPU' not in stats:
      self._logger.LogOutput(
          'WARNING: Missing data for CPU# in Turbostat output.')
      return {}
    if 'Bzy_MHz' not in stats:
      self._logger.LogOutput(
          'WARNING: Missing data for Bzy_MHz in Turbostat output.')
      return {}
    cpu_index = stats.index('CPU')
    cpufreq_index = stats.index('Bzy_MHz')
    cpufreq = cpustats.setdefault('cpufreq', {'all': []})

    # Optional parameters.
    cputemp_index = -1
    if 'CoreTmp' in stats:
      cputemp_index = stats.index('CoreTmp')
      cputemp = cpustats.setdefault('cputemp', {'all': []})

    # Parse data starting from the second line ignoring repeating headers.
    for st in read_data[1:]:
      # Data represented by int or float separated by spaces.
      numbers = st.split()
      if not all(word.replace('.', '', 1).isdigit() for word in numbers[1:]):
        # Skip the line if data mismatch.
        continue
      if numbers[cpu_index] != '-':
        # Ignore Core-specific statistics which starts with Core number.
        # Combined statistics for all core has "-" CPU identifier.
        continue

      cpufreq['all'].append(int(numbers[cpufreq_index]))
      if cputemp_index != -1:
        cputemp['all'].append(int(numbers[cputemp_index]))
    return cpustats

  def ProcessTopResults(self):
    """Given self.top_log_file process top log data.

    Returns:
      List of dictionaries with the following keyvals:
       'cmd': command name (string),
       'cpu_use_avg': average cpu usage (float),
       'count': number of occurrences (int),
       'top5_cpu_use': up to 5 highest cpu usages (descending list of floats)

    Example of the top log:
      PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
     4102 chronos   12  -8 3454472 238300 118188 R  41.8   6.1   0:08.37 chrome
      375 root       0 -20       0      0      0 S   5.9   0.0   0:00.17 kworker
      617 syslog    20   0   25332   8372   7888 S   5.9   0.2   0:00.77 systemd

      PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
     5745 chronos   20   0 5438580 139328  67988 R 122.8   3.6   0:04.26 chrome
      912 root     -51   0       0      0      0 S   2.0   0.0   0:01.04 irq/cro
      121 root      20   0       0      0      0 S   1.0   0.0   0:00.45 spi5
    """
    all_data = ''
    with open(self.top_log_file) as f:
      all_data = f.read()

    if not all_data:
      self._logger.LogOutput('WARNING: Top log file is empty.')
      return []

    top_line_regex = re.compile(
        r"""
        ^\s*(?P<pid>\d+)\s+         # Group 1: PID
        \S+\s+\S+\s+-?\d+\s+        # Ignore: user, prio, nice
        \d+\s+\d+\s+\d+\s+          # Ignore: virt/res/shared mem
        \S+\s+                      # Ignore: state
        (?P<cpu_use>\d+\.\d+)\s+    # Group 2: CPU usage
        \d+\.\d+\s+\d+:\d+\.\d+\s+  # Ignore: mem usage, time
        (?P<cmd>\S+)$               # Group 3: command
        """, re.VERBOSE)
    # Page represents top log data per one measurement within time interval
    # 'top_interval'.
    # Pages separated by empty line.
    pages = all_data.split('\n\n')
    # Snapshots are structured representation of the pages.
    snapshots = []
    for page in pages:
      if not page:
        continue

      # Snapshot list will contain all processes (command duplicates are
      # allowed).
      snapshot = []
      for line in page.splitlines():
        match = top_line_regex.match(line)
        if match:
          # Top line is valid, collect data.
          process = {
              # NOTE: One command may be represented by multiple processes.
              'cmd': match.group('cmd'),
              'pid': match.group('pid'),
              'cpu_use': float(match.group('cpu_use')),
          }

          # Filter out processes with 0 CPU usage and top command.
          if process['cpu_use'] > 0 and process['cmd'] != 'top':
            snapshot.append(process)

      # If page contained meaningful data add snapshot to the list.
      if snapshot:
        snapshots.append(snapshot)

    # Define threshold of CPU usage when Chrome is busy, i.e. benchmark is
    # running.
    # Ideally it should be 100% but it will be hardly reachable with 1 core.
    # Statistics on DUT with 2-6 cores shows that chrome load of 100%, 95% and
    # 90% equally occurs in 72-74% of all top log snapshots.
    # Further decreasing of load threshold leads to a shifting percent of
    # "high load" snapshots which might include snapshots when benchmark is
    # not running.
    # On 1-core DUT 90% chrome cpu load occurs in 55%, 95% in 33% and 100% in 2%
    # of snapshots accordingly.
    # Threshold of "high load" is reduced to 70% (from 90) when we switched to
    # topstats per process. From experiment data the rest 20% are distributed
    # among other chrome processes.
    CHROME_HIGH_CPU_LOAD = 70
    # Number of snapshots where chrome is heavily used.
    high_load_snapshots = 0
    # Total CPU use per process in ALL active snapshots.
    cmd_total_cpu_use = collections.defaultdict(float)
    # Top CPU usages per command.
    cmd_top5_cpu_use = collections.defaultdict(list)
    # List of Top Commands to be returned.
    topcmds = []

    for snapshot_processes in snapshots:
      # CPU usage per command, per PID in one snapshot.
      cmd_cpu_use_per_snapshot = collections.defaultdict(dict)
      for process in snapshot_processes:
        cmd = process['cmd']
        cpu_use = process['cpu_use']
        pid = process['pid']
        cmd_cpu_use_per_snapshot[cmd][pid] = cpu_use

      # Chrome processes, pid: cpu_usage.
      chrome_processes = cmd_cpu_use_per_snapshot.get('chrome', {})
      chrome_cpu_use_list = chrome_processes.values()

      if chrome_cpu_use_list and max(
          chrome_cpu_use_list) > CHROME_HIGH_CPU_LOAD:
        # CPU usage of any of the "chrome" processes exceeds "High load"
        # threshold which means DUT is busy running a benchmark.
        high_load_snapshots += 1
        for cmd, cpu_use_per_pid in cmd_cpu_use_per_snapshot.items():
          for pid, cpu_use in cpu_use_per_pid.items():
            # Append PID to the name of the command.
            cmd_with_pid = cmd + '-' + pid
            cmd_total_cpu_use[cmd_with_pid] += cpu_use

            # Add cpu_use into command top cpu usages, sorted in descending
            # order.
            heapq.heappush(cmd_top5_cpu_use[cmd_with_pid], round(cpu_use, 1))

    for consumer, usage in sorted(cmd_total_cpu_use.items(),
                                  key=lambda x: x[1],
                                  reverse=True):
      # Iterate through commands by descending order of total CPU usage.
      topcmd = {
          'cmd': consumer,
          'cpu_use_avg': usage / high_load_snapshots,
          'count': len(cmd_top5_cpu_use[consumer]),
          'top5_cpu_use': heapq.nlargest(5, cmd_top5_cpu_use[consumer]),
      }
      topcmds.append(topcmd)

    return topcmds

  def ProcessCpustatsResults(self):
    """Given cpustats_log_file non-null parse cpu data from file.

    Returns:
      Dictionary of 'cpufreq', 'cputemp' where each
      includes dictionary of parameter: [list_of_values]

    Example of cpustats.log output.
    ----------------------
    /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_cur_freq 1512000
    /sys/devices/system/cpu/cpu2/cpufreq/cpuinfo_cur_freq 2016000
    little-cpu 41234
    big-cpu 51234

    If cores share the same policy their frequencies may always match
    on some devices.
    To make report concise we should eliminate redundancy in the output.
    Function removes cpuN data if it duplicates data from other cores.
    """

    cpustats = {}
    read_data = ''
    with open(self.cpustats_log_file) as f:
      read_data = f.readlines()

    if not read_data:
      self._logger.LogOutput('WARNING: Cpustats output file is empty.')
      return {}

    cpufreq_regex = re.compile(r'^[/\S]+/(cpu\d+)/[/\S]+\s+(\d+)$')
    cputemp_regex = re.compile(r'^([^/\s]+)\s+(\d+)$')

    for st in read_data:
      match = cpufreq_regex.match(st)
      if match:
        cpu = match.group(1)
        # CPU frequency comes in kHz.
        freq_khz = int(match.group(2))
        freq_mhz = freq_khz / 1000
        # cpufreq represents a dictionary with CPU frequency-related
        # data from cpustats.log.
        cpufreq = cpustats.setdefault('cpufreq', {})
        cpu_n_freq = cpufreq.setdefault(cpu, [])
        cpu_n_freq.append(freq_mhz)
      else:
        match = cputemp_regex.match(st)
        if match:
          therm_type = match.group(1)
          # The value is int, uCelsius unit.
          temp_uc = float(match.group(2))
          # Round to XX.X float.
          temp_c = round(temp_uc / 1000, 1)
          # cputemp represents a dictionary with temperature measurements
          # from cpustats.log.
          cputemp = cpustats.setdefault('cputemp', {})
          therm_type = cputemp.setdefault(therm_type, [])
          therm_type.append(temp_c)

    # Remove duplicate statistics from cpustats.
    pruned_stats = {}
    for cpukey, cpuparam in cpustats.items():
      # Copy 'cpufreq' and 'cputemp'.
      pruned_params = pruned_stats.setdefault(cpukey, {})
      for paramkey, paramvalue in sorted(cpuparam.items()):
        # paramvalue is list of all measured data.
        if paramvalue not in pruned_params.values():
          pruned_params[paramkey] = paramvalue

    return pruned_stats

  def ProcessHistogramsResults(self):
    # Open and parse the json results file generated by telemetry/test_that.
    if not self.results_file:
      raise IOError('No results file found.')
    filename = self.results_file[0]
    if not filename.endswith('.json'):
      raise IOError('Attempt to call json on non-json file: %s' % filename)
    if not os.path.exists(filename):
      raise IOError('%s does not exist' % filename)

    keyvals = {}
    with open(filename) as f:
      histograms = json.load(f)
      value_map = {}
      # Gets generic set values.
      for obj in histograms:
        if 'type' in obj and obj['type'] == 'GenericSet':
          value_map[obj['guid']] = obj['values']

      for obj in histograms:
        if 'name' not in obj or 'sampleValues' not in obj:
          continue
        metric_name = obj['name']
        vals = obj['sampleValues']
        if isinstance(vals, list):
          # Remove None elements from the list
          vals = [val for val in vals if val is not None]
          if vals:
            result = float(sum(vals)) / len(vals)
          else:
            result = 0
        else:
          result = vals
        unit = obj['unit']
        diagnostics = obj['diagnostics']
        # for summaries of benchmarks
        key = metric_name
        if key not in keyvals:
          keyvals[key] = [[result], unit]
        else:
          keyvals[key][0].append(result)
        # TODO: do we need summaries of stories?
        # for summaries of story tags
        if 'storyTags' in diagnostics:
          guid = diagnostics['storyTags']
          if guid not in value_map:
            raise RuntimeError('Unrecognized storyTags in %s ' % (obj))
          for story_tag in value_map[guid]:
            key = metric_name + '__' + story_tag
            if key not in keyvals:
              keyvals[key] = [[result], unit]
            else:
              keyvals[key][0].append(result)
    # calculate summary
    for key in keyvals:
      vals = keyvals[key][0]
      unit = keyvals[key][1]
      result = float(sum(vals)) / len(vals)
      keyvals[key] = [result, unit]
    return keyvals

  def ReadPidFromPerfData(self):
    """Read PIDs from perf.data files.

    Extract PID from perf.data if "perf record" was running per process,
    i.e. with "-p <PID>" and no "-a".

    Returns:
      pids: list of PIDs.

    Raises:
      PerfDataReadError when perf.data header reading fails.
    """
    cmd = ['/usr/bin/perf', 'report', '--header-only', '-i']
    pids = []

    for perf_data_path in self.perf_data_files:
      perf_data_path_in_chroot = misc.GetInsideChrootPath(
          self.chromeos_root, perf_data_path)
      path_str = ' '.join(cmd + [perf_data_path_in_chroot])
      status, output, _ = self.ce.ChrootRunCommandWOutput(
          self.chromeos_root, path_str)
      if status:
        # Error of reading a perf.data profile is fatal.
        raise PerfDataReadError(
            f'Failed to read perf.data profile: {path_str}')

      # Pattern to search a line with "perf record" command line:
      # # cmdline : /usr/bin/perf record -e instructions -p 123"
      cmdline_regex = re.compile(
          r'^\#\scmdline\s:\s+(?P<cmd>.*perf\s+record\s+.*)$')
      # Pattern to search PID in a command line.
      pid_regex = re.compile(r'^.*\s-p\s(?P<pid>\d+)\s*.*$')
      for line in output.splitlines():
        cmd_match = cmdline_regex.match(line)
        if cmd_match:
          # Found a perf command line.
          cmdline = cmd_match.group('cmd')
          # '-a' is a system-wide mode argument.
          if '-a' not in cmdline.split():
            # It can be that perf was attached to PID and was still running in
            # system-wide mode.
            # We filter out this case here since it's not per-process.
            pid_match = pid_regex.match(cmdline)
            if pid_match:
              pids.append(pid_match.group('pid'))
          # Stop the search and move to the next perf.data file.
          break
      else:
        # cmdline wasn't found in the header. It's a fatal error.
        raise PerfDataReadError(
            f'Perf command line is not found in {path_str}')
    return pids

  def VerifyPerfDataPID(self):
    """Verify PIDs in per-process perf.data profiles.

    Check that at list one top process is profiled if perf was running in
    per-process mode.

    Raises:
      PidVerificationError if PID verification of per-process perf.data profiles
      fail.
    """
    perf_data_pids = self.ReadPidFromPerfData()
    if not perf_data_pids:
      # In system-wide mode there are no PIDs.
      self._logger.LogOutput('System-wide perf mode. Skip verification.')
      return

    # PIDs will be present only in per-process profiles.
    # In this case we need to verify that profiles are collected on the
    # hottest processes.
    top_processes = [top_cmd['cmd'] for top_cmd in self.top_cmds]
    # top_process structure: <cmd>-<pid>
    top_pids = [top_process.split('-')[-1] for top_process in top_processes]
    for top_pid in top_pids:
      if top_pid in perf_data_pids:
        self._logger.LogOutput('PID verification passed! '
                               f'Top process {top_pid} is profiled.')
        return
    raise PidVerificationError(
        f'top processes {top_processes} are missing in perf.data traces with'
        f' PID: {perf_data_pids}.')

  def ProcessResults(self, use_cache=False):
    # Note that this function doesn't know anything about whether there is a
    # cache hit or miss. It should process results agnostic of the cache hit
    # state.
    if (self.results_file and self.suite == 'telemetry_Crosperf'
        and 'histograms.json' in self.results_file[0]):
      self.keyvals = self.ProcessHistogramsResults()
    elif (self.results_file and self.suite != 'telemetry_Crosperf'
          and 'results-chart.json' in self.results_file[0]):
      self.keyvals = self.ProcessChartResults()
    else:
      if not use_cache:
        print('\n ** WARNING **: Had to use deprecated output-method to '
              'collect results.\n')
      self.keyvals = self.GetKeyvals()
    self.keyvals['retval'] = self.retval
    # If we are in CWP approximation mode, we want to collect DSO samples
    # for each perf.data file
    if self.cwp_dso and self.retval == 0:
      self.keyvals['samples'] = self.GetSamples()
      # If the samples count collected from perf file is 0, we will treat
      # it as a failed run.
      if self.keyvals['samples'][0] == 0:
        del self.keyvals['samples']
        self.keyvals['retval'] = 1
    # Generate report from all perf.data files.
    # Now parse all perf report files and include them in keyvals.
    self.GatherPerfResults()

    cpustats = {}
    # Turbostat output has higher priority of processing.
    if self.turbostat_log_file:
      cpustats = self.ProcessTurbostatResults()
    # Process cpustats output only if turbostat has no data.
    if not cpustats and self.cpustats_log_file:
      cpustats = self.ProcessCpustatsResults()
    if self.top_log_file:
      self.top_cmds = self.ProcessTopResults()
    # Verify that PID in non system-wide perf.data and top_cmds are matching.
    if self.perf_data_files and self.top_cmds:
      self.VerifyPerfDataPID()
    if self.wait_time_log_file:
      with open(self.wait_time_log_file) as f:
        wait_time = f.readline().strip()
        try:
          wait_time = float(wait_time)
        except ValueError:
          raise ValueError('Wait time in log file is not a number.')
      # This is for accumulating wait time for telemtry_Crosperf runs only,
      # for test_that runs, please refer to suite_runner.
      self.machine.AddCooldownWaitTime(wait_time)

    for param_key, param in cpustats.items():
      for param_type, param_values in param.items():
        val_avg = sum(param_values) / len(param_values)
        val_min = min(param_values)
        val_max = max(param_values)
        # Average data is always included.
        self.keyvals['_'.join([param_key, param_type, 'avg'])] = val_avg
        # Insert min/max results only if they deviate
        # from average.
        if val_min != val_avg:
          self.keyvals['_'.join([param_key, param_type, 'min'])] = val_min
        if val_max != val_avg:
          self.keyvals['_'.join([param_key, param_type, 'max'])] = val_max

  def GetChromeVersionFromCache(self, cache_dir):
    # Read chrome_version from keys file, if present.
    chrome_version = ''
    keys_file = os.path.join(cache_dir, CACHE_KEYS_FILE)
    if os.path.exists(keys_file):
      with open(keys_file, 'r') as f:
        lines = f.readlines()
        for l in lines:
          if l.startswith('Google Chrome '):
            chrome_version = l
            if chrome_version.endswith('\n'):
              chrome_version = chrome_version[:-1]
            break
    return chrome_version

  def PopulateFromCacheDir(self, cache_dir, test, suite, cwp_dso):
    self.test_name = test
    self.suite = suite
    self.cwp_dso = cwp_dso
    # Read in everything from the cache directory.
    with open(os.path.join(cache_dir, RESULTS_FILE), 'rb') as f:
      self.out = pickle.load(f)
      self.err = pickle.load(f)
      self.retval = pickle.load(f)

    # Untar the tarball to a temporary directory
    self.temp_dir = tempfile.mkdtemp(
        dir=os.path.join(self.chromeos_root, 'chroot', 'tmp'))

    command = ('cd %s && tar xf %s' %
               (self.temp_dir, os.path.join(cache_dir, AUTOTEST_TARBALL)))
    ret = self.ce.RunCommand(command, print_to_console=False)
    if ret:
      raise RuntimeError('Could not untar cached tarball')
    self.results_dir = self.temp_dir
    self.results_file = self.GetDataMeasurementsFiles()
    self.perf_data_files = self.GetPerfDataFiles()
    self.perf_report_files = self.GetPerfReportFiles()
    self.chrome_version = self.GetChromeVersionFromCache(cache_dir)
    self.ProcessResults(use_cache=True)

  def CleanUp(self, rm_chroot_tmp):
    if rm_chroot_tmp and self.results_dir:
      dirname, basename = misc.GetRoot(self.results_dir)
      if basename.find('test_that_results_') != -1:
        command = 'rm -rf %s' % self.results_dir
      else:
        command = 'rm -rf %s' % dirname
      self.ce.RunCommand(command)
    if self.temp_dir:
      command = 'rm -rf %s' % self.temp_dir
      self.ce.RunCommand(command)

  def CreateTarball(self, results_dir, tarball):
    if not results_dir.strip():
      raise ValueError('Refusing to `tar` an empty results_dir: %r' %
                       results_dir)

    ret = self.ce.RunCommand('cd %s && '
                             'tar '
                             '--exclude=var/spool '
                             '--exclude=var/log '
                             '-cjf %s .' % (results_dir, tarball))
    if ret:
      raise RuntimeError("Couldn't compress test output directory.")

  def StoreToCacheDir(self, cache_dir, machine_manager, key_list):
    # Create the dir if it doesn't exist.
    temp_dir = tempfile.mkdtemp()

    # Store to the temp directory.
    with open(os.path.join(temp_dir, RESULTS_FILE), 'wb') as f:
      pickle.dump(self.out, f)
      pickle.dump(self.err, f)
      pickle.dump(self.retval, f)

    if not test_flag.GetTestMode():
      with open(os.path.join(temp_dir, CACHE_KEYS_FILE), 'w') as f:
        f.write('%s\n' % self.label.name)
        f.write('%s\n' % self.label.chrome_version)
        f.write('%s\n' % self.machine.checksum_string)
        for k in key_list:
          f.write(k)
          f.write('\n')

    if self.results_dir:
      tarball = os.path.join(temp_dir, AUTOTEST_TARBALL)
      self.CreateTarball(self.results_dir, tarball)

    # Store machine info.
    # TODO(asharif): Make machine_manager a singleton, and don't pass it into
    # this function.
    with open(os.path.join(temp_dir, MACHINE_FILE), 'w') as f:
      f.write(machine_manager.machine_checksum_string[self.label.name])

    if os.path.exists(cache_dir):
      command = f'rm -rf {cache_dir}'
      self.ce.RunCommand(command)

    parent_dir = os.path.dirname(cache_dir)
    command = f'mkdir -p {parent_dir} && '
    command += f'chmod g+x {temp_dir} && '
    command += f'mv {temp_dir} {cache_dir}'
    ret = self.ce.RunCommand(command)
    if ret:
      command = f'rm -rf {temp_dir}'
      self.ce.RunCommand(command)
      raise RuntimeError('Could not move dir %s to dir %s' %
                         (temp_dir, cache_dir))

  @classmethod
  def CreateFromRun(cls,
                    logger,
                    log_level,
                    label,
                    machine,
                    out,
                    err,
                    retval,
                    test,
                    suite='telemetry_Crosperf',
                    cwp_dso=''):
    if suite == 'telemetry':
      result = TelemetryResult(logger, label, log_level, machine)
    else:
      result = cls(logger, label, log_level, machine)
    result.PopulateFromRun(out, err, retval, test, suite, cwp_dso)
    return result

  @classmethod
  def CreateFromCacheHit(cls,
                         logger,
                         log_level,
                         label,
                         machine,
                         cache_dir,
                         test,
                         suite='telemetry_Crosperf',
                         cwp_dso=''):
    if suite == 'telemetry':
      result = TelemetryResult(logger, label, log_level, machine)
    else:
      result = cls(logger, label, log_level, machine)
    try:
      result.PopulateFromCacheDir(cache_dir, test, suite, cwp_dso)

    except RuntimeError as e:
      logger.LogError('Exception while using cache: %s' % e)
      return None
    return result


class TelemetryResult(Result):
  """Class to hold the results of a single Telemetry run."""

  def PopulateFromRun(self, out, err, retval, test, suite, cwp_dso):
    self.out = out
    self.err = err
    self.retval = retval

    self.ProcessResults()

  # pylint: disable=arguments-differ
  def ProcessResults(self):
    # The output is:
    # url,average_commit_time (ms),...
    # www.google.com,33.4,21.2,...
    # We need to convert to this format:
    # {"www.google.com:average_commit_time (ms)": "33.4",
    #  "www.google.com:...": "21.2"}
    # Added note:  Occasionally the output comes back
    # with "JSON.stringify(window.automation.GetResults())" on
    # the first line, and then the rest of the output as
    # described above.

    lines = self.out.splitlines()
    self.keyvals = {}

    if lines:
      if lines[0].startswith('JSON.stringify'):
        lines = lines[1:]

    if not lines:
      return
    labels = lines[0].split(',')
    for line in lines[1:]:
      fields = line.split(',')
      if len(fields) != len(labels):
        continue
      for i in range(1, len(labels)):
        key = '%s %s' % (fields[0], labels[i])
        value = fields[i]
        self.keyvals[key] = value
    self.keyvals['retval'] = self.retval

  def PopulateFromCacheDir(self, cache_dir, test, suite, cwp_dso):
    self.test_name = test
    self.suite = suite
    self.cwp_dso = cwp_dso
    with open(os.path.join(cache_dir, RESULTS_FILE), 'rb') as f:
      self.out = pickle.load(f)
      self.err = pickle.load(f)
      self.retval = pickle.load(f)

    self.chrome_version = (super(TelemetryResult,
                                 self).GetChromeVersionFromCache(cache_dir))
    self.ProcessResults()


class CacheConditions(object):
  """Various Cache condition values, for export."""

  # Cache hit only if the result file exists.
  CACHE_FILE_EXISTS = 0

  # Cache hit if the checksum of cpuinfo and totalmem of
  # the cached result and the new run match.
  MACHINES_MATCH = 1

  # Cache hit if the image checksum of the cached result and the new run match.
  CHECKSUMS_MATCH = 2

  # Cache hit only if the cached result was successful
  RUN_SUCCEEDED = 3

  # Never a cache hit.
  FALSE = 4

  # Cache hit if the image path matches the cached image path.
  IMAGE_PATH_MATCH = 5

  # Cache hit if the uuid of hard disk mataches the cached one

  SAME_MACHINE_MATCH = 6


class ResultsCache(object):
  """Class to handle the cache for storing/retrieving test run results.

  This class manages the key of the cached runs without worrying about what
  is exactly stored (value). The value generation is handled by the Results
  class.
  """
  CACHE_VERSION = 6

  def __init__(self):
    # Proper initialization happens in the Init function below.
    self.chromeos_image = None
    self.chromeos_root = None
    self.test_name = None
    self.iteration = None
    self.test_args = None
    self.profiler_args = None
    self.board = None
    self.cache_conditions = None
    self.machine_manager = None
    self.machine = None
    self._logger = None
    self.ce = None
    self.label = None
    self.share_cache = None
    self.suite = None
    self.log_level = None
    self.show_all = None
    self.run_local = None
    self.cwp_dso = None

  def Init(self, chromeos_image, chromeos_root, test_name, iteration,
           test_args, profiler_args, machine_manager, machine, board,
           cache_conditions, logger_to_use, log_level, label, share_cache,
           suite, show_all_results, run_local, cwp_dso):
    self.chromeos_image = chromeos_image
    self.chromeos_root = chromeos_root
    self.test_name = test_name
    self.iteration = iteration
    self.test_args = test_args
    self.profiler_args = profiler_args
    self.board = board
    self.cache_conditions = cache_conditions
    self.machine_manager = machine_manager
    self.machine = machine
    self._logger = logger_to_use
    self.ce = command_executer.GetCommandExecuter(self._logger,
                                                  log_level=log_level)
    self.label = label
    self.share_cache = share_cache
    self.suite = suite
    self.log_level = log_level
    self.show_all = show_all_results
    self.run_local = run_local
    self.cwp_dso = cwp_dso

  def GetCacheDirForRead(self):
    matching_dirs = []
    for glob_path in self.FormCacheDir(self.GetCacheKeyList(True)):
      matching_dirs += glob.glob(glob_path)

    if matching_dirs:
      # Cache file found.
      return matching_dirs[0]
    return None

  def GetCacheDirForWrite(self, get_keylist=False):
    cache_path = self.FormCacheDir(self.GetCacheKeyList(False))[0]
    if get_keylist:
      args_str = '%s_%s_%s' % (self.test_args, self.profiler_args,
                               self.run_local)
      version, image = results_report.ParseChromeosImage(
          self.label.chromeos_image)
      keylist = [
          version, image, self.label.board, self.machine.name, self.test_name,
          str(self.iteration), args_str
      ]
      return cache_path, keylist
    return cache_path

  def FormCacheDir(self, list_of_strings):
    cache_key = ' '.join(list_of_strings)
    cache_dir = misc.GetFilenameFromString(cache_key)
    if self.label.cache_dir:
      cache_home = os.path.abspath(os.path.expanduser(self.label.cache_dir))
      cache_path = [os.path.join(cache_home, cache_dir)]
    else:
      cache_path = [os.path.join(SCRATCH_DIR, cache_dir)]

    if self.share_cache:
      for path in [x.strip() for x in self.share_cache.split(',')]:
        if os.path.exists(path):
          cache_path.append(os.path.join(path, cache_dir))
        else:
          self._logger.LogFatal('Unable to find shared cache: %s' % path)

    return cache_path

  def GetCacheKeyList(self, read):
    if read and CacheConditions.MACHINES_MATCH not in self.cache_conditions:
      machine_checksum = '*'
    else:
      machine_checksum = self.machine_manager.machine_checksum[self.label.name]
    if read and CacheConditions.CHECKSUMS_MATCH not in self.cache_conditions:
      checksum = '*'
    elif self.label.image_type == 'trybot':
      checksum = hashlib.md5(
          self.label.chromeos_image.encode('utf-8')).hexdigest()
    elif self.label.image_type == 'official':
      checksum = '*'
    else:
      checksum = ImageChecksummer().Checksum(self.label, self.log_level)

    if read and CacheConditions.IMAGE_PATH_MATCH not in self.cache_conditions:
      image_path_checksum = '*'
    else:
      image_path_checksum = hashlib.md5(
          self.chromeos_image.encode('utf-8')).hexdigest()

    machine_id_checksum = ''
    if read and CacheConditions.SAME_MACHINE_MATCH not in self.cache_conditions:
      machine_id_checksum = '*'
    else:
      if self.machine and self.machine.name in self.label.remote:
        machine_id_checksum = self.machine.machine_id_checksum
      else:
        for machine in self.machine_manager.GetMachines(self.label):
          if machine.name == self.label.remote[0]:
            machine_id_checksum = machine.machine_id_checksum
            break

    temp_test_args = '%s %s %s' % (self.test_args, self.profiler_args,
                                   self.run_local)
    test_args_checksum = hashlib.md5(
        temp_test_args.encode('utf-8')).hexdigest()
    return (image_path_checksum, self.test_name, str(self.iteration),
            test_args_checksum, checksum, machine_checksum,
            machine_id_checksum, str(self.CACHE_VERSION))

  def ReadResult(self):
    if CacheConditions.FALSE in self.cache_conditions:
      cache_dir = self.GetCacheDirForWrite()
      command = 'rm -rf %s' % (cache_dir, )
      self.ce.RunCommand(command)
      return None
    cache_dir = self.GetCacheDirForRead()

    if not cache_dir:
      return None

    if not os.path.isdir(cache_dir):
      return None

    if self.log_level == 'verbose':
      self._logger.LogOutput('Trying to read from cache dir: %s' % cache_dir)
    result = Result.CreateFromCacheHit(self._logger, self.log_level,
                                       self.label, self.machine, cache_dir,
                                       self.test_name, self.suite,
                                       self.cwp_dso)
    if not result:
      return None

    if (result.retval == 0
        or CacheConditions.RUN_SUCCEEDED not in self.cache_conditions):
      return result

    return None

  def StoreResult(self, result):
    cache_dir, keylist = self.GetCacheDirForWrite(get_keylist=True)
    result.StoreToCacheDir(cache_dir, self.machine_manager, keylist)


class MockResultsCache(ResultsCache):
  """Class for mock testing, corresponding to ResultsCache class."""

  # FIXME: pylint complains about this mock init method, we should probably
  # replace all Mock classes in Crosperf with simple Mock.mock().
  # pylint: disable=arguments-differ
  def Init(self, *args):
    pass

  def ReadResult(self):
    return None

  def StoreResult(self, result):
    pass


class MockResult(Result):
  """Class for mock testing, corresponding to Result class."""

  def PopulateFromRun(self, out, err, retval, test, suite, cwp_dso):
    self.out = out
    self.err = err
    self.retval = retval
