/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
7296.7.1 by Jelmer Vernooij
Split out MultiWalker.
1
# Copyright (C) 2006-2009, 2011 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 MultiWalker."""
18
19
from breezy import (
20
    revision,
21
    multiwalker,
22
    tree as _mod_tree,
23
    )
24
from breezy.tests import (
25
    TestCaseWithTransport,
26
    )
27
28
29
class TestMultiWalker(TestCaseWithTransport):
30
31
    def assertStepOne(self, has_more, path, file_id, iterator):
32
        retval = multiwalker.MultiWalker._step_one(iterator)
33
        if not has_more:
34
            self.assertIs(None, path)
35
            self.assertIs(None, file_id)
36
            self.assertEqual((False, None, None), retval)
37
        else:
38
            self.assertEqual((has_more, path, file_id),
39
                             (retval[0], retval[1], retval[2].file_id))
40
41
    def test__step_one_empty(self):
42
        tree = self.make_branch_and_tree('empty')
43
        repo = tree.branch.repository
44
        empty_tree = repo.revision_tree(revision.NULL_REVISION)
45
46
        iterator = empty_tree.iter_entries_by_dir()
47
        self.assertStepOne(False, None, None, iterator)
48
        self.assertStepOne(False, None, None, iterator)
49
50
    def test__step_one(self):
51
        tree = self.make_branch_and_tree('tree')
52
        self.build_tree(['tree/a', 'tree/b/', 'tree/b/c'])
53
        tree.add(['a', 'b', 'b/c'], [b'a-id', b'b-id', b'c-id'])
54
55
        iterator = tree.iter_entries_by_dir()
56
        tree.lock_read()
57
        self.addCleanup(tree.unlock)
58
59
        root_id = tree.path2id('')
60
        self.assertStepOne(True, '', root_id, iterator)
61
        self.assertStepOne(True, 'a', b'a-id', iterator)
62
        self.assertStepOne(True, 'b', b'b-id', iterator)
63
        self.assertStepOne(True, 'b/c', b'c-id', iterator)
64
        self.assertStepOne(False, None, None, iterator)
65
        self.assertStepOne(False, None, None, iterator)
66
67
    def assertWalkerNext(self, exp_path, exp_file_id, master_has_node,
68
                         exp_other_paths, iterator):
69
        """Check what happens when we step the iterator.
70
71
        :param path: The path for this entry
72
        :param file_id: The file_id for this entry
73
        :param master_has_node: Does the master tree have this entry?
74
        :param exp_other_paths: A list of other_path values.
75
        :param iterator: The iterator to step
76
        """
77
        path, file_id, master_ie, other_values = next(iterator)
78
        self.assertEqual((exp_path, exp_file_id), (path, file_id),
79
                         'Master entry did not match')
80
        if master_has_node:
81
            self.assertIsNot(None, master_ie, 'master should have an entry')
82
        else:
83
            self.assertIs(None, master_ie, 'master should not have an entry')
84
        self.assertEqual(len(exp_other_paths), len(other_values),
85
                         'Wrong number of other entries')
86
        other_paths = []
87
        other_file_ids = []
88
        for path, ie in other_values:
89
            other_paths.append(path)
90
            if ie is None:
91
                other_file_ids.append(None)
92
            else:
93
                other_file_ids.append(ie.file_id)
94
95
        exp_file_ids = []
96
        for path in exp_other_paths:
97
            if path is None:
98
                exp_file_ids.append(None)
99
            else:
100
                exp_file_ids.append(file_id)
101
        self.assertEqual(exp_other_paths, other_paths, "Other paths incorrect")
102
        self.assertEqual(exp_file_ids, other_file_ids,
103
                         "Other file_ids incorrect")
104
105
    def lock_and_get_basis_and_root_id(self, tree):
106
        tree.lock_read()
107
        self.addCleanup(tree.unlock)
108
        basis_tree = tree.basis_tree()
109
        basis_tree.lock_read()
110
        self.addCleanup(basis_tree.unlock)
111
        root_id = tree.path2id('')
