blob: c913d0d0f10db289f2d76778d887b5d5e6d473f6 [file] [log] [blame]
# Copyright (c) 2012 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 time
from autotest_lib.client.bin import test
from autotest_lib.client.bin import utils as bin_utils
from autotest_lib.client.common_lib import error, utils
from autotest_lib.client.cros.graphics import graphics_utils
# to run this test manually on a test target
# ssh root@machine
# cd /usr/local/autotest/tests/graphics_GpuReset/src/
# stop ui
# ./gpureset
# start ui
class graphics_GpuReset(graphics_utils.GraphicsTest):
"""
Reset the GPU and check recovery mechanism.
"""
version = 1
preserve_srcdir = True
loops = 1
def setup(self):
os.chdir(self.srcdir)
utils.make('clean')
utils.make('all')
def initialize(self):
# GpuReset should pretty much be the only test where we don't want to raise
# a test error when we detect a GPU hang.
super(graphics_GpuReset, self).initialize(raise_error_on_hang=False)
def cleanup(self):
super(graphics_GpuReset, self).cleanup()
@graphics_utils.GraphicsTest.failure_report_decorator('graphics_GpuReset')
def run_once(self, options=''):
gpu_family = bin_utils.get_gpu_family()
if gpu_family == 'stoney':
options = '-s 7 -t 1'
exefile = 'amdgpu_test'
else:
options = ''
exefile = os.path.join(self.srcdir, 'gpureset')
if not os.path.isfile(exefile):
raise error.TestFail('Failed: could not locate gpureset executable (' +
exefile + ').')
cmd = '%s %s' % (exefile, options)
# If UI is running, we must stop it and restore later.
need_restart_ui = False
status_output = utils.system_output('initctl status ui')
# If chrome is running, result will be similar to:
# ui start/running, process 11895
logging.info('initctl status ui returns: %s', status_output)
need_restart_ui = status_output.startswith('ui start')
summary = ''
# Run the gpureset test in a loop to stress the recovery.
for i in range(1, self.loops + 1):
summary += 'graphics_GpuReset iteration %d of %d\n' % (i, self.loops)
if need_restart_ui:
summary += 'initctl stop ui\n'
utils.system('initctl stop ui', ignore_status=True)
# TODO(ihf): Remove this code if no improvement for issue 409019.
logging.info('Make sure chrome is dead before triggering hang.')
utils.system('killall -9 chrome', ignore_status=True)
time.sleep(3)
try:
summary += utils.system_output(cmd, retain_output=True)
summary += '\n'
finally:
if need_restart_ui:
summary += 'initctl start ui\n'
utils.system('initctl start ui')
# 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('# need ui restart: %s\n' % need_restart_ui)
f.write('# ---------------------------------------------------\n')
f.write('# [' + cmd + ']\n')
f.write(summary)
f.write('\n# -------------------------------------------------\n')
f.write('# [graphics_GpuReset.py postprocessing]\n')
# Analyze the output. Sample:
# [ OK ] graphics_GpuReset
# [ FAILED ] graphics_GpuReset
results = summary.splitlines()
if not results:
f.close()
raise error.TestFail('Failed: No output from test. Check /tmp/' +
'test_that_latest/graphics_GpuReset/summary.txt' +
' for details.')
# Analyze summary and count number of passes.
pass_count = 0
for line in results:
if gpu_family == 'stoney':
if "passed" in line:
pass_count += 1
if "failed" in line:
raise error.TestFail('Failed: %s' % line)
else:
if line.strip().startswith('[ OK ] graphics_GpuReset'):
pass_count += 1
if line.strip().startswith('[ FAILED ] graphics_GpuReset'):
msg = line.strip()[30:]
failed_msg = 'Test failed with %s' % msg
raise error.TestFail('Failed: %s' % failed_msg)
f.close()
# Final chance to fail.
if pass_count != self.loops:
failed_msg = 'Test failed with incomplete output. System hung? '
failed_msg += '(pass_count=%d of %d)' % (pass_count, self.loops)
raise error.TestFail('Failed: %s' % failed_msg)
# We need to wait a bit for X to come back after the 'start ui'.
time.sleep(5)