/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
4988.10.5 by John Arbash Meinel
Merge bzr.dev 5021 to resolve NEWS
1
# Copyright (C) 2005-2010 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 (
4597.2.23 by Vincent Ladeuil
Start translating blackbox tests into whitebox ones.
21
    branchbuilder,
4597.2.2 by Vincent Ladeuil
Cleanup conflict tests.
22
    bzrdir,
23
    conflicts,
24
    errors,
4597.3.51 by Vincent Ladeuil
Implement conflicts.ResolveActionOption.
25
    option,
4597.2.2 by Vincent Ladeuil
Cleanup conflict tests.
26
    tests,
4597.2.23 by Vincent Ladeuil
Start translating blackbox tests into whitebox ones.
27
    workingtree,
4597.2.2 by Vincent Ladeuil
Cleanup conflict tests.
28
    )
4597.3.12 by Vincent Ladeuil
Start writing tests for all expected conflict resolution actions.
29
from bzrlib.tests import script
1185.14.8 by Aaron Bentley
Added test_commit.py
30
1534.10.4 by Aaron Bentley
Implemented conflict serialization
31
4597.2.26 by Vincent Ladeuil
Fix bug #529968 by renaming the kept file on content conflicts.
32
def load_tests(standard_tests, module, loader):
33
    result = loader.suiteClass()
34
35
    sp_tests, remaining_tests = tests.split_suite_by_condition(
36
        standard_tests, tests.condition_isinstance((
4597.7.4 by Vincent Ladeuil
Abstract the test class some more to address more conflict
37
                TestParametrizedResolveConflicts,
4597.2.26 by Vincent Ladeuil
Fix bug #529968 by renaming the kept file on content conflicts.
38
                )))
4597.7.16 by Vincent Ladeuil
Some cleanup.
39
    # Each test class defines its own scenarios. This is needed for
4597.7.10 by Vincent Ladeuil
Define scenarios by test classes.
40
    # TestResolvePathConflictBefore531967 that verifies that the same tests as
41
    # TestResolvePathConflict still pass.
42
    for test in tests.iter_suite_tests(sp_tests):
43
        tests.apply_scenarios(test, test.scenarios(), result)
4597.2.26 by Vincent Ladeuil
Fix bug #529968 by renaming the kept file on content conflicts.
44
45
    # No parametrization for the remaining tests
46
    result.addTests(remaining_tests)
47
48
    return result
49
50
1185.14.8 by Aaron Bentley
Added test_commit.py
51
# 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.
52
# RBC 20060124 is that not tested in test_commit.py ?
1185.14.8 by Aaron Bentley
Added test_commit.py
53
1666.1.4 by Robert Collins
* 'Metadir' is now the default disk format. This improves behaviour in
54
# The order of 'path' here is important - do not let it
55
# 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.
56
# u'\xe5' == a with circle
57
# '\xc3\xae' == u'\xee' == i with hat
4597.2.2 by Vincent Ladeuil
Cleanup conflict tests.
58
# So these are u'path' and 'id' only with a circle and a hat. (shappo?)
59
example_conflicts = conflicts.ConflictList(
60
    [conflicts.MissingParent('Not deleting', u'p\xe5thg', '\xc3\xaedg'),
61
     conflicts.ContentsConflict(u'p\xe5tha', None, '\xc3\xaeda'),
62
     conflicts.TextConflict(u'p\xe5tha'),
63
     conflicts.PathConflict(u'p\xe5thb', u'p\xe5thc', '\xc3\xaedb'),
64
     conflicts.DuplicateID('Unversioned existing file',
65
                           u'p\xe5thc', u'p\xe5thc2',
66
                           '\xc3\xaedc', '\xc3\xaedc'),
67
    conflicts.DuplicateEntry('Moved existing file to',
68
                             u'p\xe5thdd.moved', u'p\xe5thd',
69
                             '\xc3\xaedd', None),
70
    conflicts.ParentLoop('Cancelled move', u'p\xe5the', u'p\xe5th2e',
71
                         None, '\xc3\xaed2e'),
72
    conflicts.UnversionedParent('Versioned directory',
73
                                u'p\xe5thf', '\xc3\xaedf'),
74
    conflicts.NonDirectoryParent('Created directory',
75
                                 u'p\xe5thg', '\xc3\xaedg'),
1534.10.22 by Aaron Bentley
Got ConflictList implemented
76
])
1534.10.4 by Aaron Bentley
Implemented conflict serialization
77
78
4597.2.2 by Vincent Ladeuil
Cleanup conflict tests.
79
class TestConflicts(tests.TestCaseWithTransport):
1185.14.8 by Aaron Bentley
Added test_commit.py
80
81
    def test_conflicts(self):
82
        """Conflicts are detected properly"""
4597.2.3 by Vincent Ladeuil
More cleanup.
83
        # Use BzrDirFormat6 so we can fake conflicts
84
        tree = self.make_branch_and_tree('.', format=bzrdir.BzrDirFormat6())
85
        self.build_tree_contents([('hello', 'hello world4'),
86
                                  ('hello.THIS', 'hello world2'),
87
                                  ('hello.BASE', 'hello world1'),
88
                                  ('hello.OTHER', 'hello world3'),
89
                                  ('hello.sploo.BASE', 'yellowworld'),
90
                                  ('hello.sploo.OTHER', 'yellowworld2'),
91
                                  ])
2255.2.61 by John Arbash Meinel
Find callers of list_files() and make sure the tree is always locked.
92
        tree.lock_read()
4597.2.28 by Vincent Ladeuil
Use assertLength where appropriate.
93
        self.assertLength(6, list(tree.list_files()))
2255.2.61 by John Arbash Meinel
Find callers of list_files() and make sure the tree is always locked.
94
        tree.unlock()
4597.2.3 by Vincent Ladeuil
More cleanup.
95
        tree_conflicts = tree.conflicts()
4597.2.28 by Vincent Ladeuil
Use assertLength where appropriate.
96
        self.assertLength(2, tree_conflicts)
4597.2.3 by Vincent Ladeuil
More cleanup.
97
        self.assertTrue('hello' in tree_conflicts[0].path)
98
        self.assertTrue('hello.sploo' in tree_conflicts[1].path)
99
        conflicts.restore('hello')
100
        conflicts.restore('hello.sploo')
4597.2.28 by Vincent Ladeuil
Use assertLength where appropriate.
101
        self.assertLength(0, tree.conflicts())
1185.35.1 by Aaron Bentley
Implemented conflicts.restore
102
        self.assertFileEqual('hello world2', 'hello')
3376.2.4 by Martin Pool
Remove every assert statement from bzrlib!
103
        self.assertFalse(os.path.lexists('hello.sploo'))
4597.2.3 by Vincent Ladeuil
More cleanup.
104
        self.assertRaises(errors.NotConflicted, conflicts.restore, 'hello')
105
        self.assertRaises(errors.NotConflicted,
106
                          conflicts.restore, 'hello.sploo')
1534.10.4 by Aaron Bentley
Implemented conflict serialization
107
1558.12.9 by Aaron Bentley
Handle resolving conflicts with directories properly
108
    def test_resolve_conflict_dir(self):
109
        tree = self.make_branch_and_tree('.')
4597.2.3 by Vincent Ladeuil
More cleanup.
110
        self.build_tree_contents([('hello', 'hello world4'),
111
                                  ('hello.THIS', 'hello world2'),
112
                                  ('hello.BASE', 'hello world1'),
113
                                  ])
114
        os.mkdir('hello.OTHER')
1558.12.9 by Aaron Bentley
Handle resolving conflicts with directories properly
115
        tree.add('hello', 'q')
4597.2.3 by Vincent Ladeuil
More cleanup.
116
        l = conflicts.ConflictList([conflicts.TextConflict('hello')])
1558.12.9 by Aaron Bentley
Handle resolving conflicts with directories properly
117
        l.remove_files(tree)
