~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/bzrdir_implementations/test_bzrdir.py

Merge integration.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# (C) 2005, 2006 Canonical Ltd
 
2
 
 
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.
 
7
 
 
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.
 
12
 
 
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
 
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
16
 
 
17
"""Tests for bzrdir implementations - tests a bzrdir format."""
 
18
 
 
19
import os
 
20
from stat import *
 
21
import sys
 
22
 
 
23
import bzrlib.branch
 
24
import bzrlib.bzrdir as bzrdir
 
25
from bzrlib.branch import Branch, needs_read_lock, needs_write_lock
 
26
from bzrlib.commit import commit
 
27
import bzrlib.errors as errors
 
28
from bzrlib.errors import (FileExists,
 
29
                           NoSuchRevision,
 
30
                           NoSuchFile,
 
31
                           UninitializableFormat,
 
32
                           NotBranchError,
 
33
                           )
 
34
import bzrlib.repository as repository
 
35
from bzrlib.tests import TestCase, TestCaseWithTransport, TestSkipped
 
36
from bzrlib.trace import mutter
 
37
import bzrlib.transactions as transactions
 
38
import bzrlib.transport as transport
 
39
from bzrlib.transport import get_transport
 
40
from bzrlib.upgrade import upgrade
 
41
import bzrlib.workingtree as workingtree
 
42
 
 
43
 
 
44
class TestCaseWithBzrDir(TestCaseWithTransport):
 
45
 
 
46
    def setUp(self):
 
47
        super(TestCaseWithBzrDir, self).setUp()
 
48
        self.bzrdir = None
 
49
 
 
50
    def get_bzrdir(self):
 
51
        if self.bzrdir is None:
 
52
            self.bzrdir = self.make_bzrdir(None)
 
53
        return self.bzrdir
 
54
 
 
55
    def make_bzrdir(self, relpath):
 
56
        try:
 
57
            url = self.get_url(relpath)
 
58
            segments = url.split('/')
 
59
            if segments and segments[-1] not in ('', '.'):
 
60
                parent = '/'.join(segments[:-1])
 
61
                t = get_transport(parent)
 
62
                try:
 
63
                    t.mkdir(segments[-1])
 
64
                except FileExists:
 
65
                    pass
 
66
            return self.bzrdir_format.initialize(url)
 
67
        except UninitializableFormat:
 
68
            raise TestSkipped("Format %s is not initializable.")
 
69
 
 
70
 
 
71
class TestBzrDir(TestCaseWithBzrDir):
 
72
    # Many of these tests test for disk equality rather than checking
 
73
    # for semantic equivalence. This works well for some tests but
 
74
    # is not good at handling changes in representation or the addition
 
75
    # or removal of control data. It would be nice to for instance:
 
76
    # sprout a new branch, check that the nickname has been reset by hand
 
77
    # and then set the nickname to match the source branch, at which point
 
78
    # a semantic equivalence should pass
 
79
 
 
80
    def assertDirectoriesEqual(self, source, target, ignore_list=[]):
 
81
        """Assert that the content of source and target are identical.
 
82
 
 
83
        paths in ignore list will be completely ignored.
 
84
        """
 
85
        files = []
 
86
        directories = ['.']
 
87
        while directories:
 
88
            dir = directories.pop()
 
89
            for path in source.list_dir(dir):
 
90
                path = dir + '/' + path
 
91
                if path in ignore_list:
 
92
                    continue
 
93
                stat = source.stat(path)
 
94
                if S_ISDIR(stat.st_mode):
 
95
                    self.assertTrue(S_ISDIR(target.stat(path).st_mode))
 
96
                    directories.append(path)
 
97
                else:
 
98
                    self.assertEqualDiff(source.get(path).read(),
 
99
                                         target.get(path).read(),
 
100
                                         "text for file %r differs:\n" % path)
 
101
 
 
102
    def test_clone_bzrdir_empty(self):
 
103
        dir = self.make_bzrdir('source')
 
104
        target = dir.clone(self.get_url('target'))
 
105
        self.assertNotEqual(dir.transport.base, target.transport.base)
 
106
        self.assertDirectoriesEqual(dir.root_transport, target.root_transport)
 
