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