~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

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

Merge in bzr-dir phase 2.

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 as 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
 
 
152
    def test_clone_bzrdir_branch_reference(self):
 
153
        # cloning should preserve the reference status of the branch in a bzrdir
 
154
        referenced_branch = self.make_branch('referencced')
 
155
        dir = self.make_bzrdir('source')
 
156
        try:
 
157
            reference = branch.BranchReferenceFormat().initialize(dir,
 
158
                referenced_branch)
 
159
        except errors.IncompatibleFormat:
 
160
            # this is ok too, not all formats have to support references.
 
161
            return
 
162
        target = dir.clone(self.get_url('target'))
 
163
        self.assertNotEqual(dir.transport.base, target.transport.base)
 
164
        self.assertDirectoriesEqual(dir.root_transport, target.root_transport)
 
165
 
 
166
    def test_clone_bzrdir_branch_revision(self):
 
167
        # test for revision limiting, [smoke test, not corner case checks].
 
168
        # make a branch with some revisions,
 
169
        # and clone it with a revision limit.
 
170
        # 
 
171
        tree = self.make_branch_and_tree('commit_tree')
 
172
        self.build_tree(['foo'], transport=tree.bzrdir.transport.clone('..'))
 
173
        tree.add('foo')
 
174
        tree.commit('revision 1', rev_id='1')
 
175
        tree.commit('revision 2', rev_id='2', allow_pointless=True)
 
176
        source = self.make_branch('source')
 
177
        tree.bzrdir.open_repository().copy_content_into(source.repository)
 
178
        tree.bzrdir.open_branch().copy_content_into(source)
 
179
        dir = source.bzrdir
 
180
        target = dir.clone(self.get_url('target'), revision_id='1')
 
181
        self.assertEqual('1', target.open_branch().last_revision())
 
182
        
 
183
    def test_clone_bzrdir_tree_branch_repo(self):
 
184
        tree = self.make_branch_and_tree('sourcce')
 
185
        self.build_tree(['foo'], transport=tree.bzrdir.transport.clone('..'))
 
186
        tree.add('foo')
 
187
        tree.commit('revision 1')
 
188
        dir = tree.bzrdir
 
189
        target = dir.clone(self.get_url('target'))
 
190
        self.assertNotEqual(dir.transport.base, target.transport.base)
 
191
        self.assertDirectoriesEqual(dir.root_transport, target.root_transport,
 
192
                                    ['./.bzr/stat-cache'])
 
193
 
 
194
    def test_clone_bzrdir_tree_branch_reference(self):
 
195
        # a tree with a branch reference (aka a checkout) 
 
196
        # should stay a checkout on clone.
 
197
        referenced_branch = self.make_branch('referencced')
 
198
        dir = self.make_bzrdir('source')
 
199
        try:
 
200
            reference = branch.BranchReferenceFormat().initialize(dir,
 
201
                referenced_branch)
 
202
        except errors.IncompatibleFormat:
 
203
            # this is ok too, not all formats have to support references.
 
204
            return
 
205
        dir.create_workingtree()
 
206
        target = dir.clone(self.get_url('target'))
 
207
        self.assertNotEqual(dir.transport.base, target.transport.base)
 
208
        self.assertDirectoriesEqual(dir.root_transport, target.root_transport,
 
209
                                    ['./.bzr/stat-cache'])
 
210
 
 
211
    def test_clone_bzrdir_tree_revision(self):
 
212
        # test for revision limiting, [smoke test, not corner case checks].
 
213
        # make a tree with a revision with a last-revision
 
214
        # and clone it with a revision limit.
 
215
        # This smoke test just checks the revision-id is right. Tree specific
 
216
        # tests will check corner cases.
 
217
        tree = self.make_branch_and_tree('source')
 
218
        self.build_tree(['foo'], transport=tree.bzrdir.transport.clone('..'))
 
219
        tree.add('foo')
 
220
        tree.commit('revision 1', rev_id='1')
 
221
        tree.commit('revision 2', rev_id='2', allow_pointless=True)
 
222
        dir = tree.bzrdir
 
223
        target = dir.clone(self.get_url('target'), revision_id='1')
 
224
        self.assertEqual('1', target.open_workingtree().last_revision())
 
225
 
 
226
    def test_clone_bzrdir_incomplete_source_with_basis(self):
 
