~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_selftest.py

Merge up through 2.2.0.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005, 2006, 2007, 2008, 2009 Canonical Ltd
 
1
# Copyright (C) 2005-2010 Canonical Ltd
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
17
17
"""Tests for the test framework."""
18
18
 
19
19
from cStringIO import StringIO
 
20
from doctest import ELLIPSIS
20
21
import os
21
22
import signal
22
23
import sys
24
25
import unittest
25
26
import warnings
26
27
 
 
28
from testtools import MultiTestResult
 
29
from testtools.content_type import ContentType
 
30
from testtools.matchers import (
 
31
    DocTestMatches,
 
32
    Equals,
 
33
    )
 
34
import testtools.tests.helpers
 
35
 
27
36
import bzrlib
28
37
from bzrlib import (
29
38
    branchbuilder,
38
47
    repository,
39
48
    symbol_versioning,
40
49
    tests,
 
50
    transport,
41
51
    workingtree,
42
52
    )
43
53
from bzrlib.repofmt import (
51
61
    deprecated_method,
52
62
    )
53
63
from bzrlib.tests import (
54
 
    SubUnitFeature,
 
64
    features,
55
65
    test_lsprof,
 
66
    test_server,
56
67
    test_sftp_transport,
57
68
    TestUtil,
58
69
    )
59
70
from bzrlib.trace import note
60
 
from bzrlib.transport.memory import MemoryServer, MemoryTransport
 
71
from bzrlib.transport import memory
61
72
from bzrlib.version import _get_bzr_source_tree
62
73
 
63
74
 
77
88
                          TestUtil._load_module_by_name,
78
89
                          'bzrlib.no-name-yet')
79
90
 
 
91
 
80
92
class MetaTestLog(tests.TestCase):
81
93
 
82
94
    def test_logging(self):
83
95
        """Test logs are captured when a test fails."""
84
96
        self.log('a test message')
85
 
        self._log_file.flush()
86
 
        self.assertContainsRe(self._get_log(keep_log_file=True),
87
 
                              'a test message\n')
 
97
        details = self.getDetails()
 
98
        log = details['log']
 
99
        self.assertThat(log.content_type, Equals(ContentType(
 
100
            "text", "plain", {"charset": "utf8"})))
 
101
        self.assertThat(u"".join(log.iter_text()), Equals(self.get_log()))
 
102
        self.assertThat(self.get_log(),
 
103
            DocTestMatches(u"...a test message\n", ELLIPSIS))
88
104
 
89
105
 
90
106
class TestUnicodeFilename(tests.TestCase):
489
505
        self.assertEqualStat(real, fake)
490
506
 
491
507
    def test_assertEqualStat_notequal(self):
492
 
        self.build_tree(["foo", "bar"])
 
508
        self.build_tree(["foo", "longname"])
493
509
        self.assertRaises(AssertionError, self.assertEqualStat,
494
 
            os.lstat("foo"), os.lstat("bar"))
 
510
            os.lstat("foo"), os.lstat("longname"))
495
511
 
496
512
 
497
513
class TestTestCaseWithMemoryTransport(tests.TestCaseWithMemoryTransport):
515
531
        cwd = osutils.getcwd()
516
532
        self.assertIsSameRealPath(self.test_dir, cwd)
517
533
 
 
534
    def test_BZR_HOME_and_HOME_are_bytestrings(self):
 
535
        """The $BZR_HOME and $HOME environment variables should not be unicode.
 
536
 
 
537
        See https://bugs.launchpad.net/bzr/+bug/464174
 
538
        """
 
539
        self.assertIsInstance(os.environ['BZR_HOME'], str)
 
540
        self.assertIsInstance(os.environ['HOME'], str)
 
541
 
518
542
    def test_make_branch_and_memory_tree(self):
519
543
        """In TestCaseWithMemoryTransport we should not make the branch on disk.
520
544
 
576
600
                         self.get_transport().get_bytes(
577
601
                            'dir/.bzr/repository/format'))
578
602
 
579
 
    def test_safety_net(self):
580
 
        """No test should modify the safety .bzr directory.
581
 
 
582
 
        We just test that the _check_safety_net private method raises
583
 
        AssertionError, it's easier than building a test suite with the same
584
 
        test.
