blob: 08cb2a5c762212c1f1c4d147fa66c57b8e060877 [file] [log] [blame]
# 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.
"""The functionality in this class is used whenever one of the graphics_*
tests runs. It provides a sanity check on GPU failures and emits warnings
on recovered GPU hangs and errors on fallback to software rasterization.
"""
import glob, logging, os, sys
from autotest_lib.client.bin import utils
from autotest_lib.client.common_lib import error
from autotest_lib.client.cros import cros_ui
def take_screenshot(resultsdir, fname_prefix, format='png'):
"""Take screenshot and save to a new file in the results dir.
Args:
@param resultsdir: Directory to store the output in.
@param fname_prefix: Prefix for the output fname.
@param format: String indicating file format ('png', 'jpg', etc).
Returns:
the path of the saved screenshot file
"""
next_index = len(glob.glob(
os.path.join(resultsdir, '%s-*.%s' % (fname_prefix, format))))
screenshot_file = os.path.join(
resultsdir, '%s-%d.%s' % (fname_prefix, next_index, format))
logging.info('Saving screenshot to %s.', screenshot_file)
old_exc_type = sys.exc_info()[0]
try:
cros_ui.xsystem('/usr/local/bin/import -window root -depth 8 %s' %
screenshot_file)
except Exception as err:
# Do not raise an exception if the screenshot fails while processing
# another exception.
if old_exc_type is None:
raise
logging.error(err)
return screenshot_file
class GraphicsStateChecker(object):
"""Analyzes the state of the GPU and log history. Should be instantiated
at the beginning of each graphics_* test.
"""
hangs = {}
crash_blacklist = []
_BROWSER_VERSION_COMMAND = '/opt/google/chrome/chrome --version'
_HANGCHECK = 'drm:i915_hangcheck_elapsed'
_MESSAGES_FILE = '/var/log/messages'
def __init__(self):
"""Analyzes the initial state of the GPU and log history.
"""
if utils.get_cpu_arch() != 'arm':
cmd = 'glxinfo | grep "OpenGL renderer string"'
cmd = cros_ui.xcommand(cmd)
output = utils.run(cmd)
result = output.stdout.splitlines()[0]
logging.info('glxinfo: %s', result)
# TODO(ihf): Find exhaustive error conditions (especially ARM).
if 'llvmpipe' in result.lower() or 'soft' in result.lower():
raise error.TestFail('Refusing to run on SW rasterizer: ' + result)
logging.info('Initialize: Checking for old GPU hangs...')
f = open(self._MESSAGES_FILE, 'r')
for line in f:
if self._HANGCHECK in line:
logging.info(line)
self.hangs[line] = line
f.close()
def finalize(self):
"""Analyzes the state of the GPU, log history and emits warnings or
errors if the state changed since initialize. Also makes a note of the
Chrome version for later usage in the perf-dashboard.
"""
if utils.get_cpu_arch() != 'arm':
logging.info('Cleanup: Checking for new GPU hangs...')
f = open(self._MESSAGES_FILE, 'r')
for line in f:
if self._HANGCHECK in line:
if not line in self.hangs.keys():
logging.info(line)
self.job.record('WARN', None, 'Saw GPU hang during test.')
f.close()
cmd = 'glxinfo | grep "OpenGL renderer string"'
cmd = cros_ui.xcommand(cmd)
output = utils.run(cmd)
result = output.stdout.splitlines()[0]
logging.info('glxinfo: %s', result)
# TODO(ihf): Find exhaustive error conditions (especially ARM).
if 'llvmpipe' in result.lower() or 'soft' in result.lower():
logging.info('Finished test on SW rasterizer.')
raise error.TestFail('Finished test on SW rasterizer: ' + result)
# TODO(ihf): Perform crash processing (primarily for Piglit) as is done
# right now by ./client/cros/cros_ui_test.py and cros_logging.py.