/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
4597.2.2 by Vincent Ladeuil
Cleanup conflict tests.
1
# Copyright (C) 2005, 2006, 2007, 2008, 2009 Canonical Ltd
1887.1.1 by Adeodato Simó
Do not separate paragraphs in the copyright statement with blank lines,
2
#
1185.14.8 by Aaron Bentley
Added test_commit.py
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.
1887.1.1 by Adeodato Simó
Do not separate paragraphs in the copyright statement with blank lines,
7
#
1185.14.8 by Aaron Bentley
Added test_commit.py
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.
1887.1.1 by Adeodato Simó
Do not separate paragraphs in the copyright statement with blank lines,
12
#
1185.14.8 by Aaron Bentley
Added test_commit.py
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
1185.14.8 by Aaron Bentley
Added test_commit.py
16
17
18
import os
19
4597.2.2 by Vincent Ladeuil
Cleanup conflict tests.
20
from bzrlib import (
21
    bzrdir,
22
    conflicts,
23
    errors,
24
    tests,
25
    )
4597.3.12 by Vincent Ladeuil
Start writing tests for all expected conflict resolution actions.
26
from bzrlib.tests import script
1185.14.8 by Aaron Bentley
Added test_commit.py
27
1534.10.4 by Aaron Bentley
Implemented conflict serialization
28
1185.14.8 by Aaron Bentley
Added test_commit.py
29
# TODO: Test commit with some added, and added-but-missing files
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
30
# RBC 20060124 is that not tested in test_commit.py ?
1185.14.8 by Aaron Bentley
Added test_commit.py
31
1666.1.4 by Robert Collins
* 'Metadir' is now the default disk format. This improves behaviour in
32
# The order of 'path' here is important - do not let it
33
# be a sorted list.
2309.4.13 by John Arbash Meinel
Conflicts go through Stanza so the need to be aware of utf8 versus unicode file ids.
34
# u'\xe5' == a with circle
35
# '\xc3\xae' == u'\xee' == i with hat
4597.2.2 by Vincent Ladeuil
Cleanup conflict tests.
36
# So these are u'path' and 'id' only with a circle and a hat. (shappo?)
37
example_conflicts = conflicts.ConflictList(
38
    [conflicts.MissingParent('Not deleting', u'p\xe5thg', '\xc3\xaedg'),
39
     conflicts.ContentsConflict(u'p\xe5tha', None, '\xc3\xaeda'),
40
     conflicts.TextConflict(u'p\xe5tha'),
41
     conflicts.PathConflict(u'p\xe5thb', u'p\xe5thc', '\xc3\xaedb'),
42
     conflicts.DuplicateID('Unversioned existing file',
43
                           u'p\xe5thc', u'p\xe5thc2',
44
                           '\xc3\xaedc', '\xc3\xaedc'),
45
    conflicts.DuplicateEntry('Moved existing file to',
46
                             u'p\xe5thdd.moved', u'p\xe5thd',
47
                             '\xc3\xaedd', None),
48
    conflicts.ParentLoop('Cancelled move', u'p\xe5the', u'p\xe5th2e',
49
                         None, '\xc3\xaed2e'),
50
    conflicts.UnversionedParent('Versioned directory',
51
                                u'p\xe5thf', '\xc3\xaedf'),
52
    conflicts.NonDirectoryParent('Created directory',
53
                                 u'p\xe5thg', '\xc3\xaedg'),
1534.10.22 by Aaron Bentley
Got ConflictList implemented
54
])
1534.10.4 by Aaron Bentley
Implemented conflict serialization
55
56
4597.2.2 by Vincent Ladeuil
Cleanup conflict tests.
57
class TestConflictStanzas(tests.TestCase):
58
59
    def test_stanza_roundtrip(self):
60
        # write and read our example stanza.
61
        stanza_iter = example_conflicts.to_stanzas()
62
        processed = conflicts.ConflictList.from_stanzas(stanza_iter)
