~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_selftest.py

Merge pt1 hooks branch.

Show diffs side-by-side

added added

removed removed

Lines of Context:
29
29
from testtools import (
30
30
    ExtendedToOriginalDecorator,
31
31
    MultiTestResult,
32
 
    __version__ as testtools_version,
33
32
    )
34
33
from testtools.content import Content
35
34
from testtools.content_type import ContentType
37
36
    DocTestMatches,
38
37
    Equals,
39
38
    )
40
 
import testtools.testresult.doubles
 
39
import testtools.tests.helpers
41
40
 
42
41
import bzrlib
43
42
from bzrlib import (
44
43
    branchbuilder,
45
44
    bzrdir,
46
45
    errors,
47
 
    hooks,
48
46
    lockdir,
49
47
    memorytree,
50
48
    osutils,
54
52
    tests,
55
53
    transport,
56
54
    workingtree,
57
 
    workingtree_3,
58
 
    workingtree_4,
59
55
    )
60
56
from bzrlib.repofmt import (
61
57
    groupcompress_repo,
 
58
    weaverepo,
62
59
    )
63
60
from bzrlib.symbol_versioning import (
64
61
    deprecated_function,
94
91
            DocTestMatches(u"...a test message\n", doctest.ELLIPSIS))
95
92
 
96
93
 
 
94
class TestUnicodeFilename(tests.TestCase):
 
95
 
 
96
    def test_probe_passes(self):
 
97
        """UnicodeFilename._probe passes."""
 
98
        # We can't test much more than that because the behaviour depends
 
99
        # on the platform.
 
100
        tests.UnicodeFilename._probe()
 
101
 
 
102
 
97
103
class TestTreeShape(tests.TestCaseInTempDir):
98
104
 
99
105
    def test_unicode_paths(self):
100
 
        self.requireFeature(features.UnicodeFilenameFeature)
 
106
        self.requireFeature(tests.UnicodeFilename)
101
107
 
102
108
        filename = u'hell\u00d8'
103
109
        self.build_tree_contents([(filename, 'contents of hello')])
104
 
        self.assertPathExists(filename)
 
110
        self.failUnlessExists(filename)
105
111
 
106
112
 
107
113
class TestClassesAvailable(tests.TestCase):
333
339
        from bzrlib.tests.per_workingtree import make_scenarios
334
340
        server1 = "a"
335
341
        server2 = "b"
336
 
        formats = [workingtree_4.WorkingTreeFormat4(),
337
 
                   workingtree_3.WorkingTreeFormat3(),]
 
342
        formats = [workingtree.WorkingTreeFormat2(),
 
343
                   workingtree.WorkingTreeFormat3(),]
338
344
        scenarios = make_scenarios(server1, server2, formats)
