# Copyright (c) 2010 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 httplib
import logging
import os
import urllib2

from autotest_lib.client.bin import test, utils
from autotest_lib.client.common_lib import error
from autotest_lib.client.cros import perf
from autotest_lib.client.cros import service_stopper

# to run this test manually on a test target
# ssh root@machine
# cd /usr/local/autotest/deps/glbench
# stop ui
# X :1 & sleep 1; DISPLAY=:1 ./glbench [-save [-oudir=<dir>]]
# start ui


# Keep track of hosts that result in any errors other than HTTPError 404 (url
# not found).  A 404 error is expected (and timely).  Any other error means
# that the access timed out.  Avoid any subsequent attempt to access that "bad"
# host, to avoid accumulation of many timeouts.
bad_host_cache = set()

def ReferenceImageExists(images_file, images_url, imagename):
  found = False
  # check imagename in index file first
  if imagename in images_file:
    return True
  # check if image can be found on web server
  url = images_url + imagename
  host = urllib2.urlparse.urlparse(url).netloc
  if host in bad_host_cache:
    logging.warning('skipping cached unreachable host %s' % host)
    return False
  try:
    urllib2.urlopen(urllib2.Request(url))
    found = True
  except (urllib2.HTTPError, urllib2.URLError, httplib.HTTPException) as e:
    found = False
    if not (isinstance(e, urllib2.HTTPError) and e.getcode() == 404):
      bad_host_cache.add(host)
      logging.warning('cached unreachable host %s' % host)
  return found


