/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to brzlib/tests/test_tree.py

  • Committer: Jelmer Vernooij
  • Date: 2017-05-21 12:41:27 UTC
  • mto: This revision was merged to the branch mainline in revision 6623.
  • Revision ID: jelmer@jelmer.uk-20170521124127-iv8etg0vwymyai6y
s/bzr/brz/ in apport config.

Show diffs side-by-side

added added

removed removed

Lines of Context:
16
16
 
17
17
"""Tests for Tree and InterTree."""
18
18
 
19
 
from breezy import (
 
19
from brzlib import (
20
20
    errors,
21
21
    revision,
22
22
    tree as _mod_tree,
23
23
    )
24
 
from breezy.tests import (
25
 
    TestCase,
26
 
    TestCaseWithTransport,
27
 
    )
28
 
from breezy.tree import (
29
 
    FileTimestampUnavailable,
30
 
    InterTree,
31
 
    find_previous_paths,
32
 
    get_canonical_path,
33
 
    )
34
 
 
35
 
 
36
 
class TestErrors(TestCase):
37
 
 
38
 
    def test_file_timestamp_unavailable(self):
39
 
        e = FileTimestampUnavailable("/path/foo")
40
 
        self.assertEqual("The filestamp for /path/foo is not available.",
41
 
                         str(e))
 
24
from brzlib.tests import TestCaseWithTransport
 
25
from brzlib.tree import InterTree
42
26
 
43
27
 
44
28
class TestInterTree(TestCaseWithTransport):
83
67
    calls = []
84
68
 
85
69
    def compare(self, want_unchanged=False, specific_files=None,
86
 
                extra_trees=None, require_versioned=False, include_root=False,
87
 
                want_unversioned=False):
 
70
        extra_trees=None, require_versioned=False, include_root=False,
 
71
        want_unversioned=False):
88
72
        self.calls.append(
89
73
            ('compare', self.source, self.target, want_unchanged,
90
74
             specific_files, extra_trees, require_versioned,
115
99
                              'require', True)
116
100
            # pass in all optional arguments by keyword
117
101
            tree.changes_from(tree2,
118
 
                              specific_files='specific',
119
 
                              want_unchanged='unchanged',
120
 
                              extra_trees='extra',
121
 
                              require_versioned='require',
122
 
                              include_root=True,
123
 
                              want_unversioned=True,
124
 
                              )
 
102
                specific_files='specific',
 
103
                want_unchanged='unchanged',
 
104
                extra_trees='extra',
 
105
                require_versioned='require',
 
106
                include_root=True,
 
107
                want_unversioned=True,
 
108
                )
125
109
        finally:
126
110
            InterTree._optimisers = old_optimisers
127
111
        self.assertEqual(
128
112
            [
129
 
                ('compare', tree2, tree, False, None, None, False, False,
130
 
                    False),
131
 
                ('compare', tree2, tree, 'unchanged', 'specific', 'extra',
132
 
                    'require', True, False),
133
 
                ('compare', tree2, tree, 'unchanged', 'specific', 'extra',
134
 
                    'require', True, True),
 
113
             ('compare', tree2, tree, False, None, None, False, False, False),
 
114
             ('compare', tree2, tree, 'unchanged', 'specific', 'extra',
 
115
              'require', True, False),
 
116
             ('compare', tree2, tree, 'unchanged', 'specific', 'extra',
 
117
              'require', True, True),
135
118
            ], RecordingOptimiser.calls)
136
119
 
137
120
    def test_changes_from_with_root(self):
141
124
        self.assertEqual(len(delta.added), 0)
142
125
        delta = wt.changes_from(wt.basis_tree(), include_root=True)
143
126
        self.assertEqual(len(delta.added), 1)
144
 
        self.assertEqual(delta.added[0].path[1], '')
 
127
        self.assertEqual(delta.added[0][0], '')
145
128
 
146
129
    def test_changes_from_with_require_versioned(self):
147
130
        """Ensure the require_versioned option does what's expected."""
149
132
        self.build_tree(['known_file', 'unknown_file'])
150
133
        wt.add('known_file')
151
134
 
