~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/__init__.py

  • Committer: Naoki INADA
  • Date: 2009-10-29 10:01:19 UTC
  • mto: (4634.97.3 2.0)
  • mto: This revision was merged to the branch mainline in revision 4798.
  • Revision ID: inada-n@klab.jp-20091029100119-uckv9t7ej2qrghw3
import doc-ja rev90

Show diffs side-by-side

added added

removed removed

Lines of Context:
52
52
from bzrlib import (
53
53
    branchbuilder,
54
54
    bzrdir,
 
55
    chk_map,
55
56
    debug,
56
57
    errors,
57
58
    hooks,
102
103
                          TestLoader,
103
104
                          )
104
105
from bzrlib.tests.treeshape import build_tree_contents
 
106
from bzrlib.ui import NullProgressView
105
107
from bzrlib.ui.text import TextUIFactory
106
108
import bzrlib.version_info_formats.format_custom
107
109
from bzrlib.workingtree import WorkingTree, WorkingTreeFormat2
113
115
 
114
116
default_transport = LocalURLServer
115
117
 
 
118
# Subunit result codes, defined here to prevent a hard dependency on subunit.
 
119
SUBUNIT_SEEK_SET = 0
 
120
SUBUNIT_SEEK_CUR = 1
 
121
 
116
122
 
117
123
class ExtendedTestResult(unittest._TextTestResult):
118
124
    """Accepts, reports and accumulates the results of running tests.
134
140
 
135
141
    def __init__(self, stream, descriptions, verbosity,
136
142
                 bench_history=None,
137
 
                 num_tests=None,
138
143
                 strict=False,
139
144
                 ):
140
145
        """Construct new TestResult.
159
164
            bench_history.write("--date %s %s\n" % (time.time(), revision_id))
160
165
        self._bench_history = bench_history
161
166
        self.ui = ui.ui_factory
162
 
        self.num_tests = num_tests
 
167
        self.num_tests = 0
163
168
        self.error_count = 0
164
169
        self.failure_count = 0
165
170
        self.known_failure_count = 0
171
176
        self._strict = strict
172
177
 
173
178
    def done(self):
 
179
        # nb: called stopTestRun in the version of this that Python merged
 
180
        # upstream, according to lifeless 20090803
174
181
        if self._strict:
175
182
            ok = self.wasStrictlySuccessful()
176
183
        else:
220
227
        self._recordTestStartTime()
221
228
 
222
229
    def startTests(self):
223
 
        self.stream.write(
224
 
            'testing: %s\n' % (osutils.realpath(sys.argv[0]),))
