/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_workingtree.py

  • Committer: Robert Collins
  • Date: 2007-03-06 12:28:18 UTC
  • mto: (2321.1.1 integration)
  • mto: This revision was merged to the branch mainline in revision 2322.
  • Revision ID: robertc@robertcollins.net-20070306122818-xk0lc3l01ecl6vbc
Get merge_nested finally working: change nested tree iterators to take file_ids, and ensure the right branch is connected to in the merge logic. May not be suitable for shared repositories yet.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005-2011 Canonical Ltd
 
1
# Copyright (C) 2005, 2006 Canonical Ltd
2
2
# Authors:  Robert Collins <robert.collins@canonical.com>
3
3
#
4
4
# This program is free software; you can redistribute it and/or modify
13
13
#
14
14
# You should have received a copy of the GNU General Public License
15
15
# along with this program; if not, write to the Free Software
16
 
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 
16
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
17
 
 
18
from cStringIO import StringIO
 
19
import os
17
20
 
18
21
from bzrlib import (
19
22
    bzrdir,
20
23
    conflicts,
21
24
    errors,
22
 
    symbol_versioning,
23
 
    transport,
24
25
    workingtree,
25
 
    workingtree_3,
26
 
    workingtree_4,
27
26
    )
 
27
from bzrlib.branch import Branch
 
28
from bzrlib.bzrdir import BzrDir
28
29
from bzrlib.lockdir import LockDir
29
30
from bzrlib.mutabletree import needs_tree_write_lock
 
31
from bzrlib.symbol_versioning import zero_thirteen
30
32
from bzrlib.tests import TestCase, TestCaseWithTransport, TestSkipped
 
