/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to breezy/tests/test_selftest.py

  • Committer: Jelmer Vernooij
  • Date: 2020-05-06 02:13:25 UTC
  • mfrom: (7490.7.21 work)
  • mto: This revision was merged to the branch mainline in revision 7501.
  • Revision ID: jelmer@jelmer.uk-20200506021325-awbmmqu1zyorz7sj
Merge 3.1 branch.

Show diffs side-by-side

added added

removed removed

Lines of Context:
18
18
 
19
19
import gc
20
20
import doctest
 
21
from functools import reduce
 
22
from io import BytesIO, StringIO, TextIOWrapper
21
23
import os
22
24
import signal
23
25
import sys
62
64
from ..bzr import (
63
65
    groupcompress_repo,
64
66
    )
65
 
from ..sixish import (
66
 
    StringIO,
67
 
    text_type,
 
67
from ..git import (
 
68
    workingtree as git_workingtree,
68
69
    )
69
70
from ..symbol_versioning import (
70
71
    deprecated_function,
97
98
            "text", "plain", {"charset": "utf8"})))
98
99
        self.assertThat(u"".join(log.iter_text()), Equals(self.get_log()))
99
100
        self.assertThat(self.get_log(),
100
 
            DocTestMatches(u"...a test message\n", doctest.ELLIPSIS))
 
101
                        DocTestMatches(u"...a test message\n", doctest.ELLIPSIS))
101
102
 
102
103
 
103
104
class TestTreeShape(tests.TestCaseInTempDir):
106
107
        self.requireFeature(features.UnicodeFilenameFeature)
107
108
 
108
109
        filename = u'hell\u00d8'
109
 
        self.build_tree_contents([(filename, 'contents of hello')])
 
110
        self.build_tree_contents([(filename, b'contents of hello')])
110
111
        self.assertPathExists(filename)
111
112
 
112
113
 
156
157
        for module in modules:
157
158
            try:
158
159
                permutation_count += len(reduce(getattr,
159
 
                    (module + ".get_test_permutations").split('.')[1:],
160
 
                     __import__(module))())
 
160
                                                (module
 
161
                                                 + ".get_test_permutations").split('.')[1:],
 
162
                                                __import__(module))())
161
163
            except errors.DependencyNotPresent:
162
164
                pass
163
165
        scenarios = transport_test_permutations()
235
237
        from .per_repository import formats_to_scenarios
236
238
        formats = [("(c)", remote.RemoteRepositoryFormat()),
237
239
                   ("(d)", repository.format_registry.get(
238
 
                    'Bazaar repository format 2a (needs bzr 1.16 or later)\n'))]
 
240
                    b'Bazaar repository format 2a (needs bzr 1.16 or later)\n'))]
239
241
        no_vfs_scenarios = formats_to_scenarios(formats, "server", "readonly",
240
 
            None)
 
242
                                                None)
241
243
        vfs_scenarios = formats_to_scenarios(formats, "server", "readonly",
242
 
            vfs_transport_factory="vfs")
 
244
                                             vfs_transport_factory="vfs")
243
245
        # no_vfs generate scenarios without vfs_transport_factory
244
246
        expected = [
245
247
            ('RemoteRepositoryFormat(c)',
277
279
        input_test = TestTestScenarioApplication("test_apply_scenario")
278
280
        # setup two adapted tests
279
281
        adapted_test1 = apply_scenario(input_test,
280
 
            ("new id",
281
 
            {"bzrdir_format":"bzr_format",
282
 
             "repository_format":"repo_fmt",
283
 
             "transport_server":"transport_server",
284
 
             "transport_readonly_server":"readonly-server"}))
 
282
                                       ("new id",
 
283
                                        {"bzrdir_format": "bzr_format",
 
284
                                         "repository_format": "repo_fmt",
 
285
                                         "transport_server": "transport_server",
 
286
                                         "transport_readonly_server": "readonly-server"}))
285
287
        adapted_test2 = apply_scenario(input_test,
286
 
            ("new id 2", {"bzrdir_format":None}))
 
288
                                       ("new id 2", {"bzrdir_format": None}))
287
289
        # input_test should have been altered.
288
290
        self.assertRaises(AttributeError, getattr, input_test, "bzrdir_format")
289
291
        # the new tests are mutually incompatible, ensuring it has
293
295
        self.assertEqual("repo_fmt", adapted_test1.repository_format)
294
296
        self.assertEqual("transport_server", adapted_test1.transport_server)
295
297
        self.assertEqual("readonly-server",
296
 
            adapted_test1.transport_readonly_server)
 
298
                         adapted_test1.transport_readonly_server)
297
299
        self.assertEqual(
298
300
            "breezy.tests.test_selftest.TestTestScenarioApplication."
299
301
            "test_apply_scenario(new id)",
343
345
                   workingtree_3.WorkingTreeFormat3(),
344
346
                   workingtree_4.WorkingTreeFormat6()]
345
347
        scenarios = make_scenarios(server1, server2, formats,
346
 
            remote_server='c', remote_readonly_server='d',
347
 
            remote_backing_server='e')
 
348
                                   remote_server='c', remote_readonly_server='d',
 
349
                                   remote_backing_server='e')
348
350
        self.assertEqual([
349
351
            ('WorkingTreeFormat4',
350
352
             {'bzrdir_format': formats[0]._matchingcontroldir,
397
399
        smart_readonly_server = test_server.ReadonlySmartTCPServer_for_testing
398
400
        mem_server = memory.MemoryServer
399
401
        formats = [workingtree_4.WorkingTreeFormat4(),
400
 
                   workingtree_3.WorkingTreeFormat3(),]
 
402
                   workingtree_3.WorkingTreeFormat3(), ]
401
403
        scenarios = make_scenarios(server1, server2, formats)
402
 
        self.assertEqual(8, len(scenarios))
 
404
        self.assertEqual(9, len(scenarios))
403
405
        default_wt_format = workingtree.format_registry.get_default()
404
406
        wt4_format = workingtree_4.WorkingTreeFormat4()
405
407
        wt5_format = workingtree_4.WorkingTreeFormat5()
406
408
        wt6_format = workingtree_4.WorkingTreeFormat6()
 
409
        git_wt_format = git_workingtree.GitWorkingTreeFormat()
407
410
        expected_scenarios = [
408
411
            ('WorkingTreeFormat4',
409
412
             {'bzrdir_format': formats[0]._matchingcontroldir,
418
421
              'transport_server': 'a',
419
422
              'workingtree_format': formats[1],
420
423
              '_workingtree_to_test_tree': return_parameter,
421
 
             }),
 
424
              }),
422
425
            ('WorkingTreeFormat6,remote',
423
426
             {'bzrdir_format': wt6_format._matchingcontroldir,
424
427
              'repo_is_remote': True,
427
430
              'vfs_transport_factory': mem_server,
428
431
              'workingtree_format': wt6_format,
429
432
              '_workingtree_to_test_tree': return_parameter,
430
 
             }),
 
433
              }),
431
434
            ('RevisionTree',
432
435
             {'_workingtree_to_test_tree': revision_tree_from_workingtree,
433
436
              'bzrdir_format': default_wt_format._matchingcontroldir,
434
437
              'transport_readonly_server': 'b',
435
438
              'transport_server': 'a',
436
439
              'workingtree_format': default_wt_format,
437
 
             }),
 
440
              }),
 
441
            ('GitRevisionTree',
 
442
             {'_workingtree_to_test_tree': revision_tree_from_workingtree,
 
443
              'bzrdir_format': git_wt_format._matchingcontroldir,
 
444
              'transport_readonly_server': 'b',
 
445
              'transport_server': 'a',
 
446
              'workingtree_format': git_wt_format,
 
447
              }
 
448
             ),
438
449
            ('DirStateRevisionTree,WT4',
439
450
             {'_workingtree_to_test_tree': _dirstate_tree_from_workingtree,
440
451
              'bzrdir_format': wt4_format._matchingcontroldir,
441
452
              'transport_readonly_server': 'b',
442
453
              'transport_server': 'a',
443
454
              'workingtree_format': wt4_format,
444
 
             }),
 
455
              }),
445
456
            ('DirStateRevisionTree,WT5',
446
457
             {'_workingtree_to_test_tree': _dirstate_tree_from_workingtree,
447
458
              'bzrdir_format': wt5_format._matchingcontroldir,
448
459
              'transport_readonly_server': 'b',
449
460
              'transport_server': 'a',
450
461
              'workingtree_format': wt5_format,
451
 
             }),
 
462
              }),
452
463
            ('PreviewTree',
453
464
             {'_workingtree_to_test_tree': preview_tree_pre,
454
465
              'bzrdir_format': default_wt_format._matchingcontroldir,
461
472
              'transport_readonly_server': 'b',
462
473
              'transport_server': 'a',
463
474
              'workingtree_format': default_wt_format}),
464
 
             ]
 
475
            ]
465
476
        self.assertEqual(expected_scenarios, scenarios)
466
477
 
467
478
 
493
504
        format1 = WorkingTreeFormat4()
494
505
        format2 = WorkingTreeFormat3()
495
506
        formats = [("1", str, format1, format2, "converter1"),
496
 
            ("2", int, format2, format1, "converter2")]
 
507
                   ("2", int, format2, format1, "converter2")]
497
508
        scenarios = make_scenarios(server1, server2, formats)
498
509
        self.assertEqual(2, len(scenarios))
499
510
        expected_scenarios = [
534
545
        self.build_tree(["foo"])
535
546
        real = os.lstat("foo")
536
547
        fake = _FakeStat(real.st_size, real.st_mtime, real.st_ctime,
537
 
            real.st_dev, real.st_ino, real.st_mode)
 
548
                         real.st_dev, real.st_ino, real.st_mode)
538
549
        self.assertEqualStat(real, fake)
539
550
 
540
551
    def test_assertEqualStat_notequal(self):
541
552
        self.build_tree(["foo", "longname"])
542
553
        self.assertRaises(AssertionError, self.assertEqualStat,
543
 
            os.lstat("foo"), os.lstat("longname"))
 
554
                          os.lstat("foo"), os.lstat("longname"))
544
555
 
545
556
    def test_assertPathExists(self):
546
557
        self.assertPathExists('.')
600
611
        self.assertFalse(osutils.lexists('dir'))
601
612
        self.assertIsInstance(tree, memorytree.MemoryTree)
602
613
        self.assertEqual(format.repository_format.__class__,
603
 
            tree.branch.repository._format.__class__)
 
614
                         tree.branch.repository._format.__class__)
604
615
 
605
616
    def test_make_branch_builder(self):
606
617
        builder = self.make_branch_builder('dir')
624
635
                         the_branch.repository._format.__class__)
625
636
        self.assertEqual(repo_format.get_format_string(),
626
637
                         self.get_transport().get_bytes(
627
 
                            'dir/.bzr/repository/format'))
 
638
            'dir/.bzr/repository/format'))
628
639
 
629
640
    def test_make_branch_builder_with_format_name(self):
630
641
        builder = self.make_branch_builder('dir', format='knit')
635
646
        dir_format = controldir.format_registry.make_controldir('knit')
636
647
        self.assertEqual(dir_format.repository_format.__class__,
637
648
                         the_branch.repository._format.__class__)
638
 
        self.assertEqual('Bazaar-NG Knit Repository Format 1',
 
649
        self.assertEqual(b'Bazaar-NG Knit Repository Format 1',
639
650
                         self.get_transport().get_bytes(
640
 
                            'dir/.bzr/repository/format'))
 
651
                             'dir/.bzr/repository/format'))
641
652
 
642
653
    def test_dangling_locks_cause_failures(self):
643
654
        class TestDanglingLock(tests.TestCaseWithMemoryTransport):
676
687
 
677
688
    def test_get_readonly_url_http(self):
678
689
        from .http_server import HttpServer
679
 
        from ..transport.http import HttpTransportBase
 
690
        from ..transport.http import HttpTransport
680
691
        self.transport_server = test_server.LocalURLServer
681
692
        self.transport_readonly_server = HttpServer
682
693
        # calling get_readonly_transport() gives us a HTTP server instance.
685
696
        # the transport returned may be any HttpTransportBase subclass
686
697
        t = transport.get_transport_from_url(url)
687
698
        t2 = transport.get_transport_from_url(url2)
688
 
        self.assertIsInstance(t, HttpTransportBase)
689
 
        self.assertIsInstance(t2, HttpTransportBase)
 
699
        self.assertIsInstance(t, HttpTransport)
 
700
        self.assertIsInstance(t2, HttpTransport)
690
701
        self.assertEqual(t2.base[:-1], t.abspath('foo/bar'))
691
702
 
692
703
    def test_is_directory(self):
695
706
        self.build_tree(['a_dir/', 'a_file'], transport=t)
