~bzr-pqm/bzr/bzr.dev

2201.1.1 by John Arbash Meinel
Fix bug #76299 by ignoring write errors during readonly hashcache write.
1
# Copyright (C) 2006 Canonical Ltd
2
#
3
# This program is free software; you can redistribute it and/or modify
4
# it under the terms of the GNU General Public License as published by
5
# the Free Software Foundation; either version 2 of the License, or
6
# (at your option) any later version.
7
#
8
# This program is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
# GNU General Public License for more details.
12
#
13
# You should have received a copy of the GNU General Public License
14
# along with this program; if not, write to the Free Software
4183.7.1 by Sabin Iacob
update FSF mailing address
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
2201.1.1 by John Arbash Meinel
Fix bug #76299 by ignoring write errors during readonly hashcache write.
16
17
"""Test that WorkingTrees don't fail if they are in a readonly dir."""
18
19
import os
20
import sys
21
import time
22
23
from bzrlib import (
24
    hashcache,
25
    tests,
26
    )
4523.1.4 by Martin Pool
Rename remaining *_implementations tests
27
from bzrlib.tests.per_workingtree import TestCaseWithWorkingTree
2201.1.1 by John Arbash Meinel
Fix bug #76299 by ignoring write errors during readonly hashcache write.
28
6113.1.1 by Jelmer Vernooij
Skip some tests against foreign formats.
29
from bzrlib.workingtree import InventoryWorkingTree
30
2201.1.1 by John Arbash Meinel
Fix bug #76299 by ignoring write errors during readonly hashcache write.
31
32
class TestReadonly(TestCaseWithWorkingTree):
33
34
    def setUp(self):
35
        if not self.platform_supports_readonly_dirs():
36
            raise tests.TestSkipped('platform does not support readonly'
37
                                    ' directories.')
38
        super(TestReadonly, self).setUp()
39
40
    def platform_supports_readonly_dirs(self):
41
        if sys.platform in ('win32', 'cygwin'):
42
            # Setting a directory to readonly in windows or cygwin doesn't seem
43
            # to have any effect. You can still create files in subdirectories.
44
            # TODO: jam 20061219 We could cheat and set just the hashcache file
45
            #       to readonly, which would make it fail when we try to delete
46
            #       or rewrite it. But that is a lot of cheating...
47
            return False
48
        return True
49
50
    def _set_all_dirs(self, basedir, readonly=True):
51
        """Recursively set all directories beneath this one."""
52
        if readonly:
53
            mode = 0555
54
        else:
55
            mode = 0755
56
57
        for root, dirs, files in os.walk(basedir, topdown=False):
58
            for d in dirs:
59
                path = os.path.join(root, d)
60
                os.chmod(path, mode)
61
62
    def set_dirs_readonly(self, basedir):
63
        """Set all directories readonly, and have it cleanup on test exit."""
4985.2.1 by Vincent Ladeuil
Deploy addAttrCleanup on the whole test suite.
64
        self.addCleanup(self._set_all_dirs, basedir, readonly=False)
2201.1.1 by John Arbash Meinel
Fix bug #76299 by ignoring write errors during readonly hashcache write.
65
        self._set_all_dirs(basedir, readonly=True)
66
67
    def create_basic_tree(self):
68
        tree = self.make_branch_and_tree('tree')
69
        self.build_tree(['tree/a', 'tree/b/', 'tree/b/c'])
70
        tree.add(['a', 'b', 'b/c'])
71
        tree.commit('creating an initial tree.')
72
        return tree
73
74
    def _custom_cutoff_time(self):
75
        """We need to fake the cutoff time."""
76
        return time.time() + 10
77
78
    def test_readonly_unclean(self):
79
        """Even if the tree is unclean, we should still handle readonly dirs."""
80
        # First create a tree
81
        tree = self.create_basic_tree()
6113.1.1 by Jelmer Vernooij
Skip some tests against foreign formats.
82
        if not isinstance(tree, InventoryWorkingTree):
83
            raise tests.TestNotApplicable("requires inventory working tree")
2201.1.1 by John Arbash Meinel
Fix bug #76299 by ignoring write errors during readonly hashcache write.
84
85
        # XXX: *Ugly* *ugly* hack, we need the hashcache to think it is out of
86
        # date, but we don't want to actually wait 3 seconds doing nothing.
2201.1.2 by John Arbash Meinel
Update from Aaron
87
        # WorkingTree formats that don't have a _hashcache should update this
88
        # test so that they pass. For now, we just assert that we have the
89
        # right type of objects available.
90
        the_hashcache = getattr(tree, '_hashcache', None)
2255.10.1 by John Arbash Meinel
Update WorkingTree4 so that it doesn't use a HashCache,
91
        if the_hashcache is not None:
92
            self.assertIsInstance(the_hashcache, hashcache.HashCache)
93
            the_hashcache._cutoff_time = self._custom_cutoff_time
94
            hack_dirstate = False
95
        else:
96
            # DirState trees don't have a HashCache, but they do have the same
97
            # function as part of the DirState. However, until the tree is
98
            # locked, we don't have a DirState to modify
99
            hack_dirstate = True
2201.1.1 by John Arbash Meinel
Fix bug #76299 by ignoring write errors during readonly hashcache write.
100
101
        # Make it a little dirty
102
        self.build_tree_contents([('tree/a', 'new contents of a\n')])
103
104
        # Make it readonly, and do some operations and then unlock
105
        self.set_dirs_readonly('tree')
106
107
        tree.lock_read()
108
        try:
2255.10.1 by John Arbash Meinel
Update WorkingTree4 so that it doesn't use a HashCache,
109
            if hack_dirstate:
110
                tree._dirstate._sha_cutoff_time = self._custom_cutoff_time
2201.1.1 by John Arbash Meinel
Fix bug #76299 by ignoring write errors during readonly hashcache write.
111
            # Make sure we check all the files
5837.2.2 by Jelmer Vernooij
Fix more uses of Tree.__iter__
112
            for file_id in tree.all_file_ids():
2201.1.1 by John Arbash Meinel
Fix bug #76299 by ignoring write errors during readonly hashcache write.
113
                size = tree.get_file_size(file_id)
114
                sha1 = tree.get_file_sha1(file_id)
115
        finally:
116
            tree.unlock()