107
    
 
108
    def test_clone_bzrdir_repository(self):
 
109
        dir = self.make_bzrdir('source')
 
110
        repo = dir.create_repository()
 
111
        # add some content to differentiate from an empty repository.
 
112
        repo.control_weaves.add_text('inventory',
 
113
                                     "A",
 
114
                                     [],
 
115
                                     [],
 
116
                                     repo.get_transaction())
 
117
        target = dir.clone(self.get_url('target'))
 
118
        self.assertNotEqual(dir.transport.base, target.transport.base)
 
119
        self.assertDirectoriesEqual(dir.root_transport, target.root_transport)
 
120
 
 
121
    def test_clone_bzrdir_repository_revision(self):
 
122
        # test for revision limiting, [smoke test, not corner case checks].
 
123
        # make a repository with some revisions,
 
124
        # and clone it with a revision limit.
 
125
        # 
 
126
        tree = self.make_branch_and_tree('commit_tree')
 
127
        self.build_tree(['foo'], transport=tree.bzrdir.transport.clone('..'))
 
128
        tree.add('foo')
 
129
        tree.commit('revision 1', rev_id='1')
 
130
        tree.bzrdir.open_branch().set_revision_history([])
 
131
        tree.set_last_revision(None)
 
132
        tree.commit('revision 2', rev_id='2')
 
133
        source = self.make_repository('source')
 
134
        tree.bzrdir.open_repository().copy_content_into(source)
 
135
        dir = source.bzrdir
 
136
        target = dir.clone(self.get_url('target'), revision_id='2')
 
137
        raise TestSkipped('revision limiting not strict yet')
 
138
 
 
139
    def test_clone_bzrdir_branch_and_repo(self):
 
140
        tree = self.make_branch_and_tree('commit_tree')
 
141
        self.build_tree(['foo'], transport=tree.bzrdir.transport.clone('..'))
 
142
        tree.add('foo')
 
143
        tree.commit('revision 1')
 
144
        source = self.make_branch('source')
 
145
        tree.bzrdir.open_repository().copy_content_into(source.repository)
 
146
        tree.bzrdir.open_branch().copy_content_into(source)
 
147
        dir = source.bzrdir
 
148
        target = dir.clone(self.get_url('target'))
 
149
        self.assertNotEqual(dir.transport.base, target.transport.base)
 
150
        self.assertDirectoriesEqual(dir.root_transport, target.root_transport,
 
151
                                    ['./.bzr/stat-cache', './.bzr/checkout/stat-cache'])
 
152
 
 
153
    def test_clone_bzrdir_branch_reference(self):
 
154
        # cloning should preserve the reference status of the branch in a bzrdir
 
155
        referenced_branch = self.make_branch('referencced')
 
156
        dir = self.make_bzrdir('source')
 
157
        try:
 
158
            reference = bzrlib.branch.BranchReferenceFormat().initialize(dir,
 
159
                referenced_branch)
 
160
        except errors.IncompatibleFormat:
 
161
            # this is ok too, not all formats have to support references.
 
162
            return
 
163
        target = dir.clone(self.get_url('target'))
 
164
        self.assertNotEqual(dir.transport.base, target.transport.base)
 
165
        self.assertDirectoriesEqual(dir.root_transport, target.root_transport)
 
166
 
 
167
    def test_clone_bzrdir_branch_revision(self):
 
168
        # test for revision limiting, [smoke test, not corner case checks].
 
169
        # make a branch with some revisions,
 
170
        # and clone it with a revision limit.
 
171
        # 
 
172
        tree = self.make_branch_and_tree('commit_tree')
 
173
        self.build_tree(['foo'], transport=tree.bzrdir.transport.clone('..'))
 
174
        tree.add('foo')
 
175
        tree.commit('revision 1', rev_id='1')
 
176
        tree.commit('revision 2', rev_id='2', allow_pointless=True)
 
177
        source = self.make_branch('source')
 
178
        tree.bzrdir.open_repository().copy_content_into(source.repository)
 
179
        tree.bzrdir.open_branch().copy_content_into(source)
 
180
        dir = source.bzrdir
 
181
        target = dir.clone(self.get_url('target'), revision_id='1')
 
