~bzr-pqm/bzr/bzr.dev

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