/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to breezy/tests/test__dirstate_helpers.py

  • Committer: Jelmer Vernooij
  • Date: 2017-06-08 23:30:31 UTC
  • mto: This revision was merged to the branch mainline in revision 6690.
  • Revision ID: jelmer@jelmer.uk-20170608233031-3qavls2o7a1pqllj
Update imports.

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
20
20
import os
21
21
import time
22
22
 
23
 
from bzrlib import (
24
 
    dirstate,
 
23
from .. import (
25
24
    errors,
26
25
    osutils,
27
26
    tests,
28
27
    )
29
 
from bzrlib.tests import (
 
28
from ..bzr import (
 
29
    dirstate,
 
30
    _dirstate_helpers_py,
 
31
    )
 
32
from . import (
30
33
    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
 
34
    )
 
35
from .test_osutils import dir_reader_scenarios
 
36
from .scenarios import (
 
37
    load_tests_apply_scenarios,
 
38
    multiply_scenarios,
 
39
    )
 
40
from . import (
 
41
    features,
 
42
    )
 
43
 
 
44
 
 
45
load_tests = load_tests_apply_scenarios
 
46
 
 
47
 
 
48
compiled_dirstate_helpers_feature = features.ModuleAvailableFeature(
 
49
    'breezy._dirstate_helpers_pyx')
 
50
 
 
51
 
 
52
# FIXME: we should also parametrize against SHA1Provider !
 
53
 
 
54
ue_scenarios = [('dirstate_Python',
 
55
    {'update_entry': dirstate.py_update_entry})]
 
56
if compiled_dirstate_helpers_feature.available():
 
57
    update_entry = compiled_dirstate_helpers_feature.module.update_entry
 
58
    ue_scenarios.append(('dirstate_Pyrex', {'update_entry': update_entry}))
 
59
 
 
60
pe_scenarios = [('dirstate_Python',
 
61
    {'_process_entry': dirstate.ProcessEntryPython})]
 
62
if compiled_dirstate_helpers_feature.available():
 
63
    process_entry = compiled_dirstate_helpers_feature.module.ProcessEntryC
 
64
    pe_scenarios.append(('dirstate_Pyrex', {'_process_entry': process_entry}))
 
65
 
 
66
helper_scenarios = [('dirstate_Python', {'helpers': _dirstate_helpers_py})]
 
67
if compiled_dirstate_helpers_feature.available():
 
68
    helper_scenarios.append(('dirstate_Pyrex',
 
69
        {'helpers': compiled_dirstate_helpers_feature.module}))
85
70
 
86
71
 
87
72
class TestBisectPathMixin(object):
243
228
    """Run all Bisect Path tests against _bisect_path_left."""
244
229
 
245
230
    def get_bisect_path(self):
246
 
        from bzrlib._dirstate_helpers_py import _bisect_path_left
 
231
        from breezy._dirstate_helpers_py import _bisect_path_left
247
232
        return _bisect_path_left
248
233
 
249
234
    def get_bisect(self):
256
241
    _test_needs_features = [compiled_dirstate_helpers_feature]
257
242
 
258
243
    def get_bisect_path(self):
259
 
        from bzrlib._dirstate_helpers_pyx import _bisect_path_left
 
244
        from breezy._dirstate_helpers_pyx import _bisect_path_left
260
245
        return _bisect_path_left
261
246
 
262
247
 
264
249
    """Run all Bisect Path tests against _bisect_path_right"""
265
250
 
266
251
    def get_bisect_path(self):
267
 
        from bzrlib._dirstate_helpers_py import _bisect_path_right
 
252
        from breezy._dirstate_helpers_py import _bisect_path_right
268
253
        return _bisect_path_right
269
254
 
270
255
    def get_bisect(self):
277
262
    _test_needs_features = [compiled_dirstate_helpers_feature]
278
263
 
279
264
    def get_bisect_path(self):
280
 
        from bzrlib._dirstate_helpers_pyx import _bisect_path_right
 
265
        from breezy._dirstate_helpers_pyx import _bisect_path_right
281
266
        return _bisect_path_right
282
267
 
283
268
 
295
280
 
296
281
    def get_bisect_dirblock(self):
297
282
        """Return an implementation of bisect_dirblock"""
298
 
        from bzrlib._dirstate_helpers_py import bisect_dirblock
 
283
        from breezy._dirstate_helpers_py import bisect_dirblock
299
284
        return bisect_dirblock
300
285
 
301
286
    def assertBisect(self, dirblocks, split_dirblocks, path, *args, **kwargs):
389
374
    _test_needs_features = [compiled_dirstate_helpers_feature]
390
375
 
391
376
    def get_bisect_dirblock(self):
392
 
        from bzrlib._dirstate_helpers_pyx import bisect_dirblock
 
377
        from breezy._dirstate_helpers_pyx import bisect_dirblock
393
378
        return bisect_dirblock
394
379
 
395
380
 
405
390
 
406
391
    def get_cmp_by_dirs(self):
407
392
        """Get a specific implementation of cmp_by_dirs."""
408
 
        from bzrlib._dirstate_helpers_py import cmp_by_dirs
 
393
        from breezy._dirstate_helpers_py import cmp_by_dirs
409
394
        return cmp_by_dirs
410
395
 
411
396
    def assertCmpByDirs(self, expected, str1, str2):
511
496
    _test_needs_features = [compiled_dirstate_helpers_feature]
512
497
 
513
498
    def get_cmp_by_dirs(self):
514
 
        from bzrlib._dirstate_helpers_pyx import cmp_by_dirs
 
499
        from breezy._dirstate_helpers_pyx import cmp_by_dirs
515
500
        return cmp_by_dirs
516
501
 
517
502
 
527
512
 
528
513
    def get_cmp_path_by_dirblock(self):
529
514
        """Get a specific implementation of _cmp_path_by_dirblock."""
530
 
        from bzrlib._dirstate_helpers_py import _cmp_path_by_dirblock
 
515
        from breezy._dirstate_helpers_py import _cmp_path_by_dirblock
531
516
        return _cmp_path_by_dirblock
532
517
 
533
518
    def assertCmpPathByDirblock(self, paths):
662
647
    _test_needs_features = [compiled_dirstate_helpers_feature]
663
648
 
664
649
    def get_cmp_by_dirs(self):
665
 
        from bzrlib._dirstate_helpers_pyx import _cmp_path_by_dirblock
 
650
        from breezy._dirstate_helpers_pyx import _cmp_path_by_dirblock
666
651
        return _cmp_path_by_dirblock
667
652
 
668
653
 
672
657
    _test_needs_features = [compiled_dirstate_helpers_feature]
673
658
 
674
659
    def assertMemRChr(self, expected, s, c):
675
 
        from bzrlib._dirstate_helpers_pyx import _py_memrchr
 
660
        from breezy._dirstate_helpers_pyx import _py_memrchr
676
661
        self.assertEqual(expected, _py_memrchr(s, c))
677
662
 
678
663
    def test_missing(self):
719
704
    implementation.
720
705
    """
721
706
 
 
707
    # inherits scenarios from test_dirstate
 
708
 
722
709
    def get_read_dirblocks(self):
723
 
        from bzrlib._dirstate_helpers_py import _read_dirblocks
 
710
        from breezy._dirstate_helpers_py import _read_dirblocks
724
711
        return _read_dirblocks
725
712
 
726
713
    def test_smoketest(self):
737
724
 
738
725
    def test_trailing_garbage(self):
739
726
        tree, state, expected = self.create_basic_dirstate()
740
 
        # On Linux, we can write extra data as long as we haven't read yet, but
 
727
        # On Unix, we can write extra data as long as we haven't read yet, but
741
728
        # on Win32, if you've opened the file with FILE_SHARE_READ, trying to
742
729
        # open it in append mode will fail.
743
730
        state.unlock()
760
747
    _test_needs_features = [compiled_dirstate_helpers_feature]
761
748
 
762
749
    def get_read_dirblocks(self):
763
 
        from bzrlib._dirstate_helpers_pyx import _read_dirblocks
 
750
        from breezy._dirstate_helpers_pyx import _read_dirblocks
764
751
        return _read_dirblocks
765
752
 
766
753
 
774
761
 
775
762
    def test_bisect_dirblock(self):
776
763
        if compiled_dirstate_helpers_feature.available():
777
 
            from bzrlib._dirstate_helpers_pyx import bisect_dirblock
 
764
            from breezy._dirstate_helpers_pyx import bisect_dirblock
778
765
        else:
779
 
            from bzrlib._dirstate_helpers_py import bisect_dirblock
 
766
            from breezy._dirstate_helpers_py import bisect_dirblock
780
767
        self.assertIs(bisect_dirblock, dirstate.bisect_dirblock)
781
768
 
782
769
    def test__bisect_path_left(self):
783
770
        if compiled_dirstate_helpers_feature.available():
784
 
            from bzrlib._dirstate_helpers_pyx import _bisect_path_left
 
771
            from breezy._dirstate_helpers_pyx import _bisect_path_left
785
772
        else:
786
 
            from bzrlib._dirstate_helpers_py import _bisect_path_left
 
773
            from breezy._dirstate_helpers_py import _bisect_path_left
787
774
        self.assertIs(_bisect_path_left, dirstate._bisect_path_left)
788
775
 
789
776
    def test__bisect_path_right(self):
790
777
        if compiled_dirstate_helpers_feature.available():
791
 
            from bzrlib._dirstate_helpers_pyx import _bisect_path_right
 
778
            from breezy._dirstate_helpers_pyx import _bisect_path_right
792
779
        else:
793
 
            from bzrlib._dirstate_helpers_py import _bisect_path_right
 
780
            from breezy._dirstate_helpers_py import _bisect_path_right
794
781
        self.assertIs(_bisect_path_right, dirstate._bisect_path_right)
795
782
 
796
783
    def test_cmp_by_dirs(self):
797
784
        if compiled_dirstate_helpers_feature.available():
798
 
            from bzrlib._dirstate_helpers_pyx import cmp_by_dirs
 
785
            from breezy._dirstate_helpers_pyx import cmp_by_dirs
799
786
        else:
800
 
            from bzrlib._dirstate_helpers_py import cmp_by_dirs
 
787
            from breezy._dirstate_helpers_py import cmp_by_dirs
801
788
        self.assertIs(cmp_by_dirs, dirstate.cmp_by_dirs)
802
789
 
803
790
    def test__read_dirblocks(self):
804
791
        if compiled_dirstate_helpers_feature.available():
805
 
            from bzrlib._dirstate_helpers_pyx import _read_dirblocks
 
792
            from breezy._dirstate_helpers_pyx import _read_dirblocks
806
793
        else:
807
 
            from bzrlib._dirstate_helpers_py import _read_dirblocks
 
794
            from breezy._dirstate_helpers_py import _read_dirblocks
808
795
        self.assertIs(_read_dirblocks, dirstate._read_dirblocks)
809
796
 
810
797
    def test_update_entry(self):
811
798
        if compiled_dirstate_helpers_feature.available():
812
 
            from bzrlib._dirstate_helpers_pyx import update_entry
 
799
            from breezy._dirstate_helpers_pyx import update_entry
813
800
        else:
814
 
            from bzrlib.dirstate import update_entry
 
801
            from breezy.dirstate import update_entry
815
802
        self.assertIs(update_entry, dirstate.update_entry)
816
803
 
817
804
    def test_process_entry(self):
818
805
        if compiled_dirstate_helpers_feature.available():
819
 
            from bzrlib._dirstate_helpers_pyx import ProcessEntryC
 
806
            from breezy._dirstate_helpers_pyx import ProcessEntryC
820
807
            self.assertIs(ProcessEntryC, dirstate._process_entry)
821
808
        else:
822
 
            from bzrlib.dirstate import ProcessEntryPython
 
809
            from breezy.dirstate import ProcessEntryPython
823
810
            self.assertIs(ProcessEntryPython, dirstate._process_entry)
824
811
 
825
812
 
826
813
class TestUpdateEntry(test_dirstate.TestCaseWithDirState):
827
814
    """Test the DirState.update_entry functions"""
828
815
 
 
816
    scenarios = multiply_scenarios(
 
817
        dir_reader_scenarios(), ue_scenarios)
 
818
 
829
819
    # Set by load_tests
830
820
    update_entry = None
831
821
 
843
833
 
844
834
    def test_observed_sha1_cachable(self):
845
835
        state, entry = self.get_state_with_a()
 
836
        state.save()
846
837
        atime = time.time() - 10
847
838
        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)
 
839
        statvalue = test_dirstate._FakeStat.from_stat(os.lstat('a'))
 
840
        statvalue.st_mtime = statvalue.st_ctime = atime
 
841
        self.assertEqual(dirstate.DirState.IN_MEMORY_UNMODIFIED,
 
842
                         state._dirblock_state)
851
843
        state._observed_sha1(entry, "foo", statvalue)
852
844
        self.assertEqual('foo', entry[1][0][1])
853
845
        packed_stat = dirstate.pack_stat(statvalue)
854
846
        self.assertEqual(packed_stat, entry[1][0][4])
 
847
        self.assertEqual(dirstate.DirState.IN_MEMORY_HASH_MODIFIED,
 
848
                         state._dirblock_state)
855
849
 
856
850
    def test_observed_sha1_not_cachable(self):
857
851
        state, entry = self.get_state_with_a()
 
852
        state.save()
858
853
        oldval = entry[1][0][1]
859
854
        oldstat = entry[1][0][4]
860
855
        self.build_tree(['a'])
861
856
        statvalue = os.lstat('a')
 
857
        self.assertEqual(dirstate.DirState.IN_MEMORY_UNMODIFIED,
 
858
                         state._dirblock_state)
862
859
        state._observed_sha1(entry, "foo", statvalue)
863
860
        self.assertEqual(oldval, entry[1][0][1])
864
861
        self.assertEqual(oldstat, entry[1][0][4])
 
862
        self.assertEqual(dirstate.DirState.IN_MEMORY_UNMODIFIED,
 
863
                         state._dirblock_state)
865
864
 
866
865
    def test_update_entry(self):
867
866
        state, _ = self.get_state_with_a()
892
891
                                          stat_value=stat_value)
893
892
        self.assertEqual(None, link_or_sha1)
894
893
 
895
 
        # The dirblock entry should not have cached the file's sha1 (too new)
 
894
        # The dirblock entry should not have computed or cached the file's
 
895
        # sha1, but it did update the files' st_size. However, this is not
 
896
        # worth writing a dirstate file for, so we leave the state UNMODIFIED
896
897
        self.assertEqual(('f', '', 14, False, dirstate.DirState.NULLSTAT),
897
898
                         entry[1][0])
898
 
        self.assertEqual(dirstate.DirState.IN_MEMORY_MODIFIED,
 
899
        self.assertEqual(dirstate.DirState.IN_MEMORY_UNMODIFIED,
899
900
                         state._dirblock_state)
900
901
        mode = stat_value.st_mode
901
902
        self.assertEqual([('is_exec', mode, False)], state._log)
904
905
        self.assertEqual(dirstate.DirState.IN_MEMORY_UNMODIFIED,
905
906
                         state._dirblock_state)
906
907
 
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.
 
908
        # Roll the clock back so the file is guaranteed to look too new. We
 
909
        # should still not compute the sha1.
910
910
        state.adjust_time(-10)
911
911
        del state._log[:]
912
912
 
914
914
                                          stat_value=stat_value)
915
915
        self.assertEqual([('is_exec', mode, False)], state._log)
916
916
        self.assertEqual(None, link_or_sha1)
917
 
        self.assertEqual(dirstate.DirState.IN_MEMORY_MODIFIED,
 
917
        self.assertEqual(dirstate.DirState.IN_MEMORY_UNMODIFIED,
918
918
                         state._dirblock_state)
919
919
        self.assertEqual(('f', '', 14, False, dirstate.DirState.NULLSTAT),
920
920
                         entry[1][0])
930
930
        self.assertEqual([('is_exec', mode, False)], state._log)
931
931
        self.assertEqual(('f', '', 14, False, dirstate.DirState.NULLSTAT),
932
932
                         entry[1][0])
 
933
        self.assertEqual(dirstate.DirState.IN_MEMORY_UNMODIFIED,
 
934
                         state._dirblock_state)
933
935
 
934
936
        # If the file is no longer new, and the clock has been moved forward
935
937
        # sufficiently, it will cache the sha.
960
962
 
961
963
    def test_update_entry_symlink(self):
962
964
        """Update entry should read symlinks."""
963
 
        self.requireFeature(tests.SymlinkFeature)
 
965
        self.requireFeature(features.SymlinkFeature)
964
966
        state, entry = self.get_state_with_a()
965
967
        state.save()
966
968
        self.assertEqual(dirstate.DirState.IN_MEMORY_UNMODIFIED,
977
979
        # Dirblock is not updated (the link is too new)
978
980
        self.assertEqual([('l', '', 6, False, dirstate.DirState.NULLSTAT)],
979
981
                         entry[1])
980
 
        self.assertEqual(dirstate.DirState.IN_MEMORY_MODIFIED,
 
982
        # The file entry turned into a symlink, that is considered
 
983
        # HASH modified worthy.
 
984
        self.assertEqual(dirstate.DirState.IN_MEMORY_HASH_MODIFIED,
981
985
                         state._dirblock_state)
982
986
 
983
987
        # Because the stat_value looks new, we should re-read the target
 
988
        del state._log[:]
984
989
        link_or_sha1 = self.update_entry(state, entry, abspath='a',
985
990
                                          stat_value=stat_value)
986
991
        self.assertEqual('target', link_or_sha1)
987
 
        self.assertEqual([('read_link', 'a', ''),
988
 
                          ('read_link', 'a', ''),
989
 
                         ], state._log)
 
992
        self.assertEqual([('read_link', 'a', '')], state._log)
990
993
        self.assertEqual([('l', '', 6, False, dirstate.DirState.NULLSTAT)],
991
994
                         entry[1])
 
995
        state.save()
992
996
        state.adjust_time(+20) # Skip into the future, all files look old
 
997
        del state._log[:]
993
998
        link_or_sha1 = self.update_entry(state, entry, abspath='a',
994
999
                                          stat_value=stat_value)
 
1000
        # The symlink stayed a symlink. So while it is new enough to cache, we
 
1001
        # don't bother setting the flag, because it is not really worth saving
 
1002
        # (when we stat the symlink, we'll have paged in the target.)
 
1003
        self.assertEqual(dirstate.DirState.IN_MEMORY_UNMODIFIED,
 
1004
                         state._dirblock_state)
995
1005
        self.assertEqual('target', link_or_sha1)
996
1006
        # 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)
 
1007
        self.assertEqual([('read_link', 'a', '')], state._log)
1001
1008
        self.assertEqual([('l', 'target', 6, False, packed_stat)],
1002
1009
                         entry[1])
1003
1010
 
 
1011
        del state._log[:]
1004
1012
        # 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)
 
1013
        self.assertEqual([], state._log)
1009
1014
        link_or_sha1 = self.update_entry(state, entry, abspath='a',
1010
1015
                                          stat_value=stat_value)
1011
1016
        self.assertEqual('target', link_or_sha1)
1026
1031
        self.build_tree(['a/'])
1027
1032
        state.adjust_time(+20)
1028
1033
        self.assertIs(None, self.do_update_entry(state, entry, 'a'))
 
1034
        # a/ used to be a file, but is now a directory, worth saving
1029
1035
        self.assertEqual(dirstate.DirState.IN_MEMORY_MODIFIED,
1030
1036
                         state._dirblock_state)
1031
1037
        state.save()
1032
1038
        self.assertEqual(dirstate.DirState.IN_MEMORY_UNMODIFIED,
1033
1039
                         state._dirblock_state)
1034
 
        self.assertIs(None, self.do_update_entry(state, entry, 'a'))
 
1040
        # No changes to a/ means not worth saving.
 
1041
        self.assertIs(None, self.do_update_entry(state, entry, 'a'))
 
1042
        self.assertEqual(dirstate.DirState.IN_MEMORY_UNMODIFIED,
 
1043
                         state._dirblock_state)
 
1044
        # Change the last-modified time for the directory
 
1045
        t = time.time() - 100.0
 
1046
        try:
 
1047
            os.utime('a', (t, t))
 
1048
        except OSError:
 
1049
            # It looks like Win32 + FAT doesn't allow to change times on a dir.
 
1050
            raise tests.TestSkipped("can't update mtime of a dir on FAT")
 
1051
        saved_packed_stat = entry[1][0][-1]
 
1052
        self.assertIs(None, self.do_update_entry(state, entry, 'a'))
 
1053
        # We *do* go ahead and update the information in the dirblocks, but we
 
1054
        # don't bother setting IN_MEMORY_MODIFIED because it is trivial to
 
1055
        # recompute.
 
1056
        self.assertNotEqual(saved_packed_stat, entry[1][0][-1])
1035
1057
        self.assertEqual(dirstate.DirState.IN_MEMORY_UNMODIFIED,
1036
1058
                         state._dirblock_state)
1037
1059
 
1137
1159
 
1138
1160
    def test_update_file_to_symlink(self):
1139
1161
        """File becomes a symlink"""
1140
 
        self.requireFeature(tests.SymlinkFeature)
 
1162
        self.requireFeature(features.SymlinkFeature)
1141
1163
        state, entry = self.get_state_with_a()
1142
1164
        # The file sha1 won't be cached unless the file is old
1143
1165
        state.adjust_time(+10)
1156
1178
 
1157
1179
    def test_update_dir_to_symlink(self):
1158
1180
        """Directory becomes a symlink"""
1159
 
        self.requireFeature(tests.SymlinkFeature)
 
1181
        self.requireFeature(features.SymlinkFeature)
1160
1182
        state, entry = self.get_state_with_a()
1161
1183
        # The symlink target won't be cached if it isn't old
1162
1184
        state.adjust_time(+10)
1166
1188
 
1167
1189
    def test_update_symlink_to_file(self):
1168
1190
        """Symlink becomes a file"""
1169
 
        self.requireFeature(tests.SymlinkFeature)
 
1191
        self.requireFeature(features.SymlinkFeature)
1170
1192
        state, entry = self.get_state_with_a()
1171
1193
        # The symlink and file info won't be cached unless old
1172
1194
        state.adjust_time(+10)
1176
1198
 
1177
1199
    def test_update_symlink_to_dir(self):
1178
1200
        """Symlink becomes a directory"""
1179
 
        self.requireFeature(tests.SymlinkFeature)
 
1201
        self.requireFeature(features.SymlinkFeature)
1180
1202
        state, entry = self.get_state_with_a()
1181
1203
        # The symlink target won't be cached if it isn't old
1182
1204
        state.adjust_time(+10)
1269
1291
 
1270
1292
class TestProcessEntry(test_dirstate.TestCaseWithDirState):
1271
1293
 
 
1294
    scenarios = multiply_scenarios(dir_reader_scenarios(), pe_scenarios)
 
1295
 
1272
1296
    # Set by load_tests
1273
1297
    _process_entry = None
1274
1298
 
1321
1345
        state._sha1_provider = UppercaseSHA1Provider()
1322
1346
        self.assertChangedFileIds(['file-id'], tree)
1323
1347
 
 
1348
 
 
1349
class TestPackStat(tests.TestCase):
 
1350
    """Check packed representaton of stat values is robust on all inputs"""
 
1351
 
 
1352
    scenarios = helper_scenarios
 
1353
 
 
1354
    def pack(self, statlike_tuple):
 
1355
        return self.helpers.pack_stat(os.stat_result(statlike_tuple))
 
1356
 
 
1357
    @staticmethod
 
1358
    def unpack_field(packed_string, stat_field):
 
1359
        return _dirstate_helpers_py._unpack_stat(packed_string)[stat_field]
 
1360
 
 
1361
    def test_result(self):
 
1362
        self.assertEqual("AAAQAAAAABAAAAARAAAAAgAAAAEAAIHk",
 
1363
            self.pack((33252, 1, 2, 0, 0, 0, 4096, 15.5, 16.5, 17.5)))
 
1364
 
 
1365
    def test_giant_inode(self):
 
1366
        packed = self.pack((33252, 0xF80000ABC, 0, 0, 0, 0, 0, 0, 0, 0))
 
1367
        self.assertEqual(0x80000ABC, self.unpack_field(packed, "st_ino"))
 
1368
 
 
1369
    def test_giant_size(self):
 
1370
        packed = self.pack((33252, 0, 0, 0, 0, 0, (1 << 33) + 4096, 0, 0, 0))
 
1371
        self.assertEqual(4096, self.unpack_field(packed, "st_size"))
 
1372
 
 
1373
    def test_fractional_mtime(self):
 
1374
        packed = self.pack((33252, 0, 0, 0, 0, 0, 0, 0, 16.9375, 0))
 
1375
        self.assertEqual(16, self.unpack_field(packed, "st_mtime"))
 
1376
 
 
1377
    def test_ancient_mtime(self):
 
1378
        packed = self.pack((33252, 0, 0, 0, 0, 0, 0, 0, -11644473600.0, 0))
 
1379
        self.assertEqual(1240428288, self.unpack_field(packed, "st_mtime"))
 
1380
 
 
1381
    def test_distant_mtime(self):
 
1382
        packed = self.pack((33252, 0, 0, 0, 0, 0, 0, 0, 64060588800.0, 0))
 
1383
        self.assertEqual(3931046656, self.unpack_field(packed, "st_mtime"))
 
1384
 
 
1385
    def test_fractional_ctime(self):
 
1386
        packed = self.pack((33252, 0, 0, 0, 0, 0, 0, 0, 0, 17.5625))
 
1387
        self.assertEqual(17, self.unpack_field(packed, "st_ctime"))
 
1388
 
 
1389
    def test_ancient_ctime(self):
 
1390
        packed = self.pack((33252, 0, 0, 0, 0, 0, 0, 0, 0, -11644473600.0))
 
1391
        self.assertEqual(1240428288, self.unpack_field(packed, "st_ctime"))
 
1392
 
 
1393
    def test_distant_ctime(self):
 
1394
        packed = self.pack((33252, 0, 0, 0, 0, 0, 0, 0, 0, 64060588800.0))
 
1395
        self.assertEqual(3931046656, self.unpack_field(packed, "st_ctime"))
 
1396
 
 
1397
    def test_negative_dev(self):
 
1398
        packed = self.pack((33252, 0, -0xFFFFFCDE, 0, 0, 0, 0, 0, 0, 0))
 
1399
        self.assertEqual(0x322, self.unpack_field(packed, "st_dev"))