~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test__dirstate_helpers.py

  • Committer: Patch Queue Manager
  • Date: 2011-09-22 14:12:18 UTC
  • mfrom: (6155.3.1 jam)
  • Revision ID: pqm@pqm.ubuntu.com-20110922141218-86s4uu6nqvourw4f
(jameinel) Cleanup comments bzrlib/smart/__init__.py (John A Meinel)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2007-2010 Canonical Ltd
 
1
# Copyright (C) 2007-2011 Canonical Ltd
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
28
28
    )
29
29
from bzrlib.tests import (
30
30
    test_dirstate,
31
 
    test_osutils,
32
 
    )
33
 
 
34
 
try:
35
 
    from bzrlib import _dirstate_helpers_pyx
36
 
    has_dirstate_helpers_pyx = True
37
 
except ImportError:
38
 
    has_dirstate_helpers_pyx = False
39
 
 
40
 
 
41
 
compiled_dirstate_helpers_feature = tests.ModuleAvailableFeature(
42
 
                                'bzrlib._dirstate_helpers_pyx')
43
 
 
44
 
 
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
49
 
 
50
 
    dir_reader_scenarios = test_osutils.dir_reader_scenarios()
51
 
 
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,
62
 
                                                  ue_scenarios),
63
 
                         suite)
64
 
 
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,
75
 
                                                  pe_scenarios),
76
 
                         suite)
77
 
 
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)
83
 
 
84
 
    return suite
 
31
    )
 
32
from bzrlib.tests.test_osutils import dir_reader_scenarios
 
33
from bzrlib.tests.scenarios import (
 
34
    load_tests_apply_scenarios,
 
35
    multiply_scenarios,
 
36
    )
 
37
from bzrlib.tests import (
 
38
    features,
 
39
    )
 
40
 
 
41
 
 
42
load_tests = load_tests_apply_scenarios
 
43
 
 
44
 
 
45
compiled_dirstate_helpers_feature = features.ModuleAvailableFeature(
 
46
    'bzrlib._dirstate_helpers_pyx')
 
47
 
 
48
 
 
49
# FIXME: we should also parametrize against SHA1Provider !
 
50
 
 
51
ue_scenarios = [('dirstate_Python',
 
52
    {'update_entry': dirstate.py_update_entry})]
 
53
if compiled_dirstate_helpers_feature.available():
 
54
    update_entry = compiled_dirstate_helpers_feature.module.update_entry
 
55
    ue_scenarios.append(('dirstate_Pyrex', {'update_entry': update_entry}))
 
56
 
 
57
pe_scenarios = [('dirstate_Python',
 
58
    {'_process_entry': dirstate.ProcessEntryPython})]
 
59
if compiled_dirstate_helpers_feature.available():
 
60
    process_entry = compiled_dirstate_helpers_feature.module.ProcessEntryC
 
61
    pe_scenarios.append(('dirstate_Pyrex', {'_process_entry': process_entry}))
85
62
 
86
63
 
87
64
class TestBisectPathMixin(object):
719
696
    implementation.