696
707
        self.assertIsDirectory('a_dir', t)
697
708
        self.assertRaises(AssertionError, self.assertIsDirectory, 'a_file', t)
698
 
        self.assertRaises(AssertionError, self.assertIsDirectory, 'not_here', t)
 
709
        self.assertRaises(
 
710
            AssertionError, self.assertIsDirectory, 'not_here', t)
699
711
 
700
712
    def test_make_branch_builder(self):
701
713
        builder = self.make_branch_builder('dir')
739
751
        self.requireFeature(features.lsprof_feature)
740
752
        terminal = testtools.testresult.doubles.ExtendedTestResult()
741
753
        result = tests.ProfileResult(terminal)
 
754
 
742
755
        class Sample(tests.TestCase):
743
756
            def a(self):
744
757
                self.sample_function()
 
758
 
745
759
            def sample_function(self):
746
760
                pass
747
761
        test = Sample("a")
767
781
        class ShortDelayTestCase(tests.TestCase):
768
782
            def test_short_delay(self):
769
783
                time.sleep(0.003)
 
784
 
770
785
            def test_short_benchmark(self):
771
786
                self.time(time.sleep, 0.003)
772
787
        self.check_timing(ShortDelayTestCase('test_short_delay'),
789
804
 
790
805
        This is used to exercise the test framework.
791
806
        """
792
 
        self.time(unicode, 'hello', errors='replace')
793
 
        self.time(unicode, 'world', errors='replace')
 
807
        self.time(str, b'hello', errors='replace')
 
808
        self.time(str, b'world', errors='replace')
794
809
 
795
810
    def test_lsprofiling(self):
796
811
        """Verbose test result prints lsprof statistics from test cases."""
821
836
        # this should appear in the output stream of our test result.
822
837
        output = result_stream.getvalue()
823
838
        self.assertContainsRe(output,
824
 
            r"LSProf output for <type 'unicode'>\(\('hello',\), {'errors': 'replace'}\)")
825
 
        self.assertContainsRe(output,
826
 
            r" *CallCount *Recursive *Total\(ms\) *Inline\(ms\) *module:lineno\(function\)\n")
827
 
        self.assertContainsRe(output,
828
 
            r"( +1 +0 +0\.\d+ +0\.\d+ +<method 'disable' of '_lsprof\.Profiler' objects>\n)?")
829
 
        self.assertContainsRe(output,
830
 
            r"LSProf output for <type 'unicode'>\(\('world',\), {'errors': 'replace'}\)\n")
 
839
                              r"LSProf output for <class 'str'>\(\(b'hello',\), {'errors': 'replace'}\)")
 
840
        self.assertContainsRe(output,
 
841
                              r"LSProf output for <class 'str'>\(\(b'world',\), {'errors': 'replace'}\)")
 
842
        self.assertContainsRe(output,
 
843
                              r" *CallCount *Recursive *Total\(ms\) *Inline\(ms\) *module:lineno\(function\)\n")
 
844
        self.assertContainsRe(output,
 
845
                              r"( +1 +0 +0\.\d+ +0\.\d+ +<method 'disable' of '_lsprof\.Profiler' objects>\n)?")
831
846
 
832
847
    def test_uses_time_from_testtools(self):
833
848
        """Test case timings in verbose results should use testtools times"""
834
849
        import datetime
 
850
 
835
851
        class TimeAddedVerboseTestResult(tests.VerboseTestResult):
836
852
            def startTest(self, test):
837
853
                self.time(datetime.datetime.utcfromtimestamp(1.145))
838
854
                super(TimeAddedVerboseTestResult, self).startTest(test)
 
855
 
839
856
            def addSuccess(self, test):
840
857
                self.time(datetime.datetime.utcfromtimestamp(51.147))
841
858
                super(TimeAddedVerboseTestResult, self).addSuccess(test)
 
859
 
842
860
            def report_tests_starting(self): pass
843
861
        sio = StringIO()
844
862
        self.get_passing_test().run(TimeAddedVerboseTestResult(sio, 0, 2))
848
866
        """Using knownFailure should trigger several result actions."""
849
867
        class InstrumentedTestResult(tests.ExtendedTestResult):
850
868
            def stopTestRun(self): pass
 
869
 
851
870
            def report_tests_starting(self): pass
 
871
 
852
872
            def report_known_failure(self, test, err=None, details=None):
853
873
                self._call = test, 'known failure'
854
874
        result = InstrumentedTestResult(None, None, None, None)
 
875
 
855
876
        class Test(tests.TestCase):
856
877
            def test_function(self):
857
878
                self.knownFailure('failed!')
878
899
            )
879
900
        _get_test("test_xfail").run(result)
880
901
        self.assertContainsRe(result_stream.getvalue(),
881
 
            "\n\\S+\\.test_xfail\\s+XFAIL\\s+\\d+ms\n"
882
 
            "\\s*(?:Text attachment: )?reason"
883
 
            "(?:\n-+\n|: {{{)"
884
 
            "this_fails"
885
 
            "(?:\n-+\n|}}}\n)")
 
902
                              "\n\\S+\\.test_xfail\\s+XFAIL\\s+\\d+ms\n"
 
903
                              "\\s*(?:Text attachment: )?reason"
 
904
                              "(?:\n-+\n|: {{{)"
 
905
                              "this_fails"
 
906
                              "(?:\n-+\n|}}}\n)")
886
907
 
887
908
    def get_passing_test(self):
888
909
        """Return a test object that can't be run usefully."""
894
915
        """Test the behaviour of invoking addNotSupported."""
895
916
        class InstrumentedTestResult(tests.ExtendedTestResult):
896
917
            def stopTestRun(self): pass
 
918
 
897
919
            def report_tests_starting(self): pass
 
920
 
898
921
            def report_unsupported(self, test, feature):
899
922
                self._call = test, feature
900
923
        result = InstrumentedTestResult(None, None, None, None)
938
961
    def test_unavailable_exception(self):
939
962
        """An UnavailableFeature being raised should invoke addNotSupported."""
940
963
        class InstrumentedTestResult(tests.ExtendedTestResult):
941
 
            def stopTestRun(self): pass
942
 
            def report_tests_starting(self): pass
 
964
            def stopTestRun(self):
 
965
                pass
 
966
 
 
967
            def report_tests_starting(self):
 
968
                pass
 
969
 
943
970
            def addNotSupported(self, test, feature):
944
971
                self._call = test, feature
945
972
        result = InstrumentedTestResult(None, None, None, None)
946
973
        feature = features.Feature()
 
974
 
947
975
        class Test(tests.TestCase):
948
976
            def test_function(self):
949
977
                raise tests.UnavailableFeature(feature)
982
1010
        """Starting the first test should trigger startTests."""
983
1011
        class InstrumentedTestResult(tests.ExtendedTestResult):
984
1012
            calls = 0
985
 
            def startTests(self): self.calls += 1
 
1013
 
 
1014
            def startTests(self):
 
1015
                self.calls += 1
986
1016
        result = InstrumentedTestResult(None, None, None, None)
 
1017
 
987
1018
        def test_function():
988
1019
            pass
989
1020
        test = unittest.FunctionTestCase(test_function)
994
1025
        """With multiple tests startTests should still only be called once"""
995
1026
        class InstrumentedTestResult(tests.ExtendedTestResult):
996
1027
            calls = 0
997
 
            def startTests(self): self.calls += 1
 
1028
 
 
1029
            def startTests(self):
 
1030
                self.calls += 1
998
1031
        result = InstrumentedTestResult(None, None, None, None)
999
1032
        suite = unittest.TestSuite([
1000
1033
            unittest.FunctionTestCase(lambda: None),
1034
1067
                self.expectFailure('failed', self.assertTrue, False)
1035
1068
        test = unittest.TestSuite()
1036
1069
        test.addTest(Test("known_failure_test"))
 
1070
 
1037
1071
        def failing_test():
1038
1072
            raise AssertionError('foo')
1039
1073
        test.addTest(unittest.FunctionTestCase(failing_test))
1040
1074
        stream = StringIO()
1041
1075
        runner = tests.TextTestRunner(stream=stream)
1042
 
        result = self.run_test_runner(runner, test)
1043
 
        lines = stream.getvalue().splitlines()
1044
 
        self.assertContainsRe(stream.getvalue(),
 
1076
        self.run_test_runner(runner, test)
 
1077
        self.assertContainsRe(
 
1078
            stream.getvalue(),
1045
1079
            '(?sm)^brz selftest.*$'
1046
1080
            '.*'
1047
1081
            '^======================================================================\n'
1048
1082
            '^FAIL: failing_test\n'
1049
1083
            '^----------------------------------------------------------------------\n'
1050
1084
            'Traceback \\(most recent call last\\):\n'
1051
 
            '  .*' # File .*, line .*, in failing_test' - but maybe not from .pyc
 
1085
            '  .*'  # File .*, line .*, in failing_test' - but maybe not from .pyc
1052
1086
            '    raise AssertionError\\(\'foo\'\\)\n'
1053
1087
            '.*'
1054
1088
            '^----------------------------------------------------------------------\n'
1065
1099
        test = Test("known_failure_test")
1066
1100
        stream = StringIO()
1067
1101
        runner = tests.TextTestRunner(stream=stream)
1068
 
        result = self.run_test_runner(runner, test)
 
1102
        self.run_test_runner(runner, test)
1069
1103
        self.assertContainsRe(stream.getvalue(),
1070
 
            '\n'
1071
 
            '-*\n'
1072
 
            'Ran 1 test in .*\n'
1073
 
            '\n'
1074
 
            'OK \\(known_failures=1\\)\n')
 
1104
                              '\n'
 
1105
                              '-*\n'
 
1106
                              'Ran 1 test in .*\n'
 
1107
                              '\n'
 
1108
                              'OK \\(known_failures=1\\)\n')
1075
1109
 
1076
1110
    def test_unexpected_success_bad(self):
1077
1111
        class Test(tests.TestCase):
1078
1112
            def test_truth(self):
1079
1113
                self.expectFailure("No absolute truth", self.assertTrue, True)
1080
1114
        runner = tests.TextTestRunner(stream=StringIO())
1081
 
        result = self.run_test_runner(runner, Test("test_truth"))
 
1115
        self.run_test_runner(runner, Test("test_truth"))
1082
1116
        self.assertContainsRe(runner.stream.getvalue(),
1083
 
            "=+\n"
1084
 
            "FAIL: \\S+\\.test_truth\n"
1085
 
            "-+\n"
1086
 
            "(?:.*\n)*"
1087
 
            "\\s*(?:Text attachment: )?reason"
1088
 
            "(?:\n-+\n|: {{{)"
1089
 
            "No absolute truth"
1090
 
            "(?:\n-+\n|}}}\n)"
1091
 
            "(?:.*\n)*"
1092
 
            "-+\n"
1093
 
            "Ran 1 test in .*\n"
1094
 
            "\n"
1095
 
            "FAILED \\(failures=1\\)\n\\Z")
 
1117
                              "=+\n"
 
1118
                              "FAIL: \\S+\\.test_truth\n"
 
1119
                              "-+\n"
 
1120
                              "(?:.*\n)*"
 
1121
                              "\\s*(?:Text attachment: )?reason"
 
1122
                              "(?:\n-+\n|: {{{)"
 
1123
                              "No absolute truth"
 
1124
                              "(?:\n-+\n|}}}\n)"
 
1125
                              "(?:.*\n)*"
 
1126
                              "-+\n"
 
1127
                              "Ran 1 test in .*\n"
 
1128
                              "\n"
 
1129
                              "FAILED \\(failures=1\\)\n\\Z")
1096
1130
 
1097
1131
    def test_result_decorator(self):
1098
1132
        # decorate results
1099
1133
        calls = []
 
1134
 
1100
1135
        class LoggingDecorator(ExtendedToOriginalDecorator):
1101
1136
            def startTest(self, test):
1102
1137
                ExtendedToOriginalDecorator.startTest(self, test)
1103
1138
                calls.append('start')
1104
 
        test = unittest.FunctionTestCase(lambda:None)
 
1139
        test = unittest.FunctionTestCase(lambda: None)
1105
1140
        stream = StringIO()
1106
1141
        runner = tests.TextTestRunner(stream=stream,
1107
 
            result_decorators=[LoggingDecorator])
1108
 
        result = self.run_test_runner(runner, test)
 
1142
                                      result_decorators=[LoggingDecorator])
 
1143
        self.run_test_runner(runner, test)
1109
1144
        self.assertLength(1, calls)
1110
1145
 
1111
1146
    def test_skipped_test(self):
1122
1157
 
1123
1158
    def test_skipped_from_setup(self):
1124
1159
        calls = []
 
1160
 
1125
1161
        class SkippedSetupTest(tests.TestCase):
1126
1162
 
1127
1163
            def setUp(self):
1144
1180
 
1145
1181
    def test_skipped_from_test(self):
1146
1182
        calls = []
 
1183
 
1147
1184
        class SkippedTest(tests.TestCase):
1148
1185
 
1149
1186
            def setUp(self):
1177
1214
        self.assertTrue(result.wasSuccessful())
1178
1215
        self.assertTrue(result.wasStrictlySuccessful())
1179
1216
        self.assertContainsRe(out.getvalue(),
1180
 
                r'(?m)not_applicable_test  * N/A')
 
1217
                              r'(?m)not_applicable_test  * N/A')
1181
1218
        self.assertContainsRe(out.getvalue(),
1182
 
                r'(?m)^    this test never runs')
 
1219
                              r'(?m)^    this test never runs')
