summaryrefslogtreecommitdiff
path: root/bzrlib/tests/per_workingtree/test_readonly.py
diff options
context:
space:
mode:
Diffstat (limited to 'bzrlib/tests/per_workingtree/test_readonly.py')
-rw-r--r--bzrlib/tests/per_workingtree/test_readonly.py116
1 files changed, 116 insertions, 0 deletions
diff --git a/bzrlib/tests/per_workingtree/test_readonly.py b/bzrlib/tests/per_workingtree/test_readonly.py
new file mode 100644
index 0000000..f1a3614
--- /dev/null
+++ b/bzrlib/tests/per_workingtree/test_readonly.py
@@ -0,0 +1,116 @@
+# Copyright (C) 2006 Canonical Ltd
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+"""Test that WorkingTrees don't fail if they are in a readonly dir."""
+
+import os
+import sys
+import time
+
+from bzrlib import (
+ hashcache,
+ tests,
+ )
+from bzrlib.tests.per_workingtree import TestCaseWithWorkingTree
+
+from bzrlib.workingtree import InventoryWorkingTree
+
+
+class TestReadonly(TestCaseWithWorkingTree):
+
+ def setUp(self):
+ if not self.platform_supports_readonly_dirs():
+ raise tests.TestSkipped('platform does not support readonly'
+ ' directories.')
+ super(TestReadonly, self).setUp()
+
+ def platform_supports_readonly_dirs(self):
+ if sys.platform in ('win32', 'cygwin'):
+ # Setting a directory to readonly in windows or cygwin doesn't seem
+ # to have any effect. You can still create files in subdirectories.
+ # TODO: jam 20061219 We could cheat and set just the hashcache file
+ # to readonly, which would make it fail when we try to delete
+ # or rewrite it. But that is a lot of cheating...
+ return False
+ return True
+
+ def _set_all_dirs(self, basedir, readonly=True):
+ """Recursively set all directories beneath this one."""
+ if readonly:
+ mode = 0555
+ else:
+ mode = 0755
+
+ for root, dirs, files in os.walk(basedir, topdown=False):
+ for d in dirs:
+ path = os.path.join(root, d)
+ os.chmod(path, mode)
+
+ def set_dirs_readonly(self, basedir):
+ """Set all directories readonly, and have it cleanup on test exit."""
+ self.addCleanup(self._set_all_dirs, basedir, readonly=False)
+ self._set_all_dirs(basedir, readonly=True)
+
+ def create_basic_tree(self):
+ tree = self.make_branch_and_tree('tree')
+ self.build_tree(['tree/a', 'tree/b/', 'tree/b/c'])
+ tree.add(['a', 'b', 'b/c'])
+ tree.commit('creating an initial tree.')
+ return tree
+
+ def _custom_cutoff_time(self):
+ """We need to fake the cutoff time."""
+ return time.time() + 10
+
+ def test_readonly_unclean(self):
+ """Even if the tree is unclean, we should still handle readonly dirs."""
+ # First create a tree
+ tree = self.create_basic_tree()
+ if not isinstance(tree, InventoryWorkingTree):
+ raise tests.TestNotApplicable("requires inventory working tree")
+
+ # XXX: *Ugly* *ugly* hack, we need the hashcache to think it is out of
+ # date, but we don't want to actually wait 3 seconds doing nothing.
+ # WorkingTree formats that don't have a _hashcache should update this
+ # test so that they pass. For now, we just assert that we have the
+ # right type of objects available.
+ the_hashcache = getattr(tree, '_hashcache', None)
+ if the_hashcache is not None:
+ self.assertIsInstance(the_hashcache, hashcache.HashCache)
+ the_hashcache._cutoff_time = self._custom_cutoff_time
+ hack_dirstate = False
+ else:
+ # DirState trees don't have a HashCache, but they do have the same
+ # function as part of the DirState. However, until the tree is
+ # locked, we don't have a DirState to modify
+ hack_dirstate = True
+
+ # Make it a little dirty
+ self.build_tree_contents([('tree/a', 'new contents of a\n')])
+
+ # Make it readonly, and do some operations and then unlock
+ self.set_dirs_readonly('tree')
+
+ tree.lock_read()
+ try:
+ if hack_dirstate:
+ tree._dirstate._sha_cutoff_time = self._custom_cutoff_time
+ # Make sure we check all the files
+ for file_id in tree.all_file_ids():
+ size = tree.get_file_size(file_id)
+ sha1 = tree.get_file_sha1(file_id)
+ finally:
+ tree.unlock()