~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/__init__.py

  • Committer: Robert J. Tanner
  • Date: 2009-04-30 22:40:42 UTC
  • mfrom: (4323 +trunk)
  • mto: This revision was merged to the branch mainline in revision 4324.
  • Revision ID: tanner@real-time.com-20090430224042-53v45axtue5bw45l
Merge 1.14.1 back to trunk

Show diffs side-by-side

added added

removed removed

Lines of Context:
55
55
    debug,
56
56
    errors,
57
57
    hooks,
 
58
    lock as _mod_lock,
58
59
    memorytree,
59
60
    osutils,
60
61
    progress,
133
134
    def __init__(self, stream, descriptions, verbosity,
134
135
                 bench_history=None,
135
136
                 num_tests=None,
 
137
                 strict=False,
136
138
                 ):
137
139
        """Construct new TestResult.
138
140
 
165
167
        self.unsupported = {}
166
168
        self.count = 0
167
169
        self._overall_start_time = time.time()
 
170
        self._strict = strict
 
171
 
 
172
    def done(self):
 
173
        if self._strict:
 
174
            ok = self.wasStrictlySuccessful()
 
175
        else:
 
176
            ok = self.wasSuccessful()
 
177
        if ok:
 
178
            self.stream.write('tests passed\n')
 
179
        else:
 
180
            self.stream.write('tests failed\n')
 
181
        if TestCase._first_thread_leaker_id:
 
182
            self.stream.write(
 
183
                '%s is leaking threads among %d leaking tests.\n' % (
 
184
                TestCase._first_thread_leaker_id,
 
185
                TestCase._leaking_threads_tests))
168
186
 
169
187
    def _extractBenchmarkTime(self, testCase):
170
188
        """Add a benchmark time for the current test case."""
196
214
 
197
215
    def startTest(self, test):
198
216
        unittest.TestResult.startTest(self, test)
 
217
        if self.count == 0:
 
218
            self.startTests()
199
219
        self.report_test_start(test)
200
220
        test.number = self.count
201
221
        self._recordTestStartTime()
202
222
 
 
223
    def startTests(self):
 
224
        self.stream.write(
 
225
            'testing: %s\n' % (osutils.realpath(sys.argv[0]),))
 
226
        self.stream.write(
 
227
            '   %s (%s python%s)\n' % (
 
228
                    bzrlib.__path__[0],
 
229
                    bzrlib.version_string,
 
230
                    bzrlib._format_version_tuple(sys.version_info),
 
231
                    ))
 
232
        self.stream.write('\n')
 
233
 
203
234
    def _recordTestStartTime(self):
204
235
        """Record that a test has started."""
205
236
        self._start_time = time.time()
349
380
                 bench_history=None,
350
381
                 num_tests=None,
351
382
                 pb=None,
 
383
                 strict=None,
352
384
                 ):
353
385
        ExtendedTestResult.__init__(self, stream, descriptions, verbosity,
354
 
            bench_history, num_tests)
 
386
            bench_history, num_tests, strict)
355
387
        if pb is None:
356
388
            self.pb = self.ui.nested_progress_bar()
357
389
            self._supplied_pb = False
512
544
                 descriptions=0,
513
545
                 verbosity=1,
514
546
                 bench_history=None,
515
 
                 list_only=False
 
547
                 list_only=False,
 
548
                 strict=False,
516
549
                 ):
517
550
        self.stream = unittest._WritelnDecorator(stream)
518
551
        self.descriptions = descriptions
519
552
        self.verbosity = verbosity
520
553
        self._bench_history = bench_history
521
554
        self.list_only = list_only
 
555
        self._strict = strict
522
556
 
523
557
    def run(self, test):
524
558
        "Run the given test case or test suite."
532
566
                              self.verbosity,
533
567
                              bench_history=self._bench_history,
534
568
                              num_tests=test.countTestCases(),
 
569
                              strict=self._strict,
535
570
                              )
536
571
        result.stop_early = self.stop_on_failure
537
572
        result.report_starting()
716
751
        return password
717
752
 
718
753
 
719
 
def _report_leaked_threads():
720
 
    bzrlib.trace.warning('%s is leaking threads among %d leaking tests',
721
 
                         TestCase._first_thread_leaker_id,
722
 
                         TestCase._leaking_threads_tests)
723
 
 
724
 
 
725
754
class TestCase(unittest.TestCase):
726
755
    """Base class for bzr unit tests.
