Changeset 122643 in webkit
- Timestamp:
- Jul 13, 2012 4:36:29 PM (12 years ago)
- Location:
- trunk/Tools
- Files:
-
- 4 edited
- 1 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/Tools/ChangeLog
r122632 r122643 1 2012-07-13 Dirk Pranke <dpranke@chromium.org> 2 3 webkitpy: split printing/logging code for test-webkitpy out into a new class 4 https://bugs.webkit.org/show_bug.cgi?id=91282 5 6 Reviewed by Ojan Vafai. 7 8 This patch is the first step at splitting all of the 9 printing/logging code out separately from the actual 10 test-running code. 11 12 This is just moving stuff around; no new functionality and no 13 new tests needed. 14 15 * Scripts/webkitpy/test/finder_unittest.py: 16 (FinderTest.setUp): 17 * Scripts/webkitpy/test/main.py: 18 (Tester.__init__): 19 (Tester._parse_args): 20 (Tester.run): 21 (Tester._run_tests): 22 (Tester._log_exception): 23 * Scripts/webkitpy/test/main_unittest.py: 24 (TesterTest.test_no_tests_found): 25 * Scripts/webkitpy/test/printer.py: Added. 26 (Printer): 27 (Printer.__init__): 28 (Printer.configure): 29 (Printer.configure.filter): 30 (_CaptureAndPassThroughStream): 31 (_CaptureAndPassThroughStream.__init__): 32 (_CaptureAndPassThroughStream.write): 33 (_CaptureAndPassThroughStream._message_is_from_pdb): 34 (_CaptureAndPassThroughStream.flush): 35 (_CaptureAndPassThroughStream.getvalue): 36 1 37 2012-07-13 James Simonsen <simonjam@chromium.org> 2 38 -
trunk/Tools/Scripts/webkitpy/test/finder_unittest.py
r122536 r122643 50 50 self.log_handler = None 51 51 for h in self.root_logger.handlers: 52 if getattr(h, 'name', None) == 'webkitpy.test. main':52 if getattr(h, 'name', None) == 'webkitpy.test.printer': 53 53 self.log_handler = h 54 54 break -
trunk/Tools/Scripts/webkitpy/test/main.py
r122548 r122643 26 26 import logging 27 27 import optparse 28 import os29 28 import StringIO 30 29 import sys … … 33 32 34 33 from webkitpy.common.system.filesystem import FileSystem 35 from webkitpy.common.system import outputcapture36 34 from webkitpy.test.finder import Finder 35 from webkitpy.test.printer import Printer 37 36 from webkitpy.test.runner import Runner 38 37 … … 43 42 def __init__(self, filesystem=None): 44 43 self.finder = Finder(filesystem or FileSystem()) 45 self.stream = sys.stderr 44 self.printer = Printer(sys.stderr) 45 self._options = None 46 46 47 47 def add_tree(self, top_directory, starting_subdirectory=None): … … 51 51 parser = optparse.OptionParser(usage='usage: %prog [options] [args...]') 52 52 parser.add_option('-a', '--all', action='store_true', default=False, 53 help='run all the tests') ,53 help='run all the tests') 54 54 parser.add_option('-c', '--coverage', action='store_true', default=False, 55 help='generate code coverage info (requires http://pypi.python.org/pypi/coverage)') ,55 help='generate code coverage info (requires http://pypi.python.org/pypi/coverage)') 56 56 parser.add_option('-q', '--quiet', action='store_true', default=False, 57 help='run quietly (errors, warnings, and progress only)') ,57 help='run quietly (errors, warnings, and progress only)') 58 58 parser.add_option('-t', '--timing', action='store_true', default=False, 59 help='display per-test execution time (implies --verbose)') ,59 help='display per-test execution time (implies --verbose)') 60 60 parser.add_option('-v', '--verbose', action='count', default=0, 61 61 help='verbose output (specify once for individual test results, twice for debug messages)') … … 70 70 return parser.parse_args() 71 71 72 def _configure(self, options):73 self._options = options74 75 if options.timing:76 # --timing implies --verbose77 options.verbose = max(options.verbose, 1)78 79 log_level = logging.INFO80 if options.quiet:81 log_level = logging.WARNING82 elif options.verbose == 2:83 log_level = logging.DEBUG84 self._configure_logging(log_level)85 86 def _configure_logging(self, log_level):87 """Configure the root logger.88 89 Configure the root logger not to log any messages from webkitpy --90 except for messages from the autoinstall module. Also set the91 logging level as described below.92 """93 handler = logging.StreamHandler(self.stream)94 # We constrain the level on the handler rather than on the root95 # logger itself. This is probably better because the handler is96 # configured and known only to this module, whereas the root logger97 # is an object shared (and potentially modified) by many modules.98 # Modifying the handler, then, is less intrusive and less likely to99 # interfere with modifications made by other modules (e.g. in unit100 # tests).101 handler.name = __name__102 handler.setLevel(log_level)103 formatter = logging.Formatter("%(message)s")104 handler.setFormatter(formatter)105 106 logger = logging.getLogger()107 logger.addHandler(handler)108 logger.setLevel(logging.NOTSET)109 110 # Filter out most webkitpy messages.111 #112 # Messages can be selectively re-enabled for this script by updating113 # this method accordingly.114 def filter(record):115 """Filter out autoinstall and non-third-party webkitpy messages."""116 # FIXME: Figure out a way not to use strings here, for example by117 # using syntax like webkitpy.test.__name__. We want to be118 # sure not to import any non-Python 2.4 code, though, until119 # after the version-checking code has executed.120 if (record.name.startswith("webkitpy.common.system.autoinstall") or121 record.name.startswith("webkitpy.test")):122 return True123 if record.name.startswith("webkitpy"):124 return False125 return True126 127 testing_filter = logging.Filter()128 testing_filter.filter = filter129 130 # Display a message so developers are not mystified as to why131 # logging does not work in the unit tests.132 _log.info("Suppressing most webkitpy logging while running unit tests.")133 handler.addFilter(testing_filter)134 135 72 def run(self): 136 options, args = self._parse_args()137 self. _configure(options)73 self._options, args = self._parse_args() 74 self.printer.configure(self._options) 138 75 139 76 self.finder.clean_trees() … … 150 87 try: 151 88 import webkitpy.thirdparty.autoinstalled.coverage as coverage 152 except ImportError , e:89 except ImportError: 153 90 _log.error("Failed to import 'coverage'; can't generate coverage numbers.") 154 91 return False … … 170 107 try: 171 108 __import__(name) 172 except ImportError , e:109 except ImportError: 173 110 _log.fatal('Failed to import %s:' % name) 174 111 self._log_exception() … … 178 115 179 116 test_suite = unittest.TestSuite(suites) 180 test_runner = Runner(self. stream, self._options, loader)117 test_runner = Runner(self.printer.stream, self._options, loader) 181 118 182 119 _log.debug("Running the tests.") 183 if self._options.pass_through:184 outputcapture.OutputCapture.stream_wrapper = _CaptureAndPassThroughStream185 120 result = test_runner.run(test_suite) 186 121 if self._options.coverage: … … 195 130 for l in s.buflist: 196 131 _log.error(' ' + l.rstrip()) 197 198 199 class _CaptureAndPassThroughStream(object):200 def __init__(self, stream):201 self._buffer = StringIO.StringIO()202 self._stream = stream203 204 def write(self, msg):205 self._stream.write(msg)206 207 # Note that we don't want to capture any output generated by the debugger208 # because that could cause the results of capture_output() to be invalid.209 if not self._message_is_from_pdb():210 self._buffer.write(msg)211 212 def _message_is_from_pdb(self):213 # We will assume that if the pdb module is in the stack then the output214 # is being generated by the python debugger (or the user calling something215 # from inside the debugger).216 import inspect217 import pdb218 stack = inspect.stack()219 return any(frame[1] == pdb.__file__.replace('.pyc', '.py') for frame in stack)220 221 def flush(self):222 self._stream.flush()223 224 def getvalue(self):225 return self._buffer.getvalue() -
trunk/Tools/Scripts/webkitpy/test/main_unittest.py
r119443 r122643 41 41 root_logger.handlers = [] 42 42 43 tester. stream = errors43 tester.printer.stream = errors 44 44 tester.finder.find_names = lambda args, skip_integration, run_all: [] 45 45 oc = OutputCapture() -
trunk/Tools/Scripts/webkitpy/test/printer.py
r122641 r122643 22 22 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 23 24 """unit testing code for webkitpy.""" 24 import logging 25 import StringIO 25 26 26 import logging27 import optparse28 import os29 import StringIO30 import sys31 import traceback32 import unittest33 34 from webkitpy.common.system.filesystem import FileSystem35 27 from webkitpy.common.system import outputcapture 36 from webkitpy.test.finder import Finder37 from webkitpy.test.runner import Runner38 28 39 29 _log = logging.getLogger(__name__) 40 30 41 31 42 class Tester(object):43 def __init__(self, filesystem=None):44 self. finder = Finder(filesystem or FileSystem())45 self. stream = sys.stderr32 class Printer(object): 33 def __init__(self, stream, options=None): 34 self.stream = stream 35 self.options = options 46 36 47 def add_tree(self, top_directory, starting_subdirectory=None): 48 self.finder.add_tree(top_directory, starting_subdirectory) 49 50 def _parse_args(self): 51 parser = optparse.OptionParser(usage='usage: %prog [options] [args...]') 52 parser.add_option('-a', '--all', action='store_true', default=False, 53 help='run all the tests'), 54 parser.add_option('-c', '--coverage', action='store_true', default=False, 55 help='generate code coverage info (requires http://pypi.python.org/pypi/coverage)'), 56 parser.add_option('-q', '--quiet', action='store_true', default=False, 57 help='run quietly (errors, warnings, and progress only)'), 58 parser.add_option('-t', '--timing', action='store_true', default=False, 59 help='display per-test execution time (implies --verbose)'), 60 parser.add_option('-v', '--verbose', action='count', default=0, 61 help='verbose output (specify once for individual test results, twice for debug messages)') 62 parser.add_option('--skip-integrationtests', action='store_true', default=False, 63 help='do not run the integration tests') 64 parser.add_option('-p', '--pass-through', action='store_true', default=False, 65 help='be debugger friendly by passing captured output through to the system') 66 67 parser.epilog = ('[args...] is an optional list of modules, test_classes, or individual tests. ' 68 'If no args are given, all the tests will be run.') 69 70 return parser.parse_args() 71 72 def _configure(self, options): 73 self._options = options 37 def configure(self, options): 38 self.options = options 74 39 75 40 if options.timing: … … 82 47 elif options.verbose == 2: 83 48 log_level = logging.DEBUG 84 self._configure_logging(log_level)85 49 86 def _configure_logging(self, log_level):87 """Configure the root logger.88 89 Configure the root logger not to log any messages from webkitpy --90 except for messages from the autoinstall module. Also set the91 logging level as described below.92 """93 50 handler = logging.StreamHandler(self.stream) 94 51 # We constrain the level on the handler rather than on the root … … 112 69 # Messages can be selectively re-enabled for this script by updating 113 70 # this method accordingly. 114 def filter (record):71 def filter_records(record): 115 72 """Filter out autoinstall and non-third-party webkitpy messages.""" 116 73 # FIXME: Figure out a way not to use strings here, for example by … … 126 83 127 84 testing_filter = logging.Filter() 128 testing_filter.filter = filter 85 testing_filter.filter = filter_records 129 86 130 87 # Display a message so developers are not mystified as to why … … 133 90 handler.addFilter(testing_filter) 134 91 135 def run(self): 136 options, args = self._parse_args() 137 self._configure(options) 138 139 self.finder.clean_trees() 140 141 names = self.finder.find_names(args, self._options.skip_integrationtests, self._options.all) 142 if not names: 143 _log.error('No tests to run') 144 return False 145 146 return self._run_tests(names) 147 148 def _run_tests(self, names): 149 if self._options.coverage: 150 try: 151 import webkitpy.thirdparty.autoinstalled.coverage as coverage 152 except ImportError, e: 153 _log.error("Failed to import 'coverage'; can't generate coverage numbers.") 154 return False 155 cov = coverage.coverage() 156 cov.start() 157 158 # Make sure PYTHONPATH is set up properly. 159 sys.path = self.finder.additional_paths(sys.path) + sys.path 160 161 _log.debug("Loading the tests...") 162 163 loader = unittest.defaultTestLoader 164 suites = [] 165 for name in names: 166 if self.finder.is_module(name): 167 # if we failed to load a name and it looks like a module, 168 # try importing it directly, because loadTestsFromName() 169 # produces lousy error messages for bad modules. 170 try: 171 __import__(name) 172 except ImportError, e: 173 _log.fatal('Failed to import %s:' % name) 174 self._log_exception() 175 return False 176 177 suites.append(loader.loadTestsFromName(name, None)) 178 179 test_suite = unittest.TestSuite(suites) 180 test_runner = Runner(self.stream, self._options, loader) 181 182 _log.debug("Running the tests.") 183 if self._options.pass_through: 92 if self.options.pass_through: 184 93 outputcapture.OutputCapture.stream_wrapper = _CaptureAndPassThroughStream 185 result = test_runner.run(test_suite)186 if self._options.coverage:187 cov.stop()188 cov.save()189 cov.report(show_missing=False)190 return result.wasSuccessful()191 192 def _log_exception(self):193 s = StringIO.StringIO()194 traceback.print_exc(file=s)195 for l in s.buflist:196 _log.error(' ' + l.rstrip())197 94 198 95
Note: See TracChangeset
for help on using the changeset viewer.