33
from bzrlib.transport import get_transport
31
34
from bzrlib.workingtree import (
32
35
    TreeEntry,
33
36
    TreeDirectory,
63
66
class TestDefaultFormat(TestCaseWithTransport):
64
67
 
65
68
    def test_get_set_default_format(self):
66
 
        old_format = workingtree.format_registry.get_default()
67
 
        # default is 6
68
 
        self.assertTrue(isinstance(old_format, workingtree_4.WorkingTreeFormat6))
69
 
        workingtree.format_registry.set_default(SampleTreeFormat())
70
 
        try:
71
 
            # the default branch format is used by the meta dir format
72
 
            # which is not the default bzrdir format at this point
73
 
            dir = bzrdir.BzrDirMetaFormat1().initialize('.')
74
 
            dir.create_repository()
75
 
            dir.create_branch()
76
 
            result = dir.create_workingtree()
77
 
            self.assertEqual(result, 'A tree')
78
 
        finally:
79
 
            workingtree.format_registry.set_default(old_format)
80
 
        self.assertEqual(old_format, workingtree.format_registry.get_default())
81
 
 
82
 
    def test_get_set_default_format_by_key(self):
83
 
        old_format = workingtree.format_registry.get_default()
84
 
        # default is 6
85
 
        format = SampleTreeFormat()
86
 
        workingtree.format_registry.register(format)
87
 
        self.addCleanup(workingtree.format_registry.remove, format)
88
 
        self.assertTrue(isinstance(old_format, workingtree_4.WorkingTreeFormat6))
89
 
        workingtree.format_registry.set_default_key(format.get_format_string())
90
 
        try:
91
 
            # the default branch format is used by the meta dir format
92
 
            # which is not the default bzrdir format at this point
93
 
            dir = bzrdir.BzrDirMetaFormat1().initialize('.')
94
 
            dir.create_repository()
95
 
            dir.create_branch()
96
 
            result = dir.create_workingtree()
97
 
            self.assertEqual(result, 'A tree')
98
 
        finally:
99
 
            workingtree.format_registry.set_default_key(
100
 
                old_format.get_format_string())
101
 
        self.assertEqual(old_format, workingtree.format_registry.get_default())
102
 
 
103
 
    def test_open(self):
104
 
        tree = self.make_branch_and_tree('.')
105
 
        open_direct = workingtree.WorkingTree.open('.')
106
 
        self.assertEqual(tree.basedir, open_direct.basedir)
107
 
        open_no_args = workingtree.WorkingTree.open()
108
 
        self.assertEqual(tree.basedir, open_no_args.basedir)
109
 
 
110
 
    def test_open_containing(self):
111
 
        tree = self.make_branch_and_tree('.')
112
 
        open_direct, relpath = workingtree.WorkingTree.open_containing('.')
113
 
        self.assertEqual(tree.basedir, open_direct.basedir)
114
 
        self.assertEqual('', relpath)
115
 
        open_no_args, relpath = workingtree.WorkingTree.open_containing()
116
 
        self.assertEqual(tree.basedir, open_no_args.basedir)
117
 
        self.assertEqual('', relpath)
118
 
        open_subdir, relpath = workingtree.WorkingTree.open_containing('subdir')
119
 
        self.assertEqual(tree.basedir, open_subdir.basedir)
120
 
        self.assertEqual('subdir', relpath)
 
69
        old_format = workingtree.WorkingTreeFormat.get_default_format()
 
70
        # default is 3
 
71
        self.assertTrue(isinstance(old_format, workingtree.WorkingTreeFormat3))
 
72
        workingtree.WorkingTreeFormat.set_default_format(SampleTreeFormat())
 
73
        try:
 
74
            # the default branch format is used by the meta dir format
 
75
            # which is not the default bzrdir format at this point
 
76
            dir = bzrdir.BzrDirMetaFormat1().initialize('.')
 
77
            dir.create_repository()
 
78
            dir.create_branch()
 
79
            result = dir.create_workingtree()
 
80
            self.assertEqual(result, 'A tree')
 
81
        finally:
 
82
            workingtree.WorkingTreeFormat.set_default_format(old_format)
 
83
        self.assertEqual(old_format, workingtree.WorkingTreeFormat.get_default_format())
121
84
 
122
85
 
123
86
class SampleTreeFormat(workingtree.WorkingTreeFormat):
124
87
    """A sample format
125
88
 
126
 
    this format is initializable, unsupported to aid in testing the
 
89
    this format is initializable, unsupported to aid in testing the 
127
90
    open and open_downlevel routines.
128
91
    """
129
92
 
131
94
        """See WorkingTreeFormat.get_format_string()."""
132
95
        return "Sample tree format."
133
96
 
134
 
    def initialize(self, a_bzrdir, revision_id=None, from_branch=None,
135
 
                   accelerator_tree=None, hardlink=False):
 
97
    def initialize(self, a_bzrdir, revision_id=None):
136
98
        """Sample branches cannot be created."""
137
99
        t = a_bzrdir.get_workingtree_transport(self)
138
100
        t.put_bytes('format', self.get_format_string())
145
107
        return "opened tree."
146
108
 
147
109
 
148
 
class SampleExtraTreeFormat(workingtree.WorkingTreeFormat):
149
 
    """A sample format that does not support use in a metadir.
150
 
 
151
 
    """
152
 
 
153
 
    def get_format_string(self):
154
 
        # Not usable in a metadir, so no format string
155
 
        return None
156
 
 
157
 
    def initialize(self, a_bzrdir, revision_id=None, from_branch=None,
158
 
                   accelerator_tree=None, hardlink=False):
159
 
        raise NotImplementedError(self.initialize)
160
 
 
161
 
    def is_supported(self):
162
 
        return False
163
 
 
164
 
    def open(self, transport, _found=False):
165
 
        raise NotImplementedError(self.open)
166
 
 
167
 
 
168
110
class TestWorkingTreeFormat(TestCaseWithTransport):
169
111
    """Tests for the WorkingTreeFormat facility."""
170
112
 
171
 
    def test_find_format_string(self):
172
 
        # is the right format object found for a working tree?
173
 
        branch = self.make_branch('branch')
174
 
        self.assertRaises(errors.NoWorkingTree,
175
 
            workingtree.WorkingTreeFormat.find_format_string, branch.bzrdir)
176
 
        transport = branch.bzrdir.get_workingtree_transport(None)
177
 
        transport.mkdir('.')
178
 
        transport.put_bytes("format", "some format name")
179
 
        # The format does not have to be known by Bazaar,
180
 
        # find_format_string just retrieves the name
181
 
        self.assertEquals("some format name",
182
 
            workingtree.WorkingTreeFormat.find_format_string(branch.bzrdir))
183
 
 
184
113
    def test_find_format(self):
185
114
        # is the right format object found for a working tree?
186
115
        # create a branch with a few known format objects.
190
119
            dir.create_repository()
191
120
            dir.create_branch()
192
121
            format.initialize(dir)
193
 
            t = transport.get_transport(url)
 
122
            t = get_transport(url)
194
123
            found_format = workingtree.WorkingTreeFormat.find_format(dir)
195
 
            self.assertIsInstance(found_format, format.__class__)
196
 
        check_format(workingtree_3.WorkingTreeFormat3(), "bar")
197
 
 
 
124
            self.failUnless(isinstance(found_format, format.__class__))
 
125
        check_format(workingtree.WorkingTreeFormat3(), "bar")
 
126
        
198
127
    def test_find_format_no_tree(self):
199
128
        dir = bzrdir.BzrDirMetaFormat1().initialize('.')
200
129
        self.assertRaises(errors.NoWorkingTree,
219
148
        # make a branch
220
149
        format.initialize(dir)
221
150
        # register a format for it.
222
 
        self.applyDeprecated(symbol_versioning.deprecated_in((2, 4, 0)),
223
 
            workingtree.WorkingTreeFormat.register_format, format)
224
 
        self.assertTrue(format in 
225
 
            self.applyDeprecated(symbol_versioning.deprecated_in((2, 4, 0)),
226
 
                workingtree.WorkingTreeFormat.get_formats))
 
151
        workingtree.WorkingTreeFormat.register_format(format)
227
152
        # which branch.Open will refuse (not supported)
228
153
        self.assertRaises(errors.UnsupportedFormatError, workingtree.WorkingTree.open, '.')
229
154
        # but open_downlevel will work
230
155
        self.assertEqual(format.open(dir), workingtree.WorkingTree.open_downlevel('.'))
231
156
        # unregister the format
232
 
        self.applyDeprecated(symbol_versioning.deprecated_in((2, 4, 0)),
233
 
            workingtree.WorkingTreeFormat.unregister_format, format)
234
 
        self.assertFalse(format in
235
 
            self.applyDeprecated(symbol_versioning.deprecated_in((2, 4, 0)),
236
 
                workingtree.WorkingTreeFormat.get_formats))
237
 
 
238
 
 
239
 
class TestWorkingTreeFormatRegistry(TestCase):
240
 
 
241
 
    def setUp(self):
242
 
        super(TestWorkingTreeFormatRegistry, self).setUp()
243
 
        self.registry = workingtree.WorkingTreeFormatRegistry()
244
 
 
245
 
    def test_register_unregister_format(self):
246
 
        format = SampleTreeFormat()
247
 
        self.registry.register(format)
248
 
        self.assertEquals(format, self.registry.get("Sample tree format."))
249
 
        self.registry.remove(format)
250
 
        self.assertRaises(KeyError, self.registry.get, "Sample tree format.")
251
 
 
252
 
    def test_get_all(self):
253
 
        format = SampleTreeFormat()
254
 
        self.assertEquals([], self.registry._get_all())
255
 
        self.registry.register(format)
256
 
        self.assertEquals([format], self.registry._get_all())
257
 
 
258
 
    def test_register_extra(self):
259
 
        format = SampleExtraTreeFormat()
260
 
        self.assertEquals([], self.registry._get_all())
261
 
        self.registry.register_extra(format)
262
 
        self.assertEquals([format], self.registry._get_all())
263
 
 
264
 
    def test_register_extra_lazy(self):
265
 
        self.assertEquals([], self.registry._get_all())
266
 
        self.registry.register_extra_lazy("bzrlib.tests.test_workingtree",
267
 
            "SampleExtraTreeFormat")
268
 
        formats = self.registry._get_all()
269
 
        self.assertEquals(1, len(formats))
270
 
        self.assertIsInstance(formats[0], SampleExtraTreeFormat)
 
157
        workingtree.WorkingTreeFormat.unregister_format(format)
271
158
 
272
159
 
273
160
class TestWorkingTreeFormat3(TestCaseWithTransport):
277
164
        control = bzrdir.BzrDirMetaFormat1().initialize(self.get_url())
278
165
        control.create_repository()
279
166
        control.create_branch()
280
 
        tree = workingtree_3.WorkingTreeFormat3().initialize(control)
 
167
        tree = workingtree.WorkingTreeFormat3().initialize(control)
281
168
        # we want:
282
169
        # format 'Bazaar-NG Working Tree format 3'
283
170
        # inventory = blank inventory
287
174
        t = control.get_workingtree_transport(None)
288
175
        self.assertEqualDiff('Bazaar-NG Working Tree format 3',
289
176
                             t.get('format').read())
290
 
        self.assertEqualDiff(t.get('inventory').read(),
 
177
        self.assertEqualDiff(t.get('inventory').read(), 
291
178
                              '<inventory format="5">\n'
292
179
                              '</inventory>\n',
293
180
                             )
296
183
        self.assertFalse(t.has('inventory.basis'))
297
184
        # no last-revision file means 'None' or 'NULLREVISION'
298
185
        self.assertFalse(t.has('last-revision'))
299
 
        # TODO RBC 20060210 do a commit, check the inventory.basis is created
 
186
        # TODO RBC 20060210 do a commit, check the inventory.basis is created 
300
187
        # correctly and last-revision file becomes present.
301
188
 
302
189
    def test_uses_lockdir(self):
303
190
        """WorkingTreeFormat3 uses its own LockDir:
304
 
 
 
191
            
305
192
            - lock is a directory
306
193
            - when the WorkingTree is locked, LockDir can see that
307
194
        """
311
198
        repo = dir.create_repository()
312
199
        branch = dir.create_branch()
313
200
        try:
314
 
            tree = workingtree_3.WorkingTreeFormat3().initialize(dir)
 
201
            tree = workingtree.WorkingTreeFormat3().initialize(dir)
315
202
        except errors.NotLocalUrl:
316
203
            raise TestSkipped('Not a local URL')
317
204
        self.assertIsDirectory('.bzr', t)
328
215
        control = bzrdir.BzrDirMetaFormat1().initialize(self.get_url())
329
216
        control.create_repository()
330
217
        control.create_branch()
331
 
        tree = workingtree_3.WorkingTreeFormat3().initialize(control)
332
 
        tree._transport.delete("pending-merges")
 
218
        tree = workingtree.WorkingTreeFormat3().initialize(control)
 
219
        tree._control_files._transport.delete("pending-merges")
333
220
        self.assertEqual([], tree.get_parent_ids())
334
221
 
335
222
 
 
223
class TestFormat2WorkingTree(TestCaseWithTransport):
 
224
    """Tests that are specific to format 2 trees."""
 
225
 
 
226
    def create_format2_tree(self, url):
 
227
        return self.make_branch_and_tree(
 
228
            url, format=bzrdir.BzrDirFormat6())
 
229
 
 
230
    def test_conflicts(self):
 
231
        # test backwards compatability
 
232
        tree = self.create_format2_tree('.')
 
233
        self.assertRaises(errors.UnsupportedOperation, tree.set_conflicts,
 
234
                          None)
 
235
        file('lala.BASE', 'wb').write('labase')
 
236
        expected = conflicts.ContentsConflict('lala')
 
237
        self.assertEqual(list(tree.conflicts()), [expected])
 
238
        file('lala', 'wb').write('la')
 
239
        tree.add('lala', 'lala-id')
 
240
        expected = conflicts.ContentsConflict('lala', file_id='lala-id')
 
241
        self.assertEqual(list(tree.conflicts()), [expected])
 
242
        file('lala.THIS', 'wb').write('lathis')
 
243
        file('lala.OTHER', 'wb').write('laother')
 
244
        # When "text conflict"s happen, stem, THIS and OTHER are text
 
245
        expected = conflicts.TextConflict('lala', file_id='lala-id')
 
246
        self.assertEqual(list(tree.conflicts()), [expected])
 
247
        os.unlink('lala.OTHER')
 
248
        os.mkdir('lala.OTHER')
 
249
        expected = conflicts.ContentsConflict('lala', file_id='lala-id')
 
250
        self.assertEqual(list(tree.conflicts()), [expected])
 
251
 
 
252
 
 
253
class TestNonFormatSpecificCode(TestCaseWithTransport):
 
254
    """This class contains tests of workingtree that are not format specific."""
 
255
 
 
256
    def test_gen_file_id(self):
 
257
        file_id = self.applyDeprecated(zero_thirteen, workingtree.gen_file_id,
 
258
                                      'filename')
 
259
        self.assertStartsWith(file_id, 'filename-')
 
260
 
 
261
    def test_gen_root_id(self):
 
262
        file_id = self.applyDeprecated(zero_thirteen, workingtree.gen_root_id)
 
263
        self.assertStartsWith(file_id, 'tree_root-')
 
264
        
 
265
 
336
266
class InstrumentedTree(object):
337
267
    """A instrumented tree to check the needs_tree_write_lock decorator."""
338
268
 
350
280
    @needs_tree_write_lock
351
281
    def method_that_raises(self):
352
282
        """This method causes an exception when called with parameters.
353
 
 
 
283
        
354
284
        This allows the decorator code to be checked - it should still call
355
285
        unlock.
356
286
        """
367
297
        self.assertEqual(
368
298
            'method_with_tree_write_lock',
369
299
            tree.method_with_tree_write_lock.__name__)
370
 
        self.assertDocstring(
 
300
        self.assertEqual(
371
301
            "A lock_tree_write decorated method that returns its arguments.",
372
 
            tree.method_with_tree_write_lock)
 
302
            tree.method_with_tree_write_lock.__doc__)
373
303
        args = (1, 2, 3)
374
304
        kwargs = {'a':'b'}
375
305
        result = tree.method_with_tree_write_lock(1,2,3, a='b')
377
307
        self.assertEqual(['t', 'u'], tree._locks)
378
308
        self.assertRaises(TypeError, tree.method_that_raises, 'foo')
379
309
        self.assertEqual(['t', 'u', 't', 'u'], tree._locks)
380
 
 
381
 
 
382
 
class TestRevert(TestCaseWithTransport):
383
 
 
384
 
    def test_revert_conflicts_recursive(self):
385
 
        this_tree = self.make_branch_and_tree('this-tree')
386
 
        self.build_tree_contents([('this-tree/foo/',),
387
 
                                  ('this-tree/foo/bar', 'bar')])
388
 
        this_tree.add(['foo', 'foo/bar'])
389
 
        this_tree.commit('created foo/bar')
390
 
        other_tree = this_tree.bzrdir.sprout('other-tree').open_workingtree()
391
 
        self.build_tree_contents([('other-tree/foo/bar', 'baz')])
392
 
        other_tree.commit('changed bar')
393
 
        self.build_tree_contents([('this-tree/foo/bar', 'qux')])
394
 
        this_tree.commit('changed qux')
395
 
        this_tree.merge_from_branch(other_tree.branch)
396
 
        self.assertEqual(1, len(this_tree.conflicts()))
397
 
        this_tree.revert(['foo'])
398
 
        self.assertEqual(0, len(this_tree.conflicts()))
399
 
 
400
 
 
401
 
class TestAutoResolve(TestCaseWithTransport):
402
 
 
403
 
    def test_auto_resolve(self):
404
 
        base = self.make_branch_and_tree('base')
405
 
        self.build_tree_contents([('base/hello', 'Hello')])
406
 
        base.add('hello', 'hello_id')
407
 
        base.commit('Hello')
408
 
        other = base.bzrdir.sprout('other').open_workingtree()
409
 
        self.build_tree_contents([('other/hello', 'hELLO')])
410
 
        other.commit('Case switch')
411
 
        this = base.bzrdir.sprout('this').open_workingtree()
412
 
        self.assertPathExists('this/hello')
413
 
        self.build_tree_contents([('this/hello', 'Hello World')])
414
 
        this.commit('Add World')
415
 
        this.merge_from_branch(other.branch)
416
 
        self.assertEqual([conflicts.TextConflict('hello', 'hello_id')],
417
 
                         this.conflicts())
418
 
        this.auto_resolve()
419
 
        self.assertEqual([conflicts.TextConflict('hello', 'hello_id')],
420
 
                         this.conflicts())
421
 
        self.build_tree_contents([('this/hello', '<<<<<<<')])
422
 
        this.auto_resolve()
423
 
        self.assertEqual([conflicts.TextConflict('hello', 'hello_id')],
424
 
                         this.conflicts())
425
 
        self.build_tree_contents([('this/hello', '=======')])
426
 
        this.auto_resolve()
427
 
        self.assertEqual([conflicts.TextConflict('hello', 'hello_id')],
428
 
                         this.conflicts())
429
 
        self.build_tree_contents([('this/hello', '\n>>>>>>>')])
430
 
        remaining, resolved = this.auto_resolve()
431
 
        self.assertEqual([conflicts.TextConflict('hello', 'hello_id')],
432
 
                         this.conflicts())
433
 
        self.assertEqual([], resolved)
434
 
        self.build_tree_contents([('this/hello', 'hELLO wORLD')])
435
 
        remaining, resolved = this.auto_resolve()
436
 
        self.assertEqual([], this.conflicts())
437
 
        self.assertEqual([conflicts.TextConflict('hello', 'hello_id')],
438
 
                         resolved)
439
 
        self.assertPathDoesNotExist('this/hello.BASE')
440
 
 
441
 
    def test_auto_resolve_dir(self):
442
 
        tree = self.make_branch_and_tree('tree')
443
 
        self.build_tree(['tree/hello/'])
444
 
        tree.add('hello', 'hello-id')
445
 
        file_conflict = conflicts.TextConflict('file', 'hello-id')
446
 
        tree.set_conflicts(conflicts.ConflictList([file_conflict]))
447
 
        tree.auto_resolve()
448
 
 
449
 
 
450
 
class TestFindTrees(TestCaseWithTransport):
451
 
 
452
 
    def test_find_trees(self):
453
 
        self.make_branch_and_tree('foo')
454
 
        self.make_branch_and_tree('foo/bar')
455
 
        # Sticking a tree inside a control dir is heinous, so let's skip it
456
 
        self.make_branch_and_tree('foo/.bzr/baz')
457
 
        self.make_branch('qux')
458
 
        trees = workingtree.WorkingTree.find_trees('.')
459
 
        self.assertEqual(2, len(list(trees)))