585
 
        """
586
 
        # Oops, a commit in the current directory (i.e. without local .bzr
587
 
        # directory) will crawl up the hierarchy to find a .bzr directory.
588
 
        self.run_bzr(['commit', '-mfoo', '--unchanged'])
589
 
        # But we have a safety net in place.
590
 
        self.assertRaises(AssertionError, self._check_safety_net)
591
 
 
592
603
    def test_dangling_locks_cause_failures(self):
593
604
        class TestDanglingLock(tests.TestCaseWithMemoryTransport):
594
605
            def test_function(self):
598
609
                l.attempt_lock()
599
610
        test = TestDanglingLock('test_function')
600
611
        result = test.run()
 
612
        total_failures = result.errors + result.failures
601
613
        if self._lock_check_thorough:
602
 
            self.assertEqual(1, len(result.errors))
 
614
            self.assertLength(1, total_failures)
603
615
        else:
604
616
            # When _lock_check_thorough is disabled, then we don't trigger a
605
617
            # failure
606
 
            self.assertEqual(0, len(result.errors))
 
618
            self.assertLength(0, total_failures)
607
619
 
608
620
 
609
621
class TestTestCaseWithTransport(tests.TestCaseWithTransport):
610
622
    """Tests for the convenience functions TestCaseWithTransport introduces."""
611
623
 
612
624
    def test_get_readonly_url_none(self):
613
 
        from bzrlib.transport import get_transport
614
 
        from bzrlib.transport.memory import MemoryServer
615
625
        from bzrlib.transport.readonly import ReadonlyTransportDecorator
616
 
        self.vfs_transport_factory = MemoryServer
 
626
        self.vfs_transport_factory = memory.MemoryServer
617
627
        self.transport_readonly_server = None
618
628
        # calling get_readonly_transport() constructs a decorator on the url
619
629
        # for the server
620
630
        url = self.get_readonly_url()
621
631
        url2 = self.get_readonly_url('foo/bar')
622
 
        t = get_transport(url)
623
 
        t2 = get_transport(url2)
 
632
        t = transport.get_transport(url)
 
633
        t2 = transport.get_transport(url2)
624
634
        self.failUnless(isinstance(t, ReadonlyTransportDecorator))
625
635
        self.failUnless(isinstance(t2, ReadonlyTransportDecorator))
626
636
        self.assertEqual(t2.base[:-1], t.abspath('foo/bar'))
627
637
 
628
638
    def test_get_readonly_url_http(self):
629
639
        from bzrlib.tests.http_server import HttpServer
630
 
        from bzrlib.transport import get_transport
631
 
        from bzrlib.transport.local import LocalURLServer
632
640
        from bzrlib.transport.http import HttpTransportBase
633
 
        self.transport_server = LocalURLServer
 
641
        self.transport_server = test_server.LocalURLServer
634
642
        self.transport_readonly_server = HttpServer
635
643
        # calling get_readonly_transport() gives us a HTTP server instance.
636
644
        url = self.get_readonly_url()
637
645
        url2 = self.get_readonly_url('foo/bar')
638
646
        # the transport returned may be any HttpTransportBase subclass
639
 
        t = get_transport(url)
640
 
        t2 = get_transport(url2)
 
647
        t = transport.get_transport(url)
 
648
        t2 = transport.get_transport(url2)
641
649
        self.failUnless(isinstance(t, HttpTransportBase))
642
650
        self.failUnless(isinstance(t2, HttpTransportBase))
643
651
        self.assertEqual(t2.base[:-1], t.abspath('foo/bar'))
667
675
 
668
676
    def setUp(self):
669
677
        super(TestTestCaseTransports, self).setUp()
670
 
        self.vfs_transport_factory = MemoryServer
 
678
        self.vfs_transport_factory = memory.MemoryServer
671
679
 
672
680
    def test_make_bzrdir_preserves_transport(self):
673
681
        t = self.get_transport()
674
682
        result_bzrdir = self.make_bzrdir('subdir')
675
683
        self.assertIsInstance(result_bzrdir.transport,
676
 
                              MemoryTransport)
 
684
                              memory.MemoryTransport)
677
685
        # should not be on disk, should only be in memory
678
686
        self.failIfExists('subdir')
679
687
 
681
689
class TestChrootedTest(tests.ChrootedTestCase):
682
690
 
683
691
    def test_root_is_root(self):
684
 
        from bzrlib.transport import get_transport
685
 
        t = get_transport(self.get_readonly_url())
 
692
        t = transport.get_transport(self.get_readonly_url())
686
693
        url = t.base
687
694
        self.assertEqual(url, t.clone('..').base)
688
695
 
689
696
 
 
697
class TestProfileResult(tests.TestCase):
 
698
 
 
699
    def test_profiles_tests(self):
 
700
        self.requireFeature(test_lsprof.LSProfFeature)
 
701
        terminal = testtools.tests.helpers.ExtendedTestResult()
 
702
        result = tests.ProfileResult(terminal)
 
703
        class Sample(tests.TestCase):
 
704
            def a(self):
 
705
                self.sample_function()
 
706
            def sample_function(self):
 
707
                pass
 
708
        test = Sample("a")
 
709
        test.run(result)
 
710
        case = terminal._events[0][1]
 
711
        self.assertLength(1, case._benchcalls)
 
712
        # We must be able to unpack it as the test reporting code wants
 
713
        (_, _, _), stats = case._benchcalls[0]
 
714
        self.assertTrue(callable(stats.pprint))
 
715
 
 
716
 
690
717
class TestTestResult(tests.TestCase):
691
718
 
692
719
    def check_timing(self, test_case, expected_re):
694
721
                descriptions=0,
695
722
                verbosity=1,
696
723
                )
697
 
        test_case.run(result)
698
 
        timed_string = result._testTimeString(test_case)
 
724
        capture = testtools.tests.helpers.ExtendedTestResult()
 
725
        test_case.run(MultiTestResult(result, capture))
 
726
        run_case = capture._events[0][1]
 
727
        timed_string = result._testTimeString(run_case)
699
728
        self.assertContainsRe(timed_string, expected_re)
700
729
 
701
730
    def test_test_reporting(self):
719
748
        self.check_timing(ShortDelayTestCase('test_short_delay'),
720
749
                          r"^ +[0-9]+ms$")
721
750
 
 
751
    def _patch_get_bzr_source_tree(self):
 
752
        # Reading from the actual source tree breaks isolation, but we don't
 
753
        # want to assume that thats *all* that would happen.
 
754
        self.overrideAttr(bzrlib.version, '_get_bzr_source_tree', lambda: None)
 
755
 
722
756
    def test_assigned_benchmark_file_stores_date(self):
 
757
        self._patch_get_bzr_source_tree()
723
758
        output = StringIO()
724
759
        result = bzrlib.tests.TextTestResult(self._log_file,
725
760
                                        descriptions=0,
733
768
        self.assertContainsRe(output_string, "--date [0-9.]+")
734
769
 
735
770
    def test_benchhistory_records_test_times(self):
 
771
        self._patch_get_bzr_source_tree()
736
772
        result_stream = StringIO()
737
773
        result = bzrlib.tests.TextTestResult(
738
774
            self._log_file,
800
836
    def test_known_failure(self):
801
837
        """A KnownFailure being raised should trigger several result actions."""
802
838
        class InstrumentedTestResult(tests.ExtendedTestResult):
803
 
            def done(self): pass
 
839
            def stopTestRun(self): pass
804
840
            def startTests(self): pass
805
841
            def report_test_start(self, test): pass
806
 
            def report_known_failure(self, test, err):
807
 
                self._call = test, err
 
842
            def report_known_failure(self, test, err=None, details=None):
 
843
                self._call = test, 'known failure'
808
844
        result = InstrumentedTestResult(None, None, None, None)
809
 
        def test_function():
810
 
            raise tests.KnownFailure('failed!')
811
 
        test = unittest.FunctionTestCase(test_function)
 
845
        class Test(tests.TestCase):
 
846
            def test_function(self):
 
847
                raise tests.KnownFailure('failed!')
 
848
        test = Test("test_function")
812
849
        test.run(result)
813
850
        # it should invoke 'report_known_failure'.
814
851
        self.assertEqual(2, len(result._call))
815
 
        self.assertEqual(test, result._call[0])
816
 
        self.assertEqual(tests.KnownFailure, result._call[1][0])
817
 
        self.assertIsInstance(result._call[1][1], tests.KnownFailure)
 
852
        self.assertEqual(test.id(), result._call[0].id())
 
853
        self.assertEqual('known failure', result._call[1])
818
854
        # we dont introspec the traceback, if the rest is ok, it would be
819
855
        # exceptional for it not to be.
820
856
        # it should update the known_failure_count on the object.
854
890
    def test_add_not_supported(self):
855
891
        """Test the behaviour of invoking addNotSupported."""
856
892
        class InstrumentedTestResult(tests.ExtendedTestResult):
857
 
            def done(self): pass
 
893
            def stopTestRun(self): pass
858
894
            def startTests(self): pass
859
895
            def report_test_start(self, test): pass
860
896
            def report_unsupported(self, test, feature):
892
928
        result.report_unsupported(test, feature)
893
929
        output = result_stream.getvalue()[prefix:]
894
930
        lines = output.splitlines()
895
 
        self.assertEqual(lines, ['NODEP        0ms',
896
 
                                 "    The feature 'Feature' is not available."])
 
931
        # We don't check for the final '0ms' since it may fail on slow hosts
 
932
        self.assertStartsWith(lines[0], 'NODEP')
 
933
        self.assertEqual(lines[1],
 
934
                         "    The feature 'Feature' is not available.")
897
935
 
898
936
    def test_unavailable_exception(self):
899
937
        """An UnavailableFeature being raised should invoke addNotSupported."""
900
938
        class InstrumentedTestResult(tests.ExtendedTestResult):
901
 
            def done(self): pass
 
939
            def stopTestRun(self): pass
902
940
            def startTests(self): pass
903
941
            def report_test_start(self, test): pass
904
942
            def addNotSupported(self, test, feature):
905
943
                self._call = test, feature
906
944
        result = InstrumentedTestResult(None, None, None, None)
907
945
        feature = tests.Feature()
908
 
        def test_function():
909
 
            raise tests.UnavailableFeature(feature)
910
 
        test = unittest.FunctionTestCase(test_function)
 
946
        class Test(tests.TestCase):
 
947
            def test_function(self):
 
948
                raise tests.UnavailableFeature(feature)
 
949
        test = Test("test_function")
911
950
        test.run(result)
912
951
        # it should invoke 'addNotSupported'.
913
952
        self.assertEqual(2, len(result._call))
914
 
        self.assertEqual(test, result._call[0])
 
953
        self.assertEqual(test.id(), result._call[0].id())
915
954
        self.assertEqual(feature, result._call[1])
916
955
        # and not count as an error
917
956
        self.assertEqual(0, result.error_count)
930
969
                                             verbosity=1)
931
970
        test = self.get_passing_test()
932
971
        err = (tests.KnownFailure, tests.KnownFailure('foo'), None)
933
 
        result._addKnownFailure(test, err)
 
972
        result.addExpectedFailure(test, err)
934
973
        self.assertFalse(result.wasStrictlySuccessful())
935
974
        self.assertEqual(None, result._extractBenchmarkTime(test))
936
975
 
981
1020
        because of our use of global state.
982
1021
        """
