~bzr-pqm/bzr/bzr.dev

5557.1.15 by John Arbash Meinel
Merge bzr.dev 5597 to resolve NEWS, aka bzr-2.3.txt
1
# Copyright (C) 2009, 2010, 2011 Canonical Ltd
4020.1.1 by Jelmer Vernooij
Import clean-tree from bzrtools.
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
4020.1.1 by Jelmer Vernooij
Import clean-tree from bzrtools.
16
17
5376.1.3 by Parth Malwankar
clean-tree now specifically handes EACCES
18
import errno
4020.1.1 by Jelmer Vernooij
Import clean-tree from bzrtools.
19
import os
5376.1.1 by Parth Malwankar
clean-tree issues warning if it cant delete a file
20
import shutil
5376.1.8 by Parth Malwankar
onerror and test updated to handle EACCES specifically
21
import sys
5376.1.1 by Parth Malwankar
clean-tree issues warning if it cant delete a file
22
import types
4020.1.2 by Jelmer Vernooij
Import blackbox test for clean-tree, run regular tests.
23
5376.1.1 by Parth Malwankar
clean-tree issues warning if it cant delete a file
24
from bzrlib import tests, ui
4020.1.2 by Jelmer Vernooij
Import blackbox test for clean-tree, run regular tests.
25
from bzrlib.bzrdir import (
26
    BzrDir,
27
    )
28
from bzrlib.clean_tree import (
29
    clean_tree,
30
    iter_deletables,
31
    )
32
from bzrlib.osutils import (
33
    has_symlinks,
34
    )
35
from bzrlib.tests import (
36
    TestCaseInTempDir,
37
    )
4020.1.1 by Jelmer Vernooij
Import clean-tree from bzrtools.
38
4020.1.5 by Aaron Bentley
Fix some formatting issues.
39
4020.1.1 by Jelmer Vernooij
Import clean-tree from bzrtools.
40
class TestCleanTree(TestCaseInTempDir):
4020.1.2 by Jelmer Vernooij
Import blackbox test for clean-tree, run regular tests.
41
4020.1.1 by Jelmer Vernooij
Import clean-tree from bzrtools.
42
    def test_symlinks(self):
43
        if has_symlinks() is False:
44
            return
45
        os.mkdir('branch')
46
        BzrDir.create_standalone_workingtree('branch')
47
        os.symlink(os.path.realpath('no-die-please'), 'branch/die-please')
48
        os.mkdir('no-die-please')
5784.1.3 by Martin Pool
Switch away from using failUnlessExists and failIfExists
49
        self.assertPathExists('branch/die-please')
4020.1.1 by Jelmer Vernooij
Import clean-tree from bzrtools.
50
        os.mkdir('no-die-please/child')
51
52
        clean_tree('branch', unknown=True, no_prompt=True)
5784.1.3 by Martin Pool
Switch away from using failUnlessExists and failIfExists
53
        self.assertPathExists('no-die-please')
54
        self.assertPathExists('no-die-please/child')
4020.1.1 by Jelmer Vernooij
Import clean-tree from bzrtools.
55
56
    def test_iter_deletable(self):
57
        """Files are selected for deletion appropriately"""
58
        os.mkdir('branch')
59
        tree = BzrDir.create_standalone_workingtree('branch')
4020.1.4 by Aaron Bentley
Assign copyright, update tests.
60
        transport = tree.bzrdir.root_transport
61
        transport.put_bytes('.bzrignore', '*~\n*.pyc\n.bzrignore\n')
62
        transport.put_bytes('file.BASE', 'contents')
4020.1.1 by Jelmer Vernooij
Import clean-tree from bzrtools.
63
        tree.lock_write()
64
        try:
65
            self.assertEqual(len(list(iter_deletables(tree, unknown=True))), 1)
4020.1.4 by Aaron Bentley
Assign copyright, update tests.
66
            transport.put_bytes('file', 'contents')
67
            transport.put_bytes('file~', 'contents')
68
            transport.put_bytes('file.pyc', 'contents')
4020.1.1 by Jelmer Vernooij
Import clean-tree from bzrtools.
69
            dels = sorted([r for a,r in iter_deletables(tree, unknown=True)])
4020.1.7 by Aaron Bentley
Convert asserts to TestCase helper methods
70
            self.assertEqual(['file', 'file.BASE'], dels)
4020.1.1 by Jelmer Vernooij
Import clean-tree from bzrtools.
71
72
            dels = [r for a,r in iter_deletables(tree, detritus=True)]
4020.1.7 by Aaron Bentley
Convert asserts to TestCase helper methods
73
            self.assertEqual(sorted(['file~', 'file.BASE']), dels)
4020.1.1 by Jelmer Vernooij
Import clean-tree from bzrtools.
74
75
            dels = [r for a,r in iter_deletables(tree, ignored=True)]
