/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
0.65.4 by James Westby
Make the rename handling more robust.
1
# Copyright (C) 2008 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
17
import time
18
19
from bzrlib import (
20
    branch,
21
    tests,
22
    )
23
24
from bzrlib.plugins.fastimport import (
25
    commands,
26
    errors,
27
    )
28
29
from bzrlib.plugins.fastimport.processors import (
30
    generic_processor,
31
    )
32
33
0.76.1 by Ian Clatworthy
clean-up tests for GenericProcessor
34
class TestCaseForGenericProcessor(tests.TestCaseWithTransport):
0.65.4 by James Westby
Make the rename handling more robust.
35
36
    def get_handler(self):
37
        branch = self.make_branch('.')
38
        handler = generic_processor.GenericProcessor(branch.bzrdir)
0.76.1 by Ian Clatworthy
clean-up tests for GenericProcessor
39
        return handler, branch
0.65.4 by James Westby
Make the rename handling more robust.
40
41
    # FIXME: [] as a default is bad, as it is mutable, but I want
42
    # to use None to mean "don't check this".
0.76.1 by Ian Clatworthy
clean-up tests for GenericProcessor
43
    def assertChanges(self, branch, revno, expected_added=[],
44
            expected_removed=[], expected_modified=[],
45
            expected_renamed=[]):
46
        """Check the changes introduced in a revision of a branch.
47
48
        This method checks that a revision introduces expected changes.
49
        The required changes are passed in as a list, where
50
        each entry contains the needed information about the change.
51
52
        If you do not wish to assert anything about a particular
53
        category then pass None instead.
54
55
        branch: The branch.
56
        revno: revision number of revision to check.
57
        expected_added: a list of (filename,) tuples that must have
58
            been added in the delta.
59
        expected_removed: a list of (filename,) tuples that must have
60
            been removed in the delta.
61
        expected_modified: a list of (filename,) tuples that must have
62
            been modified in the delta.
63
        expected_renamed: a list of (old_path, new_path) tuples that
64
            must have been renamed in the delta.
65
        :return: revtree1, revtree2
66
        """
67
        repo = branch.repository
0.80.1 by Ian Clatworthy
basic units tests for filemodify
68
        revtree1 = repo.revision_tree(branch.get_rev_id(revno - 1))
69
        revtree2 = repo.revision_tree(branch.get_rev_id(revno))
0.76.1 by Ian Clatworthy
clean-up tests for GenericProcessor
70
        changes = revtree2.changes_from(revtree1)
71
        self.check_changes(changes, expected_added, expected_removed,
72
            expected_modified, expected_renamed)
73
        return revtree1, revtree2
74
0.65.4 by James Westby
Make the rename handling more robust.
75
    def check_changes(self, changes, expected_added=[],
76
            expected_removed=[], expected_modified=[],
77
            expected_renamed=[]):
78
        """Check the changes in a TreeDelta
79
80
        This method checks that the TreeDelta contains the expected
81
        modifications between the two trees that were used to generate
82
        it. The required changes are passed in as a list, where
83
        each entry contains the needed information about the change.
84
85
        If you do not wish to assert anything about a particular
86
        category then pass None instead.
87
88
        changes: The TreeDelta to check.
89
        expected_added: a list of (filename,) tuples that must have
90
            been added in the delta.
91
        expected_removed: a list of (filename,) tuples that must have
92
            been removed in the delta.
93
        expected_modified: a list of (filename,) tuples that must have
94
            been modified in the delta.
95
        expected_renamed: a list of (old_path, new_path) tuples that
96
            must have been renamed in the delta.
97
        """
98
        renamed = changes.renamed
99
        added = changes.added
100
        removed = changes.removed
101
        modified = changes.modified
102
        if expected_renamed is not None:
103
            self.assertEquals(len(renamed), len(expected_renamed),
0.74.1 by John Arbash Meinel
Change the rename code to create a new text entry.
104
                "%s is renamed, expected %s" % (renamed, expected_renamed))
