104
104
from bzrlib.tests.treeshape import build_tree_contents
105
from bzrlib.ui import NullProgressView
106
from bzrlib.ui.text import TextUIFactory
105
107
import bzrlib.version_info_formats.format_custom
106
108
from bzrlib.workingtree import WorkingTree, WorkingTreeFormat2
113
115
default_transport = LocalURLServer
117
# Subunit result codes, defined here to prevent a hard dependency on subunit.
116
122
class ExtendedTestResult(unittest._TextTestResult):
117
123
"""Accepts, reports and accumulates the results of running tests.
158
163
bench_history.write("--date %s %s\n" % (time.time(), revision_id))
159
164
self._bench_history = bench_history
160
165
self.ui = ui.ui_factory
161
self.num_tests = num_tests
162
167
self.error_count = 0
163
168
self.failure_count = 0
164
169
self.known_failure_count = 0
195
202
def _testTimeString(self, testCase):
196
203
benchmark_time = self._extractBenchmarkTime(testCase)
197
204
if benchmark_time is not None:
199
self._formatTime(benchmark_time),
200
self._elapsedTestTimeString())
205
return self._formatTime(benchmark_time) + "*"
202
return " %s" % self._elapsedTestTimeString()
207
return self._elapsedTestTimeString()
204
209
def _formatTime(self, seconds):
205
210
"""Format seconds as milliseconds with leading spaces."""
346
351
self.stream.write("%s: " % flavour)
347
352
self.stream.writeln(self.getDescription(test))
348
353
if getattr(test, '_get_log', None) is not None:
349
self.stream.write('\n')
351
('vvvv[log from %s]' % test.id()).ljust(78,'-'))
352
self.stream.write('\n')
353
self.stream.write(test._get_log())
354
self.stream.write('\n')
356
('^^^^[log from %s]' % test.id()).ljust(78,'-'))
357
self.stream.write('\n')
354
log_contents = test._get_log()
356
self.stream.write('\n')
358
('vvvv[log from %s]' % test.id()).ljust(78,'-'))
359
self.stream.write('\n')
360
self.stream.write(log_contents)
361
self.stream.write('\n')
363
('^^^^[log from %s]' % test.id()).ljust(78,'-'))
364
self.stream.write('\n')
358
365
self.stream.writeln(self.separator2)
359
366
self.stream.writeln("%s" % err)
368
def progress(self, offset, whence):
369
"""The test is adjusting the count of tests to run."""
370
if whence == SUBUNIT_SEEK_SET:
371
self.num_tests = offset
372
elif whence == SUBUNIT_SEEK_CUR:
373
self.num_tests += offset
375
raise errors.BzrError("Unknown whence %r" % whence)
361
377
def finished(self):
379
395
def __init__(self, stream, descriptions, verbosity,
380
396
bench_history=None,
385
400
ExtendedTestResult.__init__(self, stream, descriptions, verbosity,
386
bench_history, num_tests, strict)
388
self.pb = self.ui.nested_progress_bar()
389
self._supplied_pb = False
392
self._supplied_pb = True
401
bench_history, strict)
402
# We no longer pass them around, but just rely on the UIFactory stack
405
warnings.warn("Passing pb to TextTestResult is deprecated")
406
self.pb = self.ui.nested_progress_bar()
393
407
self.pb.show_pct = False
394
408
self.pb.show_spinner = False
395
409
self.pb.show_eta = False,
396
410
self.pb.show_count = False
397
411
self.pb.show_bar = False
412
self.pb.update_latency = 0
413
self.pb.show_transport_activity = False
416
# called when the tests that are going to run have run
418
super(TextTestResult, self).done()
399
423
def report_starting(self):
400
424
self.pb.update('[test 0/%d] Starting' % (self.num_tests))
426
def printErrors(self):
427
# clear the pb to make room for the error listing
429
super(TextTestResult, self).printErrors()
402
431
def _progress_prefix_text(self):
403
432
# the longer this text, the less space we have to show the test
409
438
## a += ', %d skip' % self.skip_count
410
439
## if self.known_failure_count:
411
440
## a += '+%dX' % self.known_failure_count
412
if self.num_tests is not None:
413
442
a +='/%d' % self.num_tests
415
444
runtime = time.time() - self._overall_start_time
464
493
def report_cleaning_up(self):
465
494
self.pb.update('Cleaning up')
468
if not self._supplied_pb:
472
497
class VerboseTestResult(ExtendedTestResult):
473
498
"""Produce long output, with one line per test run plus times"""
486
511
def report_test_start(self, test):
488
513
name = self._shortened_test_description(test)
489
# width needs space for 6 char status, plus 1 for slash, plus 2 10-char
490
# numbers, plus a trailing blank
514
# width needs space for 6 char status, plus 1 for slash, plus an
515
# 11-char time string, plus a trailing blank
491
516
# when NUMBERED_DIRS: plus 5 chars on test number, plus 1 char on space
492
517
self.stream.write(self._ellipsize_to_right(name,
493
osutils.terminal_width()-30))
518
osutils.terminal_width()-18))
494
519
self.stream.flush()
496
521
def _error_summary(self, err):
702
726
return setattr(self._cstring, name, val)
705
class TestUIFactory(ui.CLIUIFactory):
729
class TestUIFactory(TextUIFactory):
706
730
"""A UI Factory for testing.
708
732
Hide the progress bar but emit note()s.
710
734
Allows get_password to be tested without real tty attached.
736
See also CannedInputUIFactory which lets you provide programmatic input in
739
# TODO: Capture progress events at the model level and allow them to be
740
# observed by tests that care.
742
# XXX: Should probably unify more with CannedInputUIFactory or a
743
# particular configuration of TextUIFactory, or otherwise have a clearer
744
# idea of how they're supposed to be different.
745
# See https://bugs.edge.launchpad.net/bzr/+bug/408213
713
747
def __init__(self, stdout=None, stderr=None, stdin=None):
714
748
if stdin is not None:
719
753
stdin = StringIOWrapper(stdin)
720
754
super(TestUIFactory, self).__init__(stdin, stdout, stderr)
723
"""See progress.ProgressBar.clear()."""
725
def clear_term(self):
726
"""See progress.ProgressBar.clear_term()."""
729
"""See progress.ProgressBar.finished()."""
731
def note(self, fmt_string, *args):
732
"""See progress.ProgressBar.note()."""
734
fmt_string = fmt_string % args
735
self.stdout.write(fmt_string + "\n")
737
def progress_bar(self):
740
def nested_progress_bar(self):
756
def make_progress_view(self):
757
return NullProgressView()
743
759
def update(self, message, count=None, total=None):
744
760
"""See progress.ProgressBar.update()."""
1093
1109
osutils.realpath(path2),
1094
1110
"apparent paths:\na = %s\nb = %s\n," % (path1, path2))
1096
def assertIsInstance(self, obj, kls):
1097
"""Fail if obj is not an instance of kls"""
1112
def assertIsInstance(self, obj, kls, msg=None):
1113
"""Fail if obj is not an instance of kls
1115
:param msg: Supplementary message to show if the assertion fails.
1098
1117
if not isinstance(obj, kls):
1099
self.fail("%r is an instance of %s rather than %s" % (
1100
obj, obj.__class__, kls))
1118
m = "%r is an instance of %s rather than %s" % (
1119
obj, obj.__class__, kls)
1102
1124
def expectFailure(self, reason, assertion, *args, **kwargs):
1103
1125
"""Invoke a test, expecting it to fail for the given reason.
1325
1347
'BZR_PROGRESS_BAR': None,
1326
1348
'BZR_LOG': None,
1327
1349
'BZR_PLUGIN_PATH': None,
1350
# Make sure that any text ui tests are consistent regardless of
1351
# the environment the test case is run in; you may want tests that
1352
# test other combinations. 'dumb' is a reasonable guess for tests
1353
# going to a pipe or a StringIO.
1329
1358
'SSH_AUTH_SOCK': None,
2738
2767
decorators.append(filter_tests(pattern))
2739
2768
if suite_decorators:
2740
2769
decorators.extend(suite_decorators)
2770
# tell the result object how many tests will be running:
2771
decorators.append(CountingDecorator)
2741
2772
for decorator in decorators:
2742
2773
suite = decorator(suite)
2743
2774
result = runner.run(suite)
2881
class CountingDecorator(TestDecorator):
2882
"""A decorator which calls result.progress(self.countTestCases)."""
2884
def run(self, result):
2885
progress_method = getattr(result, 'progress', None)
2886
if callable(progress_method):
2887
progress_method(self.countTestCases(), SUBUNIT_SEEK_SET)
2888
return super(CountingDecorator, self).run(result)
2850
2891
class ExcludeDecorator(TestDecorator):
2851
2892
"""A decorator which excludes test matching an exclude pattern."""
2959
3000
concurrency = osutils.local_concurrency()
2961
3002
from subunit import TestProtocolClient, ProtocolTestCase
3004
from subunit.test_results import AutoTimingTestResultDecorator
3006
AutoTimingTestResultDecorator = lambda x:x
2962
3007
class TestInOtherProcess(ProtocolTestCase):
2963
3008
# Should be in subunit, I think. RBC.
2964
3009
def __init__(self, stream, pid):
2987
3032
sys.stdin.close()
2988
3033
sys.stdin = None
2989
3034
stream = os.fdopen(c2pwrite, 'wb', 1)
2990
subunit_result = TestProtocolClient(stream)
3035
subunit_result = AutoTimingTestResultDecorator(
3036
TestProtocolClient(stream))
2991
3037
process_suite.run(subunit_result)
3981
4027
# Only define SubUnitBzrRunner if subunit is available.
3983
4029
from subunit import TestProtocolClient
4031
from subunit.test_results import AutoTimingTestResultDecorator
4033
AutoTimingTestResultDecorator = lambda x:x
3984
4034
class SubUnitBzrRunner(TextTestRunner):
3985
4035
def run(self, test):
3986
result = TestProtocolClient(self.stream)
4036
result = AutoTimingTestResultDecorator(
4037
TestProtocolClient(self.stream))
3987
4038
test.run(result)
3989
4040
except ImportError: