~bzr-pqm/bzr/bzr.dev

1852.16.5 by John Arbash Meinel
[merge] bzr.dev 2255, resolve conflicts, update copyrights
1
# Copyright (C) 2006, 2007 Canonical Ltd
1852.15.9 by Robert Collins
Add missing test script.
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
1852.15.9 by Robert Collins
Add missing test script.
16
17
"""Tests for the extra cases that WorkingTree.walkdirs can encounter."""
18
19
import os
20
1852.15.12 by Robert Collins
WorkingTree.walkdirs handling of changing file kinds, and multi-directory with missing and unknown ordering bugfix.
21
from bzrlib import transform
5967.12.1 by Martin Pool
Move all test features into bzrlib.tests.features
22
from bzrlib.tests.features import SymlinkFeature
4523.1.4 by Martin Pool
Rename remaining *_implementations tests
23
from bzrlib.tests.per_workingtree import TestCaseWithWorkingTree
1852.15.9 by Robert Collins
Add missing test script.
24
25
# tests to write:
26
# type mismatches - file to link, dir, dir to file, link, link to file, dir
27
2457.2.5 by Marius Kruger
move DirBlock out of TestWalkdirs as per review comment
28
class DirBlock:
2457.2.6 by Marius Kruger
add DirBlock comment
29
    """Object representation of the tuples returned by dirstate."""
2457.2.5 by Marius Kruger
move DirBlock out of TestWalkdirs as per review comment
30
31
    def __init__(self, tree, file_path, file_name=None, id=None,
32
                 inventory_kind=None, stat=None, disk_kind='unknown'):
33
        self.file_path = file_path
34
        self.abspath = tree.abspath(file_path)
35
        self.relpath = tree.relpath(file_path)
3376.2.11 by Martin Pool
Compare to None using is/is not not ==
36
        if file_name is None:
2457.2.5 by Marius Kruger
move DirBlock out of TestWalkdirs as per review comment
37
           file_name = os.path.split(file_path)[-1]
38
           if len(file_name) == 0:
39
               file_name = os.path.split(file_path)[-2]
40
        self.file_name = file_name
41
        self.id = id
42
        self.inventory_kind = inventory_kind
43
        self.stat = stat
44
        self.disk_kind = disk_kind
45
46
    def as_tuple(self):
47
         return (self.relpath, self.file_name, self.disk_kind,
48
                 self.stat, self.id, self.inventory_kind)
49
50
    def as_dir_tuple(self):
51
         return (self.relpath, self.id)
52
53
    def __str__(self):
54
        return """
2457.2.1 by Marius Kruger
* Fix workingtree.walkdirs to support getting a prefix which specifies an empty directory.
55
file_path      = %r
56
abspath        = %r
57
relpath        = %r
58
file_name      = %r
59
id             = %r
60
inventory_kind = %r
61
stat           = %r
62
disk_kind      = %r""" % (self.file_path, self.abspath, self.relpath,
2457.2.5 by Marius Kruger
move DirBlock out of TestWalkdirs as per review comment
63
        self.file_name, self.id, self.inventory_kind, self.stat,
64
        self.disk_kind)
65
66
67
class TestWalkdirs(TestCaseWithWorkingTree):
68
69
    added='added'
70
    missing='missing'
71
    unknown='unknown'
2457.2.1 by Marius Kruger
* Fix workingtree.walkdirs to support getting a prefix which specifies an empty directory.
72
73
    def get_tree(self, file_status, prefix=None):
1852.15.9 by Robert Collins
Add missing test script.
74
        tree = self.make_branch_and_tree('.')
2457.2.1 by Marius Kruger
* Fix workingtree.walkdirs to support getting a prefix which specifies an empty directory.
75
        dirblocks = []
76
        paths = [
77
            file_status + ' file',
78
            file_status + ' dir/',
79
            file_status + ' dir/a file',
80
            file_status + ' empty dir/',
81
            ]
82
        self.build_tree(paths)
83
84
        def add_dirblock(path, kind):
2457.2.5 by Marius Kruger
move DirBlock out of TestWalkdirs as per review comment
85
            dirblock = DirBlock(tree, path)
2457.2.1 by Marius Kruger
* Fix workingtree.walkdirs to support getting a prefix which specifies an empty directory.
86
            if file_status != self.unknown:
87
                dirblock.id = 'a ' + str(path).replace('/','-') + '-id'
88
                dirblock.inventory_kind = kind
89
            if file_status != self.missing:
90
                dirblock.disk_kind = kind
91
                dirblock.stat = os.lstat(dirblock.relpath)
92
            dirblocks.append(dirblock)
93
94
        add_dirblock(paths[0], 'file')
95
        add_dirblock(paths[1], 'directory')
96
        add_dirblock(paths[2], 'file')
97
        add_dirblock(paths[3], 'directory')
98
99
        if file_status != self.unknown:
100
            tree.add(paths, [db.id for db in dirblocks])
101
102
        if file_status == self.missing:
103
            # now make the files be missing
104
            tree.bzrdir.root_transport.delete(dirblocks[0].relpath)
