~bzr-pqm/bzr/bzr.dev

5557.1.7 by John Arbash Meinel
Merge in the bzr.dev 5582
1
# Copyright (C) 2005-2011 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,
4597.3.51 by Vincent Ladeuil
Implement conflicts.ResolveActionOption.
24
    option,
5609.17.1 by Vincent Ladeuil
Reproduce bug #715068.
25
    osutils,
4597.2.2 by Vincent Ladeuil
Cleanup conflict tests.
26
    tests,
27
    )
4597.13.3 by Vincent Ladeuil
Switch to load_tests_apply_scenarios.
28
from bzrlib.tests import (
29
    script,
30
    scenarios,
31
    )
32
33
34
load_tests = scenarios.load_tests_apply_scenarios
4597.2.26 by Vincent Ladeuil
Fix bug #529968 by renaming the kept file on content conflicts.
35
36
1185.14.8 by Aaron Bentley
Added test_commit.py
37
# 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.
38
# RBC 20060124 is that not tested in test_commit.py ?
1185.14.8 by Aaron Bentley
Added test_commit.py
39
1666.1.4 by Robert Collins
* 'Metadir' is now the default disk format. This improves behaviour in
40
# The order of 'path' here is important - do not let it
41
# 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.
42
# u'\xe5' == a with circle
43
# '\xc3\xae' == u'\xee' == i with hat
4597.2.2 by Vincent Ladeuil
Cleanup conflict tests.
44
# So these are u'path' and 'id' only with a circle and a hat. (shappo?)
45
example_conflicts = conflicts.ConflictList(
46
    [conflicts.MissingParent('Not deleting', u'p\xe5thg', '\xc3\xaedg'),
47
     conflicts.ContentsConflict(u'p\xe5tha', None, '\xc3\xaeda'),
48
     conflicts.TextConflict(u'p\xe5tha'),
49
     conflicts.PathConflict(u'p\xe5thb', u'p\xe5thc', '\xc3\xaedb'),
50
     conflicts.DuplicateID('Unversioned existing file',
51
                           u'p\xe5thc', u'p\xe5thc2',
52
                           '\xc3\xaedc', '\xc3\xaedc'),
53
    conflicts.DuplicateEntry('Moved existing file to',
54
                             u'p\xe5thdd.moved', u'p\xe5thd',
55
                             '\xc3\xaedd', None),
56
    conflicts.ParentLoop('Cancelled move', u'p\xe5the', u'p\xe5th2e',
57
                         None, '\xc3\xaed2e'),
58
    conflicts.UnversionedParent('Versioned directory',
59
                                u'p\xe5thf', '\xc3\xaedf'),
60
    conflicts.NonDirectoryParent('Created directory',
61
                                 u'p\xe5thg', '\xc3\xaedg'),
1534.10.22 by Aaron Bentley
Got ConflictList implemented
62
])
1534.10.4 by Aaron Bentley
Implemented conflict serialization
63
64
5898.1.1 by Martin
Refactor conflict stanzas tests to use scenarios
65
def vary_by_conflicts():
66
    for conflict in example_conflicts:
67
        yield (conflict.__class__.__name__, {"conflict": conflict})
68
69
4597.2.2 by Vincent Ladeuil
Cleanup conflict tests.
70
class TestConflicts(tests.TestCaseWithTransport):
1185.14.8 by Aaron Bentley
Added test_commit.py
71
1558.12.9 by Aaron Bentley
Handle resolving conflicts with directories properly
72
    def test_resolve_conflict_dir(self):
73
        tree = self.make_branch_and_tree('.')
4597.2.3 by Vincent Ladeuil
More cleanup.
74
        self.build_tree_contents([('hello', 'hello world4'),
75
                                  ('hello.THIS', 'hello world2'),
76
                                  ('hello.BASE', 'hello world1'),
77
                                  ])
78
        os.mkdir('hello.OTHER')
1558.12.9 by Aaron Bentley
Handle resolving conflicts with directories properly
79
        tree.add('hello', 'q')
4597.2.3 by Vincent Ladeuil
More cleanup.
80
        l = conflicts.ConflictList([conflicts.TextConflict('hello')])
1558.12.9 by Aaron Bentley
Handle resolving conflicts with directories properly
81
        l.remove_files(tree)