983
1022
        old_root = tests.TestCaseInTempDir.TEST_ROOT
 
1023
        old_leak = tests.TestCase._first_thread_leaker_id
984
1024
        try:
985
1025
            tests.TestCaseInTempDir.TEST_ROOT = None
 
1026
            tests.TestCase._first_thread_leaker_id = None
986
1027
            return testrunner.run(test)
987
1028
        finally:
988
1029
            tests.TestCaseInTempDir.TEST_ROOT = old_root
 
1030
            tests.TestCase._first_thread_leaker_id = old_leak
989
1031
 
990
1032
    def test_known_failure_failed_run(self):
991
1033
        # run a test that generates a known failure which should be printed in
992
1034
        # the final output when real failures occur.
993
 
        def known_failure_test():
994
 
            raise tests.KnownFailure('failed')
 
1035
        class Test(tests.TestCase):
 
1036
            def known_failure_test(self):
 
1037
                self.expectFailure('failed', self.assertTrue, False)
995
1038
        test = unittest.TestSuite()
996
 
        test.addTest(unittest.FunctionTestCase(known_failure_test))
 
1039
        test.addTest(Test("known_failure_test"))
997
1040
        def failing_test():
998
 
            raise AssertionError('foo')
 
1041
            self.fail('foo')
999
1042
        test.addTest(unittest.FunctionTestCase(failing_test))
1000
1043
        stream = StringIO()
1001
1044
        runner = tests.TextTestRunner(stream=stream)
1002
1045
        result = self.run_test_runner(runner, test)
1003
1046
        lines = stream.getvalue().splitlines()
1004
1047
        self.assertContainsRe(stream.getvalue(),
1005
 
            '(?sm)^testing.*$'
 
1048
            '(?sm)^bzr selftest.*$'
1006
1049
            '.*'
1007
1050
            '^======================================================================\n'
1008
 
            '^FAIL: unittest.FunctionTestCase \\(failing_test\\)\n'
 
1051
            '^FAIL: failing_test\n'
1009
1052
            '^----------------------------------------------------------------------\n'
1010
1053
            'Traceback \\(most recent call last\\):\n'
1011
1054
            '  .*' # File .*, line .*, in failing_test' - but maybe not from .pyc
1012
 
            '    raise AssertionError\\(\'foo\'\\)\n'
 
1055
            '    self.fail\\(\'foo\'\\)\n'
1013
1056
            '.*'
1014
1057
            '^----------------------------------------------------------------------\n'
1015
1058
            '.*'
1017
1060
            )
1018
1061
 
1019
1062
    def test_known_failure_ok_run(self):
1020
 
        # run a test that generates a known failure which should be printed in the final output.
1021
 
        def known_failure_test():
1022
 
            raise tests.KnownFailure('failed')
1023
 
        test = unittest.FunctionTestCase(known_failure_test)
 
1063
        # run a test that generates a known failure which should be printed in
 
1064
        # the final output.
 
1065
        class Test(tests.TestCase):
 
1066
            def known_failure_test(self):
 
1067
                self.expectFailure('failed', self.assertTrue, False)
 
1068
        test = Test("known_failure_test")
1024
1069
        stream = StringIO()
1025
1070
        runner = tests.TextTestRunner(stream=stream)
1026
1071
        result = self.run_test_runner(runner, test)
1031
1076
            '\n'
1032
1077
            'OK \\(known_failures=1\\)\n')
1033
1078
 
 
1079
    def test_result_decorator(self):
 
1080
        # decorate results
 
1081
        calls = []
 
1082
        class LoggingDecorator(tests.ForwardingResult):
 
1083
            def startTest(self, test):
 
1084
                tests.ForwardingResult.startTest(self, test)
 
1085
                calls.append('start')
 
1086
        test = unittest.FunctionTestCase(lambda:None)
 
1087
        stream = StringIO()
 
1088
        runner = tests.TextTestRunner(stream=stream,
 
1089
            result_decorators=[LoggingDecorator])
 
1090
        result = self.run_test_runner(runner, test)
 
1091
        self.assertLength(1, calls)
 
1092
 
1034
1093
    def test_skipped_test(self):
1035
1094
        # run a test that is skipped, and check the suite as a whole still
1036
1095
        # succeeds.
1089
1148
 
1090
1149
    def test_not_applicable(self):
1091
1150
        # run a test that is skipped because it's not applicable
1092
 
        def not_applicable_test():
1093
 
            raise tests.TestNotApplicable('this test never runs')
 
1151
        class Test(tests.TestCase):
 
1152
            def not_applicable_test(self):
 
1153
                raise tests.TestNotApplicable('this test never runs')
1094
1154
        out = StringIO()
1095
1155
        runner = tests.TextTestRunner(stream=out, verbosity=2)
1096
 
        test = unittest.FunctionTestCase(not_applicable_test)
 
1156
        test = Test("not_applicable_test")
1097
1157
        result = self.run_test_runner(runner, test)
1098
1158
        self._log_file.write(out.getvalue())
1099
1159
        self.assertTrue(result.wasSuccessful())
1103
1163
        self.assertContainsRe(out.getvalue(),
1104
1164
                r'(?m)^    this test never runs')
1105
1165
 
1106
 
    def test_not_applicable_demo(self):
1107
 
        # just so you can see it in the test output
1108
 
        raise tests.TestNotApplicable('this test is just a demonstation')
1109
 
 
1110
1166
    def test_unsupported_features_listed(self):
1111
1167
        """When unsupported features are encountered they are detailed."""
1112
1168
        class Feature1(tests.Feature):
1132
1188
            ],
1133
1189
            lines[-3:])
1134
1190
 
 
1191
    def _patch_get_bzr_source_tree(self):
 
1192
        # Reading from the actual source tree breaks isolation, but we don't
 
1193
        # want to assume that thats *all* that would happen.
 
1194
        self._get_source_tree_calls = []
 
1195
        def new_get():
 
1196
            self._get_source_tree_calls.append("called")
 
1197
            return None
 
1198
        self.overrideAttr(bzrlib.version, '_get_bzr_source_tree',  new_get)
 
1199
 
1135
1200
    def test_bench_history(self):
1136
 
        # tests that the running the benchmark produces a history file
1137
 
        # containing a timestamp and the revision id of the bzrlib source which
1138
 
        # was tested.
1139
 
        workingtree = _get_bzr_source_tree()
 
1201
        # tests that the running the benchmark passes bench_history into
 
1202
        # the test result object. We can tell that happens if
 
1203
        # _get_bzr_source_tree is called.
 
1204
        self._patch_get_bzr_source_tree()
1140
1205
        test = TestRunner('dummy_test')
1141
1206
        output = StringIO()
