/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: Aaron Bentley
  • Date: 2009-10-16 15:25:24 UTC
  • mfrom: (4753 +trunk)
  • mto: This revision was merged to the branch mainline in revision 4754.
  • Revision ID: aaron@aaronbentley.com-20091016152524-hjvft60j2xs6ixa6
Merge bzr.dev

Show diffs side-by-side

added added

removed removed

Lines of Context:
28
28
 
29
29
import atexit
30
30
import codecs
 
31
from copy import copy
31
32
from cStringIO import StringIO
32
33
import difflib
33
34
import doctest
52
53
from bzrlib import (
53
54
    branchbuilder,
54
55
    bzrdir,
 
56
    config,
55
57
    debug,
56
58
    errors,
57
59
    hooks,
89
91
    deprecated_passed,
90
92
    )
91
93
import bzrlib.trace
92
 
from bzrlib.transport import get_transport
 
94
from bzrlib.transport import get_transport, pathfilter
93
95
import bzrlib.transport
94
96
from bzrlib.transport.local import LocalURLServer
95
97
from bzrlib.transport.memory import MemoryServer
174
176
        self._overall_start_time = time.time()
175
177
        self._strict = strict
176
178
 
177
 
    def done(self):
178
 
        # nb: called stopTestRun in the version of this that Python merged
179
 
        # upstream, according to lifeless 20090803
 
179
    def stopTestRun(self):
 
180
        run = self.testsRun
 
181
        actionTaken = "Ran"
 
182
        stopTime = time.time()
 
183
        timeTaken = stopTime - self.startTime
 
184
        self.printErrors()
 
185
        self.stream.writeln(self.separator2)
 
186
        self.stream.writeln("%s %d test%s in %.3fs" % (actionTaken,
 
187
                            run, run != 1 and "s" or "", timeTaken))
 
188
        self.stream.writeln()
 
189
        if not self.wasSuccessful():
 
190
            self.stream.write("FAILED (")
 
191
            failed, errored = map(len, (self.failures, self.errors))
 
192
            if failed:
 
193
                self.stream.write("failures=%d" % failed)
 
194
            if errored:
 
195
                if failed: self.stream.write(", ")
 
196
                self.stream.write("errors=%d" % errored)
 
197
            if self.known_failure_count:
 
198
                if failed or errored: self.stream.write(", ")
 
199
                self.stream.write("known_failure_count=%d" %
 
200
                    self.known_failure_count)
 
201
            self.stream.writeln(")")
 
202
        else:
 
203
            if self.known_failure_count:
 
204
                self.stream.writeln("OK (known_failures=%d)" %
 
205
                    self.known_failure_count)
 
206
            else:
 
207
                self.stream.writeln("OK")
 
208
        if self.skip_count > 0:
 
209
            skipped = self.skip_count
 
210
            self.stream.writeln('%d test%s skipped' %
 
211
                                (skipped, skipped != 1 and "s" or ""))
 
212
        if self.unsupported:
 
213
            for feature, count in sorted(self.unsupported.items()):
 
214
                self.stream.writeln("Missing feature '%s' skipped %d tests." %
 
215
                    (feature, count))
180
216
        if self._strict:
181
217
            ok = self.wasStrictlySuccessful()
182
218
        else:
183
219
            ok = self.wasSuccessful()
184
 
        if ok:
185
 
            self.stream.write('tests passed\n')
186
 
        else:
187
 
            self.stream.write('tests failed\n')
188
220
        if TestCase._first_thread_leaker_id:
189
221
            self.stream.write(
190
222
                '%s is leaking threads among %d leaking tests.\n' % (
191
223
                TestCase._first_thread_leaker_id,
192
224
                TestCase._leaking_threads_tests))
 
225
            # We don't report the main thread as an active one.
 
226
            self.stream.write(
 
227
                '%d non-main threads were left active in the end.\n'
 
228
                % (TestCase._active_threads - 1))
193
229
 
194
230
    def _extractBenchmarkTime(self, testCase):
195
231
        """Add a benchmark time for the current test case."""
267
303
        elif isinstance(err[1], UnavailableFeature):
268
304
            return self.addNotSupported(test, err[1].args[0])
269
305
        else:
 
306
            self._post_mortem()
270
307
            unittest.TestResult.addError(self, test, err)
271
308
            self.error_count += 1
272
309
            self.report_error(test, err)
284
321
        if isinstance(err[1], KnownFailure):
285
322
            return self._addKnownFailure(test, err)
286
323
        else:
 
324
            self._post_mortem()
287
325
            unittest.TestResult.addFailure(self, test, err)
288
326
            self.failure_count += 1
289
327
            self.report_failure(test, err)
373
411
            self.stream.writeln(self.separator2)
374
412
            self.stream.writeln("%s" % err)
375
413
 
 
414
    def _post_mortem(self):
 
415
        """Start a PDB post mortem session."""
 
416
        if os.environ.get('BZR_TEST_PDB', None):
 
417
            import pdb;pdb.post_mortem()
 
418
 
376
419
    def progress(self, offset, whence):
377
420
        """The test is adjusting the count of tests to run."""
378
421
        if whence == SUBUNIT_SEEK_SET:
382
425
        else:
383
426
            raise errors.BzrError("Unknown whence %r" % whence)
384
427
 
385
 
    def finished(self):
386
 
        pass
387
 
 
388
428
    def report_cleaning_up(self):
389
429
        pass
390
430
 
 
431
    def startTestRun(self):
 
432
        self.startTime = time.time()
 
433
 
391
434
    def report_success(self, test):
392
435
        pass
393
436
 
420
463
        self.pb.update_latency = 0
421
464
        self.pb.show_transport_activity = False
422
465
 
423
 
    def done(self):
 
466
    def stopTestRun(self):
424
467
        # called when the tests that are going to run have run
425
468
        self.pb.clear()
426
 
        super(TextTestResult, self).done()
427
 
 
428
 
    def finished(self):
429
469
        self.pb.finished()
 
470
        super(TextTestResult, self).stopTestRun()
430
471
 
431
 
    def report_starting(self):
 
472
    def startTestRun(self):
 
473
        super(TextTestResult, self).startTestRun()
432
474
        self.pb.update('[test 0/%d] Starting' % (self.num_tests))
433
475
 
434
476
    def printErrors(self):
458
500
            a += ', %d err' % self.error_count
459
501
        if self.failure_count:
460
502
            a += ', %d fail' % self.failure_count
461
 
        if self.unsupported:
462
 
            a += ', %d missing' % len(self.unsupported)
 
503
        # if self.unsupported:
 
504
        #     a += ', %d missing' % len(self.unsupported)
463
505
        a += ']'
464
506
        return a
465
507
 
474
516
        return self._shortened_test_description(test)
475
517
 
476
518
    def report_error(self, test, err):
477
 
        self.pb.note('ERROR: %s\n    %s\n',
 
519
        ui.ui_factory.note('ERROR: %s\n    %s\n' % (
478
520
            self._test_description(test),
479
521
            err[1],
480
 
            )
 
522
            ))
481
523
 
482
524
    def report_failure(self, test, err):
483
 
        self.pb.note('FAIL: %s\n    %s\n',
 
525
        ui.ui_factory.note('FAIL: %s\n    %s\n' % (
484
526
            self._test_description(test),
485
527
            err[1],
486
 
            )
 
528
            ))
487
529
 
488
530
    def report_known_failure(self, test, err):
489
 
        self.pb.note('XFAIL: %s\n%s\n',
490
 
            self._test_description(test), err[1])
 
531
        ui.ui_factory.note('XFAIL: %s\n%s\n' % (
 
532
            self._test_description(test), err[1]))
491
533
 
492
534
    def report_skip(self, test, reason):
493
535
        pass
513
555
            result = a_string
514
556
        return result.ljust(final_width)
515
557
 
516
 
    def report_starting(self):
 
558
    def startTestRun(self):
 
559
        super(VerboseTestResult, self).startTestRun()
517
560
        self.stream.write('running %d tests...\n' % self.num_tests)
518
561
 
519
562
    def report_test_start(self, test):
577
620
                 descriptions=0,
578
621
                 verbosity=1,
