~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_selftest.py

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2011-06-30 18:28:17 UTC
  • mfrom: (5967.10.2 test-cat)
  • Revision ID: pqm@pqm.ubuntu.com-20110630182817-83a5q9r9rxfkdn8r
(mbp) don't use subprocesses for testing cat (Martin Pool)

Show diffs side-by-side

added added

removed removed

Lines of Context:
17
17
"""Tests for the test framework."""
18
18
 
19
19
from cStringIO import StringIO
20
 
import gc
21
20
import doctest
22
21
import os
23
22
import signal
43
42
from bzrlib import (
44
43
    branchbuilder,
45
44
    bzrdir,
46
 
    controldir,
47
45
    errors,
48
46
    hooks,
49
47
    lockdir,
95
93
            DocTestMatches(u"...a test message\n", doctest.ELLIPSIS))
96
94
 
97
95
 
 
96
class TestUnicodeFilename(tests.TestCase):
 
97
 
 
98
    def test_probe_passes(self):
 
99
        """UnicodeFilename._probe passes."""
 
100
        # We can't test much more than that because the behaviour depends
 
101
        # on the platform.
 
102
        tests.UnicodeFilename._probe()
 
103
 
 
104
 
98
105
class TestTreeShape(tests.TestCaseInTempDir):
99
106
 
100
107
    def test_unicode_paths(self):
101
 
        self.requireFeature(features.UnicodeFilenameFeature)
 
108
        self.requireFeature(tests.UnicodeFilename)
102
109
 
103
110
        filename = u'hell\u00d8'
104
111
        self.build_tree_contents([(filename, 'contents of hello')])
335
342
        server1 = "a"
336
343
        server2 = "b"
337
344
        formats = [workingtree_4.WorkingTreeFormat4(),
338
 
                   workingtree_3.WorkingTreeFormat3(),
339
 
                   workingtree_4.WorkingTreeFormat6()]
340
 
        scenarios = make_scenarios(server1, server2, formats,
341
 
            remote_server='c', remote_readonly_server='d',
342
 
            remote_backing_server='e')
 
345
                   workingtree_3.WorkingTreeFormat3(),]
 
346
        scenarios = make_scenarios(server1, server2, formats)
343
347
        self.assertEqual([
344
348
            ('WorkingTreeFormat4',
345
349
             {'bzrdir_format': formats[0]._matchingbzrdir,
350
354
             {'bzrdir_format': formats[1]._matchingbzrdir,
351
355
              'transport_readonly_server': 'b',
352
356
              'transport_server': 'a',
353
 
              'workingtree_format': formats[1]}),
354
 
            ('WorkingTreeFormat6',
355
 
             {'bzrdir_format': formats[2]._matchingbzrdir,
356
 
              'transport_readonly_server': 'b',
357
 
              'transport_server': 'a',
358
 
              'workingtree_format': formats[2]}),
359
 
            ('WorkingTreeFormat6,remote',
360
 
             {'bzrdir_format': formats[2]._matchingbzrdir,
361
 
              'repo_is_remote': True,
362
 
              'transport_readonly_server': 'd',
363
 
              'transport_server': 'c',
364
 
              'vfs_transport_factory': 'e',
365
 
              'workingtree_format': formats[2]}),
366
 
            ], scenarios)
 
357
              'workingtree_format': formats[1]})],
 
358
            scenarios)
367
359
 
368
360
 
369
361
class TestTreeScenarios(tests.TestCase):
370
362
 
371
363
    def test_scenarios(self):
372
364
        # the tree implementation scenario generator is meant to setup one
373
 
        # instance for each working tree format, one additional instance
 
365
        # instance for each working tree format, and one additional instance
374
366
        # that will use the default wt format, but create a revision tree for
375
 
        # the tests, and one more that uses the default wt format as a
376
 
        # lightweight checkout of a remote repository.  This means that the wt
377
 
        # ones should have the workingtree_to_test_tree attribute set to
378
 
        # 'return_parameter' and the revision one set to
379
 
        # revision_tree_from_workingtree.
 
367
        # the tests.  this means that the wt ones should have the
 
368
        # workingtree_to_test_tree attribute set to 'return_parameter' and the
 
369
        # revision one set to revision_tree_from_workingtree.
380
370
 
381
371
        from bzrlib.tests.per_tree import (
382
372
            _dirstate_tree_from_workingtree,
388
378
            )
389
379
        server1 = "a"
390
380
        server2 = "b"
391
 
        smart_server = test_server.SmartTCPServer_for_testing
392
 
        smart_readonly_server = test_server.ReadonlySmartTCPServer_for_testing
393
 
        mem_server = memory.MemoryServer
394
381
        formats = [workingtree_4.WorkingTreeFormat4(),
395
382
                   workingtree_3.WorkingTreeFormat3(),]
396
383
        scenarios = make_scenarios(server1, server2, formats)