1183
1220
 
1184
1221
    def test_unsupported_features_listed(self):
1185
1222
        """When unsupported features are encountered they are detailed."""
1186
1223
        class Feature1(features.Feature):
1187
 
            def _probe(self): return False
 
1224
            def _probe(self):
 
1225
                return False
 
1226
 
1188
1227
        class Feature2(features.Feature):
1189
 
            def _probe(self): return False
 
1228
            def _probe(self):
 
1229
                return False
1190
1230
        # create sample tests
1191
1231
        test1 = SampleTestCase('_test_pass')
1192
1232
        test1._test_needs_features = [Feature1()]
1197
1237
        test.addTest(test2)
1198
1238
        stream = StringIO()
1199
1239
        runner = tests.TextTestRunner(stream=stream)
1200
 
        result = self.run_test_runner(runner, test)
 
1240
        self.run_test_runner(runner, test)
1201
1241
        lines = stream.getvalue().splitlines()
1202
1242
        self.assertEqual([
1203
1243
            'OK',
1215
1255
        stream = StringIO()
1216
1256
        runner = tests.TextTestRunner(stream=stream, verbosity=2)
1217
1257
        # Need to use the CountingDecorator as that's what sets num_tests
1218
 
        result = self.run_test_runner(runner, tests.CountingDecorator(suite))
 
1258
        self.run_test_runner(runner, tests.CountingDecorator(suite))
1219
1259
        self.assertStartsWith(stream.getvalue(), "running 2 tests")
1220
1260
 
1221
1261
    def test_startTestRun(self):
1222
1262
        """run should call result.startTestRun()"""
1223
1263
        calls = []
 
1264
 
1224
1265
        class LoggingDecorator(ExtendedToOriginalDecorator):
1225
1266
            def startTestRun(self):
1226
1267
                ExtendedToOriginalDecorator.startTestRun(self)
1227
1268
                calls.append('startTestRun')
1228
 
        test = unittest.FunctionTestCase(lambda:None)
 
1269
        test = unittest.FunctionTestCase(lambda: None)
1229
1270
        stream = StringIO()
1230
1271
        runner = tests.TextTestRunner(stream=stream,
1231
 
            result_decorators=[LoggingDecorator])
1232
 
        result = self.run_test_runner(runner, test)
 
1272
                                      result_decorators=[LoggingDecorator])
 
1273
        self.run_test_runner(runner, test)
1233
1274
        self.assertLength(1, calls)
1234
1275
 
1235
1276
    def test_stopTestRun(self):
1236
1277
        """run should call result.stopTestRun()"""
1237
1278
        calls = []
 
1279
 
1238
1280
        class LoggingDecorator(ExtendedToOriginalDecorator):
1239
1281
            def stopTestRun(self):
1240
1282
                ExtendedToOriginalDecorator.stopTestRun(self)
1241
1283
                calls.append('stopTestRun')
1242
 
        test = unittest.FunctionTestCase(lambda:None)
 
1284
        test = unittest.FunctionTestCase(lambda: None)
1243
1285
        stream = StringIO()
1244
1286
        runner = tests.TextTestRunner(stream=stream,
1245
 
            result_decorators=[LoggingDecorator])
1246
 
        result = self.run_test_runner(runner, test)
 
1287
                                      result_decorators=[LoggingDecorator])
 
1288
        self.run_test_runner(runner, test)
1247
1289
        self.assertLength(1, calls)
1248
1290
 
1249
1291
    def test_unicode_test_output_on_ascii_stream(self):
1252
1294
            def test_log_unicode(self):
1253
1295
                self.log(u"\u2606")
1254
1296
                self.fail("Now print that log!")
1255
 
        out = StringIO()
 
1297
        bio = BytesIO()
 
1298
        out = TextIOWrapper(bio, 'ascii', 'backslashreplace')
1256
1299
        self.overrideAttr(osutils, "get_terminal_encoding",
1257
 
            lambda trace=False: "ascii")
1258
 
        result = self.run_test_runner(tests.TextTestRunner(stream=out),
 
1300
                          lambda trace=False: "ascii")
 
1301
        self.run_test_runner(
 
1302
            tests.TextTestRunner(stream=out),
1259
1303
            FailureWithUnicode("test_log_unicode"))
1260
 
        self.assertContainsRe(out.getvalue(),
1261
 
            "(?:Text attachment: )?log"
1262
 
            "(?:\n-+\n|: {{{)"
1263
 
            "\\d+\\.\\d+  \\\\u2606"
1264
 
            "(?:\n-+\n|}}}\n)")
 
1304
        out.flush()
 
1305
        self.assertContainsRe(bio.getvalue(),
 
1306
                              b"(?:Text attachment: )?log"
 
1307
                              b"(?:\n-+\n|: {{{)"
 
1308
                              b"\\d+\\.\\d+  \\\\u2606"
 
1309
                              b"(?:\n-+\n|}}}\n)")
1265
1310
 
1266
1311
 
1267
1312
class SampleTestCase(tests.TestCase):
1269
1314
    def _test_pass(self):
1270
1315
        pass
1271
1316
 
 
1317
 
1272
1318
class _TestException(Exception):
1273
1319
    pass
1274
1320
 
1291
1337
    def test_assertLength_shows_sequence_in_failure(self):
1292
1338
        a_list = [1, 2, 3]
1293
1339
        exception = self.assertRaises(AssertionError, self.assertLength, 2,
1294
 
            a_list)
 
1340
                                      a_list)
1295
1341
        self.assertEqual('Incorrect length: wanted 2, got 3 for [1, 2, 3]',
1296
 
            exception.args[0])
 
1342
                         exception.args[0])
1297
1343
 
1298
1344
    def test_base_setUp_not_called_causes_failure(self):
1299
1345
        class TestCaseWithBrokenSetUp(tests.TestCase):
1300
1346
            def setUp(self):
1301
 
                pass # does not call TestCase.setUp
 
1347
                pass  # does not call TestCase.setUp
 
1348
 
1302
1349
            def test_foo(self):
1303
1350
                pass
1304
1351
        test = TestCaseWithBrokenSetUp('test_foo')
1310
1357
    def test_base_tearDown_not_called_causes_failure(self):
1311
1358
        class TestCaseWithBrokenTearDown(tests.TestCase):
1312
1359
            def tearDown(self):
1313
 
                pass # does not call TestCase.tearDown
 
1360
                pass  # does not call TestCase.tearDown
 
1361
 
1314
1362
            def test_foo(self):
1315
1363
                pass
1316
1364
        test = TestCaseWithBrokenTearDown('test_foo')