727
756
 
770
799
        self._benchcalls = []
771
800
        self._benchtime = None
772
801
        self._clear_hooks()
 
802
        # Track locks - needs to be called before _clear_debug_flags.
 
803
        self._track_locks()
773
804
        self._clear_debug_flags()
774
805
        TestCase._active_threads = threading.activeCount()
775
806
        self.addCleanup(self._check_leaked_threads)
787
818
            TestCase._leaking_threads_tests += 1
788
819
            if TestCase._first_thread_leaker_id is None:
789
820
                TestCase._first_thread_leaker_id = self.id()
790
 
                # we're not specifically told when all tests are finished.
791
 
                # This will do. We use a function to avoid keeping a reference
792
 
                # to a TestCase object.
793
 
                atexit.register(_report_leaked_threads)
794
821
 
795
822
    def _clear_debug_flags(self):
796
823
        """Prevent externally set debug flags affecting tests.
826
853
        ui.ui_factory = ui.SilentUIFactory()
827
854
        self.addCleanup(_restore)
828
855
 
 
856
    def _check_locks(self):
 
857
        """Check that all lock take/release actions have been paired."""
 
858
        # once we have fixed all the current lock problems, we can change the
 
859
        # following code to always check for mismatched locks, but only do
 
860
        # traceback showing with -Dlock (self._lock_check_thorough is True).
 
861
        # For now, because the test suite will fail, we only assert that lock
 
862
        # matching has occured with -Dlock.
 
863
        # unhook:
 
864
        acquired_locks = [lock for action, lock in self._lock_actions
 
865
            if action == 'acquired']
 
866
        released_locks = [lock for action, lock in self._lock_actions
 
867
            if action == 'released']
 
868
        # trivially, given the tests for lock acquistion and release, if we
 
869
        # have as many in each list, it should be ok.
 
870
        if len(acquired_locks) != len(released_locks):
 
871
            message = \
 
872
                ("Different number of acquired and released locks. (%s, %s)" %
 
873
                (acquired_locks, released_locks))
 
874
            if not self._lock_check_thorough:
 
875
                # Rather than fail, just warn
 
876
                print "Broken test %s: %s" % (self, message)
 
877
                return
 
878
            self.fail(message)
 
879
 
 
880
    def _track_locks(self):
 
881
        """Track lock activity during tests."""
 
882
        self._lock_actions = []
 
883
        self._lock_check_thorough = 'lock' in debug.debug_flags
 
884
        self.addCleanup(self._check_locks)
 
885
        _mod_lock.Lock.hooks.install_named_hook('lock_acquired', self._lock_acquired, None)
 
886
        _mod_lock.Lock.hooks.install_named_hook('lock_released', self._lock_released, None)
 
887
 
 
888
    def _lock_acquired(self, result):
 
889
        self._lock_actions.append(('acquired', result))
 
890
 
 
891
    def _lock_released(self, result):
 
892
        self._lock_actions.append(('released', result))
 
893
 
829
894
    def _ndiff_strings(self, a, b):
830
895
        """Return ndiff between two strings containing lines.
831
896
 
1307
1372
                else:
1308
1373
                    result.addSuccess(self)
1309
1374
                result.stopTest(self)
1310
 
                return
 
1375
                return result
1311
1376
        try:
1312
1377
            try:
1313
1378
                result.startTest(self)
1326
1391
                                "test setUp did not invoke "
1327
1392
                                "bzrlib.tests.TestCase's setUp")
1328
1393
                    except KeyboardInterrupt:
 