112
        return basis_tree, root_id
113
114
    def test_simple_stepping(self):
115
        tree = self.make_branch_and_tree('tree')
116
        self.build_tree(['tree/a', 'tree/b/', 'tree/b/c'])
117
        tree.add(['a', 'b', 'b/c'], [b'a-id', b'b-id', b'c-id'])
118
119
        tree.commit('first', rev_id=b'first-rev-id')
120
121
        basis_tree, root_id = self.lock_and_get_basis_and_root_id(tree)
122
123
        walker = multiwalker.MultiWalker(tree, [basis_tree])
124
        iterator = walker.iter_all()
125
        self.assertWalkerNext(u'', root_id, True, [u''], iterator)
126
        self.assertWalkerNext(u'a', b'a-id', True, [u'a'], iterator)
127
        self.assertWalkerNext(u'b', b'b-id', True, [u'b'], iterator)
128
        self.assertWalkerNext(u'b/c', b'c-id', True, [u'b/c'], iterator)
129
        self.assertRaises(StopIteration, next, iterator)
130
131
    def test_master_has_extra(self):
132
        tree = self.make_branch_and_tree('tree')
133
        self.build_tree(['tree/a', 'tree/b/', 'tree/c', 'tree/d'])
134
        tree.add(['a', 'b', 'd'], [b'a-id', b'b-id', b'd-id'])
135
136
        tree.commit('first', rev_id=b'first-rev-id')
137
138
        tree.add(['c'], [b'c-id'])
139
        basis_tree, root_id = self.lock_and_get_basis_and_root_id(tree)
140
141
        walker = multiwalker.MultiWalker(tree, [basis_tree])
142
        iterator = walker.iter_all()
143
        self.assertWalkerNext(u'', root_id, True, [u''], iterator)
144
        self.assertWalkerNext(u'a', b'a-id', True, [u'a'], iterator)
145
        self.assertWalkerNext(u'b', b'b-id', True, [u'b'], iterator)
146
        self.assertWalkerNext(u'c', b'c-id', True, [None], iterator)
147
        self.assertWalkerNext(u'd', b'd-id', True, [u'd'], iterator)
148
        self.assertRaises(StopIteration, next, iterator)
149
150
    def test_master_renamed_to_earlier(self):
151
        """The record is still present, it just shows up early."""
152
        tree = self.make_branch_and_tree('tree')
153
        self.build_tree(['tree/a', 'tree/c', 'tree/d'])
154
        tree.add(['a', 'c', 'd'], [b'a-id', b'c-id', b'd-id'])
155
        tree.commit('first', rev_id=b'first-rev-id')
156
        tree.rename_one('d', 'b')
157
158
        basis_tree, root_id = self.lock_and_get_basis_and_root_id(tree)
159
160
        walker = multiwalker.MultiWalker(tree, [basis_tree])
161
        iterator = walker.iter_all()
162
        self.assertWalkerNext(u'', root_id, True, [u''], iterator)
163
        self.assertWalkerNext(u'a', b'a-id', True, [u'a'], iterator)
164
        self.assertWalkerNext(u'b', b'd-id', True, [u'd'], iterator)
165
        self.assertWalkerNext(u'c', b'c-id', True, [u'c'], iterator)
166
        self.assertRaises(StopIteration, next, iterator)
167
168
    def test_master_renamed_to_later(self):
169
        tree = self.make_branch_and_tree('tree')
170
        self.build_tree(['tree/a', 'tree/b', 'tree/d'])
171
        tree.add(['a', 'b', 'd'], [b'a-id', b'b-id', b'd-id'])
172
        tree.commit('first', rev_id=b'first-rev-id')
173
        tree.rename_one('b', 'e')
174
175
        basis_tree, root_id = self.lock_and_get_basis_and_root_id(tree)
176
177
        walker = multiwalker.MultiWalker(tree, [basis_tree])
178
        iterator = walker.iter_all()
179
        self.assertWalkerNext(u'', root_id, True, [u''], iterator)