82
1551.15.58 by Aaron Bentley
Status honours selected paths for conflicts (#127606)
83
    def test_select_conflicts(self):
84
        tree = self.make_branch_and_tree('.')
4597.2.3 by Vincent Ladeuil
More cleanup.
85
        clist = conflicts.ConflictList
86
87
        def check_select(not_selected, selected, paths, **kwargs):
88
            self.assertEqual(
89
                (not_selected, selected),
90
                tree_conflicts.select_conflicts(tree, paths, **kwargs))
91
92
        foo = conflicts.ContentsConflict('foo')
93
        bar = conflicts.ContentsConflict('bar')
94
        tree_conflicts = clist([foo, bar])
95
96
        check_select(clist([bar]), clist([foo]), ['foo'])
97
        check_select(clist(), tree_conflicts,
98
                     [''], ignore_misses=True, recurse=True)
99
100
        foobaz  = conflicts.ContentsConflict('foo/baz')
101
        tree_conflicts = clist([foobaz, bar])
102
103
        check_select(clist([bar]), clist([foobaz]),
104
                     ['foo'], ignore_misses=True, recurse=True)
105
106
        qux = conflicts.PathConflict('qux', 'foo/baz')
107
        tree_conflicts = clist([qux])
108
109
        check_select(clist(), tree_conflicts,
110
                     ['foo'], ignore_misses=True, recurse=True)
111
        check_select (tree_conflicts, clist(), ['foo'], ignore_misses=True)
1551.15.58 by Aaron Bentley
Status honours selected paths for conflicts (#127606)
112
3017.2.1 by Aaron Bentley
Revert now resolves conflicts recursively (#102739)
113
    def test_resolve_conflicts_recursive(self):
114
        tree = self.make_branch_and_tree('.')
115
        self.build_tree(['dir/', 'dir/hello'])
116
        tree.add(['dir', 'dir/hello'])
4597.2.3 by Vincent Ladeuil
More cleanup.
117
118
        dirhello = conflicts.ConflictList([conflicts.TextConflict('dir/hello')])
119
        tree.set_conflicts(dirhello)
120
121
        conflicts.resolve(tree, ['dir'], recursive=False, ignore_misses=True)
122
        self.assertEqual(dirhello, tree.conflicts())
123
124
        conflicts.resolve(tree, ['dir'], recursive=True, ignore_misses=True)
125
        self.assertEqual(conflicts.ConflictList([]), tree.conflicts())
4773.1.1 by Vincent Ladeuil
Cleanup imports in test_conflicts
126
127
5898.1.3 by Martin
Add tests for non-ascii conflict serialisation
128
class TestPerConflict(tests.TestCase):
4597.3.43 by Vincent Ladeuil
Cleanups, ready to record.
129
5898.1.1 by Martin
Refactor conflict stanzas tests to use scenarios
130
    scenarios = scenarios.multiply_scenarios(vary_by_conflicts())
131
5898.1.3 by Martin
Add tests for non-ascii conflict serialisation
132
    def test_stringification(self):
133
        text = unicode(self.conflict)
134
        self.assertContainsString(text, self.conflict.path)
135
        self.assertContainsString(text.lower(), "conflict")
136
        self.assertContainsString(repr(self.conflict),
137
            self.conflict.__class__.__name__)
138
4597.3.43 by Vincent Ladeuil
Cleanups, ready to record.
139
    def test_stanza_roundtrip(self):
5898.1.1 by Martin
Refactor conflict stanzas tests to use scenarios
140
        p = self.conflict
141
        o = conflicts.Conflict.factory(**p.as_stanza().as_dict())
142
        self.assertEqual(o, p)
143
144
        self.assertIsInstance(o.path, unicode)
145
146
        if o.file_id is not None:
147
            self.assertIsInstance(o.file_id, str)
148
149
        conflict_path = getattr(o, 'conflict_path', None)
150
        if conflict_path is not None:
151
            self.assertIsInstance(conflict_path, unicode)
152
153
        conflict_file_id = getattr(o, 'conflict_file_id', None)
154
        if conflict_file_id is not None:
155
            self.assertIsInstance(conflict_file_id, str)
4597.3.43 by Vincent Ladeuil
Cleanups, ready to record.
156
157
    def test_stanzification(self):
5898.1.1 by Martin
Refactor conflict stanzas tests to use scenarios
158
        stanza = self.conflict.as_stanza()
159
        if 'file_id' in stanza:
160
            # In Stanza form, the file_id has to be unicode.
161
            self.assertStartsWith(stanza['file_id'], u'\xeed')
162
        self.assertStartsWith(stanza['path'], u'p\xe5th')
163
        if 'conflict_path' in stanza:
164
            self.assertStartsWith(stanza['conflict_path'], u'p\xe5th')
165
        if 'conflict_file_id' in stanza:
166
            self.assertStartsWith(stanza['conflict_file_id'], u'\xeed')
167
168
5898.1.3 by Martin
Add tests for non-ascii conflict serialisation
169
class TestConflictList(tests.TestCase):
5898.1.1 by Martin
Refactor conflict stanzas tests to use scenarios
170
171
    def test_stanzas_roundtrip(self):
172
        stanzas_iter = example_conflicts.to_stanzas()
173
        processed = conflicts.ConflictList.from_stanzas(stanzas_iter)
174
        self.assertEqual(example_conflicts, processed)
4597.3.43 by Vincent Ladeuil
Cleanups, ready to record.
175
5898.1.3 by Martin
Add tests for non-ascii conflict serialisation
176
    def test_stringification(self):
177
        for text, o in zip(example_conflicts.to_strings(), example_conflicts):
178
            self.assertEqual(text, unicode(o))
179
4597.3.43 by Vincent Ladeuil
Cleanups, ready to record.
180
4597.3.74 by Vincent Ladeuil
Add a FIXME about rewriting shell-like tests into real whitebox tests.
181
# FIXME: The shell-like tests should be converted to real whitebox tests... or
182
# moved to a blackbox module -- vila 20100205
183
4597.7.11 by Vincent Ladeuil
Fix #531967 by creating helpers for PathConflicts when a deletion
184
# FIXME: test missing for multiple conflicts
185
4597.3.31 by Vincent Ladeuil
Implement --interactive for MissingParent.
186
# FIXME: Tests missing for DuplicateID conflict type
4597.3.12 by Vincent Ladeuil
Start writing tests for all expected conflict resolution actions.
187
class TestResolveConflicts(script.TestCaseWithTransportAndScript):
188
189
    preamble = None # The setup script set by daughter classes
190
191
    def setUp(self):
192
        super(TestResolveConflicts, self).setUp()
193
        self.run_script(self.preamble)
194
195
4597.10.11 by Vincent Ladeuil
Turn mirror_scenarios into a simple function.
196
def mirror_scenarios(base_scenarios):
197
    """Return a list of mirrored scenarios.
198
199
    Each scenario in base_scenarios is duplicated switching the roles of 'this'
200
    and 'other'
201
    """
202
    scenarios = []
4597.10.14 by Vincent Ladeuil
Some more cleanup and typos.
203
    for common, (lname, ldict), (rname, rdict) in base_scenarios:
4597.10.11 by Vincent Ladeuil
Turn mirror_scenarios into a simple function.
204
        a = tests.multiply_scenarios([(lname, dict(_this=ldict))],
205
                                     [(rname, dict(_other=rdict))])
206
        b = tests.multiply_scenarios([(rname, dict(_this=rdict))],
207
                                     [(lname, dict(_other=ldict))])
208
        # Inject the common parameters in all scenarios
209
        for name, d in a + b:
210
            d.update(common)
211
        scenarios.extend(a + b)
212
    return scenarios
213
214
4597.7.10 by Vincent Ladeuil
Define scenarios by test classes.
215
# FIXME: Get rid of parametrized (in the class name) once we delete
216
# TestResolveConflicts -- vila 20100308
4597.7.4 by Vincent Ladeuil
Abstract the test class some more to address more conflict
217
class TestParametrizedResolveConflicts(tests.TestCaseWithTransport):
4597.7.18 by Vincent Ladeuil
Start addressing Andrew's concerns.
218
    """This class provides a base to test single conflict resolution.
219
4597.10.7 by Vincent Ladeuil
Simplify scenarios mirroring and give a better docstring for TestParametrizedResolveConflicts.
220
    Since all conflict objects are created with specific semantics for their
221
    attributes, each class should implement the necessary functions and
222
    attributes described below.
223
224
    Each class should define the scenarios that create the expected (single)
225
    conflict.
226
227
    Each scenario describes:
228
    * how to create 'base' tree (and revision)
229
    * how to create 'left' tree (and revision, parent rev 'base')
230
    * how to create 'right' tree (and revision, parent rev 'base')
231
    * how to check that changes in 'base'->'left' have been taken
232
    * how to check that changes in 'base'->'right' have been taken
233
234
    From each base scenario, we generate two concrete scenarios where:
235
    * this=left, other=right
236
    * this=right, other=left
237
238
    Then the test case verifies each concrete scenario by:
239
    * creating a branch containing the 'base', 'this' and 'other' revisions
240
    * creating a working tree for the 'this' revision
241
    * performing the merge of 'other' into 'this'
242
    * verifying the expected conflict was generated
243
    * resolving with --take-this or --take-other, and running the corresponding
244
      checks (for either 'base'->'this', or 'base'->'other')
245
246
    :cvar _conflict_type: The expected class of the generated conflict.
247
248
    :cvar _assert_conflict: A method receiving the working tree and the
249
        conflict object and checking its attributes.
250
4597.10.9 by Vincent Ladeuil
More doc.
251
    :cvar _base_actions: The branchbuilder actions to create the 'base'
252
        revision.
253
254
    :cvar _this: The dict related to 'base' -> 'this'. It contains at least:
255
      * 'actions': The branchbuilder actions to create the 'this'
256
          revision.
4597.10.10 by Vincent Ladeuil
Fix typo.
257
      * 'check': how to check the changes after resolution with --take-this.
4597.10.9 by Vincent Ladeuil
More doc.
258
259
    :cvar _other: The dict related to 'base' -> 'other'. It contains at least:
260
      * 'actions': The branchbuilder actions to create the 'other'
261
          revision.
4597.10.10 by Vincent Ladeuil
Fix typo.
262
      * 'check': how to check the changes after resolution with --take-other.
4597.7.18 by Vincent Ladeuil
Start addressing Andrew's concerns.
263
    """
4597.2.23 by Vincent Ladeuil
Start translating blackbox tests into whitebox ones.
264
4597.7.16 by Vincent Ladeuil
Some cleanup.
265
    # Set by daughter classes
266
    _conflict_type = None
267
    _assert_conflict = None
268
4597.2.26 by Vincent Ladeuil
Fix bug #529968 by renaming the kept file on content conflicts.
269
    # Set by load_tests
4597.7.6 by Vincent Ladeuil
Cleanup TestParametrizedResolveConflicts some more.
270
    _base_actions = None
4597.10.7 by Vincent Ladeuil
Simplify scenarios mirroring and give a better docstring for TestParametrizedResolveConflicts.
271
    _this = None
272
    _other = None
4597.7.7 by Vincent Ladeuil
Reproduce bug #531967 on various aspects.
273
4597.13.3 by Vincent Ladeuil
Switch to load_tests_apply_scenarios.
274
    scenarios = []
275
    """The scenario list for the conflict type defined by the class.
276
277
    Each scenario is of the form:
278
    (common, (left_name, left_dict), (right_name, right_dict))
279
280
    * common is a dict
281
282
    * left_name and right_name are the scenario names that will be combined
283
284
    * left_dict and right_dict are the attributes specific to each half of
285
      the scenario. They should include at least 'actions' and 'check' and
286
      will be available as '_this' and '_other' test instance attributes.
287
288
    Daughters classes are free to add their specific attributes as they see
289
    fit in any of the three dicts.
290
291
    This is a class method so that load_tests can find it.
292
293
    '_base_actions' in the common dict, 'actions' and 'check' in the left
294
    and right dicts use names that map to methods in the test classes. Some
295
    prefixes are added to these names to get the correspong methods (see
296
    _get_actions() and _get_check()). The motivation here is to avoid
297
    collisions in the class namespace.
298
    """
4597.7.10 by Vincent Ladeuil
Define scenarios by test classes.
299
4597.2.23 by Vincent Ladeuil
Start translating blackbox tests into whitebox ones.
300
    def setUp(self):
4597.7.4 by Vincent Ladeuil
Abstract the test class some more to address more conflict
301
        super(TestParametrizedResolveConflicts, self).setUp()
4597.2.23 by Vincent Ladeuil
Start translating blackbox tests into whitebox ones.
302
        builder = self.make_branch_builder('trunk')
303
        builder.start_series()
4597.7.6 by Vincent Ladeuil
Cleanup TestParametrizedResolveConflicts some more.
304
4597.2.23 by Vincent Ladeuil
Start translating blackbox tests into whitebox ones.
305
        # Create an empty trunk
306
        builder.build_snapshot('start', None, [
307
                ('add', ('', 'root-id', 'directory', ''))])
308
        # Add a minimal base content
4597.10.8 by Vincent Ladeuil
Separate actions and conflict attributes.
309
        base_actions = self._get_actions(self._base_actions)()
4597.10.7 by Vincent Ladeuil
Simplify scenarios mirroring and give a better docstring for TestParametrizedResolveConflicts.
310
        builder.build_snapshot('base', ['start'], base_actions)
4597.2.23 by Vincent Ladeuil
Start translating blackbox tests into whitebox ones.
311
        # Modify the base content in branch
4597.10.8 by Vincent Ladeuil
Separate actions and conflict attributes.
312
        actions_other = self._get_actions(self._other['actions'])()
4597.7.10 by Vincent Ladeuil
Define scenarios by test classes.
313
        builder.build_snapshot('other', ['base'], actions_other)
4597.2.23 by Vincent Ladeuil
Start translating blackbox tests into whitebox ones.
314
        # Modify the base content in trunk
4597.10.8 by Vincent Ladeuil
Separate actions and conflict attributes.
315
        actions_this = self._get_actions(self._this['actions'])()
4597.7.10 by Vincent Ladeuil
Define scenarios by test classes.
316
        builder.build_snapshot('this', ['base'], actions_this)
4597.7.7 by Vincent Ladeuil
Reproduce bug #531967 on various aspects.
317
        # builder.get_branch() tip is now 'this'
4597.7.6 by Vincent Ladeuil
Cleanup TestParametrizedResolveConflicts some more.
318
4597.2.23 by Vincent Ladeuil
Start translating blackbox tests into whitebox ones.
319
        builder.finish_series()
320
        self.builder = builder
321
4597.2.26 by Vincent Ladeuil
Fix bug #529968 by renaming the kept file on content conflicts.
322
    def _get_actions(self, name):
323
        return getattr(self, 'do_%s' % name)
324
325
    def _get_check(self, name):
326
        return getattr(self, 'check_%s' % name)
327
4597.2.24 by Vincent Ladeuil
Translate one more test.
328
    def _merge_other_into_this(self):
4597.2.23 by Vincent Ladeuil
Start translating blackbox tests into whitebox ones.
329
        b = self.builder.get_branch()
330
        wt = b.bzrdir.sprout('branch').open_workingtree()
331
        wt.merge_from_branch(b, 'other')
4597.2.24 by Vincent Ladeuil
Translate one more test.
332
        return wt
333
4597.8.7 by Vincent Ladeuil
Add whitebox tests for ParentLoop.
334
    def assertConflict(self, wt):
335
        confs = wt.conflicts()
336
        self.assertLength(1, confs)
337
        c = confs[0]
338
        self.assertIsInstance(c, self._conflict_type)
339
        self._assert_conflict(wt, c)
340
341
    def _get_resolve_path_arg(self, wt, action):
4597.10.1 by Vincent Ladeuil
Refactor to better handle various conflict types.
342
        raise NotImplementedError(self._get_resolve_path_arg)
4597.8.7 by Vincent Ladeuil
Add whitebox tests for ParentLoop.
343
344
    def check_resolved(self, wt, action):
345
        path = self._get_resolve_path_arg(wt, action)
346
        conflicts.resolve(wt, [path], action=action)
347
        # Check that we don't have any conflicts nor unknown left
348
        self.assertLength(0, wt.conflicts())
349
        self.assertLength(0, list(wt.unknowns()))
350
4597.2.24 by Vincent Ladeuil
Translate one more test.
351
    def test_resolve_taking_this(self):
352
        wt = self._merge_other_into_this()
4597.7.7 by Vincent Ladeuil
Reproduce bug #531967 on various aspects.
353
        self.assertConflict(wt)
4597.8.7 by Vincent Ladeuil
Add whitebox tests for ParentLoop.
354
        self.check_resolved(wt, 'take_this')
4597.10.7 by Vincent Ladeuil
Simplify scenarios mirroring and give a better docstring for TestParametrizedResolveConflicts.
355
        check_this = self._get_check(self._this['check'])
4597.2.26 by Vincent Ladeuil
Fix bug #529968 by renaming the kept file on content conflicts.
356
        check_this()
4597.2.24 by Vincent Ladeuil
Translate one more test.
357
358
    def test_resolve_taking_other(self):
359
        wt = self._merge_other_into_this()
4597.7.7 by Vincent Ladeuil
Reproduce bug #531967 on various aspects.
360
        self.assertConflict(wt)
4597.8.7 by Vincent Ladeuil
Add whitebox tests for ParentLoop.
361
        self.check_resolved(wt, 'take_other')
4597.10.7 by Vincent Ladeuil
Simplify scenarios mirroring and give a better docstring for TestParametrizedResolveConflicts.
362
        check_other = self._get_check(self._other['check'])
4597.2.26 by Vincent Ladeuil
Fix bug #529968 by renaming the kept file on content conflicts.
363
        check_other()
4597.3.28 by Vincent Ladeuil
Implement --interactive for ContentsConflict.
364
4597.3.12 by Vincent Ladeuil
Start writing tests for all expected conflict resolution actions.
365
4597.14.2 by Vincent Ladeuil
Implements --take-this and --take-other when resolving text conflicts
366
class TestResolveTextConflicts(TestParametrizedResolveConflicts):
367
368
    _conflict_type = conflicts.TextConflict
369
370
    # Set by the scenarios
371
    # path and file-id for the file involved in the conflict
372
    _path = None
373
    _file_id = None
374
375
    scenarios = mirror_scenarios(
376
        [
5609.17.1 by Vincent Ladeuil
Reproduce bug #715068.
377
            # File modified on both sides
4597.14.2 by Vincent Ladeuil
Implements --take-this and --take-other when resolving text conflicts
378
            (dict(_base_actions='create_file',
379
                  _path='file', _file_id='file-id'),
380
             ('filed_modified_A',
381
              dict(actions='modify_file_A', check='file_has_content_A')),
382
             ('file_modified_B',
383
              dict(actions='modify_file_B', check='file_has_content_B')),),
5609.17.1 by Vincent Ladeuil
Reproduce bug #715068.
384
            # File modified on both sides in dir
385
            (dict(_base_actions='create_file_in_dir',
386
                  _path='dir/file', _file_id='file-id'),
387
             ('filed_modified_A_in_dir',
388
              dict(actions='modify_file_A',
389
                   check='file_in_dir_has_content_A')),
390
             ('file_modified_B',
391
              dict(actions='modify_file_B',
392
                   check='file_in_dir_has_content_B')),),
4597.14.2 by Vincent Ladeuil
Implements --take-this and --take-other when resolving text conflicts
393
            ])
394
5609.17.1 by Vincent Ladeuil
Reproduce bug #715068.
395
    def do_create_file(self, path='file'):
396
        return [('add', (path, 'file-id', 'file', 'trunk content\n'))]
4597.14.2 by Vincent Ladeuil
Implements --take-this and --take-other when resolving text conflicts
397
398
    def do_modify_file_A(self):
399
        return [('modify', ('file-id', 'trunk content\nfeature A\n'))]
400
401
    def do_modify_file_B(self):
402
        return [('modify', ('file-id', 'trunk content\nfeature B\n'))]
403
5609.17.1 by Vincent Ladeuil
Reproduce bug #715068.
404
    def check_file_has_content_A(self, path='file'):
405
        self.assertFileEqual('trunk content\nfeature A\n',
406
                             osutils.pathjoin('branch', path))
407
408
    def check_file_has_content_B(self, path='file'):
409
        self.assertFileEqual('trunk content\nfeature B\n',
410
                             osutils.pathjoin('branch', path))
411
412
    def do_create_file_in_dir(self):
413
        return [('add', ('dir', 'dir-id', 'directory', '')),
414
            ] + self.do_create_file('dir/file')
415
416
    def check_file_in_dir_has_content_A(self):
417
        self.check_file_has_content_A('dir/file')
418
419
    def check_file_in_dir_has_content_B(self):
420
        self.check_file_has_content_B('dir/file')
4597.14.2 by Vincent Ladeuil
Implements --take-this and --take-other when resolving text conflicts
421
422
    def _get_resolve_path_arg(self, wt, action):
423
        return self._path
424
425
    def assertTextConflict(self, wt, c):
426
        self.assertEqual(self._file_id, c.file_id)
427
        self.assertEqual(self._path, c.path)
428
    _assert_conflict = assertTextConflict
429
430
4597.7.10 by Vincent Ladeuil
Define scenarios by test classes.
431
class TestResolveContentsConflict(TestParametrizedResolveConflicts):
432
4597.13.3 by Vincent Ladeuil
Switch to load_tests_apply_scenarios.
433
    _conflict_type = conflicts.ContentsConflict
4597.10.1 by Vincent Ladeuil
Refactor to better handle various conflict types.
434
4597.13.3 by Vincent Ladeuil
Switch to load_tests_apply_scenarios.
435
    # Set by the scenarios
4597.10.8 by Vincent Ladeuil
Separate actions and conflict attributes.
436
    # path and file-id for the file involved in the conflict
437
    _path = None
438
    _file_id = None
4597.10.1 by Vincent Ladeuil
Refactor to better handle various conflict types.
439
4597.13.3 by Vincent Ladeuil
Switch to load_tests_apply_scenarios.
440
    scenarios = mirror_scenarios(
441
        [
4597.10.12 by Vincent Ladeuil
Some more doc.
442
            # File modified/deleted
4597.10.8 by Vincent Ladeuil
Separate actions and conflict attributes.
443
            (dict(_base_actions='create_file',
444
                  _path='file', _file_id='file-id'),
4597.10.12 by Vincent Ladeuil
Some more doc.
445
             ('file_modified',
446
              dict(actions='modify_file', check='file_has_more_content')),
447
             ('file_deleted',
448
              dict(actions='delete_file', check='file_doesnt_exist')),),
5988.2.1 by Vincent Ladeuil
Do not generate path conflicts if a corresponding content conflict exists
449
            # File renamed-modified/deleted
450
            (dict(_base_actions='create_file',
451
                  _path='new-file', _file_id='file-id'),
452
             ('file_renamed_and_modified',
453
              dict(actions='modify_and_rename_file',
454
                   check='file_renamed_and_more_content')),
455
             ('file_deleted',
456
              dict(actions='delete_file', check='file_doesnt_exist')),),
5050.63.3 by Vincent Ladeuil
Correctly resolve content conflicts for files in subdirs
457
            # File modified/deleted in dir
458
            (dict(_base_actions='create_file_in_dir',
459
                  _path='dir/file', _file_id='file-id'),
460
             ('file_modified_in_dir',
461
              dict(actions='modify_file_in_dir',
462
                   check='file_in_dir_has_more_content')),
463
             ('file_deleted_in_dir',
464
              dict(actions='delete_file',
465
                   check='file_in_dir_doesnt_exist')),),
4597.13.3 by Vincent Ladeuil
Switch to load_tests_apply_scenarios.
466
            ])
4597.7.10 by Vincent Ladeuil
Define scenarios by test classes.
467
4597.10.1 by Vincent Ladeuil
Refactor to better handle various conflict types.
468
    def do_create_file(self):
4597.10.8 by Vincent Ladeuil
Separate actions and conflict attributes.
469
        return [('add', ('file', 'file-id', 'file', 'trunk content\n'))]
4597.10.1 by Vincent Ladeuil
Refactor to better handle various conflict types.
470
471
    def do_modify_file(self):
4597.10.8 by Vincent Ladeuil
Separate actions and conflict attributes.
472
        return [('modify', ('file-id', 'trunk content\nmore content\n'))]
4597.10.1 by Vincent Ladeuil
Refactor to better handle various conflict types.
473
5988.2.1 by Vincent Ladeuil
Do not generate path conflicts if a corresponding content conflict exists
474
    def do_modify_and_rename_file(self):
475
        return [('modify', ('file-id', 'trunk content\nmore content\n')),
476
                ('rename', ('file', 'new-file'))]
477
4597.10.1 by Vincent Ladeuil
Refactor to better handle various conflict types.
478
    def check_file_has_more_content(self):
479
        self.assertFileEqual('trunk content\nmore content\n', 'branch/file')
480
5988.2.1 by Vincent Ladeuil
Do not generate path conflicts if a corresponding content conflict exists
481
    def check_file_renamed_and_more_content(self):
482
        self.assertFileEqual('trunk content\nmore content\n', 'branch/new-file')
483
4597.10.1 by Vincent Ladeuil
Refactor to better handle various conflict types.
484
    def do_delete_file(self):
4597.10.8 by Vincent Ladeuil
Separate actions and conflict attributes.
485
        return [('unversion', 'file-id')]
4597.10.1 by Vincent Ladeuil
Refactor to better handle various conflict types.
486
487
    def check_file_doesnt_exist(self):
5784.1.3 by Martin Pool
Switch away from using failUnlessExists and failIfExists
488
        self.assertPathDoesNotExist('branch/file')
4597.10.1 by Vincent Ladeuil
Refactor to better handle various conflict types.
489
5050.63.3 by Vincent Ladeuil
Correctly resolve content conflicts for files in subdirs
490
    def do_create_file_in_dir(self):
491
        return [('add', ('dir', 'dir-id', 'directory', '')),
492
                ('add', ('dir/file', 'file-id', 'file', 'trunk content\n'))]
493
494
    def do_modify_file_in_dir(self):
495
        return [('modify', ('file-id', 'trunk content\nmore content\n'))]
496
497
    def check_file_in_dir_has_more_content(self):
498
        self.assertFileEqual('trunk content\nmore content\n', 'branch/dir/file')
499
500
    def check_file_in_dir_doesnt_exist(self):
5784.1.3 by Martin Pool
Switch away from using failUnlessExists and failIfExists
501
        self.assertPathDoesNotExist('branch/dir/file')
5050.63.3 by Vincent Ladeuil
Correctly resolve content conflicts for files in subdirs
502
4597.10.1 by Vincent Ladeuil
Refactor to better handle various conflict types.
503
    def _get_resolve_path_arg(self, wt, action):
4597.10.8 by Vincent Ladeuil
Separate actions and conflict attributes.
504
        return self._path
4597.10.1 by Vincent Ladeuil
Refactor to better handle various conflict types.
505
4597.7.17 by Vincent Ladeuil
Add a scenario and activate the compatibility tests.
506
    def assertContentsConflict(self, wt, c):
4597.10.8 by Vincent Ladeuil
Separate actions and conflict attributes.
507
        self.assertEqual(self._file_id, c.file_id)
508
        self.assertEqual(self._path, c.path)
4597.7.16 by Vincent Ladeuil
Some cleanup.
509
    _assert_conflict = assertContentsConflict
510
4597.7.10 by Vincent Ladeuil
Define scenarios by test classes.
511
512
class TestResolvePathConflict(TestParametrizedResolveConflicts):
513
4597.13.3 by Vincent Ladeuil
Switch to load_tests_apply_scenarios.
514
    _conflict_type = conflicts.PathConflict
4597.7.16 by Vincent Ladeuil
Some cleanup.
515
4597.10.8 by Vincent Ladeuil
Separate actions and conflict attributes.
516
    def do_nothing(self):
517
        return []
4597.10.1 by Vincent Ladeuil
Refactor to better handle various conflict types.
518
4597.13.3 by Vincent Ladeuil
Switch to load_tests_apply_scenarios.
519
    # Each side dict additionally defines:
520
    # - path path involved (can be '<deleted>')
521
    # - file-id involved
522
    scenarios = mirror_scenarios(
523
        [
4597.10.8 by Vincent Ladeuil
Separate actions and conflict attributes.
524
            # File renamed/deleted
525
            (dict(_base_actions='create_file'),
526
             ('file_renamed',
527
              dict(actions='rename_file', check='file_renamed',
528
                   path='new-file', file_id='file-id')),
4597.7.17 by Vincent Ladeuil
Add a scenario and activate the compatibility tests.
529
             ('file_deleted',
4597.10.8 by Vincent Ladeuil
Separate actions and conflict attributes.
530
              dict(actions='delete_file', check='file_doesnt_exist',
531
                   # PathConflicts deletion handling requires a special
532
                   # hard-coded value
533
                   path='<deleted>', file_id='file-id')),),
5050.63.6 by Vincent Ladeuil
Same fix for path conflicts.
534
            # File renamed/deleted in dir
535
            (dict(_base_actions='create_file_in_dir'),
536
             ('file_renamed_in_dir',
537
              dict(actions='rename_file_in_dir', check='file_in_dir_renamed',
538
                   path='dir/new-file', file_id='file-id')),
539
             ('file_deleted',
540
              dict(actions='delete_file', check='file_in_dir_doesnt_exist',
541
                   # PathConflicts deletion handling requires a special
542
                   # hard-coded value
543
                   path='<deleted>', file_id='file-id')),),
4597.10.8 by Vincent Ladeuil
Separate actions and conflict attributes.
544
            # File renamed/renamed differently
545
            (dict(_base_actions='create_file'),
546
             ('file_renamed',
547
              dict(actions='rename_file', check='file_renamed',
548
                   path='new-file', file_id='file-id')),
4597.8.4 by Vincent Ladeuil
Delete PathConflict bloackbox tests.
549
             ('file_renamed2',
4597.10.8 by Vincent Ladeuil
Separate actions and conflict attributes.
550
              dict(actions='rename_file2', check='file_renamed2',
551
                   path='new-file2', file_id='file-id')),),
552
            # Dir renamed/deleted
553
            (dict(_base_actions='create_dir'),
554
             ('dir_renamed',
555
              dict(actions='rename_dir', check='dir_renamed',
556
                   path='new-dir', file_id='dir-id')),
4597.7.17 by Vincent Ladeuil
Add a scenario and activate the compatibility tests.
557
             ('dir_deleted',
4597.10.8 by Vincent Ladeuil
Separate actions and conflict attributes.
558
              dict(actions='delete_dir', check='dir_doesnt_exist',
559
                   # PathConflicts deletion handling requires a special
560
                   # hard-coded value
561
                   path='<deleted>', file_id='dir-id')),),
562
            # Dir renamed/renamed differently
563
            (dict(_base_actions='create_dir'),
564
             ('dir_renamed',
565
              dict(actions='rename_dir', check='dir_renamed',
566
                   path='new-dir', file_id='dir-id')),
4597.7.17 by Vincent Ladeuil
Add a scenario and activate the compatibility tests.
567
             ('dir_renamed2',
4597.10.8 by Vincent Ladeuil
Separate actions and conflict attributes.
568
              dict(actions='rename_dir2', check='dir_renamed2',
569
                   path='new-dir2', file_id='dir-id')),),
4597.13.3 by Vincent Ladeuil
Switch to load_tests_apply_scenarios.
570
            ])
4597.7.17 by Vincent Ladeuil
Add a scenario and activate the compatibility tests.
571
4597.10.1 by Vincent Ladeuil
Refactor to better handle various conflict types.
572
    def do_create_file(self):
4597.10.8 by Vincent Ladeuil
Separate actions and conflict attributes.
573
        return [('add', ('file', 'file-id', 'file', 'trunk content\n'))]
4597.10.1 by Vincent Ladeuil
Refactor to better handle various conflict types.
574
575
    def do_create_dir(self):
4597.10.8 by Vincent Ladeuil
Separate actions and conflict attributes.
576
        return [('add', ('dir', 'dir-id', 'directory', ''))]
4597.10.1 by Vincent Ladeuil
Refactor to better handle various conflict types.
577
578
    def do_rename_file(self):
4597.10.8 by Vincent Ladeuil
Separate actions and conflict attributes.
579
        return [('rename', ('file', 'new-file'))]
4597.10.1 by Vincent Ladeuil
Refactor to better handle various conflict types.
580
581
    def check_file_renamed(self):
5784.1.3 by Martin Pool
Switch away from using failUnlessExists and failIfExists
582
        self.assertPathDoesNotExist('branch/file')
583
        self.assertPathExists('branch/new-file')
4597.10.1 by Vincent Ladeuil
Refactor to better handle various conflict types.
584
585
    def do_rename_file2(self):
4597.10.8 by Vincent Ladeuil
Separate actions and conflict attributes.
586
        return [('rename', ('file', 'new-file2'))]
4597.10.1 by Vincent Ladeuil
Refactor to better handle various conflict types.
587
588
    def check_file_renamed2(self):
5784.1.3 by Martin Pool
Switch away from using failUnlessExists and failIfExists
589
        self.assertPathDoesNotExist('branch/file')
590
        self.assertPathExists('branch/new-file2')
4597.10.1 by Vincent Ladeuil
Refactor to better handle various conflict types.
591
592
    def do_rename_dir(self):
4597.10.8 by Vincent Ladeuil
Separate actions and conflict attributes.
593
        return [('rename', ('dir', 'new-dir'))]
4597.10.1 by Vincent Ladeuil
Refactor to better handle various conflict types.
594
595
    def check_dir_renamed(self):
5784.1.3 by Martin Pool
Switch away from using failUnlessExists and failIfExists
596
        self.assertPathDoesNotExist('branch/dir')
597
        self.assertPathExists('branch/new-dir')
4597.10.1 by Vincent Ladeuil
Refactor to better handle various conflict types.
598
599
    def do_rename_dir2(self):
4597.10.8 by Vincent Ladeuil
Separate actions and conflict attributes.
600
        return [('rename', ('dir', 'new-dir2'))]
4597.10.1 by Vincent Ladeuil
Refactor to better handle various conflict types.
601
602
    def check_dir_renamed2(self):
5784.1.3 by Martin Pool
Switch away from using failUnlessExists and failIfExists
603
        self.assertPathDoesNotExist('branch/dir')
604
        self.assertPathExists('branch/new-dir2')
4597.10.1 by Vincent Ladeuil
Refactor to better handle various conflict types.
605
4597.7.17 by Vincent Ladeuil
Add a scenario and activate the compatibility tests.
606
    def do_delete_file(self):
4597.10.8 by Vincent Ladeuil
Separate actions and conflict attributes.
607
        return [('unversion', 'file-id')]
4597.10.1 by Vincent Ladeuil
Refactor to better handle various conflict types.
608
609
    def check_file_doesnt_exist(self):
5784.1.3 by Martin Pool
Switch away from using failUnlessExists and failIfExists
610
        self.assertPathDoesNotExist('branch/file')
4597.10.1 by Vincent Ladeuil
Refactor to better handle various conflict types.
611
612
    def do_delete_dir(self):
4597.10.8 by Vincent Ladeuil
Separate actions and conflict attributes.
613
        return [('unversion', 'dir-id')]
4597.10.1 by Vincent Ladeuil
Refactor to better handle various conflict types.
614
615
    def check_dir_doesnt_exist(self):
5784.1.3 by Martin Pool
Switch away from using failUnlessExists and failIfExists
616
        self.assertPathDoesNotExist('branch/dir')
4597.10.1 by Vincent Ladeuil
Refactor to better handle various conflict types.
617
5050.63.6 by Vincent Ladeuil
Same fix for path conflicts.
618
    def do_create_file_in_dir(self):
619
        return [('add', ('dir', 'dir-id', 'directory', '')),
620
                ('add', ('dir/file', 'file-id', 'file', 'trunk content\n'))]
621
622
    def do_rename_file_in_dir(self):
623
        return [('rename', ('dir/file', 'dir/new-file'))]
624
625
    def check_file_in_dir_renamed(self):
5784.1.3 by Martin Pool
Switch away from using failUnlessExists and failIfExists
626
        self.assertPathDoesNotExist('branch/dir/file')
627
        self.assertPathExists('branch/dir/new-file')
5050.63.6 by Vincent Ladeuil
Same fix for path conflicts.
628
629
    def check_file_in_dir_doesnt_exist(self):
5784.1.3 by Martin Pool
Switch away from using failUnlessExists and failIfExists
630
        self.assertPathDoesNotExist('branch/dir/file')
5050.63.6 by Vincent Ladeuil
Same fix for path conflicts.
631
4597.10.1 by Vincent Ladeuil
Refactor to better handle various conflict types.
632
    def _get_resolve_path_arg(self, wt, action):
4597.10.8 by Vincent Ladeuil
Separate actions and conflict attributes.
633
        tpath = self._this['path']
634
        opath = self._other['path']
4597.10.1 by Vincent Ladeuil
Refactor to better handle various conflict types.
635
        if tpath == '<deleted>':
636
            path = opath
637
        else:
638
            path = tpath
639
        return path
4597.7.17 by Vincent Ladeuil
Add a scenario and activate the compatibility tests.
640
641
    def assertPathConflict(self, wt, c):
4597.10.8 by Vincent Ladeuil
Separate actions and conflict attributes.
642
        tpath = self._this['path']
643
        tfile_id = self._this['file_id']
644
        opath = self._other['path']
645
        ofile_id = self._other['file_id']
4597.10.1 by Vincent Ladeuil
Refactor to better handle various conflict types.
646
        self.assertEqual(tfile_id, ofile_id) # Sanity check
647
        self.assertEqual(tfile_id, c.file_id)
648
        self.assertEqual(tpath, c.path)
649
        self.assertEqual(opath, c.conflict_path)
4597.7.16 by Vincent Ladeuil
Some cleanup.
650
    _assert_conflict = assertPathConflict
4597.7.10 by Vincent Ladeuil
Define scenarios by test classes.
651
652
4597.7.17 by Vincent Ladeuil
Add a scenario and activate the compatibility tests.
653
class TestResolvePathConflictBefore531967(TestResolvePathConflict):
4597.7.10 by Vincent Ladeuil
Define scenarios by test classes.
654
    """Same as TestResolvePathConflict but a specific conflict object.
655
    """
656
4597.7.16 by Vincent Ladeuil
Some cleanup.
657
    def assertPathConflict(self, c):
4597.7.17 by Vincent Ladeuil
Add a scenario and activate the compatibility tests.
658
        # We create a conflict object as it was created before the fix and
659
        # inject it into the working tree, the test will exercise the
660
        # compatibility code.
661
        old_c = conflicts.PathConflict('<deleted>', self._item_path,
662
                                       file_id=None)
4597.10.8 by Vincent Ladeuil
Separate actions and conflict attributes.
663
        wt.set_conflicts(conflicts.ConflictList([old_c]))
4597.7.10 by Vincent Ladeuil
Define scenarios by test classes.
664
665
4597.8.5 by Vincent Ladeuil
Replace DuplicateEntry blackbox tests by whitebox ones.
666
class TestResolveDuplicateEntry(TestParametrizedResolveConflicts):
667
4597.13.3 by Vincent Ladeuil
Switch to load_tests_apply_scenarios.
668
    _conflict_type = conflicts.DuplicateEntry
4597.10.1 by Vincent Ladeuil
Refactor to better handle various conflict types.
669
4597.13.3 by Vincent Ladeuil
Switch to load_tests_apply_scenarios.
670
    scenarios = mirror_scenarios(
671
        [
4597.10.8 by Vincent Ladeuil
Separate actions and conflict attributes.
672
            # File created with different file-ids
673
            (dict(_base_actions='nothing'),
674
             ('filea_created',
675
              dict(actions='create_file_a', check='file_content_a',
676
                   path='file', file_id='file-a-id')),
677
             ('fileb_created',
678
              dict(actions='create_file_b', check='file_content_b',
679
                   path='file', file_id='file-b-id')),),
6015.47.3 by Vincent Ladeuil
Failing tests reproducing bug #880701.
680
            # File created with different file-ids but deleted on one side
681
            (dict(_base_actions='create_file_a'),
682
             ('filea_replaced',
683
              dict(actions='replace_file_a_by_b', check='file_content_b',
684
                   path='file', file_id='file-b-id')),
685
             ('filea_modified',
686
              dict(actions='modify_file_a', check='file_new_content',
687
                   path='file', file_id='file-a-id')),),
4597.13.3 by Vincent Ladeuil
Switch to load_tests_apply_scenarios.
688
            ])
4597.8.5 by Vincent Ladeuil
Replace DuplicateEntry blackbox tests by whitebox ones.
689
4597.10.8 by Vincent Ladeuil
Separate actions and conflict attributes.
690
    def do_nothing(self):
691
        return []
692
4597.10.1 by Vincent Ladeuil
Refactor to better handle various conflict types.
693
    def do_create_file_a(self):
4597.10.8 by Vincent Ladeuil
Separate actions and conflict attributes.
694
        return [('add', ('file', 'file-a-id', 'file', 'file a content\n'))]
4597.10.1 by Vincent Ladeuil
Refactor to better handle various conflict types.
695
696
    def check_file_content_a(self):
697
        self.assertFileEqual('file a content\n', 'branch/file')
698
699
    def do_create_file_b(self):
4597.10.8 by Vincent Ladeuil
Separate actions and conflict attributes.
700
        return [('add', ('file', 'file-b-id', 'file', 'file b content\n'))]
4597.10.1 by Vincent Ladeuil
Refactor to better handle various conflict types.
701
702
    def check_file_content_b(self):
703
        self.assertFileEqual('file b content\n', 'branch/file')
704
6015.47.3 by Vincent Ladeuil
Failing tests reproducing bug #880701.
705
    def do_replace_file_a_by_b(self):
706
        return [('unversion', 'file-a-id'),
707
                ('add', ('file', 'file-b-id', 'file', 'file b content\n'))]
708
709
    def do_modify_file_a(self):
710
        return [('modify', ('file-a-id', 'new content\n'))]
711
712
    def check_file_new_content(self):
713
        self.assertFileEqual('new content\n', 'branch/file')
714
4597.10.1 by Vincent Ladeuil
Refactor to better handle various conflict types.
715
    def _get_resolve_path_arg(self, wt, action):
4597.10.8 by Vincent Ladeuil
Separate actions and conflict attributes.
716
        return self._this['path']
4597.10.1 by Vincent Ladeuil
Refactor to better handle various conflict types.
717
4597.8.5 by Vincent Ladeuil
Replace DuplicateEntry blackbox tests by whitebox ones.
718
    def assertDuplicateEntry(self, wt, c):
4597.10.8 by Vincent Ladeuil
Separate actions and conflict attributes.
719
        tpath = self._this['path']
720
        tfile_id = self._this['file_id']
721
        opath = self._other['path']
722
        ofile_id = self._other['file_id']
4597.10.1 by Vincent Ladeuil
Refactor to better handle various conflict types.
723
        self.assertEqual(tpath, opath) # Sanity check
724
        self.assertEqual(tfile_id, c.file_id)
725
        self.assertEqual(tpath + '.moved', c.path)
726
        self.assertEqual(tpath, c.conflict_path)
4597.8.5 by Vincent Ladeuil
Replace DuplicateEntry blackbox tests by whitebox ones.
727
    _assert_conflict = assertDuplicateEntry
4597.3.19 by Vincent Ladeuil
Some failing tests.
728
4597.3.12 by Vincent Ladeuil
Start writing tests for all expected conflict resolution actions.
729
730
class TestResolveUnversionedParent(TestResolveConflicts):
731
4597.3.29 by Vincent Ladeuil
Fix bogus tests.
732
    # FIXME: Add the reverse tests: dir deleted in trunk, file added in branch
733
4597.3.30 by Vincent Ladeuil
Light changes learned while starting to understand multiple conflicts on
734
    # FIXME: While this *creates* UnversionedParent conflicts, this really only
735
    # tests MissingParent resolution :-/
4597.3.12 by Vincent Ladeuil
Start writing tests for all expected conflict resolution actions.
736
    preamble = """
4597.3.15 by Vincent Ladeuil
Update to new shell-like tests syntax.
737
$ bzr init trunk
5422.3.4 by Martin Pool
Update test_resolve to pass --quiet or ignore command output it doesn't care about
738
...
4597.3.15 by Vincent Ladeuil
Update to new shell-like tests syntax.
739
$ cd trunk
4597.3.29 by Vincent Ladeuil
Fix bogus tests.
740
$ mkdir dir
5422.3.4 by Martin Pool
Update test_resolve to pass --quiet or ignore command output it doesn't care about
741
$ bzr add -q dir
742
$ bzr commit -m 'Create trunk' -q
4597.3.29 by Vincent Ladeuil
Fix bogus tests.
743
$ echo 'trunk content' >dir/file
5422.3.4 by Martin Pool
Update test_resolve to pass --quiet or ignore command output it doesn't care about
744
$ bzr add -q dir/file
745
$ bzr commit -q -m 'Add dir/file in trunk'
746
$ bzr branch -q . -r 1 ../branch
4597.3.15 by Vincent Ladeuil
Update to new shell-like tests syntax.
747
$ cd ../branch
5422.3.4 by Martin Pool
Update test_resolve to pass --quiet or ignore command output it doesn't care about
748
$ bzr rm dir -q
749
$ bzr commit -q -m 'Remove dir in branch'
4597.3.15 by Vincent Ladeuil
Update to new shell-like tests syntax.
750
$ bzr merge ../trunk
4597.3.29 by Vincent Ladeuil
Fix bogus tests.
751
2>+N  dir/
752
2>+N  dir/file
753
2>Conflict adding files to dir.  Created directory.
754
2>Conflict because dir is not versioned, but has versioned children.  Versioned directory.
755
2>2 conflicts encountered.
4597.3.12 by Vincent Ladeuil
Start writing tests for all expected conflict resolution actions.
756
"""
757
4597.3.67 by Vincent Ladeuil
Settle with --take-this and --take-other as action names.
758
    def test_take_this(self):
4597.3.12 by Vincent Ladeuil
Start writing tests for all expected conflict resolution actions.
759
        self.run_script("""
5422.3.4 by Martin Pool
Update test_resolve to pass --quiet or ignore command output it doesn't care about
760
$ bzr rm -q dir  --force
4597.3.29 by Vincent Ladeuil
Fix bogus tests.
761
$ bzr resolve dir
6138.3.5 by Jonathan Riddell
make the test suite pass
762
2>2 conflicts resolved, 0 remaining
5422.3.4 by Martin Pool
Update test_resolve to pass --quiet or ignore command output it doesn't care about
763
$ bzr commit -q --strict -m 'No more conflicts nor unknown files'
4597.3.12 by Vincent Ladeuil
Start writing tests for all expected conflict resolution actions.
764
""")
765
4597.3.67 by Vincent Ladeuil
Settle with --take-this and --take-other as action names.
766
    def test_take_other(self):
4597.3.12 by Vincent Ladeuil
Start writing tests for all expected conflict resolution actions.
767
        self.run_script("""
4597.3.29 by Vincent Ladeuil
Fix bogus tests.
768
$ bzr resolve dir
6138.3.5 by Jonathan Riddell
make the test suite pass
769
2>2 conflicts resolved, 0 remaining
5422.3.4 by Martin Pool
Update test_resolve to pass --quiet or ignore command output it doesn't care about
770
$ bzr commit -q --strict -m 'No more conflicts nor unknown files'
4597.3.12 by Vincent Ladeuil
Start writing tests for all expected conflict resolution actions.
771
""")
772
773
774
class TestResolveMissingParent(TestResolveConflicts):
775
776
    preamble = """
4597.3.15 by Vincent Ladeuil
Update to new shell-like tests syntax.
777
$ bzr init trunk
5422.3.4 by Martin Pool
Update test_resolve to pass --quiet or ignore command output it doesn't care about
778
...
4597.3.15 by Vincent Ladeuil
Update to new shell-like tests syntax.
779
$ cd trunk
780
$ mkdir dir
781
$ echo 'trunk content' >dir/file
5422.3.4 by Martin Pool
Update test_resolve to pass --quiet or ignore command output it doesn't care about
782
$ bzr add -q
783
$ bzr commit -m 'Create trunk' -q
4597.3.15 by Vincent Ladeuil
Update to new shell-like tests syntax.
784
$ echo 'trunk content' >dir/file2
5422.3.4 by Martin Pool
Update test_resolve to pass --quiet or ignore command output it doesn't care about
785
$ bzr add -q dir/file2
786
$ bzr commit -q -m 'Add dir/file2 in branch'
787
$ bzr branch -q . -r 1 ../branch
4597.3.15 by Vincent Ladeuil
Update to new shell-like tests syntax.
788
$ cd ../branch
5422.3.4 by Martin Pool
Update test_resolve to pass --quiet or ignore command output it doesn't care about
789
$ bzr rm -q dir/file --force
790
$ bzr rm -q dir
791
$ bzr commit -q -m 'Remove dir/file'
4597.3.15 by Vincent Ladeuil
Update to new shell-like tests syntax.
792
$ bzr merge ../trunk
4597.3.12 by Vincent Ladeuil
Start writing tests for all expected conflict resolution actions.
793
2>+N  dir/
794
2>+N  dir/file2
795
2>Conflict adding files to dir.  Created directory.
796
2>Conflict because dir is not versioned, but has versioned children.  Versioned directory.
797
2>2 conflicts encountered.
798
"""
799
800
    def test_keep_them_all(self):
801
        self.run_script("""
4597.3.15 by Vincent Ladeuil
Update to new shell-like tests syntax.
802
$ bzr resolve dir
6138.3.5 by Jonathan Riddell
make the test suite pass
803
2>2 conflicts resolved, 0 remaining
5422.3.4 by Martin Pool
Update test_resolve to pass --quiet or ignore command output it doesn't care about
804
$ bzr commit -q --strict -m 'No more conflicts nor unknown files'
4597.3.12 by Vincent Ladeuil
Start writing tests for all expected conflict resolution actions.
805
""")
806
807
    def test_adopt_child(self):
808
        self.run_script("""
5422.3.4 by Martin Pool
Update test_resolve to pass --quiet or ignore command output it doesn't care about
809
$ bzr mv -q dir/file2 file2
810
$ bzr rm -q dir --force
4597.3.15 by Vincent Ladeuil
Update to new shell-like tests syntax.
811
$ bzr resolve dir
6138.3.5 by Jonathan Riddell
make the test suite pass
812
2>2 conflicts resolved, 0 remaining
5422.3.4 by Martin Pool
Update test_resolve to pass --quiet or ignore command output it doesn't care about
813
$ bzr commit -q --strict -m 'No more conflicts nor unknown files'
4597.3.12 by Vincent Ladeuil
Start writing tests for all expected conflict resolution actions.
814
""")
815
816
    def test_kill_them_all(self):
817
        self.run_script("""
5422.3.4 by Martin Pool
Update test_resolve to pass --quiet or ignore command output it doesn't care about
818
$ bzr rm -q dir --force
4597.3.15 by Vincent Ladeuil
Update to new shell-like tests syntax.
819
$ bzr resolve dir
6138.3.5 by Jonathan Riddell
make the test suite pass
820
2>2 conflicts resolved, 0 remaining
5422.3.4 by Martin Pool
Update test_resolve to pass --quiet or ignore command output it doesn't care about
821
$ bzr commit -q --strict -m 'No more conflicts nor unknown files'
4597.3.12 by Vincent Ladeuil
Start writing tests for all expected conflict resolution actions.
822
""")
823
4597.3.67 by Vincent Ladeuil
Settle with --take-this and --take-other as action names.
824
    def test_resolve_taking_this(self):
4597.3.31 by Vincent Ladeuil
Implement --interactive for MissingParent.
825
        self.run_script("""
4597.3.67 by Vincent Ladeuil
Settle with --take-this and --take-other as action names.
826
$ bzr resolve --take-this dir
5422.3.4 by Martin Pool
Update test_resolve to pass --quiet or ignore command output it doesn't care about
827
2>...
828
$ bzr commit -q --strict -m 'No more conflicts nor unknown files'
4597.3.31 by Vincent Ladeuil
Implement --interactive for MissingParent.
829
""")
830
4597.3.67 by Vincent Ladeuil
Settle with --take-this and --take-other as action names.
831
    def test_resolve_taking_other(self):
4597.3.31 by Vincent Ladeuil
Implement --interactive for MissingParent.
832
        self.run_script("""
4597.3.67 by Vincent Ladeuil
Settle with --take-this and --take-other as action names.
833
$ bzr resolve --take-other dir
5422.3.4 by Martin Pool
Update test_resolve to pass --quiet or ignore command output it doesn't care about
834
2>...
835
$ bzr commit -q --strict -m 'No more conflicts nor unknown files'
4597.3.31 by Vincent Ladeuil
Implement --interactive for MissingParent.
836
""")
837
4597.3.12 by Vincent Ladeuil
Start writing tests for all expected conflict resolution actions.
838
839
class TestResolveDeletingParent(TestResolveConflicts):
840
841
    preamble = """
4597.3.15 by Vincent Ladeuil
Update to new shell-like tests syntax.
842
$ bzr init trunk
5422.3.4 by Martin Pool
Update test_resolve to pass --quiet or ignore command output it doesn't care about
843
...
4597.3.15 by Vincent Ladeuil
Update to new shell-like tests syntax.
844
$ cd trunk
845
$ mkdir dir
846
$ echo 'trunk content' >dir/file
5422.3.4 by Martin Pool
Update test_resolve to pass --quiet or ignore command output it doesn't care about
847
$ bzr add -q
848
$ bzr commit -m 'Create trunk' -q
849
$ bzr rm -q dir/file --force
850
$ bzr rm -q dir --force
851
$ bzr commit -q -m 'Remove dir/file'
852
$ bzr branch -q . -r 1 ../branch
4597.3.15 by Vincent Ladeuil
Update to new shell-like tests syntax.
853
$ cd ../branch
854
$ echo 'branch content' >dir/file2
5422.3.4 by Martin Pool
Update test_resolve to pass --quiet or ignore command output it doesn't care about
855
$ bzr add -q dir/file2
856
$ bzr commit -q -m 'Add dir/file2 in branch'
4597.3.15 by Vincent Ladeuil
Update to new shell-like tests syntax.
857
$ bzr merge ../trunk
4597.3.12 by Vincent Ladeuil
Start writing tests for all expected conflict resolution actions.
858
2>-D  dir/file
859
2>Conflict: can't delete dir because it is not empty.  Not deleting.
860
2>Conflict because dir is not versioned, but has versioned children.  Versioned directory.
861
2>2 conflicts encountered.
862
"""
863
864
    def test_keep_them_all(self):
865
        self.run_script("""
4597.3.15 by Vincent Ladeuil
Update to new shell-like tests syntax.
866
$ bzr resolve dir
6138.3.5 by Jonathan Riddell
make the test suite pass
867
2>2 conflicts resolved, 0 remaining
5422.3.4 by Martin Pool
Update test_resolve to pass --quiet or ignore command output it doesn't care about
868
$ bzr commit -q --strict -m 'No more conflicts nor unknown files'
4597.3.12 by Vincent Ladeuil
Start writing tests for all expected conflict resolution actions.
869
""")
870
871
    def test_adopt_child(self):
872
        self.run_script("""
5422.3.4 by Martin Pool
Update test_resolve to pass --quiet or ignore command output it doesn't care about
873
$ bzr mv -q dir/file2 file2
874
$ bzr rm -q dir --force
4597.3.15 by Vincent Ladeuil
Update to new shell-like tests syntax.
875
$ bzr resolve dir
6138.3.5 by Jonathan Riddell
make the test suite pass
876
2>2 conflicts resolved, 0 remaining
5422.3.4 by Martin Pool
Update test_resolve to pass --quiet or ignore command output it doesn't care about
877
$ bzr commit -q --strict -m 'No more conflicts nor unknown files'
4597.3.12 by Vincent Ladeuil
Start writing tests for all expected conflict resolution actions.
878
""")
879
880
    def test_kill_them_all(self):
881
        self.run_script("""
5422.3.4 by Martin Pool
Update test_resolve to pass --quiet or ignore command output it doesn't care about
882
$ bzr rm -q dir --force
4597.3.15 by Vincent Ladeuil
Update to new shell-like tests syntax.
883
$ bzr resolve dir
6138.3.5 by Jonathan Riddell
make the test suite pass
884
2>2 conflicts resolved, 0 remaining
5422.3.4 by Martin Pool
Update test_resolve to pass --quiet or ignore command output it doesn't care about
885
$ bzr commit -q --strict -m 'No more conflicts nor unknown files'
4597.3.12 by Vincent Ladeuil
Start writing tests for all expected conflict resolution actions.
886
""")
887
4597.3.67 by Vincent Ladeuil
Settle with --take-this and --take-other as action names.
888
    def test_resolve_taking_this(self):
4597.3.32 by Vincent Ladeuil
Implement --interactive for DeletingParent noting the inconsistency.
889
        self.run_script("""
4597.3.67 by Vincent Ladeuil
Settle with --take-this and --take-other as action names.
890
$ bzr resolve --take-this dir
6138.3.5 by Jonathan Riddell
make the test suite pass
891
2>2 conflicts resolved, 0 remaining
5422.3.4 by Martin Pool
Update test_resolve to pass --quiet or ignore command output it doesn't care about
892
$ bzr commit -q --strict -m 'No more conflicts nor unknown files'
4597.3.32 by Vincent Ladeuil
Implement --interactive for DeletingParent noting the inconsistency.
893
""")
894
4597.3.67 by Vincent Ladeuil
Settle with --take-this and --take-other as action names.
895
    def test_resolve_taking_other(self):
4597.3.32 by Vincent Ladeuil
Implement --interactive for DeletingParent noting the inconsistency.
896
        self.run_script("""
4597.3.67 by Vincent Ladeuil
Settle with --take-this and --take-other as action names.
897
$ bzr resolve --take-other dir
5422.3.4 by Martin Pool
Update test_resolve to pass --quiet or ignore command output it doesn't care about
898
2>deleted dir/file2
899
2>deleted dir
6138.3.5 by Jonathan Riddell
make the test suite pass
900
2>2 conflicts resolved, 0 remaining
5422.3.4 by Martin Pool
Update test_resolve to pass --quiet or ignore command output it doesn't care about
901
$ bzr commit -q --strict -m 'No more conflicts nor unknown files'
4597.3.32 by Vincent Ladeuil
Implement --interactive for DeletingParent noting the inconsistency.
902
""")
903
4597.3.12 by Vincent Ladeuil
Start writing tests for all expected conflict resolution actions.
904
4597.8.7 by Vincent Ladeuil
Add whitebox tests for ParentLoop.
905
class TestResolveParentLoop(TestParametrizedResolveConflicts):
906
4597.13.3 by Vincent Ladeuil
Switch to load_tests_apply_scenarios.
907
    _conflict_type = conflicts.ParentLoop
4597.10.1 by Vincent Ladeuil
Refactor to better handle various conflict types.
908
909
    _this_args = None
910
    _other_args = None
911
4597.13.3 by Vincent Ladeuil
Switch to load_tests_apply_scenarios.
912
    # Each side dict additionally defines:
913
    # - dir_id: the directory being moved
914
    # - target_id: The target directory
915
    # - xfail: whether the test is expected to fail if the action is
916
    #   involved as 'other'
917
    scenarios = mirror_scenarios(
918
        [
4597.10.8 by Vincent Ladeuil
Separate actions and conflict attributes.
919
            # Dirs moved into each other
920
            (dict(_base_actions='create_dir1_dir2'),
921
             ('dir1_into_dir2',
922
              dict(actions='move_dir1_into_dir2', check='dir1_moved',
923
                   dir_id='dir1-id', target_id='dir2-id', xfail=False)),
924
             ('dir2_into_dir1',
925
              dict(actions='move_dir2_into_dir1', check='dir2_moved',
926
                   dir_id='dir2-id', target_id='dir1-id', xfail=False))),
927
            # Subdirs moved into each other
928
            (dict(_base_actions='create_dir1_4'),
929
             ('dir1_into_dir4',
930
              dict(actions='move_dir1_into_dir4', check='dir1_2_moved',
931
                   dir_id='dir1-id', target_id='dir4-id', xfail=True)),
932
             ('dir3_into_dir2',
933
              dict(actions='move_dir3_into_dir2', check='dir3_4_moved',
934
                   dir_id='dir3-id', target_id='dir2-id', xfail=True))),
4597.13.3 by Vincent Ladeuil
Switch to load_tests_apply_scenarios.
935
            ])
4597.8.7 by Vincent Ladeuil
Add whitebox tests for ParentLoop.
936
937
    def do_create_dir1_dir2(self):
4597.10.8 by Vincent Ladeuil
Separate actions and conflict attributes.
938
        return [('add', ('dir1', 'dir1-id', 'directory', '')),
939
                ('add', ('dir2', 'dir2-id', 'directory', '')),]
4597.8.7 by Vincent Ladeuil
Add whitebox tests for ParentLoop.
940
4597.8.8 by Vincent Ladeuil
Exhibit bug #537956.
941
    def do_move_dir1_into_dir2(self):
4597.10.8 by Vincent Ladeuil
Separate actions and conflict attributes.
942
        return [('rename', ('dir1', 'dir2/dir1'))]
4597.8.7 by Vincent Ladeuil
Add whitebox tests for ParentLoop.
943
944
    def check_dir1_moved(self):
5784.1.3 by Martin Pool
Switch away from using failUnlessExists and failIfExists
945
        self.assertPathDoesNotExist('branch/dir1')
946
        self.assertPathExists('branch/dir2/dir1')
4597.8.7 by Vincent Ladeuil
Add whitebox tests for ParentLoop.
947
4597.8.8 by Vincent Ladeuil
Exhibit bug #537956.
948
    def do_move_dir2_into_dir1(self):
4597.10.8 by Vincent Ladeuil
Separate actions and conflict attributes.
949
        return [('rename', ('dir2', 'dir1/dir2'))]
4597.8.7 by Vincent Ladeuil
Add whitebox tests for ParentLoop.
950
951
    def check_dir2_moved(self):
5784.1.3 by Martin Pool
Switch away from using failUnlessExists and failIfExists
952
        self.assertPathDoesNotExist('branch/dir2')
953
        self.assertPathExists('branch/dir1/dir2')
4597.8.7 by Vincent Ladeuil
Add whitebox tests for ParentLoop.
954
4597.8.8 by Vincent Ladeuil
Exhibit bug #537956.
955
    def do_create_dir1_4(self):
4597.10.8 by Vincent Ladeuil
Separate actions and conflict attributes.
956
        return [('add', ('dir1', 'dir1-id', 'directory', '')),
957
                ('add', ('dir1/dir2', 'dir2-id', 'directory', '')),
958
                ('add', ('dir3', 'dir3-id', 'directory', '')),
959
                ('add', ('dir3/dir4', 'dir4-id', 'directory', '')),]
4597.8.8 by Vincent Ladeuil
Exhibit bug #537956.
960
961
    def do_move_dir1_into_dir4(self):
4597.10.8 by Vincent Ladeuil
Separate actions and conflict attributes.
962
        return [('rename', ('dir1', 'dir3/dir4/dir1'))]
4597.8.8 by Vincent Ladeuil
Exhibit bug #537956.
963
964
    def check_dir1_2_moved(self):
5784.1.3 by Martin Pool
Switch away from using failUnlessExists and failIfExists
965
        self.assertPathDoesNotExist('branch/dir1')
966
        self.assertPathExists('branch/dir3/dir4/dir1')
967
        self.assertPathExists('branch/dir3/dir4/dir1/dir2')
4597.8.8 by Vincent Ladeuil
Exhibit bug #537956.
968
969
    def do_move_dir3_into_dir2(self):
4597.10.8 by Vincent Ladeuil
Separate actions and conflict attributes.
970
        return [('rename', ('dir3', 'dir1/dir2/dir3'))]
4597.8.8 by Vincent Ladeuil
Exhibit bug #537956.
971
972
    def check_dir3_4_moved(self):
5784.1.3 by Martin Pool
Switch away from using failUnlessExists and failIfExists
973
        self.assertPathDoesNotExist('branch/dir3')
974
        self.assertPathExists('branch/dir1/dir2/dir3')
975
        self.assertPathExists('branch/dir1/dir2/dir3/dir4')
4597.8.8 by Vincent Ladeuil
Exhibit bug #537956.
976
4597.8.7 by Vincent Ladeuil
Add whitebox tests for ParentLoop.
977
    def _get_resolve_path_arg(self, wt, action):
4597.10.9 by Vincent Ladeuil
More doc.
978
        # ParentLoop says: moving <conflict_path> into <path>. Cancelled move.
4597.8.7 by Vincent Ladeuil
Add whitebox tests for ParentLoop.
979
        # But since <path> doesn't exist in the working tree, we need to use
4597.10.9 by Vincent Ladeuil
More doc.
980
        # <conflict_path> instead, and that, in turn, is given by dir_id. Pfew.
4597.10.8 by Vincent Ladeuil
Separate actions and conflict attributes.
981
        return wt.id2path(self._other['dir_id'])
4597.8.7 by Vincent Ladeuil
Add whitebox tests for ParentLoop.
982
983
    def assertParentLoop(self, wt, c):
4597.10.8 by Vincent Ladeuil
Separate actions and conflict attributes.
984
        self.assertEqual(self._other['dir_id'], c.file_id)
985
        self.assertEqual(self._other['target_id'], c.conflict_file_id)
4597.8.8 by Vincent Ladeuil
Exhibit bug #537956.
986
        # The conflict paths are irrelevant (they are deterministic but not
987
        # worth checking since they don't provide the needed information
988
        # anyway)
4597.10.8 by Vincent Ladeuil
Separate actions and conflict attributes.
989
        if self._other['xfail']:
990
            # It's a bit hackish to raise from here relying on being called for
991
            # both tests but this avoid overriding test_resolve_taking_other
6050.1.2 by Martin
Make tests raising KnownFailure use the knownFailure method instead
992
            self.knownFailure(
4597.10.4 by Vincent Ladeuil
Handle TestResolveParentLoop expected failures more precisely.
993
                "ParentLoop doesn't carry enough info to resolve --take-other")
4597.8.7 by Vincent Ladeuil
Add whitebox tests for ParentLoop.
994
    _assert_conflict = assertParentLoop
995
996
4597.3.12 by Vincent Ladeuil
Start writing tests for all expected conflict resolution actions.
997
class TestResolveNonDirectoryParent(TestResolveConflicts):
998
999
    preamble = """
4597.3.15 by Vincent Ladeuil
Update to new shell-like tests syntax.
1000
$ bzr init trunk
5422.3.4 by Martin Pool
Update test_resolve to pass --quiet or ignore command output it doesn't care about
1001
...
4597.3.15 by Vincent Ladeuil
Update to new shell-like tests syntax.
1002
$ cd trunk
1003
$ bzr mkdir foo
5422.3.4 by Martin Pool
Update test_resolve to pass --quiet or ignore command output it doesn't care about
1004
...
1005
$ bzr commit -m 'Create trunk' -q
4597.3.15 by Vincent Ladeuil
Update to new shell-like tests syntax.
1006
$ echo "Boing" >foo/bar
5422.3.4 by Martin Pool
Update test_resolve to pass --quiet or ignore command output it doesn't care about
1007
$ bzr add -q foo/bar
1008
$ bzr commit -q -m 'Add foo/bar'
1009
$ bzr branch -q . -r 1 ../branch
4597.3.15 by Vincent Ladeuil
Update to new shell-like tests syntax.
1010
$ cd ../branch
1011
$ rm -r foo
1012
$ echo "Boo!" >foo
5422.3.4 by Martin Pool
Update test_resolve to pass --quiet or ignore command output it doesn't care about
1013
$ bzr commit -q -m 'foo is now a file'
4597.3.15 by Vincent Ladeuil
Update to new shell-like tests syntax.
1014
$ bzr merge ../trunk
4597.3.12 by Vincent Ladeuil
Start writing tests for all expected conflict resolution actions.
1015
2>+N  foo.new/bar
1016
2>RK  foo => foo.new/
1017
# FIXME: The message is misleading, foo.new *is* a directory when the message
1018
# is displayed -- vila 090916
1019
2>Conflict: foo.new is not a directory, but has files in it.  Created directory.
1020
2>1 conflicts encountered.
1021
"""
1022
4597.3.67 by Vincent Ladeuil
Settle with --take-this and --take-other as action names.
1023
    def test_take_this(self):
4597.3.12 by Vincent Ladeuil
Start writing tests for all expected conflict resolution actions.
1024
        self.run_script("""
5422.3.4 by Martin Pool
Update test_resolve to pass --quiet or ignore command output it doesn't care about
1025
$ bzr rm -q foo.new --force
4597.3.12 by Vincent Ladeuil
Start writing tests for all expected conflict resolution actions.
1026
# FIXME: Isn't it weird that foo is now unkown even if foo.new has been put
1027
# aside ? -- vila 090916
5422.3.4 by Martin Pool
Update test_resolve to pass --quiet or ignore command output it doesn't care about
1028
$ bzr add -q foo
4597.3.15 by Vincent Ladeuil
Update to new shell-like tests syntax.
1029
$ bzr resolve foo.new
6138.3.5 by Jonathan Riddell
make the test suite pass
1030
2>1 conflict resolved, 0 remaining
5422.3.4 by Martin Pool
Update test_resolve to pass --quiet or ignore command output it doesn't care about
1031
$ bzr commit -q --strict -m 'No more conflicts nor unknown files'
4597.3.12 by Vincent Ladeuil
Start writing tests for all expected conflict resolution actions.
1032
""")
1033
4597.3.67 by Vincent Ladeuil
Settle with --take-this and --take-other as action names.
1034
    def test_take_other(self):
4597.3.35 by Vincent Ladeuil
Implement --interactive for NonDirectoryParent, sort of.
1035
        self.run_script("""
5422.3.4 by Martin Pool
Update test_resolve to pass --quiet or ignore command output it doesn't care about
1036
$ bzr rm -q foo --force
1037
$ bzr mv -q foo.new foo
4597.3.35 by Vincent Ladeuil
Implement --interactive for NonDirectoryParent, sort of.
1038
$ bzr resolve foo
6138.3.5 by Jonathan Riddell
make the test suite pass
1039
2>1 conflict resolved, 0 remaining
5422.3.4 by Martin Pool
Update test_resolve to pass --quiet or ignore command output it doesn't care about
1040
$ bzr commit -q --strict -m 'No more conflicts nor unknown files'
4597.3.35 by Vincent Ladeuil
Implement --interactive for NonDirectoryParent, sort of.
1041
""")
1042
4597.3.67 by Vincent Ladeuil
Settle with --take-this and --take-other as action names.
1043
    def test_resolve_taking_this(self):
4597.3.35 by Vincent Ladeuil
Implement --interactive for NonDirectoryParent, sort of.
1044
        self.run_script("""
4597.3.67 by Vincent Ladeuil
Settle with --take-this and --take-other as action names.
1045
$ bzr resolve --take-this foo.new
5422.3.4 by Martin Pool
Update test_resolve to pass --quiet or ignore command output it doesn't care about
1046
2>...
1047
$ bzr commit -q --strict -m 'No more conflicts nor unknown files'
4597.3.35 by Vincent Ladeuil
Implement --interactive for NonDirectoryParent, sort of.
1048
""")
1049
4597.3.67 by Vincent Ladeuil
Settle with --take-this and --take-other as action names.
1050
    def test_resolve_taking_other(self):
4597.3.35 by Vincent Ladeuil
Implement --interactive for NonDirectoryParent, sort of.
1051
        self.run_script("""
4597.3.67 by Vincent Ladeuil
Settle with --take-this and --take-other as action names.
1052
$ bzr resolve --take-other foo.new
5422.3.4 by Martin Pool
Update test_resolve to pass --quiet or ignore command output it doesn't care about
1053
2>...
1054
$ bzr commit -q --strict -m 'No more conflicts nor unknown files'
4597.3.35 by Vincent Ladeuil
Implement --interactive for NonDirectoryParent, sort of.
1055
""")
1056
4597.3.12 by Vincent Ladeuil
Start writing tests for all expected conflict resolution actions.
1057
1058
class TestMalformedTransform(script.TestCaseWithTransportAndScript):
1059
1060
    def test_bug_430129(self):
1061
        # This is nearly like TestResolveNonDirectoryParent but with branch and
1062
        # trunk switched. As such it should certainly produce the same
1063
        # conflict.
6015.47.1 by Vincent Ladeuil
Turn MalformedTransform into an InternalBzrError so users get a traceback.
1064
        self.assertRaises(errors.MalformedTransform,
1065
                          self.run_script,"""
4597.3.15 by Vincent Ladeuil
Update to new shell-like tests syntax.
1066
$ bzr init trunk
5422.3.4 by Martin Pool
Update test_resolve to pass --quiet or ignore command output it doesn't care about
1067
...
4597.3.15 by Vincent Ladeuil
Update to new shell-like tests syntax.
1068
$ cd trunk
1069
$ bzr mkdir foo
5422.3.4 by Martin Pool
Update test_resolve to pass --quiet or ignore command output it doesn't care about
1070
...
1071
$ bzr commit -m 'Create trunk' -q
4597.3.15 by Vincent Ladeuil
Update to new shell-like tests syntax.
1072
$ rm -r foo
1073
$ echo "Boo!" >foo
5422.3.4 by Martin Pool
Update test_resolve to pass --quiet or ignore command output it doesn't care about
1074
$ bzr commit -m 'foo is now a file' -q
1075
$ bzr branch -q . -r 1 ../branch -q
4597.3.15 by Vincent Ladeuil
Update to new shell-like tests syntax.
1076
$ cd ../branch
1077
$ echo "Boing" >foo/bar
5422.3.4 by Martin Pool
Update test_resolve to pass --quiet or ignore command output it doesn't care about
1078
$ bzr add -q foo/bar -q
1079
$ bzr commit -m 'Add foo/bar' -q
4597.3.15 by Vincent Ladeuil
Update to new shell-like tests syntax.
1080
$ bzr merge ../trunk
4597.3.12 by Vincent Ladeuil
Start writing tests for all expected conflict resolution actions.
1081
2>bzr: ERROR: Tree transform is malformed [('unversioned executability', 'new-1')]
1082
""")
4597.3.51 by Vincent Ladeuil
Implement conflicts.ResolveActionOption.
1083
5050.63.2 by Vincent Ladeuil
The file should be in a subdir to reproduce the bug.
1084
5050.73.6 by Vincent Ladeuil
Reproduce bug #805809.
1085
class TestNoFinalPath(script.TestCaseWithTransportAndScript):
1086
1087
    def test_bug_805809(self):
1088
        self.run_script("""
1089
$ bzr init trunk
1090
Created a standalone tree (format: 2a)
1091
$ cd trunk
1092
$ echo trunk >file
1093
$ bzr add
1094
adding file
1095
$ bzr commit -m 'create file on trunk'
1096
2>Committing to: .../trunk/
1097
2>added file
1098
2>Committed revision 1.
5050.73.7 by Vincent Ladeuil
Slightly simpler test.
1099
# Create a debian branch based on trunk
5050.73.6 by Vincent Ladeuil
Reproduce bug #805809.
1100
$ cd ..
1101
$ bzr branch trunk -r 1 debian
6143.1.4 by Jonathan Riddell
update tests
1102
2>Branched 1 revision.
5050.73.6 by Vincent Ladeuil
Reproduce bug #805809.
1103
$ cd debian
1104
$ mkdir dir
1105
$ bzr add
1106
adding dir
1107
$ bzr mv file dir
1108
file => dir/file
1109
$ bzr commit -m 'rename file to dir/file for debian'
1110
2>Committing to: .../debian/
1111
2>added dir
1112
2>renamed file => dir/file
1113
2>Committed revision 2.
5050.73.7 by Vincent Ladeuil
Slightly simpler test.
1114
# Create an experimental branch with a new root-id
5050.73.6 by Vincent Ladeuil
Reproduce bug #805809.
1115
$ cd ..
1116
$ bzr init experimental
5609.49.2 by Vincent Ladeuil
Fix pqm failure.
1117
Created a standalone tree (format: 2a)
5050.73.6 by Vincent Ladeuil
Reproduce bug #805809.
1118
$ cd experimental
5050.73.13 by Vincent Ladeuil
Fix the test for trunk where merging into an empty branch now behave differently
1119
# Work around merging into empty branch not being supported
1120
# (http://pad.lv/308562)
1121
$ echo something >not-empty
1122
$ bzr add
1123
adding not-empty
1124
$ bzr commit -m 'Add some content in experimental'
1125
2>Committing to: .../experimental/
1126
2>added not-empty
1127
2>Committed revision 1.
5050.73.7 by Vincent Ladeuil
Slightly simpler test.
1128
# merge debian even without a common ancestor
5050.73.6 by Vincent Ladeuil
Reproduce bug #805809.
1129
$ bzr merge ../debian -r0..2
1130
2>+N  dir/
1131
2>+N  dir/file
1132
2>All changes applied successfully.
5050.73.7 by Vincent Ladeuil
Slightly simpler test.
1133
$ bzr commit -m 'merging debian into experimental'
5050.73.6 by Vincent Ladeuil
Reproduce bug #805809.
1134
2>Committing to: .../experimental/
5050.73.13 by Vincent Ladeuil
Fix the test for trunk where merging into an empty branch now behave differently
1135
2>added dir
1136
2>added dir/file
1137
2>Committed revision 2.
5050.73.7 by Vincent Ladeuil
Slightly simpler test.
1138
# Create an ubuntu branch with yet another root-id
5050.73.6 by Vincent Ladeuil
Reproduce bug #805809.
1139
$ cd ..
1140
$ bzr init ubuntu
5609.49.2 by Vincent Ladeuil
Fix pqm failure.
1141
Created a standalone tree (format: 2a)
5050.73.6 by Vincent Ladeuil
Reproduce bug #805809.
1142
$ cd ubuntu
5050.73.13 by Vincent Ladeuil
Fix the test for trunk where merging into an empty branch now behave differently
1143
# Work around merging into empty branch not being supported
1144
# (http://pad.lv/308562)
1145
$ echo something >not-empty-ubuntu
1146
$ bzr add
1147
adding not-empty-ubuntu
1148
$ bzr commit -m 'Add some content in experimental'
1149
2>Committing to: .../ubuntu/
1150
2>added not-empty-ubuntu
1151
2>Committed revision 1.
5050.73.7 by Vincent Ladeuil
Slightly simpler test.
1152
# Also merge debian
5050.73.6 by Vincent Ladeuil
Reproduce bug #805809.
1153
$ bzr merge ../debian -r0..2
1154
2>+N  dir/
1155
2>+N  dir/file
1156
2>All changes applied successfully.
1157
$ bzr commit -m 'merging debian'
1158
2>Committing to: .../ubuntu/
5050.73.13 by Vincent Ladeuil
Fix the test for trunk where merging into an empty branch now behave differently
1159
2>added dir
1160
2>added dir/file
1161
2>Committed revision 2.
5050.73.7 by Vincent Ladeuil
Slightly simpler test.
1162
# Now try to merge experimental
5050.73.6 by Vincent Ladeuil
Reproduce bug #805809.
1163
$ bzr merge ../experimental
5050.73.13 by Vincent Ladeuil
Fix the test for trunk where merging into an empty branch now behave differently
1164
2>+N  not-empty
5050.73.6 by Vincent Ladeuil
Reproduce bug #805809.
1165
2>Path conflict: dir / dir
1166
2>1 conflicts encountered.
1167
""")
1168
1169
4597.3.51 by Vincent Ladeuil
Implement conflicts.ResolveActionOption.
1170
class TestResolveActionOption(tests.TestCase):
1171
1172
    def setUp(self):
1173
        super(TestResolveActionOption, self).setUp()
1174
        self.options = [conflicts.ResolveActionOption()]
1175
        self.parser = option.get_optparser(dict((o.name, o)
1176
                                                for o in self.options))
1177
1178
    def parse(self, args):
1179
        return self.parser.parse_args(args)
1180
1181
    def test_unknown_action(self):
1182
        self.assertRaises(errors.BadOptionValue,
1183
                          self.parse, ['--action', 'take-me-to-the-moon'])
1184
1185
    def test_done(self):
1186
        opts, args = self.parse(['--action', 'done'])
1187
        self.assertEqual({'action':'done'}, opts)
1188
4597.3.67 by Vincent Ladeuil
Settle with --take-this and --take-other as action names.
1189
    def test_take_this(self):
1190
        opts, args = self.parse(['--action', 'take-this'])
1191
        self.assertEqual({'action': 'take_this'}, opts)
1192
        opts, args = self.parse(['--take-this'])
1193
        self.assertEqual({'action': 'take_this'}, opts)
4597.3.51 by Vincent Ladeuil
Implement conflicts.ResolveActionOption.
1194
4597.3.67 by Vincent Ladeuil
Settle with --take-this and --take-other as action names.
1195
    def test_take_other(self):
1196
        opts, args = self.parse(['--action', 'take-other'])
1197
        self.assertEqual({'action': 'take_other'}, opts)
1198
        opts, args = self.parse(['--take-other'])
1199
        self.assertEqual({'action': 'take_other'}, opts)