714
691
self.assertEqual(dirstate.DirState.IN_MEMORY_UNMODIFIED,
715
692
state._dirblock_state)
717
def test_trailing_garbage(self):
718
tree, state, expected = self.create_basic_dirstate()
719
# On Unix, we can write extra data as long as we haven't read yet, but
720
# on Win32, if you've opened the file with FILE_SHARE_READ, trying to
721
# open it in append mode will fail.
723
f = open('dirstate', 'ab')
725
# Add bogus trailing garbage
730
e = self.assertRaises(errors.DirstateCorrupt,
731
state._read_dirblocks_if_needed)
732
# Make sure we mention the bogus characters in the error
733
self.assertContainsRe(str(e), 'bogus')
736
695
class TestCompiledReadDirblocks(TestReadDirblocks):
737
696
"""Test the pyrex implementation of _read_dirblocks"""
739
_test_needs_features = [compiled_dirstate_helpers_feature]
698
_test_needs_features = [CompiledDirstateHelpersFeature]
741
700
def get_read_dirblocks(self):
742
from bzrlib._dirstate_helpers_pyx import _read_dirblocks
743
return _read_dirblocks
701
from bzrlib._dirstate_helpers_c import _read_dirblocks_c
702
return _read_dirblocks_c
746
705
class TestUsingCompiledIfAvailable(tests.TestCase):
747
706
"""Check that any compiled functions that are available are the default.
749
708
It is possible to have typos, etc in the import line, such that
750
_dirstate_helpers_pyx is actually available, but the compiled functions are
709
_dirstate_helpers_c is actually available, but the compiled functions are
754
713
def test_bisect_dirblock(self):
755
if compiled_dirstate_helpers_feature.available():
756
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)
758
from bzrlib._dirstate_helpers_py import bisect_dirblock
759
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)
761
721
def test__bisect_path_left(self):
762
if compiled_dirstate_helpers_feature.available():
763
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)
765
from bzrlib._dirstate_helpers_py import _bisect_path_left
766
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)
768
729
def test__bisect_path_right(self):
769
if compiled_dirstate_helpers_feature.available():
770
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)
772
from bzrlib._dirstate_helpers_py import _bisect_path_right
773
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)
775
737
def test_cmp_by_dirs(self):
776
if compiled_dirstate_helpers_feature.available():
777
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)
779
from bzrlib._dirstate_helpers_py import cmp_by_dirs
780
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)
782
745
def test__read_dirblocks(self):
783
if compiled_dirstate_helpers_feature.available():
784
from bzrlib._dirstate_helpers_pyx import _read_dirblocks
786
from bzrlib._dirstate_helpers_py import _read_dirblocks
787
self.assertIs(_read_dirblocks, dirstate._read_dirblocks)
789
def test_update_entry(self):
790
if compiled_dirstate_helpers_feature.available():
791
from bzrlib._dirstate_helpers_pyx import update_entry
793
from bzrlib.dirstate import update_entry
794
self.assertIs(update_entry, dirstate.update_entry)
796
def test_process_entry(self):
797
if compiled_dirstate_helpers_feature.available():
798
from bzrlib._dirstate_helpers_pyx import ProcessEntryC
799
self.assertIs(ProcessEntryC, dirstate._process_entry)
801
from bzrlib.dirstate import ProcessEntryPython
802
self.assertIs(ProcessEntryPython, dirstate._process_entry)
805
class TestUpdateEntry(test_dirstate.TestCaseWithDirState):
806
"""Test the DirState.update_entry functions"""
808
scenarios = multiply_scenarios(
809
dir_reader_scenarios(), ue_scenarios)
815
super(TestUpdateEntry, self).setUp()
816
self.overrideAttr(dirstate, 'update_entry', self.update_entry)
818
def get_state_with_a(self):
819
"""Create a DirState tracking a single object named 'a'"""
820
state = test_dirstate.InstrumentedDirState.initialize('dirstate')
821
self.addCleanup(state.unlock)
822
state.add('a', 'a-id', 'file', None, '')
823
entry = state._get_entry(0, path_utf8='a')
826
def test_observed_sha1_cachable(self):
827
state, entry = self.get_state_with_a()
829
atime = time.time() - 10
830
self.build_tree(['a'])
831
statvalue = test_dirstate._FakeStat.from_stat(os.lstat('a'))
832
statvalue.st_mtime = statvalue.st_ctime = atime
833
self.assertEqual(dirstate.DirState.IN_MEMORY_UNMODIFIED,
834
state._dirblock_state)
835
state._observed_sha1(entry, "foo", statvalue)
836
self.assertEqual('foo', entry[1][0][1])
837
packed_stat = dirstate.pack_stat(statvalue)
838
self.assertEqual(packed_stat, entry[1][0][4])
839
self.assertEqual(dirstate.DirState.IN_MEMORY_HASH_MODIFIED,
840
state._dirblock_state)
842
def test_observed_sha1_not_cachable(self):
843
state, entry = self.get_state_with_a()
845
oldval = entry[1][0][1]
846
oldstat = entry[1][0][4]
847
self.build_tree(['a'])
848
statvalue = os.lstat('a')
849
self.assertEqual(dirstate.DirState.IN_MEMORY_UNMODIFIED,
850
state._dirblock_state)
851
state._observed_sha1(entry, "foo", statvalue)
852
self.assertEqual(oldval, entry[1][0][1])
853
self.assertEqual(oldstat, entry[1][0][4])
854
self.assertEqual(dirstate.DirState.IN_MEMORY_UNMODIFIED,
855
state._dirblock_state)
857
def test_update_entry(self):
858
state, _ = self.get_state_with_a()
859
tree = self.make_branch_and_tree('tree')
861
empty_revid = tree.commit('empty')
862
self.build_tree(['tree/a'])
863
tree.add(['a'], ['a-id'])
864
with_a_id = tree.commit('with_a')
865
self.addCleanup(tree.unlock)
866
state.set_parent_trees(
867
[(empty_revid, tree.branch.repository.revision_tree(empty_revid))],
869
entry = state._get_entry(0, path_utf8='a')
870
self.build_tree(['a'])
871
# Add one where we don't provide the stat or sha already
872
self.assertEqual(('', 'a', 'a-id'), entry[0])
873
self.assertEqual(('f', '', 0, False, dirstate.DirState.NULLSTAT),
875
# Flush the buffers to disk
877
self.assertEqual(dirstate.DirState.IN_MEMORY_UNMODIFIED,
878
state._dirblock_state)
880
stat_value = os.lstat('a')
881
packed_stat = dirstate.pack_stat(stat_value)
882
link_or_sha1 = self.update_entry(state, entry, abspath='a',
883
stat_value=stat_value)
884
self.assertEqual(None, link_or_sha1)
886
# The dirblock entry should not have computed or cached the file's
887
# sha1, but it did update the files' st_size. However, this is not
888
# worth writing a dirstate file for, so we leave the state UNMODIFIED
889
self.assertEqual(('f', '', 14, False, dirstate.DirState.NULLSTAT),
891
self.assertEqual(dirstate.DirState.IN_MEMORY_UNMODIFIED,
892
state._dirblock_state)
893
mode = stat_value.st_mode
894
self.assertEqual([('is_exec', mode, False)], state._log)
897
self.assertEqual(dirstate.DirState.IN_MEMORY_UNMODIFIED,
898
state._dirblock_state)
900
# Roll the clock back so the file is guaranteed to look too new. We
901
# should still not compute the sha1.
902
state.adjust_time(-10)
905
link_or_sha1 = self.update_entry(state, entry, abspath='a',
906
stat_value=stat_value)
907
self.assertEqual([('is_exec', mode, False)], state._log)
908
self.assertEqual(None, link_or_sha1)
909
self.assertEqual(dirstate.DirState.IN_MEMORY_UNMODIFIED,
910
state._dirblock_state)
911
self.assertEqual(('f', '', 14, False, dirstate.DirState.NULLSTAT),
915
# If it is cachable (the clock has moved forward) but new it still
916
# won't calculate the sha or cache it.
917
state.adjust_time(+20)
919
link_or_sha1 = dirstate.update_entry(state, entry, abspath='a',
920
stat_value=stat_value)
921
self.assertEqual(None, link_or_sha1)
922
self.assertEqual([('is_exec', mode, False)], state._log)
923
self.assertEqual(('f', '', 14, False, dirstate.DirState.NULLSTAT),
925
self.assertEqual(dirstate.DirState.IN_MEMORY_UNMODIFIED,
926
state._dirblock_state)
928
# If the file is no longer new, and the clock has been moved forward
929
# sufficiently, it will cache the sha.
931
state.set_parent_trees(
932
[(with_a_id, tree.branch.repository.revision_tree(with_a_id))],
934
entry = state._get_entry(0, path_utf8='a')
936
link_or_sha1 = self.update_entry(state, entry, abspath='a',
937
stat_value=stat_value)
938
self.assertEqual('b50e5406bb5e153ebbeb20268fcf37c87e1ecfb6',
940
self.assertEqual([('is_exec', mode, False), ('sha1', 'a')],
942
self.assertEqual(('f', link_or_sha1, 14, False, packed_stat),
945
# Subsequent calls will just return the cached value
947
link_or_sha1 = self.update_entry(state, entry, abspath='a',
948
stat_value=stat_value)
949
self.assertEqual('b50e5406bb5e153ebbeb20268fcf37c87e1ecfb6',
951
self.assertEqual([], state._log)
952
self.assertEqual(('f', link_or_sha1, 14, False, packed_stat),
955
def test_update_entry_symlink(self):
956
"""Update entry should read symlinks."""
957
self.requireFeature(features.SymlinkFeature)
958
state, entry = self.get_state_with_a()
960
self.assertEqual(dirstate.DirState.IN_MEMORY_UNMODIFIED,
961
state._dirblock_state)
962
os.symlink('target', 'a')
964
state.adjust_time(-10) # Make the symlink look new
965
stat_value = os.lstat('a')
966
packed_stat = dirstate.pack_stat(stat_value)
967
link_or_sha1 = self.update_entry(state, entry, abspath='a',
968
stat_value=stat_value)
969
self.assertEqual('target', link_or_sha1)
970
self.assertEqual([('read_link', 'a', '')], state._log)
971
# Dirblock is not updated (the link is too new)
972
self.assertEqual([('l', '', 6, False, dirstate.DirState.NULLSTAT)],
974
# The file entry turned into a symlink, that is considered
975
# HASH modified worthy.
976
self.assertEqual(dirstate.DirState.IN_MEMORY_HASH_MODIFIED,
977
state._dirblock_state)
979
# Because the stat_value looks new, we should re-read the target
981
link_or_sha1 = self.update_entry(state, entry, abspath='a',
982
stat_value=stat_value)
983
self.assertEqual('target', link_or_sha1)
984
self.assertEqual([('read_link', 'a', '')], state._log)
985
self.assertEqual([('l', '', 6, False, dirstate.DirState.NULLSTAT)],
988
state.adjust_time(+20) # Skip into the future, all files look old
990
link_or_sha1 = self.update_entry(state, entry, abspath='a',
991
stat_value=stat_value)
992
# The symlink stayed a symlink. So while it is new enough to cache, we
993
# don't bother setting the flag, because it is not really worth saving
994
# (when we stat the symlink, we'll have paged in the target.)
995
self.assertEqual(dirstate.DirState.IN_MEMORY_UNMODIFIED,
996
state._dirblock_state)
997
self.assertEqual('target', link_or_sha1)
998
# We need to re-read the link because only now can we cache it
999
self.assertEqual([('read_link', 'a', '')], state._log)
1000
self.assertEqual([('l', 'target', 6, False, packed_stat)],
1004
# Another call won't re-read the link
1005
self.assertEqual([], state._log)
1006
link_or_sha1 = self.update_entry(state, entry, abspath='a',
1007
stat_value=stat_value)
1008
self.assertEqual('target', link_or_sha1)
1009
self.assertEqual([('l', 'target', 6, False, packed_stat)],
1012
def do_update_entry(self, state, entry, abspath):
1013
stat_value = os.lstat(abspath)
1014
return self.update_entry(state, entry, abspath, stat_value)
1016
def test_update_entry_dir(self):
1017
state, entry = self.get_state_with_a()
1018
self.build_tree(['a/'])
1019
self.assertIs(None, self.do_update_entry(state, entry, 'a'))
1021
def test_update_entry_dir_unchanged(self):
1022
state, entry = self.get_state_with_a()
1023
self.build_tree(['a/'])
1024
state.adjust_time(+20)
1025
self.assertIs(None, self.do_update_entry(state, entry, 'a'))
1026
# a/ used to be a file, but is now a directory, worth saving
1027
self.assertEqual(dirstate.DirState.IN_MEMORY_MODIFIED,
1028
state._dirblock_state)
1030
self.assertEqual(dirstate.DirState.IN_MEMORY_UNMODIFIED,
1031
state._dirblock_state)
1032
# No changes to a/ means not worth saving.
1033
self.assertIs(None, self.do_update_entry(state, entry, 'a'))
1034
self.assertEqual(dirstate.DirState.IN_MEMORY_UNMODIFIED,
1035
state._dirblock_state)
1036
# Change the last-modified time for the directory
1037
t = time.time() - 100.0
1039
os.utime('a', (t, t))
1041
# It looks like Win32 + FAT doesn't allow to change times on a dir.
1042
raise tests.TestSkipped("can't update mtime of a dir on FAT")
1043
saved_packed_stat = entry[1][0][-1]
1044
self.assertIs(None, self.do_update_entry(state, entry, 'a'))
1045
# We *do* go ahead and update the information in the dirblocks, but we
1046
# don't bother setting IN_MEMORY_MODIFIED because it is trivial to
1048
self.assertNotEqual(saved_packed_stat, entry[1][0][-1])
1049
self.assertEqual(dirstate.DirState.IN_MEMORY_UNMODIFIED,
1050
state._dirblock_state)
1052
def test_update_entry_file_unchanged(self):
1053
state, _ = self.get_state_with_a()
1054
tree = self.make_branch_and_tree('tree')
1056
self.build_tree(['tree/a'])
1057
tree.add(['a'], ['a-id'])
1058
with_a_id = tree.commit('witha')
1059
self.addCleanup(tree.unlock)
1060
state.set_parent_trees(
1061
[(with_a_id, tree.branch.repository.revision_tree(with_a_id))],
1063
entry = state._get_entry(0, path_utf8='a')
1064
self.build_tree(['a'])
1065
sha1sum = 'b50e5406bb5e153ebbeb20268fcf37c87e1ecfb6'
1066
state.adjust_time(+20)
1067
self.assertEqual(sha1sum, self.do_update_entry(state, entry, 'a'))
1068
self.assertEqual(dirstate.DirState.IN_MEMORY_MODIFIED,
1069
state._dirblock_state)
1071
self.assertEqual(dirstate.DirState.IN_MEMORY_UNMODIFIED,
1072
state._dirblock_state)
1073
self.assertEqual(sha1sum, self.do_update_entry(state, entry, 'a'))
1074
self.assertEqual(dirstate.DirState.IN_MEMORY_UNMODIFIED,
1075
state._dirblock_state)
1077
def test_update_entry_tree_reference(self):
1078
state = test_dirstate.InstrumentedDirState.initialize('dirstate')
1079
self.addCleanup(state.unlock)
1080
state.add('r', 'r-id', 'tree-reference', None, '')
1081
self.build_tree(['r/'])
1082
entry = state._get_entry(0, path_utf8='r')
1083
self.do_update_entry(state, entry, 'r')
1084
entry = state._get_entry(0, path_utf8='r')
1085
self.assertEqual('t', entry[1][0][0])
1087
def create_and_test_file(self, state, entry):
1088
"""Create a file at 'a' and verify the state finds it during update.
1090
The state should already be versioning *something* at 'a'. This makes
1091
sure that state.update_entry recognizes it as a file.
1093
self.build_tree(['a'])
1094
stat_value = os.lstat('a')
1095
packed_stat = dirstate.pack_stat(stat_value)
1097
link_or_sha1 = self.do_update_entry(state, entry, abspath='a')
1098
self.assertEqual(None, link_or_sha1)
1099
self.assertEqual([('f', '', 14, False, dirstate.DirState.NULLSTAT)],
1103
def create_and_test_dir(self, state, entry):
1104
"""Create a directory at 'a' and verify the state finds it.
1106
The state should already be versioning *something* at 'a'. This makes
1107
sure that state.update_entry recognizes it as a directory.
1109
self.build_tree(['a/'])
1110
stat_value = os.lstat('a')
1111
packed_stat = dirstate.pack_stat(stat_value)
1113
link_or_sha1 = self.do_update_entry(state, entry, abspath='a')
1114
self.assertIs(None, link_or_sha1)
1115
self.assertEqual([('d', '', 0, False, packed_stat)], entry[1])
1119
# FIXME: Add unicode version
1120
def create_and_test_symlink(self, state, entry):
1121
"""Create a symlink at 'a' and verify the state finds it.
1123
The state should already be versioning *something* at 'a'. This makes
1124
sure that state.update_entry recognizes it as a symlink.
1126
This should not be called if this platform does not have symlink
1129
# caller should care about skipping test on platforms without symlinks
1130
os.symlink('path/to/foo', 'a')
1132
stat_value = os.lstat('a')
1133
packed_stat = dirstate.pack_stat(stat_value)
1135
link_or_sha1 = self.do_update_entry(state, entry, abspath='a')
1136
self.assertEqual('path/to/foo', link_or_sha1)
1137
self.assertEqual([('l', 'path/to/foo', 11, False, packed_stat)],
1141
def test_update_file_to_dir(self):
1142
"""If a file changes to a directory we return None for the sha.
1143
We also update the inventory record.
1145
state, entry = self.get_state_with_a()
1146
# The file sha1 won't be cached unless the file is old
1147
state.adjust_time(+10)
1148
self.create_and_test_file(state, entry)
1150
self.create_and_test_dir(state, entry)
1152
def test_update_file_to_symlink(self):
1153
"""File becomes a symlink"""
1154
self.requireFeature(features.SymlinkFeature)
1155
state, entry = self.get_state_with_a()
1156
# The file sha1 won't be cached unless the file is old
1157
state.adjust_time(+10)
1158
self.create_and_test_file(state, entry)
1160
self.create_and_test_symlink(state, entry)
1162
def test_update_dir_to_file(self):
1163
"""Directory becoming a file updates the entry."""
1164
state, entry = self.get_state_with_a()
1165
# The file sha1 won't be cached unless the file is old
1166
state.adjust_time(+10)
1167
self.create_and_test_dir(state, entry)
1169
self.create_and_test_file(state, entry)
1171
def test_update_dir_to_symlink(self):
1172
"""Directory becomes a symlink"""
1173
self.requireFeature(features.SymlinkFeature)
1174
state, entry = self.get_state_with_a()
1175
# The symlink target won't be cached if it isn't old
1176
state.adjust_time(+10)
1177
self.create_and_test_dir(state, entry)
1179
self.create_and_test_symlink(state, entry)
1181
def test_update_symlink_to_file(self):
1182
"""Symlink becomes a file"""
1183
self.requireFeature(features.SymlinkFeature)
1184
state, entry = self.get_state_with_a()
1185
# The symlink and file info won't be cached unless old
1186
state.adjust_time(+10)
1187
self.create_and_test_symlink(state, entry)
1189
self.create_and_test_file(state, entry)
1191
def test_update_symlink_to_dir(self):
1192
"""Symlink becomes a directory"""
1193
self.requireFeature(features.SymlinkFeature)
1194
state, entry = self.get_state_with_a()
1195
# The symlink target won't be cached if it isn't old
1196
state.adjust_time(+10)
1197
self.create_and_test_symlink(state, entry)
1199
self.create_and_test_dir(state, entry)
1201
def test__is_executable_win32(self):
1202
state, entry = self.get_state_with_a()
1203
self.build_tree(['a'])
1205
# Make sure we are using the win32 implementation of _is_executable
1206
state._is_executable = state._is_executable_win32
1208
# The file on disk is not executable, but we are marking it as though
1209
# it is. With _is_executable_win32 we ignore what is on disk.
1210
entry[1][0] = ('f', '', 0, True, dirstate.DirState.NULLSTAT)
1212
stat_value = os.lstat('a')
1213
packed_stat = dirstate.pack_stat(stat_value)
1215
state.adjust_time(-10) # Make sure everything is new
1216
self.update_entry(state, entry, abspath='a', stat_value=stat_value)
1218
# The row is updated, but the executable bit stays set.
1219
self.assertEqual([('f', '', 14, True, dirstate.DirState.NULLSTAT)],
1222
# Make the disk object look old enough to cache (but it won't cache the
1223
# sha as it is a new file).
1224
state.adjust_time(+20)
1225
digest = 'b50e5406bb5e153ebbeb20268fcf37c87e1ecfb6'
1226
self.update_entry(state, entry, abspath='a', stat_value=stat_value)
1227
self.assertEqual([('f', '', 14, True, dirstate.DirState.NULLSTAT)],
1230
def _prepare_tree(self):
1232
text = 'Hello World\n'
1233
tree = self.make_branch_and_tree('tree')
1234
self.build_tree_contents([('tree/a file', text)])
1235
tree.add('a file', 'a-file-id')
1236
# Note: dirstate does not sha prior to the first commit
1237
# so commit now in order for the test to work
1238
tree.commit('first')
1241
def test_sha1provider_sha1_used(self):
1242
tree, text = self._prepare_tree()
1243
state = dirstate.DirState.from_tree(tree, 'dirstate',
1244
UppercaseSHA1Provider())
1245
self.addCleanup(state.unlock)
1246
expected_sha = osutils.sha_string(text.upper() + "foo")
1247
entry = state._get_entry(0, path_utf8='a file')
1248
state._sha_cutoff_time()
1249
state._cutoff_time += 10
1250
sha1 = self.update_entry(state, entry, 'tree/a file',
1251
os.lstat('tree/a file'))
1252
self.assertEqual(expected_sha, sha1)
1254
def test_sha1provider_stat_and_sha1_used(self):
1255
tree, text = self._prepare_tree()
1257
self.addCleanup(tree.unlock)
1258
state = tree._current_dirstate()
1259
state._sha1_provider = UppercaseSHA1Provider()
1260
# If we used the standard provider, it would look like nothing has
1262
file_ids_changed = [change[0] for change
1263
in tree.iter_changes(tree.basis_tree())]
1264
self.assertEqual(['a-file-id'], file_ids_changed)
1267
class UppercaseSHA1Provider(dirstate.SHA1Provider):
1268
"""A custom SHA1Provider."""
1270
def sha1(self, abspath):
1271
return self.stat_and_sha1(abspath)[1]
1273
def stat_and_sha1(self, abspath):
1274
file_obj = file(abspath, 'rb')
1276
statvalue = os.fstat(file_obj.fileno())
1277
text = ''.join(file_obj.readlines())
1278
sha1 = osutils.sha_string(text.upper() + "foo")
1281
return statvalue, sha1
1284
class TestProcessEntry(test_dirstate.TestCaseWithDirState):
1286
scenarios = multiply_scenarios(dir_reader_scenarios(), pe_scenarios)
1289
_process_entry = None
1292
super(TestProcessEntry, self).setUp()
1293
self.overrideAttr(dirstate, '_process_entry', self._process_entry)
1295
def assertChangedFileIds(self, expected, tree):
1298
file_ids = [info[0] for info
1299
in tree.iter_changes(tree.basis_tree())]
1302
self.assertEqual(sorted(expected), sorted(file_ids))
1304
def test_exceptions_raised(self):
1305
# This is a direct test of bug #495023, it relies on osutils.is_inside
1306
# getting called in an inner function. Which makes it a bit brittle,
1307
# but at least it does reproduce the bug.
1308
tree = self.make_branch_and_tree('tree')
1309
self.build_tree(['tree/file', 'tree/dir/', 'tree/dir/sub',
1310
'tree/dir2/', 'tree/dir2/sub2'])
1311
tree.add(['file', 'dir', 'dir/sub', 'dir2', 'dir2/sub2'])
1312
tree.commit('first commit')
1314
self.addCleanup(tree.unlock)
1315
basis_tree = tree.basis_tree()
1316
def is_inside_raises(*args, **kwargs):
1317
raise RuntimeError('stop this')
1318
self.overrideAttr(osutils, 'is_inside', is_inside_raises)
1319
self.assertListRaises(RuntimeError, tree.iter_changes, basis_tree)
1321
def test_simple_changes(self):
1322
tree = self.make_branch_and_tree('tree')
1323
self.build_tree(['tree/file'])
1324
tree.add(['file'], ['file-id'])
1325
self.assertChangedFileIds([tree.get_root_id(), 'file-id'], tree)
1327
self.assertChangedFileIds([], tree)
1329
def test_sha1provider_stat_and_sha1_used(self):
1330
tree = self.make_branch_and_tree('tree')
1331
self.build_tree(['tree/file'])
1332
tree.add(['file'], ['file-id'])
1335
self.addCleanup(tree.unlock)
1336
state = tree._current_dirstate()
1337
state._sha1_provider = UppercaseSHA1Provider()
1338
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)