29
29
from bzrlib.tests import (
32
from bzrlib.tests.test_osutils import dir_reader_scenarios
33
from bzrlib.tests.scenarios import (
34
load_tests_apply_scenarios,
39
load_tests = load_tests_apply_scenarios
35
from bzrlib import _dirstate_helpers_pyx
36
has_dirstate_helpers_pyx = True
38
has_dirstate_helpers_pyx = False
42
41
compiled_dirstate_helpers_feature = tests.ModuleAvailableFeature(
43
'bzrlib._dirstate_helpers_pyx')
46
# FIXME: we should also parametrize against SHA1Provider !
48
ue_scenarios = [('dirstate_Python',
49
{'update_entry': dirstate.py_update_entry})]
50
if compiled_dirstate_helpers_feature.available():
51
update_entry = compiled_dirstate_helpers_feature.module.update_entry
52
ue_scenarios.append(('dirstate_Pyrex', {'update_entry': update_entry}))
54
pe_scenarios = [('dirstate_Python',
55
{'_process_entry': dirstate.ProcessEntryPython})]
56
if compiled_dirstate_helpers_feature.available():
57
process_entry = compiled_dirstate_helpers_feature.module.ProcessEntryC
58
pe_scenarios.append(('dirstate_Pyrex', {'_process_entry': process_entry}))
42
'bzrlib._dirstate_helpers_pyx')
45
def load_tests(basic_tests, module, loader):
46
# FIXME: we should also parametrize against SHA1Provider !
47
suite = loader.suiteClass()
48
remaining_tests = basic_tests
50
dir_reader_scenarios = test_osutils.dir_reader_scenarios()
52
ue_scenarios = [('dirstate_Python',
53
{'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})
57
ue_scenarios.append(pyrex_scenario)
58
process_entry_tests, remaining_tests = tests.split_suite_by_condition(
59
remaining_tests, tests.condition_isinstance(TestUpdateEntry))
60
tests.multiply_tests(process_entry_tests,
61
tests.multiply_scenarios(dir_reader_scenarios,
65
pe_scenarios = [('dirstate_Python',
66
{'_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})
70
pe_scenarios.append(pyrex_scenario)
71
process_entry_tests, remaining_tests = tests.split_suite_by_condition(
72
remaining_tests, tests.condition_isinstance(TestProcessEntry))
73
tests.multiply_tests(process_entry_tests,
74
tests.multiply_scenarios(dir_reader_scenarios,
78
dir_reader_tests, remaining_tests = tests.split_suite_by_condition(
79
remaining_tests, tests.condition_isinstance(
80
test_dirstate.TestCaseWithDirState))
81
tests.multiply_tests(dir_reader_tests, dir_reader_scenarios, suite)
82
suite.addTest(remaining_tests)
61
87
class TestBisectPathMixin(object):
714
738
def test_trailing_garbage(self):
715
739
tree, state, expected = self.create_basic_dirstate()
716
# On Unix, we can write extra data as long as we haven't read yet, but
740
# On Linux, we can write extra data as long as we haven't read yet, but
717
741
# on Win32, if you've opened the file with FILE_SHARE_READ, trying to
718
742
# open it in append mode will fail.
823
844
def test_observed_sha1_cachable(self):
824
845
state, entry = self.get_state_with_a()
826
846
atime = time.time() - 10
827
847
self.build_tree(['a'])
828
statvalue = test_dirstate._FakeStat.from_stat(os.lstat('a'))
829
statvalue.st_mtime = statvalue.st_ctime = atime
830
self.assertEqual(dirstate.DirState.IN_MEMORY_UNMODIFIED,
831
state._dirblock_state)
848
statvalue = os.lstat('a')
849
statvalue = test_dirstate._FakeStat(statvalue.st_size, atime, atime,
850
statvalue.st_dev, statvalue.st_ino, statvalue.st_mode)
832
851
state._observed_sha1(entry, "foo", statvalue)
833
852
self.assertEqual('foo', entry[1][0][1])
834
853
packed_stat = dirstate.pack_stat(statvalue)
835
854
self.assertEqual(packed_stat, entry[1][0][4])
836
self.assertEqual(dirstate.DirState.IN_MEMORY_HASH_MODIFIED,
837
state._dirblock_state)
839
856
def test_observed_sha1_not_cachable(self):
840
857
state, entry = self.get_state_with_a()
842
858
oldval = entry[1][0][1]
843
859
oldstat = entry[1][0][4]
844
860
self.build_tree(['a'])
845
861
statvalue = os.lstat('a')
846
self.assertEqual(dirstate.DirState.IN_MEMORY_UNMODIFIED,
847
state._dirblock_state)
848
862
state._observed_sha1(entry, "foo", statvalue)
849
863
self.assertEqual(oldval, entry[1][0][1])
850
864
self.assertEqual(oldstat, entry[1][0][4])
851
self.assertEqual(dirstate.DirState.IN_MEMORY_UNMODIFIED,
852
state._dirblock_state)
854
866
def test_update_entry(self):
855
867
state, _ = self.get_state_with_a()
880
892
stat_value=stat_value)
881
893
self.assertEqual(None, link_or_sha1)
883
# The dirblock entry should not have computed or cached the file's
884
# sha1, but it did update the files' st_size. However, this is not
885
# worth writing a dirstate file for, so we leave the state UNMODIFIED
895
# The dirblock entry should not have cached the file's sha1 (too new)
886
896
self.assertEqual(('f', '', 14, False, dirstate.DirState.NULLSTAT),
888
self.assertEqual(dirstate.DirState.IN_MEMORY_UNMODIFIED,
898
self.assertEqual(dirstate.DirState.IN_MEMORY_MODIFIED,
889
899
state._dirblock_state)
890
900
mode = stat_value.st_mode
891
901
self.assertEqual([('is_exec', mode, False)], state._log)
903
914
stat_value=stat_value)
904
915
self.assertEqual([('is_exec', mode, False)], state._log)
905
916
self.assertEqual(None, link_or_sha1)
906
self.assertEqual(dirstate.DirState.IN_MEMORY_UNMODIFIED,
917
self.assertEqual(dirstate.DirState.IN_MEMORY_MODIFIED,
907
918
state._dirblock_state)
908
919
self.assertEqual(('f', '', 14, False, dirstate.DirState.NULLSTAT),
919
930
self.assertEqual([('is_exec', mode, False)], state._log)
920
931
self.assertEqual(('f', '', 14, False, dirstate.DirState.NULLSTAT),
922
self.assertEqual(dirstate.DirState.IN_MEMORY_UNMODIFIED,
923
state._dirblock_state)
925
934
# If the file is no longer new, and the clock has been moved forward
926
935
# sufficiently, it will cache the sha.
968
977
# Dirblock is not updated (the link is too new)
969
978
self.assertEqual([('l', '', 6, False, dirstate.DirState.NULLSTAT)],
971
# The file entry turned into a symlink, that is considered
972
# HASH modified worthy.
973
self.assertEqual(dirstate.DirState.IN_MEMORY_HASH_MODIFIED,
980
self.assertEqual(dirstate.DirState.IN_MEMORY_MODIFIED,
974
981
state._dirblock_state)
976
983
# Because the stat_value looks new, we should re-read the target
978
984
link_or_sha1 = self.update_entry(state, entry, abspath='a',
979
985
stat_value=stat_value)
980
986
self.assertEqual('target', link_or_sha1)
981
self.assertEqual([('read_link', 'a', '')], state._log)
987
self.assertEqual([('read_link', 'a', ''),
988
('read_link', 'a', ''),
982
990
self.assertEqual([('l', '', 6, False, dirstate.DirState.NULLSTAT)],
985
992
state.adjust_time(+20) # Skip into the future, all files look old
987
993
link_or_sha1 = self.update_entry(state, entry, abspath='a',
988
994
stat_value=stat_value)
989
# The symlink stayed a symlink. So while it is new enough to cache, we
990
# don't bother setting the flag, because it is not really worth saving
991
# (when we stat the symlink, we'll have paged in the target.)
992
self.assertEqual(dirstate.DirState.IN_MEMORY_UNMODIFIED,
993
state._dirblock_state)
994
995
self.assertEqual('target', link_or_sha1)
995
996
# We need to re-read the link because only now can we cache it
996
self.assertEqual([('read_link', 'a', '')], state._log)
997
self.assertEqual([('read_link', 'a', ''),
998
('read_link', 'a', ''),
999
('read_link', 'a', ''),
997
1001
self.assertEqual([('l', 'target', 6, False, packed_stat)],
1001
1004
# Another call won't re-read the link
1002
self.assertEqual([], state._log)
1005
self.assertEqual([('read_link', 'a', ''),
1006
('read_link', 'a', ''),
1007
('read_link', 'a', ''),
1003
1009
link_or_sha1 = self.update_entry(state, entry, abspath='a',
1004
1010
stat_value=stat_value)
1005
1011
self.assertEqual('target', link_or_sha1)
1020
1026
self.build_tree(['a/'])
1021
1027
state.adjust_time(+20)
1022
1028
self.assertIs(None, self.do_update_entry(state, entry, 'a'))
1023
# a/ used to be a file, but is now a directory, worth saving
1024
1029
self.assertEqual(dirstate.DirState.IN_MEMORY_MODIFIED,
1025
1030
state._dirblock_state)
1027
1032
self.assertEqual(dirstate.DirState.IN_MEMORY_UNMODIFIED,
1028
1033
state._dirblock_state)
1029
# No changes to a/ means not worth saving.
1030
self.assertIs(None, self.do_update_entry(state, entry, 'a'))
1031
self.assertEqual(dirstate.DirState.IN_MEMORY_UNMODIFIED,
1032
state._dirblock_state)
1033
# Change the last-modified time for the directory
1034
t = time.time() - 100.0
1036
os.utime('a', (t, t))
1038
# It looks like Win32 + FAT doesn't allow to change times on a dir.
1039
raise tests.TestSkipped("can't update mtime of a dir on FAT")
1040
saved_packed_stat = entry[1][0][-1]
1041
self.assertIs(None, self.do_update_entry(state, entry, 'a'))
1042
# We *do* go ahead and update the information in the dirblocks, but we
1043
# don't bother setting IN_MEMORY_MODIFIED because it is trivial to
1045
self.assertNotEqual(saved_packed_stat, entry[1][0][-1])
1034
self.assertIs(None, self.do_update_entry(state, entry, 'a'))
1046
1035
self.assertEqual(dirstate.DirState.IN_MEMORY_UNMODIFIED,
1047
1036
state._dirblock_state)