1341
1389
        """
1342
1390
        self.change_selftest_debug_flags({'allow_debug'})
1343
1391
        breezy.debug.debug_flags = {'a-flag'}
 
1392
 
1344
1393
        class TestThatRecordsFlags(tests.TestCase):
1345
1394
            def test_foo(nested_self):
1346
1395
                self.flags = set(breezy.debug.debug_flags)
1391
1440
        self.change_selftest_debug_flags({'allow_debug'})
1392
1441
        # Now run a test that modifies debug.debug_flags.
1393
1442
        breezy.debug.debug_flags = {'original-state'}
 
1443
 
1394
1444
        class TestThatModifiesFlags(tests.TestCase):
1395
1445
            def test_foo(self):
1396
1446
                breezy.debug.debug_flags = {'modified'}
1439
1489
        self.time(time.sleep, 0.007)
1440
1490
 
1441
1491
    def test_time_creates_benchmark_in_result(self):
1442
 
        """Test that the TestCase.time() method accumulates a benchmark time."""
 
1492
        """The TestCase.time() method accumulates a benchmark time."""
1443
1493
        sample_test = TestTestCase("method_that_times_a_bit_twice")
1444
1494
        output_stream = StringIO()
1445
1495
        result = breezy.tests.VerboseTestResult(
1456
1506
        # Note this test won't fail with hooks that the core library doesn't
1457
1507
        # use - but it trigger with a plugin that adds hooks, so its still a
1458
1508
        # useful warning in that case.
1459
 
        self.assertEqual(breezy.branch.BranchHooks(), breezy.branch.Branch.hooks)
 
1509
        self.assertEqual(breezy.branch.BranchHooks(),
 
1510
                         breezy.branch.Branch.hooks)
1460
1511
        self.assertEqual(
1461
1512
            breezy.bzr.smart.server.SmartServerHooks(),
1462
1513
            breezy.bzr.smart.server.SmartTCPServer.hooks)
1486
1537
        self.assertRaises(tests.KnownFailure, self.knownFailure, "A Failure")
1487
1538
 
1488
1539
    def test_open_bzrdir_safe_roots(self):
1489
 
        # even a memory transport should fail to open when its url isn't 
 
1540
        # even a memory transport should fail to open when its url isn't
1490
1541
        # permitted.
1491
1542
        # Manually set one up (TestCase doesn't and shouldn't provide magic
1492
1543
        # machinery)
1496
1547
        t = transport.get_transport_from_url(transport_server.get_url())
1497
1548
        controldir.ControlDir.create(t.base)
1498
1549
        self.assertRaises(errors.BzrError,
1499
 
            controldir.ControlDir.open_from_transport, t)
 
1550
                          controldir.ControlDir.open_from_transport, t)
1500
1551
        # But if we declare this as safe, we can open the bzrdir.
1501
1552
        self.permit_url(t.base)
1502
1553
        self._bzr_selftest_roots.append(t.base)
1505
1556
    def test_requireFeature_available(self):
1506
1557
        """self.requireFeature(available) is a no-op."""
1507
1558
        class Available(features.Feature):
1508
 
            def _probe(self):return True
 
1559
            def _probe(self):
 
1560
                return True
1509
1561
        feature = Available()
1510
1562
        self.requireFeature(feature)
1511
1563
 
1512
1564
    def test_requireFeature_unavailable(self):
1513
1565
        """self.requireFeature(unavailable) raises UnavailableFeature."""
1514
1566
        class Unavailable(features.Feature):
1515
 
            def _probe(self):return False
 
1567
            def _probe(self):
 
1568
                return False
1516
1569
        feature = Unavailable()
1517
1570
        self.assertRaises(tests.UnavailableFeature,
1518
1571
                          self.requireFeature, feature)
1524
1577
    def test_run_enabled_unittest_result(self):
1525
1578
        """Test we revert to regular behaviour when the test is enabled."""
1526
1579
        test = SampleTestCase('_test_pass')
 
1580
 
1527
1581
        class EnabledFeature(object):
1528
1582
            def available(self):
1529
1583
                return True
1535
1589
        self.assertEqual([], result.failures)
1536
1590
 
1537
1591
    def test_run_disabled_unittest_result(self):
1538
 
        """Test our compatability for disabled tests with unittest results."""
 
1592
        """Test our compatibility for disabled tests with unittest results."""
1539
1593
        test = SampleTestCase('_test_pass')
 
1594
 
1540
1595
        class DisabledFeature(object):
1541
1596
            def available(self):
1542
1597
                return False
1550
1605
    def test_run_disabled_supporting_result(self):
1551
1606
        """Test disabled tests behaviour with support aware results."""
1552
1607
        test = SampleTestCase('_test_pass')
 
1608
 
1553
1609
        class DisabledFeature(object):
1554
1610
            def __eq__(self, other):
1555
1611
                return isinstance(other, DisabledFeature)
 
1612
 
1556
1613
            def available(self):
1557
1614
                return False
1558
1615
        the_feature = DisabledFeature()
1559
1616
        test._test_needs_features = [the_feature]
 
1617
 
1560
1618
        class InstrumentedTestResult(unittest.TestResult):
1561
1619
            def __init__(self):
1562
1620
                unittest.TestResult.__init__(self)
1563
1621
                self.calls = []
 
1622
 
1564
1623
            def startTest(self, test):
1565
1624
                self.calls.append(('startTest', test))
 
1625
 
1566
1626
            def stopTest(self, test):
1567
1627
                self.calls.append(('stopTest', test))
 
1628
 
1568
1629
            def addNotSupported(self, test, feature):
1569
1630
                self.calls.append(('addNotSupported', test, feature))
1570
1631
        result = InstrumentedTestResult()
1583
1644
        self.assertEqual([], self._bzr_selftest_roots)
1584
1645
        self.start_server(transport_server)
1585
1646
        self.assertSubset([transport_server.get_url()],
1586
 
            self._bzr_selftest_roots)
 
1647
                          self._bzr_selftest_roots)
1587
1648
 
1588
1649
    def test_assert_list_raises_on_generator(self):
1589
1650
        def generator_which_will_raise():
1621
1682
            raise _NotTestException()
1622
1683
 
1623
1684
        # Wrong exceptions are not intercepted
1624
 
        self.assertRaises(_NotTestException,
 
1685
        self.assertRaises(
 
1686
            _NotTestException,
1625
1687
            self.assertListRaises, _TestException, wrong_exception)
1626
 
        self.assertRaises(_NotTestException,
 
1688
        self.assertRaises(
 
1689
            _NotTestException,
1627
1690
            self.assertListRaises, _TestException, wrong_exception_generator)
1628
1691
 
1629
1692
    def test_assert_list_raises_no_exception(self):
1635
1698
            yield 2
1636
1699
 
1637
1700
        self.assertRaises(AssertionError,
1638
 
            self.assertListRaises, _TestException, success)
 
1701
                          self.assertListRaises, _TestException, success)
1639
1702
 
1640
 
        self.assertRaises(AssertionError,
 
1703
        self.assertRaises(
 
1704
            AssertionError,
1641
1705
            self.assertListRaises, _TestException, success_generator)
1642
1706
 
1643
1707
    def _run_successful_test(self, test):
1647
1711
        return result
1648
1712
 
1649
1713
    def test_overrideAttr_without_value(self):
1650
 
        self.test_attr = 'original' # Define a test attribute
1651
 
        obj = self # Make 'obj' visible to the embedded test
 
1714
        self.test_attr = 'original'  # Define a test attribute
 
1715
        obj = self  # Make 'obj' visible to the embedded test
 
1716
 
1652
1717
        class Test(tests.TestCase):
1653
1718
 
1654
1719
            def setUp(self):
1665
1730
        self.assertEqual('original', obj.test_attr)
1666
1731
 
1667
1732
    def test_overrideAttr_with_value(self):
1668
 
        self.test_attr = 'original' # Define a test attribute
1669
 
        obj = self # Make 'obj' visible to the embedded test
 
1733
        self.test_attr = 'original'  # Define a test attribute
 
1734
        obj = self  # Make 'obj' visible to the embedded test
 
1735
 
1670
1736
        class Test(tests.TestCase):
1671
1737
 
1672
1738
            def setUp(self):
1682
1748
 
1683
1749
    def test_overrideAttr_with_no_existing_value_and_value(self):
1684
1750
        # Do not define the test_attribute
1685
 
        obj = self # Make 'obj' visible to the embedded test
 
1751
        obj = self  # Make 'obj' visible to the embedded test
 
1752
 
1686
1753
        class Test(tests.TestCase):
1687
1754
 
1688
1755
            def setUp(self):
1698
1765
 
1699
1766
    def test_overrideAttr_with_no_existing_value_and_no_value(self):
1700
1767
        # Do not define the test_attribute
1701
 
        obj = self # Make 'obj' visible to the embedded test
 
1768
        obj = self  # Make 'obj' visible to the embedded test
 
1769
 
1702
1770
        class Test(tests.TestCase):
1703
1771
 
1704
1772
            def setUp(self):
1717
1785
        calls = self.recordCalls(
1718
1786
            test_selftest, '_add_numbers')
1719
1787
        self.assertEqual(test_selftest._add_numbers(2, 10),
1720
 
            12)
 
1788
                         12)
1721
1789
        self.assertEqual(calls, [((2, 10), {})])
1722
1790
 
1723
1791
 
1728
1796
class _MissingFeature(features.Feature):
1729
1797
    def _probe(self):
1730
1798
        return False
 
1799
 
 
1800
 
1731
1801
missing_feature = _MissingFeature()
1732
1802
 
1733
1803
 
1770
1840
    return ExampleTests(name)
1771
1841
 
1772
1842
 
1773
 
def _get_skip_reasons(result):
1774
 
    # GZ 2017-06-06: Newer testtools doesn't have this, uses detail instead
1775
 
    return result.skip_reasons
1776
 
 
1777
 
 
1778
1843
class TestTestCaseLogDetails(tests.TestCase):
1779
1844
 
1780
1845
    def _run_test(self, test_name):
1788
1853
        self.assertEqual(1, len(result.failures))
1789
1854
        result_content = result.failures[0][1]
1790
1855
        self.assertContainsRe(result_content,
1791
 
            '(?m)^(?:Text attachment: )?log(?:$|: )')
 
1856
                              '(?m)^(?:Text attachment: )?log(?:$|: )')
1792
1857
        self.assertContainsRe(result_content, 'this was a failing test')
1793
1858
 
1794
1859
    def test_error_has_log(self):
1796
1861
        self.assertEqual(1, len(result.errors))
1797
1862
        result_content = result.errors[0][1]
1798
1863
        self.assertContainsRe(result_content,
1799
 
            '(?m)^(?:Text attachment: )?log(?:$|: )')
 
1864
                              '(?m)^(?:Text attachment: )?log(?:$|: )')
1800
1865
        self.assertContainsRe(result_content, 'this test errored')
1801
1866
 
1802
1867
    def test_skip_has_no_log(self):
1803
1868
        result = self._run_test('test_skip')
1804
 
        reasons = _get_skip_reasons(result)
 
1869
        reasons = result.skip_reasons
1805
1870
        self.assertEqual({'reason'}, set(reasons))
1806
1871
        skips = reasons['reason']
1807
1872
        self.assertEqual(1, len(skips))
1812
1877
        # testtools doesn't know about addNotSupported, so it just gets
1813
1878
        # considered as a skip
1814
1879
        result = self._run_test('test_missing_feature')
1815
 
        reasons = _get_skip_reasons(result)
 
1880
        reasons = result.skip_reasons
1816
1881
        self.assertEqual({str(missing_feature)}, set(reasons))
1817
1882
        skips = reasons[str(missing_feature)]
1818
1883
        self.assertEqual(1, len(skips))
1824
1889
        self.assertEqual(1, len(result.expectedFailures))
1825
1890
        result_content = result.expectedFailures[0][1]
1826
1891
        self.assertNotContainsRe(result_content,
1827
 
            '(?m)^(?:Text attachment: )?log(?:$|: )')
 
1892
                                 '(?m)^(?:Text attachment: )?log(?:$|: )')
1828
1893
        self.assertNotContainsRe(result_content, 'test with expected failure')
1829
1894
 
1830
1895
    def test_unexpected_success_has_log(self):
1903
1968
 
1904
1969
    def test_assert_isinstance(self):
1905
1970
        self.assertIsInstance(2, int)
1906
 
        self.assertIsInstance(u'', (str, text_type))
 
1971
        self.assertIsInstance(u'', str)
1907
1972
        e = self.assertRaises(AssertionError, self.assertIsInstance, None, int)
1908
 
        self.assertEqual(str(e),
1909
 
            "None is an instance of <type 'NoneType'> rather than <type 'int'>")
 
1973
        self.assertIn(
 
1974
            str(e),
 
1975
            ["None is an instance of <type 'NoneType'> rather than "
 
1976
             "<type 'int'>",
 
1977
             "None is an instance of <class 'NoneType'> rather than "
 
1978
             "<class 'int'>"])
1910
1979
        self.assertRaises(AssertionError, self.assertIsInstance, 23.3, int)
1911
1980
        e = self.assertRaises(AssertionError,
1912
 
            self.assertIsInstance, None, int, "it's just not")
1913
 
        self.assertEqual(str(e),
1914
 
            "None is an instance of <type 'NoneType'> rather than <type 'int'>"
1915
 
            ": it's just not")
 
1981
                              self.assertIsInstance, None, int,
 
1982
                              "it's just not")
 
1983
        self.assertEqual(
 
1984
            str(e),
 
1985
            "None is an instance of <class 'NoneType'> rather "
 
1986
            "than <class 'int'>: it's just not")
1916
1987
 
1917
1988
    def test_assertEndsWith(self):
1918
1989
        self.assertEndsWith('foo', 'oo')
1922
1993
        e = self.assertRaises(AssertionError,
1923
1994
                              self.assertEqualDiff, '', '\n')
1924
1995
        self.assertEqual(str(e),
1925
 
                          # Don't blink ! The '+' applies to the second string
1926
 
                          'first string is missing a final newline.\n+ \n')
 
1996
                         # Don't blink ! The '+' applies to the second string
 
1997
                         'first string is missing a final newline.\n+ \n')
1927
1998
        e = self.assertRaises(AssertionError,
1928
1999
                              self.assertEqualDiff, '\n', '')
1929
2000
        self.assertEqual(str(e),
1930
 
                          # Don't blink ! The '-' applies to the second string
1931
 
                          'second string is missing a final newline.\n- \n')
 
2001
                         # Don't blink ! The '-' applies to the second string
 
2002
                         'second string is missing a final newline.\n- \n')
1932
2003
 
1933
2004
 
1934
2005
class TestDeprecations(tests.TestCase):
1937
2008
        sample_object = ApplyDeprecatedHelper()
1938
2009
        # calling an undeprecated callable raises an assertion
1939
2010
        self.assertRaises(AssertionError, self.applyDeprecated,
1940
 
            deprecated_in((0, 11, 0)),
1941
 
            sample_object.sample_normal_method)
 
2011
                          deprecated_in((0, 11, 0)),
 
2012
                          sample_object.sample_normal_method)
1942
2013
        self.assertRaises(AssertionError, self.applyDeprecated,
1943
 
            deprecated_in((0, 11, 0)),
1944
 
            sample_undeprecated_function, "a param value")
 
2014
                          deprecated_in((0, 11, 0)),
 
2015
                          sample_undeprecated_function, "a param value")
1945
2016
        # calling a deprecated callable (function or method) with the wrong
1946
2017
        # expected deprecation fails.
1947
2018
        self.assertRaises(AssertionError, self.applyDeprecated,
1948
 
            deprecated_in((0, 10, 0)),
1949
 
            sample_object.sample_deprecated_method, "a param value")
 
2019
                          deprecated_in((0, 10, 0)),
 
2020
                          sample_object.sample_deprecated_method,
 
2021
                          "a param value")
1950
2022
        self.assertRaises(AssertionError, self.applyDeprecated,
1951
 
            deprecated_in((0, 10, 0)),
1952
 
            sample_deprecated_function)
 
2023
                          deprecated_in((0, 10, 0)),
 
2024
                          sample_deprecated_function)
1953
2025
        # calling a deprecated callable (function or method) with the right
1954
2026
        # expected deprecation returns the functions result.
1955
 
        self.assertEqual("a param value",
1956
 
            self.applyDeprecated(deprecated_in((0, 11, 0)),
1957
 
            sample_object.sample_deprecated_method, "a param value"))
 
2027
        self.assertEqual(
 
2028
            "a param value",
 
2029
            self.applyDeprecated(
 
2030
                deprecated_in((0, 11, 0)),
 
2031
                sample_object.sample_deprecated_method, "a param value"))
1958
2032
        self.assertEqual(2, self.applyDeprecated(deprecated_in((0, 11, 0)),
1959
 
            sample_deprecated_function))
 
2033
                                                 sample_deprecated_function))
1960
2034
        # calling a nested deprecation with the wrong deprecation version
1961
2035
        # fails even if a deeper nested function was deprecated with the
1962
2036
        # supplied version.
1963
 
        self.assertRaises(AssertionError, self.applyDeprecated,
 
2037
        self.assertRaises(
 
2038
            AssertionError, self.applyDeprecated,
1964
2039
            deprecated_in((0, 11, 0)), sample_object.sample_nested_deprecation)
1965
2040
        # calling a nested deprecation with the right deprecation value
1966
2041
        # returns the calls result.
1967
 
        self.assertEqual(2, self.applyDeprecated(deprecated_in((0, 10, 0)),
1968
 
            sample_object.sample_nested_deprecation))
 
2042
        self.assertEqual(
 
2043
            2, self.applyDeprecated(
 
2044
                deprecated_in((0, 10, 0)),
 
2045
                sample_object.sample_nested_deprecation))
1969
2046
 
1970
2047
    def test_callDeprecated(self):
1971
2048
        def testfunc(be_deprecated, result=None):
2002
2079
 
2003
2080
    def test_make_branch_and_tree_with_format(self):
2004
2081
        # we should be able to supply a format to make_branch_and_tree
2005
 
        self.make_branch_and_tree('a', format=breezy.bzr.bzrdir.BzrDirMetaFormat1())
 
2082
        self.make_branch_and_tree(
 
2083
            'a', format=breezy.bzr.bzrdir.BzrDirMetaFormat1())
2006
2084
        self.assertIsInstance(breezy.controldir.ControlDir.open('a')._format,
2007
2085
                              breezy.bzr.bzrdir.BzrDirMetaFormat1)
2008
2086
 
2022
2100
        base = tree.controldir.root_transport.base
2023
2101
        self.assertStartsWith(base, 'file://')
2024
2102
        self.assertEqual(tree.controldir.root_transport,
2025
 
                tree.branch.controldir.root_transport)
 
2103
                         tree.branch.controldir.root_transport)
2026
2104
        self.assertEqual(tree.controldir.root_transport,
2027
 
                tree.branch.repository.controldir.root_transport)
 
2105
                         tree.branch.repository.controldir.root_transport)
2028
2106
 
2029
2107
 
2030
2108
class SelfTestHelper(object):
2031
2109
 
2032
2110
    def run_selftest(self, **kwargs):
2033
2111
        """Run selftest returning its output."""
2034
 
        output = StringIO()
 
2112
        bio = BytesIO()
 
2113
        output = TextIOWrapper(bio, 'utf-8')
2035
2114
        old_transport = breezy.tests.default_transport
2036
2115
        old_root = tests.TestCaseWithMemoryTransport.TEST_ROOT
2037
2116
        tests.TestCaseWithMemoryTransport.TEST_ROOT = None
2040
2119
        finally:
2041
2120
            breezy.tests.default_transport = old_transport
2042
2121
            tests.TestCaseWithMemoryTransport.TEST_ROOT = old_root
2043
 
        output.seek(0)
2044
 
        return output
 
2122
        output.flush()
 
2123
        output.detach()
 
2124
        bio.seek(0)
 
2125
        return bio
2045
2126
 
2046
2127
 
2047
2128
class TestSelftest(tests.TestCase, SelfTestHelper):
2048
2129
    """Tests of breezy.tests.selftest."""
2049
2130
 
2050
 
    def test_selftest_benchmark_parameter_invokes_test_suite__benchmark__(self):
 
2131
    def test_selftest_benchmark_parameter_invokes_test_suite__benchmark__(
 
2132
            self):
2051
2133
        factory_called = []
 
2134
 
2052
2135
        def factory():
2053
2136
            factory_called.append(True)
2054
2137
            return TestUtil.TestSuite()
2055
2138
        out = StringIO()
2056
2139
        err = StringIO()
2057
2140
        self.apply_redirected(out, err, None, breezy.tests.selftest,
2058
 
            test_suite_factory=factory)
 
2141
                              test_suite_factory=factory)
2059
2142
        self.assertEqual([True], factory_called)
2060
2143
 
2061
2144
    def factory(self):
2062
2145
        """A test suite factory."""
2063
2146
        class Test(tests.TestCase):
 
2147
            def id(self):
 
2148
                return __name__ + ".Test." + self._testMethodName
 
2149
 
2064
2150
            def a(self):
2065
2151
                pass
 
2152
 
2066
2153
            def b(self):
2067
2154
                pass
2068
 
            def c(self):
 
2155
 
 
2156
            def c(telf):
2069
2157
                pass
2070
2158
        return TestUtil.TestSuite([Test("a"), Test("b"), Test("c")])
2071
2159
 
2072
2160
    def test_list_only(self):
2073
2161
        output = self.run_selftest(test_suite_factory=self.factory,
2074
 
            list_only=True)
 
2162
                                   list_only=True)
2075
2163
        self.assertEqual(3, len(output.readlines()))
2076
2164
 
2077
2165
    def test_list_only_filtered(self):
2078
2166
        output = self.run_selftest(test_suite_factory=self.factory,
2079
 
            list_only=True, pattern="Test.b")
2080
 
        self.assertEndsWith(output.getvalue(), "Test.b\n")
 
2167
                                   list_only=True, pattern="Test.b")
 
2168
        self.assertEndsWith(output.getvalue(), b"Test.b\n")
2081
2169
        self.assertLength(1, output.readlines())
2082
2170
 
2083
2171
    def test_list_only_excludes(self):
2084
2172
        output = self.run_selftest(test_suite_factory=self.factory,
2085
 
            list_only=True, exclude_pattern="Test.b")
2086
 
        self.assertNotContainsRe("Test.b", output.getvalue())
 
2173
                                   list_only=True, exclude_pattern="Test.b")
 
2174
        self.assertNotContainsRe(b"Test.b", output.getvalue())
2087
2175
        self.assertLength(2, output.readlines())
2088
2176
 
2089
2177
    def test_lsprof_tests(self):
2090
2178
        self.requireFeature(features.lsprof_feature)
2091
2179
        results = []
 
2180
 
2092
2181
        class Test(object):
2093
2182
            def __call__(test, result):
2094
2183
                test.run(result)
 
2184
 
2095
2185
            def run(test, result):
2096
2186
                results.append(result)
 
2187
 
2097
2188
            def countTestCases(self):
2098
2189
                return 1
2099
2190
        self.run_selftest(test_suite_factory=Test, lsprof_tests=True)
2103
2194
    def test_random(self):
2104
2195
        # test randomising by listing a number of tests.
2105
2196
        output_123 = self.run_selftest(test_suite_factory=self.factory,
2106
 
            list_only=True, random_seed="123")
 
2197
                                       list_only=True, random_seed="123")
2107
2198
        output_234 = self.run_selftest(test_suite_factory=self.factory,
2108
 
            list_only=True, random_seed="234")
 
2199
                                       list_only=True, random_seed="234")
2109
2200
        self.assertNotEqual(output_123, output_234)
2110
2201
        # "Randominzing test order..\n\n
2111
2202
        self.assertLength(5, output_123.readlines())
2114
2205
    def test_random_reuse_is_same_order(self):
2115
2206
        # test randomising by listing a number of tests.
2116
2207
        expected = self.run_selftest(test_suite_factory=self.factory,
2117
 
            list_only=True, random_seed="123")
 
2208
                                     list_only=True, random_seed="123")
2118
2209
        repeated = self.run_selftest(test_suite_factory=self.factory,
2119
 
            list_only=True, random_seed="123")
 
2210
                                     list_only=True, random_seed="123")
2120
2211
        self.assertEqual(expected.getvalue(), repeated.getvalue())
2121
2212
 
2122
2213
    def test_runner_class(self):
2132
2223
 
2133
2224
    def test_starting_with_single_argument(self):
2134
2225
        output = self.run_selftest(test_suite_factory=self.factory,
2135
 
            starting_with=['breezy.tests.test_selftest.Test.a'],
2136
 
            list_only=True)
2137
 
        self.assertEqual('breezy.tests.test_selftest.Test.a\n',
2138
 
            output.getvalue())
 
2226
                                   starting_with=[
 
2227
                                       'breezy.tests.test_selftest.Test.a'],
 
2228
                                   list_only=True)
 
2229
        self.assertEqual(b'breezy.tests.test_selftest.Test.a\n',
 
2230
                         output.getvalue())
2139
2231
 
2140
2232
    def test_starting_with_multiple_argument(self):
2141
 
        output = self.run_selftest(test_suite_factory=self.factory,
 
2233
        output = self.run_selftest(
 
2234
            test_suite_factory=self.factory,
2142
2235
            starting_with=['breezy.tests.test_selftest.Test.a',
2143
 
                'breezy.tests.test_selftest.Test.b'],
 
2236
                           'breezy.tests.test_selftest.Test.b'],
2144
2237
            list_only=True)
2145
 
        self.assertEqual('breezy.tests.test_selftest.Test.a\n'
2146
 
            'breezy.tests.test_selftest.Test.b\n',
2147
 
            output.getvalue())
 
2238
        self.assertEqual(b'breezy.tests.test_selftest.Test.a\n'
 
2239
                         b'breezy.tests.test_selftest.Test.b\n',
 
2240
                         output.getvalue())
2148
2241
 
2149
2242
    def check_transport_set(self, transport_server):
2150
2243
        captured_transport = []
 
2244
 
2151
2245
        def seen_transport(a_transport):
2152
2246
            captured_transport.append(a_transport)
 
2247
 
2153
2248
        class Capture(tests.TestCase):
2154
2249
            def a(self):
2155
2250
                seen_transport(breezy.tests.default_transport)
 
2251
 
2156
2252
        def factory():
2157
2253
            return TestUtil.TestSuite([Capture("a")])
2158
 
        self.run_selftest(transport=transport_server, test_suite_factory=factory)
 
2254
        self.run_selftest(transport=transport_server,
 
2255
                          test_suite_factory=factory)
2159
2256
        self.assertEqual(transport_server, captured_transport[0])
2160
2257
 
2161
2258
    def test_transport_sftp(self):
2172
2269
 
2173
2270
    def test_load_list(self):
2174
2271
        # Provide a list with one test - this test.
2175
 
        test_id_line = '%s\n' % self.id()
 
2272
        test_id_line = b'%s\n' % self.id().encode('ascii')
2176
2273
        self.build_tree_contents([('test.list', test_id_line)])
2177
2274
        # And generate a list of the tests in  the suite.
2178
2275
        stream = self.run_selftest(load_list='test.list', list_only=True)
2181
2278
    def test_load_unknown(self):
2182
2279
        # Provide a list with one test - this test.
2183
2280
        # And generate a list of the tests in  the suite.
2184
 
        err = self.assertRaises(errors.NoSuchFile, self.run_selftest,
2185
 
            load_list='missing file name', list_only=True)
 
2281
        self.assertRaises(errors.NoSuchFile, self.run_selftest,
 
2282
                          load_list='missing file name', list_only=True)
2186
2283
 
2187
2284
 
2188
2285
class TestSubunitLogDetails(tests.TestCase, SelfTestHelper):
2191
2288
 
2192
2289
    def run_subunit_stream(self, test_name):
2193
2290
        from subunit import ProtocolTestCase
 
2291
 
2194
2292
        def factory():
2195
2293
            return TestUtil.TestSuite([_get_test(test_name)])
2196
2294
        stream = self.run_selftest(
2205
2303
    def test_fail_has_log(self):
2206
2304
        content, result = self.run_subunit_stream('test_fail')
2207
2305
        self.assertEqual(1, len(result.failures))
2208
 
        self.assertContainsRe(content, '(?m)^log$')
2209
 
        self.assertContainsRe(content, 'this test will fail')
 
2306
        self.assertContainsRe(content, b'(?m)^log$')
 
2307
        self.assertContainsRe(content, b'this test will fail')
2210
2308
 
2211
2309
    def test_error_has_log(self):
2212
2310
        content, result = self.run_subunit_stream('test_error')
2213
 
        self.assertContainsRe(content, '(?m)^log$')
2214
 
        self.assertContainsRe(content, 'this test errored')
 
2311
        self.assertContainsRe(content, b'(?m)^log$')
 
2312
        self.assertContainsRe(content, b'this test errored')
2215
2313
 
2216
2314
    def test_skip_has_no_log(self):
2217
2315
        content, result = self.run_subunit_stream('test_skip')
2218
 
        self.assertNotContainsRe(content, '(?m)^log$')
2219
 
        self.assertNotContainsRe(content, 'this test will be skipped')
2220
 
        reasons = _get_skip_reasons(result)
 
2316
        self.assertNotContainsRe(content, b'(?m)^log$')
 
2317
        self.assertNotContainsRe(content, b'this test will be skipped')
 
2318
        reasons = result.skip_reasons
2221
2319
        self.assertEqual({'reason'}, set(reasons))
2222
2320
        skips = reasons['reason']
2223
2321
        self.assertEqual(1, len(skips))
2224
 
        test = skips[0]
 
2322
        # test = skips[0]
2225
2323
        # RemotedTestCase doesn't preserve the "details"
2226
 
        ## self.assertFalse('log' in test.getDetails())
 
2324
        # self.assertFalse('log' in test.getDetails())
2227
2325
 
2228
2326
    def test_missing_feature_has_no_log(self):
2229
2327
        content, result = self.run_subunit_stream('test_missing_feature')
2230
 
        self.assertNotContainsRe(content, '(?m)^log$')
2231
 
        self.assertNotContainsRe(content, 'missing the feature')
2232
 
        reasons = _get_skip_reasons(result)
 
2328
        self.assertNotContainsRe(content, b'(?m)^log$')
 
2329
        self.assertNotContainsRe(content, b'missing the feature')
 
2330
        reasons = result.skip_reasons
2233
2331
        self.assertEqual({'_MissingFeature\n'}, set(reasons))
2234
2332
        skips = reasons['_MissingFeature\n']
2235
2333
        self.assertEqual(1, len(skips))
2236
 
        test = skips[0]
 
2334
        # test = skips[0]
2237
2335
        # RemotedTestCase doesn't preserve the "details"
2238
 
        ## self.assertFalse('log' in test.getDetails())
 
2336
        # self.assertFalse('log' in test.getDetails())
2239
2337
 
2240
2338
    def test_xfail_has_no_log(self):
2241
2339
        content, result = self.run_subunit_stream('test_xfail')
2242
 
        self.assertNotContainsRe(content, '(?m)^log$')
2243
 
        self.assertNotContainsRe(content, 'test with expected failure')
 
2340
        self.assertNotContainsRe(content, b'(?m)^log$')
 
2341
        self.assertNotContainsRe(content, b'test with expected failure')
2244
2342
        self.assertEqual(1, len(result.expectedFailures))
2245
2343
        result_content = result.expectedFailures[0][1]
2246
2344
        self.assertNotContainsRe(result_content,
2247
 
            '(?m)^(?:Text attachment: )?log(?:$|: )')
 
2345
                                 '(?m)^(?:Text attachment: )?log(?:$|: )')
2248
2346
        self.assertNotContainsRe(result_content, 'test with expected failure')
2249
2347
 
2250
2348
    def test_unexpected_success_has_log(self):
2251
2349
        content, result = self.run_subunit_stream('test_unexpected_success')
2252
 
        self.assertContainsRe(content, '(?m)^log$')
2253
 
        self.assertContainsRe(content, 'test with unexpected success')
2254
 
        # GZ 2011-05-18: Old versions of subunit treat unexpected success as a
2255
 
        #                success, if a min version check is added remove this
2256
 
        from subunit import TestProtocolClient as _Client
2257
 
        if _Client.addUnexpectedSuccess.__func__ is _Client.addSuccess.__func__:
2258
 
            self.expectFailure('subunit treats "unexpectedSuccess"'
2259
 
                               ' as a plain success',
2260
 
                self.assertEqual, 1, len(result.unexpectedSuccesses))
 
2350
        self.assertContainsRe(content, b'(?m)^log$')
 
2351
        self.assertContainsRe(content, b'test with unexpected success')
2261
2352
        self.assertEqual(1, len(result.unexpectedSuccesses))
2262
 
        test = result.unexpectedSuccesses[0]
 
2353
        # test = result.unexpectedSuccesses[0]
2263
2354
        # RemotedTestCase doesn't preserve the "details"
2264
 
        ## self.assertTrue('log' in test.getDetails())
 
2355
        # self.assertTrue('log' in test.getDetails())
2265
2356
 
2266
2357
    def test_success_has_no_log(self):
2267
2358
        content, result = self.run_subunit_stream('test_success')
2268
2359
        self.assertEqual(1, result.testsRun)
2269
 
        self.assertNotContainsRe(content, '(?m)^log$')
2270
 
        self.assertNotContainsRe(content, 'this test succeeds')
 
2360
        self.assertNotContainsRe(content, b'(?m)^log$')
 
2361
        self.assertNotContainsRe(content, b'this test succeeds')
2271
2362
 
2272
2363
 
2273
2364
class TestRunBzr(tests.TestCase):
2274
2365
 
 
2366
    result = 0
2275
2367
    out = ''
2276
2368
    err = ''
2277
2369
 
2278
 
    def _run_bzr_core(self, argv, retcode=0, encoding=None, stdin=None,
2279
 
                         working_dir=None):
 
2370
    def _run_bzr_core(self, argv, encoding=None, stdin=None,
 
2371
                      stdout=None, stderr=None, working_dir=None):
2280
2372
        """Override _run_bzr_core to test how it is invoked by run_bzr.