118
1551.15.58 by Aaron Bentley
Status honours selected paths for conflicts (#127606)
119
    def test_select_conflicts(self):
120
        tree = self.make_branch_and_tree('.')
4597.2.3 by Vincent Ladeuil
More cleanup.
121
        clist = conflicts.ConflictList
122
123
        def check_select(not_selected, selected, paths, **kwargs):
124
            self.assertEqual(
125
                (not_selected, selected),
126
                tree_conflicts.select_conflicts(tree, paths, **kwargs))
127
128
        foo = conflicts.ContentsConflict('foo')
129
        bar = conflicts.ContentsConflict('bar')
130
        tree_conflicts = clist([foo, bar])
131
132
        check_select(clist([bar]), clist([foo]), ['foo'])
133
        check_select(clist(), tree_conflicts,
134
                     [''], ignore_misses=True, recurse=True)
135
136
        foobaz  = conflicts.ContentsConflict('foo/baz')
137
        tree_conflicts = clist([foobaz, bar])
138
139
        check_select(clist([bar]), clist([foobaz]),
140
                     ['foo'], ignore_misses=True, recurse=True)
141
142
        qux = conflicts.PathConflict('qux', 'foo/baz')
143
        tree_conflicts = clist([qux])
144
145
        check_select(clist(), tree_conflicts,
146
                     ['foo'], ignore_misses=True, recurse=True)
147
        check_select (tree_conflicts, clist(), ['foo'], ignore_misses=True)
1551.15.58 by Aaron Bentley
Status honours selected paths for conflicts (#127606)
148
3017.2.1 by Aaron Bentley
Revert now resolves conflicts recursively (#102739)
149
    def test_resolve_conflicts_recursive(self):
150
        tree = self.make_branch_and_tree('.')
151
        self.build_tree(['dir/', 'dir/hello'])
152
        tree.add(['dir', 'dir/hello'])
4597.2.3 by Vincent Ladeuil
More cleanup.
153
154
        dirhello = conflicts.ConflictList([conflicts.TextConflict('dir/hello')])
155
        tree.set_conflicts(dirhello)
156
157
        conflicts.resolve(tree, ['dir'], recursive=False, ignore_misses=True)
158
        self.assertEqual(dirhello, tree.conflicts())
159
160
        conflicts.resolve(tree, ['dir'], recursive=True, ignore_misses=True)
161
        self.assertEqual(conflicts.ConflictList([]), tree.conflicts())
4773.1.1 by Vincent Ladeuil
Cleanup imports in test_conflicts
162
163
4597.3.43 by Vincent Ladeuil
Cleanups, ready to record.
164
class TestConflictStanzas(tests.TestCase):
165
166
    def test_stanza_roundtrip(self):
167
        # write and read our example stanza.
168
        stanza_iter = example_conflicts.to_stanzas()
169
        processed = conflicts.ConflictList.from_stanzas(stanza_iter)
170
        for o, p in zip(processed, example_conflicts):
171
            self.assertEqual(o, p)
172
173
            self.assertIsInstance(o.path, unicode)
174
175
            if o.file_id is not None:
176
                self.assertIsInstance(o.file_id, str)
177
178
            conflict_path = getattr(o, 'conflict_path', None)
179
            if conflict_path is not None:
180
                self.assertIsInstance(conflict_path, unicode)
181
182
            conflict_file_id = getattr(o, 'conflict_file_id', None)
183
            if conflict_file_id is not None:
184
                self.assertIsInstance(conflict_file_id, str)
185
186
    def test_stanzification(self):
187
        for stanza in example_conflicts.to_stanzas():
188
            if 'file_id' in stanza:
189
                # In Stanza form, the file_id has to be unicode.
190
                self.assertStartsWith(stanza['file_id'], u'\xeed')
191
            self.assertStartsWith(stanza['path'], u'p\xe5th')
192
            if 'conflict_path' in stanza:
193
                self.assertStartsWith(stanza['conflict_path'], u'p\xe5th')
194
            if 'conflict_file_id' in stanza:
195
                self.assertStartsWith(stanza['conflict_file_id'], u'\xeed')
196
197
4597.3.74 by Vincent Ladeuil
Add a FIXME about rewriting shell-like tests into real whitebox tests.
198
# FIXME: The shell-like tests should be converted to real whitebox tests... or
199
# moved to a blackbox module -- vila 20100205
200
4597.7.11 by Vincent Ladeuil
Fix #531967 by creating helpers for PathConflicts when a deletion
201
# FIXME: test missing for multiple conflicts
202
4597.3.31 by Vincent Ladeuil
Implement --interactive for MissingParent.
203
# FIXME: Tests missing for DuplicateID conflict type
4597.3.12 by Vincent Ladeuil
Start writing tests for all expected conflict resolution actions.
204
class TestResolveConflicts(script.TestCaseWithTransportAndScript):
205
206
    preamble = None # The setup script set by daughter classes
207
208
    def setUp(self):
209
        super(TestResolveConflicts, self).setUp()
210
        self.run_script(self.preamble)
211
212
213
class TestResolveTextConflicts(TestResolveConflicts):
214
    # TBC
215
    pass
216
217
4597.7.10 by Vincent Ladeuil
Define scenarios by test classes.
218
# FIXME: Get rid of parametrized (in the class name) once we delete
219
# TestResolveConflicts -- vila 20100308
4597.7.4 by Vincent Ladeuil
Abstract the test class some more to address more conflict
220
class TestParametrizedResolveConflicts(tests.TestCaseWithTransport):
4597.7.18 by Vincent Ladeuil
Start addressing Andrew's concerns.
221
    """This class provides a base to test single conflict resolution.
222
223
    The aim is to define scenarios in daughter classes (one for each conflict
224
    type) that create a single conflict object when one branch is merged in
225
    another (and vice versa). Each class can define as many scenarios as
226
    needed. Each scenario should define a couple of actions that will be
227
    swapped to define the sibling scenarios.
228
229
    From there, both resolutions are tested (--take-this and --take-other).
230
231
    Each conflict type use its attributes in a specific way, so each class 
232
    should define a specific _assert_conflict method.
233
234
    Since the resolution change the working tree state, each action should
235
    define an associated check.
236
    """
4597.2.23 by Vincent Ladeuil
Start translating blackbox tests into whitebox ones.
237
4597.7.16 by Vincent Ladeuil
Some cleanup.
238
    # Set by daughter classes
239
    _conflict_type = None
240
    _assert_conflict = None
241
4597.2.26 by Vincent Ladeuil
Fix bug #529968 by renaming the kept file on content conflicts.
242
    # Set by load_tests
4597.7.6 by Vincent Ladeuil
Cleanup TestParametrizedResolveConflicts some more.
243
    _base_actions = None
4597.7.4 by Vincent Ladeuil
Abstract the test class some more to address more conflict
244
    _this_actions = None
245
    _other_actions = None
4597.7.10 by Vincent Ladeuil
Define scenarios by test classes.
246
    _item_path = None
247
    _item_id = None
4597.7.7 by Vincent Ladeuil
Reproduce bug #531967 on various aspects.
248
249
    # Set by _this_actions and other_actions
4597.8.8 by Vincent Ladeuil
Exhibit bug #537956.
250
    # FIXME: rename them this_args and other_args so the tests can use them
251
    # more freely
4597.7.7 by Vincent Ladeuil
Reproduce bug #531967 on various aspects.
252
    _this_path = None
253
    _this_id = None
254
    _other_path = None
255
    _other_id = None
4597.2.25 by Vincent Ladeuil
Reproduce bug #529968.
256
4597.7.11 by Vincent Ladeuil
Fix #531967 by creating helpers for PathConflicts when a deletion
257
    @classmethod
4597.7.17 by Vincent Ladeuil
Add a scenario and activate the compatibility tests.
258
    def mirror_scenarios(klass, base_scenarios):
4597.7.10 by Vincent Ladeuil
Define scenarios by test classes.
259
        scenarios = []
260
        def adapt(d, side):
261
            """Modify dict to apply to the given side.
262
263
            'actions' key is turned into '_actions_this' if side is 'this' for
264
            example.
265
            """
266
            t = {}
267
            # Turn each key into _side_key
268
            for k,v in d.iteritems():
269
                t['_%s_%s' % (k, side)] = v
270
            return t
271
        # Each base scenario is duplicated switching the roles of 'this' and
272
        # 'other'
4597.7.17 by Vincent Ladeuil
Add a scenario and activate the compatibility tests.
273
        left = [l for l, r, c in base_scenarios]
274
        right = [r for l, r, c in base_scenarios]
275
        common = [c for l, r, c in base_scenarios]
276
        for (lname, ldict), (rname, rdict), common in zip(left, right, common):
277
            a = tests.multiply_scenarios([(lname, adapt(ldict, 'this'))],
278
                                         [(rname, adapt(rdict, 'other'))])
279
            b = tests.multiply_scenarios(
4597.7.11 by Vincent Ladeuil
Fix #531967 by creating helpers for PathConflicts when a deletion
280
                    [(rname, adapt(rdict, 'this'))],
4597.7.17 by Vincent Ladeuil
Add a scenario and activate the compatibility tests.
281
                    [(lname, adapt(ldict, 'other'))])
282
            # Inject the common parameters in all scenarios
283
            for name, d in a + b:
284
                d.update(common)
285
            scenarios.extend(a + b)
4597.7.10 by Vincent Ladeuil
Define scenarios by test classes.
286
        return scenarios
287
4597.7.11 by Vincent Ladeuil
Fix #531967 by creating helpers for PathConflicts when a deletion
288
    @classmethod
289
    def scenarios(klass):
4597.7.10 by Vincent Ladeuil
Define scenarios by test classes.
290
        # Only concrete classes return actual scenarios
291
        return []
292
4597.2.23 by Vincent Ladeuil
Start translating blackbox tests into whitebox ones.
293
    def setUp(self):
4597.7.4 by Vincent Ladeuil
Abstract the test class some more to address more conflict
294
        super(TestParametrizedResolveConflicts, self).setUp()
4597.2.23 by Vincent Ladeuil
Start translating blackbox tests into whitebox ones.
295
        builder = self.make_branch_builder('trunk')
296
        builder.start_series()
4597.7.6 by Vincent Ladeuil
Cleanup TestParametrizedResolveConflicts some more.
297
4597.2.23 by Vincent Ladeuil
Start translating blackbox tests into whitebox ones.
298
        # Create an empty trunk
299
        builder.build_snapshot('start', None, [
300
                ('add', ('', 'root-id', 'directory', ''))])
301
        # Add a minimal base content
4597.7.10 by Vincent Ladeuil
Define scenarios by test classes.
302
        _, _, actions_base = self._get_actions(self._actions_base)()
303
        builder.build_snapshot('base', ['start'], actions_base)
4597.2.23 by Vincent Ladeuil
Start translating blackbox tests into whitebox ones.
304
        # Modify the base content in branch
4597.7.7 by Vincent Ladeuil
Reproduce bug #531967 on various aspects.
305
        (self._other_path, self._other_id,
4597.7.10 by Vincent Ladeuil
Define scenarios by test classes.
306
         actions_other) = self._get_actions(self._actions_other)()
307
        builder.build_snapshot('other', ['base'], actions_other)
4597.2.23 by Vincent Ladeuil
Start translating blackbox tests into whitebox ones.
308
        # Modify the base content in trunk
4597.7.7 by Vincent Ladeuil
Reproduce bug #531967 on various aspects.
309
        (self._this_path, self._this_id,
4597.7.10 by Vincent Ladeuil
Define scenarios by test classes.
310
         actions_this) = self._get_actions(self._actions_this)()
311
        builder.build_snapshot('this', ['base'], actions_this)
4597.7.7 by Vincent Ladeuil
Reproduce bug #531967 on various aspects.
312
        # builder.get_branch() tip is now 'this'
4597.7.6 by Vincent Ladeuil
Cleanup TestParametrizedResolveConflicts some more.
313
4597.2.23 by Vincent Ladeuil
Start translating blackbox tests into whitebox ones.
314
        builder.finish_series()
315
        self.builder = builder
316
4597.2.26 by Vincent Ladeuil
Fix bug #529968 by renaming the kept file on content conflicts.
317
    def _get_actions(self, name):
318
        return getattr(self, 'do_%s' % name)
319
320
    def _get_check(self, name):
321
        return getattr(self, 'check_%s' % name)
322
4597.8.5 by Vincent Ladeuil
Replace DuplicateEntry blackbox tests by whitebox ones.
323
    def do_nothing(self):
324
        return (None, None, [])
325
4597.7.6 by Vincent Ladeuil
Cleanup TestParametrizedResolveConflicts some more.
326
    def do_create_file(self):
4597.7.7 by Vincent Ladeuil
Reproduce bug #531967 on various aspects.
327
        return ('file', 'file-id',
328
                [('add', ('file', 'file-id', 'file', 'trunk content\n'))])
4597.7.6 by Vincent Ladeuil
Cleanup TestParametrizedResolveConflicts some more.
329
4597.8.5 by Vincent Ladeuil
Replace DuplicateEntry blackbox tests by whitebox ones.
330
    def do_create_file_a(self):
331
        return ('file', 'file-a-id',
332
                [('add', ('file', 'file-a-id', 'file', 'file a content\n'))])
333
334
    def check_file_content_a(self):
335
        self.assertFileEqual('file a content\n', 'branch/file')
336
337
    def do_create_file_b(self):
338
        return ('file', 'file-b-id',
339
                [('add', ('file', 'file-b-id', 'file', 'file b content\n'))])
340
341
    def check_file_content_b(self):
342
        self.assertFileEqual('file b content\n', 'branch/file')
343
4597.7.6 by Vincent Ladeuil
Cleanup TestParametrizedResolveConflicts some more.
344
    def do_create_dir(self):
4597.7.7 by Vincent Ladeuil
Reproduce bug #531967 on various aspects.
345
        return ('dir', 'dir-id', [('add', ('dir', 'dir-id', 'directory', ''))])
4597.7.6 by Vincent Ladeuil
Cleanup TestParametrizedResolveConflicts some more.
346
4597.2.26 by Vincent Ladeuil
Fix bug #529968 by renaming the kept file on content conflicts.
347
    def do_modify_file(self):
4597.7.7 by Vincent Ladeuil
Reproduce bug #531967 on various aspects.
348
        return ('file', 'file-id',
349
                [('modify', ('file-id', 'trunk content\nmore content\n'))])
4597.2.26 by Vincent Ladeuil
Fix bug #529968 by renaming the kept file on content conflicts.
350
351
    def check_file_has_more_content(self):
352
        self.assertFileEqual('trunk content\nmore content\n', 'branch/file')
353
354
    def do_delete_file(self):
4597.7.7 by Vincent Ladeuil
Reproduce bug #531967 on various aspects.
355
        return ('file', 'file-id', [('unversion', 'file-id')])
4597.2.26 by Vincent Ladeuil
Fix bug #529968 by renaming the kept file on content conflicts.
356
357
    def check_file_doesnt_exist(self):
358
        self.failIfExists('branch/file')
359
4597.7.17 by Vincent Ladeuil
Add a scenario and activate the compatibility tests.
360
    def do_rename_file(self):
361
        return ('new-file', 'file-id', [('rename', ('file', 'new-file'))])
362
363
    def check_file_renamed(self):
364
        self.failIfExists('branch/file')
365
        self.failUnlessExists('branch/new-file')
366
4597.8.4 by Vincent Ladeuil
Delete PathConflict bloackbox tests.
367
    def do_rename_file2(self):
368
        return ('new-file2', 'file-id', [('rename', ('file', 'new-file2'))])
369
370
    def check_file_renamed2(self):
371
        self.failIfExists('branch/file')
372
        self.failUnlessExists('branch/new-file2')
373
4597.7.4 by Vincent Ladeuil
Abstract the test class some more to address more conflict
374
    def do_rename_dir(self):
4597.7.7 by Vincent Ladeuil
Reproduce bug #531967 on various aspects.
375
        return ('new-dir', 'dir-id', [('rename', ('dir', 'new-dir'))])
4597.7.4 by Vincent Ladeuil
Abstract the test class some more to address more conflict
376
377
    def check_dir_renamed(self):
378
        self.failIfExists('branch/dir')
379
        self.failUnlessExists('branch/new-dir')
380
4597.7.7 by Vincent Ladeuil
Reproduce bug #531967 on various aspects.
381
    def do_rename_dir2(self):
382
        return ('new-dir2', 'dir-id', [('rename', ('dir', 'new-dir2'))])
383
384
    def check_dir_renamed2(self):
385
        self.failIfExists('branch/dir')
386
        self.failUnlessExists('branch/new-dir2')
387
4597.7.4 by Vincent Ladeuil
Abstract the test class some more to address more conflict
388
    def do_delete_dir(self):
4597.7.7 by Vincent Ladeuil
Reproduce bug #531967 on various aspects.
389
        return ('<deleted>', 'dir-id', [('unversion', 'dir-id')])
4597.7.4 by Vincent Ladeuil
Abstract the test class some more to address more conflict
390
391
    def check_dir_doesnt_exist(self):
392
        self.failIfExists('branch/dir')
393
4597.2.24 by Vincent Ladeuil
Translate one more test.
394
    def _merge_other_into_this(self):
4597.2.23 by Vincent Ladeuil
Start translating blackbox tests into whitebox ones.
395
        b = self.builder.get_branch()
396
        wt = b.bzrdir.sprout('branch').open_workingtree()
397
        wt.merge_from_branch(b, 'other')
4597.2.24 by Vincent Ladeuil
Translate one more test.
398
        return wt
399
4597.8.7 by Vincent Ladeuil
Add whitebox tests for ParentLoop.
400
    def assertConflict(self, wt):
401
        confs = wt.conflicts()
402
        self.assertLength(1, confs)
403
        c = confs[0]
404
        self.assertIsInstance(c, self._conflict_type)
405
        self._assert_conflict(wt, c)
406
407
    def _get_resolve_path_arg(self, wt, action):
408
        return self._item_path
409
410
    def check_resolved(self, wt, action):
411
        path = self._get_resolve_path_arg(wt, action)
412
        conflicts.resolve(wt, [path], action=action)
413
        # Check that we don't have any conflicts nor unknown left
414
        self.assertLength(0, wt.conflicts())
415
        self.assertLength(0, list(wt.unknowns()))
416
4597.2.24 by Vincent Ladeuil
Translate one more test.
417
    def test_resolve_taking_this(self):
418
        wt = self._merge_other_into_this()
4597.7.7 by Vincent Ladeuil
Reproduce bug #531967 on various aspects.
419
        self.assertConflict(wt)
4597.8.7 by Vincent Ladeuil
Add whitebox tests for ParentLoop.
420
        self.check_resolved(wt, 'take_this')
4597.2.26 by Vincent Ladeuil
Fix bug #529968 by renaming the kept file on content conflicts.
421
        check_this = self._get_check(self._check_this)
422
        check_this()
4597.2.24 by Vincent Ladeuil
Translate one more test.
423
424
    def test_resolve_taking_other(self):
425
        wt = self._merge_other_into_this()
4597.7.7 by Vincent Ladeuil
Reproduce bug #531967 on various aspects.
426
        self.assertConflict(wt)
4597.8.7 by Vincent Ladeuil
Add whitebox tests for ParentLoop.
427
        self.check_resolved(wt, 'take_other')
4597.2.26 by Vincent Ladeuil
Fix bug #529968 by renaming the kept file on content conflicts.
428
        check_other = self._get_check(self._check_other)
429
        check_other()
4597.3.28 by Vincent Ladeuil
Implement --interactive for ContentsConflict.
430
4597.3.12 by Vincent Ladeuil
Start writing tests for all expected conflict resolution actions.
431
4597.7.10 by Vincent Ladeuil
Define scenarios by test classes.
432
class TestResolveContentsConflict(TestParametrizedResolveConflicts):
433
4597.7.16 by Vincent Ladeuil
Some cleanup.
434
    _conflict_type = conflicts.ContentsConflict,
4597.7.11 by Vincent Ladeuil
Fix #531967 by creating helpers for PathConflicts when a deletion
435
    @classmethod
436
    def scenarios(klass):
4597.7.10 by Vincent Ladeuil
Define scenarios by test classes.
437
        base_scenarios = [
438
            (('file_modified', dict(actions='modify_file',
439
                                   check='file_has_more_content')),
440
             ('file_deleted', dict(actions='delete_file',
4597.7.17 by Vincent Ladeuil
Add a scenario and activate the compatibility tests.
441
                                   check='file_doesnt_exist')),
4597.8.5 by Vincent Ladeuil
Replace DuplicateEntry blackbox tests by whitebox ones.
442
             dict(_actions_base='create_file', _item_path='file')),
4597.7.10 by Vincent Ladeuil
Define scenarios by test classes.
443
            ]
4597.7.17 by Vincent Ladeuil
Add a scenario and activate the compatibility tests.
444
        return klass.mirror_scenarios(base_scenarios)
4597.7.10 by Vincent Ladeuil
Define scenarios by test classes.
445
4597.7.17 by Vincent Ladeuil
Add a scenario and activate the compatibility tests.
446
    def assertContentsConflict(self, wt, c):
4597.7.10 by Vincent Ladeuil
Define scenarios by test classes.
447
        self.assertEqual(self._other_id, c.file_id)
448
        self.assertEqual(self._other_path, c.path)
4597.7.16 by Vincent Ladeuil
Some cleanup.
449
    _assert_conflict = assertContentsConflict
450
4597.7.10 by Vincent Ladeuil
Define scenarios by test classes.
451
452
453
class TestResolvePathConflict(TestParametrizedResolveConflicts):
454
4597.7.16 by Vincent Ladeuil
Some cleanup.
455
    _conflict_type = conflicts.PathConflict,
456
4597.7.11 by Vincent Ladeuil
Fix #531967 by creating helpers for PathConflicts when a deletion
457
    @classmethod
458
    def scenarios(klass):
4597.8.4 by Vincent Ladeuil
Delete PathConflict bloackbox tests.
459
        for_file = dict(_actions_base='create_file',
460
                  _item_path='new-file', _item_id='file-id',)
461
        for_dir = dict(_actions_base='create_dir',
4597.7.17 by Vincent Ladeuil
Add a scenario and activate the compatibility tests.
462
                        _item_path='new-dir', _item_id='dir-id',)
4597.7.10 by Vincent Ladeuil
Define scenarios by test classes.
463
        base_scenarios = [
4597.7.17 by Vincent Ladeuil
Add a scenario and activate the compatibility tests.
464
            (('file_renamed',
465
              dict(actions='rename_file', check='file_renamed')),
466
             ('file_deleted',
467
              dict(actions='delete_file', check='file_doesnt_exist')),
4597.8.4 by Vincent Ladeuil
Delete PathConflict bloackbox tests.
468
             for_file),
469
            (('file_renamed',
470
              dict(actions='rename_file', check='file_renamed')),
471
             ('file_renamed2',
472
              dict(actions='rename_file2', check='file_renamed2')),
473
             for_file),
4597.7.17 by Vincent Ladeuil
Add a scenario and activate the compatibility tests.
474
            (('dir_renamed',
475
              dict(actions='rename_dir', check='dir_renamed')),
476
             ('dir_deleted',
477
              dict(actions='delete_dir', check='dir_doesnt_exist')),
4597.8.4 by Vincent Ladeuil
Delete PathConflict bloackbox tests.
478
             for_dir),
4597.7.17 by Vincent Ladeuil
Add a scenario and activate the compatibility tests.
479
            (('dir_renamed',
480
              dict(actions='rename_dir', check='dir_renamed')),
481
             ('dir_renamed2',
482
              dict(actions='rename_dir2', check='dir_renamed2')),
4597.8.4 by Vincent Ladeuil
Delete PathConflict bloackbox tests.
483
             for_dir),
4597.7.17 by Vincent Ladeuil
Add a scenario and activate the compatibility tests.
484
        ]
485
        return klass.mirror_scenarios(base_scenarios)
486
487
    def do_delete_file(self):
488
        sup = super(TestResolvePathConflict, self).do_delete_file()
489
        # PathConflicts handle deletion differently and requires a special
490
        # hard-coded value
491
        return ('<deleted>',) + sup[1:]
492
493
    def assertPathConflict(self, wt, c):
4597.7.10 by Vincent Ladeuil
Define scenarios by test classes.
494
        self.assertEqual(self._item_id, c.file_id)
495
        self.assertEqual(self._this_path, c.path)
496
        self.assertEqual(self._other_path, c.conflict_path)
4597.7.16 by Vincent Ladeuil
Some cleanup.
497
    _assert_conflict = assertPathConflict
4597.7.10 by Vincent Ladeuil
Define scenarios by test classes.
498
499
4597.7.17 by Vincent Ladeuil
Add a scenario and activate the compatibility tests.
500
class TestResolvePathConflictBefore531967(TestResolvePathConflict):
4597.7.10 by Vincent Ladeuil
Define scenarios by test classes.
501
    """Same as TestResolvePathConflict but a specific conflict object.
502
    """
503
4597.7.16 by Vincent Ladeuil
Some cleanup.
504
    def assertPathConflict(self, c):
4597.7.17 by Vincent Ladeuil
Add a scenario and activate the compatibility tests.
505
        # We create a conflict object as it was created before the fix and
506
        # inject it into the working tree, the test will exercise the
507
        # compatibility code.
508
        old_c = conflicts.PathConflict('<deleted>', self._item_path,
509
                                       file_id=None)
4597.7.18 by Vincent Ladeuil
Start addressing Andrew's concerns.
510
        wt.set_conflicts(conflicts.ConflictList([old_c]))
4597.7.10 by Vincent Ladeuil
Define scenarios by test classes.
511
512
4597.8.5 by Vincent Ladeuil
Replace DuplicateEntry blackbox tests by whitebox ones.
513
class TestResolveDuplicateEntry(TestParametrizedResolveConflicts):
514
515
    _conflict_type = conflicts.DuplicateEntry,
516
    @classmethod
517
    def scenarios(klass):
518
        base_scenarios = [
519
            (('filea_created', dict(actions='create_file_a',
520
                                    check='file_content_a')),
521
             ('fileb_created', dict(actions='create_file_b',
522
                                   check='file_content_b')),
4597.8.6 by Vincent Ladeuil
More precise test.
523
             dict(_actions_base='nothing', _item_path='file')),
4597.8.5 by Vincent Ladeuil
Replace DuplicateEntry blackbox tests by whitebox ones.
524
            ]
525
        return klass.mirror_scenarios(base_scenarios)
526
527
    def assertDuplicateEntry(self, wt, c):
528
        self.assertEqual(self._this_id, c.file_id)
4597.8.6 by Vincent Ladeuil
More precise test.
529
        self.assertEqual(self._item_path + '.moved', c.path)
530
        self.assertEqual(self._item_path, c.conflict_path)
4597.8.5 by Vincent Ladeuil
Replace DuplicateEntry blackbox tests by whitebox ones.
531
    _assert_conflict = assertDuplicateEntry
4597.3.19 by Vincent Ladeuil
Some failing tests.
532
4597.3.12 by Vincent Ladeuil
Start writing tests for all expected conflict resolution actions.
533
534
class TestResolveUnversionedParent(TestResolveConflicts):
535
4597.3.29 by Vincent Ladeuil
Fix bogus tests.
536
    # FIXME: Add the reverse tests: dir deleted in trunk, file added in branch
537
4597.3.30 by Vincent Ladeuil
Light changes learned while starting to understand multiple conflicts on
538
    # FIXME: While this *creates* UnversionedParent conflicts, this really only
539
    # tests MissingParent resolution :-/
4597.3.12 by Vincent Ladeuil
Start writing tests for all expected conflict resolution actions.
540
    preamble = """
4597.3.15 by Vincent Ladeuil
Update to new shell-like tests syntax.
541
$ bzr init trunk
542
$ cd trunk
4597.3.29 by Vincent Ladeuil
Fix bogus tests.
543
$ mkdir dir
544
$ bzr add dir
4597.3.15 by Vincent Ladeuil
Update to new shell-like tests syntax.
545
$ bzr commit -m 'Create trunk'
4597.2.23 by Vincent Ladeuil
Start translating blackbox tests into whitebox ones.
546
4597.3.29 by Vincent Ladeuil
Fix bogus tests.
547
$ echo 'trunk content' >dir/file
548
$ bzr add dir/file
549
$ bzr commit -m 'Add dir/file in trunk'
4597.3.15 by Vincent Ladeuil
Update to new shell-like tests syntax.
550
551
$ bzr branch . -r 1 ../branch
552
$ cd ../branch
4597.3.29 by Vincent Ladeuil
Fix bogus tests.
553
$ bzr rm dir
554
$ bzr commit -m 'Remove dir in branch'
4597.3.15 by Vincent Ladeuil
Update to new shell-like tests syntax.
555
556
$ bzr merge ../trunk
4597.3.29 by Vincent Ladeuil
Fix bogus tests.
557
2>+N  dir/
558
2>+N  dir/file
559
2>Conflict adding files to dir.  Created directory.
560
2>Conflict because dir is not versioned, but has versioned children.  Versioned directory.
561
2>2 conflicts encountered.
4597.3.12 by Vincent Ladeuil
Start writing tests for all expected conflict resolution actions.
562
"""
563
4597.3.67 by Vincent Ladeuil
Settle with --take-this and --take-other as action names.
564
    def test_take_this(self):
4597.3.12 by Vincent Ladeuil
Start writing tests for all expected conflict resolution actions.
565
        self.run_script("""
4597.3.29 by Vincent Ladeuil
Fix bogus tests.
566
$ bzr rm dir  --force
567
$ bzr resolve dir
4597.3.15 by Vincent Ladeuil
Update to new shell-like tests syntax.
568
$ bzr commit --strict -m 'No more conflicts nor unknown files'
4597.3.12 by Vincent Ladeuil
Start writing tests for all expected conflict resolution actions.
569
""")
570
4597.3.67 by Vincent Ladeuil
Settle with --take-this and --take-other as action names.
571
    def test_take_other(self):
4597.3.12 by Vincent Ladeuil
Start writing tests for all expected conflict resolution actions.
572
        self.run_script("""
4597.3.29 by Vincent Ladeuil
Fix bogus tests.
573
$ bzr resolve dir
4597.3.15 by Vincent Ladeuil
Update to new shell-like tests syntax.
574
$ bzr commit --strict -m 'No more conflicts nor unknown files'
4597.3.12 by Vincent Ladeuil
Start writing tests for all expected conflict resolution actions.
575
""")
576
577
578
class TestResolveMissingParent(TestResolveConflicts):
579
580
    preamble = """
4597.3.15 by Vincent Ladeuil
Update to new shell-like tests syntax.
581
$ bzr init trunk
582
$ cd trunk
583
$ mkdir dir
584
$ echo 'trunk content' >dir/file
585
$ bzr add
586
$ bzr commit -m 'Create trunk'
4597.2.23 by Vincent Ladeuil
Start translating blackbox tests into whitebox ones.
587
4597.3.15 by Vincent Ladeuil
Update to new shell-like tests syntax.
588
$ echo 'trunk content' >dir/file2
589
$ bzr add dir/file2
590
$ bzr commit -m 'Add dir/file2 in branch'
591
592
$ bzr branch . -r 1 ../branch
593
$ cd ../branch
594
$ bzr rm dir/file --force
595
$ bzr rm dir
596
$ bzr commit -m 'Remove dir/file'
597
598
$ bzr merge ../trunk
4597.3.12 by Vincent Ladeuil
Start writing tests for all expected conflict resolution actions.
599
2>+N  dir/
600
2>+N  dir/file2
601
2>Conflict adding files to dir.  Created directory.
602
2>Conflict because dir is not versioned, but has versioned children.  Versioned directory.
603
2>2 conflicts encountered.
604
"""
605
606
    def test_keep_them_all(self):
607
        self.run_script("""
4597.3.15 by Vincent Ladeuil
Update to new shell-like tests syntax.
608
$ bzr resolve dir
609
$ bzr commit --strict -m 'No more conflicts nor unknown files'
4597.3.12 by Vincent Ladeuil
Start writing tests for all expected conflict resolution actions.
610
""")
611
612
    def test_adopt_child(self):
613
        self.run_script("""
4597.3.15 by Vincent Ladeuil
Update to new shell-like tests syntax.
614
$ bzr mv dir/file2 file2
615
$ bzr rm dir --force
616
$ bzr resolve dir
617
$ bzr commit --strict -m 'No more conflicts nor unknown files'
4597.3.12 by Vincent Ladeuil
Start writing tests for all expected conflict resolution actions.
618
""")
619
620
    def test_kill_them_all(self):
621
        self.run_script("""
4597.3.15 by Vincent Ladeuil
Update to new shell-like tests syntax.
622
$ bzr rm dir --force
623
$ bzr resolve dir
624
$ bzr commit --strict -m 'No more conflicts nor unknown files'
4597.3.12 by Vincent Ladeuil
Start writing tests for all expected conflict resolution actions.
625
""")
626
4597.3.67 by Vincent Ladeuil
Settle with --take-this and --take-other as action names.
627
    def test_resolve_taking_this(self):
4597.3.31 by Vincent Ladeuil
Implement --interactive for MissingParent.
628
        self.run_script("""
4597.3.67 by Vincent Ladeuil
Settle with --take-this and --take-other as action names.
629
$ bzr resolve --take-this dir
4597.3.31 by Vincent Ladeuil
Implement --interactive for MissingParent.
630
$ bzr commit --strict -m 'No more conflicts nor unknown files'
631
""")
632
4597.3.67 by Vincent Ladeuil
Settle with --take-this and --take-other as action names.
633
    def test_resolve_taking_other(self):
4597.3.31 by Vincent Ladeuil
Implement --interactive for MissingParent.
634
        self.run_script("""
4597.3.67 by Vincent Ladeuil
Settle with --take-this and --take-other as action names.
635
$ bzr resolve --take-other dir
4597.3.31 by Vincent Ladeuil
Implement --interactive for MissingParent.
636
$ bzr commit --strict -m 'No more conflicts nor unknown files'
637
""")
638
4597.3.12 by Vincent Ladeuil
Start writing tests for all expected conflict resolution actions.
639
640
class TestResolveDeletingParent(TestResolveConflicts):
641
642
    preamble = """
4597.3.15 by Vincent Ladeuil
Update to new shell-like tests syntax.
643
$ bzr init trunk
644
$ cd trunk
645
$ mkdir dir
646
$ echo 'trunk content' >dir/file
647
$ bzr add
648
$ bzr commit -m 'Create trunk'
4597.2.23 by Vincent Ladeuil
Start translating blackbox tests into whitebox ones.
649
4597.3.15 by Vincent Ladeuil
Update to new shell-like tests syntax.
650
$ bzr rm dir/file --force
651
$ bzr rm dir --force
652
$ bzr commit -m 'Remove dir/file'
653
654
$ bzr branch . -r 1 ../branch
655
$ cd ../branch
656
$ echo 'branch content' >dir/file2
657
$ bzr add dir/file2
658
$ bzr commit -m 'Add dir/file2 in branch'
659
660
$ bzr merge ../trunk
4597.3.12 by Vincent Ladeuil
Start writing tests for all expected conflict resolution actions.
661
2>-D  dir/file
662
2>Conflict: can't delete dir because it is not empty.  Not deleting.
663
2>Conflict because dir is not versioned, but has versioned children.  Versioned directory.
664
2>2 conflicts encountered.
665
"""
666
667
    def test_keep_them_all(self):
668
        self.run_script("""
4597.3.15 by Vincent Ladeuil
Update to new shell-like tests syntax.
669
$ bzr resolve dir
670
$ bzr commit --strict -m 'No more conflicts nor unknown files'
4597.3.12 by Vincent Ladeuil
Start writing tests for all expected conflict resolution actions.
671
""")
672
673
    def test_adopt_child(self):
674
        self.run_script("""
4597.3.15 by Vincent Ladeuil
Update to new shell-like tests syntax.
675
$ bzr mv dir/file2 file2
676
$ bzr rm dir --force
677
$ bzr resolve dir
678
$ bzr commit --strict -m 'No more conflicts nor unknown files'
4597.3.12 by Vincent Ladeuil
Start writing tests for all expected conflict resolution actions.
679
""")
680
681
    def test_kill_them_all(self):
682
        self.run_script("""
4597.3.15 by Vincent Ladeuil
Update to new shell-like tests syntax.
683
$ bzr rm dir --force
684
$ bzr resolve dir
685
$ bzr commit --strict -m 'No more conflicts nor unknown files'
4597.3.12 by Vincent Ladeuil
Start writing tests for all expected conflict resolution actions.
686
""")
687
4597.3.67 by Vincent Ladeuil
Settle with --take-this and --take-other as action names.
688
    def test_resolve_taking_this(self):
4597.3.32 by Vincent Ladeuil
Implement --interactive for DeletingParent noting the inconsistency.
689
        self.run_script("""
4597.3.67 by Vincent Ladeuil
Settle with --take-this and --take-other as action names.
690
$ bzr resolve --take-this dir
4597.3.32 by Vincent Ladeuil
Implement --interactive for DeletingParent noting the inconsistency.
691
$ bzr commit --strict -m 'No more conflicts nor unknown files'
692
""")
693
4597.3.67 by Vincent Ladeuil
Settle with --take-this and --take-other as action names.
694
    def test_resolve_taking_other(self):
4597.3.32 by Vincent Ladeuil
Implement --interactive for DeletingParent noting the inconsistency.
695
        self.run_script("""
4597.3.67 by Vincent Ladeuil
Settle with --take-this and --take-other as action names.
696
$ bzr resolve --take-other dir
4597.3.32 by Vincent Ladeuil
Implement --interactive for DeletingParent noting the inconsistency.
697
$ bzr commit --strict -m 'No more conflicts nor unknown files'
698
""")
699
4597.3.12 by Vincent Ladeuil
Start writing tests for all expected conflict resolution actions.
700
4597.8.7 by Vincent Ladeuil
Add whitebox tests for ParentLoop.
701
class TestResolveParentLoop(TestParametrizedResolveConflicts):
702
703
    _conflict_type = conflicts.ParentLoop,
704
    @classmethod
705
    def scenarios(klass):
706
        base_scenarios = [
4597.8.8 by Vincent Ladeuil
Exhibit bug #537956.
707
            (('dir1_into_dir2', dict(actions='move_dir1_into_dir2',
4597.8.7 by Vincent Ladeuil
Add whitebox tests for ParentLoop.
708
                                      check='dir1_moved')),
4597.8.8 by Vincent Ladeuil
Exhibit bug #537956.
709
             ('dir2_into_dir1', dict(actions='move_dir2_into_dir1',
4597.8.7 by Vincent Ladeuil
Add whitebox tests for ParentLoop.
710
                                      check='dir2_moved')),
711
             dict(_actions_base='create_dir1_dir2')),
4597.8.8 by Vincent Ladeuil
Exhibit bug #537956.
712
            (('dir1_into_dir4', dict(actions='move_dir1_into_dir4',
713
                                      check='dir1_2_moved')),
714
             ('dir3_into_dir2', dict(actions='move_dir3_into_dir2',
715
                                      check='dir3_4_moved')),
716
             dict(_actions_base='create_dir1_4')),
4597.8.7 by Vincent Ladeuil
Add whitebox tests for ParentLoop.
717
            ]
718
        return klass.mirror_scenarios(base_scenarios)
719
720
    def do_create_dir1_dir2(self):
721
        return (None, None,
722
                [('add', ('dir1', 'dir1-id', 'directory', '')),
4597.8.8 by Vincent Ladeuil
Exhibit bug #537956.
723
                 ('add', ('dir2', 'dir2-id', 'directory', '')),
724
                 ])
4597.8.7 by Vincent Ladeuil
Add whitebox tests for ParentLoop.
725
4597.8.8 by Vincent Ladeuil
Exhibit bug #537956.
726
    def do_move_dir1_into_dir2(self):
727
        # The arguments are the file-id to move and the targeted file-id dir.
728
        return ('dir1-id', 'dir2-id', [('rename', ('dir1', 'dir2/dir1'))])
4597.8.7 by Vincent Ladeuil
Add whitebox tests for ParentLoop.
729
730
    def check_dir1_moved(self):
731
        self.failIfExists('branch/dir1')
732
        self.failUnlessExists('branch/dir2/dir1')
733
4597.8.8 by Vincent Ladeuil
Exhibit bug #537956.
734
    def do_move_dir2_into_dir1(self):
735
        # The arguments are the file-id to move and the targeted file-id dir.
736
        return ('dir2-id', 'dir1-id', [('rename', ('dir2', 'dir1/dir2'))])
4597.8.7 by Vincent Ladeuil
Add whitebox tests for ParentLoop.
737
738
    def check_dir2_moved(self):
739
        self.failIfExists('branch/dir2')
740
        self.failUnlessExists('branch/dir1/dir2')
741
4597.8.8 by Vincent Ladeuil
Exhibit bug #537956.
742
    def do_create_dir1_4(self):
743
        return (None, None,
744
                [('add', ('dir1', 'dir1-id', 'directory', '')),
745
                 ('add', ('dir1/dir2', 'dir2-id', 'directory', '')),
746
                 ('add', ('dir3', 'dir3-id', 'directory', '')),
747
                 ('add', ('dir3/dir4', 'dir4-id', 'directory', '')),
748
                 ])
749
750
    def do_move_dir1_into_dir4(self):
751
        # The arguments are the file-id to move and the targeted file-id dir.
752
        return ('dir1-id', 'dir4-id',
753
                [('rename', ('dir1', 'dir3/dir4/dir1'))])
754
755
    def check_dir1_2_moved(self):
756
        self.failIfExists('branch/dir1')
757
        self.failUnlessExists('branch/dir3/dir4/dir1')
758
        self.failUnlessExists('branch/dir3/dir4/dir1/dir2')
759
760
    def do_move_dir3_into_dir2(self):
761
        # The arguments are the file-id to move and the targeted file-id dir.
762
        return ('dir3-id', 'dir2-id',
763
                [('rename', ('dir3', 'dir1/dir2/dir3'))])
764
765
    def check_dir3_4_moved(self):
766
        self.failIfExists('branch/dir3')
767
        self.failUnlessExists('branch/dir1/dir2/dir3')
768
        self.failUnlessExists('branch/dir1/dir2/dir3/dir4')
769
4597.8.7 by Vincent Ladeuil
Add whitebox tests for ParentLoop.
770
    def _get_resolve_path_arg(self, wt, action):
771
        # ParentLoop is unsual as it says: 
772
        # moving <conflict_path> into <path>.  Cancelled move.
773
        # But since <path> doesn't exist in the working tree, we need to use
774
        # <conflict_path> instead
4597.8.8 by Vincent Ladeuil
Exhibit bug #537956.
775
        path = wt.id2path(self._other_id)
4597.8.7 by Vincent Ladeuil
Add whitebox tests for ParentLoop.
776
        return path
777
778
    def assertParentLoop(self, wt, c):
4597.8.9 by Vincent Ladeuil
Mark the expected failing tests as such.
779
        if 'taking_other(' in self.id() and 'dir4' in self.id():
780
            raise tests.KnownFailure(
781
                "ParentLoop doesn't carry enough info to resolve")
4597.8.8 by Vincent Ladeuil
Exhibit bug #537956.
782
        # The relevant file-ids are other_args swapped (which is the main
783
        # reason why they should be renamed other_args instead of Other_path
784
        # and other_id). In the conflict object, they represent:
785
        # c.file_id: the directory being moved
786
        # c.conflict_id_id: The target directory
787
        self.assertEqual(self._other_path, c.file_id)
4597.8.7 by Vincent Ladeuil
Add whitebox tests for ParentLoop.
788
        self.assertEqual(self._other_id, c.conflict_file_id)
4597.8.8 by Vincent Ladeuil
Exhibit bug #537956.
789
        # The conflict paths are irrelevant (they are deterministic but not
790
        # worth checking since they don't provide the needed information
791
        # anyway)
4597.8.7 by Vincent Ladeuil
Add whitebox tests for ParentLoop.
792
    _assert_conflict = assertParentLoop
793
794
795
class OldTestResolveParentLoop(TestResolveConflicts):
4597.3.12 by Vincent Ladeuil
Start writing tests for all expected conflict resolution actions.
796
797
    preamble = """
4597.3.15 by Vincent Ladeuil
Update to new shell-like tests syntax.
798
$ bzr init trunk
799
$ cd trunk
800
$ bzr mkdir dir1
801
$ bzr mkdir dir2
802
$ bzr commit -m 'Create trunk'
4597.2.23 by Vincent Ladeuil
Start translating blackbox tests into whitebox ones.
803
4597.3.15 by Vincent Ladeuil
Update to new shell-like tests syntax.
804
$ bzr mv dir2 dir1
805
$ bzr commit -m 'Moved dir2 into dir1'
806
807
$ bzr branch . -r 1 ../branch
808
$ cd ../branch
809
$ bzr mv dir1 dir2
810
$ bzr commit -m 'Moved dir1 into dir2'
811
812
$ bzr merge ../trunk
4597.8.11 by Vincent Ladeuil
The ParentLoop.format has been updated, fix fallouts.
813
2>Conflict moving dir2 into dir2/dir1. Cancelled move.
4597.3.12 by Vincent Ladeuil
Start writing tests for all expected conflict resolution actions.
814
2>1 conflicts encountered.
815
"""
816
4597.3.67 by Vincent Ladeuil
Settle with --take-this and --take-other as action names.
817
    def test_take_this(self):
4597.3.12 by Vincent Ladeuil
Start writing tests for all expected conflict resolution actions.
818
        self.run_script("""
4597.3.15 by Vincent Ladeuil
Update to new shell-like tests syntax.
819
$ bzr resolve dir2
820
$ bzr commit --strict -m 'No more conflicts nor unknown files'
4597.3.12 by Vincent Ladeuil
Start writing tests for all expected conflict resolution actions.
821
""")
822
4597.3.67 by Vincent Ladeuil
Settle with --take-this and --take-other as action names.
823
    def test_take_other(self):
4597.3.12 by Vincent Ladeuil
Start writing tests for all expected conflict resolution actions.
824
        self.run_script("""
4597.3.15 by Vincent Ladeuil
Update to new shell-like tests syntax.
825
$ bzr mv dir2/dir1 dir1
826
$ bzr mv dir2 dir1
827
$ bzr resolve dir2
828
$ bzr commit --strict -m 'No more conflicts nor unknown files'
4597.3.12 by Vincent Ladeuil
Start writing tests for all expected conflict resolution actions.
829
""")
830
4597.3.67 by Vincent Ladeuil
Settle with --take-this and --take-other as action names.
831
    def test_resolve_taking_this(self):
4597.3.34 by Vincent Ladeuil
Implement --interactive for ParentLoop.
832
        self.run_script("""
4597.3.67 by Vincent Ladeuil
Settle with --take-this and --take-other as action names.
833
$ bzr resolve --take-this dir2
4597.3.34 by Vincent Ladeuil
Implement --interactive for ParentLoop.
834
$ bzr commit --strict -m 'No more conflicts nor unknown files'
835
""")
4597.3.64 by Vincent Ladeuil
Fixed as per Aaron's remark.
836
        self.failUnlessExists('dir2')
4597.3.34 by Vincent Ladeuil
Implement --interactive for ParentLoop.
837
4597.3.67 by Vincent Ladeuil
Settle with --take-this and --take-other as action names.
838
    def test_resolve_taking_other(self):
4597.3.34 by Vincent Ladeuil
Implement --interactive for ParentLoop.
839
        self.run_script("""
4597.3.67 by Vincent Ladeuil
Settle with --take-this and --take-other as action names.
840
$ bzr resolve --take-other dir2
4597.3.34 by Vincent Ladeuil
Implement --interactive for ParentLoop.
841
$ bzr commit --strict -m 'No more conflicts nor unknown files'
842
""")
4597.3.64 by Vincent Ladeuil
Fixed as per Aaron's remark.
843
        self.failUnlessExists('dir1')
4597.3.34 by Vincent Ladeuil
Implement --interactive for ParentLoop.
844
4597.3.12 by Vincent Ladeuil
Start writing tests for all expected conflict resolution actions.
845
846
class TestResolveNonDirectoryParent(TestResolveConflicts):
847
848
    preamble = """
4597.3.15 by Vincent Ladeuil
Update to new shell-like tests syntax.
849
$ bzr init trunk
850
$ cd trunk
851
$ bzr mkdir foo
852
$ bzr commit -m 'Create trunk'
853
$ echo "Boing" >foo/bar
854
$ bzr add foo/bar
855
$ bzr commit -m 'Add foo/bar'
856
857
$ bzr branch . -r 1 ../branch
858
$ cd ../branch
859
$ rm -r foo
860
$ echo "Boo!" >foo
861
$ bzr commit -m 'foo is now a file'
862
863
$ bzr merge ../trunk
4597.3.12 by Vincent Ladeuil
Start writing tests for all expected conflict resolution actions.
864
2>+N  foo.new/bar
865
2>RK  foo => foo.new/
866
# FIXME: The message is misleading, foo.new *is* a directory when the message
867
# is displayed -- vila 090916
868
2>Conflict: foo.new is not a directory, but has files in it.  Created directory.
869
2>1 conflicts encountered.
870
"""
871
4597.3.67 by Vincent Ladeuil
Settle with --take-this and --take-other as action names.
872
    def test_take_this(self):
4597.3.12 by Vincent Ladeuil
Start writing tests for all expected conflict resolution actions.
873
        self.run_script("""
4597.3.15 by Vincent Ladeuil
Update to new shell-like tests syntax.
874
$ bzr rm foo.new --force
4597.3.12 by Vincent Ladeuil
Start writing tests for all expected conflict resolution actions.
875
# FIXME: Isn't it weird that foo is now unkown even if foo.new has been put
876
# aside ? -- vila 090916
4597.3.15 by Vincent Ladeuil
Update to new shell-like tests syntax.
877
$ bzr add foo
878
$ bzr resolve foo.new
879
$ bzr commit --strict -m 'No more conflicts nor unknown files'
4597.3.12 by Vincent Ladeuil
Start writing tests for all expected conflict resolution actions.
880
""")
881
4597.3.67 by Vincent Ladeuil
Settle with --take-this and --take-other as action names.
882
    def test_take_other(self):
4597.3.35 by Vincent Ladeuil
Implement --interactive for NonDirectoryParent, sort of.
883
        self.run_script("""
884
$ bzr rm foo --force
885
$ bzr mv foo.new foo
886
$ bzr resolve foo
887
$ bzr commit --strict -m 'No more conflicts nor unknown files'
888
""")
889
4597.3.67 by Vincent Ladeuil
Settle with --take-this and --take-other as action names.
890
    def test_resolve_taking_this(self):
4597.3.35 by Vincent Ladeuil
Implement --interactive for NonDirectoryParent, sort of.
891
        self.run_script("""
4597.3.67 by Vincent Ladeuil
Settle with --take-this and --take-other as action names.
892
$ bzr resolve --take-this foo.new
4597.3.35 by Vincent Ladeuil
Implement --interactive for NonDirectoryParent, sort of.
893
$ bzr commit --strict -m 'No more conflicts nor unknown files'
894
""")
895
4597.3.67 by Vincent Ladeuil
Settle with --take-this and --take-other as action names.
896
    def test_resolve_taking_other(self):
4597.3.35 by Vincent Ladeuil
Implement --interactive for NonDirectoryParent, sort of.
897
        self.run_script("""
4597.3.67 by Vincent Ladeuil
Settle with --take-this and --take-other as action names.
898
$ bzr resolve --take-other foo.new
4597.3.35 by Vincent Ladeuil
Implement --interactive for NonDirectoryParent, sort of.
899
$ bzr commit --strict -m 'No more conflicts nor unknown files'
900
""")
901
4597.3.12 by Vincent Ladeuil
Start writing tests for all expected conflict resolution actions.
902
903
class TestMalformedTransform(script.TestCaseWithTransportAndScript):
904
905
    def test_bug_430129(self):
906
        # This is nearly like TestResolveNonDirectoryParent but with branch and
907
        # trunk switched. As such it should certainly produce the same
908
        # conflict.
909
        self.run_script("""
4597.3.15 by Vincent Ladeuil
Update to new shell-like tests syntax.
910
$ bzr init trunk
911
$ cd trunk
912
$ bzr mkdir foo
913
$ bzr commit -m 'Create trunk'
914
$ rm -r foo
915
$ echo "Boo!" >foo
916
$ bzr commit -m 'foo is now a file'
917
918
$ bzr branch . -r 1 ../branch
919
$ cd ../branch
920
$ echo "Boing" >foo/bar
921
$ bzr add foo/bar
922
$ bzr commit -m 'Add foo/bar'
923
924
$ bzr merge ../trunk
4597.3.12 by Vincent Ladeuil
Start writing tests for all expected conflict resolution actions.
925
2>bzr: ERROR: Tree transform is malformed [('unversioned executability', 'new-1')]
926
""")
4597.3.51 by Vincent Ladeuil
Implement conflicts.ResolveActionOption.
927
928
929
class TestResolveActionOption(tests.TestCase):
930
931
    def setUp(self):
932
        super(TestResolveActionOption, self).setUp()
933
        self.options = [conflicts.ResolveActionOption()]
934
        self.parser = option.get_optparser(dict((o.name, o)
935
                                                for o in self.options))
936
937
    def parse(self, args):
938
        return self.parser.parse_args(args)
939
940
    def test_unknown_action(self):
941
        self.assertRaises(errors.BadOptionValue,
942
                          self.parse, ['--action', 'take-me-to-the-moon'])
943
944
    def test_done(self):
945
        opts, args = self.parse(['--action', 'done'])
946
        self.assertEqual({'action':'done'}, opts)
947
4597.3.67 by Vincent Ladeuil
Settle with --take-this and --take-other as action names.
948
    def test_take_this(self):
949
        opts, args = self.parse(['--action', 'take-this'])
950
        self.assertEqual({'action': 'take_this'}, opts)
951
        opts, args = self.parse(['--take-this'])
952
        self.assertEqual({'action': 'take_this'}, opts)
4597.3.51 by Vincent Ladeuil
Implement conflicts.ResolveActionOption.
953
4597.3.67 by Vincent Ladeuil
Settle with --take-this and --take-other as action names.
954
    def test_take_other(self):
955
        opts, args = self.parse(['--action', 'take-other'])
956
        self.assertEqual({'action': 'take_other'}, opts)
957
        opts, args = self.parse(['--take-other'])
958
        self.assertEqual({'action': 'take_other'}, opts)