Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(111)

Side by Side Diff: Tools/Scripts/webkitpy/test/main.py

Issue 654063002: Switch webkitpy to use the typ test framework (delete webkitpy.test). (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: fix typo for bot_test_expectations Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 # Copyright (C) 2012 Google, Inc.
2 # Copyright (C) 2010 Chris Jerdonek (cjerdonek@webkit.org)
3 #
4 # Redistribution and use in source and binary forms, with or without
5 # modification, are permitted provided that the following conditions
6 # are met:
7 # 1. Redistributions of source code must retain the above copyright
8 # notice, this list of conditions and the following disclaimer.
9 # 2. Redistributions in binary form must reproduce the above copyright
10 # notice, this list of conditions and the following disclaimer in the
11 # documentation and/or other materials provided with the distribution.
12 #
13 # THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND
14 # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15 # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16 # DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR
17 # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18 # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
19 # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
20 # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
21 # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
22 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23
24 """unit testing code for webkitpy."""
25
26 import StringIO
27 import logging
28 import multiprocessing
29 import optparse
30 import os
31 import sys
32 import time
33 import traceback
34 import unittest
35
36 from webkitpy.common.webkit_finder import WebKitFinder
37 from webkitpy.common.system.filesystem import FileSystem
38 from webkitpy.common.system.executive import Executive
39 from webkitpy.test.finder import Finder
40 from webkitpy.test.printer import Printer
41 from webkitpy.test.runner import Runner, unit_test_name
42
43 _log = logging.getLogger(__name__)
44
45
46 up = os.path.dirname
47 webkit_root = up(up(up(up(up(os.path.abspath(__file__))))))
48
49
50 def main():
51 filesystem = FileSystem()
52 wkf = WebKitFinder(filesystem)
53 tester = Tester(filesystem, wkf)
54 tester.add_tree(wkf.path_from_webkit_base('Tools', 'Scripts'), 'webkitpy')
55
56 tester.skip(('webkitpy.common.checkout.scm.scm_unittest',), 'are really, rea lly, slow', 31818)
57 if sys.platform == 'win32':
58 tester.skip(('webkitpy.common.checkout', 'webkitpy.common.config', 'webk itpy.tool', 'webkitpy.w3c', 'webkitpy.layout_tests.layout_package.bot_test_expec tations'), 'fail horribly on win32', 54526)
59
60 # This only needs to run on Unix, so don't worry about win32 for now.
61 appengine_sdk_path = '/usr/local/google_appengine'
62 if os.path.exists(appengine_sdk_path):
63 if not appengine_sdk_path in sys.path:
64 sys.path.append(appengine_sdk_path)
65 import dev_appserver
66 from google.appengine.dist import use_library
67 use_library('django', '1.2')
68 dev_appserver.fix_sys_path()
69 tester.add_tree(wkf.path_from_webkit_base('Tools', 'TestResultServer'))
70 else:
71 _log.info('Skipping TestResultServer tests; the Google AppEngine Python SDK is not installed.')
72
73 return not tester.run()
74
75
76 class Tester(object):
77 def __init__(self, filesystem=None, webkit_finder=None):
78 self.filesystem = filesystem or FileSystem()
79 self.executive = Executive()
80 self.finder = Finder(self.filesystem)
81 self.printer = Printer(sys.stderr)
82 self.webkit_finder = webkit_finder or WebKitFinder(self.filesystem)
83 self._options = None
84
85 def add_tree(self, top_directory, starting_subdirectory=None):
86 self.finder.add_tree(top_directory, starting_subdirectory)
87
88 def skip(self, names, reason, bugid):
89 self.finder.skip(names, reason, bugid)
90
91 def _parse_args(self, argv):
92 parser = optparse.OptionParser(usage='usage: %prog [options] [args...]')
93 parser.add_option('-a', '--all', action='store_true', default=False,
94 help='run all the tests')
95 parser.add_option('-c', '--coverage', action='store_true', default=False ,
96 help='generate code coverage info')
97 parser.add_option('-j', '--child-processes', action='store', type='int', default=(1 if sys.platform == 'win32' else multiprocessing.cpu_count()),
98 help='number of tests to run in parallel (default=%def ault)')
99 parser.add_option('-p', '--pass-through', action='store_true', default=F alse,
100 help='be debugger friendly by passing captured output through to the system')
101 parser.add_option('-q', '--quiet', action='store_true', default=False,
102 help='run quietly (errors, warnings, and progress only )')
103 parser.add_option('-t', '--timing', action='store_true', default=False,
104 help='display per-test execution time (implies --verbo se)')
105 parser.add_option('-v', '--verbose', action='count', default=0,
106 help='verbose output (specify once for individual test results, twice for debug messages)')
107
108 parser.epilog = ('[args...] is an optional list of modules, test_classes , or individual tests. '
109 'If no args are given, all the tests will be run.')
110
111 return parser.parse_args(argv)
112
113 def run(self):
114 argv = sys.argv[1:]
115 self._options, args = self._parse_args(argv)
116
117 # Make sure PYTHONPATH is set up properly.
118 sys.path = self.finder.additional_paths(sys.path) + sys.path
119
120 # FIXME: coverage needs to be in sys.path for its internal imports to wo rk.
121 thirdparty_path = self.webkit_finder.path_from_webkit_base('Tools', 'Scr ipts', 'webkitpy', 'thirdparty')
122 if not thirdparty_path in sys.path:
123 sys.path.append(thirdparty_path)
124
125 self.printer.configure(self._options)
126
127 # Do this after configuring the printer, so that logging works properly.
128 if self._options.coverage:
129 argv = ['-j', '1'] + [arg for arg in argv if arg not in ('-c', '--co verage', '-j', '--child-processes')]
130 _log.warning('Checking code coverage, so running things serially')
131 return self._run_under_coverage(argv)
132
133 self.finder.clean_trees()
134
135 names = self.finder.find_names(args, self._options.all)
136 if not names:
137 _log.error('No tests to run')
138 return False
139
140 return self._run_tests(names)
141
142 def _run_under_coverage(self, argv):
143 # coverage doesn't run properly unless its parent dir is in PYTHONPATH.
144 # This means we need to add that dir to the environment. Also, the
145 # report output is best when the paths are relative to the Scripts dir.
146 dirname = self.filesystem.dirname
147 script_dir = dirname(dirname(dirname(__file__)))
148 thirdparty_dir = self.filesystem.join(script_dir, 'webkitpy', 'thirdpart y')
149
150 env = os.environ.copy()
151 python_path = env.get('PYTHONPATH', '')
152 python_path = python_path + os.pathsep + thirdparty_dir
153 env['PYTHONPATH'] = python_path
154
155 prefix_cmd = [sys.executable, 'webkitpy/thirdparty/coverage']
156 exit_code = self.executive.call(prefix_cmd + ['run', __file__] + argv, c wd=script_dir, env=env)
157 if not exit_code:
158 exit_code = self.executive.call(prefix_cmd + ['report', '--omit', 'w ebkitpy/thirdparty/*,/usr/*,/Library/*'], cwd=script_dir, env=env)
159 return (exit_code == 0)
160
161 def _run_tests(self, names):
162 self.printer.write_update("Checking imports ...")
163 if not self._check_imports(names):
164 return False
165
166 self.printer.write_update("Finding the individual test methods ...")
167 loader = unittest.TestLoader()
168 tests = self._test_names(loader, names)
169
170 self.printer.write_update("Running the tests ...")
171 self.printer.num_tests = len(tests)
172 start = time.time()
173 test_runner = Runner(self.printer, loader, self.webkit_finder)
174 test_runner.run(tests, self._options.child_processes)
175
176 self.printer.print_result(time.time() - start)
177
178 return not self.printer.num_errors and not self.printer.num_failures
179
180 def _check_imports(self, names):
181 for name in names:
182 if self.finder.is_module(name):
183 # if we failed to load a name and it looks like a module,
184 # try importing it directly, because loadTestsFromName()
185 # produces lousy error messages for bad modules.
186 try:
187 __import__(name)
188 except ImportError:
189 _log.fatal('Failed to import %s:' % name)
190 self._log_exception()
191 return False
192 return True
193
194 def _test_names(self, loader, names):
195 tests = []
196 for name in names:
197 tests.extend(self._all_test_names(loader.loadTestsFromName(name, Non e)))
198 return tests
199
200 def _all_test_names(self, suite):
201 names = []
202 if hasattr(suite, '_tests'):
203 for t in suite._tests:
204 names.extend(self._all_test_names(t))
205 else:
206 names.append(unit_test_name(suite))
207 return names
208
209 def _log_exception(self):
210 s = StringIO.StringIO()
211 traceback.print_exc(file=s)
212 for l in s.buflist:
213 _log.error(' ' + l.rstrip())
214
215
216
217 if __name__ == '__main__':
218 sys.exit(main())
OLDNEW
« no previous file with comments | « Tools/Scripts/webkitpy/test/finder_unittest.py ('k') | Tools/Scripts/webkitpy/test/main_unittest.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698