1394
                        self._runCleanups()
1329
1395
                        raise
1330
1396
                    except TestSkipped, e:
1331
1397
                        self._do_skip(result, e.args[0])
1332
1398
                        self.tearDown()
1333
 
                        return
 
1399
                        return result
1334
1400
                    except:
1335
1401
                        result.addError(self, sys.exc_info())
1336
 
                        return
 
1402
                        self._runCleanups()
 
1403
                        return result
1337
1404
 
1338
1405
                    ok = False
1339
1406
                    try:
1348
1415
                            reason = e.args[0]
1349
1416
                        self._do_skip(result, reason)
1350
1417
                    except KeyboardInterrupt:
 
1418
                        self._runCleanups()
1351
1419
                        raise
1352
1420
                    except:
1353
1421
                        result.addError(self, sys.exc_info())
1359
1427
                                "test tearDown did not invoke "
1360
1428
                                "bzrlib.tests.TestCase's tearDown")
1361
1429
                    except KeyboardInterrupt:
 
1430
                        self._runCleanups()
1362
1431
                        raise
1363
1432
                    except:
1364
1433
                        result.addError(self, sys.exc_info())
 
1434
                        self._runCleanups()
1365
1435
                        ok = False
1366
1436
                    if ok: result.addSuccess(self)
1367
1437
                finally:
1368
1438
                    result.stopTest(self)
1369
 
                return
 
1439
                return result
1370
1440
            except TestNotApplicable:
1371
1441
                # Not moved from the result [yet].
 
1442
                self._runCleanups()
1372
1443
                raise
1373
1444
            except KeyboardInterrupt:
 
1445
                self._runCleanups()
1374
1446
                raise
1375
1447
        finally:
1376
1448
            saved_attrs = {}
1382
1454
            self.__dict__ = saved_attrs
1383
1455
 
1384
1456
    def tearDown(self):
1385
 
        self._bzr_test_tearDown_run = True
1386
1457
        self._runCleanups()
1387
1458
        self._log_contents = ''
 
1459
        self._bzr_test_tearDown_run = True
1388
1460
        unittest.TestCase.tearDown(self)
1389
1461
 
1390
1462
    def time(self, callable, *args, **kwargs):
2617
2689
              exclude_pattern=None,
2618
2690
              strict=False,
2619
2691
              runner_class=None,
2620
 
              suite_decorators=None):
 
2692
              suite_decorators=None,
 
2693
              stream=None):
2621
2694
    """Run a test suite for bzr selftest.
2622
2695
 
2623
2696
    :param runner_class: The class of runner to use. Must support the
2632
2705
        verbosity = 1
2633
2706
    if runner_class is None:
2634
2707
        runner_class = TextTestRunner
2635
 
    runner = runner_class(stream=sys.stdout,
 
2708
    if stream is None:
 
2709
        stream = sys.stdout
 
2710
    runner = runner_class(stream=stream,
2636
2711
                            descriptions=0,
2637
2712
                            verbosity=verbosity,
2638
2713
                            bench_history=bench_history,
2639
2714
                            list_only=list_only,
 
2715
                            strict=strict,
2640
2716
                            )
2641
2717
    runner.stop_on_failure=stop_on_failure
2642
2718
    # built in decorator factories:
2655
2731
    result = runner.run(suite)
2656
2732
    if list_only:
2657
2733
        return True
 
2734
    result.done()
2658
2735
    if strict:
2659
2736
        return result.wasStrictlySuccessful()
2660
2737
    else:
3908
3985
    from subunit import TestProtocolClient
3909
3986
    class SubUnitBzrRunner(TextTestRunner):
3910
3987
        def run(self, test):
3911
 
            # undo out claim for testing which looks like a test start to subunit
3912
 
            self.stream.write("success: %s\n" % (osutils.realpath(sys.argv[0]),))
3913
3988
            result = TestProtocolClient(self.stream)
3914
3989
            test.run(result)
3915
3990
            return result