227
        # ensure that basis really does grab from the basis by having incomplete source
 
228
        tree = self.make_branch_and_tree('commit_tree')
 
229
        self.build_tree(['foo'], transport=tree.bzrdir.transport.clone('..'))
 
230
        tree.add('foo')
 
231
        tree.commit('revision 1', rev_id='1')
 
232
        source = self.make_branch_and_tree('source')
 
233
        # this gives us an incomplete repository
 
234
        tree.bzrdir.open_repository().copy_content_into(source.branch.repository)
 
235
        tree.commit('revision 2', rev_id='2', allow_pointless=True)
 
236
        tree.bzrdir.open_branch().copy_content_into(source.branch)
 
237
        tree.copy_content_into(source)
 
238
        self.assertFalse(source.branch.repository.has_revision('2'))
 
239
        dir = source.bzrdir
 
240
        target = dir.clone(self.get_url('target'), basis=tree.bzrdir)
 
241
        self.assertEqual('2', target.open_branch().last_revision())
 
242
        self.assertEqual('2', target.open_workingtree().last_revision())
 
243
        self.assertTrue(target.open_branch().repository.has_revision('2'))
 
244
 
 
245
    def test_sprout_bzrdir_empty(self):
 
246
        dir = self.make_bzrdir('source')
 
247
        target = dir.sprout(self.get_url('target'))
 
248
        self.assertNotEqual(dir.transport.base, target.transport.base)
 
249
        # creates a new repository branch and tree
 
250
        target.open_repository()
 
251
        target.open_branch()
 
252
        target.open_workingtree()
 
253
    
 
254
    def test_sprout_bzrdir_repository(self):
 
255
        dir = self.make_bzrdir('source')
 
256
        repo = dir.create_repository()
 
257
        # add some content to differentiate from an empty repository.
 
258
        repo.control_weaves.add_text('inventory',
 
259
                                     "A",
 
260
                                     [],
 
261
                                     [],
 
262
                                     repo.get_transaction())
 
263
        target = dir.sprout(self.get_url('target'))
 
264
        self.assertNotEqual(dir.transport.base, target.transport.base)
 
265
        self.assertDirectoriesEqual(dir.root_transport, target.root_transport)
 
266
 
 
267
    def test_sprout_bzrdir_repository_revision(self):
 
268
        # test for revision limiting, [smoke test, not corner case checks].
 
269
        # make a repository with some revisions,
 
270
        # and sprout it with a revision limit.
 
271
        # 
 
272
        tree = self.make_branch_and_tree('commit_tree')
 
273
        self.build_tree(['foo'], transport=tree.bzrdir.transport.clone('..'))
 
274
        tree.add('foo')
 
275
        tree.commit('revision 1', rev_id='1')
 
276
        tree.bzrdir.open_branch().set_revision_history([])
 
277
        tree.set_last_revision(None)
 
278
        tree.commit('revision 2', rev_id='2')
 
279
        source = self.make_repository('source')
 
280
        tree.bzrdir.open_repository().copy_content_into(source)
 
281
        dir = source.bzrdir
 
282
        target = dir.sprout(self.get_url('target'), revision_id='2')
 
283
        raise TestSkipped('revision limiting not strict yet')
 
284
 
 
285
    def test_sprout_bzrdir_branch_and_repo(self):
 
286
        tree = self.make_branch_and_tree('commit_tree')
 
287
        self.build_tree(['foo'], transport=tree.bzrdir.transport.clone('..'))
 
288
        tree.add('foo')
 
289
        tree.commit('revision 1')
 
290
        source = self.make_branch('source')
 
291
        tree.bzrdir.open_repository().copy_content_into(source.repository)
 
292
        tree.bzrdir.open_branch().copy_content_into(source)
 
293
        dir = source.bzrdir
 
294
        target = dir.sprout(self.get_url('target'))
 
295
        self.assertNotEqual(dir.transport.base, target.transport.base)
 
296
        self.assertDirectoriesEqual(dir.root_transport, target.root_transport)
 
297
 
 
298
    def test_sprout_bzrdir_branch_reference(self):
 
299
        # sprouting should create a repository if needed and a sprouted branch.
 
300
        referenced_branch = self.make_branch('referencced')
 
301
        dir = self.make_bzrdir('source')
 
302
        try:
 
