742
710
class TestCompiledReadDirblocks(TestReadDirblocks):
743
711
"""Test the pyrex implementation of _read_dirblocks"""
745
_test_needs_features = [compiled_dirstate_helpers_feature]
713
_test_needs_features = [CompiledDirstateHelpersFeature]
747
715
def get_read_dirblocks(self):
748
from bzrlib._dirstate_helpers_pyx import _read_dirblocks
749
return _read_dirblocks
716
from bzrlib._dirstate_helpers_c import _read_dirblocks_c
717
return _read_dirblocks_c
752
720
class TestUsingCompiledIfAvailable(tests.TestCase):
753
721
"""Check that any compiled functions that are available are the default.
755
723
It is possible to have typos, etc in the import line, such that
756
_dirstate_helpers_pyx is actually available, but the compiled functions are
724
_dirstate_helpers_c is actually available, but the compiled functions are
760
728
def test_bisect_dirblock(self):
761
if compiled_dirstate_helpers_feature.available():
762
from bzrlib._dirstate_helpers_pyx import bisect_dirblock
729
if CompiledDirstateHelpersFeature.available():
730
from bzrlib._dirstate_helpers_c import bisect_dirblock_c
731
self.assertIs(bisect_dirblock_c, dirstate.bisect_dirblock)
764
from bzrlib._dirstate_helpers_py import bisect_dirblock
765
self.assertIs(bisect_dirblock, dirstate.bisect_dirblock)
733
from bzrlib._dirstate_helpers_py import bisect_dirblock_py
734
self.assertIs(bisect_dirblock_py, dirstate.bisect_dirblock)
767
736
def test__bisect_path_left(self):
768
if compiled_dirstate_helpers_feature.available():
769
from bzrlib._dirstate_helpers_pyx import _bisect_path_left
737
if CompiledDirstateHelpersFeature.available():
738
from bzrlib._dirstate_helpers_c import _bisect_path_left_c
739
self.assertIs(_bisect_path_left_c, dirstate._bisect_path_left)
771
from bzrlib._dirstate_helpers_py import _bisect_path_left
772
self.assertIs(_bisect_path_left, dirstate._bisect_path_left)
741
from bzrlib._dirstate_helpers_py import _bisect_path_left_py
742
self.assertIs(_bisect_path_left_py, dirstate._bisect_path_left)
774
744
def test__bisect_path_right(self):
775
if compiled_dirstate_helpers_feature.available():
776
from bzrlib._dirstate_helpers_pyx import _bisect_path_right
745
if CompiledDirstateHelpersFeature.available():
746
from bzrlib._dirstate_helpers_c import _bisect_path_right_c
747
self.assertIs(_bisect_path_right_c, dirstate._bisect_path_right)
778
from bzrlib._dirstate_helpers_py import _bisect_path_right
779
self.assertIs(_bisect_path_right, dirstate._bisect_path_right)
749
from bzrlib._dirstate_helpers_py import _bisect_path_right_py
750
self.assertIs(_bisect_path_right_py, dirstate._bisect_path_right)
781
752
def test_cmp_by_dirs(self):
782
if compiled_dirstate_helpers_feature.available():
783
from bzrlib._dirstate_helpers_pyx import cmp_by_dirs
753
if CompiledDirstateHelpersFeature.available():
754
from bzrlib._dirstate_helpers_c import cmp_by_dirs_c
755
self.assertIs(cmp_by_dirs_c, dirstate.cmp_by_dirs)
785
from bzrlib._dirstate_helpers_py import cmp_by_dirs
786
self.assertIs(cmp_by_dirs, dirstate.cmp_by_dirs)
757
from bzrlib._dirstate_helpers_py import cmp_by_dirs_py
758
self.assertIs(cmp_by_dirs_py, dirstate.cmp_by_dirs)
788
760
def test__read_dirblocks(self):
789
if compiled_dirstate_helpers_feature.available():
790
from bzrlib._dirstate_helpers_pyx import _read_dirblocks
792
from bzrlib._dirstate_helpers_py import _read_dirblocks
793
self.assertIs(_read_dirblocks, dirstate._read_dirblocks)
795
def test_update_entry(self):
796
if compiled_dirstate_helpers_feature.available():
797
from bzrlib._dirstate_helpers_pyx import update_entry
799
from bzrlib.dirstate import update_entry
800
self.assertIs(update_entry, dirstate.update_entry)
802
def test_process_entry(self):
803
if compiled_dirstate_helpers_feature.available():
804
from bzrlib._dirstate_helpers_pyx import ProcessEntryC
805
self.assertIs(ProcessEntryC, dirstate._process_entry)
807
from bzrlib.dirstate import ProcessEntryPython
808
self.assertIs(ProcessEntryPython, dirstate._process_entry)
811
class TestUpdateEntry(test_dirstate.TestCaseWithDirState):
812
"""Test the DirState.update_entry functions"""
814
scenarios = multiply_scenarios(
815
dir_reader_scenarios(), ue_scenarios)
821
super(TestUpdateEntry, self).setUp()
822
self.overrideAttr(dirstate, 'update_entry', self.update_entry)
824
def get_state_with_a(self):
825
"""Create a DirState tracking a single object named 'a'"""
826
state = test_dirstate.InstrumentedDirState.initialize('dirstate')
827
self.addCleanup(state.unlock)
828
state.add('a', 'a-id', 'file', None, '')
829
entry = state._get_entry(0, path_utf8='a')
832
def test_observed_sha1_cachable(self):
833
state, entry = self.get_state_with_a()
835
atime = time.time() - 10
836
self.build_tree(['a'])
837
statvalue = test_dirstate._FakeStat.from_stat(os.lstat('a'))
838
statvalue.st_mtime = statvalue.st_ctime = atime
839
self.assertEqual(dirstate.DirState.IN_MEMORY_UNMODIFIED,
840
state._dirblock_state)
841
state._observed_sha1(entry, "foo", statvalue)
842
self.assertEqual('foo', entry[1][0][1])
843
packed_stat = dirstate.pack_stat(statvalue)
844
self.assertEqual(packed_stat, entry[1][0][4])
845
self.assertEqual(dirstate.DirState.IN_MEMORY_HASH_MODIFIED,
846
state._dirblock_state)
848
def test_observed_sha1_not_cachable(self):
849
state, entry = self.get_state_with_a()
851
oldval = entry[1][0][1]
852
oldstat = entry[1][0][4]
853
self.build_tree(['a'])
854
statvalue = os.lstat('a')
855
self.assertEqual(dirstate.DirState.IN_MEMORY_UNMODIFIED,
856
state._dirblock_state)
857
state._observed_sha1(entry, "foo", statvalue)
858
self.assertEqual(oldval, entry[1][0][1])
859
self.assertEqual(oldstat, entry[1][0][4])
860
self.assertEqual(dirstate.DirState.IN_MEMORY_UNMODIFIED,
861
state._dirblock_state)
863
def test_update_entry(self):
864
state, _ = self.get_state_with_a()
865
tree = self.make_branch_and_tree('tree')
867
empty_revid = tree.commit('empty')
868
self.build_tree(['tree/a'])
869
tree.add(['a'], ['a-id'])
870
with_a_id = tree.commit('with_a')
871
self.addCleanup(tree.unlock)
872
state.set_parent_trees(
873
[(empty_revid, tree.branch.repository.revision_tree(empty_revid))],
875
entry = state._get_entry(0, path_utf8='a')
876
self.build_tree(['a'])
877
# Add one where we don't provide the stat or sha already
878
self.assertEqual(('', 'a', 'a-id'), entry[0])
879
self.assertEqual(('f', '', 0, False, dirstate.DirState.NULLSTAT),
881
# Flush the buffers to disk
883
self.assertEqual(dirstate.DirState.IN_MEMORY_UNMODIFIED,
884
state._dirblock_state)
886
stat_value = os.lstat('a')
887
packed_stat = dirstate.pack_stat(stat_value)
888
link_or_sha1 = self.update_entry(state, entry, abspath='a',
889
stat_value=stat_value)
890
self.assertEqual(None, link_or_sha1)
892
# The dirblock entry should not have computed or cached the file's
893
# sha1, but it did update the files' st_size. However, this is not
894
# worth writing a dirstate file for, so we leave the state UNMODIFIED
895
self.assertEqual(('f', '', 14, False, dirstate.DirState.NULLSTAT),
897
self.assertEqual(dirstate.DirState.IN_MEMORY_UNMODIFIED,
898
state._dirblock_state)
899
mode = stat_value.st_mode
900
self.assertEqual([('is_exec', mode, False)], state._log)
903
self.assertEqual(dirstate.DirState.IN_MEMORY_UNMODIFIED,
904
state._dirblock_state)
906
# Roll the clock back so the file is guaranteed to look too new. We
907
# should still not compute the sha1.
908
state.adjust_time(-10)
911
link_or_sha1 = self.update_entry(state, entry, abspath='a',
912
stat_value=stat_value)
913
self.assertEqual([('is_exec', mode, False)], state._log)
914
self.assertEqual(None, link_or_sha1)
915
self.assertEqual(dirstate.DirState.IN_MEMORY_UNMODIFIED,
916
state._dirblock_state)
917
self.assertEqual(('f', '', 14, False, dirstate.DirState.NULLSTAT),
921
# If it is cachable (the clock has moved forward) but new it still
922
# won't calculate the sha or cache it.
923
state.adjust_time(+20)
925
link_or_sha1 = dirstate.update_entry(state, entry, abspath='a',
926
stat_value=stat_value)
927
self.assertEqual(None, link_or_sha1)
928
self.assertEqual([('is_exec', mode, False)], state._log)
929
self.assertEqual(('f', '', 14, False, dirstate.DirState.NULLSTAT),
931
self.assertEqual(dirstate.DirState.IN_MEMORY_UNMODIFIED,
932
state._dirblock_state)
934
# If the file is no longer new, and the clock has been moved forward
935
# sufficiently, it will cache the sha.
937
state.set_parent_trees(
938
[(with_a_id, tree.branch.repository.revision_tree(with_a_id))],
940
entry = state._get_entry(0, path_utf8='a')
942
link_or_sha1 = self.update_entry(state, entry, abspath='a',
943
stat_value=stat_value)
944
self.assertEqual('b50e5406bb5e153ebbeb20268fcf37c87e1ecfb6',
946
self.assertEqual([('is_exec', mode, False), ('sha1', 'a')],
948
self.assertEqual(('f', link_or_sha1, 14, False, packed_stat),
951
# Subsequent calls will just return the cached value
953
link_or_sha1 = self.update_entry(state, entry, abspath='a',
954
stat_value=stat_value)
955
self.assertEqual('b50e5406bb5e153ebbeb20268fcf37c87e1ecfb6',
957
self.assertEqual([], state._log)
958
self.assertEqual(('f', link_or_sha1, 14, False, packed_stat),
961
def test_update_entry_symlink(self):
962
"""Update entry should read symlinks."""
963
self.requireFeature(features.SymlinkFeature)
964
state, entry = self.get_state_with_a()
966
self.assertEqual(dirstate.DirState.IN_MEMORY_UNMODIFIED,
967
state._dirblock_state)
968
os.symlink('target', 'a')
970
state.adjust_time(-10) # Make the symlink look new
971
stat_value = os.lstat('a')
972
packed_stat = dirstate.pack_stat(stat_value)
973
link_or_sha1 = self.update_entry(state, entry, abspath='a',
974
stat_value=stat_value)
975
self.assertEqual('target', link_or_sha1)
976
self.assertEqual([('read_link', 'a', '')], state._log)
977
# Dirblock is not updated (the link is too new)
978
self.assertEqual([('l', '', 6, False, dirstate.DirState.NULLSTAT)],
980
# The file entry turned into a symlink, that is considered
981
# HASH modified worthy.
982
self.assertEqual(dirstate.DirState.IN_MEMORY_HASH_MODIFIED,
983
state._dirblock_state)
985
# Because the stat_value looks new, we should re-read the target
987
link_or_sha1 = self.update_entry(state, entry, abspath='a',
988
stat_value=stat_value)
989
self.assertEqual('target', link_or_sha1)
990
self.assertEqual([('read_link', 'a', '')], state._log)
991
self.assertEqual([('l', '', 6, False, dirstate.DirState.NULLSTAT)],
994
state.adjust_time(+20) # Skip into the future, all files look old
996
link_or_sha1 = self.update_entry(state, entry, abspath='a',
997
stat_value=stat_value)
998
# The symlink stayed a symlink. So while it is new enough to cache, we
999
# don't bother setting the flag, because it is not really worth saving
1000
# (when we stat the symlink, we'll have paged in the target.)
1001
self.assertEqual(dirstate.DirState.IN_MEMORY_UNMODIFIED,
1002
state._dirblock_state)
1003
self.assertEqual('target', link_or_sha1)
1004
# We need to re-read the link because only now can we cache it
1005
self.assertEqual([('read_link', 'a', '')], state._log)
1006
self.assertEqual([('l', 'target', 6, False, packed_stat)],
1010
# Another call won't re-read the link
1011
self.assertEqual([], state._log)
1012
link_or_sha1 = self.update_entry(state, entry, abspath='a',
1013
stat_value=stat_value)
1014
self.assertEqual('target', link_or_sha1)
1015
self.assertEqual([('l', 'target', 6, False, packed_stat)],
1018
def do_update_entry(self, state, entry, abspath):
1019
stat_value = os.lstat(abspath)
1020
return self.update_entry(state, entry, abspath, stat_value)
1022
def test_update_entry_dir(self):
1023
state, entry = self.get_state_with_a()
1024
self.build_tree(['a/'])
1025
self.assertIs(None, self.do_update_entry(state, entry, 'a'))
1027
def test_update_entry_dir_unchanged(self):
1028
state, entry = self.get_state_with_a()
1029
self.build_tree(['a/'])
1030
state.adjust_time(+20)
1031
self.assertIs(None, self.do_update_entry(state, entry, 'a'))
1032
# a/ used to be a file, but is now a directory, worth saving
1033
self.assertEqual(dirstate.DirState.IN_MEMORY_MODIFIED,
1034
state._dirblock_state)
1036
self.assertEqual(dirstate.DirState.IN_MEMORY_UNMODIFIED,
1037
state._dirblock_state)
1038
# No changes to a/ means not worth saving.
1039
self.assertIs(None, self.do_update_entry(state, entry, 'a'))
1040
self.assertEqual(dirstate.DirState.IN_MEMORY_UNMODIFIED,
1041
state._dirblock_state)
1042
# Change the last-modified time for the directory
1043
t = time.time() - 100.0
1045
os.utime('a', (t, t))
1047
# It looks like Win32 + FAT doesn't allow to change times on a dir.
1048
raise tests.TestSkipped("can't update mtime of a dir on FAT")
1049
saved_packed_stat = entry[1][0][-1]
1050
self.assertIs(None, self.do_update_entry(state, entry, 'a'))
1051
# We *do* go ahead and update the information in the dirblocks, but we
1052
# don't bother setting IN_MEMORY_MODIFIED because it is trivial to
1054
self.assertNotEqual(saved_packed_stat, entry[1][0][-1])
1055
self.assertEqual(dirstate.DirState.IN_MEMORY_UNMODIFIED,
1056
state._dirblock_state)
1058
def test_update_entry_file_unchanged(self):
1059
state, _ = self.get_state_with_a()
1060
tree = self.make_branch_and_tree('tree')
1062
self.build_tree(['tree/a'])
1063
tree.add(['a'], ['a-id'])
1064
with_a_id = tree.commit('witha')
1065
self.addCleanup(tree.unlock)
1066
state.set_parent_trees(
1067
[(with_a_id, tree.branch.repository.revision_tree(with_a_id))],
1069
entry = state._get_entry(0, path_utf8='a')
1070
self.build_tree(['a'])
1071
sha1sum = 'b50e5406bb5e153ebbeb20268fcf37c87e1ecfb6'
1072
state.adjust_time(+20)
1073
self.assertEqual(sha1sum, self.do_update_entry(state, entry, 'a'))
1074
self.assertEqual(dirstate.DirState.IN_MEMORY_MODIFIED,
1075
state._dirblock_state)
1077
self.assertEqual(dirstate.DirState.IN_MEMORY_UNMODIFIED,
1078
state._dirblock_state)
1079
self.assertEqual(sha1sum, self.do_update_entry(state, entry, 'a'))
1080
self.assertEqual(dirstate.DirState.IN_MEMORY_UNMODIFIED,
1081
state._dirblock_state)
1083
def test_update_entry_tree_reference(self):
1084
state = test_dirstate.InstrumentedDirState.initialize('dirstate')
1085
self.addCleanup(state.unlock)
1086
state.add('r', 'r-id', 'tree-reference', None, '')
1087
self.build_tree(['r/'])
1088
entry = state._get_entry(0, path_utf8='r')
1089
self.do_update_entry(state, entry, 'r')
1090
entry = state._get_entry(0, path_utf8='r')
1091
self.assertEqual('t', entry[1][0][0])
1093
def create_and_test_file(self, state, entry):
1094
"""Create a file at 'a' and verify the state finds it during update.
1096
The state should already be versioning *something* at 'a'. This makes
1097
sure that state.update_entry recognizes it as a file.
1099
self.build_tree(['a'])
1100
stat_value = os.lstat('a')
1101
packed_stat = dirstate.pack_stat(stat_value)
1103
link_or_sha1 = self.do_update_entry(state, entry, abspath='a')
1104
self.assertEqual(None, link_or_sha1)
1105
self.assertEqual([('f', '', 14, False, dirstate.DirState.NULLSTAT)],
1109
def create_and_test_dir(self, state, entry):
1110
"""Create a directory at 'a' and verify the state finds it.
1112
The state should already be versioning *something* at 'a'. This makes
1113
sure that state.update_entry recognizes it as a directory.
1115
self.build_tree(['a/'])
1116
stat_value = os.lstat('a')
1117
packed_stat = dirstate.pack_stat(stat_value)
1119
link_or_sha1 = self.do_update_entry(state, entry, abspath='a')
1120
self.assertIs(None, link_or_sha1)
1121
self.assertEqual([('d', '', 0, False, packed_stat)], entry[1])
1125
# FIXME: Add unicode version
1126
def create_and_test_symlink(self, state, entry):
1127
"""Create a symlink at 'a' and verify the state finds it.
1129
The state should already be versioning *something* at 'a'. This makes
1130
sure that state.update_entry recognizes it as a symlink.
1132
This should not be called if this platform does not have symlink
1135
# caller should care about skipping test on platforms without symlinks
1136
os.symlink('path/to/foo', 'a')
1138
stat_value = os.lstat('a')
1139
packed_stat = dirstate.pack_stat(stat_value)
1141
link_or_sha1 = self.do_update_entry(state, entry, abspath='a')
1142
self.assertEqual('path/to/foo', link_or_sha1)
1143
self.assertEqual([('l', 'path/to/foo', 11, False, packed_stat)],
1147
def test_update_file_to_dir(self):
1148
"""If a file changes to a directory we return None for the sha.
1149
We also update the inventory record.
1151
state, entry = self.get_state_with_a()
1152
# The file sha1 won't be cached unless the file is old
1153
state.adjust_time(+10)
1154
self.create_and_test_file(state, entry)
1156
self.create_and_test_dir(state, entry)
1158
def test_update_file_to_symlink(self):
1159
"""File becomes a symlink"""
1160
self.requireFeature(features.SymlinkFeature)
1161
state, entry = self.get_state_with_a()
1162
# The file sha1 won't be cached unless the file is old
1163
state.adjust_time(+10)
1164
self.create_and_test_file(state, entry)
1166
self.create_and_test_symlink(state, entry)
1168
def test_update_dir_to_file(self):
1169
"""Directory becoming a file updates the entry."""
1170
state, entry = self.get_state_with_a()
1171
# The file sha1 won't be cached unless the file is old
1172
state.adjust_time(+10)
1173
self.create_and_test_dir(state, entry)
1175
self.create_and_test_file(state, entry)
1177
def test_update_dir_to_symlink(self):
1178
"""Directory becomes a symlink"""
1179
self.requireFeature(features.SymlinkFeature)
1180
state, entry = self.get_state_with_a()
1181
# The symlink target won't be cached if it isn't old
1182
state.adjust_time(+10)
1183
self.create_and_test_dir(state, entry)
1185
self.create_and_test_symlink(state, entry)
1187
def test_update_symlink_to_file(self):
1188
"""Symlink becomes a file"""
1189
self.requireFeature(features.SymlinkFeature)
1190
state, entry = self.get_state_with_a()
1191
# The symlink and file info won't be cached unless old
1192
state.adjust_time(+10)
1193
self.create_and_test_symlink(state, entry)
1195
self.create_and_test_file(state, entry)
1197
def test_update_symlink_to_dir(self):
1198
"""Symlink becomes a directory"""
1199
self.requireFeature(features.SymlinkFeature)
1200
state, entry = self.get_state_with_a()
1201
# The symlink target won't be cached if it isn't old
1202
state.adjust_time(+10)
1203
self.create_and_test_symlink(state, entry)
1205
self.create_and_test_dir(state, entry)
1207
def test__is_executable_win32(self):
1208
state, entry = self.get_state_with_a()
1209
self.build_tree(['a'])
1211
# Make sure we are using the win32 implementation of _is_executable
1212
state._is_executable = state._is_executable_win32
1214
# The file on disk is not executable, but we are marking it as though
1215
# it is. With _is_executable_win32 we ignore what is on disk.
1216
entry[1][0] = ('f', '', 0, True, dirstate.DirState.NULLSTAT)
1218
stat_value = os.lstat('a')
1219
packed_stat = dirstate.pack_stat(stat_value)
1221
state.adjust_time(-10) # Make sure everything is new
1222
self.update_entry(state, entry, abspath='a', stat_value=stat_value)
1224
# The row is updated, but the executable bit stays set.
1225
self.assertEqual([('f', '', 14, True, dirstate.DirState.NULLSTAT)],
1228
# Make the disk object look old enough to cache (but it won't cache the
1229
# sha as it is a new file).
1230
state.adjust_time(+20)
1231
digest = 'b50e5406bb5e153ebbeb20268fcf37c87e1ecfb6'
1232
self.update_entry(state, entry, abspath='a', stat_value=stat_value)
1233
self.assertEqual([('f', '', 14, True, dirstate.DirState.NULLSTAT)],
1236
def _prepare_tree(self):
1238
text = 'Hello World\n'
1239
tree = self.make_branch_and_tree('tree')
1240
self.build_tree_contents([('tree/a file', text)])
1241
tree.add('a file', 'a-file-id')
1242
# Note: dirstate does not sha prior to the first commit
1243
# so commit now in order for the test to work
1244
tree.commit('first')
1247
def test_sha1provider_sha1_used(self):
1248
tree, text = self._prepare_tree()
1249
state = dirstate.DirState.from_tree(tree, 'dirstate',
1250
UppercaseSHA1Provider())
1251
self.addCleanup(state.unlock)
1252
expected_sha = osutils.sha_string(text.upper() + "foo")
1253
entry = state._get_entry(0, path_utf8='a file')
1254
state._sha_cutoff_time()
1255
state._cutoff_time += 10
1256
sha1 = self.update_entry(state, entry, 'tree/a file',
1257
os.lstat('tree/a file'))
1258
self.assertEqual(expected_sha, sha1)
1260
def test_sha1provider_stat_and_sha1_used(self):
1261
tree, text = self._prepare_tree()
1263
self.addCleanup(tree.unlock)
1264
state = tree._current_dirstate()
1265
state._sha1_provider = UppercaseSHA1Provider()
1266
# If we used the standard provider, it would look like nothing has
1268
file_ids_changed = [change[0] for change
1269
in tree.iter_changes(tree.basis_tree())]
1270
self.assertEqual(['a-file-id'], file_ids_changed)
1273
class UppercaseSHA1Provider(dirstate.SHA1Provider):
1274
"""A custom SHA1Provider."""
1276
def sha1(self, abspath):
1277
return self.stat_and_sha1(abspath)[1]
1279
def stat_and_sha1(self, abspath):
1280
file_obj = file(abspath, 'rb')
1282
statvalue = os.fstat(file_obj.fileno())
1283
text = ''.join(file_obj.readlines())
1284
sha1 = osutils.sha_string(text.upper() + "foo")
1287
return statvalue, sha1
1290
class TestProcessEntry(test_dirstate.TestCaseWithDirState):
1292
scenarios = multiply_scenarios(dir_reader_scenarios(), pe_scenarios)
1295
_process_entry = None
1298
super(TestProcessEntry, self).setUp()
1299
self.overrideAttr(dirstate, '_process_entry', self._process_entry)
1301
def assertChangedFileIds(self, expected, tree):
1304
file_ids = [info[0] for info
1305
in tree.iter_changes(tree.basis_tree())]
1308
self.assertEqual(sorted(expected), sorted(file_ids))
1310
def test_exceptions_raised(self):
1311
# This is a direct test of bug #495023, it relies on osutils.is_inside
1312
# getting called in an inner function. Which makes it a bit brittle,
1313
# but at least it does reproduce the bug.
1314
tree = self.make_branch_and_tree('tree')
1315
self.build_tree(['tree/file', 'tree/dir/', 'tree/dir/sub',
1316
'tree/dir2/', 'tree/dir2/sub2'])
1317
tree.add(['file', 'dir', 'dir/sub', 'dir2', 'dir2/sub2'])
1318
tree.commit('first commit')
1320
self.addCleanup(tree.unlock)
1321
basis_tree = tree.basis_tree()
1322
def is_inside_raises(*args, **kwargs):
1323
raise RuntimeError('stop this')
1324
self.overrideAttr(osutils, 'is_inside', is_inside_raises)
1325
self.assertListRaises(RuntimeError, tree.iter_changes, basis_tree)
1327
def test_simple_changes(self):
1328
tree = self.make_branch_and_tree('tree')
1329
self.build_tree(['tree/file'])
1330
tree.add(['file'], ['file-id'])
1331
self.assertChangedFileIds([tree.get_root_id(), 'file-id'], tree)
1333
self.assertChangedFileIds([], tree)
1335
def test_sha1provider_stat_and_sha1_used(self):
1336
tree = self.make_branch_and_tree('tree')
1337
self.build_tree(['tree/file'])
1338
tree.add(['file'], ['file-id'])
1341
self.addCleanup(tree.unlock)
1342
state = tree._current_dirstate()
1343
state._sha1_provider = UppercaseSHA1Provider()
1344
self.assertChangedFileIds(['file-id'], tree)
1347
class TestPackStat(tests.TestCase):
1348
"""Check packed representaton of stat values is robust on all inputs"""
1350
scenarios = helper_scenarios
1352
def pack(self, statlike_tuple):
1353
return self.helpers.pack_stat(os.stat_result(statlike_tuple))
1356
def unpack_field(packed_string, stat_field):
1357
return _dirstate_helpers_py._unpack_stat(packed_string)[stat_field]
1359
def test_result(self):
1360
self.assertEqual("AAAQAAAAABAAAAARAAAAAgAAAAEAAIHk",
1361
self.pack((33252, 1, 2, 0, 0, 0, 4096, 15.5, 16.5, 17.5)))
1363
def test_giant_inode(self):
1364
packed = self.pack((33252, 0xF80000ABC, 0, 0, 0, 0, 0, 0, 0, 0))
1365
self.assertEqual(0x80000ABC, self.unpack_field(packed, "st_ino"))
1367
def test_giant_size(self):
1368
packed = self.pack((33252, 0, 0, 0, 0, 0, (1 << 33) + 4096, 0, 0, 0))
1369
self.assertEqual(4096, self.unpack_field(packed, "st_size"))
1371
def test_fractional_mtime(self):
1372
packed = self.pack((33252, 0, 0, 0, 0, 0, 0, 0, 16.9375, 0))
1373
self.assertEqual(16, self.unpack_field(packed, "st_mtime"))
1375
def test_ancient_mtime(self):
1376
packed = self.pack((33252, 0, 0, 0, 0, 0, 0, 0, -11644473600.0, 0))
1377
self.assertEqual(1240428288, self.unpack_field(packed, "st_mtime"))
1379
def test_distant_mtime(self):
1380
packed = self.pack((33252, 0, 0, 0, 0, 0, 0, 0, 64060588800.0, 0))
1381
self.assertEqual(3931046656, self.unpack_field(packed, "st_mtime"))
1383
def test_fractional_ctime(self):
1384
packed = self.pack((33252, 0, 0, 0, 0, 0, 0, 0, 0, 17.5625))
1385
self.assertEqual(17, self.unpack_field(packed, "st_ctime"))
1387
def test_ancient_ctime(self):
1388
packed = self.pack((33252, 0, 0, 0, 0, 0, 0, 0, 0, -11644473600.0))
1389
self.assertEqual(1240428288, self.unpack_field(packed, "st_ctime"))
1391
def test_distant_ctime(self):
1392
packed = self.pack((33252, 0, 0, 0, 0, 0, 0, 0, 0, 64060588800.0))
1393
self.assertEqual(3931046656, self.unpack_field(packed, "st_ctime"))
1395
def test_negative_dev(self):
1396
packed = self.pack((33252, 0, -0xFFFFFCDE, 0, 0, 0, 0, 0, 0, 0))
1397
self.assertEqual(0x322, self.unpack_field(packed, "st_dev"))
761
if CompiledDirstateHelpersFeature.available():
762
from bzrlib._dirstate_helpers_c import _read_dirblocks_c
763
self.assertIs(_read_dirblocks_c, dirstate._read_dirblocks)
765
from bzrlib._dirstate_helpers_py import _read_dirblocks_py
766
self.assertIs(_read_dirblocks_py, dirstate._read_dirblocks)