/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/tests/__init__.py

  • Committer: John Arbash Meinel
  • Date: 2009-08-04 14:10:09 UTC
  • mfrom: (4585 +trunk)
  • mto: This revision was merged to the branch mainline in revision 4588.
  • Revision ID: john@arbash-meinel.com-20090804141009-uety2n17v1atk5ok
Merge bzr.dev 4585, resolve NEWS

Show diffs side-by-side

added added

removed removed

Lines of Context:
102
102
                          TestLoader,
103
103
                          )
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
107
109
 
112
114
 
113
115
default_transport = LocalURLServer
114
116
 
 
117
# Subunit result codes, defined here to prevent a hard dependency on subunit.
 
118
SUBUNIT_SEEK_SET = 0
 
119
SUBUNIT_SEEK_CUR = 1
 
120
 
115
121
 
116
122
class ExtendedTestResult(unittest._TextTestResult):
117
123
    """Accepts, reports and accumulates the results of running tests.
133
139
 
134
140
    def __init__(self, stream, descriptions, verbosity,
135
141
                 bench_history=None,
136
 
                 num_tests=None,
137
142
                 strict=False,
138
143
                 ):
139
144
        """Construct new TestResult.
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
 
166
        self.num_tests = 0
162
167
        self.error_count = 0
163
168
        self.failure_count = 0
164
169
        self.known_failure_count = 0
170
175
        self._strict = strict
171
176
 
172
177
    def done(self):
 
178
        # nb: called stopTestRun in the version of this that Python merged
 
179
        # upstream, according to lifeless 20090803
173
180
        if self._strict:
174
181
            ok = self.wasStrictlySuccessful()
175
182
        else:
195
202
    def _testTimeString(self, testCase):
196
203
        benchmark_time = self._extractBenchmarkTime(testCase)
197
204
        if benchmark_time is not None:
198
 
            return "%s/%s" % (
199
 
                self._formatTime(benchmark_time),
200
 
                self._elapsedTestTimeString())
 
205
            return self._formatTime(benchmark_time) + "*"
201
206
        else:
202
 
            return "           %s" % self._elapsedTestTimeString()
 
207
            return self._elapsedTestTimeString()
203
208
 
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')
350
 
                self.stream.write(
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')
355
 
                self.stream.write(
356
 
                        ('^^^^[log from %s]' % test.id()).ljust(78,'-'))
357
 
                self.stream.write('\n')
 
354
                log_contents = test._get_log()
 
355
                if log_contents:
 
356
                    self.stream.write('\n')
 
357
                    self.stream.write(
 
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')
 
362
                    self.stream.write(
 
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)
360
367
 
 
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
 
374
        else:
 
375
            raise errors.BzrError("Unknown whence %r" % whence)
 
376
 
361
377
    def finished(self):
362
378
        pass
363
379
 
378
394
 
379
395
    def __init__(self, stream, descriptions, verbosity,
380
396
                 bench_history=None,
381
 
                 num_tests=None,
382
397
                 pb=None,
383
398
                 strict=None,
384
399
                 ):
385
400
        ExtendedTestResult.__init__(self, stream, descriptions, verbosity,
386
 
            bench_history, num_tests, strict)
387
 
        if pb is None:
388
 
            self.pb = self.ui.nested_progress_bar()
389
 
            self._supplied_pb = False
390
 
        else:
391
 
            self.pb = pb
392
 
            self._supplied_pb = True
 
401
            bench_history, strict)
 
402
        # We no longer pass them around, but just rely on the UIFactory stack
 
403
        # for state
 
404
        if pb is not None:
 
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
 
414
 
 
415
    def done(self):
 
416
        # called when the tests that are going to run have run
 
417
        self.pb.clear()
 
418
        super(TextTestResult, self).done()
 
419
 
 
420
    def finished(self):
 
421
        self.pb.finished()
398
422
 
399
423
    def report_starting(self):
400
424
        self.pb.update('[test 0/%d] Starting' % (self.num_tests))
401
425
 
 
426
    def printErrors(self):
 
427
        # clear the pb to make room for the error listing
 
428
        self.pb.clear()
 
429
        super(TextTestResult, self).printErrors()
 
430
 
402
431
    def _progress_prefix_text(self):
403
432
        # the longer this text, the less space we have to show the test
404
433
        # name...
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:
 
441
        if self.num_tests:
413
442
            a +='/%d' % self.num_tests
414
443
        a += ' in '
415
444
        runtime = time.time() - self._overall_start_time
464
493
    def report_cleaning_up(self):
465
494
        self.pb.update('Cleaning up')
466
495
 
467
 
    def finished(self):
468
 
        if not self._supplied_pb:
469
 
            self.pb.finished()
470
 
 
471
496
 
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):
487
512
        self.count += 1
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()
495
520
 