303
            reference = branch.BranchReferenceFormat().initialize(dir,
 
304
                referenced_branch)
 
305
        except errors.IncompatibleFormat:
 
306
            # this is ok too, not all formats have to support references.
 
307
            return
 
308
        self.assertRaises(errors.NoRepositoryPresent, dir.open_repository)
 
309
        target = dir.sprout(self.get_url('target'))
 
310
        self.assertNotEqual(dir.transport.base, target.transport.base)
 
311
        # we want target to have a branch that is in-place.
 
312
        self.assertEqual(target, target.open_branch().bzrdir)
 
313
        # and as we dont support repositories being detached yet, a repo in 
 
314
        # place
 
315
        target.open_repository()
 
316
 
 
317
    def test_sprout_bzrdir_branch_revision(self):
 
318
        # test for revision limiting, [smoke test, not corner case checks].
 
319
        # make a repository with some revisions,
 
320
        # and sprout it with a revision limit.
 
321
        # 
 
322
        tree = self.make_branch_and_tree('commit_tree')
 
323
        self.build_tree(['foo'], transport=tree.bzrdir.transport.clone('..'))
 
324
        tree.add('foo')
 
325
        tree.commit('revision 1', rev_id='1')
 
326
        tree.commit('revision 2', rev_id='2', allow_pointless=True)
 
327
        source = self.make_branch('source')
 
328
        tree.bzrdir.open_repository().copy_content_into(source.repository)
 
329
        tree.bzrdir.open_branch().copy_content_into(source)
 
330
        dir = source.bzrdir
 
331
        target = dir.sprout(self.get_url('target'), revision_id='1')
 
332
        self.assertEqual('1', target.open_branch().last_revision())
 
333
        
 
334
    def test_sprout_bzrdir_tree_branch_repo(self):
 
335
        tree = self.make_branch_and_tree('sourcce')
 
336
        self.build_tree(['foo'], transport=tree.bzrdir.transport.clone('..'))
 
337
        tree.add('foo')
 
338
        tree.commit('revision 1')
 
339
        dir = tree.bzrdir
 
340
        target = dir.sprout(self.get_url('target'))
 
341
        self.assertNotEqual(dir.transport.base, target.transport.base)
 
342
        self.assertDirectoriesEqual(dir.root_transport, target.root_transport,
 
343
                                    ['./.bzr/stat-cache'])
 
344
 
 
345
    def test_sprout_bzrdir_tree_branch_reference(self):
 
346
        # sprouting should create a repository if needed and a sprouted branch.
 
347
        # the tree state should be copied.
 
348
        referenced_branch = self.make_branch('referencced')
 
349
        dir = self.make_bzrdir('source')
 
350
        try:
 
351
            reference = branch.BranchReferenceFormat().initialize(dir,
 
352
                referenced_branch)
 
353
        except errors.IncompatibleFormat:
 
354
            # this is ok too, not all formats have to support references.
 
355
            return
 
356
        self.assertRaises(errors.NoRepositoryPresent, dir.open_repository)
 
357
        dir.create_workingtree()
 
358
        target = dir.sprout(self.get_url('target'))
 
359
        self.assertNotEqual(dir.transport.base, target.transport.base)
 
360
        # we want target to have a branch that is in-place.
 
361
        self.assertEqual(target, target.open_branch().bzrdir)
 
362
        # and as we dont support repositories being detached yet, a repo in 
 
363
        # place
 
364
        target.open_repository()
 
365
        # we trust that the working tree sprouting works via the other tests.
 
366
        target.open_workingtree()
 
367
 
 
368
    def test_sprout_bzrdir_tree_branch_reference_revision(self):
 
369
        # sprouting should create a repository if needed and a sprouted branch.
 
370
        # the tree state should be copied but the revision changed,
 
371
        # and the likewise the new branch should be truncated too
 
372
        referenced_branch = self.make_branch('referencced')
 
373
        dir = self.make_bzrdir('source')
 
374
        try:
 
375
            reference = branch.BranchReferenceFormat().initialize(dir,
 
376
                referenced_branch)
 
377
        except errors.IncompatibleFormat:
 
378
            # this is ok too, not all formats have to support references.
 
379
            return
 
380
        self.assertRaises(errors.NoRepositoryPresent, dir.open_repository)
 
381
        tree = dir.create_workingtree()
 
