OLD | NEW |
1 #!/usr/bin/python -u | 1 #!/usr/bin/python -u |
2 | 2 |
3 import os, sys, unittest, optparse | 3 import os, sys, unittest, optparse |
4 import common | 4 import common |
5 from autotest_lib.utils import parallel | 5 from autotest_lib.utils import parallel |
6 from autotest_lib.client.common_lib.test_utils import unittest as custom_unittes
t | 6 from autotest_lib.client.common_lib.test_utils import unittest as custom_unittes
t |
7 | 7 |
8 parser = optparse.OptionParser() | 8 parser = optparse.OptionParser() |
9 parser.add_option("-r", action="store", type="string", dest="start", | 9 parser.add_option("-r", action="store", type="string", dest="start", |
10 default='', | 10 default='', |
11 help="root directory to start running unittests") | 11 help="root directory to start running unittests") |
12 parser.add_option("--full", action="store_true", dest="full", default=False, | 12 parser.add_option("--full", action="store_true", dest="full", default=False, |
13 help="whether to run the shortened version of the test") | 13 help="whether to run the shortened version of the test") |
14 parser.add_option("--debug", action="store_true", dest="debug", default=False, | 14 parser.add_option("--debug", action="store_true", dest="debug", default=False, |
15 help="run in debug mode") | 15 help="run in debug mode") |
16 parser.add_option("--skip-tests", dest="skip_tests", default=[], | 16 parser.add_option("--skip-tests", dest="skip_tests", default=[], |
17 help="A space separated list of tests to skip") | 17 help="A space separated list of tests to skip") |
18 | 18 |
| 19 parser.set_defaults(module_list=None) |
| 20 |
19 | 21 |
20 REQUIRES_DJANGO = set(( | 22 REQUIRES_DJANGO = set(( |
21 'monitor_db_unittest.py', | 23 'monitor_db_unittest.py', |
22 'monitor_db_functional_test.py', | 24 'monitor_db_functional_test.py', |
23 'monitor_db_cleanup_test.py', | 25 'monitor_db_cleanup_test.py', |
24 'frontend_unittest.py', | 26 'frontend_unittest.py', |
25 'csv_encoder_unittest.py', | 27 'csv_encoder_unittest.py', |
26 'rpc_interface_unittest.py', | 28 'rpc_interface_unittest.py', |
27 'models_test.py', | 29 'models_test.py', |
28 'scheduler_models_unittest.py', | 30 'scheduler_models_unittest.py', |
(...skipping 28 matching lines...) Expand all Loading... |
57 | 59 |
58 REQUIRES_PROTOBUFS = set(( | 60 REQUIRES_PROTOBUFS = set(( |
59 'job_serializer_unittest.py', | 61 'job_serializer_unittest.py', |
60 )) | 62 )) |
61 | 63 |
62 LONG_RUNTIME = set(( | 64 LONG_RUNTIME = set(( |
63 'base_barrier_unittest.py', | 65 'base_barrier_unittest.py', |
64 'logging_manager_test.py', | 66 'logging_manager_test.py', |
65 )) | 67 )) |
66 | 68 |
| 69 # This particular KVM autotest test is not a unittest |
| 70 SKIP = set(( |
| 71 'guest_test.py', |
| 72 )) |
| 73 |
67 LONG_TESTS = (REQUIRES_DJANGO | | 74 LONG_TESTS = (REQUIRES_DJANGO | |
68 REQUIRES_MYSQLDB | | 75 REQUIRES_MYSQLDB | |
69 REQUIRES_GWT | | 76 REQUIRES_GWT | |
70 REQUIRES_SIMPLEJSON | | 77 REQUIRES_SIMPLEJSON | |
71 REQUIRES_HTTPLIB2 | | 78 REQUIRES_HTTPLIB2 | |
72 REQUIRES_AUTH | | 79 REQUIRES_AUTH | |
73 REQUIRES_PROTOBUFS | | 80 REQUIRES_PROTOBUFS | |
74 LONG_RUNTIME) | 81 LONG_RUNTIME) |
75 | 82 |
76 | 83 |
(...skipping 19 matching lines...) Expand all Loading... |
96 test = ut_module.defaultTestLoader.loadTestsFromModule(mod) | 103 test = ut_module.defaultTestLoader.loadTestsFromModule(mod) |
97 suite = ut_module.TestSuite(test) | 104 suite = ut_module.TestSuite(test) |
98 runner = ut_module.TextTestRunner(verbosity=2) | 105 runner = ut_module.TextTestRunner(verbosity=2) |
99 result = runner.run(suite) | 106 result = runner.run(suite) |
100 if result.errors or result.failures: | 107 if result.errors or result.failures: |
101 msg = '%s had %d failures and %d errors.' | 108 msg = '%s had %d failures and %d errors.' |
102 msg %= '.'.join(mod_names), len(result.failures), len(result.errors) | 109 msg %= '.'.join(mod_names), len(result.failures), len(result.errors) |
103 raise TestFailure(msg) | 110 raise TestFailure(msg) |
104 | 111 |
105 | 112 |
106 def find_and_run_tests(start, options): | 113 def scan_for_modules(start, options): |
107 """ | 114 modules = [] |
108 Find and run Python unittest suites below the given directory. Only look | |
109 in subdirectories of start that are actual importable Python modules. | |
110 | 115 |
111 @param start: The absolute directory to look for tests under. | 116 skip_tests = SKIP |
112 @param options: optparse options. | |
113 """ | |
114 modules = [] | |
115 skip_tests = set() | |
116 if options.skip_tests: | 117 if options.skip_tests: |
117 skip_tests.update(options.skip_tests.split()) | 118 skip_tests.update(options.skip_tests.split()) |
118 | 119 |
119 for dirpath, subdirs, filenames in os.walk(start): | 120 for dirpath, subdirs, filenames in os.walk(start): |
120 # Only look in and below subdirectories that are python modules. | 121 # Only look in and below subdirectories that are python modules. |
121 if '__init__.py' not in filenames: | 122 if '__init__.py' not in filenames: |
122 if options.full: | 123 if options.full: |
123 for filename in filenames: | 124 for filename in filenames: |
124 if filename.endswith('.pyc'): | 125 if filename.endswith('.pyc'): |
125 os.unlink(os.path.join(dirpath, filename)) | 126 os.unlink(os.path.join(dirpath, filename)) |
126 # Skip all subdirectories below this one, it is not a module. | 127 # Skip all subdirectories below this one, it is not a module. |
127 del subdirs[:] | 128 del subdirs[:] |
128 if options.debug: | 129 if options.debug: |
129 print 'Skipping', dirpath | 130 print 'Skipping', dirpath |
130 continue # Skip this directory. | 131 continue # Skip this directory. |
131 | 132 |
132 # Look for unittest files. | 133 # Look for unittest files. |
133 for fname in filenames: | 134 for fname in filenames: |
134 if fname.endswith('_unittest.py') or fname.endswith('_test.py'): | 135 if fname.endswith('_unittest.py') or fname.endswith('_test.py'): |
135 if not options.full and fname in LONG_TESTS: | 136 if not options.full and fname in LONG_TESTS: |
136 continue | 137 continue |
137 if fname in skip_tests: | 138 if fname in skip_tests: |
138 continue | 139 continue |
139 path_no_py = os.path.join(dirpath, fname).rstrip('.py') | 140 path_no_py = os.path.join(dirpath, fname).rstrip('.py') |
140 assert path_no_py.startswith(ROOT) | 141 assert path_no_py.startswith(ROOT) |
141 names = path_no_py[len(ROOT)+1:].split('/') | 142 names = path_no_py[len(ROOT)+1:].split('/') |
142 modules.append(['autotest_lib'] + names) | 143 modules.append(['autotest_lib'] + names) |
143 if options.debug: | 144 if options.debug: |
144 print 'testing', path_no_py | 145 print 'testing', path_no_py |
| 146 return modules |
| 147 |
| 148 def find_and_run_tests(start, options): |
| 149 """ |
| 150 Find and run Python unittest suites below the given directory. Only look |
| 151 in subdirectories of start that are actual importable Python modules. |
| 152 |
| 153 @param start: The absolute directory to look for tests under. |
| 154 @param options: optparse options. |
| 155 """ |
| 156 if options.module_list: |
| 157 modules = [] |
| 158 for m in options.module_list: |
| 159 modules.append(m.split('.')) |
| 160 else: |
| 161 modules = scan_for_modules(start, options) |
145 | 162 |
146 if options.debug: | 163 if options.debug: |
147 print 'Number of test modules found:', len(modules) | 164 print 'Number of test modules found:', len(modules) |
148 | 165 |
149 functions = {} | 166 functions = {} |
150 for module_names in modules: | 167 for module_names in modules: |
151 # Create a function that'll test a particular module. module=module | 168 # Create a function that'll test a particular module. module=module |
152 # is a hack to force python to evaluate the params now. We then | 169 # is a hack to force python to evaluate the params now. We then |
153 # rename the function to make error reporting nicer. | 170 # rename the function to make error reporting nicer. |
154 run_module = lambda module=module_names: run_test(module, options) | 171 run_module = lambda module=module_names: run_test(module, options) |
155 name = '.'.join(module_names) | 172 name = '.'.join(module_names) |
156 run_module.__name__ = name | 173 run_module.__name__ = name |
157 functions[run_module] = set() | 174 functions[run_module] = set() |
158 | 175 |
159 try: | 176 try: |
160 dargs = {} | 177 dargs = {} |
161 if options.debug: | 178 if options.debug: |
162 dargs['max_simultaneous_procs'] = 1 | 179 dargs['max_simultaneous_procs'] = 1 |
163 pe = parallel.ParallelExecute(functions, **dargs) | 180 pe = parallel.ParallelExecute(functions, **dargs) |
164 pe.run_until_completion() | 181 pe.run_until_completion() |
165 except parallel.ParallelError, err: | 182 except parallel.ParallelError, err: |
166 return err.errors | 183 return err.errors |
167 return [] | 184 return [] |
168 | 185 |
169 | 186 |
170 def main(): | 187 def main(): |
171 options, args = parser.parse_args() | 188 options, args = parser.parse_args() |
172 if args: | 189 if args: |
173 parser.error('Unexpected argument(s): %s' % args) | 190 options.module_list = args |
174 parser.print_help() | |
175 sys.exit(1) | |
176 | 191 |
177 # Strip the arguments off the command line, so that the unit tests do not | 192 # Strip the arguments off the command line, so that the unit tests do not |
178 # see them. | 193 # see them. |
179 del sys.argv[1:] | 194 del sys.argv[1:] |
180 | 195 |
181 absolute_start = os.path.join(ROOT, options.start) | 196 absolute_start = os.path.join(ROOT, options.start) |
182 errors = find_and_run_tests(absolute_start, options) | 197 errors = find_and_run_tests(absolute_start, options) |
183 if errors: | 198 if errors: |
184 print "%d tests resulted in an error/failure:" % len(errors) | 199 print "%d tests resulted in an error/failure:" % len(errors) |
185 for error in errors: | 200 for error in errors: |
186 print "\t%s" % error | 201 print "\t%s" % error |
187 print "Rerun", sys.argv[0], "--debug to see the failure details." | 202 print "Rerun", sys.argv[0], "--debug to see the failure details." |
188 sys.exit(1) | 203 sys.exit(1) |
189 else: | 204 else: |
190 print "All passed!" | 205 print "All passed!" |
191 sys.exit(0) | 206 sys.exit(0) |
192 | 207 |
193 | 208 |
194 if __name__ == "__main__": | 209 if __name__ == "__main__": |
195 main() | 210 main() |
OLD | NEW |