397
 
        self.assertEqual(8, len(scenarios))
 
384
        self.assertEqual(7, len(scenarios))
398
385
        default_wt_format = workingtree.format_registry.get_default()
399
386
        wt4_format = workingtree_4.WorkingTreeFormat4()
400
387
        wt5_format = workingtree_4.WorkingTreeFormat5()
401
 
        wt6_format = workingtree_4.WorkingTreeFormat6()
402
388
        expected_scenarios = [
403
389
            ('WorkingTreeFormat4',
404
390
             {'bzrdir_format': formats[0]._matchingbzrdir,
414
400
              'workingtree_format': formats[1],
415
401
              '_workingtree_to_test_tree': return_parameter,
416
402
             }),
417
 
            ('WorkingTreeFormat6,remote',
418
 
             {'bzrdir_format': wt6_format._matchingbzrdir,
419
 
              'repo_is_remote': True,
420
 
              'transport_readonly_server': smart_readonly_server,
421
 
              'transport_server': smart_server,
422
 
              'vfs_transport_factory': mem_server,
423
 
              'workingtree_format': wt6_format,
424
 
              '_workingtree_to_test_tree': return_parameter,
425
 
             }),
426
403
            ('RevisionTree',
427
404
             {'_workingtree_to_test_tree': revision_tree_from_workingtree,
428
405
              'bzrdir_format': default_wt_format._matchingbzrdir,
640
617
        # Guard against regression into MemoryTransport leaking
641
618
        # files to disk instead of keeping them in memory.
642
619
        self.assertFalse(osutils.lexists('dir'))
643
 
        dir_format = controldir.format_registry.make_bzrdir('knit')
 
620
        dir_format = bzrdir.format_registry.make_bzrdir('knit')
644
621
        self.assertEqual(dir_format.repository_format.__class__,
645
622
                         the_branch.repository._format.__class__)
646
623
        self.assertEqual('Bazaar-NG Knit Repository Format 1',
650
627
    def test_dangling_locks_cause_failures(self):
651
628
        class TestDanglingLock(tests.TestCaseWithMemoryTransport):
652
629
            def test_function(self):
653
 
                t = self.get_transport_from_path('.')
 
630
                t = self.get_transport('.')
654
631
                l = lockdir.LockDir(t, 'lock')
655
632
                l.create()
656
633
                l.attempt_lock()
676
653
        # for the server
677
654
        url = self.get_readonly_url()
678
655
        url2 = self.get_readonly_url('foo/bar')
679
 
        t = transport.get_transport_from_url(url)
680
 
        t2 = transport.get_transport_from_url(url2)
 
656
        t = transport.get_transport(url)
 
657
        t2 = transport.get_transport(url2)
681
658
        self.assertIsInstance(t, ReadonlyTransportDecorator)
682
659
        self.assertIsInstance(t2, ReadonlyTransportDecorator)
683
660
        self.assertEqual(t2.base[:-1], t.abspath('foo/bar'))
691
668
        url = self.get_readonly_url()
692
669
        url2 = self.get_readonly_url('foo/bar')
693
670
        # the transport returned may be any HttpTransportBase subclass
694
 
        t = transport.get_transport_from_url(url)
695
 
        t2 = transport.get_transport_from_url(url2)
 
671
        t = transport.get_transport(url)
 
672
        t2 = transport.get_transport(url2)
696
673
        self.assertIsInstance(t, HttpTransportBase)
697
674
        self.assertIsInstance(t2, HttpTransportBase)
698
675
        self.assertEqual(t2.base[:-1], t.abspath('foo/bar'))
709
686
        builder = self.make_branch_builder('dir')
710
687
        rev_id = builder.build_commit()
711
688
        self.assertPathExists('dir')
712
 
        a_dir = controldir.ControlDir.open('dir')
 
689
        a_dir = bzrdir.BzrDir.open('dir')
713
690
        self.assertRaises(errors.NoWorkingTree, a_dir.open_workingtree)
714
691
        a_branch = a_dir.open_branch()
715
692
        builder_branch = builder.get_branch()
736
713
class TestChrootedTest(tests.ChrootedTestCase):
737
714
 
738
715
    def test_root_is_root(self):
739
 
        t = transport.get_transport_from_url(self.get_readonly_url())
 
716
        t = transport.get_transport(self.get_readonly_url())
740
717
        url = t.base
741
718
        self.assertEqual(url, t.clone('..').base)
742
719
 
744
721
class TestProfileResult(tests.TestCase):
745
722
 
746
723
    def test_profiles_tests(self):
747
 
        self.requireFeature(features.lsprof_feature)
 
724
        self.requireFeature(test_lsprof.LSProfFeature)
748
725
        terminal = testtools.testresult.doubles.ExtendedTestResult()
749
726
        result = tests.ProfileResult(terminal)
750
727
        class Sample(tests.TestCase):
805
782
 
806
783
    def test_lsprofiling(self):
807
784
        """Verbose test result prints lsprof statistics from test cases."""
808
 
        self.requireFeature(features.lsprof_feature)
 
785
        self.requireFeature(test_lsprof.LSProfFeature)
809
786
        result_stream = StringIO()
810
787
        result = bzrlib.tests.VerboseTestResult(
811
788
            result_stream,
856
833
        self.assertEndsWith(sio.getvalue(), "OK    50002ms\n")
857
834
 
858
835
    def test_known_failure(self):
859
 
        """Using knownFailure should trigger several result actions."""
 
836
        """A KnownFailure being raised should trigger several result actions."""
860
837
        class InstrumentedTestResult(tests.ExtendedTestResult):
861
838
            def stopTestRun(self): pass
862
839
            def report_tests_starting(self): pass
865
842
        result = InstrumentedTestResult(None, None, None, None)
866
843
        class Test(tests.TestCase):
867
844
            def test_function(self):
868
 
                self.knownFailure('failed!')
 
845
                raise tests.KnownFailure('failed!')
869
846
        test = Test("test_function")
870
847
        test.run(result)
871
848
        # it should invoke 'report_known_failure'.
887
864
            descriptions=0,
888
865
            verbosity=2,
889
866
            )
890
 
        _get_test("test_xfail").run(result)
891
 
        self.assertContainsRe(result_stream.getvalue(),
892
 
            "\n\\S+\\.test_xfail\\s+XFAIL\\s+\\d+ms\n"
893
 
            "\\s*(?:Text attachment: )?reason"
894
 
            "(?:\n-+\n|: {{{)"
895
 
            "this_fails"
896
 
            "(?:\n-+\n|}}}\n)")
 
867
        test = self.get_passing_test()
 
868
        result.startTest(test)
 
869
        prefix = len(result_stream.getvalue())
 
870
        # the err parameter has the shape:
 
871
        # (class, exception object, traceback)
 
872
        # KnownFailures dont get their tracebacks shown though, so we
 
873
        # can skip that.
 
874
        err = (tests.KnownFailure, tests.KnownFailure('foo'), None)
 
875
        result.report_known_failure(test, err)
 
876
        output = result_stream.getvalue()[prefix:]
 
877
        lines = output.splitlines()
 
878
        self.assertContainsRe(lines[0], r'XFAIL *\d+ms$')
 
879
        if sys.version_info > (2, 7):
 
880
            self.expectFailure("_ExpectedFailure on 2.7 loses the message",
 
881
                self.assertNotEqual, lines[1], '    ')
 
882
        self.assertEqual(lines[1], '    foo')
 
883
        self.assertEqual(2, len(lines))
897
884
 
898
885
    def get_passing_test(self):
899
886
        """Return a test object that can't be run usefully."""
910
897
                self._call = test, feature
911
898
        result = InstrumentedTestResult(None, None, None, None)
912
899
        test = SampleTestCase('_test_pass')
913
 
        feature = features.Feature()
 
900
        feature = tests.Feature()
914
901
        result.startTest(test)
915
902
        result.addNotSupported(test, feature)
916
903
        # it should invoke 'report_unsupported'.
935
922
            verbosity=2,
936
923
            )
937
924
        test = self.get_passing_test()
938
 
        feature = features.Feature()
 
925
        feature = tests.Feature()
939
926
        result.startTest(test)
940
927
        prefix = len(result_stream.getvalue())
941
928
        result.report_unsupported(test, feature)
954
941
            def addNotSupported(self, test, feature):
955
942
                self._call = test, feature
956
943
        result = InstrumentedTestResult(None, None, None, None)
957
 
        feature = features.Feature()
 
944
        feature = tests.Feature()
958
945
        class Test(tests.TestCase):
959
946
            def test_function(self):
960
947
                raise tests.UnavailableFeature(feature)
979
966
    def test_strict_with_known_failure(self):
980
967
        result = bzrlib.tests.TextTestResult(self._log_file, descriptions=0,
981
968
                                             verbosity=1)
982
 
        test = _get_test("test_xfail")
983
 
        test.run(result)
 
969
        test = self.get_passing_test()
 
970
        err = (tests.KnownFailure, tests.KnownFailure('foo'), None)
 
971
        result.addExpectedFailure(test, err)
984
972
        self.assertFalse(result.wasStrictlySuccessful())
985
973
        self.assertEqual(None, result._extractBenchmarkTime(test))
986
974
 
1018
1006
        self.assertEquals(2, result.count)
1019
1007
 
1020
1008
 
 
1009
class TestUnicodeFilenameFeature(tests.TestCase):
 
1010
 
 
1011
    def test_probe_passes(self):
 
1012
        """UnicodeFilenameFeature._probe passes."""
 
1013
        # We can't test much more than that because the behaviour depends
 
1014
        # on the platform.
 
1015
        tests.UnicodeFilenameFeature._probe()
 
1016
 
 
1017
 
1021
1018
class TestRunner(tests.TestCase):
1022
1019
 
1023
1020
    def dummy_test(self):
1098
1095
            "FAIL: \\S+\.test_truth\n"
1099
1096
            "-+\n"
1100
1097
            "(?:.*\n)*"
1101
 
            "\\s*(?:Text attachment: )?reason"
1102
 
            "(?:\n-+\n|: {{{)"
1103
 
            "No absolute truth"
1104
 
            "(?:\n-+\n|}}}\n)"
 
1098
            "No absolute truth\n"
1105
1099
            "(?:.*\n)*"
1106
1100
            "-+\n"
1107
1101
            "Ran 1 test in .*\n"
1161
1155
        class SkippedTest(tests.TestCase):
1162
1156
 
1163
1157
            def setUp(self):
1164
 
                super(SkippedTest, self).setUp()
 
1158
                tests.TestCase.setUp(self)
1165
1159
                calls.append('setUp')
1166
1160
                self.addCleanup(self.cleanup)
1167
1161
 
1197
1191
 
1198
1192
    def test_unsupported_features_listed(self):
1199
1193
        """When unsupported features are encountered they are detailed."""
1200
 
        class Feature1(features.Feature):
 
1194
        class Feature1(tests.Feature):
1201
1195
            def _probe(self): return False
1202
 
        class Feature2(features.Feature):
 
1196
        class Feature2(tests.Feature):
1203
1197
            def _probe(self): return False
1204
1198
        # create sample tests
1205
1199
        test1 = SampleTestCase('_test_pass')
1272
1266
        result = self.run_test_runner(tests.TextTestRunner(stream=out),
1273
1267
            FailureWithUnicode("test_log_unicode"))
1274
1268
        self.assertContainsRe(out.getvalue(),
1275
 
            "(?:Text attachment: )?log"
1276
 
            "(?:\n-+\n|: {{{)"
1277
 
            "\d+\.\d+  \\\\u2606"
1278
 
            "(?:\n-+\n|}}}\n)")
 
1269
            "Text attachment: log\n"
 
1270
            "-+\n"
 
1271
            "\d+\.\d+  \\\\u2606\n"
 
1272
            "-+\n")
1279
1273
 
1280
1274
 
1281
1275
class SampleTestCase(tests.TestCase):
1482
1476
 
1483
1477
        Each self.time() call is individually and separately profiled.
1484
1478
        """
1485
 
        self.requireFeature(features.lsprof_feature)
 
1479
        self.requireFeature(test_lsprof.LSProfFeature)
1486
1480
        # overrides the class member with an instance member so no cleanup
1487
1481
        # needed.
1488
1482
        self._gather_lsprof_in_benchmarks = True
1507
1501
        transport_server = memory.MemoryServer()
1508
1502
        transport_server.start_server()
1509
1503
        self.addCleanup(transport_server.stop_server)
1510
 
        t = transport.get_transport_from_url(transport_server.get_url())
1511
 
        controldir.ControlDir.create(t.base)
 
1504
        t = transport.get_transport(transport_server.get_url())
 
1505
        bzrdir.BzrDir.create(t.base)
1512
1506
        self.assertRaises(errors.BzrError,
1513
 
            controldir.ControlDir.open_from_transport, t)
 
1507
            bzrdir.BzrDir.open_from_transport, t)
1514
1508
        # But if we declare this as safe, we can open the bzrdir.
1515
1509
        self.permit_url(t.base)
1516
1510
        self._bzr_selftest_roots.append(t.base)
1517
 
        controldir.ControlDir.open_from_transport(t)
 
1511
        bzrdir.BzrDir.open_from_transport(t)
1518
1512
 
1519
1513
    def test_requireFeature_available(self):
1520
1514
        """self.requireFeature(available) is a no-op."""
1521
 
        class Available(features.Feature):
 
1515
        class Available(tests.Feature):
1522
1516
            def _probe(self):return True
1523
1517
        feature = Available()
1524
1518
        self.requireFeature(feature)
1525
1519
 
1526
1520
    def test_requireFeature_unavailable(self):
1527
1521
        """self.requireFeature(unavailable) raises UnavailableFeature."""
1528
 
        class Unavailable(features.Feature):
 
1522
        class Unavailable(tests.Feature):
1529
1523
            def _probe(self):return False
1530
1524
        feature = Unavailable()
1531
1525
        self.assertRaises(tests.UnavailableFeature,
1654
1648
        self.assertRaises(AssertionError,
1655
1649
            self.assertListRaises, _TestException, success_generator)
1656
1650
 
1657
 
    def _run_successful_test(self, test):
1658
 
        result = testtools.TestResult()
1659
 
        test.run(result)
1660
 
        self.assertTrue(result.wasSuccessful())
1661
 
        return result
1662
 
 
1663
1651
    def test_overrideAttr_without_value(self):
1664
1652
        self.test_attr = 'original' # Define a test attribute
1665
1653
        obj = self # Make 'obj' visible to the embedded test
1666
1654
        class Test(tests.TestCase):
1667
1655
 
1668
1656
            def setUp(self):
1669
 
                super(Test, self).setUp()
 
1657
                tests.TestCase.setUp(self)
1670
1658
                self.orig = self.overrideAttr(obj, 'test_attr')
1671
1659
 
1672
1660
            def test_value(self):
1675
1663
                obj.test_attr = 'modified'
1676
1664
                self.assertEqual('modified', obj.test_attr)
1677
1665
 
1678
 
        self._run_successful_test(Test('test_value'))
 
1666
        test = Test('test_value')
 
1667
        test.run(unittest.TestResult())
1679
1668
        self.assertEqual('original', obj.test_attr)
1680
1669
 
1681
1670
    def test_overrideAttr_with_value(self):
1684
1673
        class Test(tests.TestCase):
1685
1674
 
1686
1675
            def setUp(self):
1687
 
                super(Test, self).setUp()
 
1676
                tests.TestCase.setUp(self)
1688
1677
                self.orig = self.overrideAttr(obj, 'test_attr', new='modified')
1689
1678
 
1690
1679
            def test_value(self):
1691
1680
                self.assertEqual('original', self.orig)
1692
1681
                self.assertEqual('modified', obj.test_attr)
1693
1682
 
1694
 
        self._run_successful_test(Test('test_value'))
 
1683
        test = Test('test_value')
 
1684
        test.run(unittest.TestResult())
1695
1685
        self.assertEqual('original', obj.test_attr)
1696
1686
 
1697
 
    def test_overrideAttr_with_no_existing_value_and_value(self):
1698
 
        # Do not define the test_attribute
1699
 
        obj = self # Make 'obj' visible to the embedded test
1700
 
        class Test(tests.TestCase):
1701
 
 
1702
 
            def setUp(self):
1703
 
                tests.TestCase.setUp(self)
1704
 
                self.orig = self.overrideAttr(obj, 'test_attr', new='modified')
1705
 
 
1706
 
            def test_value(self):
1707
 
                self.assertEqual(tests._unitialized_attr, self.orig)
1708
 
                self.assertEqual('modified', obj.test_attr)
1709
 
 
1710
 
        self._run_successful_test(Test('test_value'))
1711
 
        self.assertRaises(AttributeError, getattr, obj, 'test_attr')
1712
 
 
1713
 
    def test_overrideAttr_with_no_existing_value_and_no_value(self):
1714
 
        # Do not define the test_attribute
1715
 
        obj = self # Make 'obj' visible to the embedded test
1716
 
        class Test(tests.TestCase):
1717
 
 
1718
 
            def setUp(self):
1719
 
                tests.TestCase.setUp(self)
1720
 
                self.orig = self.overrideAttr(obj, 'test_attr')
1721
 
 
1722
 
            def test_value(self):
1723
 
                self.assertEqual(tests._unitialized_attr, self.orig)
1724
 
                self.assertRaises(AttributeError, getattr, obj, 'test_attr')
1725
 
 
1726
 
        self._run_successful_test(Test('test_value'))
1727
 
        self.assertRaises(AttributeError, getattr, obj, 'test_attr')
1728
 
 
1729
 
    def test_recordCalls(self):
1730
 
        from bzrlib.tests import test_selftest
1731
 
        calls = self.recordCalls(
1732
 
            test_selftest, '_add_numbers')
1733
 
        self.assertEqual(test_selftest._add_numbers(2, 10),
1734
 
            12)
1735
 
        self.assertEquals(calls, [((2, 10), {})])
1736
 
 
1737
 
 
1738
 
def _add_numbers(a, b):
1739
 
    return a + b
1740
 
 
1741
 
 
1742
 
class _MissingFeature(features.Feature):
 
1687
 
 
1688
class _MissingFeature(tests.Feature):
1743
1689
    def _probe(self):
1744
1690
        return False
1745
1691
missing_feature = _MissingFeature()
1796
1742
        result = self._run_test('test_fail')
1797
1743
        self.assertEqual(1, len(result.failures))
1798
1744
        result_content = result.failures[0][1]
1799
 
        self.assertContainsRe(result_content,
1800
 
            '(?m)^(?:Text attachment: )?log(?:$|: )')
 
1745
        self.assertContainsRe(result_content, 'Text attachment: log')
1801
1746
        self.assertContainsRe(result_content, 'this was a failing test')
1802
1747
 
1803
1748
    def test_error_has_log(self):
1804
1749
        result = self._run_test('test_error')
1805
1750
        self.assertEqual(1, len(result.errors))
1806
1751
        result_content = result.errors[0][1]
1807
 
        self.assertContainsRe(result_content,
1808
 
            '(?m)^(?:Text attachment: )?log(?:$|: )')
 
1752
        self.assertContainsRe(result_content, 'Text attachment: log')
1809
1753
        self.assertContainsRe(result_content, 'this test errored')
1810
1754
 
1811
1755
    def test_skip_has_no_log(self):
1830
1774
        result = self._run_test('test_xfail')
1831
1775
        self.assertEqual(1, len(result.expectedFailures))
1832
1776
        result_content = result.expectedFailures[0][1]
1833
 
        self.assertNotContainsRe(result_content,
1834
 
            '(?m)^(?:Text attachment: )?log(?:$|: )')
 
1777
        self.assertNotContainsRe(result_content, 'Text attachment: log')
1835
1778
        self.assertNotContainsRe(result_content, 'test with expected failure')
1836
1779
 
1837
1780
    def test_unexpected_success_has_log(self):
2010
1953
    def test_make_branch_and_tree_with_format(self):
2011
1954
        # we should be able to supply a format to make_branch_and_tree
2012
1955
        self.make_branch_and_tree('a', format=bzrlib.bzrdir.BzrDirMetaFormat1())
2013
 
        self.assertIsInstance(bzrlib.controldir.ControlDir.open('a')._format,
 
1956
        self.assertIsInstance(bzrlib.bzrdir.BzrDir.open('a')._format,
2014
1957
                              bzrlib.bzrdir.BzrDirMetaFormat1)
2015
1958
 
2016
1959
    def test_make_branch_and_memory_tree(self):
2094
2037
        self.assertLength(2, output.readlines())
2095
2038
 
2096
2039
    def test_lsprof_tests(self):
2097
 
        self.requireFeature(features.lsprof_feature)
 
2040
        self.requireFeature(test_lsprof.LSProfFeature)
2098
2041
        results = []
2099
2042
        class Test(object):
2100
2043
            def __call__(test, result):
2246
2189
        self.assertNotContainsRe(content, 'test with expected failure')
2247
2190
        self.assertEqual(1, len(result.expectedFailures))
2248
2191
        result_content = result.expectedFailures[0][1]
2249
 
        self.assertNotContainsRe(result_content,
2250
 
            '(?m)^(?:Text attachment: )?log(?:$|: )')
 
2192
        self.assertNotContainsRe(result_content, 'Text attachment: log')
2251
2193
        self.assertNotContainsRe(result_content, 'test with expected failure')
2252
2194
 
2253
2195
    def test_unexpected_success_has_log(self):
2448
2390
    """Base class for tests testing how we might run bzr."""
2449
2391
 
2450
2392
    def setUp(self):
2451
 
        super(TestWithFakedStartBzrSubprocess, self).setUp()
 
2393
        tests.TestCaseWithTransport.setUp(self)
2452
2394
        self.subprocess_calls = []
2453
2395
 
2454
2396
    def start_bzr_subprocess(self, process_args, env_changes=None,
2665
2607
        self.assertEqual('bzr: interrupted\n', result[1])
2666
2608
 
2667
2609
 
 
2610
class TestFeature(tests.TestCase):
 
2611
 
 
2612
    def test_caching(self):
 
2613
        """Feature._probe is called by the feature at most once."""
 
2614
        class InstrumentedFeature(tests.Feature):
 
2615
            def __init__(self):
 
2616
                super(InstrumentedFeature, self).__init__()
 
2617
                self.calls = []
 
2618
            def _probe(self):
 
2619
                self.calls.append('_probe')
 
2620
                return False
 
2621
        feature = InstrumentedFeature()
 
2622
        feature.available()
 
2623
        self.assertEqual(['_probe'], feature.calls)
 
2624
        feature.available()
 
2625
        self.assertEqual(['_probe'], feature.calls)
 
2626
 
 
2627
    def test_named_str(self):
 
2628
        """Feature.__str__ should thunk to feature_name()."""
 
2629
        class NamedFeature(tests.Feature):
 
2630
            def feature_name(self):
 
2631
                return 'symlinks'
 
2632
        feature = NamedFeature()
 
2633
        self.assertEqual('symlinks', str(feature))
 
2634
 
 
2635
    def test_default_str(self):
 
2636
        """Feature.__str__ should default to __class__.__name__."""
 
2637
        class NamedFeature(tests.Feature):
 
2638
            pass
 
2639
        feature = NamedFeature()
 
2640
        self.assertEqual('NamedFeature', str(feature))
 
2641
 
 
2642
 
 
2643
class TestUnavailableFeature(tests.TestCase):
 
2644
 
 
2645
    def test_access_feature(self):
 
2646
        feature = tests.Feature()
 
2647
        exception = tests.UnavailableFeature(feature)
 
2648
        self.assertIs(feature, exception.args[0])
 
2649
 
 
2650
 
 
2651
simple_thunk_feature = tests._CompatabilityThunkFeature(
 
2652
    deprecated_in((2, 1, 0)),
 
2653
    'bzrlib.tests.test_selftest',
 
2654
    'simple_thunk_feature','UnicodeFilename',
 
2655
    replacement_module='bzrlib.tests'
 
2656
    )
 
2657
 
 
2658
class Test_CompatibilityFeature(tests.TestCase):
 
2659
 
 
2660
    def test_does_thunk(self):
 
2661
        res = self.callDeprecated(
 
2662
            ['bzrlib.tests.test_selftest.simple_thunk_feature was deprecated'
 
2663
             ' in version 2.1.0. Use bzrlib.tests.UnicodeFilename instead.'],
 
2664
            simple_thunk_feature.available)
 
2665
        self.assertEqual(tests.UnicodeFilename.available(), res)
 
2666
 
 
2667
 
 
2668
class TestModuleAvailableFeature(tests.TestCase):
 
2669
 
 
2670
    def test_available_module(self):
 
2671
        feature = tests.ModuleAvailableFeature('bzrlib.tests')
 
2672
        self.assertEqual('bzrlib.tests', feature.module_name)
 
2673
        self.assertEqual('bzrlib.tests', str(feature))
 
2674
        self.assertTrue(feature.available())
 
2675
        self.assertIs(tests, feature.module)
 
2676
 
 
2677
    def test_unavailable_module(self):
 
2678
        feature = tests.ModuleAvailableFeature('bzrlib.no_such_module_exists')
 
2679
        self.assertEqual('bzrlib.no_such_module_exists', str(feature))
 
2680
        self.assertFalse(feature.available())
 
2681
        self.assertIs(None, feature.module)
 
2682
 
 
2683
 
2668
2684
class TestSelftestFiltering(tests.TestCase):
2669
2685
 
2670
2686
    def setUp(self):
2671
 
        super(TestSelftestFiltering, self).setUp()
 
2687
        tests.TestCase.setUp(self)
2672
2688
        self.suite = TestUtil.TestSuite()
2673
2689
        self.loader = TestUtil.TestLoader()
2674
2690
        self.suite.addTest(self.loader.loadTestsFromModule(
3369
3385
        self.assertLength(1, calls)
3370
3386
 
3371
3387
 
3372
 
class _Selftest(object):
3373
 
    """Mixin for tests needing full selftest output"""
3374
 
 
3375
 
    def _inject_stream_into_subunit(self, stream):
3376
 
        """To be overridden by subclasses that run tests out of process"""
3377
 
 
3378
 
    def _run_selftest(self, **kwargs):
3379
 
        sio = StringIO()
3380
 
        self._inject_stream_into_subunit(sio)
3381
 
        tests.selftest(stream=sio, stop_on_failure=False, **kwargs)
3382
 
        return sio.getvalue()
3383
 
 
3384
 
 
3385
 
class _ForkedSelftest(_Selftest):
3386
 
    """Mixin for tests needing full selftest output with forked children"""
3387
 
 
3388
 
    _test_needs_features = [features.subunit]
3389
 
 
3390
 
    def _inject_stream_into_subunit(self, stream):
3391
 
        """Monkey-patch subunit so the extra output goes to stream not stdout
3392
 
 
3393
 
        Some APIs need rewriting so this kind of bogus hackery can be replaced
3394
 
        by passing the stream param from run_tests down into ProtocolTestCase.
3395
 
        """
3396
 
        from subunit import ProtocolTestCase
3397
 
        _original_init = ProtocolTestCase.__init__
3398
 
        def _init_with_passthrough(self, *args, **kwargs):
3399
 
            _original_init(self, *args, **kwargs)
3400
 
            self._passthrough = stream
3401
 
        self.overrideAttr(ProtocolTestCase, "__init__", _init_with_passthrough)
3402
 
 
3403
 
    def _run_selftest(self, **kwargs):
3404
 
        # GZ 2011-05-26: Add a PosixSystem feature so this check can go away
3405
 
        if getattr(os, "fork", None) is None:
3406
 
            raise tests.TestNotApplicable("Platform doesn't support forking")
3407
 
        # Make sure the fork code is actually invoked by claiming two cores
3408
 
        self.overrideAttr(osutils, "local_concurrency", lambda: 2)
3409
 
        kwargs.setdefault("suite_decorators", []).append(tests.fork_decorator)
3410
 
        return super(_ForkedSelftest, self)._run_selftest(**kwargs)
3411
 
 
3412
 
 
3413
 
class TestParallelFork(_ForkedSelftest, tests.TestCase):
3414
 
    """Check operation of --parallel=fork selftest option"""
3415
 
 
3416
 
    def test_error_in_child_during_fork(self):
3417
 
        """Error in a forked child during test setup should get reported"""
3418
 
        class Test(tests.TestCase):
3419
 
            def testMethod(self):
3420
 
                pass
3421
 
        # We don't care what, just break something that a child will run
3422
 
        self.overrideAttr(tests, "workaround_zealous_crypto_random", None)
3423
 
        out = self._run_selftest(test_suite_factory=Test)
3424
 
        # Lines from the tracebacks of the two child processes may be mixed
3425
 
        # together due to the way subunit parses and forwards the streams,
3426
 
        # so permit extra lines between each part of the error output.
3427
 
        self.assertContainsRe(out,
3428
 
            "Traceback.*:\n"
3429
 
            "(?:.*\n)*"
3430
 
            ".+ in fork_for_tests\n"
3431
 
            "(?:.*\n)*"
3432
 
            "\s*workaround_zealous_crypto_random\(\)\n"
3433
 
            "(?:.*\n)*"
3434
 
            "TypeError:")
3435
 
 
3436
 
 
3437
 
class TestUncollectedWarnings(_Selftest, tests.TestCase):
3438
 
    """Check a test case still alive after being run emits a warning"""
3439
 
 
3440
 
    class Test(tests.TestCase):
3441
 
        def test_pass(self):
3442
 
            pass
3443
 
        def test_self_ref(self):
3444
 
            self.also_self = self.test_self_ref
3445
 
        def test_skip(self):
3446
 
            self.skip("Don't need")
3447
 
 
3448
 
    def _get_suite(self):
3449
 
        return TestUtil.TestSuite([
3450
 
            self.Test("test_pass"),
3451
 
            self.Test("test_self_ref"),
3452
 
            self.Test("test_skip"),
3453
 
            ])
3454
 
 
3455
 
    def _run_selftest_with_suite(self, **kwargs):
3456
 
        old_flags = tests.selftest_debug_flags
3457
 
        tests.selftest_debug_flags = old_flags.union(["uncollected_cases"])
3458
 
        gc_on = gc.isenabled()
3459
 
        if gc_on:
3460
 
            gc.disable()
3461
 
        try:
3462
 
            output = self._run_selftest(test_suite_factory=self._get_suite,
3463
 
                **kwargs)
3464
 
        finally:
3465
 
            if gc_on:
3466
 
                gc.enable()
3467
 
            tests.selftest_debug_flags = old_flags
3468
 
        self.assertNotContainsRe(output, "Uncollected test case.*test_pass")
3469
 
        self.assertContainsRe(output, "Uncollected test case.*test_self_ref")
3470
 
        return output
3471
 
 
3472
 
    def test_testsuite(self):
3473
 
        self._run_selftest_with_suite()
3474
 
 
3475
 
    def test_pattern(self):
3476
 
        out = self._run_selftest_with_suite(pattern="test_(?:pass|self_ref)$")
3477
 
        self.assertNotContainsRe(out, "test_skip")
3478
 
 
3479
 
    def test_exclude_pattern(self):
3480
 
        out = self._run_selftest_with_suite(exclude_pattern="test_skip$")
3481
 
        self.assertNotContainsRe(out, "test_skip")
3482
 
 
3483
 
    def test_random_seed(self):
3484
 
        self._run_selftest_with_suite(random_seed="now")
3485
 
 
3486
 
    def test_matching_tests_first(self):
3487
 
        self._run_selftest_with_suite(matching_tests_first=True,
3488
 
            pattern="test_self_ref$")
3489
 
 
3490
 
    def test_starting_with_and_exclude(self):
3491
 
        out = self._run_selftest_with_suite(starting_with=["bt."],
3492
 
            exclude_pattern="test_skip$")
3493
 
        self.assertNotContainsRe(out, "test_skip")
3494
 
 
3495
 
    def test_additonal_decorator(self):
3496
 
        out = self._run_selftest_with_suite(
3497
 
            suite_decorators=[tests.TestDecorator])
3498
 
 
3499
 
 
3500
 
class TestUncollectedWarningsSubunit(TestUncollectedWarnings):
3501
 
    """Check warnings from tests staying alive are emitted with subunit"""
3502
 
 
3503
 
    _test_needs_features = [features.subunit]
3504
 
 
3505
 
    def _run_selftest_with_suite(self, **kwargs):
3506
 
        return TestUncollectedWarnings._run_selftest_with_suite(self,
3507
 
            runner_class=tests.SubUnitBzrRunner, **kwargs)
3508
 
 
3509
 
 
3510
 
class TestUncollectedWarningsForked(_ForkedSelftest, TestUncollectedWarnings):
3511
 
    """Check warnings from tests staying alive are emitted when forking"""
3512
 
 
3513
 
 
3514
3388
class TestEnvironHandling(tests.TestCase):
3515
3389
 
3516
3390
    def test_overrideEnv_None_called_twice_doesnt_leak(self):