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