182
        self.assertEqual('1', target.open_branch().last_revision())
 
183
        
 
184
    def test_clone_bzrdir_tree_branch_repo(self):
 
185
        tree = self.make_branch_and_tree('sourcce')
 
186
        self.build_tree(['foo'], transport=tree.bzrdir.transport.clone('..'))
 
187
        tree.add('foo')
 
188
        tree.commit('revision 1')
 
189
        dir = tree.bzrdir
 
190
        target = dir.clone(self.get_url('target'))
 
191
        self.assertNotEqual(dir.transport.base, target.transport.base)
 
192
        self.assertDirectoriesEqual(dir.root_transport, target.root_transport,
 
193
                                    ['./.bzr/stat-cache', './.bzr/checkout/stat-cache'])
 
194
 
 
195
    def test_clone_bzrdir_tree_branch_reference(self):
 
196
        # a tree with a branch reference (aka a checkout) 
 
197
        # should stay a checkout on clone.
 
198
        referenced_branch = self.make_branch('referencced')
 
199
        dir = self.make_bzrdir('source')
 
200
        try:
 
201
            reference = bzrlib.branch.BranchReferenceFormat().initialize(dir,
 
202
                referenced_branch)
 
203
        except errors.IncompatibleFormat:
 
204
            # this is ok too, not all formats have to support references.
 
205
            return
 
206
        dir.create_workingtree()
 
207
        target = dir.clone(self.get_url('target'))
 
208
        self.assertNotEqual(dir.transport.base, target.transport.base)
 
209
        self.assertDirectoriesEqual(dir.root_transport, target.root_transport,
 
210
                                    ['./.bzr/stat-cache', './.bzr/checkout/stat-cache'])
 
211
 
 
212
    def test_clone_bzrdir_tree_revision(self):
 
213
        # test for revision limiting, [smoke test, not corner case checks].
 
214
        # make a tree with a revision with a last-revision
 
215
        # and clone it with a revision limit.
 
216
        # This smoke test just checks the revision-id is right. Tree specific
 
217
        # tests will check corner cases.
 
218
        tree = self.make_branch_and_tree('source')
 
219
        self.build_tree(['foo'], transport=tree.bzrdir.transport.clone('..'))
 
220
        tree.add('foo')
 
221
        tree.commit('revision 1', rev_id='1')
 
222
        tree.commit('revision 2', rev_id='2', allow_pointless=True)
 
223
        dir = tree.bzrdir
 
224
        target = dir.clone(self.get_url('target'), revision_id='1')
 
225
        self.assertEqual('1', target.open_workingtree().last_revision())
 
226
 
 
227
    def test_clone_bzrdir_incomplete_source_with_basis(self):
 
228
        # ensure that basis really does grab from the basis by having incomplete source
 
229
        tree = self.make_branch_and_tree('commit_tree')
 
230
        self.build_tree(['foo'], transport=tree.bzrdir.transport.clone('..'))
 
231
        tree.add('foo')
 
232
        tree.commit('revision 1', rev_id='1')
 
233
        source = self.make_branch_and_tree('source')
 
234
        # this gives us an incomplete repository
 
235
        tree.bzrdir.open_repository().copy_content_into(source.branch.repository)
 
236
        tree.commit('revision 2', rev_id='2', allow_pointless=True)
 
237
        tree.bzrdir.open_branch().copy_content_into(source.branch)
 
238
        tree.copy_content_into(source)
 
239
        self.assertFalse(source.branch.repository.has_revision('2'))
 
240
        dir = source.bzrdir
 
241
        target = dir.clone(self.get_url('target'), basis=tree.bzrdir)
 
242
        self.assertEqual('2', target.open_branch().last_revision())
 
243
        self.assertEqual('2', target.open_workingtree().last_revision())
 
244
        self.assertTrue(target.open_branch().repository.has_revision('2'))
 
245
 
 
246
    def test_sprout_bzrdir_empty(self):
 
247
        dir = self.make_bzrdir('source')
 
248
        target = dir.sprout(self.get_url('target'))
 
249
        self.assertNotEqual(dir.transport.base, target.transport.base)
 
250
        # creates a new repository branch and tree
 
