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(test.test):
     22   """
     23   Reset the GPU and check recovery mechanism.
     24   """
     25   version = 1
     26   preserve_srcdir = True
     27   loops = 1
     28   GSC = None
     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     self.GSC = graphics_utils.GraphicsStateChecker(raise_error_on_hang=False)
     39 
     40   def cleanup(self):
     41     if self.GSC:
     42       self.GSC.finalize()
     43 
     44   def run_once(self, options=''):
     45     exefile = os.path.join(self.srcdir, 'gpureset')
     46     if not os.path.isfile(exefile):
     47       raise error.TestFail('Failed to locate gpureset executable (' +
     48                            exefile + '). Test setup error.')
     49 
     50     options = ''
     51     cmd = '%s %s' % (exefile, options)
     52 
     53     # If UI is running, we must stop it and restore later.
     54     need_restart_ui = False
     55     status_output = utils.system_output('initctl status ui')
     56     # If chrome is running, result will be similar to:
     57     #   ui start/running, process 11895
     58     logging.info('initctl status ui returns: %s', status_output)
     59     need_restart_ui = status_output.startswith('ui start')
     60     summary = ''
     61 
     62     # Run the gpureset test in a loop to stress the recovery.
     63     for i in range(1, self.loops + 1):
     64       summary += 'graphics_GpuReset iteration %d of %d\n' % (i, self.loops)
     65       if need_restart_ui:
     66         summary += 'initctl stop ui\n'
     67         utils.system('initctl stop ui', ignore_status=True)
     68         # TODO(ihf): Remove this code if no improvement for issue 409019.
     69         logging.info('Make sure chrome is dead before triggering hang.')
     70         utils.system('killall -9 chrome', ignore_status=True)
     71         time.sleep(3)
     72       try:
     73         summary += utils.system_output(cmd, retain_output=True)
     74         summary += '\n'
     75       finally:
     76         if need_restart_ui:
     77           summary += 'initctl start ui\n'
     78           utils.system('initctl start ui')
     79 
     80     # Write a copy of stdout to help debug failures.
     81     results_path = os.path.join(self.outputdir, 'summary.txt')
     82     f = open(results_path, 'w+')
     83     f.write('# need ui restart: %s\n' % need_restart_ui)
     84     f.write('# ---------------------------------------------------\n')
     85     f.write('# [' + cmd + ']\n')
     86     f.write(summary)
     87     f.write('\n# -------------------------------------------------\n')
     88     f.write('# [graphics_GpuReset.py postprocessing]\n')
     89 
     90     # Analyze the output. Sample:
     91     # [       OK ] graphics_GpuReset
     92     # [  FAILED  ] graphics_GpuReset
     93     results = summary.splitlines()
     94     if not results:
     95       f.close()
     96       raise error.TestFail('No output from test. Check /tmp/' +
     97                            'test_that_latest/graphics_GpuReset/summary.txt' +
     98                            ' for details.')
     99     # Analyze summary and count number of passes.
    100     pass_count = 0
    101     for line in results:
    102       if line.strip().startswith('[       OK ] graphics_GpuReset'):
    103         pass_count += 1
    104       if line.strip().startswith('[  FAILED  ] graphics_GpuReset'):
    105         msg = line.strip()[30:]
    106         failed_msg = 'Test failed with %s' % msg
    107         raise error.TestFail(failed_msg)
    108     f.close()
    109 
    110     # Final chance to fail.
    111     if pass_count != self.loops:
    112       failed_msg = 'Test failed with incomplete output. System hung? '
    113       failed_msg += '(pass_count=%d of %d)' % (pass_count, self.loops)
    114       raise error.TestFail(failed_msg)
    115 
    116     # We need to wait a bit for X to come back after the 'start ui'.
    117     time.sleep(5)
    118 
    119     keyvals = self.GSC.get_memory_keyvals()
    120     for key, val in keyvals.iteritems():
    121       self.output_perf_value(description=key, value=val, units='bytes',
    122                              higher_is_better=False)
    123