~bzr/ubuntu/lucid/bzr/beta-ppa

« back to all changes in this revision

Viewing changes to bzrlib/tests/per_workingtree/test_walkdirs.py

  • Committer: Martin Pool
  • Date: 2010-07-02 07:29:40 UTC
  • mfrom: (129.1.7 packaging-karmic)
  • Revision ID: mbp@sourcefrog.net-20100702072940-hpzq5elg8wjve8rh
* PPA rebuild.
* PPA rebuild for Karmic.
* PPA rebuild for Jaunty.
* PPA rebuild for Hardy.
* From postinst, actually remove the example bash completion scripts.
  (LP: #249452)
* New upstream release.
* New upstream release.
* New upstream release.
* Revert change to Build-depends: Dapper does not have python-central.
  Should be python-support..
* Target ppa..
* Target ppa..
* Target ppa..
* Target ppa..
* New upstream release.
* Switch to dpkg-source 3.0 (quilt) format.
* Bump standards version to 3.8.4.
* Remove embedded copy of python-configobj. Closes: #555336
* Remove embedded copy of python-elementtree. Closes: #555343
* Change section from 'Devel' to 'Vcs'..
* Change section from 'Devel' to 'Vcs'..
* Change section from 'Devel' to 'Vcs'..
* Change section from 'Devel' to 'Vcs'..
* Change section from 'Devel' to 'Vcs'..
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* debian/control: Fix obsolete-relation-form-in-source
  lintian warning. 
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* Split out docs into bzr-doc package.
* New upstream release.
* Added John Francesco Ferlito to Uploaders.
* Fix install path to quick-reference guide
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* Fix FTBFS due to path changes, again.
* Fix FTBFS due to doc paths changing
* New upstream release.
* Fix FTBFS due to path changes, again.
* Fix FTBFS due to doc paths changing
* New upstream release.
* Fix FTBFS due to path changes, again.
* Fix FTBFS due to doc paths changing
* New upstream release.
* Fix FTBFS due to path changes, again, again.
* Fix FTBFS due to path changes, again.
* Fix FTBFS due to path changes.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* Bump standards version to 3.8.3.
* Remove unused patch system.
* New upstream release.
* New upstream release.
* New upstream release.
* Fix copy and paste tab error in .install file
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
 + Fixes compatibility with Python 2.4. Closes: #537708
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream version.
* Bump standards version to 3.8.2.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* Add python-pyrex to build-deps to ensure C extensions are always build.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* Split documentation into bzr-doc package. ((LP: #385074)
* Multiple packaging changes to make us more linitan clean.
* New upstream release.
* Split documentation into bzr-doc package. ((LP: #385074)
* Multiple packaging changes to make us more linitan clean.
* New upstream release.
* Split documentation into bzr-doc package. ((LP: #385074)
* Multiple packaging changes to make us more linitan clean.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* Fix API compatibility version. (Closes: #526233)
* New upstream release.
  + Fixes default format for upgrade command. (Closes: #464688)
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* Add missing dependency on zlib development library. (Closes:
  #523595)
* Add zlib build-depends.
* Add zlib build-depends.
* Add zlib build-depends.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* Move to section vcs.
* Bump standards version to 3.8.1.
* New upstream release.
* Remove temporary patch for missing .c files from distribution
* New upstream release.
* Remove temporary patch for missing .c files from distribution
* New upstream release.
* Remove temporary patch for missing .c files from distribution
* Add temporary patch for missing .c files from distribution
* Add temporary patch for missing .c files from distribution
* Add temporary patch for missing .c files from distribution
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* Recommend ca-certificates. (Closes: #452024)
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* Update watch file. bazaar now uses launchpad to host its sources.
* Remove patch for inventory root revision copy, applied upstream.
* New upstream release.
* New upstream release.
* New upstream release
* Force removal of files installed in error to /etc/bash_completion.d/
  (LP: #249452)
* New upstream release.
* New upstream release
* New upstream release.
* Bump standards version.
* Include patch for inventory root revision copy, required for bzr-svn.
* New upstream release.
* Remove unused lintian overrides.
* Correct the package version not to be native.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* Final 1.5 release.
* New upstream release.
* New upstream release.
* New upstream release.
* Add myself as a co-maintainer.
* Add a Dm-Upload-Allowed: yes header.
* New upstream bugfix release.
* New upstream release.
* Final 1.3 release.
* New upstream release.
* First release candidate of the upcoming 1.3 release.
* Rebuild to fix the problem caused by a build with a broken python-central.
* New upstream release.
* Rebuild for dapper PPA.
* Apply Lamont's patches to fix build-dependencies on dapper.
  (See: https://bugs.launchpad.net/bzr/+bug/189915)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright (C) 2006, 2007 Canonical Ltd
 
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
 
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 
16
 
 
17
"""Tests for the extra cases that WorkingTree.walkdirs can encounter."""
 
18
 
 
19
import os
 
20
 
 
21
from bzrlib import transform
 
22
from bzrlib.tests import SymlinkFeature
 
23
from bzrlib.tests.per_workingtree import TestCaseWithWorkingTree
 
24
 
 
25
# tests to write:
 
26
# type mismatches - file to link, dir, dir to file, link, link to file, dir
 
27
 
 
28
class DirBlock:
 
29
    """Object representation of the tuples returned by dirstate."""
 
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)
 
36
        if file_name is None:
 
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 """
 
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,
 
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'
 
72
 
 
73
    def get_tree(self, file_status, prefix=None):
 
74
        tree = self.make_branch_and_tree('.')
 
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):
 
85
            dirblock = DirBlock(tree, path)
 
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
 
 
108
        expected_dirblocks = [
 
109
            (('', tree.path2id('')),
 
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
             []
 
118
            ),
 
119
            ]
 
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]
 
123
        return tree, expected_dirblocks
 
124
 
 
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
 
 
141
    def test_walkdir_unknowns(self):
 
142
        """unknown files and directories should be reported by walkdirs."""
 
143
        self._test_walkdir(self.unknown)
 
144
 
 
145
    def test_walkdir_from_unknown_dir(self):
 
146
        """Doing a walkdir when the requested prefix is unknown but on disk."""
 
147
        self._test_walkdir(self.unknown, 'unknown dir')
 
148
 
 
149
    def test_walkdir_missings(self):
 
150
        """missing files and directories should be reported by walkdirs."""
 
151
        self._test_walkdir(self.missing)
 
152
 
 
153
    def test_walkdir_from_dir(self):
 
154
        """Doing a walkdir when the requested prefix is known and on disk."""
 
155
        self._test_walkdir(self.added, 'added dir')
 
156
 
 
157
    def test_walkdir_from_empty_dir(self):
 
158
        """Doing a walkdir when the requested prefix is empty dir."""
 
159
        self._test_walkdir(self.added, 'added empty dir')
 
160
 
 
161
    def test_walkdir_from_missing_dir(self):
 
162
        """Doing a walkdir when the requested prefix is missing but on disk."""
 
163
        self._test_walkdir(self.missing, 'missing dir')
 
164
 
 
165
    def test_walkdirs_type_changes(self):
 
166
        """Walkdir shows the actual kinds on disk and the recorded kinds."""
 
167
        self.requireFeature(SymlinkFeature)
 
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 = [
 
197
             (('', tree.path2id('')),
 
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
            ]
 
223
        tree.lock_read()
 
224
        result = list(tree.walkdirs())
 
225
        tree.unlock()
 
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))
 
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))