class graphics_GLBench(test.test):
  version = 1
  preserve_srcdir = True

  # None-init vars used by cleanup() here, in case setup() fails
  _services = None

  reference_images_file = 'deps/glbench/glbench_reference_images.txt'
  knownbad_images_file = 'deps/glbench/glbench_knownbad_images.txt'

  reference_images_url = ('http://commondatastorage.googleapis.com/'
                          'chromeos-localmirror/distfiles/'
                          'glbench_reference_images/')
  knownbad_images_url = ('http://commondatastorage.googleapis.com/'
                         'chromeos-localmirror/distfiles/'
                         'glbench_knownbad_images/')

  # TODO(ihf) not sure these are still needed
  # These tests do not draw anything, they can only be used to check
  # performance.
  no_checksum_tests = set(['1280x768_fps_no_fill_compositing',
                           'mpixels_sec_pixel_read',
                           'mpixels_sec_pixel_read_2',
                           'mpixels_sec_pixel_read_3',
                           'mtexel_sec_texture_reuse_teximage2d_1024',
                           'mtexel_sec_texture_reuse_teximage2d_128',
                           'mtexel_sec_texture_reuse_teximage2d_1536',
                           'mtexel_sec_texture_reuse_teximage2d_2048',
                           'mtexel_sec_texture_reuse_teximage2d_256',
                           'mtexel_sec_texture_reuse_teximage2d_32',
                           'mtexel_sec_texture_reuse_teximage2d_512',
                           'mtexel_sec_texture_reuse_teximage2d_768',
                           'mtexel_sec_texture_reuse_texsubimage2d_1024',
                           'mtexel_sec_texture_reuse_texsubimage2d_128',
                           'mtexel_sec_texture_reuse_texsubimage2d_1536',
                           'mtexel_sec_texture_reuse_texsubimage2d_2048',
                           'mtexel_sec_texture_reuse_texsubimage2d_256',
                           'mtexel_sec_texture_reuse_texsubimage2d_32',
                           'mtexel_sec_texture_reuse_texsubimage2d_512',
                           'mtexel_sec_texture_reuse_texsubimage2d_768',
                           'mtexel_sec_texture_upload_teximage2d_1024',
                           'mtexel_sec_texture_upload_teximage2d_128',
                           'mtexel_sec_texture_upload_teximage2d_1536',
                           'mtexel_sec_texture_upload_teximage2d_2048',
                           'mtexel_sec_texture_upload_teximage2d_256',
                           'mtexel_sec_texture_upload_teximage2d_32',
                           'mtexel_sec_texture_upload_teximage2d_512',
                           'mtexel_sec_texture_upload_teximage2d_768',
                           'mtexel_sec_texture_upload_texsubimage2d_1024',
                           'mtexel_sec_texture_upload_texsubimage2d_128',
                           'mtexel_sec_texture_upload_texsubimage2d_1536',
                           'mtexel_sec_texture_upload_texsubimage2d_2048',
                           'mtexel_sec_texture_upload_texsubimage2d_256',
                           'mtexel_sec_texture_upload_texsubimage2d_32',
                           'mtexel_sec_texture_upload_texsubimage2d_512',
                           'mtexel_sec_texture_upload_texsubimage2d_768',
                           'mvtx_sec_attribute_fetch_shader',
                           'mvtx_sec_attribute_fetch_shader_2_attr',
                           'mvtx_sec_attribute_fetch_shader_4_attr',
                           'mvtx_sec_attribute_fetch_shader_8_attr',
                           'us_context_glsimple',
                           'us_context_nogl',
                           'us_swap_glsimple',
                           'us_swap_nogl', ])

  blacklist = ''

  def setup(self):
    self.job.setup_dep(['glbench'])

  def initialize(self):
    self._services = service_stopper.ServiceStopper(['ui'])

  def cleanup(self):
    if self._services:
      self._services.restore_services()

  def report_temperature(self, keyname):
    temperature = utils.get_temperature_input_max()
    logging.info('%s = %f degree Celsius', keyname, temperature)
    self.output_perf_value(description=keyname, value=temperature,
                           units='Celsius', higher_is_better=False)

  def report_temperature_critical(self, keyname):
    temperature = utils.get_temperature_critical()
    logging.info('%s = %f degree Celsius', keyname, temperature)
    self.output_perf_value(description=keyname, value=temperature,
                           units='Celsius', higher_is_better=False)

  def get_unit_from_test(self, testname):
    if testname.startswith('mpixels_sec_'):
      return ('mpixels_sec', True)
    if testname.startswith('mtexel_sec_'):
      return ('mtexel_sec', True)
    if testname.startswith('mtri_sec_'):
      return ('mtri_sec', True)
    if testname.startswith('mvtx_sec_'):
      return ('mvtx_sec', True)
    if testname.startswith('us_'):
      return ('us', False)
    if testname.startswith('1280x768_fps_'):
      return ('fps', True)
    raise error.TestFail('Unknown test unit in ' + testname)

  def run_once(self, options='', hasty=False):
    logging.info(utils.get_board_with_frequency_and_memory())
    dep = 'glbench'
    dep_dir = os.path.join(self.autodir, 'deps', dep)
    self.job.install_pkg(dep, 'dep', dep_dir)

    options += self.blacklist

    # Run the test, saving is optional and helps with debugging
    # and reference image management. If unknown images are
    # encountered one can take them from the outdir and copy
    # them (after verification) into the reference image dir.
    exefile = os.path.join(self.autodir, 'deps/glbench/glbench')
    outdir = self.outputdir
    options += ' -save -outdir=' + outdir
    # Using the -hasty option we run only a subset of tests without waiting
    # for thermals to normalize. Test should complete in 15-20 seconds.
    if hasty:
      options += ' -hasty'
    cmd = '%s %s' % (exefile, options)

    # If UI is running, we must stop it and restore later.
    self._services.stop_services()

    # Just sending SIGTERM to X is not enough; we must wait for it to
    # really die before we start a new X server (ie start ui).
    # The term_process function of /sbin/killers makes sure that all X
    # process are really dead before returning; this is what stop ui uses.
    kill_cmd = '. /sbin/killers; term_process "^X$"'
    cmd = 'X :1 vt1 & sleep 1; chvt 1 && DISPLAY=:1 %s; %s' % (cmd, kill_cmd)
    summary = None
    if hasty:
      # On BVT the test will not monitor thermals so we will not verify its
      # correct status using PerControl
      summary = utils.run(cmd,
                          stdout_tee=utils.TEE_TO_LOGS,
                          stderr_tee=utils.TEE_TO_LOGS).stdout
    else:
      self.report_temperature_critical('temperature_critical')
      self.report_temperature('temperature_1_start')
      # Wrap the test run inside of a PerfControl instance to make machine
      # behavior more consistent.
      with perf.PerfControl() as pc:
        if not pc.verify_is_valid():
          raise error.TestError(pc.get_error_reason())
        self.report_temperature('temperature_2_before_test')

        # Run the test. If it gets the CPU too hot pc should notice.
        summary = utils.run(cmd,
                            stdout_tee=utils.TEE_TO_LOGS,
                            stderr_tee=utils.TEE_TO_LOGS).stdout
        if not pc.verify_is_valid():
          raise error.TestError(pc.get_error_reason())

    # Write a copy of stdout to help debug failures.
    results_path = os.path.join(self.outputdir, 'summary.txt')
    f = open(results_path, 'w+')
    f.write('# ---------------------------------------------------\n')
    f.write('# [' + cmd + ']\n')
    f.write(summary)
    f.write('\n# -------------------------------------------------\n')
    f.write('# [graphics_GLBench.py postprocessing]\n')

    # Analyze the output. Sample:
    ## board_id: NVIDIA Corporation - Quadro FX 380/PCI/SSE2
    ## Running: ../glbench -save -outdir=img
    #us_swap_swap = 221.36 [us_swap_swap.pixmd5-20dbc...f9c700d2f.png]
    results = summary.splitlines()
    if not results:
      f.close()
      raise error.TestFail('No output from test. Check /tmp/' +
                           'run_remote_tests.../graphics_GLBench/summary.txt' +
                           ' for details.')

    # initialize reference images index for lookup
    reference_imagenames = os.path.join(self.autodir,
                                        self.reference_images_file)
    g = open(reference_imagenames, 'r')
    reference_imagenames = g.read()
    g.close()
    knownbad_imagenames = os.path.join(self.autodir,
                                       self.knownbad_images_file)
    g = open(knownbad_imagenames, 'r')
    knownbad_imagenames = g.read()
    g.close()

    # Check if we saw GLBench end as expected (without crashing).
    test_ended_normal = False
    for line in results:
      if line.strip().startswith('@TEST_END'):
        test_ended_normal = True

    # Analyze individual test results in summary.
    keyvals = {}
    failed_tests = {}
    for line in results:
      if not line.strip().startswith('@RESULT: '):
        continue
      keyval, remainder = line[9:].split('[')
      key, val = keyval.split('=')
      testname = key.strip()
      testrating = float(val)
      imagefile = remainder.split(']')[0]
      unit, higher = self.get_unit_from_test(testname)
      if not hasty:
        self.output_perf_value(description=testname, value=testrating,
                               units=unit, higher_is_better=higher)

      # classify result image
      if ReferenceImageExists(knownbad_imagenames,
                              self.knownbad_images_url,
                              imagefile):
        # we already know the image looks bad and have filed a bug
        # so don't throw an exception and remind there is a problem
        keyvals[testname] = -1.0
        f.write('# knownbad [' + imagefile + '] (setting perf as -1.0)\n')
      else:
        if ReferenceImageExists(reference_imagenames,
                                self.reference_images_url,
                                imagefile):
          # known good reference images
          keyvals[testname] = testrating
        else:
          if testname in self.no_checksum_tests:
            # TODO(ihf) these really should not write any images
            keyvals[testname] = testrating
          else:
            # completely unknown images
            keyvals[testname] = -2.0
            failed_tests[testname] = imagefile
            f.write('# unknown [' + imagefile + '] (setting perf as -2.0)\n')
    f.close()
    if not hasty:
      self.report_temperature('temperature_3_after_test')
      self.write_perf_keyval(keyvals)

    # Raise exception if images don't match.
    if failed_tests:
      logging.info('Some images are not matching their reference in %s or %s.',
                   self.reference_images_file,
                   self.reference_images_url)
      logging.info('Please verify that the output images are correct '
                   'and if so copy them to the reference directory.')
      raise error.TestFail('Some images are not matching their '
                           'references. Check /tmp/'
                           'run_remote_tests.../graphics_GLBench/summary.txt'
                           ' for details.')

    if not test_ended_normal:
      raise error.TestFail('No end marker. Presumed crash/missing images.')