496
521
    def _error_summary(self, err):
565
590
                              self.descriptions,
566
591
                              self.verbosity,
567
592
                              bench_history=self._bench_history,
568
 
                              num_tests=test.countTestCases(),
569
593
                              strict=self._strict,
570
594
                              )
571
595
        result.stop_early = self.stop_on_failure
702
726
            return setattr(self._cstring, name, val)
703
727
 
704
728
 
705
 
class TestUIFactory(ui.CLIUIFactory):
 
729
class TestUIFactory(TextUIFactory):
706
730
    """A UI Factory for testing.
707
731
 
708
732
    Hide the progress bar but emit note()s.
709
733
    Redirect stdin.
710
734
    Allows get_password to be tested without real tty attached.
 
735
 
 
736
    See also CannedInputUIFactory which lets you provide programmatic input in
 
737
    a structured way.
711
738
    """
 
739
    # TODO: Capture progress events at the model level and allow them to be
 
740
    # observed by tests that care.
 
741
    #
 
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
712
746
 
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)
721
755
 
722
 
    def clear(self):
723
 
        """See progress.ProgressBar.clear()."""
724
 
 
725
 
    def clear_term(self):
726
 
        """See progress.ProgressBar.clear_term()."""
727
 
 
728
 
    def finished(self):
729
 
        """See progress.ProgressBar.finished()."""
730
 
 
731
 
    def note(self, fmt_string, *args):
732
 
        """See progress.ProgressBar.note()."""
733
 
        if args:
734
 
            fmt_string = fmt_string % args
735
 
        self.stdout.write(fmt_string + "\n")
736
 
 
737
 
    def progress_bar(self):
738
 
        return self
739
 
 
740
 
    def nested_progress_bar(self):
741
 
        return self
 
756
    def make_progress_view(self):
 
757
        return NullProgressView()
742
758
 
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))
1095
1111
 
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
 
1114
        
 
1115
        :param msg: Supplementary message to show if the assertion fails.
 
1116
        """
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)
 
1120
            if msg:
 
1121
                m += ": " + msg
 
1122
            self.fail(m)
1101
1123
 
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.
 
1354
            'TERM': 'dumb',
 
1355
            'LINES': '25',
 
1356
            'COLUMNS': '80',
1328
1357
            # SSH Agent
1329
1358
            'SSH_AUTH_SOCK': None,
1330
1359
            # Proxies
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)
2847
2878
        return result
2848
2879
 
2849
2880
 
 
2881
class CountingDecorator(TestDecorator):
 
2882
    """A decorator which calls result.progress(self.countTestCases)."""
 
2883
 
 
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)
 
2889
 
 
2890
 
2850
2891
class ExcludeDecorator(TestDecorator):
2851
2892
    """A decorator which excludes test matching an exclude pattern."""
2852
2893
 
2959
3000
    concurrency = osutils.local_concurrency()
2960
3001
    result = []
2961
3002
    from subunit import TestProtocolClient, ProtocolTestCase
 
3003
    try:
 
3004
        from subunit.test_results import AutoTimingTestResultDecorator
 
3005
    except ImportError:
 
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)
2992
3038
            finally:
2993
3039
                os._exit(0)
3981
4027
# Only define SubUnitBzrRunner if subunit is available.
3982
4028
try:
3983
4029
    from subunit import TestProtocolClient
 
4030
    try:
 
4031
        from subunit.test_results import AutoTimingTestResultDecorator
 
4032
    except ImportError:
 
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)
3988
4039
            return result
3989
4040
except ImportError: