~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_bzrdir.py

  • Committer: Robert Collins
  • Date: 2007-03-08 04:06:06 UTC
  • mfrom: (2323.1.1 integration)
  • mto: This revision was merged to the branch mainline in revision 2442.
  • Revision ID: robertc@robertcollins.net-20070308040606-84gsniv56huiyjt4
Merge bzr.dev.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005, 2006 Canonical Ltd
 
1
# Copyright (C) 2005, 2006, 2007 Canonical Ltd
2
2
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
5
5
# the Free Software Foundation; either version 2 of the License, or
6
6
# (at your option) any later version.
7
 
 
7
#
8
8
# This program is distributed in the hope that it will be useful,
9
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
11
# GNU General Public License for more details.
12
 
 
12
#
13
13
# You should have received a copy of the GNU General Public License
14
14
# along with this program; if not, write to the Free Software
15
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19
19
For interface contract tests, see tests/bzr_dir_implementations.
20
20
"""
21
21
 
 
22
import os.path
22
23
from StringIO import StringIO
23
24
 
 
25
from bzrlib import (
 
26
    bzrdir,
 
27
    errors,
 
28
    help_topics,
 
29
    repository,
 
30
    symbol_versioning,
 
31
    urlutils,
 
32
    workingtree,
 
33
    )
24
34
import bzrlib.branch
25
 
import bzrlib.bzrdir as bzrdir
26
 
import bzrlib.errors as errors
27
35
from bzrlib.errors import (NotBranchError,
28
36
                           UnknownFormatError,
29
37
                           UnsupportedFormatError,
30
38
                           )
31
 
import bzrlib.repository as repository
32
 
from bzrlib.tests import TestCase, TestCaseWithTransport
 
39
from bzrlib.tests import TestCase, TestCaseWithTransport, test_sftp_transport
 
40
from bzrlib.tests.HttpServer import HttpServer
33
41
from bzrlib.transport import get_transport
34
 
from bzrlib.transport.http import HttpServer
35
42
from bzrlib.transport.memory import MemoryServer
36
 
import bzrlib.workingtree as workingtree
 
43
from bzrlib.repofmt import knitrepo, weaverepo
37
44
 
38
45
 
39
46
class TestDefaultFormat(TestCase):
42
49
        old_format = bzrdir.BzrDirFormat.get_default_format()
43
50
        # default is BzrDirFormat6
44
51
        self.failUnless(isinstance(old_format, bzrdir.BzrDirMetaFormat1))
45
 
        bzrdir.BzrDirFormat.set_default_format(SampleBzrDirFormat())
 
52
        self.applyDeprecated(symbol_versioning.zero_fourteen, 
 
53
                             bzrdir.BzrDirFormat.set_default_format, 
 
54
                             SampleBzrDirFormat())
46
55
        # creating a bzr dir should now create an instrumented dir.
47
56
        try:
48
 
            result = bzrdir.BzrDir.create('memory:/')
 
57
            result = bzrdir.BzrDir.create('memory:///')
49
58
            self.failUnless(isinstance(result, SampleBzrDir))
50
59
        finally:
51
 
            bzrdir.BzrDirFormat.set_default_format(old_format)
 
60
            self.applyDeprecated(symbol_versioning.zero_fourteen,
 
61
                bzrdir.BzrDirFormat.set_default_format, old_format)
52
62
        self.assertEqual(old_format, bzrdir.BzrDirFormat.get_default_format())
53
63
 
54
64
 
 
65
class TestFormatRegistry(TestCase):
 
66
 
 
67
    def make_format_registry(self):
 
68
        my_format_registry = bzrdir.BzrDirFormatRegistry()
 
69
        my_format_registry.register('weave', bzrdir.BzrDirFormat6,
 
70
            'Pre-0.8 format.  Slower and does not support checkouts or shared'
 
71
            ' repositories', deprecated=True)
 
72
        my_format_registry.register_lazy('lazy', 'bzrlib.bzrdir', 
 
73
            'BzrDirFormat6', 'Format registered lazily', deprecated=True)
 
74
        my_format_registry.register_metadir('knit',
 
75
            'bzrlib.repofmt.knitrepo.RepositoryFormatKnit1',
 
76
            'Format using knits',
 
77
            )
 
78
        my_format_registry.set_default('knit')
 
79
        my_format_registry.register_metadir(
 
80
            'branch6',
 
81
            'bzrlib.repofmt.knitrepo.RepositoryFormatKnit3',
 
82
            'Experimental successor to knit.  Use at your own risk.',
 
83
            branch_format='bzrlib.branch.BzrBranchFormat6')
 
84
        return my_format_registry
 
85
 
 
86
    def test_format_registry(self):
 
87
        my_format_registry = self.make_format_registry()
 
88
        my_bzrdir = my_format_registry.make_bzrdir('lazy')
 
89
        self.assertIsInstance(my_bzrdir, bzrdir.BzrDirFormat6)
 
90
        my_bzrdir = my_format_registry.make_bzrdir('weave')
 
91
        self.assertIsInstance(my_bzrdir, bzrdir.BzrDirFormat6)
 
92
        my_bzrdir = my_format_registry.make_bzrdir('default')
 
93
        self.assertIsInstance(my_bzrdir.repository_format, 
 
94
            knitrepo.RepositoryFormatKnit1)
 
95
        my_bzrdir = my_format_registry.make_bzrdir('knit')
 
96
        self.assertIsInstance(my_bzrdir.repository_format, 
 
97
            knitrepo.RepositoryFormatKnit1)
 
98
        my_bzrdir = my_format_registry.make_bzrdir('branch6')
 
99
        self.assertIsInstance(my_bzrdir.get_branch_format(),
 
100
                              bzrlib.branch.BzrBranchFormat6)
 
101
 
 
102
    def test_get_help(self):
 
103
        my_format_registry = self.make_format_registry()
 
104
        self.assertEqual('Format registered lazily',
 
105
                         my_format_registry.get_help('lazy'))
 
106
        self.assertEqual('Format using knits', 
 
107
                         my_format_registry.get_help('knit'))
 
108
        self.assertEqual('Format using knits', 
 
109
                         my_format_registry.get_help('default'))
 
110
        self.assertEqual('Pre-0.8 format.  Slower and does not support'
 
111
                         ' checkouts or shared repositories', 
 
112
                         my_format_registry.get_help('weave'))
 
113
        
 
114
    def test_help_topic(self):
 
115
        topics = help_topics.HelpTopicRegistry()
 
116
        topics.register('formats', self.make_format_registry().help_topic, 
 
117
                        'Directory formats')
 
118
        topic = topics.get_detail('formats')
 
119
        new, deprecated = topic.split('Deprecated formats')
 
120
        self.assertContainsRe(new, 'Bazaar directory formats')
 
121
        self.assertContainsRe(new, 
 
122
            '  knit/default:\n    \(native\) Format using knits\n')
 
123
        self.assertContainsRe(deprecated, 
 
124
            '  lazy:\n    \(native\) Format registered lazily\n')
 
125
 
 
126
    def test_set_default_repository(self):
 
127
        default_factory = bzrdir.format_registry.get('default')
 
128
        old_default = [k for k, v in bzrdir.format_registry.iteritems()
 
129
                       if v == default_factory and k != 'default'][0]
 
130
        bzrdir.format_registry.set_default_repository('dirstate-with-subtree')
 
131
        try:
 
132
            self.assertIs(bzrdir.format_registry.get('dirstate-with-subtree'),
 
133
                          bzrdir.format_registry.get('default'))
 
134
            self.assertIs(
 
135
                repository.RepositoryFormat.get_default_format().__class__,
 
136
                knitrepo.RepositoryFormatKnit3)
 
137
        finally:
 
138
            bzrdir.format_registry.set_default_repository(old_default)
 
139
 
 
140
 
55
141
class SampleBranch(bzrlib.branch.Branch):
56
142
    """A dummy branch for guess what, dummy use."""
57
143
 
62
148
class SampleBzrDir(bzrdir.BzrDir):
63
149
    """A sample BzrDir implementation to allow testing static methods."""
64
150
 
65
 
    def create_repository(self):
 
151
    def create_repository(self, shared=False):
66
152
        """See BzrDir.create_repository."""
67
153
        return "A repository"
68
154
 
94
180
        """Create a bzr dir."""
95
181
        t = get_transport(url)
96
182
        t.mkdir('.bzr')
97
 
        t.put('.bzr/branch-format', StringIO(self.get_format_string()))
 
183
        t.put_bytes('.bzr/branch-format', self.get_format_string())
98
184
        return SampleBzrDir(t, self)
99
185
 
100
186
    def is_supported(self):
129
215
    def test_find_format_unknown_format(self):
130
216
        t = get_transport(self.get_url())
131
217
        t.mkdir('.bzr')
132
 
        t.put('.bzr/branch-format', StringIO())
 
218
        t.put_bytes('.bzr/branch-format', '')
133
219
        self.assertRaises(UnknownFormatError,
134
220
                          bzrdir.BzrDirFormat.find_format,
135
221
                          get_transport('.'))
155
241
 
156
242
    def test_create_repository(self):
157
243
        format = SampleBzrDirFormat()
158
 
        old_format = bzrdir.BzrDirFormat.get_default_format()
159
 
        bzrdir.BzrDirFormat.set_default_format(format)
160
 
        try:
161
 
            repo = bzrdir.BzrDir.create_repository(self.get_url())
162
 
            self.assertEqual('A repository', repo)
163
 
        finally:
164
 
            bzrdir.BzrDirFormat.set_default_format(old_format)
 
244
        repo = bzrdir.BzrDir.create_repository(self.get_url(), format=format)
 
245
        self.assertEqual('A repository', repo)
 
246
 
 
247
    def test_create_repository_shared(self):
 
248
        old_format = bzrdir.BzrDirFormat.get_default_format()
 
249
        repo = bzrdir.BzrDir.create_repository('.', shared=True)
 
250
        self.assertTrue(repo.is_shared())
 
251
 
 
252
    def test_create_repository_nonshared(self):
 
253
        old_format = bzrdir.BzrDirFormat.get_default_format()
 
254
        repo = bzrdir.BzrDir.create_repository('.')
 
255
        self.assertFalse(repo.is_shared())
165
256
 
166
257
    def test_create_repository_under_shared(self):
167
258
        # an explicit create_repository always does so.
168
259
        # we trust the format is right from the 'create_repository test'
169
 
        old_format = bzrdir.BzrDirFormat.get_default_format()
170
 
        bzrdir.BzrDirFormat.set_default_format(bzrdir.BzrDirMetaFormat1())
171
 
        try:
172
 
            self.make_repository('.', shared=True)
173
 
            repo = bzrdir.BzrDir.create_repository(self.get_url('child'))
174
 
            self.assertTrue(isinstance(repo, repository.Repository))
175
 
            self.assertTrue(repo.bzrdir.root_transport.base.endswith('child/'))
176
 
        finally:
177
 
            bzrdir.BzrDirFormat.set_default_format(old_format)
 
260
        format = bzrdir.format_registry.make_bzrdir('knit')
 
261
        self.make_repository('.', shared=True, format=format)
 
262
        repo = bzrdir.BzrDir.create_repository(self.get_url('child'),
 
263
                                               format=format)
 
264
        self.assertTrue(isinstance(repo, repository.Repository))
 
265
        self.assertTrue(repo.bzrdir.root_transport.base.endswith('child/'))
178
266
 
179
267
    def test_create_branch_and_repo_uses_default(self):
180
268
        format = SampleBzrDirFormat()
181
 
        old_format = bzrdir.BzrDirFormat.get_default_format()
182
 
        bzrdir.BzrDirFormat.set_default_format(format)
183
 
        try:
184
 
            branch = bzrdir.BzrDir.create_branch_and_repo(self.get_url())
185
 
            self.assertTrue(isinstance(branch, SampleBranch))
186
 
        finally:
187
 
            bzrdir.BzrDirFormat.set_default_format(old_format)
 
269
        branch = bzrdir.BzrDir.create_branch_and_repo(self.get_url(), 
 
270
                                                      format=format)
 
271
        self.assertTrue(isinstance(branch, SampleBranch))
188
272
 
189
273
    def test_create_branch_and_repo_under_shared(self):
190
274
        # creating a branch and repo in a shared repo uses the
191
275
        # shared repository
192
 
        old_format = bzrdir.BzrDirFormat.get_default_format()
193
 
        bzrdir.BzrDirFormat.set_default_format(bzrdir.BzrDirMetaFormat1())
194
 
        try:
195
 
            self.make_repository('.', shared=True)
196
 
            branch = bzrdir.BzrDir.create_branch_and_repo(self.get_url('child'))
197
 
            self.assertRaises(errors.NoRepositoryPresent,
198
 
                              branch.bzrdir.open_repository)
199
 
        finally:
200
 
            bzrdir.BzrDirFormat.set_default_format(old_format)
 
276
        format = bzrdir.format_registry.make_bzrdir('knit')
 
277
        self.make_repository('.', shared=True, format=format)
 
278
        branch = bzrdir.BzrDir.create_branch_and_repo(
 
279
            self.get_url('child'), format=format)
 
280
        self.assertRaises(errors.NoRepositoryPresent,
 
281
                          branch.bzrdir.open_repository)
201
282
 
202
283
    def test_create_branch_and_repo_under_shared_force_new(self):
203
284
        # creating a branch and repo in a shared repo can be forced to 
204
285
        # make a new repo
205
 
        old_format = bzrdir.BzrDirFormat.get_default_format()
206
 
        bzrdir.BzrDirFormat.set_default_format(bzrdir.BzrDirMetaFormat1())
207
 
        try:
208
 
            self.make_repository('.', shared=True)
209
 
            branch = bzrdir.BzrDir.create_branch_and_repo(self.get_url('child'),
210
 
                                                          force_new_repo=True)
211
 
            branch.bzrdir.open_repository()
212
 
        finally:
213
 
            bzrdir.BzrDirFormat.set_default_format(old_format)
 
286
        format = bzrdir.format_registry.make_bzrdir('knit')
 
287
        self.make_repository('.', shared=True, format=format)
 
288
        branch = bzrdir.BzrDir.create_branch_and_repo(self.get_url('child'),
 
289
                                                      force_new_repo=True,
 
290
                                                      format=format)
 
291
        branch.bzrdir.open_repository()
214
292
 
215
293
    def test_create_standalone_working_tree(self):
216
294
        format = SampleBzrDirFormat()
217
 
        old_format = bzrdir.BzrDirFormat.get_default_format()
218
 
        bzrdir.BzrDirFormat.set_default_format(format)
219
 
        try:
220
 
            # note this is deliberately readonly, as this failure should 
221
 
            # occur before any writes.
222
 
            self.assertRaises(errors.NotLocalUrl,
223
 
                              bzrdir.BzrDir.create_standalone_workingtree,
224
 
                              self.get_readonly_url())
225
 
            tree = bzrdir.BzrDir.create_standalone_workingtree('.')
226
 
            self.assertEqual('A tree', tree)
227
 
        finally:
228
 
            bzrdir.BzrDirFormat.set_default_format(old_format)
 
295
        # note this is deliberately readonly, as this failure should 
 
296
        # occur before any writes.
 
297
        self.assertRaises(errors.NotLocalUrl,
 
298
                          bzrdir.BzrDir.create_standalone_workingtree,
 
299
                          self.get_readonly_url(), format=format)
 
300
        tree = bzrdir.BzrDir.create_standalone_workingtree('.', 
 
301
                                                           format=format)
 
302
        self.assertEqual('A tree', tree)
229
303
 
230
304
    def test_create_standalone_working_tree_under_shared_repo(self):
231
305
        # create standalone working tree always makes a repo.
232
 
        old_format = bzrdir.BzrDirFormat.get_default_format()
233
 
        bzrdir.BzrDirFormat.set_default_format(bzrdir.BzrDirMetaFormat1())
234
 
        try:
235
 
            self.make_repository('.', shared=True)
236
 
            # note this is deliberately readonly, as this failure should 
237
 
            # occur before any writes.
238
 
            self.assertRaises(errors.NotLocalUrl,
239
 
                              bzrdir.BzrDir.create_standalone_workingtree,
240
 
                              self.get_readonly_url('child'))
241
 
            tree = bzrdir.BzrDir.create_standalone_workingtree('child')
242
 
            tree.bzrdir.open_repository()
243
 
        finally:
244
 
            bzrdir.BzrDirFormat.set_default_format(old_format)
 
306
        format = bzrdir.format_registry.make_bzrdir('knit')
 
307
        self.make_repository('.', shared=True, format=format)
 
308
        # note this is deliberately readonly, as this failure should 
 
309
        # occur before any writes.
 
310
        self.assertRaises(errors.NotLocalUrl,
 
311
                          bzrdir.BzrDir.create_standalone_workingtree,
 
312
                          self.get_readonly_url('child'), format=format)
 
313
        tree = bzrdir.BzrDir.create_standalone_workingtree('child', 
 
314
            format=format)
 
315
        tree.bzrdir.open_repository()
245
316
 
246
317
    def test_create_branch_convenience(self):
247
318
        # outside a repo the default convenience output is a repo+branch_tree
248
 
        old_format = bzrdir.BzrDirFormat.get_default_format()
249
 
        bzrdir.BzrDirFormat.set_default_format(bzrdir.BzrDirMetaFormat1())
250
 
        try:
251
 
            branch = bzrdir.BzrDir.create_branch_convenience('.')
252
 
            branch.bzrdir.open_workingtree()
253
 
            branch.bzrdir.open_repository()
254
 
        finally:
255
 
            bzrdir.BzrDirFormat.set_default_format(old_format)
 
319
        format = bzrdir.format_registry.make_bzrdir('knit')
 
320
        branch = bzrdir.BzrDir.create_branch_convenience('.', format=format)
 
321
        branch.bzrdir.open_workingtree()
 
322
        branch.bzrdir.open_repository()
 
323
 
 
324
    def test_create_branch_convenience_root(self):
 
325
        """Creating a branch at the root of a fs should work."""
 
326
        self.transport_server = MemoryServer
 
327
        # outside a repo the default convenience output is a repo+branch_tree
 
328
        format = bzrdir.format_registry.make_bzrdir('knit')
 
329
        branch = bzrdir.BzrDir.create_branch_convenience(self.get_url(), 
 
330
                                                         format=format)
 
331
        self.assertRaises(errors.NoWorkingTree,
 
332
                          branch.bzrdir.open_workingtree)
 
333
        branch.bzrdir.open_repository()
256
334
 
257
335
    def test_create_branch_convenience_under_shared_repo(self):
258
336
        # inside a repo the default convenience output is a branch+ follow the
259
337
        # repo tree policy
260
 
        old_format = bzrdir.BzrDirFormat.get_default_format()
261
 
        bzrdir.BzrDirFormat.set_default_format(bzrdir.BzrDirMetaFormat1())
262
 
        try:
263
 
            self.make_repository('.', shared=True)
264
 
            branch = bzrdir.BzrDir.create_branch_convenience('child')
265
 
            branch.bzrdir.open_workingtree()
266
 
            self.assertRaises(errors.NoRepositoryPresent,
267
 
                              branch.bzrdir.open_repository)
268
 
        finally:
269
 
            bzrdir.BzrDirFormat.set_default_format(old_format)
 
338
        format = bzrdir.format_registry.make_bzrdir('knit')
 
339
        self.make_repository('.', shared=True, format=format)
 
340
        branch = bzrdir.BzrDir.create_branch_convenience('child',
 
341
            format=format)
 
342
        branch.bzrdir.open_workingtree()
 
343
        self.assertRaises(errors.NoRepositoryPresent,
 
344
                          branch.bzrdir.open_repository)
270
345
            
271
346
    def test_create_branch_convenience_under_shared_repo_force_no_tree(self):
272
347
        # inside a repo the default convenience output is a branch+ follow the
273
348
        # repo tree policy but we can override that
274
 
        old_format = bzrdir.BzrDirFormat.get_default_format()
275
 
        bzrdir.BzrDirFormat.set_default_format(bzrdir.BzrDirMetaFormat1())
276
 
        try:
277
 
            self.make_repository('.', shared=True)
278
 
            branch = bzrdir.BzrDir.create_branch_convenience('child',
279
 
                force_new_tree=False)
280
 
            self.assertRaises(errors.NoWorkingTree,
281
 
                              branch.bzrdir.open_workingtree)
282
 
            self.assertRaises(errors.NoRepositoryPresent,
283
 
                              branch.bzrdir.open_repository)
284
 
        finally:
285
 
            bzrdir.BzrDirFormat.set_default_format(old_format)
 
349
        format = bzrdir.format_registry.make_bzrdir('knit')
 
350
        self.make_repository('.', shared=True, format=format)
 
351
        branch = bzrdir.BzrDir.create_branch_convenience('child',
 
352
            force_new_tree=False, format=format)
 
353
        self.assertRaises(errors.NoWorkingTree,
 
354
                          branch.bzrdir.open_workingtree)
 
355
        self.assertRaises(errors.NoRepositoryPresent,
 
356
                          branch.bzrdir.open_repository)
286
357
            
287
358
    def test_create_branch_convenience_under_shared_repo_no_tree_policy(self):
288
359
        # inside a repo the default convenience output is a branch+ follow the
289
360
        # repo tree policy
290
 
        old_format = bzrdir.BzrDirFormat.get_default_format()
291
 
        bzrdir.BzrDirFormat.set_default_format(bzrdir.BzrDirMetaFormat1())
292
 
        try:
293
 
            repo = self.make_repository('.', shared=True)
294
 
            repo.set_make_working_trees(False)
295
 
            branch = bzrdir.BzrDir.create_branch_convenience('child')
296
 
            self.assertRaises(errors.NoWorkingTree,
297
 
                              branch.bzrdir.open_workingtree)
298
 
            self.assertRaises(errors.NoRepositoryPresent,
299
 
                              branch.bzrdir.open_repository)
300
 
        finally:
301
 
            bzrdir.BzrDirFormat.set_default_format(old_format)
 
361
        format = bzrdir.format_registry.make_bzrdir('knit')
 
362
        repo = self.make_repository('.', shared=True, format=format)
 
363
        repo.set_make_working_trees(False)
 
364
        branch = bzrdir.BzrDir.create_branch_convenience('child', 
 
365
                                                         format=format)
 
366
        self.assertRaises(errors.NoWorkingTree,
 
367
                          branch.bzrdir.open_workingtree)
 
368
        self.assertRaises(errors.NoRepositoryPresent,
 
369
                          branch.bzrdir.open_repository)
302
370
 
303
371
    def test_create_branch_convenience_under_shared_repo_no_tree_policy_force_tree(self):
304
372
        # inside a repo the default convenience output is a branch+ follow the
305
373
        # repo tree policy but we can override that
306
 
        old_format = bzrdir.BzrDirFormat.get_default_format()
307
 
        bzrdir.BzrDirFormat.set_default_format(bzrdir.BzrDirMetaFormat1())
308
 
        try:
309
 
            repo = self.make_repository('.', shared=True)
310
 
            repo.set_make_working_trees(False)
311
 
            branch = bzrdir.BzrDir.create_branch_convenience('child',
312
 
                force_new_tree=True)
313
 
            branch.bzrdir.open_workingtree()
314
 
            self.assertRaises(errors.NoRepositoryPresent,
315
 
                              branch.bzrdir.open_repository)
316
 
        finally:
317
 
            bzrdir.BzrDirFormat.set_default_format(old_format)
 
374
        format = bzrdir.format_registry.make_bzrdir('knit')
 
375
        repo = self.make_repository('.', shared=True, format=format)
 
376
        repo.set_make_working_trees(False)
 
377
        branch = bzrdir.BzrDir.create_branch_convenience('child',
 
378
            force_new_tree=True, format=format)
 
379
        branch.bzrdir.open_workingtree()
 
380
        self.assertRaises(errors.NoRepositoryPresent,
 
381
                          branch.bzrdir.open_repository)
318
382
 
319
383
    def test_create_branch_convenience_under_shared_repo_force_new_repo(self):
320
384
        # inside a repo the default convenience output is overridable to give
321
385
        # repo+branch+tree
322
 
        old_format = bzrdir.BzrDirFormat.get_default_format()
323
 
        bzrdir.BzrDirFormat.set_default_format(bzrdir.BzrDirMetaFormat1())
324
 
        try:
325
 
            self.make_repository('.', shared=True)
326
 
            branch = bzrdir.BzrDir.create_branch_convenience('child',
327
 
                force_new_repo=True)
328
 
            branch.bzrdir.open_repository()
329
 
            branch.bzrdir.open_workingtree()
330
 
        finally:
331
 
            bzrdir.BzrDirFormat.set_default_format(old_format)
 
386
        format = bzrdir.format_registry.make_bzrdir('knit')
 
387
        self.make_repository('.', shared=True, format=format)
 
388
        branch = bzrdir.BzrDir.create_branch_convenience('child',
 
389
            force_new_repo=True, format=format)
 
390
        branch.bzrdir.open_repository()
 
391
        branch.bzrdir.open_workingtree()
332
392
 
333
393
 
334
394
class ChrootedTests(TestCaseWithTransport):
368
428
            get_transport(self.get_readonly_url('g/p/q')))
369
429
        self.assertEqual('g/p/q', relpath)
370
430
 
 
431
    def test_open_containing_tree_or_branch(self):
 
432
        def local_branch_path(branch):
 
433
             return os.path.realpath(
 
434
                urlutils.local_path_from_url(branch.base))
 
435
 
 
436
        self.make_branch_and_tree('topdir')
 
437
        tree, branch, relpath = bzrdir.BzrDir.open_containing_tree_or_branch(
 
438
            'topdir/foo')
 
439
        self.assertEqual(os.path.realpath('topdir'),
 
440
                         os.path.realpath(tree.basedir))
 
441
        self.assertEqual(os.path.realpath('topdir'),
 
442
                         local_branch_path(branch))
 
443
        self.assertIs(tree.bzrdir, branch.bzrdir)
 
444
        self.assertEqual('foo', relpath)
 
445
        self.make_branch('topdir/foo')
 
446
        tree, branch, relpath = bzrdir.BzrDir.open_containing_tree_or_branch(
 
447
            'topdir/foo')
 
448
        self.assertIs(tree, None)
 
449
        self.assertEqual(os.path.realpath('topdir/foo'),
 
450
                         local_branch_path(branch))
 
451
        self.assertEqual('', relpath)
 
452
 
 
453
    def test_open_from_transport(self):
 
454
        # transport pointing at bzrdir should give a bzrdir with root transport
 
455
        # set to the given transport
 
456
        control = bzrdir.BzrDir.create(self.get_url())
 
457
        transport = get_transport(self.get_url())
 
458
        opened_bzrdir = bzrdir.BzrDir.open_from_transport(transport)
 
459
        self.assertEqual(transport.base, opened_bzrdir.root_transport.base)
 
460
        self.assertIsInstance(opened_bzrdir, bzrdir.BzrDir)
 
461
        
 
462
    def test_open_from_transport_no_bzrdir(self):
 
463
        transport = get_transport(self.get_url())
 
464
        self.assertRaises(NotBranchError, bzrdir.BzrDir.open_from_transport,
 
465
                          transport)
 
466
 
 
467
    def test_open_from_transport_bzrdir_in_parent(self):
 
468
        control = bzrdir.BzrDir.create(self.get_url())
 
469
        transport = get_transport(self.get_url())
 
470
        transport.mkdir('subdir')
 
471
        transport = transport.clone('subdir')
 
472
        self.assertRaises(NotBranchError, bzrdir.BzrDir.open_from_transport,
 
473
                          transport)
 
474
 
 
475
    def test_sprout_recursive(self):
 
476
        tree = self.make_branch_and_tree('tree1', format='dirstate-with-subtree')
 
477
        sub_tree = self.make_branch_and_tree('tree1/subtree',
 
478
            format='dirstate-with-subtree')
 
479
        tree.add_reference(sub_tree)
 
480
        self.build_tree(['tree1/subtree/file'])
 
481
        sub_tree.add('file')
 
482
        tree.commit('Initial commit')
 
483
        tree.bzrdir.sprout('tree2')
 
484
        self.failUnlessExists('tree2/subtree/file')
 
485
 
 
486
    def test_cloning_metadir(self):
 
487
        """Ensure that cloning metadir is suitable"""
 
488
        bzrdir = self.make_bzrdir('bzrdir')
 
489
        bzrdir.cloning_metadir()
 
490
        branch = self.make_branch('branch', format='knit')
 
491
        format = branch.bzrdir.cloning_metadir()
 
492
        self.assertIsInstance(format.workingtree_format,
 
493
            workingtree.WorkingTreeFormat3)
 
494
 
 
495
    def test_sprout_recursive_treeless(self):
 
496
        tree = self.make_branch_and_tree('tree1',
 
497
            format='dirstate-with-subtree')
 
498
        sub_tree = self.make_branch_and_tree('tree1/subtree',
 
499
            format='dirstate-with-subtree')
 
500
        tree.add_reference(sub_tree)
 
501
        self.build_tree(['tree1/subtree/file'])
 
502
        sub_tree.add('file')
 
503
        tree.commit('Initial commit')
 
504
        tree.bzrdir.destroy_workingtree()
 
505
        repo = self.make_repository('repo', shared=True,
 
506
            format='dirstate-with-subtree')
 
507
        repo.set_make_working_trees(False)
 
508
        tree.bzrdir.sprout('repo/tree2')
 
509
        self.failUnlessExists('repo/tree2/subtree')
 
510
        self.failIfExists('repo/tree2/subtree/file')
 
511
 
371
512
 
372
513
class TestMeta1DirFormat(TestCaseWithTransport):
373
514
    """Tests specific to the meta1 dir format."""
382
523
        repository_base = t.clone('repository').base
383
524
        self.assertEqual(repository_base, dir.get_repository_transport(None).base)
384
525
        self.assertEqual(repository_base,
385
 
                         dir.get_repository_transport(repository.RepositoryFormat7()).base)
 
526
                         dir.get_repository_transport(weaverepo.RepositoryFormat7()).base)
386
527
        checkout_base = t.clone('checkout').base
387
528
        self.assertEqual(checkout_base, dir.get_workingtree_transport(None).base)
388
529
        self.assertEqual(checkout_base,
394
535
        t = dir.transport
395
536
        self.assertIsDirectory('branch-lock', t)
396
537
 
397
 
        
 
538
    def test_comparison(self):
 
539
        """Equality and inequality behave properly.
 