63
        for o, p in zip(processed, example_conflicts):
64
            self.assertEqual(o, p)
65
66
            self.assertIsInstance(o.path, unicode)
67
68
            if o.file_id is not None:
69
                self.assertIsInstance(o.file_id, str)
70
71
            conflict_path = getattr(o, 'conflict_path', None)
72
            if conflict_path is not None:
73
                self.assertIsInstance(conflict_path, unicode)
74
75
            conflict_file_id = getattr(o, 'conflict_file_id', None)
76
            if conflict_file_id is not None:
77
                self.assertIsInstance(conflict_file_id, str)
78
79
    def test_stanzification(self):
80
        for stanza in example_conflicts.to_stanzas():
81
            if 'file_id' in stanza:
82
                # In Stanza form, the file_id has to be unicode.
83
                self.assertStartsWith(stanza['file_id'], u'\xeed')
84
            self.assertStartsWith(stanza['path'], u'p\xe5th')
85
            if 'conflict_path' in stanza:
86
                self.assertStartsWith(stanza['conflict_path'], u'p\xe5th')
87
            if 'conflict_file_id' in stanza:
88
                self.assertStartsWith(stanza['conflict_file_id'], u'\xeed')
89
90
91
class TestConflicts(tests.TestCaseWithTransport):
1185.14.8 by Aaron Bentley
Added test_commit.py
92
93
    def test_conflicts(self):
94
        """Conflicts are detected properly"""
4597.2.3 by Vincent Ladeuil
More cleanup.
95
        # Use BzrDirFormat6 so we can fake conflicts
96
        tree = self.make_branch_and_tree('.', format=bzrdir.BzrDirFormat6())
97
        self.build_tree_contents([('hello', 'hello world4'),
98
                                  ('hello.THIS', 'hello world2'),
99
                                  ('hello.BASE', 'hello world1'),
100
                                  ('hello.OTHER', 'hello world3'),
101
                                  ('hello.sploo.BASE', 'yellowworld'),
102
                                  ('hello.sploo.OTHER', 'yellowworld2'),
103
                                  ])
2255.2.61 by John Arbash Meinel
Find callers of list_files() and make sure the tree is always locked.
104
        tree.lock_read()
4597.2.2 by Vincent Ladeuil
Cleanup conflict tests.
105
        self.assertEqual(6, len(list(tree.list_files())))
2255.2.61 by John Arbash Meinel
Find callers of list_files() and make sure the tree is always locked.
106
        tree.unlock()
4597.2.3 by Vincent Ladeuil
More cleanup.
107
        tree_conflicts = tree.conflicts()
108
        self.assertEqual(2, len(tree_conflicts))
109
        self.assertTrue('hello' in tree_conflicts[0].path)
110
        self.assertTrue('hello.sploo' in tree_conflicts[1].path)
111
        conflicts.restore('hello')
112
        conflicts.restore('hello.sploo')
4597.2.2 by Vincent Ladeuil
Cleanup conflict tests.
113
        self.assertEqual(0, len(tree.conflicts()))
1185.35.1 by Aaron Bentley
Implemented conflicts.restore
114
        self.assertFileEqual('hello world2', 'hello')
3376.2.4 by Martin Pool
Remove every assert statement from bzrlib!
115
        self.assertFalse(os.path.lexists('hello.sploo'))
4597.2.3 by Vincent Ladeuil
More cleanup.
116
        self.assertRaises(errors.NotConflicted, conflicts.restore, 'hello')
117
        self.assertRaises(errors.NotConflicted,
118
                          conflicts.restore, 'hello.sploo')
1534.10.4 by Aaron Bentley
Implemented conflict serialization
119
1558.12.9 by Aaron Bentley
Handle resolving conflicts with directories properly
120
    def test_resolve_conflict_dir(self):
121
        tree = self.make_branch_and_tree('.')