251
        target.open_repository()
 
252
        target.open_branch()
 
253
        target.open_workingtree()
 
254
    
 
255
    def test_sprout_bzrdir_repository(self):
 
256
        dir = self.make_bzrdir('source')
 
257
        repo = dir.create_repository()
 
258
        # add some content to differentiate from an empty repository.
 
259
        repo.control_weaves.add_text('inventory',
 
260
                                     "A",
 
261
                                     [],
 
262
                                     [],
 
263
                                     repo.get_transaction())
 
264
        target = dir.sprout(self.get_url('target'))
 
265
        self.assertNotEqual(dir.transport.base, target.transport.base)
 
266
        self.assertDirectoriesEqual(dir.root_transport, target.root_transport)
 
267
 
 
268
    def test_sprout_bzrdir_repository_revision(self):
 
269
        # test for revision limiting, [smoke test, not corner case checks].
 
270
        # make a repository with some revisions,
 
271
        # and sprout it with a revision limit.
 
272
        # 
 
273
        tree = self.make_branch_and_tree('commit_tree')
 
274
        self.build_tree(['foo'], transport=tree.bzrdir.transport.clone('..'))
 
275
        tree.add('foo')
 
276
        tree.commit('revision 1', rev_id='1')
 
277
        tree.bzrdir.open_branch().set_revision_history([])
 
278
        tree.set_last_revision(None)
 
279
        tree.commit('revision 2', rev_id='2')
 
280
        source = self.make_repository('source')
 
281
        tree.bzrdir.open_repository().copy_content_into(source)
 
282
        dir = source.bzrdir
 
283
        target = dir.sprout(self.get_url('target'), revision_id='2')
 
284
        raise TestSkipped('revision limiting not strict yet')
 
285
 
 
286
    def test_sprout_bzrdir_branch_and_repo(self):
 
287
        tree = self.make_branch_and_tree('commit_tree')
 
288
        self.build_tree(['foo'], transport=tree.bzrdir.transport.clone('..'))
 
289
        tree.add('foo')
 
290
        tree.commit('revision 1')
 
291
        source = self.make_branch('source')
 
292
        tree.bzrdir.open_repository().copy_content_into(source.repository)
 
293
        tree.bzrdir.open_branch().copy_content_into(source)
 
294
        dir = source.bzrdir
 
295
        target = dir.sprout(self.get_url('target'))
 
296
        self.assertNotEqual(dir.transport.base, target.transport.base)
 
297
        self.assertDirectoriesEqual(dir.root_transport, target.root_transport)
 
298
 
 
299
    def test_sprout_bzrdir_branch_reference(self):
 
300
        # sprouting should create a repository if needed and a sprouted branch.
 
301
        referenced_branch = self.make_branch('referencced')
 
302
        dir = self.make_bzrdir('source')
 
303
        try:
 
304
            reference = bzrlib.branch.BranchReferenceFormat().initialize(dir,
 
305
                referenced_branch)
 
306
        except errors.IncompatibleFormat:
 
307
            # this is ok too, not all formats have to support references.
 
308
            return
 
309
        self.assertRaises(errors.NoRepositoryPresent, dir.open_repository)
 
310
        target = dir.sprout(self.get_url('target'))
 
311
        self.assertNotEqual(dir.transport.base, target.transport.base)
 
312
        # we want target to have a branch that is in-place.
 
313
        self.assertEqual(target, target.open_branch().bzrdir)
 
314
        # and as we dont support repositories being detached yet, a repo in 
 
315
        # place
 
316
        target.open_repository()
 
317
 
 
318
    def test_sprout_bzrdir_branch_revision(self):
 
319
        # test for revision limiting, [smoke test, not corner case checks].
 
320
        # make a repository with some revisions,
 
321
        # and sprout it with a revision limit.
 
322
        # 
 
323
        tree = self.make_branch_and_tree('commit_tree')
 
324
        self.build_tree(['foo'], transport=tree.bzrdir.transport.clone('..'))
 
325
        tree.add('foo')
 
326
        tree.commit('revision 1', rev_id='1')
 
327
        tree.commit('revision 2', rev_id='2', allow_pointless=True)
 