540
 
 
541
        Metadirs should compare equal iff they have the same repo, branch and
 
542
        tree formats.
 
543
        """
 
544
        mydir = bzrdir.format_registry.make_bzrdir('knit')
 
545
        self.assertEqual(mydir, mydir)
 
546
        self.assertFalse(mydir != mydir)
 
547
        otherdir = bzrdir.format_registry.make_bzrdir('knit')
 
548
        self.assertEqual(otherdir, mydir)
 
549
        self.assertFalse(otherdir != mydir)
 
550
        otherdir2 = bzrdir.format_registry.make_bzrdir('dirstate-with-subtree')
 
551
        self.assertNotEqual(otherdir2, mydir)
 
552
        self.assertFalse(otherdir2 == mydir)
 
553
 
 
554
    def test_needs_conversion_different_working_tree(self):
 
555
        # meta1dirs need an conversion if any element is not the default.
 
556
        old_format = bzrdir.BzrDirFormat.get_default_format()
 
557
        # test with 
 
558
        new_default = bzrdir.format_registry.make_bzrdir('dirstate')
 
559
        bzrdir.BzrDirFormat._set_default_format(new_default)
 
560
        try:
 
561
            tree = self.make_branch_and_tree('tree', format='knit')
 
562
            self.assertTrue(tree.bzrdir.needs_format_conversion())
 
563
        finally:
 
564
            bzrdir.BzrDirFormat._set_default_format(old_format)
 
565
 
 
566
 
398
567
class TestFormat5(TestCaseWithTransport):
399
568
    """Tests specific to the version 5 bzrdir format."""
400
569
 
422
591
        # format 5 dirs need a conversion if they are not the default.
423
592
        # and they start of not the default.
424
593
        old_format = bzrdir.BzrDirFormat.get_default_format()
425
 
        bzrdir.BzrDirFormat.set_default_format(bzrdir.BzrDirFormat5())
 
594
        bzrdir.BzrDirFormat._set_default_format(bzrdir.BzrDirFormat5())
426
595
        try:
427
596
            dir = bzrdir.BzrDirFormat5().initialize(self.get_url())
428
597
            self.assertFalse(dir.needs_format_conversion())
429
598
        finally:
430
 
            bzrdir.BzrDirFormat.set_default_format(old_format)
 
599
            bzrdir.BzrDirFormat._set_default_format(old_format)
431
600
        self.assertTrue(dir.needs_format_conversion())
432
601
 
433
602
 
457
626
    def test_needs_conversion(self):
458
627
        # format 6 dirs need an conversion if they are not the default.
459
628
        old_format = bzrdir.BzrDirFormat.get_default_format()
460
 
        bzrdir.BzrDirFormat.set_default_format(bzrdir.BzrDirMetaFormat1())
 
629
        bzrdir.BzrDirFormat._set_default_format(bzrdir.BzrDirMetaFormat1())
461
630
        try:
462
631
            dir = bzrdir.BzrDirFormat6().initialize(self.get_url())
463
632
            self.assertTrue(dir.needs_format_conversion())
464
633
        finally:
465
 
            bzrdir.BzrDirFormat.set_default_format(old_format)
 
634
            bzrdir.BzrDirFormat._set_default_format(old_format)
 
635
 
 
636
 
 
637
class NotBzrDir(bzrlib.bzrdir.BzrDir):
 
638
    """A non .bzr based control directory."""
 
639
 
 
640
    def __init__(self, transport, format):
 
641
        self._format = format
 
642
        self.root_transport = transport
 
643
        self.transport = transport.clone('.not')
 
644
 
 
645
 
 
646
class NotBzrDirFormat(bzrlib.bzrdir.BzrDirFormat):
 
647
    """A test class representing any non-.bzr based disk format."""
 
648
 
 
649
    def initialize_on_transport(self, transport):
 
650
        """Initialize a new .not dir in the base directory of a Transport."""
 
651
        transport.mkdir('.not')
 
652
        return self.open(transport)
 
653
 
 
654
    def open(self, transport):
 
655
        """Open this directory."""
 
656
        return NotBzrDir(transport, self)
 
657
 
 
658
    @classmethod
 
659
    def _known_formats(self):
 
660
        return set([NotBzrDirFormat()])
 
661
 
 
662
    @classmethod
 
663
    def probe_transport(self, transport):
 
664
        """Our format is present if the transport ends in '.not/'."""
 
665
        if transport.has('.not'):
 
666
            return NotBzrDirFormat()
 
667
 
 
668
 
 
669
class TestNotBzrDir(TestCaseWithTransport):
 
670
    """Tests for using the bzrdir api with a non .bzr based disk format.
 