105
            tree.bzrdir.root_transport.delete_tree(dirblocks[1].relpath)
106
            tree.bzrdir.root_transport.delete_tree(dirblocks[3].relpath)
107
1852.15.9 by Robert Collins
Add missing test script.
108
        expected_dirblocks = [
2255.2.47 by Robert Collins
Adjust walkdirs tests to talk a lock around walk_dirs.
109
            (('', tree.path2id('')),
2457.2.1 by Marius Kruger
* Fix workingtree.walkdirs to support getting a prefix which specifies an empty directory.
110
             [dirblocks[1].as_tuple(), dirblocks[3].as_tuple(),
111
              dirblocks[0].as_tuple()]
112
            ),
113
            (dirblocks[1].as_dir_tuple(),
114
             [dirblocks[2].as_tuple()]
115
            ),
116
            (dirblocks[3].as_dir_tuple(),
117
             []
1852.15.10 by Robert Collins
Tweak the Tree.walkdirs interface more to be more useful.
118
            ),
119
            ]
2457.2.1 by Marius Kruger
* Fix workingtree.walkdirs to support getting a prefix which specifies an empty directory.
120
        if prefix:
121
            expected_dirblocks = [e for e in expected_dirblocks
122
                if len(e) > 0 and len(e[0]) > 0 and e[0][0] == prefix]
1852.15.10 by Robert Collins
Tweak the Tree.walkdirs interface more to be more useful.
123
        return tree, expected_dirblocks
2457.2.1 by Marius Kruger
* Fix workingtree.walkdirs to support getting a prefix which specifies an empty directory.
124
2457.2.7 by Marius Kruger
extract method as per review request
125
    def _test_walkdir(self, file_status, prefix=""):
126
        result = []
127
        tree, expected_dirblocks = self.get_tree(file_status, prefix)
128
        tree.lock_read()
129
        for dirinfo, dirblock in tree.walkdirs(prefix):
130
            result.append((dirinfo, list(dirblock)))
131
        tree.unlock()
132
133
        # check each return value for debugging ease.
134
        for pos, item in enumerate(expected_dirblocks):
135
            result_pos = []
136
            if len(result) > pos:
137
                result_pos = result[pos]
138
            self.assertEqual(item, result_pos)
139
        self.assertEqual(expected_dirblocks, result)
140
1852.15.10 by Robert Collins
Tweak the Tree.walkdirs interface more to be more useful.
141
    def test_walkdir_unknowns(self):
142
        """unknown files and directories should be reported by walkdirs."""
2457.2.7 by Marius Kruger
extract method as per review request
143
        self._test_walkdir(self.unknown)
1852.15.10 by Robert Collins
Tweak the Tree.walkdirs interface more to be more useful.
144
145
    def test_walkdir_from_unknown_dir(self):
146
        """Doing a walkdir when the requested prefix is unknown but on disk."""
2457.2.7 by Marius Kruger
extract method as per review request
147
        self._test_walkdir(self.unknown, 'unknown dir')
148
1852.15.11 by Robert Collins
Tree.walkdirs handles missing contents in workingtrees.
149
    def test_walkdir_missings(self):
150
        """missing files and directories should be reported by walkdirs."""
2457.2.7 by Marius Kruger
extract method as per review request
151
        self._test_walkdir(self.missing)
2457.2.1 by Marius Kruger
* Fix workingtree.walkdirs to support getting a prefix which specifies an empty directory.
152
153
    def test_walkdir_from_dir(self):
154
        """Doing a walkdir when the requested prefix is known and on disk."""
2457.2.7 by Marius Kruger
extract method as per review request
155
        self._test_walkdir(self.added, 'added dir')
2457.2.1 by Marius Kruger
* Fix workingtree.walkdirs to support getting a prefix which specifies an empty directory.
156
157
    def test_walkdir_from_empty_dir(self):
158
        """Doing a walkdir when the requested prefix is empty dir."""
2457.2.7 by Marius Kruger
extract method as per review request
159
        self._test_walkdir(self.added, 'added empty dir')
1852.15.11 by Robert Collins
Tree.walkdirs handles missing contents in workingtrees.
160
161
    def test_walkdir_from_missing_dir(self):
162
        """Doing a walkdir when the requested prefix is missing but on disk."""
2457.2.7 by Marius Kruger
extract method as per review request
163
        self._test_walkdir(self.missing, 'missing dir')
1852.15.12 by Robert Collins
WorkingTree.walkdirs handling of changing file kinds, and multi-directory with missing and unknown ordering bugfix.
164
165
    def test_walkdirs_type_changes(self):
166
        """Walkdir shows the actual kinds on disk and the recorded kinds."""
2949.5.1 by Alexander Belchenko
selftest: use SymlinkFeature instead of TestSkipped where appropriate
167
        self.requireFeature(SymlinkFeature)
1852.15.12 by Robert Collins
WorkingTree.walkdirs handling of changing file kinds, and multi-directory with missing and unknown ordering bugfix.
168
        tree = self.make_branch_and_tree('.')
169
        paths = ['file1', 'file2', 'dir1/', 'dir2/']