2281
2373
 
2282
2374
        Attempts to run bzr from inside this class don't actually run it.
2285
2377
        only need to test that it passes the right parameters to run_bzr.
2286
2378
        """
2287
2379
        self.argv = list(argv)
2288
 
        self.retcode = retcode
2289
2380
        self.encoding = encoding
2290
2381
        self.stdin = stdin
2291
2382
        self.working_dir = working_dir
2292
 
        return self.retcode, self.out, self.err
 
2383
        stdout.write(self.out)
 
2384
        stderr.write(self.err)
 
2385
        return self.result
2293
2386
 
2294
2387
    def test_run_bzr_error(self):
2295
2388
        self.out = "It sure does!\n"
 
2389
        self.result = 34
2296
2390
        out, err = self.run_bzr_error(['^$'], ['rocks'], retcode=34)
2297
2391
        self.assertEqual(['rocks'], self.argv)
2298
 
        self.assertEqual(34, self.retcode)
2299
2392
        self.assertEqual('It sure does!\n', out)
2300
2393
        self.assertEqual(out, self.out)
2301
2394
        self.assertEqual('', err)
2304
2397
    def test_run_bzr_error_regexes(self):
2305
2398
        self.out = ''
2306
2399
        self.err = "bzr: ERROR: foobarbaz is not versioned"
 
2400
        self.result = 3
2307
2401
        out, err = self.run_bzr_error(
2308
2402
            ["bzr: ERROR: foobarbaz is not versioned"],
2309
2403
            ['file-id', 'foobarbaz'])
2311
2405
    def test_encoding(self):
2312
2406
        """Test that run_bzr passes encoding to _run_bzr_core"""
2313
2407
        self.run_bzr('foo bar')
2314
 
        self.assertEqual(None, self.encoding)
 
2408
        self.assertEqual(osutils.get_user_encoding(), self.encoding)
2315
2409
        self.assertEqual(['foo', 'bar'], self.argv)
2316
2410
 
2317
2411
        self.run_bzr('foo bar', encoding='baz')
2318
2412
        self.assertEqual('baz', self.encoding)
2319
2413
        self.assertEqual(['foo', 'bar'], self.argv)
2320
2414
 
2321
 
    def test_retcode(self):
2322
 
        """Test that run_bzr passes retcode to _run_bzr_core"""
2323
 
        # Default is retcode == 0
2324
 
        self.run_bzr('foo bar')
2325
 
        self.assertEqual(0, self.retcode)
2326
 
        self.assertEqual(['foo', 'bar'], self.argv)
2327
 
 
2328
 
        self.run_bzr('foo bar', retcode=1)
2329
 
        self.assertEqual(1, self.retcode)
2330
 
        self.assertEqual(['foo', 'bar'], self.argv)
2331
 
 
2332
 
        self.run_bzr('foo bar', retcode=None)
2333
 
        self.assertEqual(None, self.retcode)
2334
 
        self.assertEqual(['foo', 'bar'], self.argv)
2335
 
 
2336
 
        self.run_bzr(['foo', 'bar'], retcode=3)
2337
 
        self.assertEqual(3, self.retcode)
2338
 
        self.assertEqual(['foo', 'bar'], self.argv)
2339
 
 
2340
2415
    def test_stdin(self):
2341
2416
        # test that the stdin keyword to run_bzr is passed through to
2342
2417
        # _run_bzr_core as-is. We do this by overriding
2431
2506
 
2432
2507
class StubProcess(object):
2433
2508
    """A stub process for testing run_bzr_subprocess."""
2434
 
    
 
2509
 
2435
2510
    def __init__(self, out="", err="", retcode=0):
2436
2511
        self.out = out
2437
2512
        self.err = err
2453
2528
                             working_dir=None,
2454
2529
                             allow_plugins=False):
2455
2530
        """capture what run_bzr_subprocess tries to do."""
2456
 
        self.subprocess_calls.append({'process_args':process_args,
2457
 
            'env_changes':env_changes,
2458
 
            'skip_if_plan_to_signal':skip_if_plan_to_signal,
2459
 
            'working_dir':working_dir, 'allow_plugins':allow_plugins})
 
2531
        self.subprocess_calls.append(
 
2532
            {'process_args': process_args,
 
2533
             'env_changes': env_changes,
 
2534
             'skip_if_plan_to_signal': skip_if_plan_to_signal,
 
2535
             'working_dir': working_dir, 'allow_plugins': allow_plugins})
2460
2536
        return self.next_subprocess
2461
2537
 
2462
2538
 
2472
2548
        self.next_subprocess = process
2473
2549
        try:
2474
2550
            result = self.run_bzr_subprocess(*args, **kwargs)
2475
 
        except:
 
2551
        except BaseException:
2476
2552
            self.next_subprocess = None
2477
2553
            for key, expected in expected_args.items():
2478
2554
                self.assertEqual(expected, self.subprocess_calls[-1][key])
2485
2561
 
2486
2562
    def test_run_bzr_subprocess(self):
2487
2563
        """The run_bzr_helper_external command behaves nicely."""
2488
 
        self.assertRunBzrSubprocess({'process_args':['--version']},
2489
 
            StubProcess(), '--version')
2490
 
        self.assertRunBzrSubprocess({'process_args':['--version']},
2491
 
            StubProcess(), ['--version'])
 
2564
        self.assertRunBzrSubprocess({'process_args': ['--version']},
 
2565
                                    StubProcess(), '--version')
 
2566
        self.assertRunBzrSubprocess({'process_args': ['--version']},
 
2567
                                    StubProcess(), ['--version'])
2492
2568
        # retcode=None disables retcode checking
2493
 
        result = self.assertRunBzrSubprocess({},
2494
 
            StubProcess(retcode=3), '--version', retcode=None)
2495
 
        result = self.assertRunBzrSubprocess({},
2496
 
            StubProcess(out="is free software"), '--version')
 
2569
        result = self.assertRunBzrSubprocess(
 
2570
            {}, StubProcess(retcode=3), '--version', retcode=None)
 
2571
        result = self.assertRunBzrSubprocess(
 
2572
            {}, StubProcess(out="is free software"), '--version')
2497
2573
        self.assertContainsRe(result[0], 'is free software')
2498
2574
        # Running a subcommand that is missing errors
2499
2575
        self.assertRaises(AssertionError, self.assertRunBzrSubprocess,
2500
 
            {'process_args':['--versionn']}, StubProcess(retcode=3),
2501
 
            '--versionn')
 
2576
                          {'process_args': ['--versionn']
 
2577
                           }, StubProcess(retcode=3),
 
2578
                          '--versionn')
2502
2579
        # Unless it is told to expect the error from the subprocess
2503
 
        result = self.assertRunBzrSubprocess({},
2504
 
            StubProcess(retcode=3), '--versionn', retcode=3)
 
2580
        result = self.assertRunBzrSubprocess(
 
2581
            {}, StubProcess(retcode=3), '--versionn', retcode=3)
2505
2582
        # Or to ignore retcode checking
2506
 
        result = self.assertRunBzrSubprocess({},
2507
 
            StubProcess(err="unknown command", retcode=3), '--versionn',
2508
 
            retcode=None)
 
2583
        result = self.assertRunBzrSubprocess(
 
2584
            {}, StubProcess(err="unknown command", retcode=3),
 
2585
            '--versionn', retcode=None)
2509
2586
        self.assertContainsRe(result[1], 'unknown command')
2510
2587
 
2511
2588
    def test_env_change_passes_through(self):
2512
2589
        self.assertRunBzrSubprocess(
2513
 
            {'env_changes':{'new':'value', 'changed':'newvalue', 'deleted':None}},
 
2590
            {'env_changes': {'new': 'value', 'changed': 'newvalue', 'deleted': None}},
2514
2591
            StubProcess(), '',
2515
 
            env_changes={'new':'value', 'changed':'newvalue', 'deleted':None})
 
2592
            env_changes={'new': 'value', 'changed': 'newvalue', 'deleted': None})
2516
2593
 
2517
2594
    def test_no_working_dir_passed_as_None(self):
2518
2595
        self.assertRunBzrSubprocess({'working_dir': None}, StubProcess(), '')
2519
2596
 
2520
2597
    def test_no_working_dir_passed_through(self):
2521
2598
        self.assertRunBzrSubprocess({'working_dir': 'dir'}, StubProcess(), '',
2522
 
            working_dir='dir')
 
2599
                                    working_dir='dir')
2523
2600
 
2524
2601
    def test_run_bzr_subprocess_no_plugins(self):
2525
2602
        self.assertRunBzrSubprocess({'allow_plugins': False},
2526
 
            StubProcess(), '')
 
2603
                                    StubProcess(), '')
2527
2604
 
2528
2605
    def test_allow_plugins(self):
2529
2606
        self.assertRunBzrSubprocess({'allow_plugins': True},
2530
 
            StubProcess(), '', allow_plugins=True)
 
2607
                                    StubProcess(), '', allow_plugins=True)
2531
2608
 
2532
2609
 
2533
2610
class TestFinishBzrSubprocess(TestWithFakedStartBzrSubprocess):
2595
2672
    def test_set_env(self):
2596
2673
        self.assertFalse('EXISTANT_ENV_VAR' in os.environ)
2597
2674
        # set in the child
 
2675
 
2598
2676
        def check_environment():
2599
2677
            self.assertEqual('set variable', os.environ['EXISTANT_ENV_VAR'])
2600
2678
        self.check_popen_state = check_environment
2601
2679
        self.assertRaises(_DontSpawnProcess, self.start_bzr_subprocess, [],
2602
 
                          env_changes={'EXISTANT_ENV_VAR':'set variable'})
 
2680
                          env_changes={'EXISTANT_ENV_VAR': 'set variable'})
2603
2681
        # not set in theparent
2604
2682
        self.assertFalse('EXISTANT_ENV_VAR' in os.environ)
2605
2683
 
2606
2684
    def test_run_bzr_subprocess_env_del(self):
2607
2685
        """run_bzr_subprocess can remove environment variables too."""
2608
2686
        self.assertFalse('EXISTANT_ENV_VAR' in os.environ)
 
2687
 
2609
2688
        def check_environment():
2610
2689
            self.assertFalse('EXISTANT_ENV_VAR' in os.environ)
2611
2690
        os.environ['EXISTANT_ENV_VAR'] = 'set variable'
2612
2691
        self.check_popen_state = check_environment
2613
2692
        self.assertRaises(_DontSpawnProcess, self.start_bzr_subprocess, [],
2614
 
                          env_changes={'EXISTANT_ENV_VAR':None})
 
2693
                          env_changes={'EXISTANT_ENV_VAR': None})
2615
2694
        # Still set in parent
2616
2695
        self.assertEqual('set variable', os.environ['EXISTANT_ENV_VAR'])
2617
2696
        del os.environ['EXISTANT_ENV_VAR']
2618
2697
 
2619
2698
    def test_env_del_missing(self):
2620
2699
        self.assertFalse('NON_EXISTANT_ENV_VAR' in os.environ)
 
2700
 
2621
2701
        def check_environment():
2622
2702
            self.assertFalse('NON_EXISTANT_ENV_VAR' in os.environ)
2623
2703
        self.check_popen_state = check_environment
2624
2704
        self.assertRaises(_DontSpawnProcess, self.start_bzr_subprocess, [],
2625
 
                          env_changes={'NON_EXISTANT_ENV_VAR':None})
 
2705
                          env_changes={'NON_EXISTANT_ENV_VAR': None})
2626
2706
 
2627
2707
    def test_working_dir(self):
2628
2708
        """Test that we can specify the working dir for the child"""
2629
 
        orig_getcwd = osutils.getcwd
2630
 
        orig_chdir = os.chdir
2631
2709
        chdirs = []
 
2710
 
2632
2711
        def chdir(path):
2633
2712
            chdirs.append(path)
2634
2713
        self.overrideAttr(os, 'chdir', chdir)
 
2714
 
2635
2715
        def getcwd():
2636
2716
            return 'current'
2637
2717
        self.overrideAttr(osutils, 'getcwd', getcwd)
2655
2735
        self.disable_missing_extensions_warning()
2656
2736
        process = self.start_bzr_subprocess(['wait-until-signalled'],
2657
2737
                                            skip_if_plan_to_signal=True)
2658
 
        self.assertEqual('running\n', process.stdout.readline())
 
2738
        self.assertEqual(b'running\n', process.stdout.readline())
2659
2739
        result = self.finish_bzr_subprocess(process, send_signal=signal.SIGINT,
2660
2740
                                            retcode=3)
2661
 
        self.assertEqual('', result[0])
2662
 
        self.assertEqual('brz: interrupted\n', result[1])
 
2741
        self.assertEqual(b'', result[0])
 
2742
        self.assertEqual(b'brz: interrupted\n', result[1])
2663
2743
 
2664
2744
 
2665
2745
class TestSelftestFiltering(tests.TestCase):
2674
2754
 
2675
2755
    def test_condition_id_re(self):
2676
2756
        test_name = ('breezy.tests.test_selftest.TestSelftestFiltering.'
2677
 
            'test_condition_id_re')
 
2757
                     'test_condition_id_re')
2678
2758
        filtered_suite = tests.filter_suite_by_condition(
2679
2759
            self.suite, tests.condition_id_re('test_condition_id_re'))
2680
2760
        self.assertEqual([test_name], _test_ids(filtered_suite))
2693
2773
        klass = 'breezy.tests.test_selftest.TestSelftestFiltering.'
2694
2774
        start1 = klass + 'test_condition_id_starts'
2695
2775
        start2 = klass + 'test_condition_id_in'
2696
 
        test_names = [ klass + 'test_condition_id_in_list',
 
2776
        test_names = [klass + 'test_condition_id_in_list',
2697
2777
                      klass + 'test_condition_id_startswith',
2698
 
                     ]
 
2778
                      ]
2699
2779
        filtered_suite = tests.filter_suite_by_condition(
2700
2780
            self.suite, tests.condition_id_startswith([start1, start2]))
2701
2781
        self.assertEqual(test_names, _test_ids(filtered_suite))
2709
2789
 
2710
2790
    def test_exclude_tests_by_condition(self):
2711
2791
        excluded_name = ('breezy.tests.test_selftest.TestSelftestFiltering.'
2712
 
            'test_exclude_tests_by_condition')
2713
 
        filtered_suite = tests.exclude_tests_by_condition(self.suite,
2714
 
            lambda x:x.id() == excluded_name)
 
2792
                         'test_exclude_tests_by_condition')
 
2793
        filtered_suite = tests.exclude_tests_by_condition(
 
2794
            self.suite, lambda x: x.id() == excluded_name)
2715
2795
        self.assertEqual(len(self.all_names) - 1,
2716
 
            filtered_suite.countTestCases())
 
2796
                         filtered_suite.countTestCases())
2717
2797
        self.assertFalse(excluded_name in _test_ids(filtered_suite))
2718
2798
        remaining_names = list(self.all_names)
2719
2799
        remaining_names.remove(excluded_name)
2724
2804
        filtered_suite = tests.exclude_tests_by_re(self.suite,
2725
2805
                                                   'exclude_tests_by_re')
2726
2806
        excluded_name = ('breezy.tests.test_selftest.TestSelftestFiltering.'
2727
 
            'test_exclude_tests_by_re')
 
2807
                         'test_exclude_tests_by_re')
2728
2808
        self.assertEqual(len(self.all_names) - 1,
2729
 
            filtered_suite.countTestCases())
 
2809
                         filtered_suite.countTestCases())
2730
2810
        self.assertFalse(excluded_name in _test_ids(filtered_suite))
2731
2811
        remaining_names = list(self.all_names)
2732
2812
        remaining_names.remove(excluded_name)
2734
2814
 
2735
2815
    def test_filter_suite_by_condition(self):
2736
2816
        test_name = ('breezy.tests.test_selftest.TestSelftestFiltering.'
2737
 
            'test_filter_suite_by_condition')
2738
 
        filtered_suite = tests.filter_suite_by_condition(self.suite,
2739
 
            lambda x:x.id() == test_name)
 
2817
                     'test_filter_suite_by_condition')
 
2818
        filtered_suite = tests.filter_suite_by_condition(
 
2819
            self.suite, lambda x: x.id() == test_name)
2740
2820
        self.assertEqual([test_name], _test_ids(filtered_suite))
2741
2821
 
2742
2822
    def test_filter_suite_by_re(self):
2743
2823
        filtered_suite = tests.filter_suite_by_re(self.suite,
2744
2824
                                                  'test_filter_suite_by_r')
2745
2825
        filtered_names = _test_ids(filtered_suite)
2746
 
        self.assertEqual(filtered_names, ['breezy.tests.test_selftest.'
2747
 
            'TestSelftestFiltering.test_filter_suite_by_re'])
 
2826
        self.assertEqual(
 
2827
            filtered_names, ['breezy.tests.test_selftest.'
 
2828
                             'TestSelftestFiltering.test_filter_suite_by_re'])
2748
2829
 
2749
2830
    def test_filter_suite_by_id_list(self):
2750
2831
        test_list = ['breezy.tests.test_selftest.'
2775
2856
 
2776
2857
    def test_preserve_input(self):
2777
2858
        # NB: Surely this is something in the stdlib to do this?
2778
 
        self.assertTrue(self.suite is tests.preserve_input(self.suite))
2779
 
        self.assertTrue("@#$" is tests.preserve_input("@#$"))
 
2859
        self.assertIs(self.suite, tests.preserve_input(self.suite))
 
2860
        self.assertEqual("@#$", tests.preserve_input("@#$"))
2780
2861
 
2781
2862
    def test_randomize_suite(self):
2782
2863
        randomized_suite = tests.randomize_suite(self.suite)
2798
2879
        condition = tests.condition_id_re('test_filter_suite_by_r')
2799
2880
        split_suite = tests.split_suite_by_condition(self.suite, condition)
2800
2881
        filtered_name = ('breezy.tests.test_selftest.TestSelftestFiltering.'
2801
 
            'test_filter_suite_by_re')
 
2882
                         'test_filter_suite_by_re')
2802
2883
        self.assertEqual([filtered_name], _test_ids(split_suite[0]))
2803
2884
        self.assertFalse(filtered_name in _test_ids(split_suite[1]))
2804
2885
        remaining_names = list(self.all_names)
2810
2891
        split_suite = tests.split_suite_by_re(self.suite,
2811
2892
                                              'test_filter_suite_by_r')
2812
2893
        filtered_name = ('breezy.tests.test_selftest.TestSelftestFiltering.'
2813
 
            'test_filter_suite_by_re')
 
2894
                         'test_filter_suite_by_re')
2814
2895
        self.assertEqual([filtered_name], _test_ids(split_suite[0]))
2815
2896
        self.assertFalse(filtered_name in _test_ids(split_suite[1]))
2816
2897
        remaining_names = list(self.all_names)
2859
2940
        self.permit_url(url)
2860
2941
        out, err = self.run_bzr(["log", "%s/nonexistantpath" % url], retcode=3)
2861
2942
        self.assertEqual(out, '')
2862
 
        self.assertContainsRe(err,
2863
 
            'brz: ERROR: Not a branch: ".*nonexistantpath/".\n')
 
2943
        self.assertContainsRe(
 
2944
            err, 'brz: ERROR: Not a branch: ".*nonexistantpath/".\n')
2864
2945
 
2865
2946
 
2866
2947
class TestTestLoader(tests.TestCase):
2870
2951
        """Gets a TestLoader and a module with one test in it."""
2871
2952
        loader = TestUtil.TestLoader()
2872
2953
        module = {}
 
2954
 
2873
2955
        class Stub(tests.TestCase):
2874
2956
            def test_foo(self):
2875
2957
                pass
 
2958
 
2876
2959
        class MyModule(object):
2877
2960
            pass
2878
2961
        MyModule.a_class = Stub
2882
2965
 
2883
2966
    def test_module_no_load_tests_attribute_loads_classes(self):
2884
2967
        loader, module = self._get_loader_and_module()
2885
 
        self.assertEqual(1, loader.loadTestsFromModule(module).countTestCases())
 
2968
        self.assertEqual(1, loader.loadTestsFromModule(
 
2969
            module).countTestCases())
2886
2970
 
2887
2971
    def test_module_load_tests_attribute_gets_called(self):
2888
2972
        loader, module = self._get_loader_and_module()
 
2973
 
2889
2974
        def load_tests(loader, standard_tests, pattern):
2890
2975
            result = loader.suiteClass()
2891
2976
            for test in tests.iter_suite_tests(standard_tests):
2901
2986
        loader = TestUtil.TestLoader()
2902
2987
        suite = loader.loadTestsFromModuleName('breezy.tests.test_sampler')
2903
2988
        self.assertEqual(['breezy.tests.test_sampler.DemoTest.test_nothing'],
2904
 
                          _test_ids(suite))
 
2989
                         _test_ids(suite))
2905
2990
 
2906
2991
    def test_load_tests_from_module_name_with_bogus_module_name(self):
2907
2992
        loader = TestUtil.TestLoader()
2924
3009
 
2925
3010
        suite = TestUtil.TestSuite()
2926
3011
        for id in test_id_list:
2927
 
            t  = Stub('test_foo')
 
3012
            t = Stub('test_foo')
2928
3013
            t.id = _create_test_id(id)
2929
3014
            suite.addTest(t)
2930
3015
        return suite
2978
3063
        dupes = loader.suiteClass()
2979
3064
        for test in tests.iter_suite_tests(suite):
2980
3065
            dupes.addTest(test)
2981
 
            dupes.addTest(test) # Add it again
 
3066
            dupes.addTest(test)  # Add it again
2982
3067
 
2983
 
        test_list = ['breezy.tests.test_sampler.DemoTest.test_nothing',]
 
3068
        test_list = ['breezy.tests.test_sampler.DemoTest.test_nothing', ]
2984
3069
        not_found, duplicates = tests.suite_matches_id_list(
2985
3070
            dupes, test_list)
2986
3071
        self.assertEqual([], not_found)
2987
3072
        self.assertEqual(['breezy.tests.test_sampler.DemoTest.test_nothing'],
2988
 
                          duplicates)
 
3073
                         duplicates)
2989
3074
 
2990
3075
 
2991
3076
class TestTestSuite(tests.TestCase):
3017
3102
    def test_test_suite(self):
3018
3103
        # test_suite() loads the entire test suite to operate. To avoid this
3019
3104
        # overhead, and yet still be confident that things are happening,
3020
 
        # we temporarily replace two functions used by test_suite with 
 
3105
        # we temporarily replace two functions used by test_suite with
3021
3106
        # test doubles that supply a few sample tests to load, and check they
3022
3107
        # are loaded.
3023
3108
        calls = []
 
3109
 
3024
3110
        def testmod_names():
3025
3111
            calls.append("testmod_names")
3026
3112
            return [
3029
3115
                'breezy.tests.test_selftest',
3030
3116
                ]
3031
3117
        self.overrideAttr(tests, '_test_suite_testmod_names', testmod_names)
 
3118
 
3032
3119
        def doctests():
3033
3120
            calls.append("modules_to_doctest")
3034
3121
            if __doc__ is None:
3044
3131
            # plugins can't be tested that way since selftest may be run with
3045
3132
            # --no-plugins
3046
3133
            ]
3047
 
        if __doc__ is not None:
3048
 
            expected_test_list.extend([
3049
 
                # modules_to_doctest
3050
 
                'breezy.timestamp.format_highres_date',
3051
 
                ])
3052
3134
        suite = tests.test_suite()
3053
 
        self.assertEqual({"testmod_names", "modules_to_doctest"},
3054
 
            set(calls))
 
3135
        self.assertEqual({"testmod_names", "modules_to_doctest"}, set(calls))
3055
3136
        self.assertSubset(expected_test_list, _test_ids(suite))
3056
3137
 
3057
3138
    def test_test_suite_list_and_start(self):
3058
 
        # We cannot test this at the same time as the main load, because we want
3059
 
        # to know that starting_with == None works. So a second load is
3060
 
        # incurred - note that the starting_with parameter causes a partial load
3061
 
        # rather than a full load so this test should be pretty quick.
3062
 
        test_list = ['breezy.tests.test_selftest.TestTestSuite.test_test_suite']
 
3139
        # We cannot test this at the same time as the main load, because we
 
3140
        # want to know that starting_with == None works. So a second load is
 
3141
        # incurred - note that the starting_with parameter causes a partial
 
3142
        # load rather than a full load so this test should be pretty quick.
 
3143
        test_list = [
 
3144
            'breezy.tests.test_selftest.TestTestSuite.test_test_suite']
3063
3145
        suite = tests.test_suite(test_list,
3064
3146
                                 ['breezy.tests.test_selftest.TestTestSuite'])
3065
 
        # test_test_suite_list_and_start is not included 
 
3147
        # test_test_suite_list_and_start is not included
3066
3148
        self.assertEqual(test_list, _test_ids(suite))
3067
3149
 
3068
3150
 
3142
3224
        self.assertEqual(test_list, _test_ids(suite))
3143
3225
 
3144
3226
    def test_exclude_tests(self):
3145
 
        test_list = ['bogus']
3146
3227
        loader = self._create_loader('bogus')
3147
3228
 
3148
3229
        suite = loader.loadTestsFromModuleName('breezy.tests.test_sampler')
3166
3247
        tpr.register('bar', 'bBB.aAA.rRR')
3167
3248
        self.assertEqual('bbb.aaa.rrr', tpr.get('bar'))
3168
3249
        self.assertThat(self.get_log(),
3169
 
            DocTestMatches("...bar...bbb.aaa.rrr...BB.aAA.rRR",
3170
 
                           doctest.ELLIPSIS))
 
3250
                        DocTestMatches("...bar...bbb.aaa.rrr...BB.aAA.rRR",
 
3251
                                       doctest.ELLIPSIS))
3171
3252
 
3172
3253
    def test_get_unknown_prefix(self):
3173
3254
        tpr = self._get_registry()
3200
3281
        def __init__(self):
3201
3282
            tests.ExtendedTestResult.__init__(self, StringIO(), 0, 1)
3202
3283
            self.leaks = []
 
3284
 
3203
3285
        def _report_thread_leak(self, test, leaks, alive):
3204
3286
            self.leaks.append((test, leaks))
3205
3287
 
3215
3297
        result.stopTestRun()
3216
3298
        self.assertEqual(result._tests_leaking_threads_count, 0)
3217
3299
        self.assertEqual(result.leaks, [])
3218
 
        
 
3300
 
3219
3301
    def test_thread_leak(self):
3220
3302
        """Ensure a thread that outlives the running of a test is reported