579
622
                 bench_history=None,
580
 
                 list_only=False,
581
623
                 strict=False,
 
624
                 result_decorators=None,
582
625
                 ):
 
626
        """Create a TextTestRunner.
 
627
 
 
628
        :param result_decorators: An optional list of decorators to apply
 
629
            to the result object being used by the runner. Decorators are
 
630
            applied left to right - the first element in the list is the 
 
631
            innermost decorator.
 
632
        """
583
633
        self.stream = unittest._WritelnDecorator(stream)
584
634
        self.descriptions = descriptions
585
635
        self.verbosity = verbosity
586
636
        self._bench_history = bench_history
587
 
        self.list_only = list_only
588
637
        self._strict = strict
 
638
        self._result_decorators = result_decorators or []
589
639
 
590
640
    def run(self, test):
591
641
        "Run the given test case or test suite."
592
 
        startTime = time.time()
593
642
        if self.verbosity == 1:
594
643
            result_class = TextTestResult
595
644
        elif self.verbosity >= 2:
596
645
            result_class = VerboseTestResult
597
 
        result = result_class(self.stream,
 
646
        original_result = result_class(self.stream,
598
647
                              self.descriptions,
599
648
                              self.verbosity,
600
649
                              bench_history=self._bench_history,
601
650
                              strict=self._strict,
602
651
                              )
603
 
        result.stop_early = self.stop_on_failure
604
 
        result.report_starting()
605
 
        if self.list_only:
606
 
            if self.verbosity >= 2:
607
 
                self.stream.writeln("Listing tests only ...\n")
608
 
            run = 0
609
 
            for t in iter_suite_tests(test):
610
 
                self.stream.writeln("%s" % (t.id()))
611
 
                run += 1
612
 
            return None
613
 
        else:
614
 
            try:
615
 
                import testtools
616
 
            except ImportError:
617
 
                test.run(result)
618
 
            else:
619
 
                if isinstance(test, testtools.ConcurrentTestSuite):
620
 
                    # We need to catch bzr specific behaviors
621
 
                    test.run(BZRTransformingResult(result))
622
 
                else:
623
 
                    test.run(result)
624
 
            run = result.testsRun
625
 
            actionTaken = "Ran"
626
 
        stopTime = time.time()
627
 
        timeTaken = stopTime - startTime
628
 
        result.printErrors()
629
 
        self.stream.writeln(result.separator2)
630
 
        self.stream.writeln("%s %d test%s in %.3fs" % (actionTaken,
631
 
                            run, run != 1 and "s" or "", timeTaken))
632
 
        self.stream.writeln()
633
 
        if not result.wasSuccessful():
634
 
            self.stream.write("FAILED (")
635
 
            failed, errored = map(len, (result.failures, result.errors))
636
 
            if failed:
637
 
                self.stream.write("failures=%d" % failed)
638
 
            if errored:
639
 
                if failed: self.stream.write(", ")
640
 
                self.stream.write("errors=%d" % errored)
641
 
            if result.known_failure_count:
642
 
                if failed or errored: self.stream.write(", ")
643
 
                self.stream.write("known_failure_count=%d" %
644
 
                    result.known_failure_count)
645
 
            self.stream.writeln(")")
646
 
        else:
647
 
            if result.known_failure_count:
648
 
                self.stream.writeln("OK (known_failures=%d)" %
649
 
                    result.known_failure_count)
650
 
            else:
651
 
                self.stream.writeln("OK")
652
 
        if result.skip_count > 0:
653
 
            skipped = result.skip_count
654
 
            self.stream.writeln('%d test%s skipped' %
655
 
                                (skipped, skipped != 1 and "s" or ""))
656
 
        if result.unsupported:
657
 
            for feature, count in sorted(result.unsupported.items()):
658
 
                self.stream.writeln("Missing feature '%s' skipped %d tests." %
659
 
                    (feature, count))
660
 
        result.finished()
661
 
        return result
 
652
        # Signal to result objects that look at stop early policy to stop,
 
653
        original_result.stop_early = self.stop_on_failure
 
654
        result = original_result
 
655
        for decorator in self._result_decorators:
 
656
            result = decorator(result)
 
657
            result.stop_early = self.stop_on_failure
 
658
        try:
 
659
            import testtools
 
660
        except ImportError:
 
661
            pass
 
662
        else:
 
663
            if isinstance(test, testtools.ConcurrentTestSuite):
 
664
                # We need to catch bzr specific behaviors
 
665
                result = BZRTransformingResult(result)
 
666
        result.startTestRun()
 
667
        try:
 
668
            test.run(result)
 
669
        finally:
 
670
            result.stopTestRun()
 
671
        # higher level code uses our extended protocol to determine
 
672
        # what exit code to give.
 
673
        return original_result
662
674
 
663
675
 
664
676
def iter_suite_tests(suite):
812
824
        self._cleanups = []
813
825
        self._bzr_test_setUp_run = False
814
826
        self._bzr_test_tearDown_run = False
 
827
        self._directory_isolation = True
815
828
 
816
829
    def setUp(self):
817
830
        unittest.TestCase.setUp(self)
822
835
        self._benchcalls = []
823
836
        self._benchtime = None
824
837
        self._clear_hooks()
 
838
        self._track_transports()
825
839
        self._track_locks()
826
840
        self._clear_debug_flags()
827
841
        TestCase._active_threads = threading.activeCount()
836
850
        active = threading.activeCount()
837
851
        leaked_threads = active - TestCase._active_threads
838
852
        TestCase._active_threads = active
839
 
        if leaked_threads:
 
853
        # If some tests make the number of threads *decrease*, we'll consider
 
854
        # that they are just observing old threads dieing, not agressively kill
 
855
        # random threads. So we don't report these tests as leaking. The risk
 
856
        # is that we have false positives that way (the test see 2 threads
 
857
        # going away but leak one) but it seems less likely than the actual
 
858
        # false positives (the test see threads going away and does not leak).
 
859
        if leaked_threads > 0:
840
860
            TestCase._leaking_threads_tests += 1
841
861
            if TestCase._first_thread_leaker_id is None:
842
862
                TestCase._first_thread_leaker_id = self.id()
868
888
        # this hook should always be installed
869
889
        request._install_hook()
870
890
 
 
891
    def disable_directory_isolation(self):
 
892
        """Turn off directory isolation checks."""
 
893
        self._directory_isolation = False
 
894
 
 
895
    def enable_directory_isolation(self):
 
896
        """Enable directory isolation checks."""
 
897
        self._directory_isolation = True
 
898
 
871
899
    def _silenceUI(self):
872
900
        """Turn off UI for duration of test"""
873
901
        # by default the UI is off; tests can turn it on if they want it.
928
956
    def _lock_broken(self, result):
929
957
        self._lock_actions.append(('broken', result))
930
958
 
 
959
    def permit_dir(self, name):
 
960
        """Permit a directory to be used by this test. See permit_url."""
 
961
        name_transport = get_transport(name)
 
962
        self.permit_url(name)
 
963
        self.permit_url(name_transport.base)
 
964
 
 
965
    def permit_url(self, url):
 
966
        """Declare that url is an ok url to use in this test.
 
967
        
 
968
        Do this for memory transports, temporary test directory etc.
 
969
        
 
970
        Do not do this for the current working directory, /tmp, or any other
 
971
        preexisting non isolated url.
 
972
        """
 
973
        if not url.endswith('/'):
 
974
            url += '/'
 
975
        self._bzr_selftest_roots.append(url)
 
976
 
 
977
    def permit_source_tree_branch_repo(self):
 
978
        """Permit the source tree bzr is running from to be opened.
 
979
 
 
980
        Some code such as bzrlib.version attempts to read from the bzr branch
 
981
        that bzr is executing from (if any). This method permits that directory
 
982
        to be used in the test suite.
 
983
        """
 
984
        path = self.get_source_path()
 
985
        self.record_directory_isolation()
 
986
        try:
 
987
            try:
 
988
                workingtree.WorkingTree.open(path)
 
989
            except (errors.NotBranchError, errors.NoWorkingTree):
 
990
                return
 
991
        finally:
 
992
            self.enable_directory_isolation()
 
993
 
 
994
    def _preopen_isolate_transport(self, transport):
 
995
        """Check that all transport openings are done in the test work area."""
 
996
        while isinstance(transport, pathfilter.PathFilteringTransport):
 
997
            # Unwrap pathfiltered transports
 
998
            transport = transport.server.backing_transport.clone(
 
999
                transport._filter('.'))
 
1000
        url = transport.base
 
1001
        # ReadonlySmartTCPServer_for_testing decorates the backing transport
 
1002
        # urls it is given by prepending readonly+. This is appropriate as the
 
1003
        # client shouldn't know that the server is readonly (or not readonly).
 
1004
        # We could register all servers twice, with readonly+ prepending, but
 
1005
        # that makes for a long list; this is about the same but easier to
 
1006
        # read.
 
1007
        if url.startswith('readonly+'):
 
1008
            url = url[len('readonly+'):]
 
1009
        self._preopen_isolate_url(url)
 
1010
 
 
1011
    def _preopen_isolate_url(self, url):
 
1012
        if not self._directory_isolation:
 
1013
            return
 
1014
        if self._directory_isolation == 'record':
 
1015
            self._bzr_selftest_roots.append(url)
 
1016
            return
 
1017
        # This prevents all transports, including e.g. sftp ones backed on disk
 
1018
        # from working unless they are explicitly granted permission. We then
 
1019
        # depend on the code that sets up test transports to check that they are
 
1020
        # appropriately isolated and enable their use by calling
 
1021
        # self.permit_transport()
 
1022
        if not osutils.is_inside_any(self._bzr_selftest_roots, url):
 
1023
            raise errors.BzrError("Attempt to escape test isolation: %r %r"
 
1024
                % (url, self._bzr_selftest_roots))
 
1025
 
 
1026
    def record_directory_isolation(self):
 
1027
        """Gather accessed directories to permit later access.
 
1028
        
 
1029
        This is used for tests that access the branch bzr is running from.
 
1030
        """
 
1031
        self._directory_isolation = "record"
 
1032
 
 
1033
    def start_server(self, transport_server, backing_server=None):
 
1034
        """Start transport_server for this test.
 
1035
 
 
1036
        This starts the server, registers a cleanup for it and permits the
 
1037
        server's urls to be used.
 
1038
        """
 
1039
        if backing_server is None:
 
1040
            transport_server.setUp()
 
1041
        else:
 
1042
            transport_server.setUp(backing_server)
 
1043
        self.addCleanup(transport_server.tearDown)
 
1044
        # Obtain a real transport because if the server supplies a password, it
 
1045
        # will be hidden from the base on the client side.
 
1046
        t = get_transport(transport_server.get_url())
 
1047
        # Some transport servers effectively chroot the backing transport;
 
1048
        # others like SFTPServer don't - users of the transport can walk up the
 
1049
        # transport to read the entire backing transport. This wouldn't matter
 
1050
        # except that the workdir tests are given - and that they expect the
 
1051
        # server's url to point at - is one directory under the safety net. So
 
1052
        # Branch operations into the transport will attempt to walk up one
 
1053
        # directory. Chrooting all servers would avoid this but also mean that
 
1054
        # we wouldn't be testing directly against non-root urls. Alternatively
 
1055
        # getting the test framework to start the server with a backing server
 
1056
        # at the actual safety net directory would work too, but this then
 
1057
        # means that the self.get_url/self.get_transport methods would need
 
1058
        # to transform all their results. On balance its cleaner to handle it
 
1059
        # here, and permit a higher url when we have one of these transports.
 
1060
        if t.base.endswith('/work/'):
 
1061
            # we have safety net/test root/work
 
1062
            t = t.clone('../..')
 
1063
        elif isinstance(transport_server, server.SmartTCPServer_for_testing):
 
1064
            # The smart server adds a path similar to work, which is traversed
 
1065
            # up from by the client. But the server is chrooted - the actual
 
1066
            # backing transport is not escaped from, and VFS requests to the
 
1067
            # root will error (because they try to escape the chroot).
 
1068
            t2 = t.clone('..')
 
1069
            while t2.base != t.base:
 
1070
                t = t2
 
1071
                t2 = t.clone('..')
 
1072
        self.permit_url(t.base)
 
1073
 
 
1074
    def _track_transports(self):
 
1075
        """Install checks for transport usage."""
 
1076
        # TestCase has no safe place it can write to.
 
1077
        self._bzr_selftest_roots = []
 
1078
        # Currently the easiest way to be sure that nothing is going on is to
 
1079
        # hook into bzr dir opening. This leaves a small window of error for
 
1080
        # transport tests, but they are well known, and we can improve on this
 
1081
        # step.
 
1082
        bzrdir.BzrDir.hooks.install_named_hook("pre_open",
 
1083
            self._preopen_isolate_transport, "Check bzr directories are safe.")
 
1084
 
931
1085
    def _ndiff_strings(self, a, b):
932
1086
        """Return ndiff between two strings containing lines.
933
1087
 
970
1124
            return
971
1125
        if message is None:
972
1126
            message = "texts not equal:\n"
 
1127
        if a + '\n' == b:
 
1128
            message = 'first string is missing a final newline.\n'
973
1129
        if a == b + '\n':
974
 
            message = 'first string is missing a final newline.\n'
975
 
        if a + '\n' == b:
976
1130
            message = 'second string is missing a final newline.\n'
977
1131
        raise AssertionError(message +
978
1132
                             self._ndiff_strings(a, b))
1002
1156
            self.fail("Incorrect length: wanted %d, got %d for %r" % (
1003
1157
                length, len(obj_with_len), obj_with_len))
1004
1158
 
 
1159
    def assertLogsError(self, exception_class, func, *args, **kwargs):
 
1160
        """Assert that func(*args, **kwargs) quietly logs a specific exception.
 
1161
        """
 
1162
        from bzrlib import trace
 
1163
        captured = []
 
1164
        orig_log_exception_quietly = trace.log_exception_quietly
 
1165
        try:
 
1166
            def capture():
 
1167
                orig_log_exception_quietly()
 
1168
                captured.append(sys.exc_info())
 
1169
            trace.log_exception_quietly = capture
 
1170
            func(*args, **kwargs)
 
1171
        finally:
 
1172
            trace.log_exception_quietly = orig_log_exception_quietly
 
1173
        self.assertLength(1, captured)
 
1174
        err = captured[0][1]
 
1175
        self.assertIsInstance(err, exception_class)
 
1176
        return err
 
1177
 
1005
1178
    def assertPositive(self, val):
1006
1179
        """Assert that val is greater than 0."""
1007
1180
        self.assertTrue(val > 0, 'expected a positive value, but got %s' % val)
1658
1831
        if retcode is not None:
1659
1832
            self.assertEquals(retcode, result,
1660
1833
                              message='Unexpected return code')
1661
 
        return out, err
 
1834
        return result, out, err
1662
1835
 
1663
1836
    def run_bzr(self, args, retcode=0, encoding=None, stdin=None,
1664
1837
                working_dir=None, error_regexes=[], output_encoding=None):
1693
1866
        :keyword error_regexes: A list of expected error messages.  If
1694
1867
            specified they must be seen in the error output of the command.
1695
1868
        """
1696
 
        out, err = self._run_bzr_autosplit(
 
1869
        retcode, out, err = self._run_bzr_autosplit(
1697
1870
            args=args,
1698
1871
            retcode=retcode,
1699
1872
            encoding=encoding,
1850
2023
        """
1851
2024
        return Popen(*args, **kwargs)
1852
2025
 
 
2026
    def get_source_path(self):
 
2027
        """Return the path of the directory containing bzrlib."""
 
2028
        return os.path.dirname(os.path.dirname(bzrlib.__file__))
 
2029
 
1853
2030
    def get_bzr_path(self):
1854
2031
        """Return the path of the 'bzr' executable for this test suite."""
1855
 
        bzr_path = os.path.dirname(os.path.dirname(bzrlib.__file__))+'/bzr'
 
2032
        bzr_path = self.get_source_path()+'/bzr'
1856
2033
        if not os.path.isfile(bzr_path):
1857
2034
            # We are probably installed. Assume sys.argv is the right file
1858
2035
            bzr_path = sys.argv[0]
2067
2244
        if self.__readonly_server is None:
2068
2245
            if self.transport_readonly_server is None:
2069
2246
                # readonly decorator requested
2070
 
                # bring up the server
2071
2247
                self.__readonly_server = ReadonlyServer()
2072
 
                self.__readonly_server.setUp(self.get_vfs_only_server())
2073
2248
            else:
 
2249
                # explicit readonly transport.
2074
2250
                self.__readonly_server = self.create_transport_readonly_server()
2075
 
                self.__readonly_server.setUp(self.get_vfs_only_server())
2076
 
            self.addCleanup(self.__readonly_server.tearDown)
 
2251
            self.start_server(self.__readonly_server,
 
2252
                self.get_vfs_only_server())
2077
2253
        return self.__readonly_server
2078
2254
 
2079
2255
    def get_readonly_url(self, relpath=None):
2098
2274
        """
2099
2275
        if self.__vfs_server is None:
2100
2276
            self.__vfs_server = MemoryServer()
2101
 
            self.__vfs_server.setUp()
2102
 
            self.addCleanup(self.__vfs_server.tearDown)
 
2277
            self.start_server(self.__vfs_server)
2103
2278
        return self.__vfs_server
2104
2279
 
2105
2280
    def get_server(self):
2112
2287
        then the self.get_vfs_server is returned.
2113
2288
        """
2114
2289
        if self.__server is None:
2115
 
            if self.transport_server is None or self.transport_server is self.vfs_transport_factory:
2116
 
                return self.get_vfs_only_server()
 
2290
            if (self.transport_server is None or self.transport_server is
 
2291
                self.vfs_transport_factory):
 
2292
                self.__server = self.get_vfs_only_server()
2117
2293
            else:
2118
2294
                # bring up a decorated means of access to the vfs only server.
2119
2295
                self.__server = self.transport_server()
2120
 
                try:
2121
 
                    self.__server.setUp(self.get_vfs_only_server())
2122
 
                except TypeError, e:
2123
 
                    # This should never happen; the try:Except here is to assist
2124
 
                    # developers having to update code rather than seeing an
2125
 
                    # uninformative TypeError.
2126
 
                    raise Exception, "Old server API in use: %s, %s" % (self.__server, e)
2127
 
            self.addCleanup(self.__server.tearDown)
 
2296
                self.start_server(self.__server, self.get_vfs_only_server())
2128
2297
        return self.__server
2129
2298
 
2130
2299
    def _adjust_url(self, base, relpath):
2192
2361
        propagating. This method ensures than a test did not leaked.
2193
2362
        """
2194
2363
        root = TestCaseWithMemoryTransport.TEST_ROOT
 
2364
        self.permit_url(get_transport(root).base)
2195
2365
        wt = workingtree.WorkingTree.open(root)
2196
2366
        last_rev = wt.last_revision()
2197
2367
        if last_rev != 'null:':
2205
2375
 
2206
2376
    def _make_test_root(self):
2207
2377
        if TestCaseWithMemoryTransport.TEST_ROOT is None:
2208
 
            root = osutils.mkdtemp(prefix='testbzr-', suffix='.tmp')
 
2378
            # Watch out for tricky test dir (on OSX /tmp -> /private/tmp)
 
2379
            root = osutils.realpath(osutils.mkdtemp(prefix='testbzr-',
 
2380
                                                    suffix='.tmp'))
2209
2381
            TestCaseWithMemoryTransport.TEST_ROOT = root
2210
2382
 
2211
2383
            self._create_safety_net()
2214
2386
            # specifically told when all tests are finished.  This will do.
2215
2387
            atexit.register(_rmtree_temp_dir, root)
2216
2388
 
 
2389
        self.permit_dir(TestCaseWithMemoryTransport.TEST_ROOT)
2217
2390
        self.addCleanup(self._check_safety_net)
2218
2391
 
2219
2392
    def makeAndChdirToTestDir(self):
2227
2400
        os.chdir(TestCaseWithMemoryTransport.TEST_ROOT)
2228
2401
        self.test_dir = TestCaseWithMemoryTransport.TEST_ROOT
2229
2402
        self.test_home_dir = self.test_dir + "/MemoryTransportMissingHomeDir"
 
2403
        self.permit_dir(self.test_dir)
2230
2404
 
2231
2405
    def make_branch(self, relpath, format=None):
2232
2406
        """Create a branch on the transport at relpath."""
2263
2437
 
2264
2438
    def make_smart_server(self, path):
2265
2439
        smart_server = server.SmartTCPServer_for_testing()
2266
 
        smart_server.setUp(self.get_server())
 
2440
        self.start_server(smart_server, self.get_server())
2267
2441
        remote_transport = get_transport(smart_server.get_url()).clone(path)
2268
 
        self.addCleanup(smart_server.tearDown)
2269
2442
        return remote_transport
2270
2443
 
2271
2444
    def make_branch_and_memory_tree(self, relpath, format=None):
2365
2538
            if os.path.exists(name):
2366
2539
                name = name_prefix + '_' + str(i)
2367
2540
            else:
2368
 
                os.mkdir(name)
 
2541
                # now create test and home directories within this dir
 
2542
                self.test_base_dir = name
 
2543
                self.addCleanup(self.deleteTestDir)
 
2544
                os.mkdir(self.test_base_dir)
2369
2545
                break
2370
 
        # now create test and home directories within this dir
2371
 
        self.test_base_dir = name
 
2546
        self.permit_dir(self.test_base_dir)
 
2547
        # 'sprouting' and 'init' of a branch both walk up the tree to find
 
2548
        # stacking policy to honour; create a bzr dir with an unshared
 
2549
        # repository (but not a branch - our code would be trying to escape
 
2550
        # then!) to stop them, and permit it to be read.
 
2551
        # control = bzrdir.BzrDir.create(self.test_base_dir)
 
2552
        # control.create_repository()
2372
2553
        self.test_home_dir = self.test_base_dir + '/home'
2373
2554
        os.mkdir(self.test_home_dir)
2374
2555
        self.test_dir = self.test_base_dir + '/work'
2380
2561
            f.write(self.id())
2381
2562
        finally:
2382
2563
            f.close()
2383
 
        self.addCleanup(self.deleteTestDir)
2384
2564
 
2385
2565
    def deleteTestDir(self):
2386
2566
        os.chdir(TestCaseWithMemoryTransport.TEST_ROOT)
2472
2652
        """
2473
2653
        if self.__vfs_server is None:
2474
2654
            self.__vfs_server = self.vfs_transport_factory()
2475
 
            self.__vfs_server.setUp()
2476
 
            self.addCleanup(self.__vfs_server.tearDown)
 
2655
            self.start_server(self.__vfs_server)
2477
2656
        return self.__vfs_server
2478
2657
 
2479
2658
    def make_branch_and_tree(self, relpath, format=None):
2486
2665
        repository will also be accessed locally. Otherwise a lightweight
2487
2666
        checkout is created and returned.
2488
2667
 
 
2668
        We do this because we can't physically create a tree in the local
 
2669
        path, with a branch reference to the transport_factory url, and
 
2670
        a branch + repository in the vfs_transport, unless the vfs_transport
 
2671
        namespace is distinct from the local disk - the two branch objects
 
2672
        would collide. While we could construct a tree with its branch object
 
2673
        pointing at the transport_factory transport in memory, reopening it
 
2674
        would behaving unexpectedly, and has in the past caused testing bugs
 
2675
        when we tried to do it that way.
 
2676
 
2489
2677
        :param format: The BzrDirFormat.
2490
2678
        :returns: the WorkingTree.
2491
2679
        """
2543
2731
        super(TestCaseWithTransport, self).setUp()
2544
2732
        self.__vfs_server = None
2545
2733
 
 
2734
    def disable_missing_extensions_warning(self):
 
2735
        """Some tests expect a precise stderr content.
 
2736
 
 
2737
        There is no point in forcing them to duplicate the extension related
 
2738
        warning.
 
2739
        """
 
2740
        config.GlobalConfig().set_user_option('ignore_missing_extensions', True)
 
2741
 
2546
2742
 
2547
2743
class ChrootedTestCase(TestCaseWithTransport):
2548
2744
    """A support class that provides readonly urls outside the local namespace.
2762
2958
              strict=False,
2763
2959
              runner_class=None,
2764
2960
              suite_decorators=None,
2765
 
              stream=None):
 
2961
              stream=None,
 
2962
              result_decorators=None,
 
2963
              ):
2766
2964
    """Run a test suite for bzr selftest.
2767
2965
 
2768
2966
    :param runner_class: The class of runner to use. Must support the
2783
2981
                            descriptions=0,
2784
2982
                            verbosity=verbosity,
2785
2983
                            bench_history=bench_history,
2786
 
                            list_only=list_only,
2787
2984
                            strict=strict,
 
2985
                            result_decorators=result_decorators,
2788
2986
                            )
2789
2987
    runner.stop_on_failure=stop_on_failure
2790
2988
    # built in decorator factories:
2805
3003
        decorators.append(CountingDecorator)
2806
3004
    for decorator in decorators:
2807
3005
        suite = decorator(suite)
 
3006
    if list_only:
 
3007
        # Done after test suite decoration to allow randomisation etc
 
3008
        # to take effect, though that is of marginal benefit.
 
3009
        if verbosity >= 2:
 
3010
            stream.write("Listing tests only ...\n")
 
3011
        for t in iter_suite_tests(suite):
 
3012
            stream.write("%s\n" % (t.id()))
 
3013
        return True
2808
3014
    result = runner.run(suite)
2809
 
    if list_only:
2810
 
        return True
2811
 
    result.done()
2812
3015
    if strict:
2813
3016
        return result.wasStrictlySuccessful()
2814
3017
    else:
3131
3334
    return result
3132
3335
 
3133
3336
 
3134
 
class BZRTransformingResult(unittest.TestResult):
 
3337
class ForwardingResult(unittest.TestResult):
3135
3338
 
3136
3339
    def __init__(self, target):
3137
3340
        unittest.TestResult.__init__(self)
3143
3346
    def stopTest(self, test):
3144
3347
        self.result.stopTest(test)
3145
3348
 
 
3349
    def startTestRun(self):
 
3350
        self.result.startTestRun()
 
3351
 
 
3352
    def stopTestRun(self):
 
3353
        self.result.stopTestRun()
 
3354
 
 
3355
    def addSkip(self, test, reason):
 
3356
        self.result.addSkip(test, reason)
 
3357
 
 
3358
    def addSuccess(self, test):
 
3359
        self.result.addSuccess(test)
 
3360
 
 
3361
    def addError(self, test, err):
 
3362
        self.result.addError(test, err)
 
3363
 
 
3364
    def addFailure(self, test, err):
 
3365
        self.result.addFailure(test, err)
 
3366
 
 
3367
 
 
3368
class BZRTransformingResult(ForwardingResult):
 
3369
 
3146
3370
    def addError(self, test, err):
3147
3371
        feature = self._error_looks_like('UnavailableFeature: ', err)
3148
3372
        if feature is not None:
3158
3382
        else:
3159
3383
            self.result.addFailure(test, err)
3160
3384
 
3161
 
    def addSkip(self, test, reason):
3162
 
        self.result.addSkip(test, reason)
3163
 
 
3164
 
    def addSuccess(self, test):
3165
 
        self.result.addSuccess(test)
3166
 
 
3167
3385
    def _error_looks_like(self, prefix, err):
3168
3386
        """Deserialize exception and returns the stringify value."""
3169
3387
        import subunit
3181
3399
        return value
3182
3400
 
3183
3401
 
 
3402
class ProfileResult(ForwardingResult):
 
3403
    """Generate profiling data for all activity between start and success.
 
3404
    
 
3405
    The profile data is appended to the test's _benchcalls attribute and can
 
3406
    be accessed by the forwarded-to TestResult.
 
3407
 
 
3408
    While it might be cleaner do accumulate this in stopTest, addSuccess is
 
3409
    where our existing output support for lsprof is, and this class aims to
 
3410
    fit in with that: while it could be moved it's not necessary to accomplish
 
3411
    test profiling, nor would it be dramatically cleaner.
 
3412
    """
 
3413
 
 
3414
    def startTest(self, test):
 
3415
        self.profiler = bzrlib.lsprof.BzrProfiler()
 
3416
        self.profiler.start()
 
3417
        ForwardingResult.startTest(self, test)
 
3418
 
 
3419
    def addSuccess(self, test):
 
3420
        stats = self.profiler.stop()
 
3421
        try:
 
3422
            calls = test._benchcalls
 
3423
        except AttributeError:
 
3424
            test._benchcalls = []
 
3425
            calls = test._benchcalls
 
3426
        calls.append(((test.id(), "", ""), stats))
 
3427
        ForwardingResult.addSuccess(self, test)
 
3428
 
 
3429
    def stopTest(self, test):
 
3430
        ForwardingResult.stopTest(self, test)
 
3431
        self.profiler = None
 
3432
 
 
3433
 
3184
3434
# Controlled by "bzr selftest -E=..." option
3185
3435
# Currently supported:
3186
3436
#   -Eallow_debug           Will no longer clear debug.debug_flags() so it
3208
3458
             runner_class=None,
3209
3459
             suite_decorators=None,
3210
3460
             stream=None,
 
3461
             lsprof_tests=False,
3211
3462
             ):
3212
3463
    """Run the whole test suite under the enhanced runner"""
3213
3464
    # XXX: Very ugly way to do this...
3242
3493
        if starting_with:
3243
3494
            # But always filter as requested.
3244
3495
            suite = filter_suite_by_id_startswith(suite, starting_with)
 
3496
        result_decorators = []
 
3497
        if lsprof_tests:
 
3498
            result_decorators.append(ProfileResult)
3245
3499
        return run_suite(suite, 'testbzr', verbose=verbose, pattern=pattern,
3246
3500
                     stop_on_failure=stop_on_failure,
3247
3501
                     transport=transport,
3255
3509
                     runner_class=runner_class,
3256
3510
                     suite_decorators=suite_decorators,
3257
3511
                     stream=stream,
 
3512
                     result_decorators=result_decorators,
3258
3513
                     )
3259
3514
    finally:
3260
3515
        default_transport = old_transport
3416
3671
test_prefix_alias_registry.register('bp', 'bzrlib.plugins')
3417
3672
 
3418
3673
 
 
3674
def _test_suite_testmod_names():
 
3675
    """Return the standard list of test module names to test."""
 
3676
    return [
 
3677
        'bzrlib.doc',
 
3678
        'bzrlib.tests.blackbox',
 
3679
        'bzrlib.tests.commands',
 
3680
        'bzrlib.tests.per_branch',
 
3681
        'bzrlib.tests.per_bzrdir',
 
3682
        'bzrlib.tests.per_interrepository',
 
3683
        'bzrlib.tests.per_intertree',
 
3684
        'bzrlib.tests.per_inventory',
 
3685
        'bzrlib.tests.per_interbranch',
 
3686
        'bzrlib.tests.per_lock',
 
3687
        'bzrlib.tests.per_transport',
 
3688
        'bzrlib.tests.per_tree',
 
3689
        'bzrlib.tests.per_pack_repository',
 
3690
        'bzrlib.tests.per_repository',
 
3691
        'bzrlib.tests.per_repository_chk',
 
3692
        'bzrlib.tests.per_repository_reference',
 
3693
        'bzrlib.tests.per_uifactory',
 
3694
        'bzrlib.tests.per_versionedfile',
 
3695
        'bzrlib.tests.per_workingtree',
 
3696
        'bzrlib.tests.test__annotator',
 
3697
        'bzrlib.tests.test__chk_map',
 
3698
        'bzrlib.tests.test__dirstate_helpers',
 
3699
        'bzrlib.tests.test__groupcompress',
 
3700
        'bzrlib.tests.test__known_graph',
 
3701
        'bzrlib.tests.test__rio',
 
3702
        'bzrlib.tests.test__simple_set',
 
3703
        'bzrlib.tests.test__static_tuple',
 
3704
        'bzrlib.tests.test__walkdirs_win32',
 
3705
        'bzrlib.tests.test_ancestry',
 
3706
        'bzrlib.tests.test_annotate',
 
3707
        'bzrlib.tests.test_api',
 
3708
        'bzrlib.tests.test_atomicfile',
 
3709
        'bzrlib.tests.test_bad_files',
 
3710
        'bzrlib.tests.test_bencode',
 
3711
        'bzrlib.tests.test_bisect_multi',
 
3712
        'bzrlib.tests.test_branch',
 
3713
        'bzrlib.tests.test_branchbuilder',
 
3714
        'bzrlib.tests.test_btree_index',
 
3715
        'bzrlib.tests.test_bugtracker',
 
3716
        'bzrlib.tests.test_bundle',
 
3717
        'bzrlib.tests.test_bzrdir',
 
3718
        'bzrlib.tests.test__chunks_to_lines',
 
3719
        'bzrlib.tests.test_cache_utf8',
 
3720
        'bzrlib.tests.test_chk_map',
 
3721
        'bzrlib.tests.test_chk_serializer',
 
3722
        'bzrlib.tests.test_chunk_writer',
 
3723
        'bzrlib.tests.test_clean_tree',
 
3724
        'bzrlib.tests.test_commands',
 
3725
        'bzrlib.tests.test_commit',
 
3726
        'bzrlib.tests.test_commit_merge',
 
3727
        'bzrlib.tests.test_config',
 
3728
        'bzrlib.tests.test_conflicts',
 
3729
        'bzrlib.tests.test_counted_lock',
 
3730
        'bzrlib.tests.test_crash',
 
3731
        'bzrlib.tests.test_decorators',
 
3732
        'bzrlib.tests.test_delta',
 
3733
        'bzrlib.tests.test_debug',
 
3734
        'bzrlib.tests.test_deprecated_graph',
 
3735
        'bzrlib.tests.test_diff',
 
3736
        'bzrlib.tests.test_directory_service',
 
3737
        'bzrlib.tests.test_dirstate',
 
3738
        'bzrlib.tests.test_email_message',
 
3739
        'bzrlib.tests.test_eol_filters',
 
3740
        'bzrlib.tests.test_errors',
 
3741
        'bzrlib.tests.test_export',
 
3742
        'bzrlib.tests.test_extract',
 
3743
        'bzrlib.tests.test_fetch',
 
3744
        'bzrlib.tests.test_fifo_cache',
 
3745
        'bzrlib.tests.test_filters',
 
3746
        'bzrlib.tests.test_ftp_transport',
 
3747
        'bzrlib.tests.test_foreign',
 
3748
        'bzrlib.tests.test_generate_docs',
 
3749
        'bzrlib.tests.test_generate_ids',
 
3750
        'bzrlib.tests.test_globbing',
 
3751
        'bzrlib.tests.test_gpg',
 
3752
        'bzrlib.tests.test_graph',
 
3753
        'bzrlib.tests.test_groupcompress',
 
3754
        'bzrlib.tests.test_hashcache',
 
3755
        'bzrlib.tests.test_help',
 
3756
        'bzrlib.tests.test_hooks',
 
3757
        'bzrlib.tests.test_http',
 
3758
        'bzrlib.tests.test_http_response',
 
3759
        'bzrlib.tests.test_https_ca_bundle',
 
3760
        'bzrlib.tests.test_identitymap',
 
3761
        'bzrlib.tests.test_ignores',
 
3762
        'bzrlib.tests.test_index',
 
3763
        'bzrlib.tests.test_info',
 
3764
        'bzrlib.tests.test_inv',
 
3765
        'bzrlib.tests.test_inventory_delta',
 
3766
        'bzrlib.tests.test_knit',
 
3767
        'bzrlib.tests.test_lazy_import',
 
3768
        'bzrlib.tests.test_lazy_regex',
 
3769
        'bzrlib.tests.test_lock',
 
3770
        'bzrlib.tests.test_lockable_files',
 
3771
        'bzrlib.tests.test_lockdir',
 
3772
        'bzrlib.tests.test_log',
 
3773
        'bzrlib.tests.test_lru_cache',
 
3774
        'bzrlib.tests.test_lsprof',
 
3775
        'bzrlib.tests.test_mail_client',
 
3776
        'bzrlib.tests.test_memorytree',
 
3777
        'bzrlib.tests.test_merge',
 
3778
        'bzrlib.tests.test_merge3',
 
3779
        'bzrlib.tests.test_merge_core',
 
3780
        'bzrlib.tests.test_merge_directive',
 
3781
        'bzrlib.tests.test_missing',
 
3782
        'bzrlib.tests.test_msgeditor',
 
3783
        'bzrlib.tests.test_multiparent',
 
3784
        'bzrlib.tests.test_mutabletree',
 
3785
        'bzrlib.tests.test_nonascii',
 
3786
        'bzrlib.tests.test_options',
 
3787
        'bzrlib.tests.test_osutils',
 
3788
        'bzrlib.tests.test_osutils_encodings',
 
3789
        'bzrlib.tests.test_pack',
 
3790
        'bzrlib.tests.test_patch',
 
3791
        'bzrlib.tests.test_patches',
 
3792
        'bzrlib.tests.test_permissions',
 
3793
        'bzrlib.tests.test_plugins',
 
3794
        'bzrlib.tests.test_progress',
 
3795
        'bzrlib.tests.test_read_bundle',
 
3796
        'bzrlib.tests.test_reconcile',
 
3797
        'bzrlib.tests.test_reconfigure',
 
3798
        'bzrlib.tests.test_registry',
 
3799
        'bzrlib.tests.test_remote',
 
3800
        'bzrlib.tests.test_rename_map',
 
3801
        'bzrlib.tests.test_repository',
 
3802
        'bzrlib.tests.test_revert',
 
3803
        'bzrlib.tests.test_revision',
 
3804
        'bzrlib.tests.test_revisionspec',
 
3805
        'bzrlib.tests.test_revisiontree',
 
3806
        'bzrlib.tests.test_rio',
 
3807
        'bzrlib.tests.test_rules',
 
3808
        'bzrlib.tests.test_sampler',
 
3809
        'bzrlib.tests.test_script',
 
3810
        'bzrlib.tests.test_selftest',
 
3811
        'bzrlib.tests.test_serializer',
 
3812
        'bzrlib.tests.test_setup',
 
3813
        'bzrlib.tests.test_sftp_transport',
 
3814
        'bzrlib.tests.test_shelf',
 
3815
        'bzrlib.tests.test_shelf_ui',
 
3816
        'bzrlib.tests.test_smart',
 
3817
        'bzrlib.tests.test_smart_add',
 
3818
        'bzrlib.tests.test_smart_request',
 
3819
        'bzrlib.tests.test_smart_transport',
 
3820
        'bzrlib.tests.test_smtp_connection',
 
3821
        'bzrlib.tests.test_source',
 
3822
        'bzrlib.tests.test_ssh_transport',
 
3823
        'bzrlib.tests.test_status',
 
3824
        'bzrlib.tests.test_store',
 
3825
        'bzrlib.tests.test_strace',
 
3826
        'bzrlib.tests.test_subsume',
 
3827
        'bzrlib.tests.test_switch',
 
3828
        'bzrlib.tests.test_symbol_versioning',
 
3829
        'bzrlib.tests.test_tag',
 
3830
        'bzrlib.tests.test_testament',
 
3831
        'bzrlib.tests.test_textfile',
 
3832
        'bzrlib.tests.test_textmerge',
 
3833
        'bzrlib.tests.test_timestamp',
 
3834
        'bzrlib.tests.test_trace',
 
3835
        'bzrlib.tests.test_transactions',
 
3836
        'bzrlib.tests.test_transform',
 
3837
        'bzrlib.tests.test_transport',
 
3838
        'bzrlib.tests.test_transport_log',
 
3839
        'bzrlib.tests.test_tree',
 
3840
        'bzrlib.tests.test_treebuilder',
 
3841
        'bzrlib.tests.test_tsort',
 
3842
        'bzrlib.tests.test_tuned_gzip',
 
3843
        'bzrlib.tests.test_ui',
 
3844
        'bzrlib.tests.test_uncommit',
 
3845
        'bzrlib.tests.test_upgrade',
 
3846
        'bzrlib.tests.test_upgrade_stacked',
 
3847
        'bzrlib.tests.test_urlutils',
 
3848
        'bzrlib.tests.test_version',
 
3849
        'bzrlib.tests.test_version_info',
 
3850
        'bzrlib.tests.test_weave',
 
3851
        'bzrlib.tests.test_whitebox',
 
3852
        'bzrlib.tests.test_win32utils',
 
3853
        'bzrlib.tests.test_workingtree',
 
3854
        'bzrlib.tests.test_workingtree_4',
 
3855
        'bzrlib.tests.test_wsgi',
 
3856
        'bzrlib.tests.test_xml',
 
3857
        ]
 
3858
 
 
3859
 
 
3860
def _test_suite_modules_to_doctest():
 
3861
    """Return the list of modules to doctest."""   
 
3862
    return [
 
3863
        'bzrlib',
 
3864
        'bzrlib.branchbuilder',
 
3865
        'bzrlib.export',
 
3866
        'bzrlib.inventory',
 
3867
        'bzrlib.iterablefile',
 
3868
        'bzrlib.lockdir',
 
3869
        'bzrlib.merge3',
 
3870
        'bzrlib.option',
 
3871
        'bzrlib.symbol_versioning',
 
3872
        'bzrlib.tests',
 
3873
        'bzrlib.timestamp',
 
3874
        'bzrlib.version_info_formats.format_custom',
 
3875
        ]
 
3876
 
 
3877
 
3419
3878
def test_suite(keep_only=None, starting_with=None):
3420
3879
    """Build and return TestSuite for the whole of bzrlib.
3421
3880
 
3427
3886
    This function can be replaced if you need to change the default test
3428
3887
    suite on a global basis, but it is not encouraged.
3429
3888
    """
3430
 
    testmod_names = [
3431
 
                   'bzrlib.doc',
3432
 
                   'bzrlib.tests.blackbox',
3433
 
                   'bzrlib.tests.commands',
3434
 
                   'bzrlib.tests.per_branch',
3435
 
                   'bzrlib.tests.per_bzrdir',
3436
 
                   'bzrlib.tests.per_interrepository',
3437
 
                   'bzrlib.tests.per_intertree',
3438
 
                   'bzrlib.tests.per_inventory',
3439
 
                   'bzrlib.tests.per_interbranch',
3440
 
                   'bzrlib.tests.per_lock',
3441
 
                   'bzrlib.tests.per_transport',
3442
 
                   'bzrlib.tests.per_tree',
3443
 
                   'bzrlib.tests.per_pack_repository',
3444
 
                   'bzrlib.tests.per_repository',
3445
 
                   'bzrlib.tests.per_repository_chk',
3446
 
                   'bzrlib.tests.per_repository_reference',
3447
 
                   'bzrlib.tests.per_versionedfile',
3448
 
                   'bzrlib.tests.per_workingtree',
3449
 
                   'bzrlib.tests.test__annotator',
3450
 
                   'bzrlib.tests.test__chk_map',
3451
 
                   'bzrlib.tests.test__dirstate_helpers',
3452
 
                   'bzrlib.tests.test__groupcompress',
3453
 
                   'bzrlib.tests.test__known_graph',
3454
 
                   'bzrlib.tests.test__rio',
3455
 
                   'bzrlib.tests.test__walkdirs_win32',
3456
 
                   'bzrlib.tests.test_ancestry',
3457
 
                   'bzrlib.tests.test_annotate',
3458
 
                   'bzrlib.tests.test_api',
3459
 
                   'bzrlib.tests.test_atomicfile',
3460
 
                   'bzrlib.tests.test_bad_files',
3461
 
                   'bzrlib.tests.test_bencode',
3462
 
                   'bzrlib.tests.test_bisect_multi',
3463
 
                   'bzrlib.tests.test_branch',
3464
 
                   'bzrlib.tests.test_branchbuilder',
3465
 
                   'bzrlib.tests.test_btree_index',
3466
 
                   'bzrlib.tests.test_bugtracker',
3467
 
                   'bzrlib.tests.test_bundle',
3468
 
                   'bzrlib.tests.test_bzrdir',
3469
 
                   'bzrlib.tests.test__chunks_to_lines',
3470
 
                   'bzrlib.tests.test_cache_utf8',
3471
 
                   'bzrlib.tests.test_chk_map',
3472
 
                   'bzrlib.tests.test_chk_serializer',
3473
 
                   'bzrlib.tests.test_chunk_writer',
3474
 
                   'bzrlib.tests.test_clean_tree',
3475
 
                   'bzrlib.tests.test_commands',
3476
 
                   'bzrlib.tests.test_commit',
3477
 
                   'bzrlib.tests.test_commit_merge',
3478
 
                   'bzrlib.tests.test_config',
3479
 
                   'bzrlib.tests.test_conflicts',
3480
 
                   'bzrlib.tests.test_counted_lock',
3481
 
                   'bzrlib.tests.test_crash',
3482
 
                   'bzrlib.tests.test_decorators',
3483
 
                   'bzrlib.tests.test_delta',
3484
 
                   'bzrlib.tests.test_debug',
3485
 
                   'bzrlib.tests.test_deprecated_graph',
3486
 
                   'bzrlib.tests.test_diff',
3487
 
                   'bzrlib.tests.test_directory_service',
3488
 
                   'bzrlib.tests.test_dirstate',
3489
 
                   'bzrlib.tests.test_email_message',
3490
 
                   'bzrlib.tests.test_eol_filters',
3491
 
                   'bzrlib.tests.test_errors',
3492
 
                   'bzrlib.tests.test_export',
3493
 
                   'bzrlib.tests.test_extract',
3494
 
                   'bzrlib.tests.test_fetch',
3495
 
                   'bzrlib.tests.test_fifo_cache',
3496
 
                   'bzrlib.tests.test_filters',
3497
 
                   'bzrlib.tests.test_ftp_transport',
3498
 
                   'bzrlib.tests.test_foreign',
3499
 
                   'bzrlib.tests.test_generate_docs',
3500
 
                   'bzrlib.tests.test_generate_ids',
3501
 
                   'bzrlib.tests.test_globbing',
3502
 
                   'bzrlib.tests.test_gpg',
3503
 
                   'bzrlib.tests.test_graph',
3504
 
                   'bzrlib.tests.test_groupcompress',
3505
 
                   'bzrlib.tests.test_hashcache',
3506
 
                   'bzrlib.tests.test_help',
3507
 
                   'bzrlib.tests.test_hooks',
3508
 
                   'bzrlib.tests.test_http',
3509
 
                   'bzrlib.tests.test_http_response',
3510
 
                   'bzrlib.tests.test_https_ca_bundle',
3511
 
                   'bzrlib.tests.test_identitymap',
3512
 
                   'bzrlib.tests.test_ignores',
3513
 
                   'bzrlib.tests.test_index',
3514
 
                   'bzrlib.tests.test_info',
3515
 
                   'bzrlib.tests.test_inv',
3516
 
                   'bzrlib.tests.test_inventory_delta',
3517
 
                   'bzrlib.tests.test_knit',
3518
 
                   'bzrlib.tests.test_lazy_import',
3519
 
                   'bzrlib.tests.test_lazy_regex',
3520
 
                   'bzrlib.tests.test_lock',
3521
 
                   'bzrlib.tests.test_lockable_files',
3522
 
                   'bzrlib.tests.test_lockdir',
3523
 
                   'bzrlib.tests.test_log',
3524
 
                   'bzrlib.tests.test_lru_cache',
3525
 
                   'bzrlib.tests.test_lsprof',
3526
 
                   'bzrlib.tests.test_mail_client',
3527
 
                   'bzrlib.tests.test_memorytree',
3528
 
                   'bzrlib.tests.test_merge',
3529
 
                   'bzrlib.tests.test_merge3',
3530
 
                   'bzrlib.tests.test_merge_core',
3531
 
                   'bzrlib.tests.test_merge_directive',
3532
 
                   'bzrlib.tests.test_missing',
3533
 
                   'bzrlib.tests.test_msgeditor',
3534
 
                   'bzrlib.tests.test_multiparent',
3535
 
                   'bzrlib.tests.test_mutabletree',
3536
 
                   'bzrlib.tests.test_nonascii',
3537
 
                   'bzrlib.tests.test_options',
3538
 
                   'bzrlib.tests.test_osutils',
3539
 
                   'bzrlib.tests.test_osutils_encodings',
3540
 
                   'bzrlib.tests.test_pack',
3541
 
                   'bzrlib.tests.test_patch',
3542
 
                   'bzrlib.tests.test_patches',
3543
 
                   'bzrlib.tests.test_permissions',
3544
 
                   'bzrlib.tests.test_plugins',
3545
 
                   'bzrlib.tests.test_progress',
3546
 
                   'bzrlib.tests.test_read_bundle',
3547
 
                   'bzrlib.tests.test_reconcile',
3548
 
                   'bzrlib.tests.test_reconfigure',
3549
 
                   'bzrlib.tests.test_registry',
3550
 
                   'bzrlib.tests.test_remote',
3551
 
                   'bzrlib.tests.test_rename_map',
3552
 
                   'bzrlib.tests.test_repository',
3553
 
                   'bzrlib.tests.test_revert',
3554
 
                   'bzrlib.tests.test_revision',
3555
 
                   'bzrlib.tests.test_revisionspec',
3556
 
                   'bzrlib.tests.test_revisiontree',
3557
 
                   'bzrlib.tests.test_rio',
3558
 
                   'bzrlib.tests.test_rules',
3559
 
                   'bzrlib.tests.test_sampler',
3560
 
                   'bzrlib.tests.test_selftest',
3561
 
                   'bzrlib.tests.test_serializer',
3562
 
                   'bzrlib.tests.test_setup',
3563
 
                   'bzrlib.tests.test_sftp_transport',
3564
 
                   'bzrlib.tests.test_shelf',
3565
 
                   'bzrlib.tests.test_shelf_ui',
3566
 
                   'bzrlib.tests.test_smart',
3567
 
                   'bzrlib.tests.test_smart_add',
3568
 
                   'bzrlib.tests.test_smart_request',
3569
 
                   'bzrlib.tests.test_smart_transport',
3570
 
                   'bzrlib.tests.test_smtp_connection',
3571
 
                   'bzrlib.tests.test_source',
3572
 
                   'bzrlib.tests.test_ssh_transport',
3573
 
                   'bzrlib.tests.test_status',
3574
 
                   'bzrlib.tests.test_store',
3575
 
                   'bzrlib.tests.test_strace',
3576
 
                   'bzrlib.tests.test_subsume',
3577
 
                   'bzrlib.tests.test_switch',
3578
 
                   'bzrlib.tests.test_symbol_versioning',
3579
 
                   'bzrlib.tests.test_tag',
3580
 
                   'bzrlib.tests.test_testament',
3581
 
                   'bzrlib.tests.test_textfile',
3582
 
                   'bzrlib.tests.test_textmerge',
3583
 
                   'bzrlib.tests.test_timestamp',
3584
 
                   'bzrlib.tests.test_trace',
3585
 
                   'bzrlib.tests.test_transactions',
3586
 
                   'bzrlib.tests.test_transform',
3587
 
                   'bzrlib.tests.test_transport',
3588
 
                   'bzrlib.tests.test_transport_log',
3589
 
                   'bzrlib.tests.test_tree',
3590
 
                   'bzrlib.tests.test_treebuilder',
3591
 
                   'bzrlib.tests.test_tsort',
3592
 
                   'bzrlib.tests.test_tuned_gzip',
3593
 
                   'bzrlib.tests.test_ui',
3594
 
                   'bzrlib.tests.test_uncommit',
3595
 
                   'bzrlib.tests.test_upgrade',
3596
 
                   'bzrlib.tests.test_upgrade_stacked',
3597
 
                   'bzrlib.tests.test_urlutils',
3598
 
                   'bzrlib.tests.test_version',
3599
 
                   'bzrlib.tests.test_version_info',
3600
 
                   'bzrlib.tests.test_weave',
3601
 
                   'bzrlib.tests.test_whitebox',
3602
 
                   'bzrlib.tests.test_win32utils',
3603
 
                   'bzrlib.tests.test_workingtree',
3604
 
                   'bzrlib.tests.test_workingtree_4',
3605
 
                   'bzrlib.tests.test_wsgi',
3606
 
                   'bzrlib.tests.test_xml',
3607
 
                   ]
3608
3889
 
3609
3890
    loader = TestUtil.TestLoader()
3610
3891
 
3639
3920
    suite = loader.suiteClass()
3640
3921
 
3641
3922
    # modules building their suite with loadTestsFromModuleNames
3642
 
    suite.addTest(loader.loadTestsFromModuleNames(testmod_names))
3643
 
 
3644
 
    modules_to_doctest = [
3645
 
        'bzrlib',
3646
 
        'bzrlib.branchbuilder',
3647
 
        'bzrlib.export',
3648
 
        'bzrlib.inventory',
3649
 
        'bzrlib.iterablefile',
3650
 
        'bzrlib.lockdir',
3651
 
        'bzrlib.merge3',
3652
 
        'bzrlib.option',
3653
 
        'bzrlib.symbol_versioning',
3654
 
        'bzrlib.tests',
3655
 
        'bzrlib.timestamp',
3656
 
        'bzrlib.version_info_formats.format_custom',
3657
 
        ]
3658
 
 
3659
 
    for mod in modules_to_doctest:
 
3923
    suite.addTest(loader.loadTestsFromModuleNames(_test_suite_testmod_names()))
 
3924
 
 
3925
    for mod in _test_suite_modules_to_doctest():
3660
3926
        if not interesting_module(mod):
3661
3927
            # No tests to keep here, move along
3662
3928
            continue
3803
4069
    :param new_id: The id to assign to it.
3804
4070
    :return: The new test.
3805
4071
    """
3806
 
    from copy import deepcopy
3807
 
    new_test = deepcopy(test)
 
4072
    new_test = copy(test)
3808
4073
    new_test.id = lambda: new_id
3809
4074
    return new_test
3810
4075
 
3970
4235
HTTPSServerFeature = _HTTPSServerFeature()
3971
4236
 
3972
4237
 
 
4238
class _ParamikoFeature(Feature):
 
4239
    """Is paramiko available?"""
 
4240
 
 
4241
    def _probe(self):
 
4242
        try:
 
4243
            from bzrlib.transport.sftp import SFTPAbsoluteServer
 
4244
            return True
 
4245
        except errors.ParamikoNotPresent:
 
4246
            return False
 
4247
 
 
4248
    def feature_name(self):
 
4249
        return "Paramiko"
 
4250
 
 
4251
 
 
4252
ParamikoFeature = _ParamikoFeature()
 
4253
 
 
4254
 
3973
4255
class _UnicodeFilename(Feature):
3974
4256
    """Does the filesystem support Unicode filenames?"""
3975
4257
 
4001
4283
UTF8Filesystem = _UTF8Filesystem()
4002
4284
 
4003
4285
 
 
4286
class _BreakinFeature(Feature):
 
4287
    """Does this platform support the breakin feature?"""
 
4288
 
 
4289
    def _probe(self):
 
4290
        from bzrlib import breakin
 
4291
        if breakin.determine_signal() is None:
 
4292
            return False
 
4293
        if sys.platform == 'win32':
 
4294
            # Windows doesn't have os.kill, and we catch the SIGBREAK signal.
 
4295
            # We trigger SIGBREAK via a Console api so we need ctypes to
 
4296
            # access the function
 
4297
            if not have_ctypes:
 
4298
                return False
 
4299
        return True
 
4300
 
 
4301
    def feature_name(self):
 
4302
        return "SIGQUIT or SIGBREAK w/ctypes on win32"
 
4303
 
 
4304
 
 
4305
BreakinFeature = _BreakinFeature()
 
4306
 
 
4307
 
4004
4308
class _CaseInsCasePresFilenameFeature(Feature):
4005
4309
    """Is the file-system case insensitive, but case-preserving?"""
4006
4310