38
38
    has_dirstate_helpers_pyx = False
 
41
 
compiled_dirstate_helpers_feature = tests.ModuleAvailableFeature(
 
42
 
                                'bzrlib._dirstate_helpers_pyx')
 
 
41
class _CompiledDirstateHelpersFeature(tests.Feature):
 
 
43
        return has_dirstate_helpers_pyx
 
 
45
    def feature_name(self):
 
 
46
        return 'bzrlib._dirstate_helpers_pyx'
 
 
47
CompiledDirstateHelpersFeature = _CompiledDirstateHelpersFeature()
 
45
50
def load_tests(basic_tests, module, loader):
 
 
52
57
    ue_scenarios = [('dirstate_Python',
 
53
58
                     {'update_entry': dirstate.py_update_entry})]
 
54
 
    if compiled_dirstate_helpers_feature.available():
 
55
 
        update_entry = compiled_dirstate_helpers_feature.module.update_entry
 
56
 
        pyrex_scenario = ('dirstate_Pyrex', {'update_entry': update_entry})
 
 
59
    if has_dirstate_helpers_pyx:
 
 
60
        pyrex_scenario = ('dirstate_Pyrex',
 
 
61
                          {'update_entry': _dirstate_helpers_pyx.update_entry})
 
57
62
        ue_scenarios.append(pyrex_scenario)
 
58
63
    process_entry_tests, remaining_tests = tests.split_suite_by_condition(
 
59
64
        remaining_tests, tests.condition_isinstance(TestUpdateEntry))
 
 
65
70
    pe_scenarios = [('dirstate_Python',
 
66
71
                     {'_process_entry': dirstate.ProcessEntryPython})]
 
67
 
    if compiled_dirstate_helpers_feature.available():
 
68
 
        process_entry = compiled_dirstate_helpers_feature.module.ProcessEntryC
 
69
 
        pyrex_scenario = ('dirstate_Pyrex', {'_process_entry': process_entry})
 
 
72
    if has_dirstate_helpers_pyx:
 
 
75
            {'_process_entry': _dirstate_helpers_pyx.ProcessEntryC})
 
70
76
        pe_scenarios.append(pyrex_scenario)
 
71
77
    process_entry_tests, remaining_tests = tests.split_suite_by_condition(
 
72
78
        remaining_tests, tests.condition_isinstance(TestProcessEntry))
 
 
253
259
class TestCompiledBisectPathLeft(TestBisectPathLeft):
 
254
260
    """Run all Bisect Path tests against _bisect_path_lect"""
 
256
 
    _test_needs_features = [compiled_dirstate_helpers_feature]
 
 
262
    _test_needs_features = [CompiledDirstateHelpersFeature]
 
258
264
    def get_bisect_path(self):
 
259
265
        from bzrlib._dirstate_helpers_pyx import _bisect_path_left
 
 
274
280
class TestCompiledBisectPathRight(TestBisectPathRight):
 
275
281
    """Run all Bisect Path tests against _bisect_path_right"""
 
277
 
    _test_needs_features = [compiled_dirstate_helpers_feature]
 
 
283
    _test_needs_features = [CompiledDirstateHelpersFeature]
 
279
285
    def get_bisect_path(self):
 
280
286
        from bzrlib._dirstate_helpers_pyx import _bisect_path_right
 
 
508
514
class TestCompiledCmpByDirs(TestCmpByDirs):
 
509
515
    """Test the pyrex implementation of cmp_by_dirs"""
 
511
 
    _test_needs_features = [compiled_dirstate_helpers_feature]
 
 
517
    _test_needs_features = [CompiledDirstateHelpersFeature]
 
513
519
    def get_cmp_by_dirs(self):
 
514
520
        from bzrlib._dirstate_helpers_pyx import cmp_by_dirs
 
 
659
665
class TestCompiledCmpPathByDirblock(TestCmpPathByDirblock):
 
660
666
    """Test the pyrex implementation of _cmp_path_by_dirblock"""
 
662
 
    _test_needs_features = [compiled_dirstate_helpers_feature]
 
 
668
    _test_needs_features = [CompiledDirstateHelpersFeature]
 
664
670
    def get_cmp_by_dirs(self):
 
665
671
        from bzrlib._dirstate_helpers_pyx import _cmp_path_by_dirblock
 
 
669
675
class TestMemRChr(tests.TestCase):
 
670
676
    """Test memrchr functionality"""
 
672
 
    _test_needs_features = [compiled_dirstate_helpers_feature]
 
 
678
    _test_needs_features = [CompiledDirstateHelpersFeature]
 
674
680
    def assertMemRChr(self, expected, s, c):
 
675
681
        from bzrlib._dirstate_helpers_pyx import _py_memrchr
 
 
738
744
    def test_trailing_garbage(self):
 
739
745
        tree, state, expected = self.create_basic_dirstate()
 
740
 
        # On Linux, we can write extra data as long as we haven't read yet, but
 
741
 
        # on Win32, if you've opened the file with FILE_SHARE_READ, trying to
 
742
 
        # open it in append mode will fail.
 
 
746
        # We can modify the file as long as it hasn't been read yet.
 
744
747
        f = open('dirstate', 'ab')
 
746
749
            # Add bogus trailing garbage
 
747
750
            f.write('bogus\n')
 
751
753
        e = self.assertRaises(errors.DirstateCorrupt,
 
752
754
                              state._read_dirblocks_if_needed)
 
753
755
        # Make sure we mention the bogus characters in the error
 
 
757
759
class TestCompiledReadDirblocks(TestReadDirblocks):
 
758
760
    """Test the pyrex implementation of _read_dirblocks"""
 
760
 
    _test_needs_features = [compiled_dirstate_helpers_feature]
 
 