328
        source = self.make_branch('source')
 
329
        tree.bzrdir.open_repository().copy_content_into(source.repository)
 
330
        tree.bzrdir.open_branch().copy_content_into(source)
 
331
        dir = source.bzrdir
 
332
        target = dir.sprout(self.get_url('target'), revision_id='1')
 
333
        self.assertEqual('1', target.open_branch().last_revision())
 
334
        
 
335
    def test_sprout_bzrdir_tree_branch_repo(self):
 
336
        tree = self.make_branch_and_tree('sourcce')
 
337
        self.build_tree(['foo'], transport=tree.bzrdir.transport.clone('..'))
 
338
        tree.add('foo')
 
339
        tree.commit('revision 1')
 
340
        dir = tree.bzrdir
 
341
        target = dir.sprout(self.get_url('target'))
 
342
        self.assertNotEqual(dir.transport.base, target.transport.base)
 
343
        self.assertDirectoriesEqual(dir.root_transport, target.root_transport,
 
344
                                    ['./.bzr/stat-cache', './.bzr/checkout/stat-cache'])
 
345
 
 
346
    def test_sprout_bzrdir_tree_branch_reference(self):
 
347
        # sprouting should create a repository if needed and a sprouted branch.
 
348
        # the tree state should be copied.
 
349
        referenced_branch = self.make_branch('referencced')
 
350
        dir = self.make_bzrdir('source')
 
351
        try:
 
352
            reference = bzrlib.branch.BranchReferenceFormat().initialize(dir,
 
353
                referenced_branch)
 
354
        except errors.IncompatibleFormat:
 
355
            # this is ok too, not all formats have to support references.
 
356
            return
 
357
        self.assertRaises(errors.NoRepositoryPresent, dir.open_repository)
 
358
        dir.create_workingtree()
 
359
        target = dir.sprout(self.get_url('target'))
 
360
        self.assertNotEqual(dir.transport.base, target.transport.base)
 
361
        # we want target to have a branch that is in-place.
 
362
        self.assertEqual(target, target.open_branch().bzrdir)
 
363
        # and as we dont support repositories being detached yet, a repo in 
 
364
        # place
 
365
        target.open_repository()
 
366
        # we trust that the working tree sprouting works via the other tests.
 
367
        target.open_workingtree()
 
368
 
 
369
    def test_sprout_bzrdir_tree_branch_reference_revision(self):
 
370
        # sprouting should create a repository if needed and a sprouted branch.
 
371
        # the tree state should be copied but the revision changed,
 
372
        # and the likewise the new branch should be truncated too
 
373
        referenced_branch = self.make_branch('referencced')
 
374
        dir = self.make_bzrdir('source')
 
375
        try:
 
376
            reference = bzrlib.branch.BranchReferenceFormat().initialize(dir,
 
377
                referenced_branch)
 
378
        except errors.IncompatibleFormat:
 
379
            # this is ok too, not all formats have to support references.
 
380
            return
 
381
        self.assertRaises(errors.NoRepositoryPresent, dir.open_repository)
 
382
        tree = dir.create_workingtree()
 
383
        self.build_tree(['foo'], transport=dir.root_transport)
 
384
        tree.add('foo')
 
385
        tree.commit('revision 1', rev_id='1')
 
386
        tree.commit('revision 2', rev_id='2', allow_pointless=True)
 
387
        target = dir.sprout(self.get_url('target'), revision_id='1')
 
388
        self.assertNotEqual(dir.transport.base, target.transport.base)
 
389
        # we want target to have a branch that is in-place.
 
390
        self.assertEqual(target, target.open_branch().bzrdir)
 
391
        # and as we dont support repositories being detached yet, a repo in 
 
392
        # place
 
393
        target.open_repository()
 
394
        # we trust that the working tree sprouting works via the other tests.
 
395
        self.assertEqual('1', target.open_workingtree().last_revision())
 
396
        self.assertEqual('1', target.open_branch().last_revision())
 
397
 
 
398
    def test_sprout_bzrdir_tree_revision(self):
 
399
        # test for revision limiting, [smoke test, not corner case checks].
 
400
        # make a tree with a revision with a last-revision
 
401
        # and sprout it with a revision limit.
 