1142
1207
        runner = tests.TextTestRunner(stream=self._log_file,
1144
1209
        result = self.run_test_runner(runner, test)
1145
1210
        output_string = output.getvalue()
1146
1211
        self.assertContainsRe(output_string, "--date [0-9.]+")
1147
 
        if workingtree is not None:
1148
 
            revision_id = workingtree.get_parent_ids()[0]
1149
 
            self.assertEndsWith(output_string.rstrip(), revision_id)
1150
 
 
1151
 
    def assertLogDeleted(self, test):
1152
 
        log = test._get_log()
1153
 
        self.assertEqual("DELETED log file to reduce memory footprint", log)
1154
 
        self.assertEqual('', test._log_contents)
1155
 
        self.assertIs(None, test._log_file_name)
1156
 
 
1157
 
    def test_success_log_deleted(self):
1158
 
        """Successful tests have their log deleted"""
1159
 
 
1160
 
        class LogTester(tests.TestCase):
1161
 
 
1162
 
            def test_success(self):
1163
 
                self.log('this will be removed\n')
1164
 
 
1165
 
        sio = StringIO()
1166
 
        runner = tests.TextTestRunner(stream=sio)
1167
 
        test = LogTester('test_success')
1168
 
        result = self.run_test_runner(runner, test)
1169
 
 
1170
 
        self.assertLogDeleted(test)
1171
 
 
1172
 
    def test_skipped_log_deleted(self):
1173
 
        """Skipped tests have their log deleted"""
1174
 
 
1175
 
        class LogTester(tests.TestCase):
1176
 
 
1177
 
            def test_skipped(self):
1178
 
                self.log('this will be removed\n')
1179
 
                raise tests.TestSkipped()
1180
 
 
1181
 
        sio = StringIO()
1182
 
        runner = tests.TextTestRunner(stream=sio)
1183
 
        test = LogTester('test_skipped')
1184
 
        result = self.run_test_runner(runner, test)
1185
 
 
1186
 
        self.assertLogDeleted(test)
1187
 
 
1188
 
    def test_not_aplicable_log_deleted(self):
1189
 
        """Not applicable tests have their log deleted"""
1190
 
 
1191
 
        class LogTester(tests.TestCase):
1192
 
 
1193
 
            def test_not_applicable(self):
1194
 
                self.log('this will be removed\n')
1195
 
                raise tests.TestNotApplicable()
1196
 
 
1197
 
        sio = StringIO()
1198
 
        runner = tests.TextTestRunner(stream=sio)
1199
 
        test = LogTester('test_not_applicable')
1200
 
        result = self.run_test_runner(runner, test)
1201
 
 
1202
 
        self.assertLogDeleted(test)
1203
 
 
1204
 
    def test_known_failure_log_deleted(self):
1205
 
        """Know failure tests have their log deleted"""
1206
 
 
1207
 
        class LogTester(tests.TestCase):
1208
 
 
1209
 
            def test_known_failure(self):
1210
 
                self.log('this will be removed\n')
1211
 
                raise tests.KnownFailure()
1212
 
 
1213
 
        sio = StringIO()
1214
 
        runner = tests.TextTestRunner(stream=sio)
1215
 
        test = LogTester('test_known_failure')
1216
 
        result = self.run_test_runner(runner, test)
1217
 
 
1218
 
        self.assertLogDeleted(test)
1219
 
 
1220
 
    def test_fail_log_kept(self):
1221
 
        """Failed tests have their log kept"""
1222
 
 
1223
 
        class LogTester(tests.TestCase):
1224
 
 
1225
 
            def test_fail(self):
1226
 
                self.log('this will be kept\n')
1227
 
                self.fail('this test fails')
1228
 
 
1229
 
        sio = StringIO()
1230
 
        runner = tests.TextTestRunner(stream=sio)
1231
 
        test = LogTester('test_fail')
1232
 
        result = self.run_test_runner(runner, test)
1233
 
 
1234
 
        text = sio.getvalue()
1235
 
        self.assertContainsRe(text, 'this will be kept')
1236
 
        self.assertContainsRe(text, 'this test fails')
1237
 
 
1238
 
        log = test._get_log()
1239
 
        self.assertContainsRe(log, 'this will be kept')
1240
 
        self.assertEqual(log, test._log_contents)
1241
 
 
1242
 
    def test_error_log_kept(self):
1243
 
        """Tests with errors have their log kept"""
1244
 
 
1245
 
        class LogTester(tests.TestCase):
1246
 
 
1247
 
            def test_error(self):
1248
 
                self.log('this will be kept\n')
1249
 
                raise ValueError('random exception raised')
1250
 
 
1251
 
        sio = StringIO()
1252
 
        runner = tests.TextTestRunner(stream=sio)
1253
 
        test = LogTester('test_error')
1254
 
        result = self.run_test_runner(runner, test)
1255
 
 
1256
 
        text = sio.getvalue()
1257
 
        self.assertContainsRe(text, 'this will be kept')
1258
 
        self.assertContainsRe(text, 'random exception raised')
1259
 
 
1260
 
        log = test._get_log()
1261
 
        self.assertContainsRe(log, 'this will be kept')
1262
 
        self.assertEqual(log, test._log_contents)
 
1212
        self.assertLength(1, self._get_source_tree_calls)
 
1213
 
 
1214
    def test_startTestRun(self):
 
1215
        """run should call result.startTestRun()"""
 
1216
        calls = []
 
1217
        class LoggingDecorator(tests.ForwardingResult):
 
1218
            def startTestRun(self):
 
1219
                tests.ForwardingResult.startTestRun(self)
 
1220
                calls.append('startTestRun')
 
1221
        test = unittest.FunctionTestCase(lambda:None)
 
1222
        stream = StringIO()
 
1223
        runner = tests.TextTestRunner(stream=stream,
 
1224
            result_decorators=[LoggingDecorator])
 
1225
        result = self.run_test_runner(runner, test)
 
1226
        self.assertLength(1, calls)
 
1227
 
 
1228
    def test_stopTestRun(self):
 
1229
        """run should call result.stopTestRun()"""
 
1230
        calls = []
 
1231
        class LoggingDecorator(tests.ForwardingResult):
 
1232
            def stopTestRun(self):
 
1233
                tests.ForwardingResult.stopTestRun(self)
 
1234
                calls.append('stopTestRun')
 
1235
        test = unittest.FunctionTestCase(lambda:None)
 
1236
        stream = StringIO()
 
1237
        runner = tests.TextTestRunner(stream=stream,
 
1238
            result_decorators=[LoggingDecorator])
 
1239
        result = self.run_test_runner(runner, test)
 
1240
        self.assertLength(1, calls)
1263
1241
 
1264
1242
 
1265
1243
class SampleTestCase(tests.TestCase):
1331
1309
        self.assertEqual(flags, bzrlib.debug.debug_flags)
1332
1310
 
1333
1311
    def change_selftest_debug_flags(self, new_flags):
1334
 
        orig_selftest_flags = tests.selftest_debug_flags
1335
 
        self.addCleanup(self._restore_selftest_debug_flags, orig_selftest_flags)
1336
 
        tests.selftest_debug_flags = set(new_flags)
1337
 
 
1338
 
    def _restore_selftest_debug_flags(self, flags):
1339
 
        tests.selftest_debug_flags = flags
 
1312
        self.overrideAttr(tests, 'selftest_debug_flags', set(new_flags))
1340
1313
 
1341
1314
    def test_allow_debug_flag(self):
1342
1315
        """The -Eallow_debug flag prevents bzrlib.debug.debug_flags from being
1402
1375
        self.assertEqual(set(['original-state']), bzrlib.debug.debug_flags)
1403
1376
 
1404
1377
    def make_test_result(self):
 
1378
        """Get a test result that writes to the test log file."""
1405
1379
        return tests.TextTestResult(self._log_file, descriptions=0, verbosity=1)
1406
1380
 
1407
1381
    def inner_test(self):
1415
1389
        result = self.make_test_result()
1416
1390
        self.inner_test.run(result)
1417
1391
        note("outer finish")
 
1392
        self.addCleanup(osutils.delete_any, self._log_file_name)
1418
1393
 
1419
1394
    def test_trace_nesting(self):
1420
1395
        # this tests that each test case nests its trace facility correctly.
1480
1455
        self.assertEqual((time.sleep, (0.003,), {}), self._benchcalls[1][0])
1481
1456
        self.assertIsInstance(self._benchcalls[0][1], bzrlib.lsprof.Stats)
1482
1457
        self.assertIsInstance(self._benchcalls[1][1], bzrlib.lsprof.Stats)
 
1458
        del self._benchcalls[:]
1483
1459
 
1484
1460
    def test_knownFailure(self):
1485
1461
        """Self.knownFailure() should raise a KnownFailure exception."""
1486
1462
        self.assertRaises(tests.KnownFailure, self.knownFailure, "A Failure")
1487
1463
 
 
1464
    def test_open_bzrdir_safe_roots(self):
 
1465
        # even a memory transport should fail to open when its url isn't 
 
1466
        # permitted.
 
1467
        # Manually set one up (TestCase doesn't and shouldn't provide magic
 
1468
        # machinery)
 
1469
        transport_server = memory.MemoryServer()
 
1470
        transport_server.start_server()
 
1471
        self.addCleanup(transport_server.stop_server)
 
1472
        t = transport.get_transport(transport_server.get_url())
 
1473
        bzrdir.BzrDir.create(t.base)
 
1474
        self.assertRaises(errors.BzrError,
 
1475
            bzrdir.BzrDir.open_from_transport, t)
 
1476
        # But if we declare this as safe, we can open the bzrdir.
 
1477
        self.permit_url(t.base)
 
1478
        self._bzr_selftest_roots.append(t.base)
 
1479
        bzrdir.BzrDir.open_from_transport(t)
 
1480
 
1488
1481
    def test_requireFeature_available(self):
1489
1482
        """self.requireFeature(available) is a no-op."""
1490
1483
        class Available(tests.Feature):
1534
1527
        """Test disabled tests behaviour with support aware results."""
1535
1528
        test = SampleTestCase('_test_pass')
1536
1529
        class DisabledFeature(object):
 
1530
            def __eq__(self, other):
 
1531
                return isinstance(other, DisabledFeature)
1537
1532
            def available(self):
1538
1533
                return False
1539
1534
        the_feature = DisabledFeature()
1550
1545
                self.calls.append(('addNotSupported', test, feature))
1551
1546
        result = InstrumentedTestResult()
1552
1547
        test.run(result)
 
1548
        case = result.calls[0][1]
1553
1549
        self.assertEqual([
1554
 
            ('startTest', test),
1555
 
            ('addNotSupported', test, the_feature),
1556
 
            ('stopTest', test),
 
1550
            ('startTest', case),
 
1551
            ('addNotSupported', case, the_feature),
 
1552
            ('stopTest', case),
1557
1553
            ],
1558
1554
            result.calls)
1559
1555
 
 
1556
    def test_start_server_registers_url(self):
 
1557
        transport_server = memory.MemoryServer()
 
1558
        # A little strict, but unlikely to be changed soon.
 
1559
        self.assertEqual([], self._bzr_selftest_roots)
 
1560
        self.start_server(transport_server)
 
1561
        self.assertSubset([transport_server.get_url()],
 
1562
            self._bzr_selftest_roots)
 
1563
 
1560
1564
    def test_assert_list_raises_on_generator(self):
1561
1565
        def generator_which_will_raise():
1562
1566
            # This will not raise until after the first yield
1612
1616
        self.assertRaises(AssertionError,
1613
1617
            self.assertListRaises, _TestException, success_generator)
1614
1618
 
 
1619
    def test_overrideAttr_without_value(self):
 
1620
        self.test_attr = 'original' # Define a test attribute
 
1621
        obj = self # Make 'obj' visible to the embedded test
 
1622
        class Test(tests.TestCase):
 
1623
 
 
1624
            def setUp(self):
 
1625
                tests.TestCase.setUp(self)
 
1626
                self.orig = self.overrideAttr(obj, 'test_attr')
 
1627
 
 
1628
            def test_value(self):
 
1629
                self.assertEqual('original', self.orig)
 
1630
                self.assertEqual('original', obj.test_attr)
 
1631
                obj.test_attr = 'modified'
 
1632
                self.assertEqual('modified', obj.test_attr)
 
1633
 
 
1634
        test = Test('test_value')
 
1635
        test.run(unittest.TestResult())
 
1636
        self.assertEqual('original', obj.test_attr)
 
1637
 
 
1638
    def test_overrideAttr_with_value(self):
 
1639
        self.test_attr = 'original' # Define a test attribute
 
1640
        obj = self # Make 'obj' visible to the embedded test
 
1641
        class Test(tests.TestCase):
 
1642
 
 
1643
            def setUp(self):
 
1644
                tests.TestCase.setUp(self)
 
1645
                self.orig = self.overrideAttr(obj, 'test_attr', new='modified')
 
1646
 
 
1647
            def test_value(self):
 
1648
                self.assertEqual('original', self.orig)
 
1649
                self.assertEqual('modified', obj.test_attr)
 
1650
 
 
1651
        test = Test('test_value')
 
1652
        test.run(unittest.TestResult())
 
1653
        self.assertEqual('original', obj.test_attr)
 
1654
 
1615
1655
 
1616
1656
# NB: Don't delete this; it's not actually from 0.11!
1617
1657
@deprecated_function(deprecated_in((0, 11, 0)))
1660
1700
        self.assertEndsWith('foo', 'oo')
1661
1701
        self.assertRaises(AssertionError, self.assertEndsWith, 'o', 'oo')
1662
1702
 
 
1703
    def test_assertEqualDiff(self):
 
1704
        e = self.assertRaises(AssertionError,
 
1705
                              self.assertEqualDiff, '', '\n')
 
1706
        self.assertEquals(str(e),
 
1707
                          # Don't blink ! The '+' applies to the second string
 
1708
                          'first string is missing a final newline.\n+ \n')
 
1709
        e = self.assertRaises(AssertionError,
 
1710
                              self.assertEqualDiff, '\n', '')
 
1711
        self.assertEquals(str(e),
 
1712
                          # Don't blink ! The '-' applies to the second string
 
1713
                          'second string is missing a final newline.\n- \n')
 
1714
 
 
1715
 
 
1716
class TestDeprecations(tests.TestCase):
 
1717
 
1663
1718
    def test_applyDeprecated_not_deprecated(self):
1664
1719
        sample_object = ApplyDeprecatedHelper()
1665
1720
        # calling an undeprecated callable raises an assertion
1742
1797
        tree = self.make_branch_and_memory_tree('a')
1743
1798
        self.assertIsInstance(tree, bzrlib.memorytree.MemoryTree)
1744
1799
 
1745
 
 
1746
 
class TestSFTPMakeBranchAndTree(test_sftp_transport.TestCaseWithSFTPServer):
1747
 
 
1748
 
    def test_make_tree_for_sftp_branch(self):
1749
 
        """Transports backed by local directories create local trees."""
1750
 
        # NB: This is arguably a bug in the definition of make_branch_and_tree.
 
1800
    def test_make_tree_for_local_vfs_backed_transport(self):
 
1801
        # make_branch_and_tree has to use local branch and repositories
 
1802
        # when the vfs transport and local disk are colocated, even if
 
1803
        # a different transport is in use for url generation.
 
1804
        self.transport_server = test_server.FakeVFATServer
 
1805
        self.assertFalse(self.get_url('t1').startswith('file://'))
1751
1806
        tree = self.make_branch_and_tree('t1')
1752
1807
        base = tree.bzrdir.root_transport.base
1753
 
        self.failIf(base.startswith('sftp'),
1754
 
                'base %r is on sftp but should be local' % base)
 
1808
        self.assertStartsWith(base, 'file://')
1755
1809
        self.assertEquals(tree.bzrdir.root_transport,
1756
1810
                tree.branch.bzrdir.root_transport)
1757
1811
        self.assertEquals(tree.bzrdir.root_transport,
1817
1871
        self.assertNotContainsRe("Test.b", output.getvalue())
1818
1872
        self.assertLength(2, output.readlines())
1819
1873
 
 
1874
    def test_lsprof_tests(self):
 
1875
        self.requireFeature(test_lsprof.LSProfFeature)
 
1876
        calls = []
 
1877
        class Test(object):
 
1878
            def __call__(test, result):
 
1879
                test.run(result)
 
1880
            def run(test, result):
 
1881
                self.assertIsInstance(result, tests.ForwardingResult)
 
1882
                calls.append("called")
 
1883
            def countTestCases(self):
 
1884
                return 1
 
1885
        self.run_selftest(test_suite_factory=Test, lsprof_tests=True)
 
1886
        self.assertLength(1, calls)
 
1887
 
1820
1888
    def test_random(self):
1821
1889
        # test randomising by listing a number of tests.
1822
1890
        output_123 = self.run_selftest(test_suite_factory=self.factory,
1837
1905
        self.assertEqual(expected.getvalue(), repeated.getvalue())
1838
1906
 
1839
1907
    def test_runner_class(self):
1840
 
        self.requireFeature(SubUnitFeature)
 
1908
        self.requireFeature(features.subunit)
1841
1909
        from subunit import ProtocolTestCase
1842
1910
        stream = self.run_selftest(runner_class=tests.SubUnitBzrRunner,
1843
1911
            test_suite_factory=self.factory)
1875
1943
        self.assertEqual(transport_server, captured_transport[0])
1876
1944
 
1877
1945
    def test_transport_sftp(self):
1878
 
        try:
1879
 
            import bzrlib.transport.sftp
1880
 
        except ParamikoNotPresent:
1881
 
            raise TestSkipped("Paramiko not present")
1882
 
        self.check_transport_set(bzrlib.transport.sftp.SFTPAbsoluteServer)
 
1946
        self.requireFeature(features.paramiko)
 
1947
        from bzrlib.tests import stub_sftp
 
1948
        self.check_transport_set(stub_sftp.SFTPAbsoluteServer)
1883
1949
 
1884
1950
    def test_transport_memory(self):
1885
 
        self.check_transport_set(bzrlib.transport.memory.MemoryServer)
 
1951
        self.check_transport_set(memory.MemoryServer)
1886
1952
 
1887
1953
 
1888
1954
class TestSelftestWithIdList(tests.TestCaseInTempDir, SelfTestHelper):
1914
1980
 
1915
1981
        Attempts to run bzr from inside this class don't actually run it.
1916
1982
 
1917
 
        We test how run_bzr actually invokes bzr in another location.
1918
 
        Here we only need to test that it is run_bzr passes the right
1919
 
        parameters to run_bzr.
 
1983
        We test how run_bzr actually invokes bzr in another location.  Here we
 
1984
        only need to test that it passes the right parameters to run_bzr.
1920
1985
        """
1921
1986
        self.argv = list(argv)
1922
1987
        self.retcode = retcode
1923
1988
        self.encoding = encoding
1924
1989
        self.stdin = stdin
1925
1990
        self.working_dir = working_dir
1926
 
        return self.out, self.err
 
1991
        return self.retcode, self.out, self.err
1927
1992
 
1928
1993
    def test_run_bzr_error(self):
1929
1994
        self.out = "It sure does!\n"
1930
1995
        out, err = self.run_bzr_error(['^$'], ['rocks'], retcode=34)
1931
1996
        self.assertEqual(['rocks'], self.argv)
1932
1997
        self.assertEqual(34, self.retcode)
1933
 
        self.assertEqual(out, 'It sure does!\n')
 
1998
        self.assertEqual('It sure does!\n', out)
 
1999
        self.assertEquals(out, self.out)
 
2000
        self.assertEqual('', err)
 
2001
        self.assertEquals(err, self.err)
1934
2002
 
1935
2003
    def test_run_bzr_error_regexes(self):
1936
2004
        self.out = ''
1937
2005
        self.err = "bzr: ERROR: foobarbaz is not versioned"
1938
2006
        out, err = self.run_bzr_error(
1939
 
                ["bzr: ERROR: foobarbaz is not versioned"],
1940
 
                ['file-id', 'foobarbaz'])
 
2007
            ["bzr: ERROR: foobarbaz is not versioned"],
 
2008
            ['file-id', 'foobarbaz'])
