unittest_suite.py revision 3de2a76fa5e272503f924b5cd9d100931bed1e7f
1#!/usr/bin/python -u 2 3import os, sys, unittest, optparse 4import common 5from autotest_lib.utils import parallel 6 7 8root = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) 9 10parser = optparse.OptionParser() 11parser.add_option("-r", action="store", type="string", dest="start", 12 default='', 13 help="root directory to start running unittests") 14parser.add_option("--full", action="store_true", dest="full", default=False, 15 help="whether to run the shortened version of the test") 16parser.add_option("--debug", action="store_true", dest="debug", default=False, 17 help="run in debug mode") 18 19 20LONG_TESTS = set(( 21 'monitor_db_unittest.py', 22 'barrier_unittest.py', 23 'migrate_unittest.py', 24 'frontend_unittest.py', 25 'client_compilation_unittest.py' 26 )) 27 28DEPENDENCIES = { 29 # Annotate dependencies here. The format is 30 # module: [list of modules on which it is dependent] 31 # (All modules in the list must run before this module can) 32 33 # Note: Do not make a short test dependent on a long one. This will cause 34 # the suite to fail if it is run without the --full flag, since the module 35 # that the short test depends on will not be run. 36 37 38 # The next two dependencies are not really dependencies. This is actually a 39 # hack to keep these three modules from running at the same time, since they 40 # all create and destroy a database with the same name. 41 'autotest_lib.frontend.frontend_unittest': 42 ['autotest_lib.migrate.migrate_unittest'], 43 44 'autotest_lib.scheduler.monitor_db_unittest': 45 ['autotest_lib.frontend.frontend_unittest', 46 'autotest_lib.migrate.migrate_unittest'], 47} 48 49modules = [] 50 51 52def lister(full, dirname, files): 53 for f in files: 54 if f.endswith('_unittest.py'): 55 if not full and f in LONG_TESTS: 56 continue 57 temp = os.path.join(dirname, f).strip('.py') 58 mod_name = ['autotest_lib'] + temp[len(root)+1:].split('/') 59 modules.append(mod_name) 60 61 62def run_test(mod_name): 63 if not options.debug: 64 parallel.redirect_io() 65 66 print "Running %s" % '.'.join(mod_name) 67 mod = common.setup_modules.import_module(mod_name[-1], 68 '.'.join(mod_name[:-1])) 69 test = unittest.defaultTestLoader.loadTestsFromModule(mod) 70 suite = unittest.TestSuite(test) 71 runner = unittest.TextTestRunner(verbosity=2) 72 result = runner.run(suite) 73 if result.errors or result.failures: 74 raise Exception("%s failed" % '.'.join(mod_name)) 75 76 77def run_tests(start, full=False): 78 os.path.walk(start, lister, full) 79 80 functions = {} 81 names_to_functions = {} 82 for module in modules: 83 # Create a function that'll test a particular module. module=module 84 # is a hack to force python to evaluate the params now. We then 85 # rename the function to make error reporting nicer. 86 run_module = lambda module=module: run_test(module) 87 name = '.'.join(module) 88 run_module.__name__ = name 89 names_to_functions[name] = run_module 90 functions[run_module] = set() 91 92 for fn, deps in DEPENDENCIES.iteritems(): 93 if fn in names_to_functions: 94 functions[names_to_functions[fn]] = set( 95 names_to_functions[dep] for dep in deps) 96 97 try: 98 dargs = {} 99 if options.debug: 100 dargs['max_simultaneous_procs'] = 1 101 pe = parallel.ParallelExecute(functions, **dargs) 102 pe.run_until_completion() 103 except parallel.ParallelError, err: 104 return err.errors 105 return [] 106 107 108def main(): 109 global options, args 110 options, args = parser.parse_args() 111 if args: 112 parser.error('Unexpected argument(s): %s' % args) 113 parser.print_help() 114 sys.exit(1) 115 116 # Strip the arguments off the command line, so that the unit tests do not 117 # see them. 118 sys.argv = [sys.argv[0]] 119 120 errors = run_tests(os.path.join(root, options.start), options.full) 121 if errors: 122 print "%d tests resulted in an error/failure:" % len(errors) 123 for error in errors: 124 print "\t%s" % error 125 sys.exit(1) 126 else: 127 print "All passed!" 128 sys.exit(0) 129 130if __name__ == "__main__": 131 main() 132