0.65.4 by James Westby
Make the rename handling more robust.
105
            renamed_files = [(item[0], item[1]) for item in renamed]
106
            for expected_renamed_entry in expected_renamed:
107
                self.assertTrue(expected_renamed_entry in renamed_files,
108
                    "%s is not renamed, %s are" % (str(expected_renamed_entry),
109
                        renamed_files))
110
        if expected_added is not None:
111
            self.assertEquals(len(added), len(expected_added),
112
                "%s is added" % str(added))
113
            added_files = [(item[0],) for item in added]
114
            for expected_added_entry in expected_added:
115
                self.assertTrue(expected_added_entry in added_files,
116
                    "%s is not added, %s are" % (str(expected_added_entry),
117
                        added_files))
118
        if expected_removed is not None:
119
            self.assertEquals(len(removed), len(expected_removed),
120
                "%s is removed" % str(removed))
121
            removed_files = [(item[0],) for item in removed]
122
            for expected_removed_entry in expected_removed:
123
                self.assertTrue(expected_removed_entry in removed_files,
124
                    "%s is not removed, %s are" % (str(expected_removed_entry),
125
                        removed_files))
126
        if expected_modified is not None:
127
            self.assertEquals(len(modified), len(expected_modified),
128
                "%s is modified" % str(modified))
129
            modified_files = [(item[0],) for item in modified]
130
            for expected_modified_entry in expected_modified:
131
                self.assertTrue(expected_modified_entry in modified_files,
132
                    "%s is not modified, %s are" % (str(expected_modified_entry),
133
                        modified_files))
134
0.80.1 by Ian Clatworthy
basic units tests for filemodify
135
    def assertContent(self, branch, tree, path, content):
136
        file_id = tree.inventory.path2id(path)
137
        branch.lock_read()
138
        self.addCleanup(branch.unlock)
139
        self.assertEqual(tree.get_file_text(file_id), content)
140
141
    def assertSymlinkTarget(self, branch, tree, path, target):
142
        file_id = tree.inventory.path2id(path)
143
        branch.lock_read()
144
        self.addCleanup(branch.unlock)
145
        self.assertEqual(tree.get_symlink_target(file_id), target)
146
147
    def assertRevisionRoot(self, revtree, path):
148
        self.assertEqual(revtree.get_revision_id(),
149
                         revtree.inventory.root.children[path].revision)
150
151
152
class TestModify(TestCaseForGenericProcessor):
153
154
    def file_command_iter(self, path, kind='file'):
155
        def command_list():
156
            author = ['', 'bugs@a.com', time.time(), time.timezone]
157
            committer = ['', 'elmer@a.com', time.time(), time.timezone]
158
            def files_one():
159
                yield commands.FileModifyCommand(path, kind, False,
160
                        None, "aaa")
161
            yield commands.CommitCommand('head', '1', author,
162
                committer, "commit 1", None, [], files_one)
163
            def files_two():
164
                yield commands.FileModifyCommand(path, kind, False,
165
                        None, "bbb")
166
            yield commands.CommitCommand('head', '2', author,
167
                committer, "commit 2", ":1", [], files_two)
168
        return command_list
169
170
    def test_modify_file_in_root(self):
171
        handler, branch = self.get_handler()
172
        path = 'a'
173
        handler.process(self.file_command_iter(path))
174
        revtree0, revtree1 = self.assertChanges(branch, 1,
175
            expected_added=[(path,)])
176
        revtree1, revtree2 = self.assertChanges(branch, 2,
177
            expected_modified=[(path,)])
178
        self.assertContent(branch, revtree1, path, "aaa")
179
        self.assertContent(branch, revtree2, path, "bbb")
180
        self.assertRevisionRoot(revtree1, path)
181
        self.assertRevisionRoot(revtree2, path)
182
183
    def test_modify_file_in_subdir(self):
184
        handler, branch = self.get_handler()
185
        path = 'a/a'
186
        handler.process(self.file_command_iter(path))