225
 
        self.stream.write(
226
 
            '   %s (%s python%s)\n' % (
227
 
                    bzrlib.__path__[0],
 
230
        import platform
 
231
        if getattr(sys, 'frozen', None) is None:
 
232
            bzr_path = osutils.realpath(sys.argv[0])
 
233
        else:
 
234
            bzr_path = sys.executable
 
235
        self.stream.write(
 
236
            'testing: %s\n' % (bzr_path,))
 
237
        self.stream.write(
 
238
            '   %s\n' % (
 
239
                    bzrlib.__path__[0],))
 
240
        self.stream.write(
 
241
            '   bzr-%s python-%s %s\n' % (
228
242
                    bzrlib.version_string,
229
243
                    bzrlib._format_version_tuple(sys.version_info),
 
244
                    platform.platform(aliased=1),
230
245
                    ))
231
246
        self.stream.write('\n')
232
247
 
359
374
            self.stream.writeln(self.separator2)
360
375
            self.stream.writeln("%s" % err)
361
376
 
 
377
    def progress(self, offset, whence):
 
378
        """The test is adjusting the count of tests to run."""
 
379
        if whence == SUBUNIT_SEEK_SET:
 
380
            self.num_tests = offset
 
381
        elif whence == SUBUNIT_SEEK_CUR:
 
382
            self.num_tests += offset
 
383
        else:
 
384
            raise errors.BzrError("Unknown whence %r" % whence)
 
385
 
362
386
    def finished(self):
363
387
        pass
364
388
 
379
403
 
380
404
    def __init__(self, stream, descriptions, verbosity,
381
405
                 bench_history=None,
382
 
                 num_tests=None,
383
406
                 pb=None,
384
407
                 strict=None,
385
408
                 ):
386
409
        ExtendedTestResult.__init__(self, stream, descriptions, verbosity,
387
 
            bench_history, num_tests, strict)
388
 
        if pb is None:
389
 
            self.pb = self.ui.nested_progress_bar()
390
 
            self._supplied_pb = False
391
 
        else:
392
 
            self.pb = pb
393
 
            self._supplied_pb = True
 
410
            bench_history, strict)
 
411
        # We no longer pass them around, but just rely on the UIFactory stack
 
412
        # for state
 
413
        if pb is not None:
 
414
            warnings.warn("Passing pb to TextTestResult is deprecated")
 
415
        self.pb = self.ui.nested_progress_bar()
394
416
        self.pb.show_pct = False
395
417
        self.pb.show_spinner = False
396
418
        self.pb.show_eta = False,
397
419
        self.pb.show_count = False
398
420
        self.pb.show_bar = False
 
421
        self.pb.update_latency = 0
 
422
        self.pb.show_transport_activity = False
 
423
 
 
424
    def done(self):
 
425
        # called when the tests that are going to run have run
 
426
        self.pb.clear()
 
427
        super(TextTestResult, self).done()
 
428
 
 
429
    def finished(self):
 
430
        self.pb.finished()
399
431
 
400
432
    def report_starting(self):
401
433
        self.pb.update('[test 0/%d] Starting' % (self.num_tests))
402
434
 
 
435
    def printErrors(self):
 
436
        # clear the pb to make room for the error listing
 
437
        self.pb.clear()
 
438
        super(TextTestResult, self).printErrors()
 
439
 
403
440
    def _progress_prefix_text(self):
404
441
        # the longer this text, the less space we have to show the test
405
442
        # name...
410
447
        ##     a += ', %d skip' % self.skip_count
411
448
        ## if self.known_failure_count:
412
449
        ##     a += '+%dX' % self.known_failure_count
413
 
        if self.num_tests is not None:
 
450
        if self.num_tests:
414
451
            a +='/%d' % self.num_tests
415
452
        a += ' in '
416
453
        runtime = time.time() - self._overall_start_time
465
502
    def report_cleaning_up(self):
466
503
        self.pb.update('Cleaning up')
467
504
 
468
 
    def finished(self):
469
 
        if not self._supplied_pb:
470
 
            self.pb.finished()
471
 
 
472
505
 
473
506
class VerboseTestResult(ExtendedTestResult):
474
507
    """Produce long output, with one line per test run plus times"""
566
599
                              self.descriptions,
567
600
                              self.verbosity,
568
601
                              bench_history=self._bench_history,
569
 
                              num_tests=test.countTestCases(),
570
602
                              strict=self._strict,
571
603
                              )
572
604
        result.stop_early = self.stop_on_failure
709
741
    Hide the progress bar but emit note()s.
710
742
    Redirect stdin.
711
743
    Allows get_password to be tested without real tty attached.
 
744
 
 
745
    See also CannedInputUIFactory which lets you provide programmatic input in
 
746
    a structured way.
712
747
    """
 
748
    # TODO: Capture progress events at the model level and allow them to be
 
749
    # observed by tests that care.
 
750
    #
 
751
    # XXX: Should probably unify more with CannedInputUIFactory or a
 
752
    # particular configuration of TextUIFactory, or otherwise have a clearer
 
753
    # idea of how they're supposed to be different.
 
754
    # See https://bugs.edge.launchpad.net/bzr/+bug/408213
713
755
 
714
756
    def __init__(self, stdout=None, stderr=None, stdin=None):
715
757
        if stdin is not None:
720
762
            stdin = StringIOWrapper(stdin)
721
763
        super(TestUIFactory, self).__init__(stdin, stdout, stderr)
722
764
 
723
 
    def clear(self):
724
 
        """See progress.ProgressBar.clear()."""
725
 
 
726
 
    def clear_term(self):
727
 
        """See progress.ProgressBar.clear_term()."""
728
 
 
729
 
    def finished(self):
730
 
        """See progress.ProgressBar.finished()."""
731
 
 
732
 
    def note(self, fmt_string, *args):
733
 
        """See progress.ProgressBar.note()."""
734
 
        if args:
735
 
            fmt_string = fmt_string % args
736
 
        self.stdout.write(fmt_string + "\n")
737
 
 
738
 
    def progress_bar(self):
739
 
        return self
740
 
 
741
 
    def nested_progress_bar(self):
742
 
        return self
743
 
 
744
 
    def update(self, message, count=None, total=None):
745
 
        """See progress.ProgressBar.update()."""
746
 
 
747
765
    def get_non_echoed_password(self):
748
766
        """Get password from stdin without trying to handle the echo mode"""
749
767
        password = self.stdin.readline()
753
771
            password = password[:-1]
754
772
        return password
755
773
 
 
774
    def make_progress_view(self):
 
775
        return NullProgressView()
 
776
 
756
777
 
757
778
class TestCase(unittest.TestCase):
758
779
    """Base class for bzr unit tests.
