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