187
        revtree0, revtree1 = self.assertChanges(branch, 1,
188
            expected_added=[('a',), (path,)])
189
        revtree1, revtree2 = self.assertChanges(branch, 2,
190
            expected_modified=[(path,)])
191
        self.assertContent(branch, revtree1, path, "aaa")
192
        self.assertContent(branch, revtree2, path, "bbb")
193
194
    def test_modify_symlink_in_root(self):
195
        handler, branch = self.get_handler()
196
        path = 'a'
197
        handler.process(self.file_command_iter(path, kind='symlink'))
198
        revtree1, revtree2 = self.assertChanges(branch, 2,
199
            expected_modified=[(path,)])
200
        self.assertSymlinkTarget(branch, revtree1, path, "aaa")
201
        self.assertSymlinkTarget(branch, revtree2, path, "bbb")
202
        self.assertRevisionRoot(revtree1, path)
203
        self.assertRevisionRoot(revtree2, path)
204
205
    def test_modify_symlink_in_subdir(self):
206
        handler, branch = self.get_handler()
207
        path = 'a/a'
208
        handler.process(self.file_command_iter(path, kind='symlink'))
209
        revtree0, revtree1 = self.assertChanges(branch, 1,
210
            expected_added=[('a',), (path,)])
211
        revtree1, revtree2 = self.assertChanges(branch, 2,
212
            expected_modified=[(path,)])
213
        self.assertSymlinkTarget(branch, revtree1, path, "aaa")
214
        self.assertSymlinkTarget(branch, revtree2, path, "bbb")
215
0.76.1 by Ian Clatworthy
clean-up tests for GenericProcessor
216
0.80.2 by Ian Clatworthy
basic delete tests
217
class TestDelete(TestCaseForGenericProcessor):
218
219
    def file_command_iter(self, path, kind='file'):
220
        def command_list():
221
            author = ['', 'bugs@a.com', time.time(), time.timezone]
222
            committer = ['', 'elmer@a.com', time.time(), time.timezone]
223
            def files_one():
224
                yield commands.FileModifyCommand(path, kind, False,
225
                        None, "aaa")
226
            yield commands.CommitCommand('head', '1', author,
227
                committer, "commit 1", None, [], files_one)
228
            def files_two():
229
                yield commands.FileDeleteCommand(path)
230
            yield commands.CommitCommand('head', '2', author,
231
                committer, "commit 2", ":1", [], files_two)
232
        return command_list
233
234
    def test_delete_file_in_root(self):
235
        handler, branch = self.get_handler()
236
        path = 'a'
237
        handler.process(self.file_command_iter(path))
238
        revtree0, revtree1 = self.assertChanges(branch, 1,
239
            expected_added=[(path,)])
240
        revtree1, revtree2 = self.assertChanges(branch, 2,
241
            expected_removed=[(path,)])
242
        self.assertContent(branch, revtree1, path, "aaa")
243
        self.assertRevisionRoot(revtree1, path)
244
245
    def test_delete_file_in_subdir(self):
246
        handler, branch = self.get_handler()
247
        path = 'a/a'
248
        handler.process(self.file_command_iter(path))
249
        revtree0, revtree1 = self.assertChanges(branch, 1,
250
            expected_added=[('a',), (path,)])
251
        revtree1, revtree2 = self.assertChanges(branch, 2,
252
            expected_removed=[(path,)])
253
        self.assertContent(branch, revtree1, path, "aaa")
254
255
    def test_delete_symlink_in_root(self):
256
        handler, branch = self.get_handler()
257
        path = 'a'
258
        handler.process(self.file_command_iter(path, kind='symlink'))
259
        revtree1, revtree2 = self.assertChanges(branch, 2,
260
            expected_removed=[(path,)])
261
        self.assertSymlinkTarget(branch, revtree1, path, "aaa")
262
        self.assertRevisionRoot(revtree1, path)
263
264
    def test_delete_symlink_in_subdir(self):
265
        handler, branch = self.get_handler()