1941
2009
 
1942
2010
    def test_encoding(self):
1943
2011
        """Test that run_bzr passes encoding to _run_bzr_core"""
2072
2140
        return self.out, self.err
2073
2141
 
2074
2142
 
2075
 
class TestRunBzrSubprocess(tests.TestCaseWithTransport):
 
2143
class TestWithFakedStartBzrSubprocess(tests.TestCaseWithTransport):
 
2144
    """Base class for tests testing how we might run bzr."""
2076
2145
 
2077
2146
    def setUp(self):
2078
2147
        tests.TestCaseWithTransport.setUp(self)
2089
2158
            'working_dir':working_dir, 'allow_plugins':allow_plugins})
2090
2159
        return self.next_subprocess
2091
2160
 
 
2161
 
 
2162
class TestRunBzrSubprocess(TestWithFakedStartBzrSubprocess):
 
2163
 
2092
2164
    def assertRunBzrSubprocess(self, expected_args, process, *args, **kwargs):
2093
2165
        """Run run_bzr_subprocess with args and kwargs using a stubbed process.
2094
2166
 
2157
2229
            StubProcess(), '', allow_plugins=True)
2158
2230
 
2159
2231
 
 
2232
class TestFinishBzrSubprocess(TestWithFakedStartBzrSubprocess):
 
2233
 
 
2234
    def test_finish_bzr_subprocess_with_error(self):
 
2235
        """finish_bzr_subprocess allows specification of the desired exit code.
 