402
        # This smoke test just checks the revision-id is right. Tree specific
 
403
        # tests will check corner cases.
 
404
        tree = self.make_branch_and_tree('source')
 
405
        self.build_tree(['foo'], transport=tree.bzrdir.root_transport)
 
406
        tree.add('foo')
 
407
        tree.commit('revision 1', rev_id='1')
 
408
        tree.commit('revision 2', rev_id='2', allow_pointless=True)
 
409
        dir = tree.bzrdir
 
410
        target = dir.sprout(self.get_url('target'), revision_id='1')
 
411
        self.assertEqual('1', target.open_workingtree().last_revision())
 
412
 
 
413
    def test_sprout_bzrdir_incomplete_source_with_basis(self):
 
414
        # ensure that basis really does grab from the basis by having incomplete source
 
415
        tree = self.make_branch_and_tree('commit_tree')
 
416
        self.build_tree(['foo'], transport=tree.bzrdir.root_transport)
 
417
        tree.add('foo')
 
418
        tree.commit('revision 1', rev_id='1')
 
419
        source = self.make_branch_and_tree('source')
 
420
        # this gives us an incomplete repository
 
421
        tree.bzrdir.open_repository().copy_content_into(source.branch.repository)
 
422
        tree.commit('revision 2', rev_id='2', allow_pointless=True)
 
423
        tree.bzrdir.open_branch().copy_content_into(source.branch)
 
424
        tree.copy_content_into(source)
 
425
        self.assertFalse(source.branch.repository.has_revision('2'))
 
426
        dir = source.bzrdir
 
427
        target = dir.sprout(self.get_url('target'), basis=tree.bzrdir)
 
428
        self.assertEqual('2', target.open_branch().last_revision())
 
429
        self.assertEqual('2', target.open_workingtree().last_revision())
 
430
        self.assertTrue(target.open_branch().repository.has_revision('2'))
 
431
 
 
432
    def test_format_initialize_find_open(self):
 
433
        # loopback test to check the current format initializes to itself.
 
434
        if not self.bzrdir_format.is_supported():
 
435
            # unsupported formats are not loopback testable
 
436
            # because the default open will not open them and
 
437
            # they may not be initializable.
 
438
            return
 
439
        # supported formats must be able to init and open
 
440
        t = get_transport(self.get_url())
 
441
        readonly_t = get_transport(self.get_readonly_url())
 
442
        made_control = self.bzrdir_format.initialize(t.base)
 
443
        self.failUnless(isinstance(made_control, bzrdir.BzrDir))
 
444
        self.assertEqual(self.bzrdir_format,
 
445
                         bzrdir.BzrDirFormat.find_format(readonly_t))
 
446
        direct_opened_dir = self.bzrdir_format.open(readonly_t)
 
447
        opened_dir = bzrdir.BzrDir.open(t.base)
 
448
        self.assertEqual(made_control._format,
 
449
                         opened_dir._format)
 
450
        self.assertEqual(direct_opened_dir._format,
 
451
                         opened_dir._format)
 
452
        self.failUnless(isinstance(opened_dir, bzrdir.BzrDir))
 
453
 
 
454
    def test_open_not_bzrdir(self):
 
455
        # test the formats specific behaviour for no-content or similar dirs.
 
456
        self.assertRaises(NotBranchError,
 
457
                          self.bzrdir_format.open,
 
458
                          get_transport(self.get_readonly_url()))
 
459
 
 
460
    def test_create_branch(self):
 
461
        # a bzrdir can construct a repository for itself.
 
462
        if not self.bzrdir_format.is_supported():
 
463
            # unsupported formats are not loopback testable
 
464
            # because the default open will not open them and
 
465
            # they may not be initializable.
 
466
            return
 
467
        t = get_transport(self.get_url())
 
468
        made_control = self.bzrdir_format.initialize(t.base)
 
469
        made_repo = made_control.create_repository()
 
470
        made_branch = made_control.create_branch()
 
471
        self.failUnless(isinstance(made_branch, bzrlib.branch.Branch))
 
472
        self.assertEqual(made_control, made_branch.bzrdir)
 
473
        
 
474
    def test_open_branch(self):
 
