~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: 2013-10-07 17:04:34 UTC
  • mfrom: (6588.1.1 trunk)
  • Revision ID: pqm@pqm.ubuntu.com-20131007170434-mb0ahksmrzsnhi1i
(vila) Stricter checks on configuration option names (Vincent Ladeuil)

Show diffs side-by-side

added added

removed removed

Lines of Context:
25
25
    errors,
26
26
    osutils,
27
27
    tests,
 
28
    _dirstate_helpers_py,
28
29
    )
29
30
from bzrlib.tests import (
30
31
    test_dirstate,
34
35
    load_tests_apply_scenarios,
35
36
    multiply_scenarios,
36
37
    )
 
38
from bzrlib.tests import (
 
39
    features,
 
40
    )
37
41
 
38
42
 
39
43
load_tests = load_tests_apply_scenarios
40
44
 
41
45
 
42
 
compiled_dirstate_helpers_feature = tests.ModuleAvailableFeature(
 
46
compiled_dirstate_helpers_feature = features.ModuleAvailableFeature(
43
47
    'bzrlib._dirstate_helpers_pyx')
44
48
 
45
49
 
57
61
    process_entry = compiled_dirstate_helpers_feature.module.ProcessEntryC
58
62
    pe_scenarios.append(('dirstate_Pyrex', {'_process_entry': process_entry}))
59
63
 
 
64
helper_scenarios = [('dirstate_Python', {'helpers': _dirstate_helpers_py})]
 
65
if compiled_dirstate_helpers_feature.available():
 
66
    helper_scenarios.append(('dirstate_Pyrex',
 
67
        {'helpers': compiled_dirstate_helpers_feature.module}))
 
68
 
60
69
 
61
70
class TestBisectPathMixin(object):
62
71
    """Test that _bisect_path_*() returns the expected values.
822
831
 
823
832
    def test_observed_sha1_cachable(self):
824
833
        state, entry = self.get_state_with_a()
 
834
        state.save()
825
835
        atime = time.time() - 10
826
836
        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)
 
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)
830
841
        state._observed_sha1(entry, "foo", statvalue)
831
842
        self.assertEqual('foo', entry[1][0][1])
832
843
        packed_stat = dirstate.pack_stat(statvalue)
833
844
        self.assertEqual(packed_stat, entry[1][0][4])
 
845
        self.assertEqual(dirstate.DirState.IN_MEMORY_HASH_MODIFIED,
 
846
                         state._dirblock_state)
834
847
 
835
848
    def test_observed_sha1_not_cachable(self):
836
849
        state, entry = self.get_state_with_a()
 
850
        state.save()
837
851
        oldval = entry[1][0][1]
838
852
        oldstat = entry[1][0][4]
839
853
        self.build_tree(['a'])
840
854
        statvalue = os.lstat('a')
 
855
        self.assertEqual(dirstate.DirState.IN_MEMORY_UNMODIFIED,
 
856
                         state._dirblock_state)
841
857
        state._observed_sha1(entry, "foo", statvalue)
842
858
        self.assertEqual(oldval, entry[1][0][1])
843
859
        self.assertEqual(oldstat, entry[1][0][4])
 
860
        self.assertEqual(dirstate.DirState.IN_MEMORY_UNMODIFIED,
 
861
                         state._dirblock_state)
844
862
 
845
863
    def test_update_entry(self):
846
864
        state, _ = self.get_state_with_a()
871
889
                                          stat_value=stat_value)
872
890
        self.assertEqual(None, link_or_sha1)
873
891
 
874
 
        # The dirblock entry should not have cached the file's sha1 (too new)
 
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
875
895
        self.assertEqual(('f', '', 14, False, dirstate.DirState.NULLSTAT),
876
896
                         entry[1][0])
877
 
        self.assertEqual(dirstate.DirState.IN_MEMORY_MODIFIED,
 
897
        self.assertEqual(dirstate.DirState.IN_MEMORY_UNMODIFIED,
878
898
                         state._dirblock_state)
879
899
        mode = stat_value.st_mode
880
900
        self.assertEqual([('is_exec', mode, False)], state._log)
883
903
        self.assertEqual(dirstate.DirState.IN_MEMORY_UNMODIFIED,
884
904
                         state._dirblock_state)
885
905
 
886
 
        # If we do it again right away, we don't know if the file has changed
887
 
        # so we will re-read the file. Roll the clock back so the file is
888
 
        # guaranteed to look too new.
 
906
        # Roll the clock back so the file is guaranteed to look too new. We
 
907
        # should still not compute the sha1.
889
908
        state.adjust_time(-10)
890
909
        del state._log[:]
891
910
 
893
912
                                          stat_value=stat_value)
894
913
        self.assertEqual([('is_exec', mode, False)], state._log)
895
914
        self.assertEqual(None, link_or_sha1)
896
 
        self.assertEqual(dirstate.DirState.IN_MEMORY_MODIFIED,
 
915
        self.assertEqual(dirstate.DirState.IN_MEMORY_UNMODIFIED,
897
916
                         state._dirblock_state)
898
917
        self.assertEqual(('f', '', 14, False, dirstate.DirState.NULLSTAT),
899
918
                         entry[1][0])
909
928
        self.assertEqual([('is_exec', mode, False)], state._log)
910
929
        self.assertEqual(('f', '', 14, False, dirstate.DirState.NULLSTAT),
911
930
                         entry[1][0])
 
931
        self.assertEqual(dirstate.DirState.IN_MEMORY_UNMODIFIED,
 
932
                         state._dirblock_state)
912
933
 
913
934
        # If the file is no longer new, and the clock has been moved forward
914
935
        # sufficiently, it will cache the sha.
939
960
 
940
961
    def test_update_entry_symlink(self):
941
962
        """Update entry should read symlinks."""
942
 
        self.requireFeature(tests.SymlinkFeature)
 
963
        self.requireFeature(features.SymlinkFeature)
943
964
        state, entry = self.get_state_with_a()
944
965
        state.save()
945
966
        self.assertEqual(dirstate.DirState.IN_MEMORY_UNMODIFIED,
956
977
        # Dirblock is not updated (the link is too new)
957
978
        self.assertEqual([('l', '', 6, False, dirstate.DirState.NULLSTAT)],
958
979
                         entry[1])
959
 
        self.assertEqual(dirstate.DirState.IN_MEMORY_MODIFIED,
 
980
        # The file entry turned into a symlink, that is considered
 
981
        # HASH modified worthy.
 
982
        self.assertEqual(dirstate.DirState.IN_MEMORY_HASH_MODIFIED,
960
983
                         state._dirblock_state)
961
984
 
962
985
        # Because the stat_value looks new, we should re-read the target
 
986
        del state._log[:]
963
987
        link_or_sha1 = self.update_entry(state, entry, abspath='a',
964
988
                                          stat_value=stat_value)
965
989
        self.assertEqual('target', link_or_sha1)
966
 
        self.assertEqual([('read_link', 'a', ''),
967
 
                          ('read_link', 'a', ''),
968
 
                         ], state._log)
 
990
        self.assertEqual([('read_link', 'a', '')], state._log)
969
991
        self.assertEqual([('l', '', 6, False, dirstate.DirState.NULLSTAT)],
970
992
                         entry[1])
 
993
        state.save()
971
994
        state.adjust_time(+20) # Skip into the future, all files look old
 
995
        del state._log[:]
972
996
        link_or_sha1 = self.update_entry(state, entry, abspath='a',
973
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)
974
1003
        self.assertEqual('target', link_or_sha1)
975
1004
        # We need to re-read the link because only now can we cache it
976
 
        self.assertEqual([('read_link', 'a', ''),
977
 
                          ('read_link', 'a', ''),
978
 
                          ('read_link', 'a', ''),
979
 
                         ], state._log)
 
1005
        self.assertEqual([('read_link', 'a', '')], state._log)
980
1006
        self.assertEqual([('l', 'target', 6, False, packed_stat)],
981
1007
                         entry[1])
982
1008
 
 
1009
        del state._log[:]
983
1010
        # Another call won't re-read the link
984
 
        self.assertEqual([('read_link', 'a', ''),
985
 
                          ('read_link', 'a', ''),
986
 
                          ('read_link', 'a', ''),
987
 
                         ], state._log)
 
1011
        self.assertEqual([], state._log)
988
1012
        link_or_sha1 = self.update_entry(state, entry, abspath='a',
989
1013
                                          stat_value=stat_value)
990
1014
        self.assertEqual('target', link_or_sha1)
1005
1029
        self.build_tree(['a/'])
1006
1030
        state.adjust_time(+20)
1007
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
1008
1033
        self.assertEqual(dirstate.DirState.IN_MEMORY_MODIFIED,
1009
1034
                         state._dirblock_state)
1010
1035
        state.save()
1011
1036
        self.assertEqual(dirstate.DirState.IN_MEMORY_UNMODIFIED,
1012
1037
                         state._dirblock_state)
1013
 
        self.assertIs(None, self.do_update_entry(state, entry, 'a'))
 
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
 
1044
        try:
 
1045
            os.utime('a', (t, t))
 
1046
        except OSError:
 
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
 
1053
        # recompute.
 
1054
        self.assertNotEqual(saved_packed_stat, entry[1][0][-1])
1014
1055
        self.assertEqual(dirstate.DirState.IN_MEMORY_UNMODIFIED,
1015
1056
                         state._dirblock_state)
1016
1057
 
1116
1157
 
1117
1158
    def test_update_file_to_symlink(self):
1118
1159
        """File becomes a symlink"""
1119
 
        self.requireFeature(tests.SymlinkFeature)
 
1160
        self.requireFeature(features.SymlinkFeature)
1120
1161
        state, entry = self.get_state_with_a()
1121
1162
        # The file sha1 won't be cached unless the file is old
1122
1163
        state.adjust_time(+10)
1135
1176
 
1136
1177
    def test_update_dir_to_symlink(self):
1137
1178
        """Directory becomes a symlink"""
1138
 
        self.requireFeature(tests.SymlinkFeature)
 
1179
        self.requireFeature(features.SymlinkFeature)
1139
1180
        state, entry = self.get_state_with_a()
1140
1181
        # The symlink target won't be cached if it isn't old
1141
1182
        state.adjust_time(+10)
1145
1186
 
1146
1187
    def test_update_symlink_to_file(self):
1147
1188
        """Symlink becomes a file"""
1148
 
        self.requireFeature(tests.SymlinkFeature)
 
1189
        self.requireFeature(features.SymlinkFeature)
1149
1190
        state, entry = self.get_state_with_a()
1150
1191
        # The symlink and file info won't be cached unless old
1151
1192
        state.adjust_time(+10)
1155
1196
 
1156
1197
    def test_update_symlink_to_dir(self):
1157
1198
        """Symlink becomes a directory"""
1158
 
        self.requireFeature(tests.SymlinkFeature)
 
1199
        self.requireFeature(features.SymlinkFeature)
1159
1200
        state, entry = self.get_state_with_a()
1160
1201
        # The symlink target won't be cached if it isn't old
1161
1202
        state.adjust_time(+10)
1302
1343
        state._sha1_provider = UppercaseSHA1Provider()
1303
1344
        self.assertChangedFileIds(['file-id'], tree)
1304
1345
 
 
1346
 
 
1347
class TestPackStat(tests.TestCase):
 
1348
    """Check packed representaton of stat values is robust on all inputs"""
 
1349
 
 
1350
    scenarios = helper_scenarios
 
1351
 
 
1352
    def pack(self, statlike_tuple):
 
1353
        return self.helpers.pack_stat(os.stat_result(statlike_tuple))
 
1354
 
 
1355
    @staticmethod
 
1356
    def unpack_field(packed_string, stat_field):
 
1357
        return _dirstate_helpers_py._unpack_stat(packed_string)[stat_field]
 
1358
 
 
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)))
 
1362
 
 
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"))
 
1366
 
 
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"))
 
1370
 
 
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"))
 
1374
 
 
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"))
 
1378
 
 
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"))
 
1382
 
 
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"))
 
1386
 
 
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"))
 
1390
 
 
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"))
 
1394
 
 
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"))