3221
3303
 
3226
3308
        """
3227
3309
        event = threading.Event()
3228
3310
        thread = threading.Thread(name="Leaker", target=event.wait)
 
3311
 
3229
3312
        class Test(tests.TestCase):
3230
3313
            def test_leak(self):
3231
3314
                thread.start()
3251
3334
        thread_a = threading.Thread(name="LeakerA", target=event.wait)
3252
3335
        thread_b = threading.Thread(name="LeakerB", target=event.wait)
3253
3336
        thread_c = threading.Thread(name="LeakerC", target=event.wait)
 
3337
 
3254
3338
        class Test(tests.TestCase):
3255
3339
            def test_first_leak(self):
3256
3340
                thread_b.start()
 
3341
 
3257
3342
            def test_second_no_leak(self):
3258
3343
                pass
 
3344
 
3259
3345
            def test_third_leak(self):
3260
3346
                thread_c.start()
3261
3347
                thread_a.start()
3286
3372
        def __init__(self):
3287
3373
            tests.ExtendedTestResult.__init__(self, StringIO(), 0, 1)
3288
3374
            self.postcode = None
 
3375
 
3289
3376
        def _post_mortem(self, tb=None):
3290
3377
            """Record the code object at the end of the current traceback"""
3291
3378
            tb = tb or sys.exc_info()[2]
3295
3382
                    tb = next
3296
3383
                    next = next.tb_next
3297
3384
                self.postcode = tb.tb_frame.f_code
 
3385
 
3298
3386
        def report_error(self, test, err):
3299
3387
            pass
 
3388
 
3300
3389
        def report_failure(self, test, err):
3301
3390
            pass
3302
3391
 
3358
3447
                pass
3359
3448
        suite = Stub("test_foo")
3360
3449
        calls = []
 
3450
 
3361
3451
        class MyRunner(tests.TextTestRunner):
3362
3452
            def run(self, test):
3363
3453
                calls.append(test)
3374
3464
        """To be overridden by subclasses that run tests out of process"""
3375
3465
 
3376
3466
    def _run_selftest(self, **kwargs):
3377
 
        sio = StringIO()
3378
 
        self._inject_stream_into_subunit(sio)
 
3467
        bio = BytesIO()
 
3468
        sio = TextIOWrapper(bio, 'utf-8')
 
3469
        self._inject_stream_into_subunit(bio)
3379
3470
        tests.selftest(stream=sio, stop_on_failure=False, **kwargs)
3380
 
        return sio.getvalue()
 
3471
        sio.flush()
 
3472
        return bio.getvalue()
3381
3473
 
3382
3474
 
3383
3475
class _ForkedSelftest(_Selftest):
3393
3485
        """
