1
# Copyright (C) 2009, 2010, 2011 Canonical Ltd
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.
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.
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
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24
from bzrlib import tests, ui
25
from bzrlib.bzrdir import (
28
from bzrlib.clean_tree import (
32
from bzrlib.osutils import (
35
from bzrlib.tests import (
40
class TestCleanTree(TestCaseInTempDir):
42
def test_symlinks(self):
43
if has_symlinks() is False:
46
BzrDir.create_standalone_workingtree('branch')
47
os.symlink(os.path.realpath('no-die-please'), 'branch/die-please')
48
os.mkdir('no-die-please')
49
self.assertPathExists('branch/die-please')
50
os.mkdir('no-die-please/child')
52
clean_tree('branch', unknown=True, no_prompt=True)
53
self.assertPathExists('no-die-please')
54
self.assertPathExists('no-die-please/child')
56
def test_iter_deletable(self):
57
"""Files are selected for deletion appropriately"""
59
tree = BzrDir.create_standalone_workingtree('branch')
60
transport = tree.bzrdir.root_transport
61
transport.put_bytes('.bzrignore', '*~\n*.pyc\n.bzrignore\n')
62
transport.put_bytes('file.BASE', 'contents')
65
self.assertEqual(len(list(iter_deletables(tree, unknown=True))), 1)
66
transport.put_bytes('file', 'contents')
67
transport.put_bytes('file~', 'contents')
68
transport.put_bytes('file.pyc', 'contents')
69
dels = sorted([r for a,r in iter_deletables(tree, unknown=True)])
70
self.assertEqual(['file', 'file.BASE'], dels)
72
dels = [r for a,r in iter_deletables(tree, detritus=True)]
73
self.assertEqual(sorted(['file~', 'file.BASE']), dels)
75
dels = [r for a,r in iter_deletables(tree, ignored=True)]
76
self.assertEqual(sorted(['file~', 'file.pyc', '.bzrignore']),
79
dels = [r for a,r in iter_deletables(tree, unknown=False)]
80
self.assertEqual([], dels)
84
def test_delete_items_warnings(self):
85
"""Ensure delete_items issues warnings on EACCES. (bug #430785)
87
def _dummy_unlink(path):
88
"""unlink() files other than files named '0foo'.
90
if path.endswith('0foo'):
91
# Simulate 'permission denied' error.
92
# This should show up as a warning for the
95
e.errno = errno.EACCES
98
def _dummy_rmtree(path, ignore_errors=False, onerror=None):
99
"""Call user supplied error handler onerror.
101
# Indicate failure in removing 'path' if path is subdir0
102
# We later check to ensure that this is indicated
103
# to the user as a warning. We raise OSError to construct
104
# proper excinfo that needs to be passed to onerror
108
e.errno = errno.EACCES
109
excinfo = sys.exc_info()
111
if 'subdir0' not in path:
112
# onerror should show warning only for os.remove
113
# error. For any other failures the error should
114
# be shown to the user.
115
function = os.listdir
116
onerror(function=function,
117
path=path, excinfo=excinfo)
119
self.overrideAttr(os, 'unlink', _dummy_unlink)
120
self.overrideAttr(shutil, 'rmtree', _dummy_rmtree)
121
stdout = tests.StringIOWrapper()
122
stderr = tests.StringIOWrapper()
123
ui.ui_factory = tests.TestUIFactory(stdout=stdout, stderr=stderr)
125
BzrDir.create_standalone_workingtree('.')
126
self.build_tree(['0foo', '1bar', '2baz', 'subdir0/'])
127
clean_tree('.', unknown=True, no_prompt=True)
128
self.assertContainsRe(stderr.getvalue(),
129
'bzr: warning: unable to remove.*0foo')
130
self.assertContainsRe(stderr.getvalue(),
131
'bzr: warning: unable to remove.*subdir0')
133
# Ensure that error other than EACCES during os.remove are
134
# not turned into warnings.
135
self.build_tree(['subdir1/'])
136
self.assertRaises(OSError, clean_tree, '.',
137
unknown=True, no_prompt=True)