720
697
    """
721
698
 
 
699
    # inherits scenarios from test_dirstate
 
700
 
722
701
    def get_read_dirblocks(self):
723
702
        from bzrlib._dirstate_helpers_py import _read_dirblocks
724
703
        return _read_dirblocks
826
805
class TestUpdateEntry(test_dirstate.TestCaseWithDirState):
827
806
    """Test the DirState.update_entry functions"""
828
807
 
 
808
    scenarios = multiply_scenarios(
 
809
        dir_reader_scenarios(), ue_scenarios)
 
810
 
829
811
    # Set by load_tests
830
812
    update_entry = None
831
813
 
843
825
 
844
826
    def test_observed_sha1_cachable(self):
845
827
        state, entry = self.get_state_with_a()
 
828
        state.save()
846
829
        atime = time.time() - 10
847
830
        self.build_tree(['a'])
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)
 
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)
851
835
        state._observed_sha1(entry, "foo", statvalue)
852
836
        self.assertEqual('foo', entry[1][0][1])
853
837
        packed_stat = dirstate.pack_stat(statvalue)
854
838
        self.assertEqual(packed_stat, entry[1][0][4])
 
839
        self.assertEqual(dirstate.DirState.IN_MEMORY_HASH_MODIFIED,
 
840
                         state._dirblock_state)
855
841
 
856
842
    def test_observed_sha1_not_cachable(self):
857
843
        state, entry = self.get_state_with_a()
 
844
        state.save()
858
845
        oldval = entry[1][0][1]
859
846
        oldstat = entry[1][0][4]
860
847
        self.build_tree(['a'])
861
848
        statvalue = os.lstat('a')
 
849
        self.assertEqual(dirstate.DirState.IN_MEMORY_UNMODIFIED,
 
850
                         state._dirblock_state)
862
851
        state._observed_sha1(entry, "foo", statvalue)
863
852
        self.assertEqual(oldval, entry[1][0][1])
864
853
        self.assertEqual(oldstat, entry[1][0][4])
 
854
        self.assertEqual(dirstate.DirState.IN_MEMORY_UNMODIFIED,
 
855
                         state._dirblock_state)
865
856
 
866
857
    def test_update_entry(self):
867
858
        state, _ = self.get_state_with_a()
892
883
                                          stat_value=stat_value)
893
884
        self.assertEqual(None, link_or_sha1)
894
885
 
895
 
        # The dirblock entry should not have cached the file's sha1 (too new)
 
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
896
889
        self.assertEqual(('f', '', 14, False, dirstate.DirState.NULLSTAT),
897
890
                         entry[1][0])
898
 
        self.assertEqual(dirstate.DirState.IN_MEMORY_MODIFIED,
 
891
        self.assertEqual(dirstate.DirState.IN_MEMORY_UNMODIFIED,
899
892
                         state._dirblock_state)
900
893
        mode = stat_value.st_mode
901
894
        self.assertEqual([('is_exec', mode, False)], state._log)
904
897
        self.assertEqual(dirstate.DirState.IN_MEMORY_UNMODIFIED,
905
898
                         state._dirblock_state)
906
899
 
907
 
        # If we do it again right away, we don't know if the file has changed
908
 
        # so we will re-read the file. Roll the clock back so the file is
909
 
        # guaranteed to look too new.
 
900
        # Roll the clock back so the file is guaranteed to look too new. We
 
901
        # should still not compute the sha1.
910
902
        state.adjust_time(-10)
911
903
        del state._log[:]
912
904
 
914
906
                                          stat_value=stat_value)
915
907
        self.assertEqual([('is_exec', mode, False)], state._log)
916
908
        self.assertEqual(None, link_or_sha1)
917
 
        self.assertEqual(dirstate.DirState.IN_MEMORY_MODIFIED,
 
909
        self.assertEqual(dirstate.DirState.IN_MEMORY_UNMODIFIED,
918
910
                         state._dirblock_state)
919
911
        self.assertEqual(('f', '', 14, False, dirstate.DirState.NULLSTAT),
920
912
                         entry[1][0])
930
922
        self.assertEqual([('is_exec', mode, False)], state._log)
931
923
        self.assertEqual(('f', '', 14, False, dirstate.DirState.NULLSTAT),
932
924
                         entry[1][0])
 
925
        self.assertEqual(dirstate.DirState.IN_MEMORY_UNMODIFIED,
 
926
                         state._dirblock_state)
933
927
 
934
928
        # If the file is no longer new, and the clock has been moved forward
935
929
        # sufficiently, it will cache the sha.
960
954
 
961
955
    def test_update_entry_symlink(self):
962
956
        """Update entry should read symlinks."""
963
 
        self.requireFeature(tests.SymlinkFeature)
 
957
        self.requireFeature(features.SymlinkFeature)
964
958
        state, entry = self.get_state_with_a()
965
959
        state.save()
966
960
        self.assertEqual(dirstate.DirState.IN_MEMORY_UNMODIFIED,
977
971
        # Dirblock is not updated (the link is too new)
978
972
        self.assertEqual([('l', '', 6, False, dirstate.DirState.NULLSTAT)],
979
973
                         entry[1])
980
 
        self.assertEqual(dirstate.DirState.IN_MEMORY_MODIFIED,
 
974
        # The file entry turned into a symlink, that is considered
 
975
        # HASH modified worthy.
 
976
        self.assertEqual(dirstate.DirState.IN_MEMORY_HASH_MODIFIED,
981
977
                         state._dirblock_state)
982
978
 
983
979
        # Because the stat_value looks new, we should re-read the target
 
980
        del state._log[:]
984
981
        link_or_sha1 = self.update_entry(state, entry, abspath='a',
985
982
                                          stat_value=stat_value)
986
983
        self.assertEqual('target', link_or_sha1)
987
 
        self.assertEqual([('read_link', 'a', ''),
988
 
                          ('read_link', 'a', ''),
989
 
                         ], state._log)
 
984
        self.assertEqual([('read_link', 'a', '')], state._log)
990
985
        self.assertEqual([('l', '', 6, False, dirstate.DirState.NULLSTAT)],
991
986
                         entry[1])
 
987
        state.save()
992
988
        state.adjust_time(+20) # Skip into the future, all files look old
 
989
        del state._log[:]
993
990
        link_or_sha1 = self.update_entry(state, entry, abspath='a',
994
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)
995
997
        self.assertEqual('target', link_or_sha1)
996
998
        # We need to re-read the link because only now can we cache it
997
 
        self.assertEqual([('read_link', 'a', ''),
998
 
                          ('read_link', 'a', ''),
999
 
                          ('read_link', 'a', ''),
1000
 
                         ], state._log)
 
999
        self.assertEqual([('read_link', 'a', '')], state._log)
1001
1000
        self.assertEqual([('l', 'target', 6, False, packed_stat)],
1002
1001
                         entry[1])
1003
1002
 
 
1003
        del state._log[:]
1004
1004
        # Another call won't re-read the link
1005
 
        self.assertEqual([('read_link', 'a', ''),
1006
 
                          ('read_link', 'a', ''),
1007
 
                          ('read_link', 'a', ''),
1008
 
                         ], state._log)
 
1005
        self.assertEqual([], state._log)
1009
1006
        link_or_sha1 = self.update_entry(state, entry, abspath='a',
1010
1007
                                          stat_value=stat_value)
1011
1008
        self.assertEqual('target', link_or_sha1)
1026
1023
        self.build_tree(['a/'])
1027
1024
        state.adjust_time(+20)
1028
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
1029
1027
        self.assertEqual(dirstate.DirState.IN_MEMORY_MODIFIED,
1030
1028
                         state._dirblock_state)
1031
1029
        state.save()
1032
1030
        self.assertEqual(dirstate.DirState.IN_MEMORY_UNMODIFIED,
1033
1031
                         state._dirblock_state)
1034
 
        self.assertIs(None, self.do_update_entry(state, entry, 'a'))
 
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
 
1038
        try:
 
1039
            os.utime('a', (t, t))
 
1040
        except OSError:
 
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
 
1047
        # recompute.
 
1048
        self.assertNotEqual(saved_packed_stat, entry[1][0][-1])
1035
1049
        self.assertEqual(dirstate.DirState.IN_MEMORY_UNMODIFIED,
1036
1050
                         state._dirblock_state)
1037
1051
 
1137
1151
 
1138
1152
    def test_update_file_to_symlink(self):
1139
1153
        """File becomes a symlink"""
1140
 
        self.requireFeature(tests.SymlinkFeature)
 
1154
        self.requireFeature(features.SymlinkFeature)
1141
1155
        state, entry = self.get_state_with_a()
1142
1156
        # The file sha1 won't be cached unless the file is old
1143
1157
        state.adjust_time(+10)
1156
1170
 
1157
1171
    def test_update_dir_to_symlink(self):
1158
1172
        """Directory becomes a symlink"""
1159
 
        self.requireFeature(tests.SymlinkFeature)
 
1173
        self.requireFeature(features.SymlinkFeature)
1160
1174
        state, entry = self.get_state_with_a()
1161
1175
        # The symlink target won't be cached if it isn't old
1162
1176
        state.adjust_time(+10)
1166
1180
 
1167
1181
    def test_update_symlink_to_file(self):
1168
1182
        """Symlink becomes a file"""
1169
 
        self.requireFeature(tests.SymlinkFeature)
 
1183
        self.requireFeature(features.SymlinkFeature)
1170
1184
        state, entry = self.get_state_with_a()
1171
1185
        # The symlink and file info won't be cached unless old
1172
1186
        state.adjust_time(+10)
1176
1190
 
1177
1191
    def test_update_symlink_to_dir(self):
1178
1192
        """Symlink becomes a directory"""
1179
 
        self.requireFeature(tests.SymlinkFeature)
 
1193
        self.requireFeature(features.SymlinkFeature)
1180
1194
        state, entry = self.get_state_with_a()
1181
1195
        # The symlink target won't be cached if it isn't old
1182
1196
        state.adjust_time(+10)
1269
1283
 
1270
1284
class TestProcessEntry(test_dirstate.TestCaseWithDirState):
1271
1285
 
 
1286
    scenarios = multiply_scenarios(dir_reader_scenarios(), pe_scenarios)
 
1287
 
1272
1288
    # Set by load_tests
1273
1289
    _process_entry = None
1274
1290