| 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 |