671
    
 
672
    If/when one of these is in the core, we can let the implementation tests
 
673
    verify this works.
 
674
    """
 
675
 
 
676
    def test_create_and_find_format(self):
 
677
        # create a .notbzr dir 
 
678
        format = NotBzrDirFormat()
 
679
        dir = format.initialize(self.get_url())
 
680
        self.assertIsInstance(dir, NotBzrDir)
 
681
        # now probe for it.
 
682
        bzrlib.bzrdir.BzrDirFormat.register_control_format(format)
 
683
        try:
 
684
            found = bzrlib.bzrdir.BzrDirFormat.find_format(
 
685
                get_transport(self.get_url()))
 
686
            self.assertIsInstance(found, NotBzrDirFormat)
 
687
        finally:
 
688
            bzrlib.bzrdir.BzrDirFormat.unregister_control_format(format)
 
689
 
 
690
    def test_included_in_known_formats(self):
 
691
        bzrlib.bzrdir.BzrDirFormat.register_control_format(NotBzrDirFormat)
 
692
        try:
 
693
            formats = bzrlib.bzrdir.BzrDirFormat.known_formats()
 
694
            for format in formats:
 
695
                if isinstance(format, NotBzrDirFormat):
 
696
                    return
 
697
            self.fail("No NotBzrDirFormat in %s" % formats)
 
698
        finally:
 
699
            bzrlib.bzrdir.BzrDirFormat.unregister_control_format(NotBzrDirFormat)
466
700
 
467
701
 
468
702
class NonLocalTests(TestCaseWithTransport):
474
708
    
475
709
    def test_create_branch_convenience(self):
476
710
        # outside a repo the default convenience output is a repo+branch_tree
477
 
        old_format = bzrdir.BzrDirFormat.get_default_format()
478
 
        bzrdir.BzrDirFormat.set_default_format(bzrdir.BzrDirMetaFormat1())
479
 
        try:
480
 
            branch = bzrdir.BzrDir.create_branch_convenience(self.get_url('foo'))
481
 
            self.assertRaises(errors.NoWorkingTree,
482
 
                              branch.bzrdir.open_workingtree)
483
 
            branch.bzrdir.open_repository()
484
 
        finally:
485
 
            bzrdir.BzrDirFormat.set_default_format(old_format)
 
711
        format = bzrdir.format_registry.make_bzrdir('knit')
 
712
        branch = bzrdir.BzrDir.create_branch_convenience(
 
713
            self.get_url('foo'), format=format)
 
714
        self.assertRaises(errors.NoWorkingTree,
 
715
                          branch.bzrdir.open_workingtree)
 
716
        branch.bzrdir.open_repository()
486
717
 
487
718
    def test_create_branch_convenience_force_tree_not_local_fails(self):
488
719
        # outside a repo the default convenience output is a repo+branch_tree
489
 
        old_format = bzrdir.BzrDirFormat.get_default_format()
490
 
        bzrdir.BzrDirFormat.set_default_format(bzrdir.BzrDirMetaFormat1())
491
 
        try:
492
 
            self.assertRaises(errors.NotLocalUrl,
493
 
                bzrdir.BzrDir.create_branch_convenience,
494
 
                self.get_url('foo'),
495
 
                force_new_tree=True)
496
 
            t = get_transport(self.get_url('.'))
497
 
            self.assertFalse(t.has('foo'))
498
 
        finally:
499
 
            bzrdir.BzrDirFormat.set_default_format(old_format)
 
720
        format = bzrdir.format_registry.make_bzrdir('knit')
 
721
        self.assertRaises(errors.NotLocalUrl,
 
722
            bzrdir.BzrDir.create_branch_convenience,
 
723
            self.get_url('foo'),
 
724
            force_new_tree=True,
 
725
            format=format)
 
726
        t = get_transport(self.get_url('.'))
 
727
        self.assertFalse(t.has('foo'))
500
728
 
501
729
    def test_clone(self):
502
730
        # clone into a nonlocal path works
503
 
        old_format = bzrdir.BzrDirFormat.get_default_format()
504
 
        bzrdir.BzrDirFormat.set_default_format(bzrdir.BzrDirMetaFormat1())
505
 
        try:
506
 
            branch = bzrdir.BzrDir.create_branch_convenience('local')
507
 
        finally:
508
 
            bzrdir.BzrDirFormat.set_default_format(old_format)
 
731
        format = bzrdir.format_registry.make_bzrdir('knit')
 
732
        branch = bzrdir.BzrDir.create_branch_convenience('local',
 
733
                                                         format=format)
509
734
        branch.bzrdir.open_workingtree()
510
735
        result = branch.bzrdir.clone(self.get_url('remote'))
511
736
        self.assertRaises(errors.NoWorkingTree,
513
738
        result.open_branch()
514
739
        result.open_repository()
515
740
 
 
741
    def test_checkout_metadir(self):
 
742
        # checkout_metadir has reasonable working tree format even when no
 
743
        # working tree is present
 
744
        self.make_branch('branch-knit2', format='dirstate-with-subtree')
 
745
        my_bzrdir = bzrdir.BzrDir.open(self.get_url('branch-knit2'))
 
746
        checkout_format = my_bzrdir.checkout_metadir()
 
747
        self.assertIsInstance(checkout_format.workingtree_format,
 
748
                              workingtree.WorkingTreeFormat3)
 
749
 
 
750
 
 
751
class TestRemoteSFTP(test_sftp_transport.TestCaseWithSFTPServer):
 
752
 
 
753
    def test_open_containing_tree_or_branch(self):
 
754
        tree = self.make_branch_and_tree('tree')
 
755
        bzrdir.BzrDir.open_containing_tree_or_branch(self.get_url('tree'))