339
345
        self.assertEqual([
340
 
            ('WorkingTreeFormat4',
 
346
            ('WorkingTreeFormat2',
341
347
             {'bzrdir_format': formats[0]._matchingbzrdir,
342
348
              'transport_readonly_server': 'b',
343
349
              'transport_server': 'a',
370
376
            )
371
377
        server1 = "a"
372
378
        server2 = "b"
373
 
        formats = [workingtree_4.WorkingTreeFormat4(),
374
 
                   workingtree_3.WorkingTreeFormat3(),]
 
379
        formats = [workingtree.WorkingTreeFormat2(),
 
380
                   workingtree.WorkingTreeFormat3(),]
375
381
        scenarios = make_scenarios(server1, server2, formats)
376
382
        self.assertEqual(7, len(scenarios))
377
 
        default_wt_format = workingtree.format_registry.get_default()
378
 
        wt4_format = workingtree_4.WorkingTreeFormat4()
379
 
        wt5_format = workingtree_4.WorkingTreeFormat5()
 
383
        default_wt_format = workingtree.WorkingTreeFormat4._default_format
 
384
        wt4_format = workingtree.WorkingTreeFormat4()
 
385
        wt5_format = workingtree.WorkingTreeFormat5()
380
386
        expected_scenarios = [
381
 
            ('WorkingTreeFormat4',
 
387
            ('WorkingTreeFormat2',
382
388
             {'bzrdir_format': formats[0]._matchingbzrdir,
383
389
              'transport_readonly_server': 'b',
384
390
              'transport_server': 'a',
444
450
        # ones to add.
445
451
        from bzrlib.tests.per_tree import (
446
452
            return_parameter,
 
453
            revision_tree_from_workingtree
447
454
            )
448
455
        from bzrlib.tests.per_intertree import (
449
456
            make_scenarios,
450
457
            )
451
 
        from bzrlib.workingtree_3 import WorkingTreeFormat3
452
 
        from bzrlib.workingtree_4 import WorkingTreeFormat4
 
458
        from bzrlib.workingtree import WorkingTreeFormat2, WorkingTreeFormat3
453
459
        input_test = TestInterTreeScenarios(
454
460
            "test_scenarios")
455
461
        server1 = "a"
456
462
        server2 = "b"
457
 
        format1 = WorkingTreeFormat4()
 
463
        format1 = WorkingTreeFormat2()
458
464
        format2 = WorkingTreeFormat3()
459
465
        formats = [("1", str, format1, format2, "converter1"),
460
466
            ("2", int, format2, format1, "converter2")]
506
512
        self.assertRaises(AssertionError, self.assertEqualStat,
507
513
            os.lstat("foo"), os.lstat("longname"))
508
514
 
509
 
    def test_failUnlessExists(self):
510
 
        """Deprecated failUnlessExists and failIfExists"""
511
 
        self.applyDeprecated(
512
 
            deprecated_in((2, 4)),
513
 
            self.failUnlessExists, '.')
514
 
        self.build_tree(['foo/', 'foo/bar'])
515
 
        self.applyDeprecated(
516
 
            deprecated_in((2, 4)),
517
 
            self.failUnlessExists, 'foo/bar')
518
 
        self.applyDeprecated(
519
 
            deprecated_in((2, 4)),
520
 
            self.failIfExists, 'foo/foo')
521
 
 
522
 
    def test_assertPathExists(self):
523
 
        self.assertPathExists('.')
524
 
        self.build_tree(['foo/', 'foo/bar'])
525
 
        self.assertPathExists('foo/bar')
526
 
        self.assertPathDoesNotExist('foo/foo')
527
 
 
528
515
 
529
516
class TestTestCaseWithMemoryTransport(tests.TestCaseWithMemoryTransport):
530
517
 
564
551
        tree = self.make_branch_and_memory_tree('dir')
565
552
        # Guard against regression into MemoryTransport leaking
566
553
        # files to disk instead of keeping them in memory.
567
 
        self.assertFalse(osutils.lexists('dir'))
 
554
        self.failIf(osutils.lexists('dir'))
568
555
        self.assertIsInstance(tree, memorytree.MemoryTree)
569
556
 
570
557
    def test_make_branch_and_memory_tree_with_format(self):
571
558
        """make_branch_and_memory_tree should accept a format option."""
572
559
        format = bzrdir.BzrDirMetaFormat1()
573
 
        format.repository_format = repository.format_registry.get_default()
 
560
        format.repository_format = weaverepo.RepositoryFormat7()
574
561
        tree = self.make_branch_and_memory_tree('dir', format=format)
575
562
        # Guard against regression into MemoryTransport leaking
576
563
        # files to disk instead of keeping them in memory.
577
 
        self.assertFalse(osutils.lexists('dir'))
 
564
        self.failIf(osutils.lexists('dir'))
578
565
        self.assertIsInstance(tree, memorytree.MemoryTree)
579
566
        self.assertEqual(format.repository_format.__class__,
580
567
            tree.branch.repository._format.__class__)
584
571
        self.assertIsInstance(builder, branchbuilder.BranchBuilder)
585
572
        # Guard against regression into MemoryTransport leaking
586
573
        # files to disk instead of keeping them in memory.
587
 
        self.assertFalse(osutils.lexists('dir'))
 
574
        self.failIf(osutils.lexists('dir'))
588
575
 
589
576
    def test_make_branch_builder_with_format(self):
590
577
        # Use a repo layout that doesn't conform to a 'named' layout, to ensure
591
578
        # that the format objects are used.
592
579
        format = bzrdir.BzrDirMetaFormat1()
593
 
        repo_format = repository.format_registry.get_default()
 
580
        repo_format = weaverepo.RepositoryFormat7()
594
581
        format.repository_format = repo_format
595
582
        builder = self.make_branch_builder('dir', format=format)
596
583
        the_branch = builder.get_branch()
597
584
        # Guard against regression into MemoryTransport leaking
598
585
        # files to disk instead of keeping them in memory.
599
 
        self.assertFalse(osutils.lexists('dir'))
 
586
        self.failIf(osutils.lexists('dir'))
600
587
        self.assertEqual(format.repository_format.__class__,
601
588
                         the_branch.repository._format.__class__)
602
589
        self.assertEqual(repo_format.get_format_string(),
608
595
        the_branch = builder.get_branch()
609
596
        # Guard against regression into MemoryTransport leaking
610
597
        # files to disk instead of keeping them in memory.
611
 
        self.assertFalse(osutils.lexists('dir'))
 
598
        self.failIf(osutils.lexists('dir'))
612
599
        dir_format = bzrdir.format_registry.make_bzrdir('knit')
613
600
        self.assertEqual(dir_format.repository_format.__class__,
614
601
                         the_branch.repository._format.__class__)
619
606
    def test_dangling_locks_cause_failures(self):
620
607
        class TestDanglingLock(tests.TestCaseWithMemoryTransport):
621
608
            def test_function(self):
622
 
                t = self.get_transport_from_path('.')
 
609
                t = self.get_transport('.')
623
610
                l = lockdir.LockDir(t, 'lock')
624
611
                l.create()
625
612
                l.attempt_lock()
645
632
        # for the server
646
633
        url = self.get_readonly_url()
647
634
        url2 = self.get_readonly_url('foo/bar')
648
 
        t = transport.get_transport_from_url(url)
649
 
        t2 = transport.get_transport_from_url(url2)
650
 
        self.assertIsInstance(t, ReadonlyTransportDecorator)
651
 
        self.assertIsInstance(t2, ReadonlyTransportDecorator)
 
635
        t = transport.get_transport(url)
 
636
        t2 = transport.get_transport(url2)
 
637
        self.failUnless(isinstance(t, ReadonlyTransportDecorator))
 
638
        self.failUnless(isinstance(t2, ReadonlyTransportDecorator))
652
639
        self.assertEqual(t2.base[:-1], t.abspath('foo/bar'))
653
640
 
654
641
    def test_get_readonly_url_http(self):
660
647
        url = self.get_readonly_url()
661
648
        url2 = self.get_readonly_url('foo/bar')
662
649
        # the transport returned may be any HttpTransportBase subclass
663
 
        t = transport.get_transport_from_url(url)
664
 
        t2 = transport.get_transport_from_url(url2)
665
 
        self.assertIsInstance(t, HttpTransportBase)
666
 
        self.assertIsInstance(t2, HttpTransportBase)
 
650
        t = transport.get_transport(url)
 
651
        t2 = transport.get_transport(url2)
 
652
        self.failUnless(isinstance(t, HttpTransportBase))
 
653
        self.failUnless(isinstance(t2, HttpTransportBase))
667
654
        self.assertEqual(t2.base[:-1], t.abspath('foo/bar'))
668
655
 
669
656
    def test_is_directory(self):
677
664
    def test_make_branch_builder(self):
678
665
        builder = self.make_branch_builder('dir')
679
666
        rev_id = builder.build_commit()
680
 
        self.assertPathExists('dir')
 
667
        self.failUnlessExists('dir')
681
668
        a_dir = bzrdir.BzrDir.open('dir')
682
669
        self.assertRaises(errors.NoWorkingTree, a_dir.open_workingtree)
683
670
        a_branch = a_dir.open_branch()
699
686
        self.assertIsInstance(result_bzrdir.transport,
700
687
                              memory.MemoryTransport)
701
688
        # should not be on disk, should only be in memory
702
 
        self.assertPathDoesNotExist('subdir')
 
689
        self.failIfExists('subdir')
703
690
 
704
691
 
705
692
class TestChrootedTest(tests.ChrootedTestCase):
706
693
 
707
694
    def test_root_is_root(self):
708
 
        t = transport.get_transport_from_url(self.get_readonly_url())
 
695
        t = transport.get_transport(self.get_readonly_url())
709
696
        url = t.base
710
697
        self.assertEqual(url, t.clone('..').base)
711
698
 
713
700
class TestProfileResult(tests.TestCase):
714
701
 
715
702
    def test_profiles_tests(self):
716
 
        self.requireFeature(features.lsprof_feature)
717
 
        terminal = testtools.testresult.doubles.ExtendedTestResult()
 
703
        self.requireFeature(test_lsprof.LSProfFeature)
 
704
        terminal = testtools.tests.helpers.ExtendedTestResult()
718
705
        result = tests.ProfileResult(terminal)
719
706
        class Sample(tests.TestCase):
720
707
            def a(self):
737
724
                descriptions=0,
738
725
                verbosity=1,
739
726
                )
740
 
        capture = testtools.testresult.doubles.ExtendedTestResult()
 
727
        capture = testtools.tests.helpers.ExtendedTestResult()
741
728
        test_case.run(MultiTestResult(result, capture))
742
729
        run_case = capture._events[0][1]
743
730
        timed_string = result._testTimeString(run_case)
764
751
        self.check_timing(ShortDelayTestCase('test_short_delay'),
765
752
                          r"^ +[0-9]+ms$")
766
753
 
 
754
    def _patch_get_bzr_source_tree(self):
 
755
        # Reading from the actual source tree breaks isolation, but we don't
 
756
        # want to assume that thats *all* that would happen.
 
757
        self.overrideAttr(bzrlib.version, '_get_bzr_source_tree', lambda: None)
 
758
 
 
759
    def test_assigned_benchmark_file_stores_date(self):
 
760
        self._patch_get_bzr_source_tree()
 
761
        output = StringIO()
 
762
        result = bzrlib.tests.TextTestResult(self._log_file,
 
763
                                        descriptions=0,
 
764
                                        verbosity=1,
 
765
                                        bench_history=output
 
766
                                        )
 
767
        output_string = output.getvalue()
 
768
        # if you are wondering about the regexp please read the comment in
 
769
        # test_bench_history (bzrlib.tests.test_selftest.TestRunner)
 
770
        # XXX: what comment?  -- Andrew Bennetts
 
771
        self.assertContainsRe(output_string, "--date [0-9.]+")
 
772
 
 
773
    def test_benchhistory_records_test_times(self):
 
774
        self._patch_get_bzr_source_tree()
 
775
        result_stream = StringIO()
 
776
        result = bzrlib.tests.TextTestResult(
 
777
            self._log_file,
 
778
            descriptions=0,
 
779
            verbosity=1,
 
780
            bench_history=result_stream
 
781
            )
 
782
 
 
783
        # we want profile a call and check that its test duration is recorded
 
784
        # make a new test instance that when run will generate a benchmark
 
785
        example_test_case = TestTestResult("_time_hello_world_encoding")
 
786
        # execute the test, which should succeed and record times
 
787
        example_test_case.run(result)
 
788
        lines = result_stream.getvalue().splitlines()
 
789
        self.assertEqual(2, len(lines))
 
790
        self.assertContainsRe(lines[1],
 
791
            " *[0-9]+ms bzrlib.tests.test_selftest.TestTestResult"
 
792
            "._time_hello_world_encoding")
 
793
 
767
794
    def _time_hello_world_encoding(self):
768
795
        """Profile two sleep calls
769
796
 
774
801
 
775
802
    def test_lsprofiling(self):
776
803
        """Verbose test result prints lsprof statistics from test cases."""
777
 
        self.requireFeature(features.lsprof_feature)
 
804
        self.requireFeature(test_lsprof.LSProfFeature)
778
805
        result_stream = StringIO()
779
806
        result = bzrlib.tests.VerboseTestResult(
780
807
            result_stream,
825
852
        self.assertEndsWith(sio.getvalue(), "OK    50002ms\n")
826
853
 
827
854
    def test_known_failure(self):
828
 
        """Using knownFailure should trigger several result actions."""
 
855
        """A KnownFailure being raised should trigger several result actions."""
829
856
        class InstrumentedTestResult(tests.ExtendedTestResult):
830
857
            def stopTestRun(self): pass
831
858
            def report_tests_starting(self): pass
834
861
        result = InstrumentedTestResult(None, None, None, None)
835
862
        class Test(tests.TestCase):
836
863
            def test_function(self):
837
 
                self.knownFailure('failed!')
 
864
                raise tests.KnownFailure('failed!')
838
865
        test = Test("test_function")
839
866
        test.run(result)
840
867
        # it should invoke 'report_known_failure'.
856
883
            descriptions=0,
857
884
            verbosity=2,
858
885
            )
859
 
        _get_test("test_xfail").run(result)
860
 
        self.assertContainsRe(result_stream.getvalue(),
861
 
            "\n\\S+\\.test_xfail\\s+XFAIL\\s+\\d+ms\n"
862
 
            "\\s*(?:Text attachment: )?reason"
863
 
            "(?:\n-+\n|: {{{)"
864
 
            "this_fails"
865
 
            "(?:\n-+\n|}}}\n)")
 
886
        test = self.get_passing_test()
 
887
        result.startTest(test)
 
888
        prefix = len(result_stream.getvalue())
 
889
        # the err parameter has the shape:
 
890
        # (class, exception object, traceback)
 
891
        # KnownFailures dont get their tracebacks shown though, so we
 
892
        # can skip that.
 
893
        err = (tests.KnownFailure, tests.KnownFailure('foo'), None)
 
894
        result.report_known_failure(test, err)
 
895
        output = result_stream.getvalue()[prefix:]
 
896
        lines = output.splitlines()
 
897
        self.assertContainsRe(lines[0], r'XFAIL *\d+ms$')
 
898
        if sys.version_info > (2, 7):
 
899
            self.expectFailure("_ExpectedFailure on 2.7 loses the message",
 
900
                self.assertNotEqual, lines[1], '    ')
 
901
        self.assertEqual(lines[1], '    foo')
 
902
        self.assertEqual(2, len(lines))
866
903
 
867
904
    def get_passing_test(self):
868
905
        """Return a test object that can't be run usefully."""
879
916
                self._call = test, feature
880
917
        result = InstrumentedTestResult(None, None, None, None)
881
918
        test = SampleTestCase('_test_pass')
882
 
        feature = features.Feature()
 
919
        feature = tests.Feature()
883
920
        result.startTest(test)
884
921
        result.addNotSupported(test, feature)
885
922
        # it should invoke 'report_unsupported'.
904
941
            verbosity=2,
905
942
            )
906
943
        test = self.get_passing_test()
907
 
        feature = features.Feature()
 
944
        feature = tests.Feature()
908
945
        result.startTest(test)
909
946
        prefix = len(result_stream.getvalue())
910
947
        result.report_unsupported(test, feature)
923
960
            def addNotSupported(self, test, feature):
924
961
                self._call = test, feature
925
962
        result = InstrumentedTestResult(None, None, None, None)
926
 
        feature = features.Feature()
 
963
        feature = tests.Feature()
927
964
        class Test(tests.TestCase):
928
965
            def test_function(self):
929
966
                raise tests.UnavailableFeature(feature)
948
985
    def test_strict_with_known_failure(self):
949
986
        result = bzrlib.tests.TextTestResult(self._log_file, descriptions=0,
950
987
                                             verbosity=1)
951
 
        test = _get_test("test_xfail")
952
 
        test.run(result)
 
988
        test = self.get_passing_test()
 
989
        err = (tests.KnownFailure, tests.KnownFailure('foo'), None)
 
990
        result.addExpectedFailure(test, err)
953
991
        self.assertFalse(result.wasStrictlySuccessful())
954
992
        self.assertEqual(None, result._extractBenchmarkTime(test))
955
993
 
987
1025
        self.assertEquals(2, result.count)
988
1026
 
989
1027
 
 
1028
class TestUnicodeFilenameFeature(tests.TestCase):
 
1029
 
 
1030
    def test_probe_passes(self):
 
1031
        """UnicodeFilenameFeature._probe passes."""
 
1032
        # We can't test much more than that because the behaviour depends
 
1033
        # on the platform.
 
1034
        tests.UnicodeFilenameFeature._probe()
 
1035
 
 
1036
 
990
1037
class TestRunner(tests.TestCase):
991
1038
 
992
1039
    def dummy_test(self):
1018
1065
        test = unittest.TestSuite()
1019
1066
        test.addTest(Test("known_failure_test"))
1020
1067
        def failing_test():
1021
 
            raise AssertionError('foo')
 
1068
            self.fail('foo')
1022
1069
        test.addTest(unittest.FunctionTestCase(failing_test))
1023
1070
        stream = StringIO()
1024
1071
        runner = tests.TextTestRunner(stream=stream)
1032
1079
            '^----------------------------------------------------------------------\n'
1033
1080
            'Traceback \\(most recent call last\\):\n'
1034
1081
            '  .*' # File .*, line .*, in failing_test' - but maybe not from .pyc
1035
 
            '    raise AssertionError\\(\'foo\'\\)\n'
 
1082
            '    self.fail\\(\'foo\'\\)\n'
1036
1083
            '.*'
1037
1084
            '^----------------------------------------------------------------------\n'
1038
1085
            '.*'
1044
1091
        # the final output.
1045
1092
        class Test(tests.TestCase):
1046
1093
            def known_failure_test(self):
1047
 
                self.knownFailure("Never works...")
 
1094
                self.expectFailure('failed', self.assertTrue, False)
1048
1095
        test = Test("known_failure_test")
1049
1096
        stream = StringIO()
1050
1097
        runner = tests.TextTestRunner(stream=stream)
1056
1103
            '\n'
1057
1104
            'OK \\(known_failures=1\\)\n')
1058
1105
 
1059
 
    def test_unexpected_success_bad(self):
1060
 
        class Test(tests.TestCase):
1061
 
            def test_truth(self):
1062
 
                self.expectFailure("No absolute truth", self.assertTrue, True)
1063
 
        runner = tests.TextTestRunner(stream=StringIO())
1064
 
        result = self.run_test_runner(runner, Test("test_truth"))
1065
 
        if testtools_version[:3] <= (0, 9, 11):
1066
 
            self.assertContainsRe(runner.stream.getvalue(),
1067
 
                "=+\n"
1068
 
                "FAIL: \\S+\.test_truth\n"
1069
 
                "-+\n"
1070
 
                "(?:.*\n)*"
1071
 
                "No absolute truth\n"
1072
 
                "(?:.*\n)*"
1073
 
                "-+\n"
1074
 
                "Ran 1 test in .*\n"
1075
 
                "\n"
1076
 
                "FAILED \\(failures=1\\)\n\\Z")
1077
 
        else:
1078
 
            self.assertContainsRe(runner.stream.getvalue(),
1079
 
                "=+\n"
1080
 
                "FAIL: \\S+\.test_truth\n"
1081
 
                "-+\n"
1082
 
                "Empty attachments:\n"
1083
 
                "  log\n"
1084
 
                "\n"
1085
 
                "reason: {{{No absolute truth}}}\n"
1086
 
                "-+\n"
1087
 
                "Ran 1 test in .*\n"
1088
 
                "\n"
1089
 
                "FAILED \\(failures=1\\)\n\\Z")
1090
 
 
1091
1106
    def test_result_decorator(self):
1092
1107
        # decorate results
1093
1108
        calls = []
1177
1192
 
1178
1193
    def test_unsupported_features_listed(self):
1179
1194
        """When unsupported features are encountered they are detailed."""
1180
 
        class Feature1(features.Feature):
 
1195
        class Feature1(tests.Feature):
1181
1196
            def _probe(self): return False
1182
 
        class Feature2(features.Feature):
 
1197
        class Feature2(tests.Feature):
1183
1198
            def _probe(self): return False
1184
1199
        # create sample tests
1185
1200
        test1 = SampleTestCase('_test_pass')
1200
1215
            ],
1201
1216
            lines[-3:])
1202
1217
 
 
1218
    def _patch_get_bzr_source_tree(self):
 
1219
        # Reading from the actual source tree breaks isolation, but we don't
 
1220
        # want to assume that thats *all* that would happen.
 
1221
        self._get_source_tree_calls = []
 
1222
        def new_get():
 
1223
            self._get_source_tree_calls.append("called")
 
1224
            return None
 
1225
        self.overrideAttr(bzrlib.version, '_get_bzr_source_tree',  new_get)
 
1226
 
 
1227
    def test_bench_history(self):
 
1228
        # tests that the running the benchmark passes bench_history into
 
1229
        # the test result object. We can tell that happens if
 
1230
        # _get_bzr_source_tree is called.
 
1231
        self._patch_get_bzr_source_tree()
 
1232
        test = TestRunner('dummy_test')
 
1233
        output = StringIO()
 
1234
        runner = tests.TextTestRunner(stream=self._log_file,
 
1235
                                      bench_history=output)
 
1236
        result = self.run_test_runner(runner, test)
 
1237
        output_string = output.getvalue()
 
1238
        self.assertContainsRe(output_string, "--date [0-9.]+")
 
1239
        self.assertLength(1, self._get_source_tree_calls)
 
1240
 
1203
1241
    def test_verbose_test_count(self):
1204
1242
        """A verbose test run reports the right test count at the start"""
1205
1243
        suite = TestUtil.TestSuite([
1251
1289
            lambda trace=False: "ascii")
1252
1290
        result = self.run_test_runner(tests.TextTestRunner(stream=out),
1253
1291
            FailureWithUnicode("test_log_unicode"))
1254
 
        if testtools_version[:3] > (0, 9, 11):
1255
 
            self.assertContainsRe(out.getvalue(), "log: {{{\d+\.\d+  \\\\u2606}}}")
1256
 
        else:
1257
 
            self.assertContainsRe(out.getvalue(),
1258
 
                "Text attachment: log\n"
1259
 
                "-+\n"
1260
 
                "\d+\.\d+  \\\\u2606\n"
1261
 
                "-+\n")
 
1292
        self.assertContainsRe(out.getvalue(),
 
1293
            "Text attachment: log\n"
 
1294
            "-+\n"
 
1295
            "\d+\.\d+  \\\\u2606\n"
 
1296
            "-+\n")
1262
1297
 
1263
1298
 
1264
1299
class SampleTestCase(tests.TestCase):
1453
1488
        # Note this test won't fail with hooks that the core library doesn't
1454
1489
        # use - but it trigger with a plugin that adds hooks, so its still a
1455
1490
        # useful warning in that case.
1456
 
        self.assertEqual(bzrlib.branch.BranchHooks(), bzrlib.branch.Branch.hooks)
1457
 
        self.assertEqual(
1458
 
            bzrlib.smart.server.SmartServerHooks(),
 
1491
        self.assertEqual(bzrlib.branch.BranchHooks(),
 
1492
            bzrlib.branch.Branch.hooks)
 
1493
        self.assertEqual(bzrlib.smart.server.SmartServerHooks(),
1459
1494
            bzrlib.smart.server.SmartTCPServer.hooks)
1460
 
        self.assertEqual(
1461
 
            bzrlib.commands.CommandHooks(), bzrlib.commands.Command.hooks)
 
1495
        self.assertEqual(bzrlib.commands.CommandHooks(),
 
1496
            bzrlib.commands.Command.hooks)
1462
1497
 
1463
1498
    def test__gather_lsprof_in_benchmarks(self):
1464
1499
        """When _gather_lsprof_in_benchmarks is on, accumulate profile data.
1465
1500
 
1466
1501
        Each self.time() call is individually and separately profiled.
1467
1502
        """
1468
 
        self.requireFeature(features.lsprof_feature)
 
1503
        self.requireFeature(test_lsprof.LSProfFeature)
1469
1504
        # overrides the class member with an instance member so no cleanup
1470
1505
        # needed.
1471
1506
        self._gather_lsprof_in_benchmarks = True
1490
1525
        transport_server = memory.MemoryServer()
1491
1526
        transport_server.start_server()
1492
1527
        self.addCleanup(transport_server.stop_server)
1493
 
        t = transport.get_transport_from_url(transport_server.get_url())
 
1528
        t = transport.get_transport(transport_server.get_url())
1494
1529
        bzrdir.BzrDir.create(t.base)
1495
1530
        self.assertRaises(errors.BzrError,
1496
1531
            bzrdir.BzrDir.open_from_transport, t)
1501
1536
 
1502
1537
    def test_requireFeature_available(self):
1503
1538
        """self.requireFeature(available) is a no-op."""
1504
 
        class Available(features.Feature):
 
1539
        class Available(tests.Feature):
1505
1540
            def _probe(self):return True
1506
1541
        feature = Available()
1507
1542
        self.requireFeature(feature)
1508
1543
 
1509
1544
    def test_requireFeature_unavailable(self):
1510
1545
        """self.requireFeature(unavailable) raises UnavailableFeature."""
1511
 
        class Unavailable(features.Feature):
 
1546
        class Unavailable(tests.Feature):
1512
1547
            def _probe(self):return False
1513
1548
        feature = Unavailable()
1514
1549
        self.assertRaises(tests.UnavailableFeature,
1673
1708
        test.run(unittest.TestResult())
1674
1709
        self.assertEqual('original', obj.test_attr)
1675
1710
 
1676
 
    def test_recordCalls(self):
1677
 
        from bzrlib.tests import test_selftest
1678
 
        calls = self.recordCalls(
1679
 
            test_selftest, '_add_numbers')
1680
 
        self.assertEqual(test_selftest._add_numbers(2, 10),
1681
 
            12)
1682
 
        self.assertEquals(calls, [((2, 10), {})])
1683
 
 
1684
 
 
1685
 
def _add_numbers(a, b):
1686
 
    return a + b
1687
 
 
1688
 
 
1689
 
class _MissingFeature(features.Feature):
 
1711
 
 
1712
class _MissingFeature(tests.Feature):
1690
1713
    def _probe(self):
1691
1714
        return False
1692
1715
missing_feature = _MissingFeature()
1743
1766
        result = self._run_test('test_fail')
1744
1767
        self.assertEqual(1, len(result.failures))
1745
1768
        result_content = result.failures[0][1]
1746
 
        if testtools_version < (0, 9, 12):
1747
 
            self.assertContainsRe(result_content, 'Text attachment: log')
 
1769
        self.assertContainsRe(result_content, 'Text attachment: log')
1748
1770
        self.assertContainsRe(result_content, 'this was a failing test')
1749
1771
 
1750
1772
    def test_error_has_log(self):
1751
1773
        result = self._run_test('test_error')
1752
1774
        self.assertEqual(1, len(result.errors))
1753
1775
        result_content = result.errors[0][1]
1754
 
        if testtools_version < (0, 9, 12):
1755
 
            self.assertContainsRe(result_content, 'Text attachment: log')
 
1776
        self.assertContainsRe(result_content, 'Text attachment: log')
1756
1777
        self.assertContainsRe(result_content, 'this test errored')
1757
1778
 
1758
1779
    def test_skip_has_no_log(self):
1956
1977
    def test_make_branch_and_tree_with_format(self):
1957
1978
        # we should be able to supply a format to make_branch_and_tree
1958
1979
        self.make_branch_and_tree('a', format=bzrlib.bzrdir.BzrDirMetaFormat1())
 
1980
        self.make_branch_and_tree('b', format=bzrlib.bzrdir.BzrDirFormat6())
1959
1981
        self.assertIsInstance(bzrlib.bzrdir.BzrDir.open('a')._format,
1960
1982
                              bzrlib.bzrdir.BzrDirMetaFormat1)
 
1983
        self.assertIsInstance(bzrlib.bzrdir.BzrDir.open('b')._format,
 
1984
                              bzrlib.bzrdir.BzrDirFormat6)
1961
1985
 
1962
1986
    def test_make_branch_and_memory_tree(self):
1963
1987
        # we should be able to get a new branch and a mutable tree from
2040
2064
        self.assertLength(2, output.readlines())
2041
2065
 
2042
2066
    def test_lsprof_tests(self):
2043
 
        self.requireFeature(features.lsprof_feature)
2044
 
        results = []
 
2067
        self.requireFeature(test_lsprof.LSProfFeature)
 
2068
        calls = []
2045
2069
        class Test(object):
2046
2070
            def __call__(test, result):
2047
2071
                test.run(result)
2048
2072
            def run(test, result):
2049
 
                results.append(result)
 
2073
                self.assertIsInstance(result, ExtendedToOriginalDecorator)
 
2074
                calls.append("called")
2050
2075
            def countTestCases(self):
2051
2076
                return 1
2052
2077
        self.run_selftest(test_suite_factory=Test, lsprof_tests=True)
2053
 
        self.assertLength(1, results)
2054
 
        self.assertIsInstance(results.pop(), ExtendedToOriginalDecorator)
 
2078
        self.assertLength(1, calls)
2055
2079
 
2056
2080
    def test_random(self):
2057
2081
        # test randomising by listing a number of tests.
2199
2223
        content, result = self.run_subunit_stream('test_unexpected_success')
2200
2224
        self.assertContainsRe(content, '(?m)^log$')
2201
2225
        self.assertContainsRe(content, 'test with unexpected success')
2202
 
        # GZ 2011-05-18: Old versions of subunit treat unexpected success as a
2203
 
        #                success, if a min version check is added remove this
2204
 
        from subunit import TestProtocolClient as _Client
2205
 
        if _Client.addUnexpectedSuccess.im_func is _Client.addSuccess.im_func:
2206
 
            self.expectFailure('subunit treats "unexpectedSuccess"'
2207
 
                               ' as a plain success',
2208
 
                self.assertEqual, 1, len(result.unexpectedSuccesses))
 
2226
        self.expectFailure('subunit treats "unexpectedSuccess"'
 
2227
                           ' as a plain success',
 
2228
            self.assertEqual, 1, len(result.unexpectedSuccesses))
2209
2229
        self.assertEqual(1, len(result.unexpectedSuccesses))
2210
2230
        test = result.unexpectedSuccesses[0]
2211
2231
        # RemotedTestCase doesn't preserve the "details"
2346
2366
        # stdout and stderr of the invoked run_bzr
2347
2367
        current_factory = bzrlib.ui.ui_factory
2348
2368
        self.run_bzr(['foo'])
2349
 
        self.assertFalse(current_factory is self.factory)
 
2369
        self.failIf(current_factory is self.factory)
2350
2370
        self.assertNotEqual(sys.stdout, self.factory.stdout)
2351
2371
        self.assertNotEqual(sys.stderr, self.factory.stderr)
2352
2372
        self.assertEqual('foo\n', self.factory.stdout.getvalue())
2509
2529
 
2510
2530
 
2511
2531
class TestStartBzrSubProcess(tests.TestCase):
2512
 
    """Stub test start_bzr_subprocess."""
2513
2532
 
2514
 
    def _subprocess_log_cleanup(self):
2515
 
        """Inhibits the base version as we don't produce a log file."""
 
2533
    def check_popen_state(self):
 
2534
        """Replace to make assertions when popen is called."""
2516
2535
 
2517
2536
    def _popen(self, *args, **kwargs):
2518
 
        """Override the base version to record the command that is run.
2519
 
 
2520
 
        From there we can ensure it is correct without spawning a real process.
2521
 
        """
 
2537
        """Record the command that is run, so that we can ensure it is correct"""
2522
2538
        self.check_popen_state()
2523
2539
        self._popen_args = args
2524
2540
        self._popen_kwargs = kwargs
2525
2541
        raise _DontSpawnProcess()
2526
2542
 
2527
 
    def check_popen_state(self):
2528
 
        """Replace to make assertions when popen is called."""
2529
 
 
2530
2543
    def test_run_bzr_subprocess_no_plugins(self):
2531
2544
        self.assertRaises(_DontSpawnProcess, self.start_bzr_subprocess, [])
2532
2545
        command = self._popen_args[0]
2536
2549
 
2537
2550
    def test_allow_plugins(self):
2538
2551
        self.assertRaises(_DontSpawnProcess, self.start_bzr_subprocess, [],
2539
 
                          allow_plugins=True)
 
2552
            allow_plugins=True)
2540
2553
        command = self._popen_args[0]
2541
2554
        self.assertEqual([], command[2:])
2542
2555
 
2543
2556
    def test_set_env(self):
2544
 
        self.assertFalse('EXISTANT_ENV_VAR' in os.environ)
 
2557
        self.failIf('EXISTANT_ENV_VAR' in os.environ)
2545
2558
        # set in the child
2546
2559
        def check_environment():
2547
2560
            self.assertEqual('set variable', os.environ['EXISTANT_ENV_VAR'])
2548
2561
        self.check_popen_state = check_environment
2549
2562
        self.assertRaises(_DontSpawnProcess, self.start_bzr_subprocess, [],
2550
 
                          env_changes={'EXISTANT_ENV_VAR':'set variable'})
 
2563
            env_changes={'EXISTANT_ENV_VAR':'set variable'})
2551
2564
        # not set in theparent
2552
2565
        self.assertFalse('EXISTANT_ENV_VAR' in os.environ)
2553
2566
 
2554
2567
    def test_run_bzr_subprocess_env_del(self):
2555
2568
        """run_bzr_subprocess can remove environment variables too."""
2556
 
        self.assertFalse('EXISTANT_ENV_VAR' in os.environ)
 
2569
        self.failIf('EXISTANT_ENV_VAR' in os.environ)
2557
2570
        def check_environment():
2558
2571
            self.assertFalse('EXISTANT_ENV_VAR' in os.environ)
2559
2572
        os.environ['EXISTANT_ENV_VAR'] = 'set variable'
2560
2573
        self.check_popen_state = check_environment
2561
2574
        self.assertRaises(_DontSpawnProcess, self.start_bzr_subprocess, [],
2562
 
                          env_changes={'EXISTANT_ENV_VAR':None})
 
2575
            env_changes={'EXISTANT_ENV_VAR':None})
2563
2576
        # Still set in parent
2564
2577
        self.assertEqual('set variable', os.environ['EXISTANT_ENV_VAR'])
2565
2578
        del os.environ['EXISTANT_ENV_VAR']
2566
2579
 
2567
2580
    def test_env_del_missing(self):
2568
 
        self.assertFalse('NON_EXISTANT_ENV_VAR' in os.environ)
 
2581
        self.failIf('NON_EXISTANT_ENV_VAR' in os.environ)
2569
2582
        def check_environment():
2570
2583
            self.assertFalse('NON_EXISTANT_ENV_VAR' in os.environ)
2571
2584
        self.check_popen_state = check_environment
2572
2585
        self.assertRaises(_DontSpawnProcess, self.start_bzr_subprocess, [],
2573
 
                          env_changes={'NON_EXISTANT_ENV_VAR':None})
 
2586
            env_changes={'NON_EXISTANT_ENV_VAR':None})
2574
2587
 
2575
2588
    def test_working_dir(self):
2576
2589
        """Test that we can specify the working dir for the child"""
2579
2592
        chdirs = []
2580
2593
        def chdir(path):
2581
2594
            chdirs.append(path)
2582
 
        self.overrideAttr(os, 'chdir', chdir)
2583
 
        def getcwd():
2584
 
            return 'current'
2585
 
        self.overrideAttr(osutils, 'getcwd', getcwd)
2586
 
        self.assertRaises(_DontSpawnProcess, self.start_bzr_subprocess, [],
2587
 
                          working_dir='foo')
 
2595
        os.chdir = chdir
 
2596
        try:
 
2597
            def getcwd():
 
2598
                return 'current'
 
2599
            osutils.getcwd = getcwd
 
2600
            try:
 
2601
                self.assertRaises(_DontSpawnProcess, self.start_bzr_subprocess, [],
 
2602
                    working_dir='foo')
 
2603
            finally:
 
2604
                osutils.getcwd = orig_getcwd
 
2605
        finally:
 
2606
            os.chdir = orig_chdir
2588
2607
        self.assertEqual(['foo', 'current'], chdirs)
2589
2608
 
2590
2609
    def test_get_bzr_path_with_cwd_bzrlib(self):
2610
2629
        self.assertEqual('bzr: interrupted\n', result[1])
2611
2630
 
2612
2631
 
 
2632
class TestFeature(tests.TestCase):
 
2633
 
 
2634
    def test_caching(self):
 
2635
        """Feature._probe is called by the feature at most once."""
 
2636
        class InstrumentedFeature(tests.Feature):
 
2637
            def __init__(self):
 
2638
                super(InstrumentedFeature, self).__init__()
 
2639
                self.calls = []
 
2640
            def _probe(self):
 
2641
                self.calls.append('_probe')
 
2642
                return False
 
2643
        feature = InstrumentedFeature()
 
2644
        feature.available()
 
2645
        self.assertEqual(['_probe'], feature.calls)
 
2646
        feature.available()
 
2647
        self.assertEqual(['_probe'], feature.calls)
 
2648
 
 
2649
    def test_named_str(self):
 
2650
        """Feature.__str__ should thunk to feature_name()."""
 
2651
        class NamedFeature(tests.Feature):
 
2652
            def feature_name(self):
 
2653
                return 'symlinks'
 
2654
        feature = NamedFeature()
 
2655
        self.assertEqual('symlinks', str(feature))
 
2656
 
 
2657
    def test_default_str(self):
 
2658
        """Feature.__str__ should default to __class__.__name__."""
 
2659
        class NamedFeature(tests.Feature):
 
2660
            pass
 
2661
        feature = NamedFeature()
 
2662
        self.assertEqual('NamedFeature', str(feature))
 
2663
 
 
2664
 
 
2665
class TestUnavailableFeature(tests.TestCase):
 
2666
 
 
2667
    def test_access_feature(self):
 
2668
        feature = tests.Feature()
 
2669
        exception = tests.UnavailableFeature(feature)
 
2670
        self.assertIs(feature, exception.args[0])
 
2671
 
 
2672
 
 
2673
simple_thunk_feature = tests._CompatabilityThunkFeature(
 
2674
    deprecated_in((2, 1, 0)),
 
2675
    'bzrlib.tests.test_selftest',
 
2676
    'simple_thunk_feature','UnicodeFilename',
 
2677
    replacement_module='bzrlib.tests'
 
2678
    )
 
2679
 
 
2680
class Test_CompatibilityFeature(tests.TestCase):
 
2681
 
 
2682
    def test_does_thunk(self):
 
2683
        res = self.callDeprecated(
 
2684
            ['bzrlib.tests.test_selftest.simple_thunk_feature was deprecated'
 
2685
             ' in version 2.1.0. Use bzrlib.tests.UnicodeFilename instead.'],
 
2686
            simple_thunk_feature.available)
 
2687
        self.assertEqual(tests.UnicodeFilename.available(), res)
 
2688
 
 
2689
 
 
2690
class TestModuleAvailableFeature(tests.TestCase):
 
2691
 
 
2692
    def test_available_module(self):
 
2693
        feature = tests.ModuleAvailableFeature('bzrlib.tests')
 
2694
        self.assertEqual('bzrlib.tests', feature.module_name)
 
2695
        self.assertEqual('bzrlib.tests', str(feature))
 
2696
        self.assertTrue(feature.available())
 
2697
        self.assertIs(tests, feature.module)
 
2698
 
 
2699
    def test_unavailable_module(self):
 
2700
        feature = tests.ModuleAvailableFeature('bzrlib.no_such_module_exists')
 
2701
        self.assertEqual('bzrlib.no_such_module_exists', str(feature))
 
2702
        self.assertFalse(feature.available())
 
2703
        self.assertIs(None, feature.module)
 
2704
 
 
2705
 
2613
2706
class TestSelftestFiltering(tests.TestCase):
2614
2707
 
2615
2708
    def setUp(self):
2766
2859
        self.assertEqual(remaining_names, _test_ids(split_suite[1]))
2767
2860
 
2768
2861
 
2769
 
class TestCheckTreeShape(tests.TestCaseWithTransport):
 
2862
class TestCheckInventoryShape(tests.TestCaseWithTransport):
2770
2863
 
2771
 
    def test_check_tree_shape(self):
 
2864
    def test_check_inventory_shape(self):
2772
2865
        files = ['a', 'b/', 'b/c']
2773
2866
        tree = self.make_branch_and_tree('.')
2774
2867
        self.build_tree(files)
2775
2868
        tree.add(files)
2776
2869
        tree.lock_read()
2777
2870
        try:
2778
 
            self.check_tree_shape(tree, files)
 
2871
            self.check_inventory_shape(tree.inventory, files)
2779
2872
        finally:
2780
2873
            tree.unlock()
2781
2874
 
3317
3410
class TestEnvironHandling(tests.TestCase):
3318
3411
 
3319
3412
    def test_overrideEnv_None_called_twice_doesnt_leak(self):
3320
 
        self.assertFalse('MYVAR' in os.environ)
 
3413
        self.failIf('MYVAR' in os.environ)
3321
3414
        self.overrideEnv('MYVAR', '42')
3322
3415
        # We use an embedded test to make sure we fix the _captureVar bug
3323
3416
        class Test(tests.TestCase):
3453
3546
        self.assertDocTestStringFails(doctest.DocTestSuite, test)
3454
3547
        # tests.DocTestSuite sees None
3455
3548
        self.assertDocTestStringSucceds(tests.IsolatedDocTestSuite, test)
3456
 
 
3457
 
 
3458
 
class TestSelftestExcludePatterns(tests.TestCase):
3459
 
 
3460
 
    def setUp(self):
3461
 
        super(TestSelftestExcludePatterns, self).setUp()
3462
 
        self.overrideAttr(tests, 'test_suite', self.suite_factory)
3463
 
 
3464
 
    def suite_factory(self, keep_only=None, starting_with=None):
3465
 
        """A test suite factory with only a few tests."""
3466
 
        class Test(tests.TestCase):
3467
 
            def id(self):
3468
 
                # We don't need the full class path
3469
 
                return self._testMethodName
3470
 
            def a(self):
3471
 
                pass
3472
 
            def b(self):
3473
 
                pass
3474
 
            def c(self):
3475
 
                pass
3476
 
        return TestUtil.TestSuite([Test("a"), Test("b"), Test("c")])
3477
 
 
3478
 
    def assertTestList(self, expected, *selftest_args):
3479
 
        # We rely on setUp installing the right test suite factory so we can
3480
 
        # test at the command level without loading the whole test suite
3481
 
        out, err = self.run_bzr(('selftest', '--list') + selftest_args)
3482
 
        actual = out.splitlines()
3483
 
        self.assertEquals(expected, actual)
3484
 
 
3485
 
    def test_full_list(self):
3486
 
        self.assertTestList(['a', 'b', 'c'])
3487
 
 
3488
 
    def test_single_exclude(self):
3489
 
        self.assertTestList(['b', 'c'], '-x', 'a')
3490
 
 
3491
 
    def test_mutiple_excludes(self):
3492
 
        self.assertTestList(['c'], '-x', 'a', '-x', 'b')
3493
 
 
3494
 
 
3495
 
class TestCounterHooks(tests.TestCase, SelfTestHelper):
3496
 
 
3497
 
    _test_needs_features = [features.subunit]
3498
 
 
3499
 
    def setUp(self):
3500
 
        super(TestCounterHooks, self).setUp()
3501
 
        class Test(tests.TestCase):
3502
 
 
3503
 
            def setUp(self):
3504
 
                super(Test, self).setUp()
3505
 
                self.hooks = hooks.Hooks()
3506
 
                self.hooks.add_hook('myhook', 'Foo bar blah', (2,4))
3507
 
                self.install_counter_hook(self.hooks, 'myhook')
3508
 
 
3509
 
            def no_hook(self):
3510
 
                pass
3511
 
 
3512
 
            def run_hook_once(self):
3513
 
                for hook in self.hooks['myhook']:
3514
 
                    hook(self)
3515
 
 
3516
 
        self.test_class = Test
3517
 
 
3518
 
    def assertHookCalls(self, expected_calls, test_name):
3519
 
        test = self.test_class(test_name)
3520
 
        result = unittest.TestResult()
3521
 
        test.run(result)
3522
 
        self.assertTrue(hasattr(test, '_counters'))
3523
 
        self.assertTrue(test._counters.has_key('myhook'))
3524
 
        self.assertEquals(expected_calls, test._counters['myhook'])
3525
 
 
3526
 
    def test_no_hook(self):
3527
 
        self.assertHookCalls(0, 'no_hook')
3528
 
 
3529
 
    def test_run_hook_once(self):
3530
 
        tt = features.testtools
3531
 
        if tt.module.__version__ < (0, 9, 8):
3532
 
            raise tests.TestSkipped('testtools-0.9.8 required for addDetail')
3533
 
        self.assertHookCalls(1, 'run_hook_once')