802
823
        self._benchcalls = []
803
824
        self._benchtime = None
804
825
        self._clear_hooks()
805
 
        # Track locks - needs to be called before _clear_debug_flags.
806
826
        self._track_locks()
807
827
        self._clear_debug_flags()
808
828
        TestCase._active_threads = threading.activeCount()
831
851
        self._preserved_debug_flags = set(debug.debug_flags)
832
852
        if 'allow_debug' not in selftest_debug_flags:
833
853
            debug.debug_flags.clear()
 
854
        if 'disable_lock_checks' not in selftest_debug_flags:
 
855
            debug.debug_flags.add('strict_locks')
834
856
        self.addCleanup(self._restore_debug_flags)
835
857
 
836
858
    def _clear_hooks(self):
858
880
 
859
881
    def _check_locks(self):
860
882
        """Check that all lock take/release actions have been paired."""
861
 
        # once we have fixed all the current lock problems, we can change the
862
 
        # following code to always check for mismatched locks, but only do
863
 
        # traceback showing with -Dlock (self._lock_check_thorough is True).
864
 
        # For now, because the test suite will fail, we only assert that lock
865
 
        # matching has occured with -Dlock.
 
883
        # We always check for mismatched locks. If a mismatch is found, we
 
884
        # fail unless -Edisable_lock_checks is supplied to selftest, in which
 
885
        # case we just print a warning.
866
886
        # unhook:
867
887
        acquired_locks = [lock for action, lock in self._lock_actions
868
888
                          if action == 'acquired']
887
907
    def _track_locks(self):
888
908
        """Track lock activity during tests."""
889
909
        self._lock_actions = []
890
 
        self._lock_check_thorough = 'lock' not in debug.debug_flags
 
910
        if 'disable_lock_checks' in selftest_debug_flags:
 
911
            self._lock_check_thorough = False
 
912
        else:
 
913
            self._lock_check_thorough = True
 
914
            
891
915
        self.addCleanup(self._check_locks)
892
916
        _mod_lock.Lock.hooks.install_named_hook('lock_acquired',
893
917
                                                self._lock_acquired, None)
1309
1333
        """Make the logfile not be deleted when _finishLogFile is called."""
1310
1334
        self._keep_log_file = True
1311
1335
 
 
1336
    def thisFailsStrictLockCheck(self):
 
1337
        """It is known that this test would fail with -Dstrict_locks.
 
1338
 
 
1339
        By default, all tests are run with strict lock checking unless
 
1340
        -Edisable_lock_checks is supplied. However there are some tests which
 
1341
        we know fail strict locks at this point that have not been fixed.
 
1342
        They should call this function to disable the strict checking.
 
1343
 
 
1344
        This should be used sparingly, it is much better to fix the locking
 
1345
        issues rather than papering over the problem by calling this function.
 
1346
        """
 
1347
        debug.debug_flags.discard('strict_locks')
 
1348
 
1312
1349
    def addCleanup(self, callable, *args, **kwargs):