152
 
        self.assertRaises(
153
 
            errors.PathsNotVersionedError,
154
 
            wt.changes_from, wt.basis_tree(), wt,
155
 
            specific_files=['known_file', 'unknown_file'],
156
 
            require_versioned=True)
 
135
        self.assertRaises(errors.PathsNotVersionedError,
 
136
            wt.changes_from, wt.basis_tree(), wt, specific_files=['known_file',
 
137
            'unknown_file'], require_versioned=True)
157
138
 
158
139
        # we need to pass a known file with an unknown file to get this to
159
140
        # fail when expected.
160
141
        delta = wt.changes_from(wt.basis_tree(),
161
 
                                specific_files=['known_file', 'unknown_file'],
162
 
                                require_versioned=False)
 
142
            specific_files=['known_file', 'unknown_file'] ,
 
143
            require_versioned=False)
163
144
        self.assertEqual(len(delta.added), 1)
164
145
 
165
146
 
166
 
class FindPreviousPathsTests(TestCaseWithTransport):
167
 
 
168
 
    def test_new(self):
169
 
        tree = self.make_branch_and_tree('tree')
170
 
        self.build_tree(['tree/b'])
171
 
        tree.add(['b'])
172
 
        revid1 = tree.commit('first')
173
 
        tree1 = tree.branch.repository.revision_tree(revid1)
174
 
 
175
 
        tree0 = tree.branch.repository.revision_tree(revision.NULL_REVISION)
176
 
 
177
 
        self.assertEqual({'b': None}, find_previous_paths(tree1, tree0, ['b']))
178
 
 
179
 
    def test_find_previous_paths(self):
180
 
        tree = self.make_branch_and_tree('tree')
181
 
        self.build_tree(['tree/b'])
182
 
        tree.add(['b'])
183
 
        revid1 = tree.commit('first')
184
 
        tree1 = tree.branch.repository.revision_tree(revid1)
185
 
 
186
 
        tree.rename_one('b', 'c')
187
 
        self.build_tree(['tree/b'])
188
 
        tree.add(['b'])
189
 
        revid2 = tree.commit('second')
190
 
        tree2 = tree.branch.repository.revision_tree(revid2)
191
 
 
192
 
        self.assertEqual({'c': 'b', 'b': None},
193
 
                         find_previous_paths(tree2, tree1, ['b', 'c']))
194
 
 
195
 
 
196
 
class GetCanonicalPath(TestCaseWithTransport):
197
 
 
198
 
    def test_existing_case(self):
199
 
        # Test that we can find a file from a path with different case
200
 
        tree = self.make_branch_and_tree('tree')
201
 
        self.build_tree(['tree/b'])
202
 
        tree.add(['b'])
203
 
        self.assertEqual(
204
 
            'b',
205
 
            get_canonical_path(tree, 'b', lambda x: x.lower()))
206
 
        self.assertEqual(
207
 
            'b',
208
 
            get_canonical_path(tree, 'B', lambda x: x.lower()))
209
 
 
210
 
    def test_nonexistant_preserves_case(self):
211
 
        tree = self.make_branch_and_tree('tree')
212
 
        self.assertEqual(
213
 
            'b',
214
 
            get_canonical_path(tree, 'b', lambda x: x.lower()))
215
 
        self.assertEqual(
216
 
            'B',
217
 
            get_canonical_path(tree, 'B', lambda x: x.lower()))
218
 
 
219
 
    def test_in_directory_with_case(self):
220
 
        tree = self.make_branch_and_tree('tree')
221
 
        self.build_tree(['tree/a/', 'tree/a/b'])
222
 
        tree.add(['a', 'a/b'])
223
 
        self.assertEqual(
224
 
            'a/b',
225
 
            get_canonical_path(tree, 'a/b', lambda x: x.lower()))
226
 
        self.assertEqual(
227
 
            'a/b',
228
 
            get_canonical_path(tree, 'A/B', lambda x: x.lower()))
229
 
        self.assertEqual(
230
 
            'a/b',
231
 
            get_canonical_path(tree, 'A/b', lambda x: x.lower()))
232
 
        self.assertEqual(
233
 
            'a/C',
234
 
            get_canonical_path(tree, 'A/C', lambda x: x.lower()))
 
147
class TestMultiWalker(TestCaseWithTransport):
 
148
 
 
149
    def assertStepOne(self, has_more, path, file_id, iterator):
 