170
        ids = ['file1', 'file2', 'dir1', 'dir2']
171
        self.build_tree(paths)
172
        tree.add(paths, ids)
173
        tt = transform.TreeTransform(tree)
174
        root_transaction_id = tt.trans_id_tree_path('')
175
        tt.new_symlink('link1',
176
            root_transaction_id, 'link-target', 'link1')
177
        tt.new_symlink('link2',
178
            root_transaction_id, 'link-target', 'link2')
179
        tt.apply()
180
        tree.bzrdir.root_transport.delete_tree('dir1')
181
        tree.bzrdir.root_transport.delete_tree('dir2')
182
        tree.bzrdir.root_transport.delete('file1')
183
        tree.bzrdir.root_transport.delete('file2')
184
        tree.bzrdir.root_transport.delete('link1')
185
        tree.bzrdir.root_transport.delete('link2')
186
        changed_paths = ['dir1', 'file1/', 'link1', 'link2/']
187
        self.build_tree(changed_paths)
188
        os.symlink('target', 'dir2')
189
        os.symlink('target', 'file2')
190
        dir1_stat = os.lstat('dir1')
191
        dir2_stat = os.lstat('dir2')
192
        file1_stat = os.lstat('file1')
193
        file2_stat = os.lstat('file2')
194
        link1_stat = os.lstat('link1')
195
        link2_stat = os.lstat('link2')
196
        expected_dirblocks = [
2255.2.47 by Robert Collins
Adjust walkdirs tests to talk a lock around walk_dirs.
197
             (('', tree.path2id('')),
1852.15.12 by Robert Collins
WorkingTree.walkdirs handling of changing file kinds, and multi-directory with missing and unknown ordering bugfix.
198
              [('dir1', 'dir1', 'file', dir1_stat, 'dir1', 'directory'),
199
               ('dir2', 'dir2', 'symlink', dir2_stat, 'dir2', 'directory'),
200
               ('file1', 'file1', 'directory', file1_stat, 'file1', 'file'),
201
               ('file2', 'file2', 'symlink', file2_stat, 'file2', 'file'),
202
               ('link1', 'link1', 'file', link1_stat, 'link1', 'symlink'),
203
               ('link2', 'link2', 'directory', link2_stat, 'link2', 'symlink'),
204
              ]
205
             ),
206
             (('dir1', 'dir1'),
207
              [
208
              ]
209
             ),
210
             (('dir2', 'dir2'),
211
              [
212
              ]
213
             ),
214
             (('file1', None),
215
              [
216
              ]
217
             ),
218
             (('link2', None),
219
              [
220
              ]
221
             ),
222
            ]
2255.2.47 by Robert Collins
Adjust walkdirs tests to talk a lock around walk_dirs.
223
        tree.lock_read()
1852.15.12 by Robert Collins
WorkingTree.walkdirs handling of changing file kinds, and multi-directory with missing and unknown ordering bugfix.
224
        result = list(tree.walkdirs())
2255.2.47 by Robert Collins
Adjust walkdirs tests to talk a lock around walk_dirs.
225
        tree.unlock()
1852.15.12 by Robert Collins
WorkingTree.walkdirs handling of changing file kinds, and multi-directory with missing and unknown ordering bugfix.
226
        # check each return value for debugging ease.
227
        for pos, item in enumerate(expected_dirblocks):
228
            self.assertEqual(item, result[pos])
229
        self.assertEqual(len(expected_dirblocks), len(result))
2408.1.4 by Alexander Belchenko
workingtree_implementations: make usage of symlinks optional
230
231
    def test_walkdirs_type_changes_wo_symlinks(self):
232
        # similar to test_walkdirs_type_changes
233
        # but don't use symlinks for safe testing on win32
234
        tree = self.make_branch_and_tree('.')
235
        paths = ['file1', 'dir1/']
236
        ids = ['file1', 'dir1']
237
        self.build_tree(paths)
238
        tree.add(paths, ids)
239
        tree.bzrdir.root_transport.delete_tree('dir1')
240
        tree.bzrdir.root_transport.delete('file1')
241
        changed_paths = ['dir1', 'file1/']
242
        self.build_tree(changed_paths)
243
        dir1_stat = os.lstat('dir1')
244
        file1_stat = os.lstat('file1')
245
        expected_dirblocks = [
246
             (('', tree.path2id('')),
247
              [('dir1', 'dir1', 'file', dir1_stat, 'dir1', 'directory'),
248
               ('file1', 'file1', 'directory', file1_stat, 'file1', 'file'),
249
              ]
250
             ),
251
             (('dir1', 'dir1'),
252
              [
253
              ]
254
             ),
255
             (('file1', None),
256
              [
257
              ]
258
             ),
259
            ]
260
        tree.lock_read()
261
        result = list(tree.walkdirs())
262
        tree.unlock()
263
        # check each return value for debugging ease.
264
        for pos, item in enumerate(expected_dirblocks):
265
            self.assertEqual(item, result[pos])
266
        self.assertEqual(len(expected_dirblocks), len(result))