Home | History | Annotate | Download | only in bin
      1 # Copyright Martin J. Bligh, Andy Whitcroft, 2006
      2 #
      3 # Shell class for a test, inherited by all individual tests
      4 #
      5 # Methods:
      6 #       __init__        initialise
      7 #       initialize      run once for each job
      8 #       setup           run once for each new version of the test installed
      9 #       run             run the test (wrapped by job.run_test())
     10 #
     11 # Data:
     12 #       job             backreference to the job this test instance is part of
     13 #       outputdir       eg. results/<job>/<testname.tag>
     14 #       resultsdir      eg. results/<job>/<testname.tag>/results
     15 #       profdir         eg. results/<job>/<testname.tag>/profiling
     16 #       debugdir        eg. results/<job>/<testname.tag>/debug
     17 #       bindir          eg. tests/<test>
     18 #       src             eg. tests/<test>/src
     19 #       tmpdir          eg. tmp/<testname.tag>
     20 
     21 import os, logging, resource, glob
     22 
     23 from autotest_lib.client.common_lib import utils
     24 from autotest_lib.client.common_lib import test as common_test
     25 from autotest_lib.client.bin import os_dep
     26 
     27 
     28 class test(common_test.base_test):
     29     # Segmentation fault handling is something that is desirable only for
     30     # client side tests.
     31     def configure_crash_handler(self):
     32         """
     33         Configure the crash handler by:
     34          * Setting up core size to unlimited
     35          * Putting an appropriate crash handler on /proc/sys/kernel/core_pattern
     36          * Create files that the crash handler will use to figure which tests
     37            are active at a given moment
     38 
     39         The crash handler will pick up the core file and write it to
     40         self.debugdir, and perform analysis on it to generate a report. The
     41         program also outputs some results to syslog.
     42 
     43         If multiple tests are running, an attempt to verify if we still have
     44         the old PID on the system process table to determine whether it is a
     45         parent of the current test execution. If we can't determine it, the
     46         core file and the report file will be copied to all test debug dirs.
     47         """
     48         self.crash_handling_enabled = False
     49 
     50         # make sure this script will run with a new enough python to work
     51         cmd = ("python -c 'import sys; "
     52                "print sys.version_info[0], sys.version_info[1]'")
     53         result = utils.run(cmd, ignore_status=True)
     54         if result.exit_status != 0:
     55             logging.warning('System python is too old, crash handling disabled')
     56             return
     57         major, minor = [int(x) for x in result.stdout.strip().split()]
     58         if (major, minor) < (2, 4):
     59             logging.warning('System python is too old, crash handling disabled')
     60             return
     61 
     62         self.pattern_file = '/proc/sys/kernel/core_pattern'
     63         try:
     64             # Enable core dumps
     65             resource.setrlimit(resource.RLIMIT_CORE, (-1, -1))
     66             # Trying to backup core pattern and register our script
     67             self.core_pattern_backup = open(self.pattern_file, 'r').read()
     68             pattern_file = open(self.pattern_file, 'w')
     69             tools_dir = os.path.join(self.autodir, 'tools')
     70             crash_handler_path = os.path.join(tools_dir, 'crash_handler.py')
     71             pattern_file.write('|' + crash_handler_path + ' %p %t %u %s %h %e')
     72             # Writing the files that the crash handler is going to use
     73             self.debugdir_tmp_file = ('/tmp/autotest_results_dir.%s' %
     74                                       os.getpid())
     75             utils.open_write_close(self.debugdir_tmp_file, self.debugdir + "\n")
     76         except Exception, e:
     77             logging.warning('Crash handling disabled: %s', e)
     78         else:
     79             self.crash_handling_enabled = True
     80             try:
     81                 os_dep.command('gdb')
     82             except ValueError:
     83                 logging.warning('Could not find GDB installed. Crash handling '
     84                                 'will operate with limited functionality')
     85             logging.debug('Crash handling enabled')
     86 
     87 
     88     def crash_handler_report(self):
     89         """
     90         If core dumps are found on the debugdir after the execution of the
     91         test, let the user know.
     92         """
     93         if self.crash_handling_enabled:
     94             # Remove the debugdir info file
     95             os.unlink(self.debugdir_tmp_file)
     96             # Restore the core pattern backup
     97             try:
     98                 utils.open_write_close(self.pattern_file,
     99                                        self.core_pattern_backup)
    100             except EnvironmentError:
    101                 pass
    102             # Let the user know if core dumps were generated during the test
    103             core_dirs = glob.glob('%s/crash.*' % self.debugdir)
    104             if core_dirs:
    105                 logging.warning('Programs crashed during test execution')
    106                 for dir in core_dirs:
    107                     logging.warning('Please verify %s for more info', dir)
    108 
    109 
    110 def runtest(job, url, tag, args, dargs):
    111     # Leave some autotest bread crumbs in the system logs.
    112     utils.system('logger "autotest runtest %s"' % url, ignore_status=True)
    113     common_test.runtest(job, url, tag, args, dargs, locals(), globals(),
    114                         job.sysinfo.log_before_each_test,
    115                         job.sysinfo.log_after_each_test,
    116                         job.sysinfo.log_before_each_iteration,
    117                         job.sysinfo.log_after_each_iteration)
    118