150
        retval = _mod_tree.MultiWalker._step_one(iterator)
 
151
        if not has_more:
 
152
            self.assertIs(None, path)
 
153
            self.assertIs(None, file_id)
 
154
            self.assertEqual((False, None, None), retval)
 
155
        else:
 
156
            self.assertEqual((has_more, path, file_id),
 
157
                             (retval[0], retval[1], retval[2].file_id))
 
158
 
 
159
    def test__step_one_empty(self):
 
160
        tree = self.make_branch_and_tree('empty')
 
161
        repo = tree.branch.repository
 
162
        empty_tree = repo.revision_tree(revision.NULL_REVISION)
 
163
 
 
164
        iterator = empty_tree.iter_entries_by_dir()
 
165
        self.assertStepOne(False, None, None, iterator)
 
166
        self.assertStepOne(False, None, None, iterator)
 
167
 
 
168
    def test__step_one(self):
 
169
        tree = self.make_branch_and_tree('tree')
 
170
        self.build_tree(['tree/a', 'tree/b/', 'tree/b/c'])
 
171
        tree.add(['a', 'b', 'b/c'], ['a-id', 'b-id', 'c-id'])
 
172
 
 
173
        iterator = tree.iter_entries_by_dir()
 
174
        tree.lock_read()
 
175
        self.addCleanup(tree.unlock)
 
176
 
 
177
        root_id = tree.path2id('')
 
178
        self.assertStepOne(True, '', root_id, iterator)
 
179
        self.assertStepOne(True, 'a', 'a-id', iterator)
 
180
        self.assertStepOne(True, 'b', 'b-id', iterator)
 
181
        self.assertStepOne(True, 'b/c', 'c-id', iterator)
 
182
        self.assertStepOne(False, None, None, iterator)
 
183
        self.assertStepOne(False, None, None, iterator)
 
184
 
 
185
    def assertWalkerNext(self, exp_path, exp_file_id, master_has_node,
 
186
                         exp_other_paths, iterator):
 
187
        """Check what happens when we step the iterator.
 
188
 
 
189
        :param path: The path for this entry
 
190
        :param file_id: The file_id for this entry
 
191
        :param master_has_node: Does the master tree have this entry?
 
192
        :param exp_other_paths: A list of other_path values.
 
193
        :param iterator: The iterator to step
 
194
        """
 
195
        path, file_id, master_ie, other_values = iterator.next()
 
196
        self.assertEqual((exp_path, exp_file_id), (path, file_id),
 
197
                         'Master entry did not match')
 
198
        if master_has_node:
 
199
            self.assertIsNot(None, master_ie, 'master should have an entry')
 
200
        else:
 
201
            self.assertIs(None, master_ie, 'master should not have an entry')
 
202
        self.assertEqual(len(exp_other_paths), len(other_values),
 
203
                            'Wrong number of other entries')
 
204
        other_paths = []
 
205
        other_file_ids = []
 
206
        for path, ie in other_values:
 
207
            other_paths.append(path)
 
208
            if ie is None:
 
209
                other_file_ids.append(None)
 
210
            else:
 
211
                other_file_ids.append(ie.file_id)
 
212
 
 
213
        exp_file_ids = []
 
214
        for path in exp_other_paths:
 
215
            if path is None:
 
216
                exp_file_ids.append(None)
 
217
            else:
 
218
                exp_file_ids.append(file_id)
 
219
        self.assertEqual(exp_other_paths, other_paths, "Other paths incorrect")
 
220
        self.assertEqual(exp_file_ids, other_file_ids,
 
221
                         "Other file_ids incorrect")
 
222
 
 
223
    def lock_and_get_basis_and_root_id(self, tree):
 
224
        tree.lock_read()
 
225
        self.addCleanup(tree.unlock)
 
226
        basis_tree = tree.basis_tree()
 
227
        basis_tree.lock_read()
 
228
        self.addCleanup(basis_tree.unlock)
 
229
        root_id = tree.path2id('')
 
230
        return basis_tree, root_id
 
231
 
 
232
    def test_simple_stepping(self):
 
233
        tree = self.make_branch_and_tree('tree')
 
234
        self.build_tree(['tree/a', 'tree/b/', 'tree/b/c'])
 