2236
        """
 
2237
        process = StubProcess(err="unknown command", retcode=3)
 
2238
        result = self.finish_bzr_subprocess(process, retcode=3)
 
2239
        self.assertEqual('', result[0])
 
2240
        self.assertContainsRe(result[1], 'unknown command')
 
2241
 
 
2242
    def test_finish_bzr_subprocess_ignoring_retcode(self):
 
2243
        """finish_bzr_subprocess allows the exit code to be ignored."""
 
2244
        process = StubProcess(err="unknown command", retcode=3)
 
2245
        result = self.finish_bzr_subprocess(process, retcode=None)
 
2246
        self.assertEqual('', result[0])
 
2247
        self.assertContainsRe(result[1], 'unknown command')
 
2248
 
 
2249
    def test_finish_subprocess_with_unexpected_retcode(self):
 
2250
        """finish_bzr_subprocess raises self.failureException if the retcode is
 
2251
        not the expected one.
 
2252
        """
 
2253
        process = StubProcess(err="unknown command", retcode=3)
 
2254
        self.assertRaises(self.failureException, self.finish_bzr_subprocess,
 
2255
                          process)
 
2256
 
 
2257
 
2160
2258
class _DontSpawnProcess(Exception):
2161
2259
    """A simple exception which just allows us to skip unnecessary steps"""
2162
2260
 
2240
2338
        self.assertEqual(['foo', 'current'], chdirs)
2241
2339
 
2242
2340
 
2243
 
class TestBzrSubprocess(tests.TestCaseWithTransport):
2244
 
 
2245
 
    def test_start_and_stop_bzr_subprocess(self):
2246
 
        """We can start and perform other test actions while that process is
