setup_job.py revision 80f0078376f052d74af7bdae2975e577b0c7de7a
1# Copyright 2007 Google Inc. Released under the GPL v2 2# 3# Eric Li <ericli@google.com> 4 5import logging, os, pickle, re, sys 6import common 7 8from autotest_lib.client.bin import client_logging_config 9from autotest_lib.client.bin import job as client_job 10from autotest_lib.client.common_lib import base_job 11from autotest_lib.client.common_lib import error 12from autotest_lib.client.common_lib import logging_manager 13from autotest_lib.client.common_lib import packages 14 15 16class setup_job(client_job.job): 17 """ 18 setup_job is a job which runs client test setup() method at server side. 19 20 This job is used to pre-setup client tests when development toolchain is not 21 available at client. 22 """ 23 24 def __init__(self, options): 25 """ 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. 28 29 @param options: an object passed in from command line OptionParser. 30 See all options defined on client/bin/autotest. 31 """ 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() 38 self.pkgmgr = packages.PackageManager( 39 self.autodir, run_function_dargs={'timeout':3600}) 40 41 42def load_all_client_tests(options): 43 """ 44 Load and instantiate all client tests. 45 46 This function is inspired from runtest() on client/common_lib/test.py. 47 48 @param options: an object passed in from command line OptionParser. 49 See all options defined on client/bin/autotest. 50 51 @return a tuple containing the list of all instantiated tests and 52 a list of tests that failed to instantiate. 53 """ 54 55 local_namespace = locals().copy() 56 global_namespace = globals().copy() 57 58 all_tests = [] 59 broken_tests = [] 60 for test_base_dir in ['tests', 'site_tests']: 61 testdir = os.path.join(os.environ['AUTODIR'], test_base_dir) 62 for test_name in os.listdir(testdir): 63 job = setup_job(options=options) 64 testbindir = os.path.join(testdir, test_name) 65 local_namespace['testbindir'] = testbindir 66 67 outputdir = os.path.join(job.resultdir, 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 101 102 103def setup_tests(options): 104 """ 105 Load and instantiate all client tests. 106 107 This function is inspired from runtest() on client/common_lib/test.py. 108 109 @param options: an object passed in from command line OptionParser. 110 See all options defined on client/bin/autotest. 111 """ 112 113 assert options.client_test_setup, 'Specify prebuild client tests on the ' \ 114 'command line.' 115 116 requested_tests = options.client_test_setup.split(',') 117 candidates, broken_tests = load_all_client_tests(options) 118 119 failed_tests = [] 120 if 'all' in requested_tests: 121 need_to_setup = candidates 122 failed_tests += broken_tests 123 else: 124 need_to_setup = [] 125 for candidate in candidates: 126 if candidate.__class__.__name__ in requested_tests: 127 need_to_setup.append(candidate) 128 for broken_test in broken_tests: 129 if broken_test in requested_tests: 130 failed_tests.append(broken_test) 131 132 if need_to_setup: 133 cwd = os.getcwd() 134 os.chdir(need_to_setup[0].job.clientdir) 135 os.system('tools/make_clean') 136 os.chdir(cwd) 137 elif not failed_tests: 138 logging.error('### No test setup candidates ###') 139 raise error.AutoservError('No test setup candidates.') 140 141 for setup_test in need_to_setup: 142 test_name = setup_test.__class__.__name__ 143 try: 144 outputdir = os.path.join(setup_test.job.resultdir, test_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 161 logging.info('############################# SUMMARY ' 162 '#############################') 163 164 # Print out tests that failed 165 if failed_tests: 166 logging.info('Finished setup -- The following tests failed') 167 for failed_test in failed_tests: 168 logging.info(failed_test) 169 else: 170 logging.info('Finished setup -- All tests built successfully') 171 logging.info('######################### END SUMMARY ' 172 '##############################') 173 if failed_tests: 174 raise error.AutoservError('Finished setup with errors.') 175