180
        self.assertWalkerNext(u'a', b'a-id', True, [u'a'], iterator)
181
        self.assertWalkerNext(u'd', b'd-id', True, [u'd'], iterator)
182
        self.assertWalkerNext(u'e', b'b-id', True, [u'b'], iterator)
183
        self.assertRaises(StopIteration, next, iterator)
184
185
    def test_other_extra_in_middle(self):
186
        tree = self.make_branch_and_tree('tree')
187
        self.build_tree(['tree/a', 'tree/b', 'tree/d'])
188
        tree.add(['a', 'b', 'd'], [b'a-id', b'b-id', b'd-id'])
189
        tree.commit('first', rev_id=b'first-rev-id')
190
        tree.remove(['b'])
191
192
        basis_tree, root_id = self.lock_and_get_basis_and_root_id(tree)
193
        walker = multiwalker.MultiWalker(tree, [basis_tree])
194
        iterator = walker.iter_all()
195
        self.assertWalkerNext(u'', root_id, True, [u''], iterator)
196
        self.assertWalkerNext(u'a', b'a-id', True, [u'a'], iterator)
197
        self.assertWalkerNext(u'd', b'd-id', True, [u'd'], iterator)
198
        self.assertWalkerNext(u'b', b'b-id', False, [u'b'], iterator)
199
        self.assertRaises(StopIteration, next, iterator)
200
201
    def test_other_extra_at_end(self):
202
        tree = self.make_branch_and_tree('tree')
203
        self.build_tree(['tree/a', 'tree/b', 'tree/d'])
204
        tree.add(['a', 'b', 'd'], [b'a-id', b'b-id', b'd-id'])
205
        tree.commit('first', rev_id=b'first-rev-id')
206
        tree.remove(['d'])
207
208
        basis_tree, root_id = self.lock_and_get_basis_and_root_id(tree)
209
        walker = multiwalker.MultiWalker(tree, [basis_tree])
210
        iterator = walker.iter_all()
211
        self.assertWalkerNext(u'', root_id, True, [u''], iterator)
212
        self.assertWalkerNext(u'a', b'a-id', True, [u'a'], iterator)
213
        self.assertWalkerNext(u'b', b'b-id', True, [u'b'], iterator)
214
        self.assertWalkerNext(u'd', b'd-id', False, [u'd'], iterator)
215
        self.assertRaises(StopIteration, next, iterator)
216
217
    def test_others_extra_at_end(self):
218
        tree = self.make_branch_and_tree('tree')
219
        self.build_tree(['tree/a', 'tree/b', 'tree/c', 'tree/d', 'tree/e'])
220
        tree.add(['a', 'b', 'c', 'd', 'e'],
221
                 [b'a-id', b'b-id', b'c-id', b'd-id', b'e-id'])
222
        tree.commit('first', rev_id=b'first-rev-id')
223
        tree.remove(['e'])
224
        tree.commit('second', rev_id=b'second-rev-id')
225
        tree.remove(['d'])
226
        tree.commit('third', rev_id=b'third-rev-id')
227
        tree.remove(['c'])
228
229
        basis_tree, root_id = self.lock_and_get_basis_and_root_id(tree)
230
        first_tree = tree.branch.repository.revision_tree(b'first-rev-id')
231
        second_tree = tree.branch.repository.revision_tree(b'second-rev-id')
7296.7.7 by Jelmer Vernooij
Fix syntax.
232
        walker = multiwalker.MultiWalker(
233
            tree, [basis_tree, first_tree, second_tree])
7296.7.1 by Jelmer Vernooij
Split out MultiWalker.
234
        iterator = walker.iter_all()
235
        self.assertWalkerNext(u'', root_id, True, [u'', u'', u''], iterator)
236
        self.assertWalkerNext(u'a', b'a-id', True,
237
                              [u'a', u'a', u'a'], iterator)
238
        self.assertWalkerNext(u'b', b'b-id', True,
239
                              [u'b', u'b', u'b'], iterator)
240
        self.assertWalkerNext(u'c', b'c-id', False,
241
                              [u'c', u'c', u'c'], iterator)