4597.2.3 by Vincent Ladeuil
More cleanup.
122
        self.build_tree_contents([('hello', 'hello world4'),
123
                                  ('hello.THIS', 'hello world2'),
124
                                  ('hello.BASE', 'hello world1'),
125
                                  ])
126
        os.mkdir('hello.OTHER')
1558.12.9 by Aaron Bentley
Handle resolving conflicts with directories properly
127
        tree.add('hello', 'q')
4597.2.3 by Vincent Ladeuil
More cleanup.
128
        l = conflicts.ConflictList([conflicts.TextConflict('hello')])
1558.12.9 by Aaron Bentley
Handle resolving conflicts with directories properly
129
        l.remove_files(tree)
130
1551.15.58 by Aaron Bentley
Status honours selected paths for conflicts (#127606)
131
    def test_select_conflicts(self):
132
        tree = self.make_branch_and_tree('.')
4597.2.3 by Vincent Ladeuil
More cleanup.
133
        clist = conflicts.ConflictList
134
135
        def check_select(not_selected, selected, paths, **kwargs):
136
            self.assertEqual(
137
                (not_selected, selected),
138
                tree_conflicts.select_conflicts(tree, paths, **kwargs))
139
140
        foo = conflicts.ContentsConflict('foo')
141
        bar = conflicts.ContentsConflict('bar')
142
        tree_conflicts = clist([foo, bar])
143
144
        check_select(clist([bar]), clist([foo]), ['foo'])
145
        check_select(clist(), tree_conflicts,
146
                     [''], ignore_misses=True, recurse=True)
147
148
        foobaz  = conflicts.ContentsConflict('foo/baz')
149
        tree_conflicts = clist([foobaz, bar])
150
151
        check_select(clist([bar]), clist([foobaz]),
152
                     ['foo'], ignore_misses=True, recurse=True)
153
154
        qux = conflicts.PathConflict('qux', 'foo/baz')
155
        tree_conflicts = clist([qux])
156
157
        check_select(clist(), tree_conflicts,
158
                     ['foo'], ignore_misses=True, recurse=True)
159
        check_select (tree_conflicts, clist(), ['foo'], ignore_misses=True)
1551.15.58 by Aaron Bentley
Status honours selected paths for conflicts (#127606)
160
3017.2.1 by Aaron Bentley
Revert now resolves conflicts recursively (#102739)
161
    def test_resolve_conflicts_recursive(self):
162
        tree = self.make_branch_and_tree('.')
163
        self.build_tree(['dir/', 'dir/hello'])
164
        tree.add(['dir', 'dir/hello'])
4597.2.3 by Vincent Ladeuil
More cleanup.
165
166
        dirhello = conflicts.ConflictList([conflicts.TextConflict('dir/hello')])
167
        tree.set_conflicts(dirhello)
168
169
        conflicts.resolve(tree, ['dir'], recursive=False, ignore_misses=True)
170
        self.assertEqual(dirhello, tree.conflicts())
171
172
        conflicts.resolve(tree, ['dir'], recursive=True, ignore_misses=True)
173
        self.assertEqual(conflicts.ConflictList([]), tree.conflicts())
3017.2.1 by Aaron Bentley
Revert now resolves conflicts recursively (#102739)
174
1534.10.4 by Aaron Bentley
Implemented conflict serialization
175
4597.3.12 by Vincent Ladeuil
Start writing tests for all expected conflict resolution actions.
176
class TestResolveConflicts(script.TestCaseWithTransportAndScript):
177
178
    preamble = None # The setup script set by daughter classes
179
180
    def setUp(self):
181
        super(TestResolveConflicts, self).setUp()
182
        self.run_script(self.preamble)
183
184
185
class TestResolveTextConflicts(TestResolveConflicts):
186
    # TBC
187
    pass
188
189
190
class TestResolveContentConflicts(TestResolveConflicts):
191
192
    # FIXME: We need to add the reverse case (delete in trunk, modify in
193
    # branch) but that could wait until the resolution mechanism is implemented.
194
195
    preamble = """
196
bzr init trunk
197
cd trunk
198
echo 'trunk content' >file
199
bzr add file
200
bzr commit -m 'Create trunk'
201
202
bzr branch . ../branch
203
cd ../branch
204
bzr rm file
205
bzr commit -m 'Delete file'
206
207
cd ../trunk
208
echo 'more content' >>file
209
bzr commit -m 'Modify file'
210
211
cd ../branch
212
bzr merge ../trunk
213
2>+N  file.OTHER
214
2>Contents conflict in file
215
2>1 conflicts encountered.
216
"""
217
218
    def test_keep_this(self):
219
        self.run_script("""
220
bzr rm file.OTHER --force # a simple rm file.OTHER is valid too
221
bzr resolve file
222
bzr commit --strict -m 'No more conflicts nor unknown files'
223
""")
224
225
    def test_keep_other(self):
226
        self.run_script("""
227
bzr mv file.OTHER file
228
bzr resolve file
229
bzr commit --strict -m 'No more conflicts nor unknown files'
230
""")
231
232
233
class TestResolveDuplicatePaths(TestResolveConflicts):
234
235
    preamble = """
236
bzr init trunk
237
cd trunk
238
echo 'trunk content' >file
239
bzr add file
240
bzr commit -m 'Create trunk'
241
echo 'trunk content too' >file2
242
bzr add file2
243
bzr commit -m 'Add file2 in trunk'
244
245
bzr branch . -r 1 ../branch
246
cd ../branch
247
echo 'branch content' >file2
248
bzr add file2
249
bzr commit -m 'Add file2 in branch'
250
251
bzr merge ../trunk
252
2>+N  file2
253
2>R   file2 => file2.moved
254
2>Conflict adding file file2.  Moved existing file to file2.moved.
255
2>1 conflicts encountered.
256
"""
257
258
    def test_keep_this(self):
259
        self.run_script("""
260
bzr rm file2  --force
261
bzr mv file2.moved file2
262
bzr resolve file2
263
bzr commit --strict -m 'No more conflicts nor unknown files'
264
""")
265
266
    def test_keep_other(self):
267
        self.failIfExists('branch/file2.moved')
268
        self.run_script("""
269
bzr rm file2.moved --force
270
bzr resolve file2
271
bzr commit --strict -m 'No more conflicts nor unknown files'
272
""")
273
        self.failIfExists('branch/file2.moved')
274
275
276
class TestResolveUnversionedParent(TestResolveConflicts):
277
278
    preamble = """
279
bzr init trunk
280
cd trunk
281
echo 'trunk content' >file
282
bzr add file
283
bzr commit -m 'Create trunk'
284
echo 'trunk content too' >file2
285
bzr add file2
286
bzr commit -m 'Add file2 in trunk'
287
288
bzr branch . -r 1 ../branch
289
cd ../branch
290
echo 'branch content' >file2
291
bzr add file2
292
bzr commit -m 'Add file2 in branch'
293
294
bzr merge ../trunk
295
2>+N  file2
296
2>R   file2 => file2.moved
297
2>Conflict adding file file2.  Moved existing file to file2.moved.
298
2>1 conflicts encountered.
299
"""
300
301
    def test_keep_this(self):
302
        self.run_script("""
303
bzr rm file2  --force
304
bzr mv file2.moved file2
305
bzr resolve file2
306
bzr commit --strict -m 'No more conflicts nor unknown files'
307
""")
308
309
    def test_keep_other(self):
310
        self.failIfExists('branch/file2.moved')
311
        self.run_script("""
312
bzr rm file2.moved --force
313
bzr resolve file2
314
bzr commit --strict -m 'No more conflicts nor unknown files'
315
""")
316
        self.failIfExists('branch/file2.moved')
317
318
319
class TestResolveMissingParent(TestResolveConflicts):
320
321
    preamble = """
322
bzr init trunk
323
cd trunk
324
mkdir dir
325
echo 'trunk content' >dir/file
326
bzr add
327
bzr commit -m 'Create trunk'
328
echo 'trunk content' >dir/file2
329
bzr add dir/file2
330
bzr commit -m 'Add dir/file2 in branch'
331
332
bzr branch . -r 1 ../branch
333
cd ../branch
334
bzr rm dir/file --force
335
bzr rm dir
336
bzr commit -m 'Remove dir/file'
337
338
bzr merge ../trunk
339
2>+N  dir/
340
2>+N  dir/file2
341
2>Conflict adding files to dir.  Created directory.
342
2>Conflict because dir is not versioned, but has versioned children.  Versioned directory.
343
2>2 conflicts encountered.
344
"""
345
346
    def test_keep_them_all(self):
347
        self.run_script("""
348
bzr resolve dir
349
bzr commit --strict -m 'No more conflicts nor unknown files'
350
""")
351
352
    def test_adopt_child(self):
353
        self.run_script("""
354
bzr mv dir/file2 file2
355
bzr rm dir --force
356
bzr resolve dir
357
bzr commit --strict -m 'No more conflicts nor unknown files'
358
""")
359
360
    def test_kill_them_all(self):
361
        self.run_script("""
362
bzr rm dir --force
363
bzr resolve dir
364
bzr commit --strict -m 'No more conflicts nor unknown files'
365
""")
366
367
368
class TestResolveDeletingParent(TestResolveConflicts):
369
370
    preamble = """
371
bzr init trunk
372
cd trunk
373
mkdir dir
374
echo 'trunk content' >dir/file
375
bzr add
376
bzr commit -m 'Create trunk'
377
bzr rm dir/file --force
378
bzr rm dir --force
379
bzr commit -m 'Remove dir/file'
380
381
bzr branch . -r 1 ../branch
382
cd ../branch
383
echo 'branch content' >dir/file2
384
bzr add dir/file2
385
bzr commit -m 'Add dir/file2 in branch'
386
387
bzr merge ../trunk
388
2>-D  dir/file
389
2>Conflict: can't delete dir because it is not empty.  Not deleting.
390
2>Conflict because dir is not versioned, but has versioned children.  Versioned directory.
391
2>2 conflicts encountered.
392
"""
393
394
    def test_keep_them_all(self):
395
        self.run_script("""
396
bzr resolve dir
397
bzr commit --strict -m 'No more conflicts nor unknown files'
398
""")
399
400
    def test_adopt_child(self):
401
        self.run_script("""
402
bzr mv dir/file2 file2
403
bzr rm dir --force
404
bzr resolve dir
405
bzr commit --strict -m 'No more conflicts nor unknown files'
406
""")
407
408
    def test_kill_them_all(self):
409
        self.run_script("""
410
bzr rm dir --force
411
bzr resolve dir
412
bzr commit --strict -m 'No more conflicts nor unknown files'
413
""")
414
415
416
class TestResolvePathConflict(TestResolveConflicts):
417
418
    preamble = """
419
bzr init trunk
420
cd trunk
421
mkdir dir
422
echo 'Boo!' >file
423
bzr add
424
bzr commit -m 'Create trunk'
425
bzr mv file file-in-trunk
426
bzr commit -m 'Renamed to file-in-trunk'
427
428
bzr branch . -r 1 ../branch
429
cd ../branch
430
bzr mv file file-in-branch
431
bzr commit -m 'Renamed to file-in-branch'
432
433
bzr merge ../trunk
434
2>R   file-in-branch => file-in-trunk
435
2>Path conflict: file-in-branch / file-in-trunk
436
2>1 conflicts encountered.
437
"""
438
439
    def test_keep_source(self):
440
        self.run_script("""
441
bzr resolve file-in-trunk
442
bzr commit --strict -m 'No more conflicts nor unknown files'
443
""")
444
445
    def test_keep_target(self):
446
        self.run_script("""
447
bzr mv file-in-trunk file-in-branch
448
bzr resolve file-in-branch
449
bzr commit --strict -m 'No more conflicts nor unknown files'
450
""")
451
452
453
class TestResolveParentLoop(TestResolveConflicts):
454
455
    preamble = """
456
bzr init trunk
457
cd trunk
458
bzr mkdir dir1
459
bzr mkdir dir2
460
bzr commit -m 'Create trunk'
461
bzr mv dir2 dir1
462
bzr commit -m 'Moved dir2 into dir1'
463
464
bzr branch . -r 1 ../branch
465
cd ../branch
466
bzr mv dir1 dir2
467
bzr commit -m 'Moved dir1 into dir2'
468
469
bzr merge ../trunk
470
2>Conflict moving dir2/dir1 into dir2.  Cancelled move.
471
2>1 conflicts encountered.
472
"""
473
474
    def test_keep_target(self):
475
        self.run_script("""
476
bzr resolve dir2
477
bzr commit --strict -m 'No more conflicts nor unknown files'
478
""")
479
480
    def test_keep_source(self):
481
        self.run_script("""
482
bzr ls -RV
483
bzr mv dir2/dir1 dir1
484
bzr mv dir2 dir1
485
bzr resolve dir2
486
bzr commit --strict -m 'No more conflicts nor unknown files'
487
""")
488
489
490
class TestResolveNonDirectoryParent(TestResolveConflicts):
491
492
    preamble = """
493
bzr init trunk
494
cd trunk
495
bzr mkdir foo
496
bzr commit -m 'Create trunk'
497
echo "Boing" >foo/bar
498
bzr add foo/bar
499
bzr commit -m 'Add foo/bar'
500
501
bzr branch . -r 1 ../branch
502
cd ../branch
503
rm -r foo
504
echo "Boo!" >foo
505
bzr commit -m 'foo is now a file'
506
507
bzr merge ../trunk
508
2>+N  foo.new/bar
509
2>RK  foo => foo.new/
510
# FIXME: The message is misleading, foo.new *is* a directory when the message
511
# is displayed -- vila 090916
512
2>Conflict: foo.new is not a directory, but has files in it.  Created directory.
513
2>1 conflicts encountered.
514
"""
515
516
    def test_remove_this(self):
517
        self.run_script("""
518
bzr rm foo --force
519
bzr mv foo.new foo
520
bzr resolve foo
521
bzr commit --strict -m 'No more conflicts nor unknown files'
522
""")
523
524
    def test_remove_other(self):
525
        self.run_script("""
526
bzr rm foo.new --force
527
# FIXME: Isn't it weird that foo is now unkown even if foo.new has been put
528
# aside ? -- vila 090916
529
bzr add foo
530
bzr resolve foo.new
531
bzr commit --strict -m 'No more conflicts nor unknown files'
532
""")
533
534
535
class TestMalformedTransform(script.TestCaseWithTransportAndScript):
536
537
    def test_bug_430129(self):
538
        # This is nearly like TestResolveNonDirectoryParent but with branch and
539
        # trunk switched. As such it should certainly produce the same
540
        # conflict.
541
        self.run_script("""
542
bzr init trunk
543
cd trunk
544
bzr mkdir foo
545
bzr commit -m 'Create trunk'
546
rm -r foo
547
echo "Boo!" >foo
548
bzr commit -m 'foo is now a file'
549
550
bzr branch . -r 1 ../branch
551
cd ../branch
552
echo "Boing" >foo/bar
553
bzr add foo/bar
554
bzr commit -m 'Add foo/bar'
555
556
bzr merge ../trunk
557
2>bzr: ERROR: Tree transform is malformed [('unversioned executability', 'new-1')]
558
""")