382
        self.build_tree(['foo'], transport=dir.root_transport)
 
383
        tree.add('foo')
 
384
        tree.commit('revision 1', rev_id='1')
 
385
        tree.commit('revision 2', rev_id='2', allow_pointless=True)
 
386
        target = dir.sprout(self.get_url('target'), revision_id='1')
 
387
        self.assertNotEqual(dir.transport.base, target.transport.base)
 
388
        # we want target to have a branch that is in-place.
 
389
        self.assertEqual(target, target.open_branch().bzrdir)
 
390
        # and as we dont support repositories being detached yet, a repo in 
 
391
        # place
 
392
        target.open_repository()
 
393
        # we trust that the working tree sprouting works via the other tests.
 
394
        self.assertEqual('1', target.open_workingtree().last_revision())
 
395
        self.assertEqual('1', target.open_branch().last_revision())
 
396
 
 
397
    def test_sprout_bzrdir_tree_revision(self):
 
398
        # test for revision limiting, [smoke test, not corner case checks].
 
399
        # make a tree with a revision with a last-revision
 
400
        # and sprout it with a revision limit.
 
401
        # This smoke test just checks the revision-id is right. Tree specific
 
402
        # tests will check corner cases.
 
403
        tree = self.make_branch_and_tree('source')
 
404
        self.build_tree(['foo'], transport=tree.bzrdir.root_transport)
 
405
        tree.add('foo')
 
406
        tree.commit('revision 1', rev_id='1')
 
407
        tree.commit('revision 2', rev_id='2', allow_pointless=True)
 
408
        dir = tree.bzrdir
 
409
        target = dir.sprout(self.get_url('target'), revision_id='1')
 
410
        self.assertEqual('1', target.open_workingtree().last_revision())
 
411
 
 
412
    def test_sprout_bzrdir_incomplete_source_with_basis(self):
 
413
        # ensure that basis really does grab from the basis by having incomplete source
 
414
        tree = self.make_branch_and_tree('commit_tree')
 
415
        self.build_tree(['foo'], transport=tree.bzrdir.root_transport)
 
416
        tree.add('foo')
 
417
        tree.commit('revision 1', rev_id='1')
 
418
        source = self.make_branch_and_tree('source')
 
419
        # this gives us an incomplete repository
 
420
        tree.bzrdir.open_repository().copy_content_into(source.branch.repository)
 
421
        tree.commit('revision 2', rev_id='2', allow_pointless=True)
 
422
        tree.bzrdir.open_branch().copy_content_into(source.branch)
 
423
        tree.copy_content_into(source)
 
424
        self.assertFalse(source.branch.repository.has_revision('2'))
 
425
        dir = source.bzrdir
 
426
        target = dir.sprout(self.get_url('target'), basis=tree.bzrdir)
 
427
        self.assertEqual('2', target.open_branch().last_revision())
 
428
        self.assertEqual('2', target.open_workingtree().last_revision())
 
429
        self.assertTrue(target.open_branch().repository.has_revision('2'))
 
430
 
 
431
    def test_format_initialize_find_open(self):
 
432
        # loopback test to check the current format initializes to itself.
 
433
        if not self.bzrdir_format.is_supported():
 
434
            # unsupported formats are not loopback testable
 
435
            # because the default open will not open them and
 
436
            # they may not be initializable.
 
437
            return
 
438
        # supported formats must be able to init and open
 
439
        t = get_transport(self.get_url())
 
440
        readonly_t = get_transport(self.get_readonly_url())
 
441
        made_control = self.bzrdir_format.initialize(t.base)
 
442
        self.failUnless(isinstance(made_control, bzrdir.BzrDir))
 
443
        self.assertEqual(self.bzrdir_format,
 
444
                         bzrdir.BzrDirFormat.find_format(readonly_t))
 
445
        direct_opened_dir = self.bzrdir_format.open(readonly_t)
 
446
        opened_dir = bzrdir.BzrDir.open(t.base)
 
447
        self.assertEqual(made_control._format,
 
448
                         opened_dir._format)
 
449
        self.assertEqual(direct_opened_dir._format,
 
450
                         opened_dir._format)
 
451
        self.failUnless(isinstance(opened_dir, bzrdir.BzrDir))
 
452
 
 
453
    def test_open_not_bzrdir(self):
 
