~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test__dirstate_helpers.py

  • Committer: Richard Wilbur
  • Date: 2016-02-04 19:07:28 UTC
  • mto: This revision was merged to the branch mainline in revision 6618.
  • Revision ID: richard.wilbur@gmail.com-20160204190728-p0zvfii6zase0fw7
Update COPYING.txt from the original http://www.gnu.org/licenses/gpl-2.0.txt  (Only differences were in whitespace.)  Thanks to Petr Stodulka for pointing out the discrepancy.

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()
942
960
 
943
961
    def test_update_entry_symlink(self):
944
962
        """Update entry should read symlinks."""
945
 
        self.requireFeature(tests.SymlinkFeature)
 
963
        self.requireFeature(features.SymlinkFeature)
946
964
        state, entry = self.get_state_with_a()
947
965
        state.save()
948
966
        self.assertEqual(dirstate.DirState.IN_MEMORY_UNMODIFIED,
959
977
        # Dirblock is not updated (the link is too new)
960
978
        self.assertEqual([('l', '', 6, False, dirstate.DirState.NULLSTAT)],
961
979
                         entry[1])
962
 
        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,
963
983
                         state._dirblock_state)
964
984
 
965
985
        # Because the stat_value looks new, we should re-read the target
 
986
        del state._log[:]
966
987
        link_or_sha1 = self.update_entry(state, entry, abspath='a',
967
988
                                          stat_value=stat_value)
968
989
        self.assertEqual('target', link_or_sha1)
969
 
        self.assertEqual([('read_link', 'a', ''),
970
 
                          ('read_link', 'a', ''),
971
 
                         ], state._log)
 
990
        self.assertEqual([('read_link', 'a', '')], state._log)
972
991
        self.assertEqual([('l', '', 6, False, dirstate.DirState.NULLSTAT)],
973
992
                         entry[1])
 
993
        state.save()
974
994
        state.adjust_time(+20) # Skip into the future, all files look old
 
995
        del state._log[:]
975
996
        link_or_sha1 = self.update_entry(state, entry, abspath='a',
976
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)
977
1003
        self.assertEqual('target', link_or_sha1)
978
1004
        # We need to re-read the link because only now can we cache it
979
 
        self.assertEqual([('read_link', 'a', ''),
980
 
                          ('read_link', 'a', ''),
981
 
                          ('read_link', 'a', ''),
982
 
                         ], state._log)
 
1005
        self.assertEqual([('read_link', 'a', '')], state._log)
983
1006
        self.assertEqual([('l', 'target', 6, False, packed_stat)],
984
1007
                         entry[1])
985
1008
 
 
1009
        del state._log[:]
986
1010
        # Another call won't re-read the link
987
 
        self.assertEqual([('read_link', 'a', ''),
988
 
                          ('read_link', 'a', ''),
989
 
                          ('read_link', 'a', ''),
990
 
                         ], state._log)
 
1011
        self.assertEqual([], state._log)
991
1012
        link_or_sha1 = self.update_entry(state, entry, abspath='a',
992
1013
                                          stat_value=stat_value)
993
1014
        self.assertEqual('target', link_or_sha1)
1020
1041
                         state._dirblock_state)
1021
1042
        # Change the last-modified time for the directory
1022
1043
        t = time.time() - 100.0
1023
 
        os.utime('a', (t, t))
 
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")
1024
1049
        saved_packed_stat = entry[1][0][-1]
1025
1050
        self.assertIs(None, self.do_update_entry(state, entry, 'a'))
1026
1051
        # We *do* go ahead and update the information in the dirblocks, but we
1132
1157
 
1133
1158
    def test_update_file_to_symlink(self):
1134
1159
        """File becomes a symlink"""
1135
 
        self.requireFeature(tests.SymlinkFeature)
 
1160
        self.requireFeature(features.SymlinkFeature)
1136
1161
        state, entry = self.get_state_with_a()
1137
1162
        # The file sha1 won't be cached unless the file is old
1138
1163
        state.adjust_time(+10)
1151
1176
 
1152
1177
    def test_update_dir_to_symlink(self):
1153
1178
        """Directory becomes a symlink"""
1154
 
        self.requireFeature(tests.SymlinkFeature)
 
1179
        self.requireFeature(features.SymlinkFeature)
1155
1180
        state, entry = self.get_state_with_a()
1156
1181
        # The symlink target won't be cached if it isn't old
1157
1182
        state.adjust_time(+10)
1161
1186
 
1162
1187
    def test_update_symlink_to_file(self):
1163
1188
        """Symlink becomes a file"""
1164
 
        self.requireFeature(tests.SymlinkFeature)
 
1189
        self.requireFeature(features.SymlinkFeature)
1165
1190
        state, entry = self.get_state_with_a()
1166
1191
        # The symlink and file info won't be cached unless old
1167
1192
        state.adjust_time(+10)
1171
1196
 
1172
1197
    def test_update_symlink_to_dir(self):
1173
1198
        """Symlink becomes a directory"""
1174
 
        self.requireFeature(tests.SymlinkFeature)
 
1199
        self.requireFeature(features.SymlinkFeature)
1175
1200
        state, entry = self.get_state_with_a()
1176
1201
        # The symlink target won't be cached if it isn't old
1177
1202
        state.adjust_time(+10)
1318
1343
        state._sha1_provider = UppercaseSHA1Provider()
1319
1344
        self.assertChangedFileIds(['file-id'], tree)
1320
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"))