475
        if not self.bzrdir_format.is_supported():
 
476
            # unsupported formats are not loopback testable
 
477
            # because the default open will not open them and
 
478
            # they may not be initializable.
 
479
            return
 
480
        t = get_transport(self.get_url())
 
481
        made_control = self.bzrdir_format.initialize(t.base)
 
482
        made_repo = made_control.create_repository()
 
483
        made_branch = made_control.create_branch()
 
484
        opened_branch = made_control.open_branch()
 
485
        self.assertEqual(made_control, opened_branch.bzrdir)
 
486
        self.failUnless(isinstance(opened_branch, made_branch.__class__))
 
487
        self.failUnless(isinstance(opened_branch._format, made_branch._format.__class__))
 
488
 
 
489
    def test_create_repository(self):
 
490
        # a bzrdir can construct a repository for itself.
 
491
        if not self.bzrdir_format.is_supported():
 
492
            # unsupported formats are not loopback testable
 
493
            # because the default open will not open them and
 
494
            # they may not be initializable.
 
495
            return
 
496
        t = get_transport(self.get_url())
 
497
        made_control = self.bzrdir_format.initialize(t.base)
 
498
        made_repo = made_control.create_repository()
 
499
        self.failUnless(isinstance(made_repo, repository.Repository))
 
500
        self.assertEqual(made_control, made_repo.bzrdir)
 
501
        
 
502
    def test_open_repository(self):
 
503
        if not self.bzrdir_format.is_supported():
 
504
            # unsupported formats are not loopback testable
 
505
            # because the default open will not open them and
 
506
            # they may not be initializable.
 
507
            return
 
508
        t = get_transport(self.get_url())
 
509
        made_control = self.bzrdir_format.initialize(t.base)
 
510
        made_repo = made_control.create_repository()
 
511
        opened_repo = made_control.open_repository()
 
512
        self.assertEqual(made_control, opened_repo.bzrdir)
 
513
        self.failUnless(isinstance(opened_repo, made_repo.__class__))
 
514
        self.failUnless(isinstance(opened_repo._format, made_repo._format.__class__))
 
515
 
 
516
    def test_create_workingtree(self):
 
517
        # a bzrdir can construct a working tree for itself.
 
518
        if not self.bzrdir_format.is_supported():
 
519
            # unsupported formats are not loopback testable
 
520
            # because the default open will not open them and
 
521
            # they may not be initializable.
 
522
            return
 
523
        # this has to be tested with local access as we still support creating 
 
524
        # format 6 bzrdirs
 
525
        t = get_transport('.')
 
526
        made_control = self.bzrdir_format.initialize(t.base)
 
527
        made_repo = made_control.create_repository()
 
528
        made_branch = made_control.create_branch()
 
529
        made_tree = made_control.create_workingtree()
 
530
        self.failUnless(isinstance(made_tree, workingtree.WorkingTree))
 
531
        self.assertEqual(made_control, made_tree.bzrdir)
 
532
        
 
533
    def test_create_workingtree_revision(self):
 
534
        # a bzrdir can construct a working tree for itself @ a specific revision.
 
535
        source = self.make_branch_and_tree('source')
 
536
        source.commit('a', rev_id='a', allow_pointless=True)
 
537
        source.commit('b', rev_id='b', allow_pointless=True)
 
538
        self.build_tree(['new/'])
 
539
        made_control = self.bzrdir_format.initialize('new')
 
540
        source.branch.repository.clone(made_control)
 
541
        source.branch.clone(made_control)
 
542
        made_tree = made_control.create_workingtree(revision_id='a')
 
543
        self.assertEqual('a', made_tree.last_revision())
 
544
        
 
545
    def test_open_workingtree(self):
 
546
        if not self.bzrdir_format.is_supported():
 
547
            # unsupported formats are not loopback testable
 
548
            # because the default open will not open them and
 
549
            # they may not be initializable.
 
550
            return
 
551
        # this has to be tested with local access as we still support creating 
 
552
        # format 6 bzrdirs
 
553
        t = get_transport('.')
 
554
        made_control = self.bzrdir_format.initialize(t.base)
 
555
        made_repo = made_control.create_repository()
 