266
        path = 'a/a'
267
        handler.process(self.file_command_iter(path, kind='symlink'))
268
        revtree0, revtree1 = self.assertChanges(branch, 1,
269
            expected_added=[('a',), (path,)])
270
        revtree1, revtree2 = self.assertChanges(branch, 2,
271
            expected_removed=[(path,)])
272
        self.assertSymlinkTarget(branch, revtree1, path, "aaa")
273
274
0.76.1 by Ian Clatworthy
clean-up tests for GenericProcessor
275
class TestRename(TestCaseForGenericProcessor):
276
277
    def get_command_iter(self, old_path, new_path):
278
        def command_list():
279
            author = ['', 'bugs@a.com', time.time(), time.timezone]
280
            committer = ['', 'elmer@a.com', time.time(), time.timezone]
281
            def files_one():
282
                yield commands.FileModifyCommand(old_path, 'file', False,
283
                        None, "aaa")
284
            yield commands.CommitCommand('head', '1', author,
285
                committer, "commit 1", None, [], files_one)
286
            def files_two():
287
                yield commands.FileRenameCommand(old_path, new_path)
288
            yield commands.CommitCommand('head', '2', author,
289
                committer, "commit 2", ":1", [], files_two)
290
        return command_list
291
0.65.4 by James Westby
Make the rename handling more robust.
292
    def test_rename_in_root(self):
0.76.1 by Ian Clatworthy
clean-up tests for GenericProcessor
293
        handler, branch = self.get_handler()
0.65.4 by James Westby
Make the rename handling more robust.
294
        old_path = 'a'
295
        new_path = 'b'
0.76.1 by Ian Clatworthy
clean-up tests for GenericProcessor
296
        handler.process(self.get_command_iter(old_path, new_path))
0.80.1 by Ian Clatworthy
basic units tests for filemodify
297
        revtree1, revtree2 = self.assertChanges(branch, 2,
0.76.1 by Ian Clatworthy
clean-up tests for GenericProcessor
298
            expected_renamed=[(old_path, new_path)])
0.80.1 by Ian Clatworthy
basic units tests for filemodify
299
        self.assertRevisionRoot(revtree1, old_path)
300
        self.assertRevisionRoot(revtree2, new_path)
0.65.4 by James Westby
Make the rename handling more robust.
301
302
    def test_rename_in_subdir(self):
0.76.1 by Ian Clatworthy
clean-up tests for GenericProcessor
303
        handler, branch = self.get_handler()
0.65.4 by James Westby
Make the rename handling more robust.
304
        old_path = 'a/a'
305
        new_path = 'a/b'
0.76.1 by Ian Clatworthy
clean-up tests for GenericProcessor
306
        handler.process(self.get_command_iter(old_path, new_path))
0.80.1 by Ian Clatworthy
basic units tests for filemodify
307
        self.assertChanges(branch, 2, expected_renamed=[(old_path, new_path)])
0.65.4 by James Westby
Make the rename handling more robust.
308
309
    def test_move_to_new_dir(self):
0.76.1 by Ian Clatworthy
clean-up tests for GenericProcessor
310
        handler, branch = self.get_handler()
0.65.4 by James Westby
Make the rename handling more robust.
311
        old_path = 'a/a'
312
        new_path = 'b/a'
0.76.1 by Ian Clatworthy
clean-up tests for GenericProcessor
313
        handler.process(self.get_command_iter(old_path, new_path))
0.80.1 by Ian Clatworthy
basic units tests for filemodify
314
        self.assertChanges(branch, 2, expected_renamed=[(old_path, new_path)],
0.65.4 by James Westby
Make the rename handling more robust.
315
            expected_added=[('b',)])
0.64.74 by Ian Clatworthy
fix symlink importing
316
317
0.76.2 by Ian Clatworthy
code & tests for file copying
318
class TestCopy(TestCaseForGenericProcessor):
319
0.80.1 by Ian Clatworthy
basic units tests for filemodify
320
    def file_command_iter(self, src_path, dest_path, kind='file'):