2247
 
        still alive.
2248
 
        """
2249
 
        process = self.start_bzr_subprocess(['--version'])
2250
 
        result = self.finish_bzr_subprocess(process)
2251
 
        self.assertContainsRe(result[0], 'is free software')
2252
 
        self.assertEqual('', result[1])
2253
 
 
2254
 
    def test_start_and_stop_bzr_subprocess_with_error(self):
2255
 
        """finish_bzr_subprocess allows specification of the desired exit code.
2256
 
        """
2257
 
        process = self.start_bzr_subprocess(['--versionn'])
2258
 
        result = self.finish_bzr_subprocess(process, retcode=3)
2259
 
        self.assertEqual('', result[0])
2260
 
        self.assertContainsRe(result[1], 'unknown command')
2261
 
 
2262
 
    def test_start_and_stop_bzr_subprocess_ignoring_retcode(self):
2263
 
        """finish_bzr_subprocess allows the exit code to be ignored."""
2264
 
        process = self.start_bzr_subprocess(['--versionn'])
2265
 
        result = self.finish_bzr_subprocess(process, retcode=None)
2266
 
        self.assertEqual('', result[0])
2267
 
        self.assertContainsRe(result[1], 'unknown command')
2268
 
 
2269
 
    def test_start_and_stop_bzr_subprocess_with_unexpected_retcode(self):
2270
 
        """finish_bzr_subprocess raises self.failureException if the retcode is
2271
 
        not the expected one.
2272
 
        """
2273
 
        process = self.start_bzr_subprocess(['--versionn'])
2274
 
        self.assertRaises(self.failureException, self.finish_bzr_subprocess,
2275
 
                          process)
 
2341
class TestActuallyStartBzrSubprocess(tests.TestCaseWithTransport):
 
2342
    """Tests that really need to do things with an external bzr."""
2276
2343
 
2277
2344
    def test_start_and_stop_bzr_subprocess_send_signal(self):
2278
2345
        """finish_bzr_subprocess raises self.failureException if the retcode is
2279
2346
        not the expected one.