556
        made_branch = made_control.create_branch()
 
557
        made_tree = made_control.create_workingtree()
 
558
        opened_tree = made_control.open_workingtree()
 
559
        self.assertEqual(made_control, opened_tree.bzrdir)
 
560
        self.failUnless(isinstance(opened_tree, made_tree.__class__))
 
561
        self.failUnless(isinstance(opened_tree._format, made_tree._format.__class__))
 
562
 
 
563
    def test_get_branch_transport(self):
 
564
        dir = self.make_bzrdir('.')
 
565
        # without a format, get_branch_transport gives use a transport
 
566
        # which -may- point to an existing dir.
 
567
        self.assertTrue(isinstance(dir.get_branch_transport(None),
 
568
                                   transport.Transport))
 
569
        # with a given format, either the bzr dir supports identifiable
 
570
        # branches, or it supports anonymous  branch formats, but not both.
 
571
        anonymous_format = bzrlib.branch.BzrBranchFormat4()
 
572
        identifiable_format = bzrlib.branch.BzrBranchFormat5()
 
573
        try:
 
574
            found_transport = dir.get_branch_transport(anonymous_format)
 
575
            self.assertRaises(errors.IncompatibleFormat,
 
576
                              dir.get_branch_transport,
 
577
                              identifiable_format)
 
578
        except errors.IncompatibleFormat:
 
579
            found_transport = dir.get_branch_transport(identifiable_format)
 
580
        self.assertTrue(isinstance(found_transport, transport.Transport))
 
581
        # and the dir which has been initialized for us must be statable.
 
582
        found_transport.stat('.')
 
583
 
 
584
    def test_get_repository_transport(self):
 
585
        dir = self.make_bzrdir('.')
 
586
        # without a format, get_repository_transport gives use a transport
 
587
        # which -may- point to an existing dir.
 
588
        self.assertTrue(isinstance(dir.get_repository_transport(None),
 
589
                                   transport.Transport))
 
590
        # with a given format, either the bzr dir supports identifiable
 
591
        # repositoryes, or it supports anonymous  repository formats, but not both.
 
592
        anonymous_format = repository.RepositoryFormat6()
 
593
        identifiable_format = repository.RepositoryFormat7()
 
594
        try:
 
595
            found_transport = dir.get_repository_transport(anonymous_format)
 
596
            self.assertRaises(errors.IncompatibleFormat,
 
597
                              dir.get_repository_transport,
 
598
                              identifiable_format)
 
599
        except errors.IncompatibleFormat:
 
600
            found_transport = dir.get_repository_transport(identifiable_format)
 
601
        self.assertTrue(isinstance(found_transport, transport.Transport))
 
602
        # and the dir which has been initialized for us must be statable.
 
603
        found_transport.stat('.')
 
604
 
 
605
    def test_get_workingtree_transport(self):
 
606
        dir = self.make_bzrdir('.')
 
607
        # without a format, get_workingtree_transport gives use a transport
 
608
        # which -may- point to an existing dir.
 
609
        self.assertTrue(isinstance(dir.get_workingtree_transport(None),
 
610
                                   transport.Transport))
 
611
        # with a given format, either the bzr dir supports identifiable
 
612
        # trees, or it supports anonymous tree formats, but not both.
 
613
        anonymous_format = workingtree.WorkingTreeFormat2()
 
614
        identifiable_format = workingtree.WorkingTreeFormat3()
 
615
        try:
 
616
            found_transport = dir.get_workingtree_transport(anonymous_format)
 
617
            self.assertRaises(errors.IncompatibleFormat,
 
618
                              dir.get_workingtree_transport,
 
619
                              identifiable_format)
 
620
        except errors.IncompatibleFormat:
 
621
            found_transport = dir.get_workingtree_transport(identifiable_format)
 
622
        self.assertTrue(isinstance(found_transport, transport.Transport))
 
623
        # and the dir which has been initialized for us must be statable.
 
624
        found_transport.stat('.')
 
625
 
 
626
    def test_root_transport(self):
 
627
        dir = self.make_bzrdir('.')
 
628
        self.assertEqual(dir.root_transport.base,
 
629
                         get_transport(self.get_url('.')).base)
 
630