0.76.2 by Ian Clatworthy
code & tests for file copying
321
        def command_list():
322
            author = ['', 'bugs@a.com', time.time(), time.timezone]
323
            committer = ['', 'elmer@a.com', time.time(), time.timezone]
324
            def files_one():
0.80.1 by Ian Clatworthy
basic units tests for filemodify
325
                yield commands.FileModifyCommand(src_path, kind, False,
0.76.2 by Ian Clatworthy
code & tests for file copying
326
                        None, "aaa")
327
            yield commands.CommitCommand('head', '1', author,
328
                committer, "commit 1", None, [], files_one)
329
            def files_two():
330
                yield commands.FileCopyCommand(src_path, dest_path)
331
            yield commands.CommitCommand('head', '2', author,
332
                committer, "commit 2", ":1", [], files_two)
333
        return command_list
334
335
    def test_copy_file_in_root(self):
336
        handler, branch = self.get_handler()
337
        src_path = 'a'
338
        dest_path = 'b'
339
        handler.process(self.file_command_iter(src_path, dest_path))
0.80.1 by Ian Clatworthy
basic units tests for filemodify
340
        revtree1, revtree2 = self.assertChanges(branch, 2,
0.76.2 by Ian Clatworthy
code & tests for file copying
341
            expected_added=[(dest_path,)])
0.80.1 by Ian Clatworthy
basic units tests for filemodify
342
        self.assertContent(branch, revtree1, src_path, "aaa")
343
        self.assertContent(branch, revtree2, src_path, "aaa")
0.76.2 by Ian Clatworthy
code & tests for file copying
344
        self.assertContent(branch, revtree2, dest_path, "aaa")
0.80.1 by Ian Clatworthy
basic units tests for filemodify
345
        self.assertRevisionRoot(revtree1, src_path)
346
        self.assertRevisionRoot(revtree2, dest_path)
0.76.2 by Ian Clatworthy
code & tests for file copying
347
348
    def test_copy_file_in_subdir(self):
349
        handler, branch = self.get_handler()
350
        src_path = 'a/a'
351
        dest_path = 'a/b'
352
        handler.process(self.file_command_iter(src_path, dest_path))
0.80.1 by Ian Clatworthy
basic units tests for filemodify
353
        revtree1, revtree2 = self.assertChanges(branch, 2,
0.76.2 by Ian Clatworthy
code & tests for file copying
354
            expected_added=[(dest_path,)])
0.80.1 by Ian Clatworthy
basic units tests for filemodify
355
        self.assertContent(branch, revtree1, src_path, "aaa")
356
        self.assertContent(branch, revtree2, src_path, "aaa")
0.76.2 by Ian Clatworthy
code & tests for file copying
357
        self.assertContent(branch, revtree2, dest_path, "aaa")
358
359
    def test_copy_file_to_new_dir(self):
360
        handler, branch = self.get_handler()
361
        src_path = 'a/a'
362
        dest_path = 'b/a'
363
        handler.process(self.file_command_iter(src_path, dest_path))
0.80.1 by Ian Clatworthy
basic units tests for filemodify
364
        revtree1, revtree2 = self.assertChanges(branch, 2,
0.76.2 by Ian Clatworthy
code & tests for file copying
365
            expected_added=[('b',), (dest_path,)])
0.80.1 by Ian Clatworthy
basic units tests for filemodify
366
        self.assertContent(branch, revtree1, src_path, "aaa")
367
        self.assertContent(branch, revtree2, src_path, "aaa")
0.76.2 by Ian Clatworthy
code & tests for file copying
368
        self.assertContent(branch, revtree2, dest_path, "aaa")
369
0.76.3 by Ian Clatworthy
symlink copying tests
370
    def test_copy_symlink_in_root(self):
371
        handler, branch = self.get_handler()
372
        src_path = 'a'
373
        dest_path = 'b'
0.80.1 by Ian Clatworthy
basic units tests for filemodify
374
        handler.process(self.file_command_iter(src_path, dest_path, 'symlink'))