235
        tree.add(['a', 'b', 'b/c'], ['a-id', 'b-id', 'c-id'])
 
236
 
 
237
        tree.commit('first', rev_id='first-rev-id')
 
238
 
 
239
        basis_tree, root_id = self.lock_and_get_basis_and_root_id(tree)
 
240
 
 
241
        walker = _mod_tree.MultiWalker(tree, [basis_tree])
 
242
        iterator = walker.iter_all()
 
243
        self.assertWalkerNext(u'', root_id, True, [u''], iterator)
 
244
        self.assertWalkerNext(u'a', 'a-id', True, [u'a'], iterator)
 
245
        self.assertWalkerNext(u'b', 'b-id', True, [u'b'], iterator)
 
246
        self.assertWalkerNext(u'b/c', 'c-id', True, [u'b/c'], iterator)
 
247
        self.assertRaises(StopIteration, iterator.next)
 
248
 
 
249
    def test_master_has_extra(self):
 
250
        tree = self.make_branch_and_tree('tree')
 
251
        self.build_tree(['tree/a', 'tree/b/', 'tree/c', 'tree/d'])
 
252
        tree.add(['a', 'b', 'd'], ['a-id', 'b-id', 'd-id'])
 
253
 
 
254
        tree.commit('first', rev_id='first-rev-id')
 
255
 
 
256
        tree.add(['c'], ['c-id'])
 
257
        basis_tree, root_id = self.lock_and_get_basis_and_root_id(tree)
 
258
 
 
259
        walker = _mod_tree.MultiWalker(tree, [basis_tree])
 
260
        iterator = walker.iter_all()
 
261
        self.assertWalkerNext(u'', root_id, True, [u''], iterator)
 
262
        self.assertWalkerNext(u'a', 'a-id', True, [u'a'], iterator)
 
263
        self.assertWalkerNext(u'b', 'b-id', True, [u'b'], iterator)
 
264
        self.assertWalkerNext(u'c', 'c-id', True, [None], iterator)
 
265
        self.assertWalkerNext(u'd', 'd-id', True, [u'd'], iterator)
 
266
        self.assertRaises(StopIteration, iterator.next)
 
267
 
 
268
    def test_master_renamed_to_earlier(self):
 
269
        """The record is still present, it just shows up early."""
 
270
        tree = self.make_branch_and_tree('tree')
 
271
        self.build_tree(['tree/a', 'tree/c', 'tree/d'])
 
272
        tree.add(['a', 'c', 'd'], ['a-id', 'c-id', 'd-id'])
 
273
        tree.commit('first', rev_id='first-rev-id')
 
274
        tree.rename_one('d', 'b')
 
275
 
 
276
        basis_tree, root_id = self.lock_and_get_basis_and_root_id(tree)
 
277
 
 
278
        walker = _mod_tree.MultiWalker(tree, [basis_tree])
 
279
        iterator = walker.iter_all()
 
280
        self.assertWalkerNext(u'', root_id, True, [u''], iterator)
 
281
        self.assertWalkerNext(u'a', 'a-id', True, [u'a'], iterator)
 
282
        self.assertWalkerNext(u'b', 'd-id', True, [u'd'], iterator)
 
283
        self.assertWalkerNext(u'c', 'c-id', True, [u'c'], iterator)
 
284
        self.assertRaises(StopIteration, iterator.next)
 
285
 
 
286
    def test_master_renamed_to_later(self):
 
287
        tree = self.make_branch_and_tree('tree')
 
288
        self.build_tree(['tree/a', 'tree/b', 'tree/d'])
 
289
        tree.add(['a', 'b', 'd'], ['a-id', 'b-id', 'd-id'])
 
290
        tree.commit('first', rev_id='first-rev-id')
 
291
        tree.rename_one('b', 'e')
 
292
 
 
293
        basis_tree, root_id = self.lock_and_get_basis_and_root_id(tree)
 
294
 
 
295
        walker = _mod_tree.MultiWalker(tree, [basis_tree])
 
296
        iterator = walker.iter_all()
 
297
        self.assertWalkerNext(u'', root_id, True, [u''], iterator)
 
298
        self.assertWalkerNext(u'a', 'a-id', True, [u'a'], iterator)
 
