711
691
self.assertEqual(dirstate.DirState.IN_MEMORY_UNMODIFIED,
712
692
state._dirblock_state)
714
def test_trailing_garbage(self):
715
tree, state, expected = self.create_basic_dirstate()
716
# On Unix, we can write extra data as long as we haven't read yet, but
717
# on Win32, if you've opened the file with FILE_SHARE_READ, trying to
718
# open it in append mode will fail.
720
f = open('dirstate', 'ab')
722
# Add bogus trailing garbage
727
e = self.assertRaises(errors.DirstateCorrupt,
728
state._read_dirblocks_if_needed)
729
# Make sure we mention the bogus characters in the error
730
self.assertContainsRe(str(e), 'bogus')
733
695
class TestCompiledReadDirblocks(TestReadDirblocks):
734
696
"""Test the pyrex implementation of _read_dirblocks"""
736
_test_needs_features = [compiled_dirstate_helpers_feature]
698
_test_needs_features = [CompiledDirstateHelpersFeature]
738
700
def get_read_dirblocks(self):
739
from bzrlib._dirstate_helpers_pyx import _read_dirblocks
740
return _read_dirblocks
701
from bzrlib._dirstate_helpers_c import _read_dirblocks_c
702
return _read_dirblocks_c
743
705
class TestUsingCompiledIfAvailable(tests.TestCase):
744
706
"""Check that any compiled functions that are available are the default.
746
708
It is possible to have typos, etc in the import line, such that
747
_dirstate_helpers_pyx is actually available, but the compiled functions are
709
_dirstate_helpers_c is actually available, but the compiled functions are
751
713
def test_bisect_dirblock(self):
752
if compiled_dirstate_helpers_feature.available():
753
from bzrlib._dirstate_helpers_pyx import bisect_dirblock
714
if CompiledDirstateHelpersFeature.available():
715
from bzrlib._dirstate_helpers_c import bisect_dirblock_c
716
self.assertIs(bisect_dirblock_c, dirstate.bisect_dirblock)
755
from bzrlib._dirstate_helpers_py import bisect_dirblock
756
self.assertIs(bisect_dirblock, dirstate.bisect_dirblock)
718
from bzrlib._dirstate_helpers_py import bisect_dirblock_py
719
self.assertIs(bisect_dirblock_py, dirstate.bisect_dirblock)
758
721
def test__bisect_path_left(self):
759
if compiled_dirstate_helpers_feature.available():
760
from bzrlib._dirstate_helpers_pyx import _bisect_path_left
722
if CompiledDirstateHelpersFeature.available():
723
from bzrlib._dirstate_helpers_c import _bisect_path_left_c
724
self.assertIs(_bisect_path_left_c, dirstate._bisect_path_left)
762
from bzrlib._dirstate_helpers_py import _bisect_path_left
763
self.assertIs(_bisect_path_left, dirstate._bisect_path_left)
726
from bzrlib._dirstate_helpers_py import _bisect_path_left_py
727
self.assertIs(_bisect_path_left_py, dirstate._bisect_path_left)
765
729
def test__bisect_path_right(self):
766
if compiled_dirstate_helpers_feature.available():
767
from bzrlib._dirstate_helpers_pyx import _bisect_path_right
730
if CompiledDirstateHelpersFeature.available():
731
from bzrlib._dirstate_helpers_c import _bisect_path_right_c
732
self.assertIs(_bisect_path_right_c, dirstate._bisect_path_right)
769
from bzrlib._dirstate_helpers_py import _bisect_path_right
770
self.assertIs(_bisect_path_right, dirstate._bisect_path_right)
734
from bzrlib._dirstate_helpers_py import _bisect_path_right_py
735
self.assertIs(_bisect_path_right_py, dirstate._bisect_path_right)
772
737
def test_cmp_by_dirs(self):
773
if compiled_dirstate_helpers_feature.available():
774
from bzrlib._dirstate_helpers_pyx import cmp_by_dirs
738
if CompiledDirstateHelpersFeature.available():
739
from bzrlib._dirstate_helpers_c import cmp_by_dirs_c
740
self.assertIs(cmp_by_dirs_c, dirstate.cmp_by_dirs)
776
from bzrlib._dirstate_helpers_py import cmp_by_dirs
777
self.assertIs(cmp_by_dirs, dirstate.cmp_by_dirs)
742
from bzrlib._dirstate_helpers_py import cmp_by_dirs_py
743
self.assertIs(cmp_by_dirs_py, dirstate.cmp_by_dirs)
779
745
def test__read_dirblocks(self):
780
if compiled_dirstate_helpers_feature.available():
781
from bzrlib._dirstate_helpers_pyx import _read_dirblocks
783
from bzrlib._dirstate_helpers_py import _read_dirblocks
784
self.assertIs(_read_dirblocks, dirstate._read_dirblocks)
786
def test_update_entry(self):
787
if compiled_dirstate_helpers_feature.available():
788
from bzrlib._dirstate_helpers_pyx import update_entry
790
from bzrlib.dirstate import update_entry
791
self.assertIs(update_entry, dirstate.update_entry)
793
def test_process_entry(self):
794
if compiled_dirstate_helpers_feature.available():
795
from bzrlib._dirstate_helpers_pyx import ProcessEntryC
796
self.assertIs(ProcessEntryC, dirstate._process_entry)
798
from bzrlib.dirstate import ProcessEntryPython
799
self.assertIs(ProcessEntryPython, dirstate._process_entry)
802
class TestUpdateEntry(test_dirstate.TestCaseWithDirState):
803
"""Test the DirState.update_entry functions"""
805
scenarios = multiply_scenarios(
806
dir_reader_scenarios(), ue_scenarios)
812
super(TestUpdateEntry, self).setUp()
813
self.overrideAttr(dirstate, 'update_entry', self.update_entry)
815
def get_state_with_a(self):
816
"""Create a DirState tracking a single object named 'a'"""
817
state = test_dirstate.InstrumentedDirState.initialize('dirstate')
818
self.addCleanup(state.unlock)
819
state.add('a', 'a-id', 'file', None, '')
820
entry = state._get_entry(0, path_utf8='a')
823
def test_observed_sha1_cachable(self):
824
state, entry = self.get_state_with_a()
825
atime = time.time() - 10
826
self.build_tree(['a'])
827
statvalue = os.lstat('a')
828
statvalue = test_dirstate._FakeStat(statvalue.st_size, atime, atime,
829
statvalue.st_dev, statvalue.st_ino, statvalue.st_mode)
830
state._observed_sha1(entry, "foo", statvalue)
831
self.assertEqual('foo', entry[1][0][1])
832
packed_stat = dirstate.pack_stat(statvalue)
833
self.assertEqual(packed_stat, entry[1][0][4])
835
def test_observed_sha1_not_cachable(self):
836
state, entry = self.get_state_with_a()
837
oldval = entry[1][0][1]
838
oldstat = entry[1][0][4]
839
self.build_tree(['a'])
840
statvalue = os.lstat('a')
841
state._observed_sha1(entry, "foo", statvalue)
842
self.assertEqual(oldval, entry[1][0][1])
843
self.assertEqual(oldstat, entry[1][0][4])
845
def test_update_entry(self):
846
state, _ = self.get_state_with_a()
847
tree = self.make_branch_and_tree('tree')
849
empty_revid = tree.commit('empty')
850
self.build_tree(['tree/a'])
851
tree.add(['a'], ['a-id'])
852
with_a_id = tree.commit('with_a')
853
self.addCleanup(tree.unlock)
854
state.set_parent_trees(
855
[(empty_revid, tree.branch.repository.revision_tree(empty_revid))],
857
entry = state._get_entry(0, path_utf8='a')
858
self.build_tree(['a'])
859
# Add one where we don't provide the stat or sha already
860
self.assertEqual(('', 'a', 'a-id'), entry[0])
861
self.assertEqual(('f', '', 0, False, dirstate.DirState.NULLSTAT),
863
# Flush the buffers to disk
865
self.assertEqual(dirstate.DirState.IN_MEMORY_UNMODIFIED,
866
state._dirblock_state)
868
stat_value = os.lstat('a')
869
packed_stat = dirstate.pack_stat(stat_value)
870
link_or_sha1 = self.update_entry(state, entry, abspath='a',
871
stat_value=stat_value)
872
self.assertEqual(None, link_or_sha1)
874
# The dirblock entry should not have computed or cached the file's
875
# sha1, but it did update the files' st_size. However, this is not
876
# worth writing a dirstate file for, so we leave the state UNMODIFIED
877
self.assertEqual(('f', '', 14, False, dirstate.DirState.NULLSTAT),
879
self.assertEqual(dirstate.DirState.IN_MEMORY_UNMODIFIED,
880
state._dirblock_state)
881
mode = stat_value.st_mode
882
self.assertEqual([('is_exec', mode, False)], state._log)
885
self.assertEqual(dirstate.DirState.IN_MEMORY_UNMODIFIED,
886
state._dirblock_state)
888
# Roll the clock back so the file is guaranteed to look too new. We
889
# should still not compute the sha1.
890
state.adjust_time(-10)
893
link_or_sha1 = self.update_entry(state, entry, abspath='a',
894
stat_value=stat_value)
895
self.assertEqual([('is_exec', mode, False)], state._log)
896
self.assertEqual(None, link_or_sha1)
897
self.assertEqual(dirstate.DirState.IN_MEMORY_UNMODIFIED,
898
state._dirblock_state)
899
self.assertEqual(('f', '', 14, False, dirstate.DirState.NULLSTAT),
903
# If it is cachable (the clock has moved forward) but new it still
904
# won't calculate the sha or cache it.
905
state.adjust_time(+20)
907
link_or_sha1 = dirstate.update_entry(state, entry, abspath='a',
908
stat_value=stat_value)
909
self.assertEqual(None, link_or_sha1)
910
self.assertEqual([('is_exec', mode, False)], state._log)
911
self.assertEqual(('f', '', 14, False, dirstate.DirState.NULLSTAT),
913
self.assertEqual(dirstate.DirState.IN_MEMORY_UNMODIFIED,
914
state._dirblock_state)
916
# If the file is no longer new, and the clock has been moved forward
917
# sufficiently, it will cache the sha.
919
state.set_parent_trees(
920
[(with_a_id, tree.branch.repository.revision_tree(with_a_id))],
922
entry = state._get_entry(0, path_utf8='a')
924
link_or_sha1 = self.update_entry(state, entry, abspath='a',
925
stat_value=stat_value)
926
self.assertEqual('b50e5406bb5e153ebbeb20268fcf37c87e1ecfb6',
928
self.assertEqual([('is_exec', mode, False), ('sha1', 'a')],
930
self.assertEqual(('f', link_or_sha1, 14, False, packed_stat),
933
# Subsequent calls will just return the cached value
935
link_or_sha1 = self.update_entry(state, entry, abspath='a',
936
stat_value=stat_value)
937
self.assertEqual('b50e5406bb5e153ebbeb20268fcf37c87e1ecfb6',
939
self.assertEqual([], state._log)
940
self.assertEqual(('f', link_or_sha1, 14, False, packed_stat),
943
def test_update_entry_symlink(self):
944
"""Update entry should read symlinks."""
945
self.requireFeature(tests.SymlinkFeature)
946
state, entry = self.get_state_with_a()
948
self.assertEqual(dirstate.DirState.IN_MEMORY_UNMODIFIED,
949
state._dirblock_state)
950
os.symlink('target', 'a')
952
state.adjust_time(-10) # Make the symlink look new
953
stat_value = os.lstat('a')
954
packed_stat = dirstate.pack_stat(stat_value)
955
link_or_sha1 = self.update_entry(state, entry, abspath='a',
956
stat_value=stat_value)
957
self.assertEqual('target', link_or_sha1)
958
self.assertEqual([('read_link', 'a', '')], state._log)
959
# Dirblock is not updated (the link is too new)
960
self.assertEqual([('l', '', 6, False, dirstate.DirState.NULLSTAT)],
962
self.assertEqual(dirstate.DirState.IN_MEMORY_MODIFIED,
963
state._dirblock_state)
965
# Because the stat_value looks new, we should re-read the target
966
link_or_sha1 = self.update_entry(state, entry, abspath='a',
967
stat_value=stat_value)
968
self.assertEqual('target', link_or_sha1)
969
self.assertEqual([('read_link', 'a', ''),
970
('read_link', 'a', ''),
972
self.assertEqual([('l', '', 6, False, dirstate.DirState.NULLSTAT)],
974
state.adjust_time(+20) # Skip into the future, all files look old
975
link_or_sha1 = self.update_entry(state, entry, abspath='a',
976
stat_value=stat_value)
977
self.assertEqual('target', link_or_sha1)
978
# We need to re-read the link because only now can we cache it
979
self.assertEqual([('read_link', 'a', ''),
980
('read_link', 'a', ''),
981
('read_link', 'a', ''),
983
self.assertEqual([('l', 'target', 6, False, packed_stat)],
986
# Another call won't re-read the link
987
self.assertEqual([('read_link', 'a', ''),
988
('read_link', 'a', ''),
989
('read_link', 'a', ''),
991
link_or_sha1 = self.update_entry(state, entry, abspath='a',
992
stat_value=stat_value)
993
self.assertEqual('target', link_or_sha1)
994
self.assertEqual([('l', 'target', 6, False, packed_stat)],
997
def do_update_entry(self, state, entry, abspath):
998
stat_value = os.lstat(abspath)
999
return self.update_entry(state, entry, abspath, stat_value)
1001
def test_update_entry_dir(self):
1002
state, entry = self.get_state_with_a()
1003
self.build_tree(['a/'])
1004
self.assertIs(None, self.do_update_entry(state, entry, 'a'))
1006
def test_update_entry_dir_unchanged(self):
1007
state, entry = self.get_state_with_a()
1008
self.build_tree(['a/'])
1009
state.adjust_time(+20)
1010
self.assertIs(None, self.do_update_entry(state, entry, 'a'))
1011
# a/ used to be a file, but is now a directory, worth saving
1012
self.assertEqual(dirstate.DirState.IN_MEMORY_MODIFIED,
1013
state._dirblock_state)
1015
self.assertEqual(dirstate.DirState.IN_MEMORY_UNMODIFIED,
1016
state._dirblock_state)
1017
# No changes to a/ means not worth saving.
1018
self.assertIs(None, self.do_update_entry(state, entry, 'a'))
1019
self.assertEqual(dirstate.DirState.IN_MEMORY_UNMODIFIED,
1020
state._dirblock_state)
1021
# Change the last-modified time for the directory
1022
t = time.time() - 100.0
1024
os.utime('a', (t, t))
1026
# It looks like Win32 + FAT doesn't allow to change times on a dir.
1027
raise tests.TestSkipped("can't update mtime of a dir on FAT")
1028
saved_packed_stat = entry[1][0][-1]
1029
self.assertIs(None, self.do_update_entry(state, entry, 'a'))
1030
# We *do* go ahead and update the information in the dirblocks, but we
1031
# don't bother setting IN_MEMORY_MODIFIED because it is trivial to
1033
self.assertNotEqual(saved_packed_stat, entry[1][0][-1])
1034
self.assertEqual(dirstate.DirState.IN_MEMORY_UNMODIFIED,
1035
state._dirblock_state)
1037
def test_update_entry_file_unchanged(self):
1038
state, _ = self.get_state_with_a()
1039
tree = self.make_branch_and_tree('tree')
1041
self.build_tree(['tree/a'])
1042
tree.add(['a'], ['a-id'])
1043
with_a_id = tree.commit('witha')
1044
self.addCleanup(tree.unlock)
1045
state.set_parent_trees(
1046
[(with_a_id, tree.branch.repository.revision_tree(with_a_id))],
1048
entry = state._get_entry(0, path_utf8='a')
1049
self.build_tree(['a'])
1050
sha1sum = 'b50e5406bb5e153ebbeb20268fcf37c87e1ecfb6'
1051
state.adjust_time(+20)
1052
self.assertEqual(sha1sum, self.do_update_entry(state, entry, 'a'))
1053
self.assertEqual(dirstate.DirState.IN_MEMORY_MODIFIED,
1054
state._dirblock_state)
1056
self.assertEqual(dirstate.DirState.IN_MEMORY_UNMODIFIED,
1057
state._dirblock_state)
1058
self.assertEqual(sha1sum, self.do_update_entry(state, entry, 'a'))
1059
self.assertEqual(dirstate.DirState.IN_MEMORY_UNMODIFIED,
1060
state._dirblock_state)
1062
def test_update_entry_tree_reference(self):
1063
state = test_dirstate.InstrumentedDirState.initialize('dirstate')
1064
self.addCleanup(state.unlock)
1065
state.add('r', 'r-id', 'tree-reference', None, '')
1066
self.build_tree(['r/'])
1067
entry = state._get_entry(0, path_utf8='r')
1068
self.do_update_entry(state, entry, 'r')
1069
entry = state._get_entry(0, path_utf8='r')
1070
self.assertEqual('t', entry[1][0][0])
1072
def create_and_test_file(self, state, entry):
1073
"""Create a file at 'a' and verify the state finds it during update.
1075
The state should already be versioning *something* at 'a'. This makes
1076
sure that state.update_entry recognizes it as a file.
1078
self.build_tree(['a'])
1079
stat_value = os.lstat('a')
1080
packed_stat = dirstate.pack_stat(stat_value)
1082
link_or_sha1 = self.do_update_entry(state, entry, abspath='a')
1083
self.assertEqual(None, link_or_sha1)
1084
self.assertEqual([('f', '', 14, False, dirstate.DirState.NULLSTAT)],
1088
def create_and_test_dir(self, state, entry):
1089
"""Create a directory at 'a' and verify the state finds it.
1091
The state should already be versioning *something* at 'a'. This makes
1092
sure that state.update_entry recognizes it as a directory.
1094
self.build_tree(['a/'])
1095
stat_value = os.lstat('a')
1096
packed_stat = dirstate.pack_stat(stat_value)
1098
link_or_sha1 = self.do_update_entry(state, entry, abspath='a')
1099
self.assertIs(None, link_or_sha1)
1100
self.assertEqual([('d', '', 0, False, packed_stat)], entry[1])
1104
# FIXME: Add unicode version
1105
def create_and_test_symlink(self, state, entry):
1106
"""Create a symlink at 'a' and verify the state finds it.
1108
The state should already be versioning *something* at 'a'. This makes
1109
sure that state.update_entry recognizes it as a symlink.
1111
This should not be called if this platform does not have symlink
1114
# caller should care about skipping test on platforms without symlinks
1115
os.symlink('path/to/foo', 'a')
1117
stat_value = os.lstat('a')
1118
packed_stat = dirstate.pack_stat(stat_value)
1120
link_or_sha1 = self.do_update_entry(state, entry, abspath='a')
1121
self.assertEqual('path/to/foo', link_or_sha1)
1122
self.assertEqual([('l', 'path/to/foo', 11, False, packed_stat)],
1126
def test_update_file_to_dir(self):
1127
"""If a file changes to a directory we return None for the sha.
1128
We also update the inventory record.
1130
state, entry = self.get_state_with_a()
1131
# The file sha1 won't be cached unless the file is old
1132
state.adjust_time(+10)
1133
self.create_and_test_file(state, entry)
1135
self.create_and_test_dir(state, entry)
1137
def test_update_file_to_symlink(self):
1138
"""File becomes a symlink"""
1139
self.requireFeature(tests.SymlinkFeature)
1140
state, entry = self.get_state_with_a()
1141
# The file sha1 won't be cached unless the file is old
1142
state.adjust_time(+10)
1143
self.create_and_test_file(state, entry)
1145
self.create_and_test_symlink(state, entry)
1147
def test_update_dir_to_file(self):
1148
"""Directory becoming a file updates the entry."""
1149
state, entry = self.get_state_with_a()
1150
# The file sha1 won't be cached unless the file is old
1151
state.adjust_time(+10)
1152
self.create_and_test_dir(state, entry)
1154
self.create_and_test_file(state, entry)
1156
def test_update_dir_to_symlink(self):
1157
"""Directory becomes a symlink"""
1158
self.requireFeature(tests.SymlinkFeature)
1159
state, entry = self.get_state_with_a()
1160
# The symlink target won't be cached if it isn't old
1161
state.adjust_time(+10)
1162
self.create_and_test_dir(state, entry)
1164
self.create_and_test_symlink(state, entry)
1166
def test_update_symlink_to_file(self):
1167
"""Symlink becomes a file"""
1168
self.requireFeature(tests.SymlinkFeature)
1169
state, entry = self.get_state_with_a()
1170
# The symlink and file info won't be cached unless old
1171
state.adjust_time(+10)
1172
self.create_and_test_symlink(state, entry)
1174
self.create_and_test_file(state, entry)
1176
def test_update_symlink_to_dir(self):
1177
"""Symlink becomes a directory"""
1178
self.requireFeature(tests.SymlinkFeature)
1179
state, entry = self.get_state_with_a()
1180
# The symlink target won't be cached if it isn't old
1181
state.adjust_time(+10)
1182
self.create_and_test_symlink(state, entry)
1184
self.create_and_test_dir(state, entry)
1186
def test__is_executable_win32(self):
1187
state, entry = self.get_state_with_a()
1188
self.build_tree(['a'])
1190
# Make sure we are using the win32 implementation of _is_executable
1191
state._is_executable = state._is_executable_win32
1193
# The file on disk is not executable, but we are marking it as though
1194
# it is. With _is_executable_win32 we ignore what is on disk.
1195
entry[1][0] = ('f', '', 0, True, dirstate.DirState.NULLSTAT)
1197
stat_value = os.lstat('a')
1198
packed_stat = dirstate.pack_stat(stat_value)
1200
state.adjust_time(-10) # Make sure everything is new
1201
self.update_entry(state, entry, abspath='a', stat_value=stat_value)
1203
# The row is updated, but the executable bit stays set.
1204
self.assertEqual([('f', '', 14, True, dirstate.DirState.NULLSTAT)],
1207
# Make the disk object look old enough to cache (but it won't cache the
1208
# sha as it is a new file).
1209
state.adjust_time(+20)
1210
digest = 'b50e5406bb5e153ebbeb20268fcf37c87e1ecfb6'
1211
self.update_entry(state, entry, abspath='a', stat_value=stat_value)
1212
self.assertEqual([('f', '', 14, True, dirstate.DirState.NULLSTAT)],
1215
def _prepare_tree(self):
1217
text = 'Hello World\n'
1218
tree = self.make_branch_and_tree('tree')
1219
self.build_tree_contents([('tree/a file', text)])
1220
tree.add('a file', 'a-file-id')
1221
# Note: dirstate does not sha prior to the first commit
1222
# so commit now in order for the test to work
1223
tree.commit('first')
1226
def test_sha1provider_sha1_used(self):
1227
tree, text = self._prepare_tree()
1228
state = dirstate.DirState.from_tree(tree, 'dirstate',
1229
UppercaseSHA1Provider())
1230
self.addCleanup(state.unlock)
1231
expected_sha = osutils.sha_string(text.upper() + "foo")
1232
entry = state._get_entry(0, path_utf8='a file')
1233
state._sha_cutoff_time()
1234
state._cutoff_time += 10
1235
sha1 = self.update_entry(state, entry, 'tree/a file',
1236
os.lstat('tree/a file'))
1237
self.assertEqual(expected_sha, sha1)
1239
def test_sha1provider_stat_and_sha1_used(self):
1240
tree, text = self._prepare_tree()
1242
self.addCleanup(tree.unlock)
1243
state = tree._current_dirstate()
1244
state._sha1_provider = UppercaseSHA1Provider()
1245
# If we used the standard provider, it would look like nothing has
1247
file_ids_changed = [change[0] for change
1248
in tree.iter_changes(tree.basis_tree())]
1249
self.assertEqual(['a-file-id'], file_ids_changed)
1252
class UppercaseSHA1Provider(dirstate.SHA1Provider):
1253
"""A custom SHA1Provider."""
1255
def sha1(self, abspath):
1256
return self.stat_and_sha1(abspath)[1]
1258
def stat_and_sha1(self, abspath):
1259
file_obj = file(abspath, 'rb')
1261
statvalue = os.fstat(file_obj.fileno())
1262
text = ''.join(file_obj.readlines())
1263
sha1 = osutils.sha_string(text.upper() + "foo")
1266
return statvalue, sha1
1269
class TestProcessEntry(test_dirstate.TestCaseWithDirState):
1271
scenarios = multiply_scenarios(dir_reader_scenarios(), pe_scenarios)
1274
_process_entry = None
1277
super(TestProcessEntry, self).setUp()
1278
self.overrideAttr(dirstate, '_process_entry', self._process_entry)
1280
def assertChangedFileIds(self, expected, tree):
1283
file_ids = [info[0] for info
1284
in tree.iter_changes(tree.basis_tree())]
1287
self.assertEqual(sorted(expected), sorted(file_ids))
1289
def test_exceptions_raised(self):
1290
# This is a direct test of bug #495023, it relies on osutils.is_inside
1291
# getting called in an inner function. Which makes it a bit brittle,
1292
# but at least it does reproduce the bug.
1293
tree = self.make_branch_and_tree('tree')
1294
self.build_tree(['tree/file', 'tree/dir/', 'tree/dir/sub',
1295
'tree/dir2/', 'tree/dir2/sub2'])
1296
tree.add(['file', 'dir', 'dir/sub', 'dir2', 'dir2/sub2'])
1297
tree.commit('first commit')
1299
self.addCleanup(tree.unlock)
1300
basis_tree = tree.basis_tree()
1301
def is_inside_raises(*args, **kwargs):
1302
raise RuntimeError('stop this')
1303
self.overrideAttr(osutils, 'is_inside', is_inside_raises)
1304
self.assertListRaises(RuntimeError, tree.iter_changes, basis_tree)
1306
def test_simple_changes(self):
1307
tree = self.make_branch_and_tree('tree')
1308
self.build_tree(['tree/file'])
1309
tree.add(['file'], ['file-id'])
1310
self.assertChangedFileIds([tree.get_root_id(), 'file-id'], tree)
1312
self.assertChangedFileIds([], tree)
1314
def test_sha1provider_stat_and_sha1_used(self):
1315
tree = self.make_branch_and_tree('tree')
1316
self.build_tree(['tree/file'])
1317
tree.add(['file'], ['file-id'])
1320
self.addCleanup(tree.unlock)
1321
state = tree._current_dirstate()
1322
state._sha1_provider = UppercaseSHA1Provider()
1323
self.assertChangedFileIds(['file-id'], tree)
746
if CompiledDirstateHelpersFeature.available():
747
from bzrlib._dirstate_helpers_c import _read_dirblocks_c
748
self.assertIs(_read_dirblocks_c, dirstate._read_dirblocks)
750
from bzrlib._dirstate_helpers_py import _read_dirblocks_py
751
self.assertIs(_read_dirblocks_py, dirstate._read_dirblocks)