3394
3486
        from subunit import ProtocolTestCase
3395
3487
        _original_init = ProtocolTestCase.__init__
 
3488
 
3396
3489
        def _init_with_passthrough(self, *args, **kwargs):
3397
3490
            _original_init(self, *args, **kwargs)
3398
3491
            self._passthrough = stream
3423
3516
        # together due to the way subunit parses and forwards the streams,
3424
3517
        # so permit extra lines between each part of the error output.
3425
3518
        self.assertContainsRe(out,
3426
 
            "Traceback.*:\n"
3427
 
            "(?:.*\n)*"
3428
 
            ".+ in fork_for_tests\n"
3429
 
            "(?:.*\n)*"
3430
 
            "\\s*workaround_zealous_crypto_random\\(\\)\n"
3431
 
            "(?:.*\n)*"
3432
 
            "TypeError:")
 
3519
                              b"Traceback.*:\n"
 
3520
                              b"(?:.*\n)*"
 
3521
                              b".+ in fork_for_tests\n"
 
3522
                              b"(?:.*\n)*"
 
3523
                              b"\\s*workaround_zealous_crypto_random\\(\\)\n"
 
3524
                              b"(?:.*\n)*"
 
3525
                              b"TypeError:")
3433
3526
 
3434
3527
 
3435
3528
class TestUncollectedWarnings(_Selftest, tests.TestCase):
3438
3531
    class Test(tests.TestCase):