299
        self.assertWalkerNext(u'd', 'd-id', True, [u'd'], iterator)
 
300
        self.assertWalkerNext(u'e', 'b-id', True, [u'b'], iterator)
 
301
        self.assertRaises(StopIteration, iterator.next)
 
302
 
 
303
    def test_other_extra_in_middle(self):
 
304
        tree = self.make_branch_and_tree('tree')
 
305
        self.build_tree(['tree/a', 'tree/b', 'tree/d'])
 
306
        tree.add(['a', 'b', 'd'], ['a-id', 'b-id', 'd-id'])
 
307
        tree.commit('first', rev_id='first-rev-id')
 
308
        tree.remove(['b'])
 
309
 
 
310
        basis_tree, root_id = self.lock_and_get_basis_and_root_id(tree)
 
311
        walker = _mod_tree.MultiWalker(tree, [basis_tree])
 
312
        iterator = walker.iter_all()
 
313
        self.assertWalkerNext(u'', root_id, True, [u''], iterator)
 
314
        self.assertWalkerNext(u'a', 'a-id', True, [u'a'], iterator)
 
315
        self.assertWalkerNext(u'd', 'd-id', True, [u'd'], iterator)
 
316
        self.assertWalkerNext(u'b', 'b-id', False, [u'b'], iterator)
 
317
        self.assertRaises(StopIteration, iterator.next)
 
318
 
 
319
    def test_other_extra_at_end(self):
 
320
        tree = self.make_branch_and_tree('tree')
 
321
        self.build_tree(['tree/a', 'tree/b', 'tree/d'])
 
322
        tree.add(['a', 'b', 'd'], ['a-id', 'b-id', 'd-id'])
 
323
        tree.commit('first', rev_id='first-rev-id')
 
324
        tree.remove(['d'])
 
325
 
 
326
        basis_tree, root_id = self.lock_and_get_basis_and_root_id(tree)
 
327
        walker = _mod_tree.MultiWalker(tree, [basis_tree])
 
328
        iterator = walker.iter_all()
 
329
        self.assertWalkerNext(u'', root_id, True, [u''], iterator)
 
330
        self.assertWalkerNext(u'a', 'a-id', True, [u'a'], iterator)
 
331
        self.assertWalkerNext(u'b', 'b-id', True, [u'b'], iterator)
 
332
        self.assertWalkerNext(u'd', 'd-id', False, [u'd'], iterator)
 
333
        self.assertRaises(StopIteration, iterator.next)
 
334
 
 
335
    def test_others_extra_at_end(self):
 
336
        tree = self.make_branch_and_tree('tree')
 
337
        self.build_tree(['tree/a', 'tree/b', 'tree/c', 'tree/d', 'tree/e'])
 
338
        tree.add(['a', 'b', 'c', 'd', 'e'],
 
339
                 ['a-id', 'b-id', 'c-id', 'd-id', 'e-id'])
 
340
        tree.commit('first', rev_id='first-rev-id')
 
341
        tree.remove(['e'])
 
342
        tree.commit('second', rev_id='second-rev-id')
 
343
        tree.remove(['d'])
 
344
        tree.commit('third', rev_id='third-rev-id')
 
345
        tree.remove(['c'])
 
346
 
 
347
        basis_tree, root_id = self.lock_and_get_basis_and_root_id(tree)
 
348
        first_tree = tree.branch.repository.revision_tree('first-rev-id')
 
349
        second_tree = tree.branch.repository.revision_tree('second-rev-id')
 
350
        walker = _mod_tree.MultiWalker(tree, [basis_tree, first_tree,
 
351
                                              second_tree])
 
352
        iterator = walker.iter_all()
 
353
        self.assertWalkerNext(u'', root_id, True, [u'', u'', u''], iterator)
 
354
        self.assertWalkerNext(u'a', 'a-id', True, [u'a', u'a', u'a'], iterator)
 
355
        self.assertWalkerNext(u'b', 'b-id', True, [u'b', u'b', u'b'], iterator)
 
356
        self.assertWalkerNext(u'c', 'c-id', False, [u'c', u'c', u'c'], iterator)
 
357
        self.assertWalkerNext(u'd', 'd-id', False, [None, u'd', u'd'], iterator)
 
