Changeset 87596 in webkit
- Timestamp:
- May 27, 2011 7:28:00 PM (13 years ago)
- Location:
- trunk/Tools
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Tools/ChangeLog
r87594 r87596 1 2011-05-27 Dirk Pranke <dpranke@chromium.org> 2 3 Reviewed by Eric Seidel. 4 5 NRWT: clean up metered_stream code in preparation for 'nooverwriting' patch 6 https://bugs.webkit.org/show_bug.cgi?id=60326 7 8 This patch removes a lot of the complexity from the 9 metered_stream implementation that was unnecessary since there 10 was only one caller and the logic could be coordinated better. 11 12 There should be no functional changes in this patch, just code 13 getting deleted and cleaned up. 14 15 * Scripts/webkitpy/layout_tests/layout_package/metered_stream.py: 16 * Scripts/webkitpy/layout_tests/layout_package/metered_stream_unittest.py: 17 * Scripts/webkitpy/layout_tests/layout_package/printing.py: 18 * Scripts/webkitpy/layout_tests/layout_package/printing_unittest.py: 19 1 20 2011-05-27 Dirk Pranke <dpranke@chromium.org> 2 21 -
trunk/Tools/Scripts/webkitpy/layout_tests/layout_package/metered_stream.py
r59106 r87596 38 38 """ 39 39 40 import logging41 42 _log = logging.getLogger("webkitpy.layout_tests.metered_stream")43 44 45 40 class MeteredStream: 46 41 """This class is a wrapper around a stream that allows you to implement 47 42 meters (progress bars, etc.). 48 43 49 It can be used directly as a stream, by calling write(), but provides 50 two other methods for output, update(), and progress(). 44 It can be used directly as a stream, by calling write(), but also provides 45 a method called update() that will overwite prior updates(). 46 """ 51 47 52 In normal usage, update() will overwrite the output of the immediately 53 preceding update() (write() also will overwrite update()). So, calling 54 multiple update()s in a row can provide an updating status bar (note that 55 if an update string contains newlines, only the text following the last 56 newline will be overwritten/erased). 57 58 If the MeteredStream is constructed in "verbose" mode (i.e., by passing 59 verbose=true), then update() no longer overwrite a previous update(), and 60 instead the call is equivalent to write(), although the text is 61 actually sent to the logger rather than to the stream passed 62 to the constructor. 63 64 progress() is just like update(), except that if you are in verbose mode, 65 progress messages are not output at all (they are dropped). This is 66 used for things like progress bars which are presumed to be unwanted in 67 verbose mode. 68 69 Note that the usual usage for this class is as a destination for 70 a logger that can also be written to directly (i.e., some messages go 71 through the logger, some don't). We thus have to dance around a 72 layering inversion in update() for things to work correctly. 73 """ 74 75 def __init__(self, verbose, stream): 48 def __init__(self, stream): 76 49 """ 77 50 Args: 78 verbose: whether progress is a no-op and updates() aren't overwritten79 51 stream: output stream to write to 80 52 """ 53 self._stream = stream 81 54 self._dirty = False 82 self._verbose = verbose83 self._stream = stream84 55 self._last_update = "" 85 56 86 57 def write(self, txt): 87 58 """Write to the stream, overwriting and resetting the meter.""" 88 if self._dirty:89 self._write(txt)90 self._dirty = False91 self._last_update = ''92 else:93 self._stream.write(txt)94 59 95 def flush(self): 96 """Flush any buffered output.""" 97 self._stream.flush() 60 # This routine is called by the logging infrastructure, and 61 # must not call back into logging. It is not a public function. 62 self._overwrite(txt) 63 self._reset() 98 64 99 def progress(self, str):100 """ 101 Write a message to the stream that will get overwritten.65 def update(self, txt): 66 """Write a message that will be overwritten by subsequent update() or write() calls.""" 67 self._overwrite(txt) 102 68 103 This is used for progress updates that don't need to be preserved in 104 the log. If the MeteredStream was initialized with verbose==True, 105 then this output is discarded. We have this in case we are logging 106 lots of output and the update()s will get lost or won't work 107 properly (typically because verbose streams are redirected to files). 108 109 """ 110 if self._verbose: 111 return 112 self._write(str) 113 114 def update(self, str): 115 """ 116 Write a message that is also included when logging verbosely. 117 118 This routine preserves the same console logging behavior as progress(), 119 but will also log the message if verbose() was true. 120 121 """ 122 # Note this is a separate routine that calls either into the logger 123 # or the metering stream. We have to be careful to avoid a layering 124 # inversion (stream calling back into the logger). 125 if self._verbose: 126 _log.info(str) 127 else: 128 self._write(str) 129 130 def _write(self, str): 131 """Actually write the message to the stream.""" 132 133 # FIXME: Figure out if there is a way to detect if we're writing 134 # to a stream that handles CRs correctly (e.g., terminals). That might 135 # be a cleaner way of handling this. 136 69 def _overwrite(self, txt): 137 70 # Print the necessary number of backspaces to erase the previous 138 71 # message. … … 141 74 " " * len(self._last_update) + 142 75 "\b" * len(self._last_update)) 143 self._stream.write( str)144 last_newline = str.rfind("\n")145 self._last_update = str[(last_newline + 1):]76 self._stream.write(txt) 77 last_newline = txt.rfind("\n") 78 self._last_update = txt[(last_newline + 1):] 146 79 self._dirty = True 80 81 def _reset(self): 82 self._dirty = False 83 self._last_update = '' -
trunk/Tools/Scripts/webkitpy/layout_tests/layout_package/metered_stream_unittest.py
r66640 r87596 30 30 """Unit tests for metered_stream.py.""" 31 31 32 import os33 import optparse34 import pdb35 import sys36 32 import unittest 37 33 … … 43 39 def test_regular(self): 44 40 a = ArrayStream() 45 m = metered_stream.MeteredStream( verbose=False,stream=a)41 m = metered_stream.MeteredStream(stream=a) 46 42 self.assertTrue(a.empty()) 47 43 48 # basic test - note that the flush() is a no-op, but we include it 49 # for coverage. 44 # basic test 50 45 m.write("foo") 51 m.flush()52 46 exp = ['foo'] 53 47 self.assertEquals(a.get(), exp) … … 70 64 self.assertEquals(a.get(), exp) 71 65 72 m.progress("progress") 66 # now check that a write() does overwrite the update 67 m.write("foo") 73 68 exp.append('\b\b\b \b\b\b') 74 exp.append('progress')75 self.assertEquals(a.get(), exp)76 77 # now check that a write() does overwrite the progress bar78 m.write("foo")79 exp.append('\b\b\b\b\b\b\b\b \b\b\b\b\b\b\b\b')80 69 exp.append('foo') 81 70 self.assertEquals(a.get(), exp) … … 90 79 self.assertEquals(a.get(), ['foo\nbar', '\b\b\b \b\b\b', 'baz']) 91 80 92 def test_verbose(self):93 a = ArrayStream()94 m = metered_stream.MeteredStream(verbose=True, stream=a)95 self.assertTrue(a.empty())96 m.write("foo")97 self.assertEquals(a.get(), ['foo'])98 99 import logging100 b = ArrayStream()101 logger = logging.getLogger()102 handler = logging.StreamHandler(b)103 logger.addHandler(handler)104 m.update("bar")105 logger.handlers.remove(handler)106 self.assertEquals(a.get(), ['foo'])107 self.assertEquals(b.get(), ['bar\n'])108 109 m.progress("dropped")110 self.assertEquals(a.get(), ['foo'])111 self.assertEquals(b.get(), ['bar\n'])112 113 81 114 82 if __name__ == '__main__': -
trunk/Tools/Scripts/webkitpy/layout_tests/layout_package/printing.py
r87594 r87596 131 131 elif verbose: 132 132 switches = set(PRINT_EVERYTHING.split(',')) 133 switches.discard('one-line-progress') 133 134 else: 134 135 switches = set(PRINT_DEFAULT.split(',')) … … 208 209 self._stream = regular_output 209 210 210 self._meter = metered_stream.MeteredStream(options.verbose, 211 regular_output) 212 self._logging_handler = None 213 if configure_logging: 211 self._meter = None 212 if options.verbose: 213 self._logging_handler = _configure_logging(regular_output, options.verbose) 214 else: 215 self._meter = metered_stream.MeteredStream(regular_output) 214 216 self._logging_handler = _configure_logging(self._meter, options.verbose) 215 217 … … 347 349 if retrying: 348 350 action = "Retrying" 349 self._meter. progress("%s (%d%%): %d ran as expected, %d didn't,"351 self._meter.update("%s (%d%%): %d ran as expected, %d didn't," 350 352 " %d left" % (action, percent_complete, result_summary.expected, 351 353 result_summary.unexpected, result_summary.remaining)) … … 440 442 if self.disabled('updates'): 441 443 return 442 self._ meter.update(msg)444 self._update(msg) 443 445 444 446 def write(self, msg, option="misc"): … … 448 450 449 451 def _write(self, msg): 450 # FIXME: we could probably get away with calling _log.info() all of451 # the time, but there doesn't seem to be a good way to test the output 452 # from the logger :(.453 if self._ options.verbose:454 _log.info(msg)455 else: 456 self._ meter.write("%s\n" %msg)452 _log.info(msg) 453 454 def _update(self, msg): 455 if self._meter: 456 self._meter.update(msg) 457 else: 458 self._write(msg) -
trunk/Tools/Scripts/webkitpy/layout_tests/layout_package/printing_unittest.py
r87593 r87596 92 92 93 93 # test that verbose defaults to everything 94 test_switches([], printing.PRINT_EVERYTHING , verbose=True)94 test_switches([], printing.PRINT_EVERYTHING.replace(',one-line-progress',''), verbose=True) 95 95 96 96 # test that --print default does what it's supposed to
Note: See TracChangeset
for help on using the changeset viewer.