/brz/remove-bazaar

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