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