2280
2347
        """
 
2348
        self.disable_missing_extensions_warning()
2281
2349
        process = self.start_bzr_subprocess(['wait-until-signalled'],
2282
2350
                                            skip_if_plan_to_signal=True)
2283
2351
        self.assertEqual('running\n', process.stdout.readline())
2286
2354
        self.assertEqual('', result[0])
2287
2355
        self.assertEqual('bzr: interrupted\n', result[1])
2288
2356
 
2289
 
    def test_start_and_stop_working_dir(self):
2290
 
        cwd = osutils.getcwd()
2291
 
        self.make_branch_and_tree('one')
2292
 
        process = self.start_bzr_subprocess(['root'], working_dir='one')
2293
 
        result = self.finish_bzr_subprocess(process, universal_newlines=True)
2294
 
        self.assertEndsWith(result[0], 'one\n')
2295
 
        self.assertEqual('', result[1])
2296
 
 
2297
 
 
2298
 
class TestKnownFailure(tests.TestCase):
2299
 
 
2300
 
    def test_known_failure(self):
2301
 
        """Check that KnownFailure is defined appropriately."""
2302
 
        # a KnownFailure is an assertion error for compatability with unaware
2303
 
        # runners.
2304
 
        self.assertIsInstance(tests.KnownFailure(""), AssertionError)
2305
 
 
2306
 
    def test_expect_failure(self):
2307
 
        try:
2308
 
            self.expectFailure("Doomed to failure", self.assertTrue, False)
2309
 
        except tests.KnownFailure, e:
2310
 
            self.assertEqual('Doomed to failure', e.args[0])
2311
 
        try:
2312
 
            self.expectFailure("Doomed to failure", self.assertTrue, True)
2313
 
        except AssertionError, e:
2314
 
            self.assertEqual('Unexpected success.  Should have failed:'
2315
 
                             ' Doomed to failure', e.args[0])
2316
 
        else:
2317
 
            self.fail('Assertion not raised')
2318
 
 
2319
2357
 
2320
2358
class TestFeature(tests.TestCase):
2321
2359
 
2358
2396
        self.assertIs(feature, exception.args[0])
2359
2397
 
2360
2398
 
 
2399
simple_thunk_feature = tests._CompatabilityThunkFeature(
 
2400
    deprecated_in((2, 1, 0)),
 
2401
    'bzrlib.tests.test_selftest',
 
2402
    'simple_thunk_feature','UnicodeFilename',
 
2403
    replacement_module='bzrlib.tests'
 
2404
    )
 
2405
 
 
2406
class Test_CompatibilityFeature(tests.TestCase):
 
2407
 
 
2408
    def test_does_thunk(self):
 
2409
        res = self.callDeprecated(
 
2410
            ['bzrlib.tests.test_selftest.simple_thunk_feature was deprecated'
 
2411
             ' in version 2.1.0. Use bzrlib.tests.UnicodeFilename instead.'],
 
2412
            simple_thunk_feature.available)
 
2413
        self.assertEqual(tests.UnicodeFilename.available(), res)
 
2414
 
 
2415
 
 
2416
class TestModuleAvailableFeature(tests.TestCase):
 
2417
 
 
2418
    def test_available_module(self):
 
2419
        feature = tests.ModuleAvailableFeature('bzrlib.tests')
 
2420
        self.assertEqual('bzrlib.tests', feature.module_name)
 
2421
        self.assertEqual('bzrlib.tests', str(feature))
 
2422
        self.assertTrue(feature.available())
 
2423
        self.assertIs(tests, feature.module)
 
2424
 
 
2425
    def test_unavailable_module(self):
 
2426
        feature = tests.ModuleAvailableFeature('bzrlib.no_such_module_exists')
 
2427
        self.assertEqual('bzrlib.no_such_module_exists', str(feature))
 
2428
        self.assertFalse(feature.available())
 
2429
        self.assertIs(None, feature.module)
 
2430
 
 
2431
 
2361
2432
class TestSelftestFiltering(tests.TestCase):
2362
2433
 
2363
2434
    def setUp(self):
2542
2613
        # the test framework
2543
2614
        self.assertEquals('always fails', str(e))
2544
2615
        # check that there's no traceback in the test log
2545
 
        self.assertNotContainsRe(self._get_log(keep_log_file=True),
2546
 
            r'Traceback')
 
2616
        self.assertNotContainsRe(self.get_log(), r'Traceback')
2547
2617
 
2548
2618
    def test_run_bzr_user_error_caught(self):
2549
2619
        # Running bzr in blackbox mode, normal/expected/user errors should be
2550
2620
        # caught in the regular way and turned into an error message plus exit
2551
2621
        # code.
2552
 
        out, err = self.run_bzr(["log", "/nonexistantpath"], retcode=3)
 
2622
        transport_server = memory.MemoryServer()
 
2623
        transport_server.start_server()
 
2624
        self.addCleanup(transport_server.stop_server)
 
2625
        url = transport_server.get_url()
 
2626
        self.permit_url(url)
 
2627
        out, err = self.run_bzr(["log", "%s/nonexistantpath" % url], retcode=3)
2553
2628
        self.assertEqual(out, '')
2554
2629
        self.assertContainsRe(err,
2555
2630
            'bzr: ERROR: Not a branch: ".*nonexistantpath/".\n')
2681
2756
 
2682
2757
class TestTestSuite(tests.TestCase):
2683
2758
 
 
2759
    def test__test_suite_testmod_names(self):
 
2760
        # Test that a plausible list of test module names are returned
 
2761
        # by _test_suite_testmod_names.
 
2762
        test_list = tests._test_suite_testmod_names()
 
2763
        self.assertSubset([
 
2764
            'bzrlib.tests.blackbox',
 
2765
            'bzrlib.tests.per_transport',
 
2766
            'bzrlib.tests.test_selftest',
 
2767
            ],
 
2768
            test_list)
 
2769
 
 
2770
    def test__test_suite_modules_to_doctest(self):
 
2771
        # Test that a plausible list of modules to doctest is returned
 
2772
        # by _test_suite_modules_to_doctest.
 
2773
        test_list = tests._test_suite_modules_to_doctest()
 
2774
        if __doc__ is None:
 
2775
            # When docstrings are stripped, there are no modules to doctest
 
2776
            self.assertEqual([], test_list)
 
2777
            return
 
2778
        self.assertSubset([
 
2779
            'bzrlib.timestamp',
 
2780
            ],
 
2781
            test_list)
 
2782
 
2684
2783
    def test_test_suite(self):
2685
 
        # This test is slow - it loads the entire test suite to operate, so we
2686
 
        # do a single test with one test in each category
2687
 
        test_list = [
 
2784
        # test_suite() loads the entire test suite to operate. To avoid this
 
2785
        # overhead, and yet still be confident that things are happening,
 
2786
        # we temporarily replace two functions used by test_suite with 
 
2787
        # test doubles that supply a few sample tests to load, and check they
 
2788
        # are loaded.
 
2789
        calls = []
 
2790
        def testmod_names():
 
2791
            calls.append("testmod_names")
 
2792
            return [
 
2793
                'bzrlib.tests.blackbox.test_branch',
 
2794
                'bzrlib.tests.per_transport',
 
2795
                'bzrlib.tests.test_selftest',
 
2796
                ]
 
2797
        self.overrideAttr(tests, '_test_suite_testmod_names', testmod_names)
 
2798
        def doctests():
 
2799
            calls.append("modules_to_doctest")
 
2800
            if __doc__ is None:
 
2801
                return []
 
2802
            return ['bzrlib.timestamp']
 
2803
        self.overrideAttr(tests, '_test_suite_modules_to_doctest', doctests)
 
2804
        expected_test_list = [
2688
2805
            # testmod_names
2689
2806
            'bzrlib.tests.blackbox.test_branch.TestBranch.test_branch',
2690
2807
            ('bzrlib.tests.per_transport.TransportTests'
2691
 
             '.test_abspath(LocalURLServer)'),
 
2808
             '.test_abspath(LocalTransport,LocalURLServer)'),
2692
2809
            'bzrlib.tests.test_selftest.TestTestSuite.test_test_suite',
2693
 
            # modules_to_doctest
2694
 
            'bzrlib.timestamp.format_highres_date',
2695
2810
            # plugins can't be tested that way since selftest may be run with
2696
2811
            # --no-plugins
2697
2812
            ]
2698
 
        suite = tests.test_suite(test_list)
2699
 
        self.assertEquals(test_list, _test_ids(suite))
 
2813
        if __doc__ is not None:
 
2814
            expected_test_list.extend([
 
2815
                # modules_to_doctest
 
2816
                'bzrlib.timestamp.format_highres_date',
 
2817
                ])
 
2818
        suite = tests.test_suite()
 
2819
        self.assertEqual(set(["testmod_names", "modules_to_doctest"]),
 
2820
            set(calls))
 
2821
        self.assertSubset(expected_test_list, _test_ids(suite))
2700
2822
 
2701
2823
    def test_test_suite_list_and_start(self):
2702
2824
        # We cannot test this at the same time as the main load, because we want
2703
 
        # to know that starting_with == None works. So a second full load is
2704
 
        # incurred.
 
2825
        # to know that starting_with == None works. So a second load is
 
2826
        # incurred - note that the starting_with parameter causes a partial load
 
2827
        # rather than a full load so this test should be pretty quick.
2705
2828
        test_list = ['bzrlib.tests.test_selftest.TestTestSuite.test_test_suite']
2706
2829
        suite = tests.test_suite(test_list,
2707
2830
                                 ['bzrlib.tests.test_selftest.TestTestSuite'])
2752
2875
    def test_load_tests(self):
2753
2876
        test_list = ['bzrlib.tests.test_sampler.DemoTest.test_nothing']
2754
2877
        loader = self._create_loader(test_list)
2755
 
 
2756
2878
        suite = loader.loadTestsFromModuleName('bzrlib.tests.test_sampler')
2757
2879
        self.assertEquals(test_list, _test_ids(suite))
2758
2880
 
2759
2881
    def test_exclude_tests(self):
2760
2882
        test_list = ['bogus']
2761
2883
        loader = self._create_loader(test_list)
2762
 
 
2763
2884
        suite = loader.loadTestsFromModuleName('bzrlib.tests.test_sampler')
2764
2885
        self.assertEquals([], _test_ids(suite))
2765
2886
 
2810
2931
        tpr.register('bar', 'bbb.aaa.rrr')
2811
2932
        tpr.register('bar', 'bBB.aAA.rRR')
2812
2933
        self.assertEquals('bbb.aaa.rrr', tpr.get('bar'))
2813
 
        self.assertContainsRe(self._get_log(keep_log_file=True),
2814
 
                              r'.*bar.*bbb.aaa.rrr.*bBB.aAA.rRR')
 
2934
        self.assertThat(self.get_log(),
 
2935
            DocTestMatches("...bar...bbb.aaa.rrr...BB.aAA.rRR", ELLIPSIS))
2815
2936
 
2816
2937
    def test_get_unknown_prefix(self):
2817
2938
        tpr = self._get_registry()
2853
2974
                                                self.verbosity)
2854
2975
        tests.run_suite(suite, runner_class=MyRunner, stream=StringIO())
2855
2976
        self.assertLength(1, calls)
2856
 
 
2857
 
    def test_done(self):
2858
 
        """run_suite should call result.done()"""
2859
 
        self.calls = 0
2860
 
        def one_more_call(): self.calls += 1
2861
 
        def test_function():
2862
 
            pass
2863
 
        test = unittest.FunctionTestCase(test_function)
2864
 
        class InstrumentedTestResult(tests.ExtendedTestResult):
2865
 
            def done(self): one_more_call()
2866
 
        class MyRunner(tests.TextTestRunner):
2867
 
            def run(self, test):
2868
 
                return InstrumentedTestResult(self.stream, self.descriptions,
2869
 
                                              self.verbosity)
2870
 
        tests.run_suite(test, runner_class=MyRunner, stream=StringIO())
2871
 
        self.assertEquals(1, self.calls)