358
        self.assertWalkerNext(u'e', 'e-id', False, [None, u'e', None], iterator)
 
359
        self.assertRaises(StopIteration, iterator.next)
 
360
 
 
361
    def test_different_file_id_in_others(self):
 
362
        tree = self.make_branch_and_tree('tree')
 
363
        self.build_tree(['tree/a', 'tree/b', 'tree/c/'])
 
364
        tree.add(['a', 'b', 'c'], ['a-id', 'b-id', 'c-id'])
 
365
        tree.commit('first', rev_id='first-rev-id')
 
366
 
 
367
        tree.rename_one('b', 'c/d')
 
368
        self.build_tree(['tree/b'])
 
369
        tree.add(['b'], ['b2-id'])
 
370
        tree.commit('second', rev_id='second-rev-id')
 
371
 
 
372
        tree.rename_one('a', 'c/e')
 
373
        self.build_tree(['tree/a'])
 
374
        tree.add(['a'], ['a2-id'])
 
375
 
 
376
        basis_tree, root_id = self.lock_and_get_basis_and_root_id(tree)
 
377
        first_tree = tree.branch.repository.revision_tree('first-rev-id')
 
378
        walker = _mod_tree.MultiWalker(tree, [basis_tree, first_tree])
 
379
 
 
380
        iterator = walker.iter_all()
 
381
        self.assertWalkerNext(u'', root_id, True, [u'', u''], iterator)
 
382
        self.assertWalkerNext(u'a', 'a2-id', True, [None, None], iterator)
 
383
        self.assertWalkerNext(u'b', 'b2-id', True, [u'b', None], iterator)
 
384
        self.assertWalkerNext(u'c', 'c-id', True, [u'c', u'c'], iterator)
 
385
        self.assertWalkerNext(u'c/d', 'b-id', True, [u'c/d', u'b'], iterator)
 
386
        self.assertWalkerNext(u'c/e', 'a-id', True, [u'a', u'a'], iterator)
 
387
        self.assertRaises(StopIteration, iterator.next)
 
388
 
 
389
    def assertCmpByDirblock(self, cmp_val, path1, path2):
 
390
        self.assertEqual(cmp_val,
 
391
            _mod_tree.MultiWalker._cmp_path_by_dirblock(path1, path2))
 
392
 
 
393
    def test__cmp_path_by_dirblock(self):
 
394
        # We only support Unicode strings at this point
 
395
        self.assertRaises(TypeError,
 
396
            _mod_tree.MultiWalker._cmp_path_by_dirblock, '', 'b')
 
397
        self.assertCmpByDirblock(0, u'', u'')
 
398
        self.assertCmpByDirblock(0, u'a', u'a')
 
399
        self.assertCmpByDirblock(0, u'a/b', u'a/b')
 
400
        self.assertCmpByDirblock(0, u'a/b/c', u'a/b/c')
 
401
        self.assertCmpByDirblock(1, u'a-a', u'a')
 
402
        self.assertCmpByDirblock(-1, u'a-a', u'a/a')
 
403
        self.assertCmpByDirblock(-1, u'a=a', u'a/a')
 
404
        self.assertCmpByDirblock(1, u'a-a/a', u'a/a')
 
405
        self.assertCmpByDirblock(1, u'a=a/a', u'a/a')
 
406
        self.assertCmpByDirblock(1, u'a-a/a', u'a/a/a')
 
407
        self.assertCmpByDirblock(1, u'a=a/a', u'a/a/a')
 
408
        self.assertCmpByDirblock(1, u'a-a/a/a', u'a/a/a')
 
409
        self.assertCmpByDirblock(1, u'a=a/a/a', u'a/a/a')
 
410
 
 
411
    def assertPathToKey(self, expected, path):
 
412
        self.assertEqual(expected, _mod_tree.MultiWalker._path_to_key(path))
 
413
 
 
414
    def test__path_to_key(self):
 
415
        self.assertPathToKey(([u''], u''), u'')
 
416
        self.assertPathToKey(([u''], u'a'), u'a')
 
417
        self.assertPathToKey(([u'a'], u'b'), u'a/b')
 
418
        self.assertPathToKey(([u'a', u'b'], u'c'), u'a/b/c')