762
    _test_needs_features = [CompiledDirstateHelpersFeature]
 
762
764
    def get_read_dirblocks(self):
 
763
765
        from bzrlib._dirstate_helpers_pyx import _read_dirblocks
 
 
775
777
    def test_bisect_dirblock(self):
 
776
 
        if compiled_dirstate_helpers_feature.available():
 
 
778
        if CompiledDirstateHelpersFeature.available():
 
777
779
            from bzrlib._dirstate_helpers_pyx import bisect_dirblock
 
779
781
            from bzrlib._dirstate_helpers_py import bisect_dirblock
 
780
782
        self.assertIs(bisect_dirblock, dirstate.bisect_dirblock)
 
782
784
    def test__bisect_path_left(self):
 
783
 
        if compiled_dirstate_helpers_feature.available():
 
 
785
        if CompiledDirstateHelpersFeature.available():
 
784
786
            from bzrlib._dirstate_helpers_pyx import _bisect_path_left
 
786
788
            from bzrlib._dirstate_helpers_py import _bisect_path_left
 
787
789
        self.assertIs(_bisect_path_left, dirstate._bisect_path_left)
 
789
791
    def test__bisect_path_right(self):
 
790
 
        if compiled_dirstate_helpers_feature.available():
 
 
792
        if CompiledDirstateHelpersFeature.available():
 
791
793
            from bzrlib._dirstate_helpers_pyx import _bisect_path_right
 
793
795
            from bzrlib._dirstate_helpers_py import _bisect_path_right
 
794
796
        self.assertIs(_bisect_path_right, dirstate._bisect_path_right)
 
796
798
    def test_cmp_by_dirs(self):
 
797
 
        if compiled_dirstate_helpers_feature.available():
 
 
799
        if CompiledDirstateHelpersFeature.available():
 
798
800
            from bzrlib._dirstate_helpers_pyx import cmp_by_dirs
 
800
802
            from bzrlib._dirstate_helpers_py import cmp_by_dirs
 
801
803
        self.assertIs(cmp_by_dirs, dirstate.cmp_by_dirs)
 
803
805
    def test__read_dirblocks(self):
 
804
 
        if compiled_dirstate_helpers_feature.available():
 
 
806
        if CompiledDirstateHelpersFeature.available():
 
805
807
            from bzrlib._dirstate_helpers_pyx import _read_dirblocks
 
807
809
            from bzrlib._dirstate_helpers_py import _read_dirblocks
 
808
810
        self.assertIs(_read_dirblocks, dirstate._read_dirblocks)
 
810
812
    def test_update_entry(self):
 
811
 
        if compiled_dirstate_helpers_feature.available():
 
 
813
        if CompiledDirstateHelpersFeature.available():
 
812
814
            from bzrlib._dirstate_helpers_pyx import update_entry
 
814
816
            from bzrlib.dirstate import update_entry
 
815
817
        self.assertIs(update_entry, dirstate.update_entry)
 
817
819
    def test_process_entry(self):
 
818
 
        if compiled_dirstate_helpers_feature.available():
 
 
820
        if CompiledDirstateHelpersFeature.available():
 
819
821
            from bzrlib._dirstate_helpers_pyx import ProcessEntryC
 
820
822
            self.assertIs(ProcessEntryC, dirstate._process_entry)
 
 
833
835
        super(TestUpdateEntry, self).setUp()
 
834
 
        self.overrideAttr(dirstate, 'update_entry', self.update_entry)
 
 
836
        orig = dirstate.update_entry
 
 
838
            dirstate.update_entry = orig
 
 
839
        self.addCleanup(cleanup)
 
 
840
        dirstate.update_entry = self.update_entry
 
836
842
    def get_state_with_a(self):
 
837
843
        """Create a DirState tracking a single object named 'a'"""
 
 
1275
1281
    def setUp(self):
 
1276
1282
        super(TestProcessEntry, self).setUp()
 
1277
 
        self.overrideAttr(dirstate, '_process_entry', self._process_entry)
 
 
1283
        orig = dirstate._process_entry
 
 
1285
            dirstate._process_entry = orig
 
 
1286
        self.addCleanup(cleanup)
 
 
1287
        dirstate._process_entry = self._process_entry
 
1279
1289
    def assertChangedFileIds(self, expected, tree):
 
1280
1290
        tree.lock_read()
 
 
1286
1296
        self.assertEqual(sorted(expected), sorted(file_ids))
 
1288
 
    def test_exceptions_raised(self):
 
1289
 
        # This is a direct test of bug #495023, it relies on osutils.is_inside
 
1290
 
        # getting called in an inner function. Which makes it a bit brittle,
 
1291
 
        # but at least it does reproduce the bug.
 
1292
 
        tree = self.make_branch_and_tree('tree')
 
1293
 
        self.build_tree(['tree/file', 'tree/dir/', 'tree/dir/sub',
 
1294
 
                         'tree/dir2/', 'tree/dir2/sub2'])
 
1295
 
        tree.add(['file', 'dir', 'dir/sub', 'dir2', 'dir2/sub2'])
 
1296
 
        tree.commit('first commit')
 
1298
 
        self.addCleanup(tree.unlock)
 
1299
 
        basis_tree = tree.basis_tree()
 
1300
 
        def is_inside_raises(*args, **kwargs):
 
1301
 
            raise RuntimeError('stop this')
 
1302
 
        self.overrideAttr(osutils, 'is_inside', is_inside_raises)
 
1303
 
        self.assertListRaises(RuntimeError, tree.iter_changes, basis_tree)
 
1305
1298
    def test_simple_changes(self):
 
1306
1299
        tree = self.make_branch_and_tree('tree')
 
1307
1300
        self.build_tree(['tree/file'])