1313
1350
        """Arrange to run a callable when this case is torn down.
1314
1351
 
1581
1618
 
1582
1619
    def _run_bzr_core(self, args, retcode, encoding, stdin,
1583
1620
            working_dir):
 
1621
        # Clear chk_map page cache, because the contents are likely to mask
 
1622
        # locking errors.
 
1623
        chk_map.clear_cache()
1584
1624
        if encoding is None:
1585
1625
            encoding = osutils.get_user_encoding()
1586
1626
        stdout = StringIOWrapper()
1926
1966
        sio.encoding = output_encoding
1927
1967
        return sio
1928
1968
 
 
1969
    def disable_verb(self, verb):
 
1970
        """Disable a smart server verb for one test."""
 
1971
        from bzrlib.smart import request
 
1972
        request_handlers = request.request_handlers
 
1973
        orig_method = request_handlers.get(verb)
 
1974
        request_handlers.remove(verb)
 
1975
        def restoreVerb():
 
1976
            request_handlers.register(verb, orig_method)
 
1977
        self.addCleanup(restoreVerb)
 
1978
 
1929
1979
 
1930
1980
class CapturedCall(object):
1931
1981
    """A helper for capturing smart server calls for easy debug analysis."""
2298
2348
 
2299
2349
    def _getTestDirPrefix(self):
2300
2350
        # create a directory within the top level test directory
2301
 
        if sys.platform == 'win32':
 
2351
        if sys.platform in ('win32', 'cygwin'):
2302
2352
            name_prefix = re.sub('[<>*=+",:;_/\\-]', '_', self.id())
2303
2353
            # windows is likely to have path-length limits so use a short name
2304
2354
            name_prefix = name_prefix[-30:]
2752
2802
        decorators.append(filter_tests(pattern))
2753
2803
    if suite_decorators:
2754
2804
        decorators.extend(suite_decorators)
 
2805
    # tell the result object how many tests will be running: (except if
 
2806
    # --parallel=fork is being used. Robert said he will provide a better
 
2807
    # progress design later -- vila 20090817)
 
2808
    if fork_decorator not in decorators:
 
2809
        decorators.append(CountingDecorator)
2755
2810
    for decorator in decorators:
2756
2811
        suite = decorator(suite)
2757
2812
    result = runner.run(suite)
2861
2916
        return result
2862
2917
 
2863
2918
 
 
2919
class CountingDecorator(TestDecorator):
 
2920
    """A decorator which calls result.progress(self.countTestCases)."""
 
2921
 
 
2922
    def run(self, result):
 
2923
        progress_method = getattr(result, 'progress', None)
 
2924
        if callable(progress_method):
 
2925
            progress_method(self.countTestCases(), SUBUNIT_SEEK_SET)
 
2926
        return super(CountingDecorator, self).run(result)
 
2927
 
 
2928
 
2864
2929
class ExcludeDecorator(TestDecorator):
2865
2930
    """A decorator which excludes test matching an exclude pattern."""
2866
2931
 
3121
3186
 
3122
3187
 
3123
3188
# Controlled by "bzr selftest -E=..." option
 
3189
# Currently supported:
 
3190
#   -Eallow_debug           Will no longer clear debug.debug_flags() so it
 
3191
#                           preserves any flags supplied at the command line.
 
3192
#   -Edisable_lock_checks   Turns errors in mismatched locks into simple prints
 
3193
#                           rather than failing tests. And no longer raise
 
3194
#                           LockContention when fctnl locks are not being used
 
3195
#                           with proper exclusion rules.
3124
3196
selftest_debug_flags = set()
3125
3197
 
3126
3198
 
3139
3211
             starting_with=None,
3140
3212
             runner_class=None,
3141
3213
             suite_decorators=None,
 
3214
             stream=None,
3142
3215
             ):
3143
3216
    """Run the whole test suite under the enhanced runner"""
3144
3217
    # XXX: Very ugly way to do this...
3161
3234
            keep_only = None
3162
3235
        else:
3163
3236
            keep_only = load_test_id_list(load_list)
 
3237
        if starting_with:
 
3238
            starting_with = [test_prefix_alias_registry.resolve_alias(start)
 
3239
                             for start in starting_with]
3164
3240
        if test_suite_factory is None:
 
3241
            # Reduce loading time by loading modules based on the starting_with
 
3242
            # patterns.
3165
3243
            suite = test_suite(keep_only, starting_with)
3166
3244
        else:
3167
3245
            suite = test_suite_factory()
 
3246
        if starting_with:
 
3247
            # But always filter as requested.
 
3248
            suite = filter_suite_by_id_startswith(suite, starting_with)
3168
3249
        return run_suite(suite, 'testbzr', verbose=verbose, pattern=pattern,
3169
3250
                     stop_on_failure=stop_on_failure,
3170
3251
                     transport=transport,
3177
3258
                     strict=strict,
3178
3259
                     runner_class=runner_class,
3179
3260
                     suite_decorators=suite_decorators,
 
3261
                     stream=stream,
3180
3262
                     )
3181
3263
    finally:
3182
3264
        default_transport = old_transport
3362
3444
                   'bzrlib.tests.per_lock',
3363
3445
                   'bzrlib.tests.per_transport',
3364
3446
                   'bzrlib.tests.per_tree',
 
3447
                   'bzrlib.tests.per_pack_repository',
3365
3448
                   'bzrlib.tests.per_repository',
3366
3449
                   'bzrlib.tests.per_repository_chk',
3367
3450
                   'bzrlib.tests.per_repository_reference',
 
3451
                   'bzrlib.tests.per_versionedfile',
3368
3452
                   'bzrlib.tests.per_workingtree',
3369
3453
                   'bzrlib.tests.test__annotator',
3370
3454
                   'bzrlib.tests.test__chk_map',
3398
3482
                   'bzrlib.tests.test_config',
3399
3483
                   'bzrlib.tests.test_conflicts',
3400
3484
                   'bzrlib.tests.test_counted_lock',
 
3485
                   'bzrlib.tests.test_crash',
3401
3486
                   'bzrlib.tests.test_decorators',
3402
3487
                   'bzrlib.tests.test_delta',
3403
3488
                   'bzrlib.tests.test_debug',
3436
3521
                   'bzrlib.tests.test_knit',
3437
3522
                   'bzrlib.tests.test_lazy_import',
3438
3523
                   'bzrlib.tests.test_lazy_regex',
 
3524
                   'bzrlib.tests.test_lock',
3439
3525
                   'bzrlib.tests.test_lockable_files',
3440
3526
                   'bzrlib.tests.test_lockdir',
3441
3527
                   'bzrlib.tests.test_log',
3456
3542
                   'bzrlib.tests.test_osutils',
3457
3543
                   'bzrlib.tests.test_osutils_encodings',
3458
3544
                   'bzrlib.tests.test_pack',
3459
 
                   'bzrlib.tests.test_pack_repository',
3460
3545
                   'bzrlib.tests.test_patch',
3461
3546
                   'bzrlib.tests.test_patches',
3462
3547
                   'bzrlib.tests.test_permissions',
3516
3601
                   'bzrlib.tests.test_urlutils',
3517
3602
                   'bzrlib.tests.test_version',
3518
3603
                   'bzrlib.tests.test_version_info',
3519
 
                   'bzrlib.tests.test_versionedfile',
3520
3604
                   'bzrlib.tests.test_weave',
3521
3605
                   'bzrlib.tests.test_whitebox',
3522
3606
                   'bzrlib.tests.test_win32utils',
3531
3615
    if keep_only is not None:
3532
3616
        id_filter = TestIdList(keep_only)
3533
3617
    if starting_with:
3534
 
        starting_with = [test_prefix_alias_registry.resolve_alias(start)
3535
 
                         for start in starting_with]
3536
3618
        # We take precedence over keep_only because *at loading time* using
3537
3619
        # both options means we will load less tests for the same final result.
3538
3620
        def interesting_module(name):
3613
3695
            reload(sys)
3614
3696
            sys.setdefaultencoding(default_encoding)
3615
3697
 
3616
 
    if starting_with:
3617
 
        suite = filter_suite_by_id_startswith(suite, starting_with)
3618
 
 
3619
3698
    if keep_only is not None:
3620
3699
        # Now that the referred modules have loaded their tests, keep only the
3621
3700
        # requested ones.
3749
3828
    try:
3750
3829
        osutils.rmtree(dirname)
3751
3830
    except OSError, e:
3752
 
        if sys.platform == 'win32' and e.errno == errno.EACCES:
3753
 
            sys.stderr.write('Permission denied: '
3754
 
                             'unable to remove testing dir '
3755
 
                             '%s\n%s'
3756
 
                             % (os.path.basename(dirname), e))
3757
 
        else:
3758
 
            raise
 
3831
        # We don't want to fail here because some useful display will be lost
 
3832
        # otherwise. Polluting the tmp dir is bad, but not giving all the
 
3833
        # possible info to the test runner is even worse.
 
3834
        sys.stderr.write('Unable to remove testing dir %s\n%s'
 
3835
                         % (os.path.basename(dirname), e))
3759
3836
 
3760
3837
 
3761
3838
class Feature(object):