242
        self.assertWalkerNext(u'd', b'd-id', False,
243
                              [None, u'd', u'd'], iterator)
244
        self.assertWalkerNext(u'e', b'e-id', False,
245
                              [None, u'e', None], iterator)
246
        self.assertRaises(StopIteration, next, iterator)
247
248
    def test_different_file_id_in_others(self):
249
        tree = self.make_branch_and_tree('tree')
250
        self.build_tree(['tree/a', 'tree/b', 'tree/c/'])
251
        tree.add(['a', 'b', 'c'], [b'a-id', b'b-id', b'c-id'])
252
        tree.commit('first', rev_id=b'first-rev-id')
253
254
        tree.rename_one('b', 'c/d')
255
        self.build_tree(['tree/b'])
256
        tree.add(['b'], [b'b2-id'])
257
        tree.commit('second', rev_id=b'second-rev-id')
258
259
        tree.rename_one('a', 'c/e')
260
        self.build_tree(['tree/a'])
261
        tree.add(['a'], [b'a2-id'])
262
263
        basis_tree, root_id = self.lock_and_get_basis_and_root_id(tree)
264
        first_tree = tree.branch.repository.revision_tree(b'first-rev-id')
265
        walker = multiwalker.MultiWalker(tree, [basis_tree, first_tree])
266
267
        iterator = walker.iter_all()
268
        self.assertWalkerNext(u'', root_id, True, [u'', u''], iterator)
269
        self.assertWalkerNext(u'a', b'a2-id', True, [None, None], iterator)
270
        self.assertWalkerNext(u'b', b'b2-id', True, [u'b', None], iterator)
271
        self.assertWalkerNext(u'c', b'c-id', True, [u'c', u'c'], iterator)
272
        self.assertWalkerNext(u'c/d', b'b-id', True, [u'c/d', u'b'], iterator)
273
        self.assertWalkerNext(u'c/e', b'a-id', True, [u'a', u'a'], iterator)
274
        self.assertRaises(StopIteration, next, iterator)
275
276
    def assertLtByDirblock(self, lt_val, path1, path2):
277
        self.assertEqual(
278
            lt_val, multiwalker.MultiWalker._lt_path_by_dirblock(path1, path2))
279
280
    def test__lt_path_by_dirblock(self):
281
        # We only support Unicode strings at this point
282
        self.assertRaises(
283
            TypeError, multiwalker.MultiWalker._lt_path_by_dirblock, b'', b'b')
284
        self.assertLtByDirblock(False, u'', u'')
285
        self.assertLtByDirblock(False, u'a', u'a')
286
        self.assertLtByDirblock(False, u'a/b', u'a/b')
287
        self.assertLtByDirblock(False, u'a/b/c', u'a/b/c')
288
        self.assertLtByDirblock(False, u'a-a', u'a')
289
        self.assertLtByDirblock(True, u'a-a', u'a/a')
290
        self.assertLtByDirblock(True, u'a=a', u'a/a')
291
        self.assertLtByDirblock(False, u'a-a/a', u'a/a')
292
        self.assertLtByDirblock(False, u'a=a/a', u'a/a')
293
        self.assertLtByDirblock(False, u'a-a/a', u'a/a/a')
294
        self.assertLtByDirblock(False, u'a=a/a', u'a/a/a')
295
        self.assertLtByDirblock(False, u'a-a/a/a', u'a/a/a')
296
        self.assertLtByDirblock(False, u'a=a/a/a', u'a/a/a')
297
298
    def assertPathToKey(self, expected, path):
299
        self.assertEqual(expected, multiwalker.MultiWalker._path_to_key(path))
300
301
    def test__path_to_key(self):
302
        self.assertPathToKey(([u''], u''), u'')
303
        self.assertPathToKey(([u''], u'a'), u'a')
304
        self.assertPathToKey(([u'a'], u'b'), u'a/b')
305
        self.assertPathToKey(([u'a', u'b'], u'c'), u'a/b/c')