454
        # test the formats specific behaviour for no-content or similar dirs.
 
455
        self.assertRaises(NotBranchError,
 
456
                          self.bzrdir_format.open,
 
457
                          get_transport(self.get_readonly_url()))
 
458
 
 
459
    def test_create_branch(self):
 
460
        # a bzrdir can construct a repository for itself.
 
461
        if not self.bzrdir_format.is_supported():
 
462
            # unsupported formats are not loopback testable
 
463
            # because the default open will not open them and
 
464
            # they may not be initializable.
 
465
            return
 
466
        t = get_transport(self.get_url())
 
467
        made_control = self.bzrdir_format.initialize(t.base)
 
468
        made_repo = made_control.create_repository()
 
469
        made_branch = made_control.create_branch()
 
470
        self.failUnless(isinstance(made_branch, branch.Branch))
 
471
        self.assertEqual(made_control, made_branch.bzrdir)
 
472
        
 
473
    def test_open_branch(self):
 
474
        if not self.bzrdir_format.is_supported():
 
475
            # unsupported formats are not loopback testable
 
476
            # because the default open will not open them and
 
477
            # they may not be initializable.
 
478
            return
 
479
        t = get_transport(self.get_url())
 
480
        made_control = self.bzrdir_format.initialize(t.base)
 
481
        made_repo = made_control.create_repository()
 
482
        made_branch = made_control.create_branch()
 
483
        opened_branch = made_control.open_branch()
 
484
        self.assertEqual(made_control, opened_branch.bzrdir)
 
485
        self.failUnless(isinstance(opened_branch, made_branch.__class__))
 
486
        self.failUnless(isinstance(opened_branch._format, made_branch._format.__class__))
 
487
 
 
488
    def test_create_repository(self):
 
489
        # a bzrdir can construct a repository for itself.
 
490
        if not self.bzrdir_format.is_supported():
 
491
            # unsupported formats are not loopback testable
 
492
            # because the default open will not open them and
 
493
            # they may not be initializable.
 
494
            return
 
495
        t = get_transport(self.get_url())
 
496
        made_control = self.bzrdir_format.initialize(t.base)
 
497
        made_repo = made_control.create_repository()
 
498
        self.failUnless(isinstance(made_repo, repository.Repository))
 
499
        self.assertEqual(made_control, made_repo.bzrdir)
 
500
        
 
501
    def test_open_repository(self):
 
502
        if not self.bzrdir_format.is_supported():
 
503
            # unsupported formats are not loopback testable
 
504
            # because the default open will not open them and
 
505
            # they may not be initializable.
 
506
            return
 
507
        t = get_transport(self.get_url())
 
508
        made_control = self.bzrdir_format.initialize(t.base)
 
509
        made_repo = made_control.create_repository()
 
510
        opened_repo = made_control.open_repository()
 
511
        self.assertEqual(made_control, opened_repo.bzrdir)
 
512
        self.failUnless(isinstance(opened_repo, made_repo.__class__))
 
513
        self.failUnless(isinstance(opened_repo._format, made_repo._format.__class__))
 
514
 
 
515
    def test_create_workingtree(self):
 
516
        # a bzrdir can construct a working tree for itself.
 
517
        if not self.bzrdir_format.is_supported():
 
518
            # unsupported formats are not loopback testable
 
519
            # because the default open will not open them and
 
520
            # they may not be initializable.
 
521
            return
 
522
        # this has to be tested with local access as we still support creating 
 
523
        # format 6 bzrdirs
 
524
        t = get_transport('.')
 
525
        made_control = self.bzrdir_format.initialize(t.base)
 
526
        made_repo = made_control.create_repository()
 
527
        made_branch = made_control.create_branch()
 
528
        made_tree = made_control.create_workingtree()
 
529
        self.failUnless(isinstance(made_tree, workingtree.WorkingTree))
 
530
        self.assertEqual(made_control, made_tree.bzrdir)
 
531
        
 
532
    def test_open_workingtree(self):
 
533
        if not self.bzrdir_format.is_supported():
 
534
            # unsupported formats are not loopback testable
 
535
            # because the default open will not open them and
 
536
            # they may not be initializable.
 
537
            return
 
538
        # this has to be tested with local access as we still support creating 
 
539
        # format 6 bzrdirs
 