4020.1.7 by Aaron Bentley
Convert asserts to TestCase helper methods
76
            self.assertEqual(sorted(['file~', 'file.pyc', '.bzrignore']),
77
                             dels)
4020.1.1 by Jelmer Vernooij
Import clean-tree from bzrtools.
78
79
            dels = [r for a,r in iter_deletables(tree, unknown=False)]
4020.1.7 by Aaron Bentley
Convert asserts to TestCase helper methods
80
            self.assertEqual([], dels)
4020.1.1 by Jelmer Vernooij
Import clean-tree from bzrtools.
81
        finally:
82
            tree.unlock()
5376.1.1 by Parth Malwankar
clean-tree issues warning if it cant delete a file
83
84
    def test_delete_items_warnings(self):
5376.1.8 by Parth Malwankar
onerror and test updated to handle EACCES specifically
85
        """Ensure delete_items issues warnings on EACCES. (bug #430785)
5376.1.1 by Parth Malwankar
clean-tree issues warning if it cant delete a file
86
        """
87
        def _dummy_unlink(path):
5376.1.6 by Parth Malwankar
closed review comments
88
            """unlink() files other than files named '0foo'.
89
            """
5376.1.1 by Parth Malwankar
clean-tree issues warning if it cant delete a file
90
            if path.endswith('0foo'):
5376.1.6 by Parth Malwankar
closed review comments
91
                # Simulate 'permission denied' error.
92
                # This should show up as a warning for the
93
                # user.
5376.1.3 by Parth Malwankar
clean-tree now specifically handes EACCES
94
                e = OSError()
95
                e.errno = errno.EACCES
96
                raise e
5376.1.1 by Parth Malwankar
clean-tree issues warning if it cant delete a file
97
98
        def _dummy_rmtree(path, ignore_errors=False, onerror=None):
5376.1.8 by Parth Malwankar
onerror and test updated to handle EACCES specifically
99
            """Call user supplied error handler onerror.
5376.1.6 by Parth Malwankar
closed review comments
100
            """
101
            self.assertTrue(isinstance(onerror, types.FunctionType))
5376.1.8 by Parth Malwankar
onerror and test updated to handle EACCES specifically
102
            # Indicate failure in removing 'path' if path is subdir0
5376.1.6 by Parth Malwankar
closed review comments
103
            # We later check to ensure that this is indicated
5376.1.9 by Parth Malwankar
improved comments
104
            # to the user as a warning. We raise OSError to construct
105
            # proper excinfo that needs to be passed to onerror
5376.1.8 by Parth Malwankar
onerror and test updated to handle EACCES specifically
106
            try:
107
                raise OSError
108
            except OSError, e:
109
                e.errno = errno.EACCES
110
                excinfo = sys.exc_info()
111
                function = os.remove
112
                if 'subdir0' not in path:
113
                    # onerror should show warning only for os.remove
114
                    # error. For any other failures the error should
115
                    # be shown to the user.
116
                    function = os.listdir
117
                onerror(function=function,
118
                    path=path, excinfo=excinfo)
5376.1.1 by Parth Malwankar
clean-tree issues warning if it cant delete a file
119
120
        self.overrideAttr(os, 'unlink', _dummy_unlink)
121
        self.overrideAttr(shutil, 'rmtree', _dummy_rmtree)
122
        stdout = tests.StringIOWrapper()
123
        stderr = tests.StringIOWrapper()
124
        ui.ui_factory = tests.TestUIFactory(stdout=stdout, stderr=stderr)
5376.1.9 by Parth Malwankar
improved comments
125
5376.1.6 by Parth Malwankar
closed review comments
126
        BzrDir.create_standalone_workingtree('.')
5376.1.8 by Parth Malwankar
onerror and test updated to handle EACCES specifically
127
        self.build_tree(['0foo', '1bar', '2baz', 'subdir0/'])
5376.1.1 by Parth Malwankar
clean-tree issues warning if it cant delete a file
128
        clean_tree('.', unknown=True, no_prompt=True)
129
        self.assertContainsRe(stderr.getvalue(),
5376.1.6 by Parth Malwankar
closed review comments
130
            'bzr: warning: unable to remove.*0foo')
5376.1.1 by Parth Malwankar
clean-tree issues warning if it cant delete a file
131
        self.assertContainsRe(stderr.getvalue(),
5376.1.8 by Parth Malwankar
onerror and test updated to handle EACCES specifically
132
            'bzr: warning: unable to remove.*subdir0')
133
134
        # Ensure that error other than EACCES during os.remove are
135
        # not turned into warnings.
136
        self.build_tree(['subdir1/'])
137
        self.assertRaises(OSError, clean_tree, '.',
138
            unknown=True, no_prompt=True)
139