ronnie
2022-10-14 1504bb53e29d3d46222c0b3ea994fc494b48e153
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
# Copyright 2007 Google Inc. Released under the GPL v2
#
# Eric Li <ericli@google.com>
 
import logging, os, pickle, re, sys
import common
 
from autotest_lib.client.bin import job as client_job
from autotest_lib.client.common_lib import base_job
from autotest_lib.client.common_lib import error
from autotest_lib.client.common_lib import logging_manager
from autotest_lib.client.common_lib import packages
 
 
class setup_job(client_job.job):
    """
    setup_job is a job which runs client test setup() method at server side.
 
    This job is used to pre-setup client tests when development toolchain is not
    available at client.
    """
 
    def __init__(self, options):
        """
        Since setup_job is a client job but run on a server, it takes no control
        file as input. So client_job.__init__ is by-passed.
 
        @param options: an object passed in from command line OptionParser.
                        See all options defined on client/bin/autotest.
        """
        base_job.base_job.__init__(self, options=options)
        self._cleanup_debugdir_files()
        self._cleanup_results_dir()
        self.machine_dict_list = [{'hostname' : options.hostname}]
        # Client side tests should always run the same whether or not they are
        # running in the lab.
        self.in_lab = False
        self.pkgmgr = packages.PackageManager(
            self.autodir, run_function_dargs={'timeout':3600})
 
 
def init_test(options, testdir):
    """
    Instantiate a client test object from a given test directory.
 
    @param options Command line options passed in to instantiate a setup_job
                   which associates with this test.
    @param testdir The test directory.
    @returns A test object or None if failed to instantiate.
    """
 
    locals_dict = locals().copy()
    globals_dict = globals().copy()
 
    locals_dict['testdir'] = testdir
 
    job = setup_job(options=options)
    locals_dict['job'] = job
 
    test_name = os.path.split(testdir)[-1]
    outputdir = os.path.join(job.resultdir, test_name)
    try:
        os.makedirs(outputdir)
    except OSError:
        pass
    locals_dict['outputdir'] = outputdir
 
    sys.path.insert(0, testdir)
    client_test = None
    try:
        try:
            import_stmt = 'import %s' % test_name
            init_stmt = ('auto_test = %s.%s(job, testdir, outputdir)' %
                         (test_name, test_name))
            exec import_stmt + '\n' + init_stmt in locals_dict, globals_dict
            client_test = globals_dict['auto_test']
        except ImportError, e:
            # skips error if test is control file without python test
            if re.search(test_name, str(e)):
                pass
            # give the user a warning if there is an import error.
            else:
                logging.exception('%s import error: %s.  Skipping %s' %
                              (test_name, e, test_name))
        except Exception, e:
            # Log other errors (e.g., syntax errors) and collect the test.
            logging.exception("%s: %s", test_name, e)
    finally:
        sys.path.pop(0) # pop up testbindir
    return client_test
 
 
def load_all_client_tests(options):
    """
    Load and instantiate all client tests.
 
    This function is inspired from runtest() on client/common_lib/test.py.
 
    @param options: an object passed in from command line OptionParser.
                    See all options defined on client/bin/autotest.
 
    @return a tuple containing the list of all instantiated tests and
            a list of tests that failed to instantiate.
    """
 
    local_namespace = locals().copy()
    global_namespace = globals().copy()
 
    all_tests = []
    broken_tests = []
    for test_base_dir in ['tests', 'site_tests']:
        testdir = os.path.join(os.environ['AUTODIR'], test_base_dir)
        for test_name in sorted(os.listdir(testdir)):
            client_test = init_test(options, os.path.join(testdir, test_name))
            if client_test:
                all_tests.append(client_test)
            else:
                broken_tests.append(test_name)
    return all_tests, broken_tests
 
 
def setup_test(client_test):
    """
    Direct invoke test.setup() method.
 
    @returns A boolean to represent success or not.
    """
 
    # TODO: check if its already build. .version? hash?
    test_name = client_test.__class__.__name__
    cwd = os.getcwd()
    good_setup = False
    try:
        try:
            outputdir = os.path.join(client_test.job.resultdir, test_name)
            try:
                os.makedirs(outputdir)
                os.chdir(outputdir)
            except OSError:
                pass
            logging.info('setup %s.' % test_name)
            client_test.setup()
 
            # Touch .version file under src to prevent further setup on client
            # host. See client/common_lib/utils.py update_version()
            if os.path.exists(client_test.srcdir):
                versionfile = os.path.join(client_test.srcdir, '.version')
                pickle.dump(client_test.version, open(versionfile, 'w'))
            good_setup = True
        except Exception, err:
            logging.error(err)
            raise error.AutoservError('Failed to build client test %s on '
                                      'server.' % test_name)
    finally:
        # back to original working dir
        os.chdir(cwd)
    return good_setup
 
 
def setup_tests(options):
    """
    Load and instantiate all client tests.
 
    This function is inspired from runtest() on client/common_lib/test.py.
 
    @param options: an object passed in from command line OptionParser.
                    See all options defined on client/bin/autotest.
    """
 
    assert options.client_test_setup, 'Specify prebuild client tests on the ' \
                                      'command line.'
 
    requested_tests = options.client_test_setup.split(',')
    candidates, broken_tests = load_all_client_tests(options)
 
    failed_tests = []
    if 'all' in requested_tests:
        need_to_setup = candidates
        failed_tests += broken_tests
    else:
        need_to_setup = []
        for candidate in candidates:
            if candidate.__class__.__name__ in requested_tests:
                need_to_setup.append(candidate)
        for broken_test in broken_tests:
            if broken_test in requested_tests:
                failed_tests.append(broken_test)
 
    if need_to_setup:
        cwd = os.getcwd()
        os.chdir(need_to_setup[0].job.clientdir)
        os.system('tools/make_clean')
        os.chdir(cwd)
    elif not failed_tests:
        logging.error('### No test setup candidates ###')
        raise error.AutoservError('No test setup candidates.')
 
    for client_test in need_to_setup:
        good_setup = setup_test(client_test)
        if not good_setup:
            failed_tests.append(client_test.__class__.__name__)
 
    logging.info('############################# SUMMARY '
                 '#############################')
 
    # Print out tests that failed
    if failed_tests:
        logging.info('Finished setup -- The following tests failed')
        for failed_test in failed_tests:
            logging.info(failed_test)
    else:
        logging.info('Finished setup -- All tests built successfully')
    logging.info('######################### END SUMMARY '
                 '##############################')
    if failed_tests:
        raise error.AutoservError('Finished setup with errors.')