3439
3532
        def test_pass(self):
3440
3533
            pass
 
3534
 
3441
3535
        def test_self_ref(self):
3442
3536
            self.also_self = self.test_self_ref
 
3537
 
3443
3538
        def test_skip(self):
3444
3539
            self.skipTest("Don't need")
3445
3540
 
3458
3553
            gc.disable()
3459
3554
        try:
3460
3555
            output = self._run_selftest(test_suite_factory=self._get_suite,
3461
 
                **kwargs)
 
3556
                                        **kwargs)
3462
3557
        finally:
3463
3558
            if gc_on:
3464
3559
                gc.enable()
3465
3560
            tests.selftest_debug_flags = old_flags
3466
 
        self.assertNotContainsRe(output, "Uncollected test case.*test_pass")
3467
 
        self.assertContainsRe(output, "Uncollected test case.*test_self_ref")
 
3561
        self.assertNotContainsRe(output, b"Uncollected test case.*test_pass")
 
3562
        self.assertContainsRe(output, b"Uncollected test case.*test_self_ref")
3468
3563
        return output
3469
3564
 
3470
3565
    def test_testsuite(self):
3472
3567
 
3473
3568
    def test_pattern(self):
3474
3569
        out = self._run_selftest_with_suite(pattern="test_(?:pass|self_ref)$")
3475
 
        self.assertNotContainsRe(out, "test_skip")
 
3570
        self.assertNotContainsRe(out, b"test_skip")
3476
3571
 
3477
3572
    def test_exclude_pattern(self):
3478
3573
        out = self._run_selftest_with_suite(exclude_pattern="test_skip$")
3479
 
        self.assertNotContainsRe(out, "test_skip")
 
3574
        self.assertNotContainsRe(out, b"test_skip")
3480
3575
 
3481
3576
    def test_random_seed(self):
3482
3577
        self._run_selftest_with_suite(random_seed="now")
3483
3578
 
3484
3579
    def test_matching_tests_first(self):
3485
3580
        self._run_selftest_with_suite(matching_tests_first=True,
3486
 
            pattern="test_self_ref$")
 
3581
                                      pattern="test_self_ref$")
3487
3582
 
3488
3583
    def test_starting_with_and_exclude(self):
3489
3584
        out = self._run_selftest_with_suite(starting_with=["bt."],
3490
 
            exclude_pattern="test_skip$")
3491
 
        self.assertNotContainsRe(out, "test_skip")
 
3585
                                            exclude_pattern="test_skip$")
 
3586
        self.assertNotContainsRe(out, b"test_skip")
3492
3587
 
3493
3588
    def test_additonal_decorator(self):
3494
 
        out = self._run_selftest_with_suite(
3495
 
            suite_decorators=[tests.TestDecorator])
 
3589
        self._run_selftest_with_suite(suite_decorators=[tests.TestDecorator])
3496
3590
 
3497
3591
 
3498
3592
class TestUncollectedWarningsSubunit(TestUncollectedWarnings):
3515
3609
        self.assertFalse('MYVAR' in os.environ)
3516
3610
        self.overrideEnv('MYVAR', '42')
3517
3611
        # We use an embedded test to make sure we fix the _captureVar bug
 
3612
 
3518
3613
        class Test(tests.TestCase):
3519
3614
            def test_me(self):
3520
3615
                # The first call save the 42 value
3662
3757
            def id(self):
3663
3758
                # We don't need the full class path
3664
3759
                return self._testMethodName
 
3760
 
3665
3761
            def a(self):
3666
3762
                pass
 
3763
 
3667
3764
            def b(self):
3668
3765
                pass
 
3766
 
3669
3767
            def c(self):
3670
3768
                pass
3671
3769
        return TestUtil.TestSuite([Test("a"), Test("b"), Test("c")])
3693
3791
 
3694
3792
    def setUp(self):
3695
3793
        super(TestCounterHooks, self).setUp()
 
3794
 
3696
3795
        class Test(tests.TestCase):
3697
3796
 
3698
3797
            def setUp(self):