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