375
        revtree1, revtree2 = self.assertChanges(branch, 2,
0.76.3 by Ian Clatworthy
symlink copying tests
376
            expected_added=[(dest_path,)])
0.80.1 by Ian Clatworthy
basic units tests for filemodify
377
        self.assertSymlinkTarget(branch, revtree1, src_path, "aaa")
378
        self.assertSymlinkTarget(branch, revtree2, src_path, "aaa")
0.76.3 by Ian Clatworthy
symlink copying tests
379
        self.assertSymlinkTarget(branch, revtree2, dest_path, "aaa")
0.80.1 by Ian Clatworthy
basic units tests for filemodify
380
        self.assertRevisionRoot(revtree1, src_path)
381
        self.assertRevisionRoot(revtree2, dest_path)
0.76.3 by Ian Clatworthy
symlink copying tests
382
383
    def test_copy_symlink_in_subdir(self):
384
        handler, branch = self.get_handler()
385
        src_path = 'a/a'
386
        dest_path = 'a/b'
0.80.1 by Ian Clatworthy
basic units tests for filemodify
387
        handler.process(self.file_command_iter(src_path, dest_path, 'symlink'))
388
        revtree1, revtree2 = self.assertChanges(branch, 2,
0.76.3 by Ian Clatworthy
symlink copying tests
389
            expected_added=[(dest_path,)])
0.80.1 by Ian Clatworthy
basic units tests for filemodify
390
        self.assertSymlinkTarget(branch, revtree1, src_path, "aaa")
391
        self.assertSymlinkTarget(branch, revtree2, src_path, "aaa")
0.76.3 by Ian Clatworthy
symlink copying tests
392
        self.assertSymlinkTarget(branch, revtree2, dest_path, "aaa")
393
394
    def test_copy_symlink_to_new_dir(self):
395
        handler, branch = self.get_handler()
396
        src_path = 'a/a'
397
        dest_path = 'b/a'
0.80.1 by Ian Clatworthy
basic units tests for filemodify
398
        handler.process(self.file_command_iter(src_path, dest_path, 'symlink'))
399
        revtree1, revtree2 = self.assertChanges(branch, 2,
0.76.3 by Ian Clatworthy
symlink copying tests
400
            expected_added=[('b',), (dest_path,)])
0.80.1 by Ian Clatworthy
basic units tests for filemodify
401
        self.assertSymlinkTarget(branch, revtree1, src_path, "aaa")
402
        self.assertSymlinkTarget(branch, revtree2, src_path, "aaa")
0.76.3 by Ian Clatworthy
symlink copying tests
403
        self.assertSymlinkTarget(branch, revtree2, dest_path, "aaa")
404
0.76.2 by Ian Clatworthy
code & tests for file copying
405
0.76.1 by Ian Clatworthy
clean-up tests for GenericProcessor
406
class TestFileKinds(TestCaseForGenericProcessor):
0.64.74 by Ian Clatworthy
fix symlink importing
407
408
    def get_command_iter(self, path, kind, content):
409
        def command_list():
410
            committer = ['', 'elmer@a.com', time.time(), time.timezone]
411
            def files_one():
412
                yield commands.FileModifyCommand(path, kind, False,
413
                        None, content)
414
            yield commands.CommitCommand('head', '1', None,
415
                committer, "commit 1", None, [], files_one)
416
        return command_list
417
418
    def test_import_plainfile(self):
0.76.1 by Ian Clatworthy
clean-up tests for GenericProcessor
419
        handler, branch = self.get_handler()
420
        handler.process(self.get_command_iter('foo', 'file', 'aaa'))
0.64.74 by Ian Clatworthy
fix symlink importing
421
422
    def test_import_symlink(self):
0.76.1 by Ian Clatworthy
clean-up tests for GenericProcessor
423
        handler, branch = self.get_handler()
424
        handler.process(self.get_command_iter('foo', 'symlink', 'bar'))