/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_bzrdir.py

  • Committer: v.ladeuil+lp at free
  • Date: 2007-02-04 17:41:12 UTC
  • mto: (2323.7.1 redirection)
  • mto: This revision was merged to the branch mainline in revision 2390.
  • Revision ID: v.ladeuil+lp@free.fr-20070204174112-iv6gxzinnjddlaxj
Add tests for redirection. Preserve transport decorations.

* bzrlib/tests/test_http.py:
(TestRedirections): new tests.

* bzrlib/tests/HttpServer.py:
(HttpServer): Make server host and port public once the socket
have been established.

* bzrlib/tests/HTTPTestUtil.py:
(RedirectRequestHandler, HTTPServerRedirecting): New http test
server for redirections. Only a whole host can be redirected, so
far.

* bzrlib/errors.py:
(RedirectRequested.__init__): Add a 'qual_proto' oso that
transport decorations can be transmitted to redirected transport.
(RedirectRequested._requalify_url,
RedirectRequested.get_source_url,
RedirectRequested.get_target_url): New methods providing fully
decorated urls.

* bzrlib/bzrdir.py:
(BzrDir.open_from_transport): The redirection should preserve
transport decorations.
(BzrDirMetaFormat1): To be able to specialize bzr branches from
foreign branches, we need to register BzrDirMetaFormat1 as the
default control format (instead of BzrDirMetaFormat which is
abstract and can still be used by foreign branches).

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright (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 the BzrDir facility and any format specific tests.
 
18
 
 
19
For interface contract tests, see tests/bzr_dir_implementations.
 
20
"""
 
21
 
 
22
import os.path
 
23
from StringIO import StringIO
 
24
 
 
25
from bzrlib import (
 
26
    help_topics,
 
27
    symbol_versioning,
 
28
    urlutils,
 
29
    )
 
30
import bzrlib.branch
 
31
import bzrlib.bzrdir as bzrdir
 
32
import bzrlib.errors as errors
 
33
from bzrlib.errors import (NotBranchError,
 
34
                           UnknownFormatError,
 
35
                           UnsupportedFormatError,
 
36
                           )
 
37
import bzrlib.repository as repository
 
38
from bzrlib.tests import TestCase, TestCaseWithTransport, test_sftp_transport
 
39
from bzrlib.tests.HttpServer import HttpServer
 
40
from bzrlib.transport import get_transport
 
41
from bzrlib.transport.memory import MemoryServer
 
42
import bzrlib.workingtree as workingtree
 
43
 
 
44
 
 
45
class TestDefaultFormat(TestCase):
 
46
 
 
47
    def test_get_set_default_format(self):
 
48
        old_format = bzrdir.BzrDirFormat.get_default_format()
 
49
        # default is BzrDirFormat6
 
50
        self.failUnless(isinstance(old_format, bzrdir.BzrDirMetaFormat1))
 
51
        self.applyDeprecated(symbol_versioning.zero_fourteen, 
 
52
                             bzrdir.BzrDirFormat.set_default_format, 
 
53
                             SampleBzrDirFormat())
 
54
        # creating a bzr dir should now create an instrumented dir.
 
55
        try:
 
56
            result = bzrdir.BzrDir.create('memory:///')
 
57
            self.failUnless(isinstance(result, SampleBzrDir))
 
58
        finally:
 
59
            self.applyDeprecated(symbol_versioning.zero_fourteen,
 
60
                bzrdir.BzrDirFormat.set_default_format, old_format)
 
61
        self.assertEqual(old_format, bzrdir.BzrDirFormat.get_default_format())
 
62
 
 
63
 
 
64
class TestFormatRegistry(TestCase):
 
65
 
 
66
    def make_format_registry(self):
 
67
        my_format_registry = bzrdir.BzrDirFormatRegistry()
 
68
        my_format_registry.register('weave', bzrdir.BzrDirFormat6,
 
69
            'Pre-0.8 format.  Slower and does not support checkouts or shared'
 
70
            ' repositories', deprecated=True)
 
71
        my_format_registry.register_lazy('lazy', 'bzrlib.bzrdir', 
 
72
            'BzrDirFormat6', 'Format registered lazily', deprecated=True)
 
73
        my_format_registry.register_metadir('knit', 'RepositoryFormatKnit1',
 
74
            'Format using knits')
 
75
        my_format_registry.set_default('knit')
 
76
        my_format_registry.register_metadir('metaweave', 'RepositoryFormat7',
 
77
            'Transitional format in 0.8.  Slower than knit.', deprecated=True)
 
78
        my_format_registry.register_metadir('experimental-knit2', 
 
79
                                            'RepositoryFormatKnit2',
 
80
            'Experimental successor to knit.  Use at your own risk.')
 
81
        return my_format_registry
 
82
 
 
83
    def test_format_registry(self):
 
84
        my_format_registry = self.make_format_registry()
 
85
        my_bzrdir = my_format_registry.make_bzrdir('lazy')
 
86
        self.assertIsInstance(my_bzrdir, bzrdir.BzrDirFormat6)
 
87
        my_bzrdir = my_format_registry.make_bzrdir('weave')
 
88
        self.assertIsInstance(my_bzrdir, bzrdir.BzrDirFormat6)
 
89
        my_bzrdir = my_format_registry.make_bzrdir('default')
 
90
        self.assertIsInstance(my_bzrdir.repository_format, 
 
91
            repository.RepositoryFormatKnit1)
 
92
        my_bzrdir = my_format_registry.make_bzrdir('knit')
 
93
        self.assertIsInstance(my_bzrdir.repository_format, 
 
94
            repository.RepositoryFormatKnit1)
 
95
        my_bzrdir = my_format_registry.make_bzrdir('metaweave')
 
96
        self.assertIsInstance(my_bzrdir.repository_format, 
 
97
            repository.RepositoryFormat7)
 
98
 
 
99
    def test_get_help(self):
 
100
        my_format_registry = self.make_format_registry()
 
101
        self.assertEqual('Format registered lazily',
 
102
                         my_format_registry.get_help('lazy'))
 
103
        self.assertEqual('Format using knits', 
 
104
                         my_format_registry.get_help('knit'))
 
105
        self.assertEqual('Format using knits', 
 
106
                         my_format_registry.get_help('default'))
 
107
        self.assertEqual('Pre-0.8 format.  Slower and does not support'
 
108
                         ' checkouts or shared repositories', 
 
109
                         my_format_registry.get_help('weave'))
 
110
        
 
111
    def test_help_topic(self):
 
112
        topics = help_topics.HelpTopicRegistry()
 
113
        topics.register('formats', self.make_format_registry().help_topic, 
 
114
                        'Directory formats')
 
115
        topic = topics.get_detail('formats')
 
116
        new, deprecated = topic.split('Deprecated formats')
 
117
        self.assertContainsRe(new, 'Bazaar directory formats')
 
118
        self.assertContainsRe(new, 
 
119
            '  knit/default:\n    \(native\) Format using knits\n')
 
120
        self.assertContainsRe(deprecated, 
 
121
            '  lazy:\n    \(native\) Format registered lazily\n')
 
122
 
 
123
    def test_set_default_repository(self):
 
124
        default_factory = bzrdir.format_registry.get('default')
 
125
        old_default = [k for k, v in bzrdir.format_registry.iteritems()
 
126
                       if v == default_factory and k != 'default'][0]
 
127
        bzrdir.format_registry.set_default_repository('metaweave')
 
128
        try:
 
129
            self.assertIs(bzrdir.format_registry.get('metaweave'),
 
130
                          bzrdir.format_registry.get('default'))
 
131
            self.assertIs(
 
132
                repository.RepositoryFormat.get_default_format().__class__,
 
133
                repository.RepositoryFormat7)
 
134
        finally:
 
135
            bzrdir.format_registry.set_default_repository(old_default)
 
136
 
 
137
class SampleBranch(bzrlib.branch.Branch):
 
138
    """A dummy branch for guess what, dummy use."""
 
139
 
 
140
    def __init__(self, dir):
 
141
        self.bzrdir = dir
 
142
 
 
143
 
 
144
class SampleBzrDir(bzrdir.BzrDir):
 
145
    """A sample BzrDir implementation to allow testing static methods."""
 
146
 
 
147
    def create_repository(self, shared=False):
 
148
        """See BzrDir.create_repository."""
 
149
        return "A repository"
 
150
 
 
151
    def open_repository(self):
 
152
        """See BzrDir.open_repository."""
 
153
        return "A repository"
 
154
 
 
155
    def create_branch(self):
 
156
        """See BzrDir.create_branch."""
 
157
        return SampleBranch(self)
 
158
 
 
159
    def create_workingtree(self):
 
160
        """See BzrDir.create_workingtree."""
 
161
        return "A tree"
 
162
 
 
163
 
 
164
class SampleBzrDirFormat(bzrdir.BzrDirFormat):
 
165
    """A sample format
 
166
 
 
167
    this format is initializable, unsupported to aid in testing the 
 
168
    open and open_downlevel routines.
 
169
    """
 
170
 
 
171
    def get_format_string(self):
 
172
        """See BzrDirFormat.get_format_string()."""
 
173
        return "Sample .bzr dir format."
 
174
 
 
175
    def initialize(self, url):
 
176
        """Create a bzr dir."""
 
177
        t = get_transport(url)
 
178
        t.mkdir('.bzr')
 
179
        t.put_bytes('.bzr/branch-format', self.get_format_string())
 
180
        return SampleBzrDir(t, self)
 
181
 
 
182
    def is_supported(self):
 
183
        return False
 
184
 
 
185
    def open(self, transport, _found=None):
 
186
        return "opened branch."
 
187
 
 
188
 
 
189
class TestBzrDirFormat(TestCaseWithTransport):
 
190
    """Tests for the BzrDirFormat facility."""
 
191
 
 
192
    def test_find_format(self):
 
193
        # is the right format object found for a branch?
 
194
        # create a branch with a few known format objects.
 
195
        # this is not quite the same as 
 
196
        t = get_transport(self.get_url())
 
197
        self.build_tree(["foo/", "bar/"], transport=t)
 
198
        def check_format(format, url):
 
199
            format.initialize(url)
 
200
            t = get_transport(url)
 
201
            found_format = bzrdir.BzrDirFormat.find_format(t)
 
202
            self.failUnless(isinstance(found_format, format.__class__))
 
203
        check_format(bzrdir.BzrDirFormat5(), "foo")
 
204
        check_format(bzrdir.BzrDirFormat6(), "bar")
 
205
        
 
206
    def test_find_format_nothing_there(self):
 
207
        self.assertRaises(NotBranchError,
 
208
                          bzrdir.BzrDirFormat.find_format,
 
209
                          get_transport('.'))
 
210
 
 
211
    def test_find_format_unknown_format(self):
 
212
        t = get_transport(self.get_url())
 
213
        t.mkdir('.bzr')
 
214
        t.put_bytes('.bzr/branch-format', '')
 
215
        self.assertRaises(UnknownFormatError,
 
216
                          bzrdir.BzrDirFormat.find_format,
 
217
                          get_transport('.'))
 
218
 
 
219
    def test_register_unregister_format(self):
 
220
        format = SampleBzrDirFormat()
 
221
        url = self.get_url()
 
222
        # make a bzrdir
 
223
        format.initialize(url)
 
224
        # register a format for it.
 
225
        bzrdir.BzrDirFormat.register_format(format)
 
226
        # which bzrdir.Open will refuse (not supported)
 
227
        self.assertRaises(UnsupportedFormatError, bzrdir.BzrDir.open, url)
 
228
        # which bzrdir.open_containing will refuse (not supported)
 
229
        self.assertRaises(UnsupportedFormatError, bzrdir.BzrDir.open_containing, url)
 
230
        # but open_downlevel will work
 
231
        t = get_transport(url)
 
232
        self.assertEqual(format.open(t), bzrdir.BzrDir.open_unsupported(url))
 
233
        # unregister the format
 
234
        bzrdir.BzrDirFormat.unregister_format(format)
 
235
        # now open_downlevel should fail too.
 
236
        self.assertRaises(UnknownFormatError, bzrdir.BzrDir.open_unsupported, url)
 
237
 
 
238
    def test_create_repository(self):
 
239
        format = SampleBzrDirFormat()
 
240
        repo = bzrdir.BzrDir.create_repository(self.get_url(), format=format)
 
241
        self.assertEqual('A repository', repo)
 
242
 
 
243
    def test_create_repository_shared(self):
 
244
        old_format = bzrdir.BzrDirFormat.get_default_format()
 
245
        repo = bzrdir.BzrDir.create_repository('.', shared=True)
 
246
        self.assertTrue(repo.is_shared())
 
247
 
 
248
    def test_create_repository_nonshared(self):
 
249
        old_format = bzrdir.BzrDirFormat.get_default_format()
 
250
        repo = bzrdir.BzrDir.create_repository('.')
 
251
        self.assertFalse(repo.is_shared())
 
252
 
 
253
    def test_create_repository_under_shared(self):
 
254
        # an explicit create_repository always does so.
 
255
        # we trust the format is right from the 'create_repository test'
 
256
        format = bzrdir.format_registry.make_bzrdir('knit')
 
257
        self.make_repository('.', shared=True, format=format)
 
258
        repo = bzrdir.BzrDir.create_repository(self.get_url('child'),
 
259
                                               format=format)
 
260
        self.assertTrue(isinstance(repo, repository.Repository))
 
261
        self.assertTrue(repo.bzrdir.root_transport.base.endswith('child/'))
 
262
 
 
263
    def test_create_branch_and_repo_uses_default(self):
 
264
        format = SampleBzrDirFormat()
 
265
        branch = bzrdir.BzrDir.create_branch_and_repo(self.get_url(), 
 
266
                                                      format=format)
 
267
        self.assertTrue(isinstance(branch, SampleBranch))
 
268
 
 
269
    def test_create_branch_and_repo_under_shared(self):
 
270
        # creating a branch and repo in a shared repo uses the
 
271
        # shared repository
 
272
        format = bzrdir.format_registry.make_bzrdir('knit')
 
273
        self.make_repository('.', shared=True, format=format)
 
274
        branch = bzrdir.BzrDir.create_branch_and_repo(
 
275
            self.get_url('child'), format=format)
 
276
        self.assertRaises(errors.NoRepositoryPresent,
 
277
                          branch.bzrdir.open_repository)
 
278
 
 
279
    def test_create_branch_and_repo_under_shared_force_new(self):
 
280
        # creating a branch and repo in a shared repo can be forced to 
 
281
        # make a new repo
 
282
        format = bzrdir.format_registry.make_bzrdir('knit')
 
283
        self.make_repository('.', shared=True, format=format)
 
284
        branch = bzrdir.BzrDir.create_branch_and_repo(self.get_url('child'),
 
285
                                                      force_new_repo=True,
 
286
                                                      format=format)
 
287
        branch.bzrdir.open_repository()
 
288
 
 
289
    def test_create_standalone_working_tree(self):
 
290
        format = SampleBzrDirFormat()
 
291
        # note this is deliberately readonly, as this failure should 
 
292
        # occur before any writes.
 
293
        self.assertRaises(errors.NotLocalUrl,
 
294
                          bzrdir.BzrDir.create_standalone_workingtree,
 
295
                          self.get_readonly_url(), format=format)
 
296
        tree = bzrdir.BzrDir.create_standalone_workingtree('.', 
 
297
                                                           format=format)
 
298
        self.assertEqual('A tree', tree)
 
299
 
 
300
    def test_create_standalone_working_tree_under_shared_repo(self):
 
301
        # create standalone working tree always makes a repo.
 
302
        format = bzrdir.format_registry.make_bzrdir('knit')
 
303
        self.make_repository('.', shared=True, format=format)
 
304
        # note this is deliberately readonly, as this failure should 
 
305
        # occur before any writes.
 
306
        self.assertRaises(errors.NotLocalUrl,
 
307
                          bzrdir.BzrDir.create_standalone_workingtree,
 
308
                          self.get_readonly_url('child'), format=format)
 
309
        tree = bzrdir.BzrDir.create_standalone_workingtree('child', 
 
310
            format=format)
 
311
        tree.bzrdir.open_repository()
 
312
 
 
313
    def test_create_branch_convenience(self):
 
314
        # outside a repo the default convenience output is a repo+branch_tree
 
315
        format = bzrdir.format_registry.make_bzrdir('knit')
 
316
        branch = bzrdir.BzrDir.create_branch_convenience('.', format=format)
 
317
        branch.bzrdir.open_workingtree()
 
318
        branch.bzrdir.open_repository()
 
319
 
 
320
    def test_create_branch_convenience_root(self):
 
321
        """Creating a branch at the root of a fs should work."""
 
322
        self.transport_server = MemoryServer
 
323
        # outside a repo the default convenience output is a repo+branch_tree
 
324
        format = bzrdir.format_registry.make_bzrdir('knit')
 
325
        branch = bzrdir.BzrDir.create_branch_convenience(self.get_url(), 
 
326
                                                         format=format)
 
327
        self.assertRaises(errors.NoWorkingTree,
 
328
                          branch.bzrdir.open_workingtree)
 
329
        branch.bzrdir.open_repository()
 
330
 
 
331
    def test_create_branch_convenience_under_shared_repo(self):
 
332
        # inside a repo the default convenience output is a branch+ follow the
 
333
        # repo tree policy
 
334
        format = bzrdir.format_registry.make_bzrdir('knit')
 
335
        self.make_repository('.', shared=True, format=format)
 
336
        branch = bzrdir.BzrDir.create_branch_convenience('child',
 
337
            format=format)
 
338
        branch.bzrdir.open_workingtree()
 
339
        self.assertRaises(errors.NoRepositoryPresent,
 
340
                          branch.bzrdir.open_repository)
 
341
            
 
342
    def test_create_branch_convenience_under_shared_repo_force_no_tree(self):
 
343
        # inside a repo the default convenience output is a branch+ follow the
 
344
        # repo tree policy but we can override that
 
345
        format = bzrdir.format_registry.make_bzrdir('knit')
 
346
        self.make_repository('.', shared=True, format=format)
 
347
        branch = bzrdir.BzrDir.create_branch_convenience('child',
 
348
            force_new_tree=False, format=format)
 
349
        self.assertRaises(errors.NoWorkingTree,
 
350
                          branch.bzrdir.open_workingtree)
 
351
        self.assertRaises(errors.NoRepositoryPresent,
 
352
                          branch.bzrdir.open_repository)
 
353
            
 
354
    def test_create_branch_convenience_under_shared_repo_no_tree_policy(self):
 
355
        # inside a repo the default convenience output is a branch+ follow the
 
356
        # repo tree policy
 
357
        format = bzrdir.format_registry.make_bzrdir('knit')
 
358
        repo = self.make_repository('.', shared=True, format=format)
 
359
        repo.set_make_working_trees(False)
 
360
        branch = bzrdir.BzrDir.create_branch_convenience('child', 
 
361
                                                         format=format)
 
362
        self.assertRaises(errors.NoWorkingTree,
 
363
                          branch.bzrdir.open_workingtree)
 
364
        self.assertRaises(errors.NoRepositoryPresent,
 
365
                          branch.bzrdir.open_repository)
 
366
 
 
367
    def test_create_branch_convenience_under_shared_repo_no_tree_policy_force_tree(self):
 
368
        # inside a repo the default convenience output is a branch+ follow the
 
369
        # repo tree policy but we can override that
 
370
        format = bzrdir.format_registry.make_bzrdir('knit')
 
371
        repo = self.make_repository('.', shared=True, format=format)
 
372
        repo.set_make_working_trees(False)
 
373
        branch = bzrdir.BzrDir.create_branch_convenience('child',
 
374
            force_new_tree=True, format=format)
 
375
        branch.bzrdir.open_workingtree()
 
376
        self.assertRaises(errors.NoRepositoryPresent,
 
377
                          branch.bzrdir.open_repository)
 
378
 
 
379
    def test_create_branch_convenience_under_shared_repo_force_new_repo(self):
 
380
        # inside a repo the default convenience output is overridable to give
 
381
        # repo+branch+tree
 
382
        format = bzrdir.format_registry.make_bzrdir('knit')
 
383
        self.make_repository('.', shared=True, format=format)
 
384
        branch = bzrdir.BzrDir.create_branch_convenience('child',
 
385
            force_new_repo=True, format=format)
 
386
        branch.bzrdir.open_repository()
 
387
        branch.bzrdir.open_workingtree()
 
388
 
 
389
 
 
390
class ChrootedTests(TestCaseWithTransport):
 
391
    """A support class that provides readonly urls outside the local namespace.
 
392
 
 
393
    This is done by checking if self.transport_server is a MemoryServer. if it
 
394
    is then we are chrooted already, if it is not then an HttpServer is used
 
395
    for readonly urls.
 
396
    """
 
397
 
 
398
    def setUp(self):
 
399
        super(ChrootedTests, self).setUp()
 
400
        if not self.transport_server == MemoryServer:
 
401
            self.transport_readonly_server = HttpServer
 
402
 
 
403
    def test_open_containing(self):
 
404
        self.assertRaises(NotBranchError, bzrdir.BzrDir.open_containing,
 
405
                          self.get_readonly_url(''))
 
406
        self.assertRaises(NotBranchError, bzrdir.BzrDir.open_containing,
 
407
                          self.get_readonly_url('g/p/q'))
 
408
        control = bzrdir.BzrDir.create(self.get_url())
 
409
        branch, relpath = bzrdir.BzrDir.open_containing(self.get_readonly_url(''))
 
410
        self.assertEqual('', relpath)
 
411
        branch, relpath = bzrdir.BzrDir.open_containing(self.get_readonly_url('g/p/q'))
 
412
        self.assertEqual('g/p/q', relpath)
 
413
 
 
414
    def test_open_containing_from_transport(self):
 
415
        self.assertRaises(NotBranchError, bzrdir.BzrDir.open_containing_from_transport,
 
416
                          get_transport(self.get_readonly_url('')))
 
417
        self.assertRaises(NotBranchError, bzrdir.BzrDir.open_containing_from_transport,
 
418
                          get_transport(self.get_readonly_url('g/p/q')))
 
419
        control = bzrdir.BzrDir.create(self.get_url())
 
420
        branch, relpath = bzrdir.BzrDir.open_containing_from_transport(
 
421
            get_transport(self.get_readonly_url('')))
 
422
        self.assertEqual('', relpath)
 
423
        branch, relpath = bzrdir.BzrDir.open_containing_from_transport(
 
424
            get_transport(self.get_readonly_url('g/p/q')))
 
425
        self.assertEqual('g/p/q', relpath)
 
426
 
 
427
    def test_open_containing_tree_or_branch(self):
 
428
        def local_branch_path(branch):
 
429
             return os.path.realpath(
 
430
                urlutils.local_path_from_url(branch.base))
 
431
 
 
432
        self.make_branch_and_tree('topdir')
 
433
        tree, branch, relpath = bzrdir.BzrDir.open_containing_tree_or_branch(
 
434
            'topdir/foo')
 
435
        self.assertEqual(os.path.realpath('topdir'),
 
436
                         os.path.realpath(tree.basedir))
 
437
        self.assertEqual(os.path.realpath('topdir'),
 
438
                         local_branch_path(branch))
 
439
        self.assertIs(tree.bzrdir, branch.bzrdir)
 
440
        self.assertEqual('foo', relpath)
 
441
        self.make_branch('topdir/foo')
 
442
        tree, branch, relpath = bzrdir.BzrDir.open_containing_tree_or_branch(
 
443
            'topdir/foo')
 
444
        self.assertIs(tree, None)
 
445
        self.assertEqual(os.path.realpath('topdir/foo'),
 
446
                         local_branch_path(branch))
 
447
        self.assertEqual('', relpath)
 
448
 
 
449
    def test_open_from_transport(self):
 
450
        # transport pointing at bzrdir should give a bzrdir with root transport
 
451
        # set to the given transport
 
452
        control = bzrdir.BzrDir.create(self.get_url())
 
453
        transport = get_transport(self.get_url())
 
454
        opened_bzrdir = bzrdir.BzrDir.open_from_transport(transport)
 
455
        self.assertEqual(transport.base, opened_bzrdir.root_transport.base)
 
456
        self.assertIsInstance(opened_bzrdir, bzrdir.BzrDir)
 
457
        
 
458
    def test_open_from_transport_no_bzrdir(self):
 
459
        transport = get_transport(self.get_url())
 
460
        self.assertRaises(NotBranchError, bzrdir.BzrDir.open_from_transport,
 
461
                          transport)
 
462
 
 
463
    def test_open_from_transport_bzrdir_in_parent(self):
 
464
        control = bzrdir.BzrDir.create(self.get_url())
 
465
        transport = get_transport(self.get_url())
 
466
        transport.mkdir('subdir')
 
467
        transport = transport.clone('subdir')
 
468
        self.assertRaises(NotBranchError, bzrdir.BzrDir.open_from_transport,
 
469
                          transport)
 
470
 
 
471
 
 
472
class TestMeta1DirFormat(TestCaseWithTransport):
 
473
    """Tests specific to the meta1 dir format."""
 
474
 
 
475
    def test_right_base_dirs(self):
 
476
        dir = bzrdir.BzrDirMetaFormat1().initialize(self.get_url())
 
477
        t = dir.transport
 
478
        branch_base = t.clone('branch').base
 
479
        self.assertEqual(branch_base, dir.get_branch_transport(None).base)
 
480
        self.assertEqual(branch_base,
 
481
                         dir.get_branch_transport(bzrlib.branch.BzrBranchFormat5()).base)
 
482
        repository_base = t.clone('repository').base
 
483
        self.assertEqual(repository_base, dir.get_repository_transport(None).base)
 
484
        self.assertEqual(repository_base,
 
485
                         dir.get_repository_transport(repository.RepositoryFormat7()).base)
 
486
        checkout_base = t.clone('checkout').base
 
487
        self.assertEqual(checkout_base, dir.get_workingtree_transport(None).base)
 
488
        self.assertEqual(checkout_base,
 
489
                         dir.get_workingtree_transport(workingtree.WorkingTreeFormat3()).base)
 
490
 
 
491
    def test_meta1dir_uses_lockdir(self):
 
492
        """Meta1 format uses a LockDir to guard the whole directory, not a file."""
 
493
        dir = bzrdir.BzrDirMetaFormat1().initialize(self.get_url())
 
494
        t = dir.transport
 
495
        self.assertIsDirectory('branch-lock', t)
 
496
 
 
497
        
 
498
class TestFormat5(TestCaseWithTransport):
 
499
    """Tests specific to the version 5 bzrdir format."""
 
500
 
 
501
    def test_same_lockfiles_between_tree_repo_branch(self):
 
502
        # this checks that only a single lockfiles instance is created 
 
503
        # for format 5 objects
 
504
        dir = bzrdir.BzrDirFormat5().initialize(self.get_url())
 
505
        def check_dir_components_use_same_lock(dir):
 
506
            ctrl_1 = dir.open_repository().control_files
 
507
            ctrl_2 = dir.open_branch().control_files
 
508
            ctrl_3 = dir.open_workingtree()._control_files
 
509
            self.assertTrue(ctrl_1 is ctrl_2)
 
510
            self.assertTrue(ctrl_2 is ctrl_3)
 
511
        check_dir_components_use_same_lock(dir)
 
512
        # and if we open it normally.
 
513
        dir = bzrdir.BzrDir.open(self.get_url())
 
514
        check_dir_components_use_same_lock(dir)
 
515
    
 
516
    def test_can_convert(self):
 
517
        # format 5 dirs are convertable
 
518
        dir = bzrdir.BzrDirFormat5().initialize(self.get_url())
 
519
        self.assertTrue(dir.can_convert_format())
 
520
    
 
521
    def test_needs_conversion(self):
 
522
        # format 5 dirs need a conversion if they are not the default.
 
523
        # and they start of not the default.
 
524
        old_format = bzrdir.BzrDirFormat.get_default_format()
 
525
        bzrdir.BzrDirFormat._set_default_format(bzrdir.BzrDirFormat5())
 
526
        try:
 
527
            dir = bzrdir.BzrDirFormat5().initialize(self.get_url())
 
528
            self.assertFalse(dir.needs_format_conversion())
 
529
        finally:
 
530
            bzrdir.BzrDirFormat._set_default_format(old_format)
 
531
        self.assertTrue(dir.needs_format_conversion())
 
532
 
 
533
 
 
534
class TestFormat6(TestCaseWithTransport):
 
535
    """Tests specific to the version 6 bzrdir format."""
 
536
 
 
537
    def test_same_lockfiles_between_tree_repo_branch(self):
 
538
        # this checks that only a single lockfiles instance is created 
 
539
        # for format 6 objects
 
540
        dir = bzrdir.BzrDirFormat6().initialize(self.get_url())
 
541
        def check_dir_components_use_same_lock(dir):
 
542
            ctrl_1 = dir.open_repository().control_files
 
543
            ctrl_2 = dir.open_branch().control_files
 
544
            ctrl_3 = dir.open_workingtree()._control_files
 
545
            self.assertTrue(ctrl_1 is ctrl_2)
 
546
            self.assertTrue(ctrl_2 is ctrl_3)
 
547
        check_dir_components_use_same_lock(dir)
 
548
        # and if we open it normally.
 
549
        dir = bzrdir.BzrDir.open(self.get_url())
 
550
        check_dir_components_use_same_lock(dir)
 
551
    
 
552
    def test_can_convert(self):
 
553
        # format 6 dirs are convertable
 
554
        dir = bzrdir.BzrDirFormat6().initialize(self.get_url())
 
555
        self.assertTrue(dir.can_convert_format())
 
556
    
 
557
    def test_needs_conversion(self):
 
558
        # format 6 dirs need an conversion if they are not the default.
 
559
        old_format = bzrdir.BzrDirFormat.get_default_format()
 
560
        bzrdir.BzrDirFormat._set_default_format(bzrdir.BzrDirMetaFormat1())
 
561
        try:
 
562
            dir = bzrdir.BzrDirFormat6().initialize(self.get_url())
 
563
            self.assertTrue(dir.needs_format_conversion())
 
564
        finally:
 
565
            bzrdir.BzrDirFormat._set_default_format(old_format)
 
566
 
 
567
 
 
568
class NotBzrDir(bzrlib.bzrdir.BzrDir):
 
569
    """A non .bzr based control directory."""
 
570
 
 
571
    def __init__(self, transport, format):
 
572
        self._format = format
 
573
        self.root_transport = transport
 
574
        self.transport = transport.clone('.not')
 
575
 
 
576
 
 
577
class NotBzrDirFormat(bzrlib.bzrdir.BzrDirFormat):
 
578
    """A test class representing any non-.bzr based disk format."""
 
579
 
 
580
    def initialize_on_transport(self, transport):
 
581
        """Initialize a new .not dir in the base directory of a Transport."""
 
582
        transport.mkdir('.not')
 
583
        return self.open(transport)
 
584
 
 
585
    def open(self, transport):
 
586
        """Open this directory."""
 
587
        return NotBzrDir(transport, self)
 
588
 
 
589
    @classmethod
 
590
    def _known_formats(self):
 
591
        return set([NotBzrDirFormat()])
 
592
 
 
593
    @classmethod
 
594
    def probe_transport(self, transport):
 
595
        """Our format is present if the transport ends in '.not/'."""
 
596
        if transport.has('.not'):
 
597
            return NotBzrDirFormat()
 
598
 
 
599
 
 
600
class TestNotBzrDir(TestCaseWithTransport):
 
601
    """Tests for using the bzrdir api with a non .bzr based disk format.
 
602
    
 
603
    If/when one of these is in the core, we can let the implementation tests
 
604
    verify this works.
 
605
    """
 
606
 
 
607
    def test_create_and_find_format(self):
 
608
        # create a .notbzr dir 
 
609
        format = NotBzrDirFormat()
 
610
        dir = format.initialize(self.get_url())
 
611
        self.assertIsInstance(dir, NotBzrDir)
 
612
        # now probe for it.
 
613
        bzrlib.bzrdir.BzrDirFormat.register_control_format(format)
 
614
        try:
 
615
            found = bzrlib.bzrdir.BzrDirFormat.find_format(
 
616
                get_transport(self.get_url()))
 
617
            self.assertIsInstance(found, NotBzrDirFormat)
 
618
        finally:
 
619
            bzrlib.bzrdir.BzrDirFormat.unregister_control_format(format)
 
620
 
 
621
    def test_included_in_known_formats(self):
 
622
        bzrlib.bzrdir.BzrDirFormat.register_control_format(NotBzrDirFormat)
 
623
        try:
 
624
            formats = bzrlib.bzrdir.BzrDirFormat.known_formats()
 
625
            for format in formats:
 
626
                if isinstance(format, NotBzrDirFormat):
 
627
                    return
 
628
            self.fail("No NotBzrDirFormat in %s" % formats)
 
629
        finally:
 
630
            bzrlib.bzrdir.BzrDirFormat.unregister_control_format(NotBzrDirFormat)
 
631
 
 
632
 
 
633
class NonLocalTests(TestCaseWithTransport):
 
634
    """Tests for bzrdir static behaviour on non local paths."""
 
635
 
 
636
    def setUp(self):
 
637
        super(NonLocalTests, self).setUp()
 
638
        self.transport_server = MemoryServer
 
639
    
 
640
    def test_create_branch_convenience(self):
 
641
        # outside a repo the default convenience output is a repo+branch_tree
 
642
        format = bzrdir.format_registry.make_bzrdir('knit')
 
643
        branch = bzrdir.BzrDir.create_branch_convenience(
 
644
            self.get_url('foo'), format=format)
 
645
        self.assertRaises(errors.NoWorkingTree,
 
646
                          branch.bzrdir.open_workingtree)
 
647
        branch.bzrdir.open_repository()
 
648
 
 
649
    def test_create_branch_convenience_force_tree_not_local_fails(self):
 
650
        # outside a repo the default convenience output is a repo+branch_tree
 
651
        format = bzrdir.format_registry.make_bzrdir('knit')
 
652
        self.assertRaises(errors.NotLocalUrl,
 
653
            bzrdir.BzrDir.create_branch_convenience,
 
654
            self.get_url('foo'),
 
655
            force_new_tree=True,
 
656
            format=format)
 
657
        t = get_transport(self.get_url('.'))
 
658
        self.assertFalse(t.has('foo'))
 
659
 
 
660
    def test_clone(self):
 
661
        # clone into a nonlocal path works
 
662
        format = bzrdir.format_registry.make_bzrdir('knit')
 
663
        branch = bzrdir.BzrDir.create_branch_convenience('local',
 
664
                                                         format=format)
 
665
        branch.bzrdir.open_workingtree()
 
666
        result = branch.bzrdir.clone(self.get_url('remote'))
 
667
        self.assertRaises(errors.NoWorkingTree,
 
668
                          result.open_workingtree)
 
669
        result.open_branch()
 
670
        result.open_repository()
 
671
 
 
672
 
 
673
class TestRemoteSFTP(test_sftp_transport.TestCaseWithSFTPServer):
 
674
 
 
675
    def test_open_containing_tree_or_branch(self):
 
676
        tree = self.make_branch_and_tree('tree')
 
677
        bzrdir.BzrDir.open_containing_tree_or_branch(self.get_url('tree'))