540
        t = get_transport('.')
 
541
        made_control = self.bzrdir_format.initialize(t.base)
 
542
        made_repo = made_control.create_repository()
 
543
        made_branch = made_control.create_branch()
 
544
        made_tree = made_control.create_workingtree()
 
545
        opened_tree = made_control.open_workingtree()
 
546
        self.assertEqual(made_control, opened_tree.bzrdir)
 
547
        self.failUnless(isinstance(opened_tree, made_tree.__class__))
 
548
        self.failUnless(isinstance(opened_tree._format, made_tree._format.__class__))
 
549
 
 
550
    def test_get_branch_transport(self):
 
551
        dir = self.make_bzrdir('.')
 
552
        # without a format, get_branch_transport gives use a transport
 
553
        # which -may- point to an existing dir.
 
554
        self.assertTrue(isinstance(dir.get_branch_transport(None),
 
555
                                   transport.Transport))
 
556
        # with a given format, either the bzr dir supports identifiable
 
557
        # branches, or it supports anonymous  branch formats, but not both.
 
558
        anonymous_format = branch.BzrBranchFormat4()
 
559
        identifiable_format = branch.BzrBranchFormat5()
 
560
        try:
 
561
            found_transport = dir.get_branch_transport(anonymous_format)
 
562
            self.assertRaises(errors.IncompatibleFormat,
 
563
                              dir.get_branch_transport,
 
564
                              identifiable_format)
 
565
        except errors.IncompatibleFormat:
 
566
            found_transport = dir.get_branch_transport(identifiable_format)
 
567
        self.assertTrue(isinstance(found_transport, transport.Transport))
 
568
        # and the dir which has been initialized for us must be statable.
 
569
        found_transport.stat('.')
 
570
 
 
571
    def test_get_repository_transport(self):
 
572
        dir = self.make_bzrdir('.')
 
573
        # without a format, get_repository_transport gives use a transport
 
574
        # which -may- point to an existing dir.
 
575
        self.assertTrue(isinstance(dir.get_repository_transport(None),
 
576
                                   transport.Transport))
 
577
        # with a given format, either the bzr dir supports identifiable
 
578
        # repositoryes, or it supports anonymous  repository formats, but not both.
 
579
        anonymous_format = repository.RepositoryFormat6()
 
580
        identifiable_format = repository.RepositoryFormat7()
 
581
        try:
 
582
            found_transport = dir.get_repository_transport(anonymous_format)
 
583
            self.assertRaises(errors.IncompatibleFormat,
 
584
                              dir.get_repository_transport,
 
585
                              identifiable_format)
 
586
        except errors.IncompatibleFormat:
 
587
            found_transport = dir.get_repository_transport(identifiable_format)
 
588
        self.assertTrue(isinstance(found_transport, transport.Transport))
 
589
        # and the dir which has been initialized for us must be statable.
 
590
        found_transport.stat('.')
 
591
 
 
592
    def test_get_workingtree_transport(self):
 
593
        dir = self.make_bzrdir('.')
 
594
        # without a format, get_workingtree_transport gives use a transport
 
595
        # which -may- point to an existing dir.
 
596
        self.assertTrue(isinstance(dir.get_workingtree_transport(None),
 
597
                                   transport.Transport))
 
598
        # with a given format, either the bzr dir supports identifiable
 
599
        # trees, or it supports anonymous tree formats, but not both.
 
600
        anonymous_format = workingtree.WorkingTreeFormat2()
 
601
        identifiable_format = workingtree.WorkingTreeFormat3()
 
602
        try:
 
603
            found_transport = dir.get_workingtree_transport(anonymous_format)
 
604
            self.assertRaises(errors.IncompatibleFormat,
 
605
                              dir.get_workingtree_transport,
 
606
                              identifiable_format)
 
607
        except errors.IncompatibleFormat:
 
608
            found_transport = dir.get_workingtree_transport(identifiable_format)
 
609
        self.assertTrue(isinstance(found_transport, transport.Transport))
 
610
        # and the dir which has been initialized for us must be statable.
 
611
        found_transport.stat('.')
 
612
 
 
613
    def test_root_transport(self):
 
614
        dir = self.make_bzrdir('.')
 
615
        self.assertEqual(dir.root_transport.base,
 
616
                         get_transport(self.get_url('.')).base)
 
617