1# Copyright (c) 2012 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 5import logging 6import os 7import time 8 9from autotest_lib.client.bin import test 10from autotest_lib.client.bin import utils as bin_utils 11from autotest_lib.client.common_lib import error, utils 12from autotest_lib.client.cros.graphics import graphics_utils 13 14# to run this test manually on a test target 15# ssh root@machine 16# cd /usr/local/autotest/tests/graphics_GpuReset/src/ 17# stop ui 18# ./gpureset 19# start ui 20 21 22class graphics_GpuReset(graphics_utils.GraphicsTest): 23 """ 24 Reset the GPU and check recovery mechanism. 25 """ 26 version = 1 27 preserve_srcdir = True 28 loops = 1 29 30 def setup(self): 31 os.chdir(self.srcdir) 32 utils.make('clean') 33 utils.make('all') 34 35 def initialize(self): 36 # GpuReset should pretty much be the only test where we don't want to raise 37 # a test error when we detect a GPU hang. 38 super(graphics_GpuReset, self).initialize(raise_error_on_hang=False) 39 40 def cleanup(self): 41 super(graphics_GpuReset, self).cleanup() 42 43 @graphics_utils.GraphicsTest.failure_report_decorator('graphics_GpuReset') 44 def run_once(self, options=''): 45 gpu_family = bin_utils.get_gpu_family() 46 if gpu_family == 'stoney': 47 options = '-s 7 -t 1' 48 exefile = 'amdgpu_test' 49 else: 50 options = '' 51 exefile = os.path.join(self.srcdir, 'gpureset') 52 if not os.path.isfile(exefile): 53 raise error.TestFail('Failed: could not locate gpureset executable (' + 54 exefile + ').') 55 56 cmd = '%s %s' % (exefile, options) 57 58 # If UI is running, we must stop it and restore later. 59 need_restart_ui = False 60 status_output = utils.system_output('initctl status ui') 61 # If chrome is running, result will be similar to: 62 # ui start/running, process 11895 63 logging.info('initctl status ui returns: %s', status_output) 64 need_restart_ui = status_output.startswith('ui start') 65 summary = '' 66 67 # Run the gpureset test in a loop to stress the recovery. 68 for i in range(1, self.loops + 1): 69 summary += 'graphics_GpuReset iteration %d of %d\n' % (i, self.loops) 70 if need_restart_ui: 71 summary += 'initctl stop ui\n' 72 utils.system('initctl stop ui', ignore_status=True) 73 # TODO(ihf): Remove this code if no improvement for issue 409019. 74 logging.info('Make sure chrome is dead before triggering hang.') 75 utils.system('killall -9 chrome', ignore_status=True) 76 time.sleep(3) 77 try: 78 summary += utils.system_output(cmd, retain_output=True) 79 summary += '\n' 80 finally: 81 if need_restart_ui: 82 summary += 'initctl start ui\n' 83 utils.system('initctl start ui') 84 85 # Write a copy of stdout to help debug failures. 86 results_path = os.path.join(self.outputdir, 'summary.txt') 87 f = open(results_path, 'w+') 88 f.write('# need ui restart: %s\n' % need_restart_ui) 89 f.write('# ---------------------------------------------------\n') 90 f.write('# [' + cmd + ']\n') 91 f.write(summary) 92 f.write('\n# -------------------------------------------------\n') 93 f.write('# [graphics_GpuReset.py postprocessing]\n') 94 95 # Analyze the output. Sample: 96 # [ OK ] graphics_GpuReset 97 # [ FAILED ] graphics_GpuReset 98 results = summary.splitlines() 99 if not results: 100 f.close() 101 raise error.TestFail('Failed: No output from test. Check /tmp/' + 102 'test_that_latest/graphics_GpuReset/summary.txt' + 103 ' for details.') 104 # Analyze summary and count number of passes. 105 pass_count = 0 106 for line in results: 107 if gpu_family == 'stoney': 108 if "passed" in line: 109 pass_count += 1 110 if "failed" in line: 111 raise error.TestFail('Failed: %s' % line) 112 else: 113 if line.strip().startswith('[ OK ] graphics_GpuReset'): 114 pass_count += 1 115 if line.strip().startswith('[ FAILED ] graphics_GpuReset'): 116 msg = line.strip()[30:] 117 failed_msg = 'Test failed with %s' % msg 118 raise error.TestFail('Failed: %s' % failed_msg) 119 f.close() 120 121 # Final chance to fail. 122 if pass_count != self.loops: 123 failed_msg = 'Test failed with incomplete output. System hung? ' 124 failed_msg += '(pass_count=%d of %d)' % (pass_count, self.loops) 125 raise error.TestFail('Failed: %s' % failed_msg) 126 127 # We need to wait a bit for X to come back after the 'start ui'. 128 time.sleep(5) 129