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