/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: John Arbash Meinel
  • Date: 2006-04-25 15:05:42 UTC
  • mfrom: (1185.85.85 bzr-encoding)
  • mto: This revision was merged to the branch mainline in revision 1752.
  • Revision ID: john@arbash-meinel.com-20060425150542-c7b518dca9928691
[merge] the old bzr-encoding changes, reparenting them on bzr.dev

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2006-2013, 2016 Canonical Ltd
2
 
#
 
1
# Copyright (C) 2005, 2006 Canonical Ltd
 
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
 
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
16
 
17
17
"""Tests for the BzrDir facility and any format specific tests.
18
18
 
19
 
For interface contract tests, see tests/per_bzr_dir.
 
19
For interface contract tests, see tests/bzr_dir_implementations.
20
20
"""
21
21
 
22
 
import os
23
 
import subprocess
24
 
import sys
 
22
from StringIO import StringIO
25
23
 
26
 
from .. import (
27
 
    branch,
28
 
    bzr,
29
 
    config,
30
 
    controldir,
31
 
    errors,
32
 
    help_topics,
33
 
    lock,
34
 
    repository,
35
 
    revision as _mod_revision,
36
 
    osutils,
37
 
    transport as _mod_transport,
38
 
    urlutils,
39
 
    win32utils,
40
 
    )
41
 
from ..bzr import (
42
 
    branch as bzrbranch,
43
 
    bzrdir,
44
 
    remote,
45
 
    workingtree_3,
46
 
    workingtree_4,
47
 
    )
48
 
import breezy.branch
49
 
import breezy.bzr.branch
50
 
from ..bzr.fullhistory import BzrBranchFormat5
51
 
from ..errors import (
52
 
    NotBranchError,
53
 
    NoColocatedBranchSupport,
54
 
    UnknownFormatError,
55
 
    UnsupportedFormatError,
56
 
    )
57
 
from . import (
58
 
    TestCase,
59
 
    TestCaseWithMemoryTransport,
60
 
    TestCaseWithTransport,
61
 
    TestSkipped,
62
 
    )
63
 
from . import (
64
 
    http_server,
65
 
    http_utils,
66
 
    )
67
 
from ..transport import (
68
 
    memory,
69
 
    pathfilter,
70
 
    )
71
 
from ..transport.http import HttpTransport
72
 
from ..transport.nosmart import NoSmartTransportDecorator
73
 
from ..transport.readonly import ReadonlyTransportDecorator
74
 
from ..bzr import knitrepo, knitpack_repo
 
24
import bzrlib.branch
 
25
import bzrlib.bzrdir as bzrdir
 
26
import bzrlib.errors as errors
 
27
from bzrlib.errors import (NotBranchError,
 
28
                           UnknownFormatError,
 
29
                           UnsupportedFormatError,
 
30
                           )
 
31
import bzrlib.repository as repository
 
32
from bzrlib.tests import TestCase, TestCaseWithTransport
 
33
from bzrlib.transport import get_transport
 
34
from bzrlib.transport.http import HttpServer
 
35
from bzrlib.transport.memory import MemoryServer
 
36
import bzrlib.workingtree as workingtree
75
37
 
76
38
 
77
39
class TestDefaultFormat(TestCase):
78
40
 
79
41
    def test_get_set_default_format(self):
80
42
        old_format = bzrdir.BzrDirFormat.get_default_format()
81
 
        # default is BzrDirMetaFormat1
82
 
        self.assertIsInstance(old_format, bzrdir.BzrDirMetaFormat1)
83
 
        controldir.ControlDirFormat._set_default_format(SampleBzrDirFormat())
 
43
        # default is BzrDirFormat6
 
44
        self.failUnless(isinstance(old_format, bzrdir.BzrDirMetaFormat1))
 
45
        bzrdir.BzrDirFormat.set_default_format(SampleBzrDirFormat())
84
46
        # creating a bzr dir should now create an instrumented dir.
85
47
        try:
86
 
            result = bzrdir.BzrDir.create('memory:///')
87
 
            self.assertIsInstance(result, SampleBzrDir)
 
48
            result = bzrdir.BzrDir.create('memory:/')
 
49
            self.failUnless(isinstance(result, SampleBzrDir))
88
50
        finally:
89
 
            controldir.ControlDirFormat._set_default_format(old_format)
 
51
            bzrdir.BzrDirFormat.set_default_format(old_format)
90
52
        self.assertEqual(old_format, bzrdir.BzrDirFormat.get_default_format())
91
53
 
92
54
 
93
 
class DeprecatedBzrDirFormat(bzrdir.BzrDirFormat):
94
 
    """A deprecated bzr dir format."""
95
 
 
96
 
 
97
 
class TestFormatRegistry(TestCase):
98
 
 
99
 
    def make_format_registry(self):
100
 
        my_format_registry = controldir.ControlDirFormatRegistry()
101
 
        my_format_registry.register('deprecated', DeprecatedBzrDirFormat,
102
 
                                    'Some format.  Slower and unawesome and deprecated.',
103
 
                                    deprecated=True)
104
 
        my_format_registry.register_lazy('lazy', 'breezy.tests.test_bzrdir',
105
 
                                         'DeprecatedBzrDirFormat', 'Format registered lazily',
106
 
                                         deprecated=True)
107
 
        bzr.register_metadir(my_format_registry, 'knit',
108
 
                             'breezy.bzr.knitrepo.RepositoryFormatKnit1',
109
 
                             'Format using knits',
110
 
                             )
111
 
        my_format_registry.set_default('knit')
112
 
        bzr.register_metadir(my_format_registry,
113
 
                             'branch6',
114
 
                             'breezy.bzr.knitrepo.RepositoryFormatKnit3',
115
 
                             'Experimental successor to knit.  Use at your own risk.',
116
 
                             branch_format='breezy.bzr.branch.BzrBranchFormat6',
117
 
                             experimental=True)
118
 
        bzr.register_metadir(my_format_registry,
119
 
                             'hidden format',
120
 
                             'breezy.bzr.knitrepo.RepositoryFormatKnit3',
121
 
                             'Experimental successor to knit.  Use at your own risk.',
122
 
                             branch_format='breezy.bzr.branch.BzrBranchFormat6', hidden=True)
123
 
        my_format_registry.register('hiddendeprecated', DeprecatedBzrDirFormat,
124
 
                                    'Old format.  Slower and does not support things. ', hidden=True)
125
 
        my_format_registry.register_lazy('hiddenlazy', 'breezy.tests.test_bzrdir',
126
 
                                         'DeprecatedBzrDirFormat', 'Format registered lazily',
127
 
                                         deprecated=True, hidden=True)
128
 
        return my_format_registry
129
 
 
130
 
    def test_format_registry(self):
131
 
        my_format_registry = self.make_format_registry()
132
 
        my_bzrdir = my_format_registry.make_controldir('lazy')
133
 
        self.assertIsInstance(my_bzrdir, DeprecatedBzrDirFormat)
134
 
        my_bzrdir = my_format_registry.make_controldir('deprecated')
135
 
        self.assertIsInstance(my_bzrdir, DeprecatedBzrDirFormat)
136
 
        my_bzrdir = my_format_registry.make_controldir('default')
137
 
        self.assertIsInstance(my_bzrdir.repository_format,
138
 
                              knitrepo.RepositoryFormatKnit1)
139
 
        my_bzrdir = my_format_registry.make_controldir('knit')
140
 
        self.assertIsInstance(my_bzrdir.repository_format,
141
 
                              knitrepo.RepositoryFormatKnit1)
142
 
        my_bzrdir = my_format_registry.make_controldir('branch6')
143
 
        self.assertIsInstance(my_bzrdir.get_branch_format(),
144
 
                              breezy.bzr.branch.BzrBranchFormat6)
145
 
 
146
 
    def test_get_help(self):
147
 
        my_format_registry = self.make_format_registry()
148
 
        self.assertEqual('Format registered lazily',
149
 
                         my_format_registry.get_help('lazy'))
150
 
        self.assertEqual('Format using knits',
151
 
                         my_format_registry.get_help('knit'))
152
 
        self.assertEqual('Format using knits',
153
 
                         my_format_registry.get_help('default'))
154
 
        self.assertEqual('Some format.  Slower and unawesome and deprecated.',
155
 
                         my_format_registry.get_help('deprecated'))
156
 
 
157
 
    def test_help_topic(self):
158
 
        topics = help_topics.HelpTopicRegistry()
159
 
        registry = self.make_format_registry()
160
 
        topics.register('current-formats', registry.help_topic,
161
 
                        'Current formats')
162
 
        topics.register('other-formats', registry.help_topic,
163
 
                        'Other formats')
164
 
        new = topics.get_detail('current-formats')
165
 
        rest = topics.get_detail('other-formats')
166
 
        experimental, deprecated = rest.split('Deprecated formats')
167
 
        self.assertContainsRe(new, 'formats-help')
168
 
        self.assertContainsRe(new,
169
 
                              ':knit:\n    \\(native\\) \\(default\\) Format using knits\n')
170
 
        self.assertContainsRe(experimental,
171
 
                              ':branch6:\n    \\(native\\) Experimental successor to knit')
172
 
        self.assertContainsRe(deprecated,
173
 
                              ':lazy:\n    \\(native\\) Format registered lazily\n')
174
 
        self.assertNotContainsRe(new, 'hidden')
175
 
 
176
 
    def test_set_default_repository(self):
177
 
        default_factory = controldir.format_registry.get('default')
178
 
        old_default = [k for k, v in controldir.format_registry.iteritems()
179
 
                       if v == default_factory and k != 'default'][0]
180
 
        controldir.format_registry.set_default_repository(
181
 
            'dirstate-with-subtree')
182
 
        try:
183
 
            self.assertIs(controldir.format_registry.get('dirstate-with-subtree'),
184
 
                          controldir.format_registry.get('default'))
185
 
            self.assertIs(
186
 
                repository.format_registry.get_default().__class__,
187
 
                knitrepo.RepositoryFormatKnit3)
188
 
        finally:
189
 
            controldir.format_registry.set_default_repository(old_default)
190
 
 
191
 
    def test_aliases(self):
192
 
        a_registry = controldir.ControlDirFormatRegistry()
193
 
        a_registry.register('deprecated', DeprecatedBzrDirFormat,
194
 
                            'Old format.  Slower and does not support stuff',
195
 
                            deprecated=True)
196
 
        a_registry.register_alias('deprecatedalias', 'deprecated')
197
 
        self.assertEqual({'deprecatedalias': 'deprecated'},
198
 
                         a_registry.aliases())
199
 
 
200
 
 
201
 
class SampleBranch(breezy.branch.Branch):
 
55
class SampleBranch(bzrlib.branch.Branch):
202
56
    """A dummy branch for guess what, dummy use."""
203
57
 
204
58
    def __init__(self, dir):
205
 
        self.controldir = dir
206
 
 
207
 
 
208
 
class SampleRepository(breezy.repository.Repository):
209
 
    """A dummy repo."""
210
 
 
211
 
    def __init__(self, dir):
212
 
        self.controldir = dir
 
59
        self.bzrdir = dir
213
60
 
214
61
 
215
62
class SampleBzrDir(bzrdir.BzrDir):
216
63
    """A sample BzrDir implementation to allow testing static methods."""
217
64
 
218
 
    def create_repository(self, shared=False):
219
 
        """See ControlDir.create_repository."""
 
65
    def create_repository(self):
 
66
        """See BzrDir.create_repository."""
220
67
        return "A repository"
221
68
 
222
69
    def open_repository(self):
223
 
        """See ControlDir.open_repository."""
224
 
        return SampleRepository(self)
 
70
        """See BzrDir.open_repository."""
 
71
        return "A repository"
225
72
 
226
 
    def create_branch(self, name=None):
227
 
        """See ControlDir.create_branch."""
228
 
        if name is not None:
229
 
            raise NoColocatedBranchSupport(self)
 
73
    def create_branch(self):
 
74
        """See BzrDir.create_branch."""
230
75
        return SampleBranch(self)
231
76
 
232
77
    def create_workingtree(self):
233
 
        """See ControlDir.create_workingtree."""
 
78
        """See BzrDir.create_workingtree."""
234
79
        return "A tree"
235
80
 
236
81
 
237
82
class SampleBzrDirFormat(bzrdir.BzrDirFormat):
238
83
    """A sample format
239
84
 
240
 
    this format is initializable, unsupported to aid in testing the
 
85
    this format is initializable, unsupported to aid in testing the 
241
86
    open and open_downlevel routines.
242
87
    """
243
88
 
244
89
    def get_format_string(self):
245
90
        """See BzrDirFormat.get_format_string()."""
246
 
        return b"Sample .bzr dir format."
 
91
        return "Sample .bzr dir format."
247
92
 
248
 
    def initialize_on_transport(self, t):
 
93
    def initialize(self, url):
249
94
        """Create a bzr dir."""
 
95
        t = get_transport(url)
250
96
        t.mkdir('.bzr')
251
 
        t.put_bytes('.bzr/branch-format', self.get_format_string())
 
97
        t.put('.bzr/branch-format', StringIO(self.get_format_string()))
252
98
        return SampleBzrDir(t, self)
253
99
 
254
100
    def is_supported(self):
257
103
    def open(self, transport, _found=None):
258
104
        return "opened branch."
259
105
 
260
 
    @classmethod
261
 
    def from_string(cls, format_string):
262
 
        return cls()
263
 
 
264
 
 
265
 
class BzrDirFormatTest1(bzrdir.BzrDirMetaFormat1):
266
 
 
267
 
    @staticmethod
268
 
    def get_format_string():
269
 
        return b"Test format 1"
270
 
 
271
 
 
272
 
class BzrDirFormatTest2(bzrdir.BzrDirMetaFormat1):
273
 
 
274
 
    @staticmethod
275
 
    def get_format_string():
276
 
        return b"Test format 2"
277
 
 
278
106
 
279
107
class TestBzrDirFormat(TestCaseWithTransport):
280
108
    """Tests for the BzrDirFormat facility."""
282
110
    def test_find_format(self):
283
111
        # is the right format object found for a branch?
284
112
        # create a branch with a few known format objects.
285
 
        bzr.BzrProber.formats.register(BzrDirFormatTest1.get_format_string(),
286
 
                                       BzrDirFormatTest1())
287
 
        self.addCleanup(bzr.BzrProber.formats.remove,
288
 
                        BzrDirFormatTest1.get_format_string())
289
 
        bzr.BzrProber.formats.register(BzrDirFormatTest2.get_format_string(),
290
 
                                       BzrDirFormatTest2())
291
 
        self.addCleanup(bzr.BzrProber.formats.remove,
292
 
                        BzrDirFormatTest2.get_format_string())
293
 
        t = self.get_transport()
 
113
        # this is not quite the same as 
 
114
        t = get_transport(self.get_url())
294
115
        self.build_tree(["foo/", "bar/"], transport=t)
295
 
 
296
116
        def check_format(format, url):
297
117
            format.initialize(url)
298
 
            t = _mod_transport.get_transport_from_path(url)
 
118
            t = get_transport(url)
299
119
            found_format = bzrdir.BzrDirFormat.find_format(t)
300
 
            self.assertIsInstance(found_format, format.__class__)
301
 
        check_format(BzrDirFormatTest1(), "foo")
302
 
        check_format(BzrDirFormatTest2(), "bar")
303
 
 
 
120
            self.failUnless(isinstance(found_format, format.__class__))
 
121
        check_format(bzrdir.BzrDirFormat5(), "foo")
 
122
        check_format(bzrdir.BzrDirFormat6(), "bar")
 
123
        
304
124
    def test_find_format_nothing_there(self):
305
125
        self.assertRaises(NotBranchError,
306
126
                          bzrdir.BzrDirFormat.find_format,
307
 
                          _mod_transport.get_transport_from_path('.'))
 
127
                          get_transport('.'))
308
128
 
309
129
    def test_find_format_unknown_format(self):
310
 
        t = self.get_transport()
 
130
        t = get_transport(self.get_url())
311
131
        t.mkdir('.bzr')
312
 
        t.put_bytes('.bzr/branch-format', b'')
 
132
        t.put('.bzr/branch-format', StringIO())
313
133
        self.assertRaises(UnknownFormatError,
314
134
                          bzrdir.BzrDirFormat.find_format,
315
 
                          _mod_transport.get_transport_from_path('.'))
316
 
 
317
 
    def test_find_format_line_endings(self):
318
 
        t = self.get_transport()
319
 
        t.mkdir('.bzr')
320
 
        t.put_bytes('.bzr/branch-format', b'Corrupt line endings\r\n')
321
 
        self.assertRaises(errors.LineEndingError,
322
 
                          bzrdir.BzrDirFormat.find_format,
323
 
                          _mod_transport.get_transport_from_path('.'))
 
135
                          get_transport('.'))
324
136
 
325
137
    def test_register_unregister_format(self):
326
138
        format = SampleBzrDirFormat()
328
140
        # make a bzrdir
329
141
        format.initialize(url)
330
142
        # register a format for it.
331
 
        bzr.BzrProber.formats.register(format.get_format_string(), format)
 
143
        bzrdir.BzrDirFormat.register_format(format)
332
144
        # which bzrdir.Open will refuse (not supported)
333
145
        self.assertRaises(UnsupportedFormatError, bzrdir.BzrDir.open, url)
334
146
        # which bzrdir.open_containing will refuse (not supported)
335
 
        self.assertRaises(UnsupportedFormatError,
336
 
                          bzrdir.BzrDir.open_containing, url)
 
147
        self.assertRaises(UnsupportedFormatError, bzrdir.BzrDir.open_containing, url)
337
148
        # but open_downlevel will work
338
 
        t = _mod_transport.get_transport_from_url(url)
 
149
        t = get_transport(url)
339
150
        self.assertEqual(format.open(t), bzrdir.BzrDir.open_unsupported(url))
340
151
        # unregister the format
341
 
        bzr.BzrProber.formats.remove(format.get_format_string())
 
152
        bzrdir.BzrDirFormat.unregister_format(format)
342
153
        # now open_downlevel should fail too.
343
 
        self.assertRaises(UnknownFormatError,
344
 
                          bzrdir.BzrDir.open_unsupported, url)
 
154
        self.assertRaises(UnknownFormatError, bzrdir.BzrDir.open_unsupported, url)
 
155
 
 
156
    def test_create_repository(self):
 
157
        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)
 
165
 
 
166
    def test_create_repository_under_shared(self):
 
167
        # an explicit create_repository always does so.
 
168
        # 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)
345
178
 
346
179
    def test_create_branch_and_repo_uses_default(self):
347
180
        format = SampleBzrDirFormat()
348
 
        branch = bzrdir.BzrDir.create_branch_and_repo(self.get_url(),
349
 
                                                      format=format)
350
 
        self.assertTrue(isinstance(branch, SampleBranch))
 
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)
351
188
 
352
189
    def test_create_branch_and_repo_under_shared(self):
353
190
        # creating a branch and repo in a shared repo uses the
354
191
        # shared repository
355
 
        format = controldir.format_registry.make_controldir('knit')
356
 
        self.make_repository('.', shared=True, format=format)
357
 
        branch = bzrdir.BzrDir.create_branch_and_repo(
358
 
            self.get_url('child'), format=format)
359
 
        self.assertRaises(errors.NoRepositoryPresent,
360
 
                          branch.controldir.open_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)
361
201
 
362
202
    def test_create_branch_and_repo_under_shared_force_new(self):
363
 
        # creating a branch and repo in a shared repo can be forced to
 
203
        # creating a branch and repo in a shared repo can be forced to 
364
204
        # make a new repo
365
 
        format = controldir.format_registry.make_controldir('knit')
366
 
        self.make_repository('.', shared=True, format=format)
367
 
        branch = bzrdir.BzrDir.create_branch_and_repo(self.get_url('child'),
368
 
                                                      force_new_repo=True,
369
 
                                                      format=format)
370
 
        branch.controldir.open_repository()
 
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)
371
214
 
372
215
    def test_create_standalone_working_tree(self):
373
216
        format = SampleBzrDirFormat()
374
 
        # note this is deliberately readonly, as this failure should
375
 
        # occur before any writes.
376
 
        self.assertRaises(errors.NotLocalUrl,
377
 
                          bzrdir.BzrDir.create_standalone_workingtree,
378
 
                          self.get_readonly_url(), format=format)
379
 
        tree = bzrdir.BzrDir.create_standalone_workingtree('.',
380
 
                                                           format=format)
381
 
        self.assertEqual('A tree', tree)
 
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)
382
229
 
383
230
    def test_create_standalone_working_tree_under_shared_repo(self):
384
231
        # create standalone working tree always makes a repo.
385
 
        format = controldir.format_registry.make_controldir('knit')
386
 
        self.make_repository('.', shared=True, format=format)
387
 
        # note this is deliberately readonly, as this failure should
388
 
        # occur before any writes.
389
 
        self.assertRaises(errors.NotLocalUrl,
390
 
                          bzrdir.BzrDir.create_standalone_workingtree,
391
 
                          self.get_readonly_url('child'), format=format)
392
 
        tree = bzrdir.BzrDir.create_standalone_workingtree('child',
393
 
                                                           format=format)
394
 
        tree.controldir.open_repository()
 
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)
395
245
 
396
246
    def test_create_branch_convenience(self):
397
247
        # outside a repo the default convenience output is a repo+branch_tree
398
 
        format = controldir.format_registry.make_controldir('knit')
399
 
        branch = bzrdir.BzrDir.create_branch_convenience('.', format=format)
400
 
        branch.controldir.open_workingtree()
401
 
        branch.controldir.open_repository()
402
 
 
403
 
    def test_create_branch_convenience_possible_transports(self):
404
 
        """Check that the optional 'possible_transports' is recognized"""
405
 
        format = controldir.format_registry.make_controldir('knit')
406
 
        t = self.get_transport()
407
 
        branch = bzrdir.BzrDir.create_branch_convenience(
408
 
            '.', format=format, possible_transports=[t])
409
 
        branch.controldir.open_workingtree()
410
 
        branch.controldir.open_repository()
411
 
 
412
 
    def test_create_branch_convenience_root(self):
413
 
        """Creating a branch at the root of a fs should work."""
414
 
        self.vfs_transport_factory = memory.MemoryServer
415
 
        # outside a repo the default convenience output is a repo+branch_tree
416
 
        format = controldir.format_registry.make_controldir('knit')
417
 
        branch = bzrdir.BzrDir.create_branch_convenience(self.get_url(),
418
 
                                                         format=format)
419
 
        self.assertRaises(errors.NoWorkingTree,
420
 
                          branch.controldir.open_workingtree)
421
 
        branch.controldir.open_repository()
 
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)
422
256
 
423
257
    def test_create_branch_convenience_under_shared_repo(self):
424
258
        # inside a repo the default convenience output is a branch+ follow the
425
259
        # repo tree policy
426
 
        format = controldir.format_registry.make_controldir('knit')
427
 
        self.make_repository('.', shared=True, format=format)
428
 
        branch = bzrdir.BzrDir.create_branch_convenience('child',
429
 
                                                         format=format)
430
 
        branch.controldir.open_workingtree()
431
 
        self.assertRaises(errors.NoRepositoryPresent,
432
 
                          branch.controldir.open_repository)
433
 
 
 
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)
 
270
            
434
271
    def test_create_branch_convenience_under_shared_repo_force_no_tree(self):
435
272
        # inside a repo the default convenience output is a branch+ follow the
436
273
        # repo tree policy but we can override that
437
 
        format = controldir.format_registry.make_controldir('knit')
438
 
        self.make_repository('.', shared=True, format=format)
439
 
        branch = bzrdir.BzrDir.create_branch_convenience('child',
440
 
                                                         force_new_tree=False, format=format)
441
 
        self.assertRaises(errors.NoWorkingTree,
442
 
                          branch.controldir.open_workingtree)
443
 
        self.assertRaises(errors.NoRepositoryPresent,
444
 
                          branch.controldir.open_repository)
445
 
 
 
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)
 
286
            
446
287
    def test_create_branch_convenience_under_shared_repo_no_tree_policy(self):
447
288
        # inside a repo the default convenience output is a branch+ follow the
448
289
        # repo tree policy
449
 
        format = controldir.format_registry.make_controldir('knit')
450
 
        repo = self.make_repository('.', shared=True, format=format)
451
 
        repo.set_make_working_trees(False)
452
 
        branch = bzrdir.BzrDir.create_branch_convenience('child',
453
 
                                                         format=format)
454
 
        self.assertRaises(errors.NoWorkingTree,
455
 
                          branch.controldir.open_workingtree)
456
 
        self.assertRaises(errors.NoRepositoryPresent,
457
 
                          branch.controldir.open_repository)
 
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)
458
302
 
459
303
    def test_create_branch_convenience_under_shared_repo_no_tree_policy_force_tree(self):
460
304
        # inside a repo the default convenience output is a branch+ follow the
461
305
        # repo tree policy but we can override that
462
 
        format = controldir.format_registry.make_controldir('knit')
463
 
        repo = self.make_repository('.', shared=True, format=format)
464
 
        repo.set_make_working_trees(False)
465
 
        branch = bzrdir.BzrDir.create_branch_convenience('child',
466
 
                                                         force_new_tree=True, format=format)
467
 
        branch.controldir.open_workingtree()
468
 
        self.assertRaises(errors.NoRepositoryPresent,
469
 
                          branch.controldir.open_repository)
 
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)
470
318
 
471
319
    def test_create_branch_convenience_under_shared_repo_force_new_repo(self):
472
320
        # inside a repo the default convenience output is overridable to give
473
321
        # repo+branch+tree
474
 
        format = controldir.format_registry.make_controldir('knit')
475
 
        self.make_repository('.', shared=True, format=format)
476
 
        branch = bzrdir.BzrDir.create_branch_convenience('child',
477
 
                                                         force_new_repo=True, format=format)
478
 
        branch.controldir.open_repository()
479
 
        branch.controldir.open_workingtree()
480
 
 
481
 
 
482
 
class TestRepositoryAcquisitionPolicy(TestCaseWithTransport):
483
 
 
484
 
    def test_acquire_repository_standalone(self):
485
 
        """The default acquisition policy should create a standalone branch."""
486
 
        my_bzrdir = self.make_controldir('.')
487
 
        repo_policy = my_bzrdir.determine_repository_policy()
488
 
        repo, is_new = repo_policy.acquire_repository()
489
 
        self.assertEqual(repo.controldir.root_transport.base,
490
 
                         my_bzrdir.root_transport.base)
491
 
        self.assertFalse(repo.is_shared())
492
 
 
493
 
    def test_determine_stacking_policy(self):
494
 
        parent_bzrdir = self.make_controldir('.')
495
 
        child_bzrdir = self.make_controldir('child')
496
 
        parent_bzrdir.get_config().set_default_stack_on('http://example.org')
497
 
        repo_policy = child_bzrdir.determine_repository_policy()
498
 
        self.assertEqual('http://example.org', repo_policy._stack_on)
499
 
 
500
 
    def test_determine_stacking_policy_relative(self):
501
 
        parent_bzrdir = self.make_controldir('.')
502
 
        child_bzrdir = self.make_controldir('child')
503
 
        parent_bzrdir.get_config().set_default_stack_on('child2')
504
 
        repo_policy = child_bzrdir.determine_repository_policy()
505
 
        self.assertEqual('child2', repo_policy._stack_on)
506
 
        self.assertEqual(parent_bzrdir.root_transport.base,
507
 
                         repo_policy._stack_on_pwd)
508
 
 
509
 
    def prepare_default_stacking(self, child_format='1.6'):
510
 
        parent_bzrdir = self.make_controldir('.')
511
 
        child_branch = self.make_branch('child', format=child_format)
512
 
        parent_bzrdir.get_config().set_default_stack_on(child_branch.base)
513
 
        new_child_transport = parent_bzrdir.transport.clone('child2')
514
 
        return child_branch, new_child_transport
515
 
 
516
 
    def test_clone_on_transport_obeys_stacking_policy(self):
517
 
        child_branch, new_child_transport = self.prepare_default_stacking()
518
 
        new_child = child_branch.controldir.clone_on_transport(
519
 
            new_child_transport)
520
 
        self.assertEqual(child_branch.base,
521
 
                         new_child.open_branch().get_stacked_on_url())
522
 
 
523
 
    def test_default_stacking_with_stackable_branch_unstackable_repo(self):
524
 
        # Make stackable source branch with an unstackable repo format.
525
 
        source_bzrdir = self.make_controldir('source')
526
 
        knitpack_repo.RepositoryFormatKnitPack1().initialize(source_bzrdir)
527
 
        source_branch = breezy.bzr.branch.BzrBranchFormat7().initialize(
528
 
            source_bzrdir)
529
 
        # Make a directory with a default stacking policy
530
 
        parent_bzrdir = self.make_controldir('parent')
531
 
        stacked_on = self.make_branch('parent/stacked-on', format='pack-0.92')
532
 
        parent_bzrdir.get_config().set_default_stack_on(stacked_on.base)
533
 
        # Clone source into directory
534
 
        target = source_bzrdir.clone(self.get_url('parent/target'))
535
 
 
536
 
    def test_format_initialize_on_transport_ex_stacked_on(self):
537
 
        # trunk is a stackable format.  Note that its in the same server area
538
 
        # which is what launchpad does, but not sufficient to exercise the
539
 
        # general case.
540
 
        trunk = self.make_branch('trunk', format='1.9')
541
 
        t = self.get_transport('stacked')
542
 
        old_fmt = controldir.format_registry.make_controldir('pack-0.92')
543
 
        repo_name = old_fmt.repository_format.network_name()
544
 
        # Should end up with a 1.9 format (stackable)
545
 
        repo, control, require_stacking, repo_policy = \
546
 
            old_fmt.initialize_on_transport_ex(t,
547
 
                                               repo_format_name=repo_name, stacked_on='../trunk',
548
 
                                               stack_on_pwd=t.base)
549
 
        if repo is not None:
550
 
            # Repositories are open write-locked
551
 
            self.assertTrue(repo.is_write_locked())
552
 
            self.addCleanup(repo.unlock)
553
 
        else:
554
 
            repo = control.open_repository()
555
 
        self.assertIsInstance(control, bzrdir.BzrDir)
556
 
        opened = bzrdir.BzrDir.open(t.base)
557
 
        if not isinstance(old_fmt, remote.RemoteBzrDirFormat):
558
 
            self.assertEqual(control._format.network_name(),
559
 
                             old_fmt.network_name())
560
 
            self.assertEqual(control._format.network_name(),
561
 
                             opened._format.network_name())
562
 
        self.assertEqual(control.__class__, opened.__class__)
563
 
        self.assertLength(1, repo._fallback_repositories)
564
 
 
565
 
    def test_sprout_obeys_stacking_policy(self):
566
 
        child_branch, new_child_transport = self.prepare_default_stacking()
567
 
        new_child = child_branch.controldir.sprout(new_child_transport.base)
568
 
        self.assertEqual(child_branch.base,
569
 
                         new_child.open_branch().get_stacked_on_url())
570
 
 
571
 
    def test_clone_ignores_policy_for_unsupported_formats(self):
572
 
        child_branch, new_child_transport = self.prepare_default_stacking(
573
 
            child_format='pack-0.92')
574
 
        new_child = child_branch.controldir.clone_on_transport(
575
 
            new_child_transport)
576
 
        self.assertRaises(branch.UnstackableBranchFormat,
577
 
                          new_child.open_branch().get_stacked_on_url)
578
 
 
579
 
    def test_sprout_ignores_policy_for_unsupported_formats(self):
580
 
        child_branch, new_child_transport = self.prepare_default_stacking(
581
 
            child_format='pack-0.92')
582
 
        new_child = child_branch.controldir.sprout(new_child_transport.base)
583
 
        self.assertRaises(branch.UnstackableBranchFormat,
584
 
                          new_child.open_branch().get_stacked_on_url)
585
 
 
586
 
    def test_sprout_upgrades_format_if_stacked_specified(self):
587
 
        child_branch, new_child_transport = self.prepare_default_stacking(
588
 
            child_format='pack-0.92')
589
 
        new_child = child_branch.controldir.sprout(new_child_transport.base,
590
 
                                                   stacked=True)
591
 
        self.assertEqual(child_branch.controldir.root_transport.base,
592
 
                         new_child.open_branch().get_stacked_on_url())
593
 
        repo = new_child.open_repository()
594
 
        self.assertTrue(repo._format.supports_external_lookups)
595
 
        self.assertFalse(repo.supports_rich_root())
596
 
 
597
 
    def test_clone_on_transport_upgrades_format_if_stacked_on_specified(self):
598
 
        child_branch, new_child_transport = self.prepare_default_stacking(
599
 
            child_format='pack-0.92')
600
 
        new_child = child_branch.controldir.clone_on_transport(new_child_transport,
601
 
                                                               stacked_on=child_branch.controldir.root_transport.base)
602
 
        self.assertEqual(child_branch.controldir.root_transport.base,
603
 
                         new_child.open_branch().get_stacked_on_url())
604
 
        repo = new_child.open_repository()
605
 
        self.assertTrue(repo._format.supports_external_lookups)
606
 
        self.assertFalse(repo.supports_rich_root())
607
 
 
608
 
    def test_sprout_upgrades_to_rich_root_format_if_needed(self):
609
 
        child_branch, new_child_transport = self.prepare_default_stacking(
610
 
            child_format='rich-root-pack')
611
 
        new_child = child_branch.controldir.sprout(new_child_transport.base,
612
 
                                                   stacked=True)
613
 
        repo = new_child.open_repository()
614
 
        self.assertTrue(repo._format.supports_external_lookups)
615
 
        self.assertTrue(repo.supports_rich_root())
616
 
 
617
 
    def test_add_fallback_repo_handles_absolute_urls(self):
618
 
        stack_on = self.make_branch('stack_on', format='1.6')
619
 
        repo = self.make_repository('repo', format='1.6')
620
 
        policy = bzrdir.UseExistingRepository(repo, stack_on.base)
621
 
        policy._add_fallback(repo)
622
 
 
623
 
    def test_add_fallback_repo_handles_relative_urls(self):
624
 
        stack_on = self.make_branch('stack_on', format='1.6')
625
 
        repo = self.make_repository('repo', format='1.6')
626
 
        policy = bzrdir.UseExistingRepository(repo, '.', stack_on.base)
627
 
        policy._add_fallback(repo)
628
 
 
629
 
    def test_configure_relative_branch_stacking_url(self):
630
 
        stack_on = self.make_branch('stack_on', format='1.6')
631
 
        stacked = self.make_branch('stack_on/stacked', format='1.6')
632
 
        policy = bzrdir.UseExistingRepository(stacked.repository,
633
 
                                              '.', stack_on.base)
634
 
        policy.configure_branch(stacked)
635
 
        self.assertEqual('..', stacked.get_stacked_on_url())
636
 
 
637
 
    def test_relative_branch_stacking_to_absolute(self):
638
 
        stack_on = self.make_branch('stack_on', format='1.6')
639
 
        stacked = self.make_branch('stack_on/stacked', format='1.6')
640
 
        policy = bzrdir.UseExistingRepository(stacked.repository,
641
 
                                              '.', self.get_readonly_url('stack_on'))
642
 
        policy.configure_branch(stacked)
643
 
        self.assertEqual(self.get_readonly_url('stack_on'),
644
 
                         stacked.get_stacked_on_url())
 
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)
645
332
 
646
333
 
647
334
class ChrootedTests(TestCaseWithTransport):
654
341
 
655
342
    def setUp(self):
656
343
        super(ChrootedTests, self).setUp()
657
 
        if not self.vfs_transport_factory == memory.MemoryServer:
658
 
            self.transport_readonly_server = http_server.HttpServer
659
 
 
660
 
    def local_branch_path(self, branch):
661
 
        return os.path.realpath(urlutils.local_path_from_url(branch.base))
 
344
        if not self.transport_server == MemoryServer:
 
345
            self.transport_readonly_server = HttpServer
662
346
 
663
347
    def test_open_containing(self):
664
348
        self.assertRaises(NotBranchError, bzrdir.BzrDir.open_containing,
666
350
        self.assertRaises(NotBranchError, bzrdir.BzrDir.open_containing,
667
351
                          self.get_readonly_url('g/p/q'))
668
352
        control = bzrdir.BzrDir.create(self.get_url())
669
 
        branch, relpath = bzrdir.BzrDir.open_containing(
670
 
            self.get_readonly_url(''))
 
353
        branch, relpath = bzrdir.BzrDir.open_containing(self.get_readonly_url(''))
671
354
        self.assertEqual('', relpath)
672
 
        branch, relpath = bzrdir.BzrDir.open_containing(
673
 
            self.get_readonly_url('g/p/q'))
 
355
        branch, relpath = bzrdir.BzrDir.open_containing(self.get_readonly_url('g/p/q'))
674
356
        self.assertEqual('g/p/q', relpath)
675
357
 
676
 
    def test_open_containing_tree_branch_or_repository_empty(self):
677
 
        self.assertRaises(errors.NotBranchError,
678
 
                          bzrdir.BzrDir.open_containing_tree_branch_or_repository,
679
 
                          self.get_readonly_url(''))
680
 
 
681
 
    def test_open_containing_tree_branch_or_repository_all(self):
682
 
        self.make_branch_and_tree('topdir')
683
 
        tree, branch, repo, relpath = \
684
 
            bzrdir.BzrDir.open_containing_tree_branch_or_repository(
685
 
                'topdir/foo')
686
 
        self.assertEqual(os.path.realpath('topdir'),
687
 
                         os.path.realpath(tree.basedir))
688
 
        self.assertEqual(os.path.realpath('topdir'),
689
 
                         self.local_branch_path(branch))
690
 
        self.assertEqual(
691
 
            osutils.realpath(os.path.join('topdir', '.bzr', 'repository')),
692
 
            repo.controldir.transport.local_abspath('repository'))
693
 
        self.assertEqual(relpath, 'foo')
694
 
 
695
 
    def test_open_containing_tree_branch_or_repository_no_tree(self):
696
 
        self.make_branch('branch')
697
 
        tree, branch, repo, relpath = \
698
 
            bzrdir.BzrDir.open_containing_tree_branch_or_repository(
699
 
                'branch/foo')
700
 
        self.assertEqual(tree, None)
701
 
        self.assertEqual(os.path.realpath('branch'),
702
 
                         self.local_branch_path(branch))
703
 
        self.assertEqual(
704
 
            osutils.realpath(os.path.join('branch', '.bzr', 'repository')),
705
 
            repo.controldir.transport.local_abspath('repository'))
706
 
        self.assertEqual(relpath, 'foo')
707
 
 
708
 
    def test_open_containing_tree_branch_or_repository_repo(self):
709
 
        self.make_repository('repo')
710
 
        tree, branch, repo, relpath = \
711
 
            bzrdir.BzrDir.open_containing_tree_branch_or_repository(
712
 
                'repo')
713
 
        self.assertEqual(tree, None)
714
 
        self.assertEqual(branch, None)
715
 
        self.assertEqual(
716
 
            osutils.realpath(os.path.join('repo', '.bzr', 'repository')),
717
 
            repo.controldir.transport.local_abspath('repository'))
718
 
        self.assertEqual(relpath, '')
719
 
 
720
 
    def test_open_containing_tree_branch_or_repository_shared_repo(self):
721
 
        self.make_repository('shared', shared=True)
722
 
        bzrdir.BzrDir.create_branch_convenience('shared/branch',
723
 
                                                force_new_tree=False)
724
 
        tree, branch, repo, relpath = \
725
 
            bzrdir.BzrDir.open_containing_tree_branch_or_repository(
726
 
                'shared/branch')
727
 
        self.assertEqual(tree, None)
728
 
        self.assertEqual(os.path.realpath('shared/branch'),
729
 
                         self.local_branch_path(branch))
730
 
        self.assertEqual(
731
 
            osutils.realpath(os.path.join('shared', '.bzr', 'repository')),
732
 
            repo.controldir.transport.local_abspath('repository'))
733
 
        self.assertEqual(relpath, '')
734
 
 
735
 
    def test_open_containing_tree_branch_or_repository_branch_subdir(self):
736
 
        self.make_branch_and_tree('foo')
737
 
        self.build_tree(['foo/bar/'])
738
 
        tree, branch, repo, relpath = \
739
 
            bzrdir.BzrDir.open_containing_tree_branch_or_repository(
740
 
                'foo/bar')
741
 
        self.assertEqual(os.path.realpath('foo'),
742
 
                         os.path.realpath(tree.basedir))
743
 
        self.assertEqual(os.path.realpath('foo'),
744
 
                         self.local_branch_path(branch))
745
 
        self.assertEqual(
746
 
            osutils.realpath(os.path.join('foo', '.bzr', 'repository')),
747
 
            repo.controldir.transport.local_abspath('repository'))
748
 
        self.assertEqual(relpath, 'bar')
749
 
 
750
 
    def test_open_containing_tree_branch_or_repository_repo_subdir(self):
751
 
        self.make_repository('bar')
752
 
        self.build_tree(['bar/baz/'])
753
 
        tree, branch, repo, relpath = \
754
 
            bzrdir.BzrDir.open_containing_tree_branch_or_repository(
755
 
                'bar/baz')
756
 
        self.assertEqual(tree, None)
757
 
        self.assertEqual(branch, None)
758
 
        self.assertEqual(
759
 
            osutils.realpath(os.path.join('bar', '.bzr', 'repository')),
760
 
            repo.controldir.transport.local_abspath('repository'))
761
 
        self.assertEqual(relpath, 'baz')
762
 
 
763
358
    def test_open_containing_from_transport(self):
764
 
        self.assertRaises(NotBranchError,
765
 
                          bzrdir.BzrDir.open_containing_from_transport,
766
 
                          _mod_transport.get_transport_from_url(self.get_readonly_url('')))
767
 
        self.assertRaises(NotBranchError,
768
 
                          bzrdir.BzrDir.open_containing_from_transport,
769
 
                          _mod_transport.get_transport_from_url(
770
 
                              self.get_readonly_url('g/p/q')))
 
359
        self.assertRaises(NotBranchError, bzrdir.BzrDir.open_containing_from_transport,
 
360
                          get_transport(self.get_readonly_url('')))
 
361
        self.assertRaises(NotBranchError, bzrdir.BzrDir.open_containing_from_transport,
 
362
                          get_transport(self.get_readonly_url('g/p/q')))
771
363
        control = bzrdir.BzrDir.create(self.get_url())
772
364
        branch, relpath = bzrdir.BzrDir.open_containing_from_transport(
773
 
            _mod_transport.get_transport_from_url(
774
 
                self.get_readonly_url('')))
 
365
            get_transport(self.get_readonly_url('')))
775
366
        self.assertEqual('', relpath)
776
367
        branch, relpath = bzrdir.BzrDir.open_containing_from_transport(
777
 
            _mod_transport.get_transport_from_url(
778
 
                self.get_readonly_url('g/p/q')))
 
368
            get_transport(self.get_readonly_url('g/p/q')))
779
369
        self.assertEqual('g/p/q', relpath)
780
370
 
781
 
    def test_open_containing_tree_or_branch(self):
782
 
        self.make_branch_and_tree('topdir')
783
 
        tree, branch, relpath = bzrdir.BzrDir.open_containing_tree_or_branch(
784
 
            'topdir/foo')
785
 
        self.assertEqual(os.path.realpath('topdir'),
786
 
                         os.path.realpath(tree.basedir))
787
 
        self.assertEqual(os.path.realpath('topdir'),
788
 
                         self.local_branch_path(branch))
789
 
        self.assertIs(tree.controldir, branch.controldir)
790
 
        self.assertEqual('foo', relpath)
791
 
        # opening from non-local should not return the tree
792
 
        tree, branch, relpath = bzrdir.BzrDir.open_containing_tree_or_branch(
793
 
            self.get_readonly_url('topdir/foo'))
794
 
        self.assertEqual(None, tree)
795
 
        self.assertEqual('foo', relpath)
796
 
        # without a tree:
797
 
        self.make_branch('topdir/foo')
798
 
        tree, branch, relpath = bzrdir.BzrDir.open_containing_tree_or_branch(
799
 
            'topdir/foo')
800
 
        self.assertIs(tree, None)
801
 
        self.assertEqual(os.path.realpath('topdir/foo'),
802
 
                         self.local_branch_path(branch))
803
 
        self.assertEqual('', relpath)
804
 
 
805
 
    def test_open_tree_or_branch(self):
806
 
        self.make_branch_and_tree('topdir')
807
 
        tree, branch = bzrdir.BzrDir.open_tree_or_branch('topdir')
808
 
        self.assertEqual(os.path.realpath('topdir'),
809
 
                         os.path.realpath(tree.basedir))
810
 
        self.assertEqual(os.path.realpath('topdir'),
811
 
                         self.local_branch_path(branch))
812
 
        self.assertIs(tree.controldir, branch.controldir)
813
 
        # opening from non-local should not return the tree
814
 
        tree, branch = bzrdir.BzrDir.open_tree_or_branch(
815
 
            self.get_readonly_url('topdir'))
816
 
        self.assertEqual(None, tree)
817
 
        # without a tree:
818
 
        self.make_branch('topdir/foo')
819
 
        tree, branch = bzrdir.BzrDir.open_tree_or_branch('topdir/foo')
820
 
        self.assertIs(tree, None)
821
 
        self.assertEqual(os.path.realpath('topdir/foo'),
822
 
                         self.local_branch_path(branch))
823
 
 
824
 
    def test_open_tree_or_branch_named(self):
825
 
        tree = self.make_branch_and_tree('topdir')
826
 
        self.assertRaises(
827
 
            NotBranchError,
828
 
            bzrdir.BzrDir.open_tree_or_branch, 'topdir', name='missing')
829
 
        tree.branch.controldir.create_branch('named')
830
 
        tree, branch = bzrdir.BzrDir.open_tree_or_branch('topdir', name='named')
831
 
        self.assertEqual(os.path.realpath('topdir'),
832
 
                         os.path.realpath(tree.basedir))
833
 
        self.assertEqual(os.path.realpath('topdir'),
834
 
                         self.local_branch_path(branch))
835
 
        self.assertEqual(branch.name, 'named')
836
 
        self.assertIs(tree.controldir, branch.controldir)
837
 
 
838
 
    def test_open_from_transport(self):
839
 
        # transport pointing at bzrdir should give a bzrdir with root transport
840
 
        # set to the given transport
841
 
        control = bzrdir.BzrDir.create(self.get_url())
842
 
        t = self.get_transport()
843
 
        opened_bzrdir = bzrdir.BzrDir.open_from_transport(t)
844
 
        self.assertEqual(t.base, opened_bzrdir.root_transport.base)
845
 
        self.assertIsInstance(opened_bzrdir, bzrdir.BzrDir)
846
 
 
847
 
    def test_open_from_transport_no_bzrdir(self):
848
 
        t = self.get_transport()
849
 
        self.assertRaises(NotBranchError, bzrdir.BzrDir.open_from_transport, t)
850
 
 
851
 
    def test_open_from_transport_bzrdir_in_parent(self):
852
 
        control = bzrdir.BzrDir.create(self.get_url())
853
 
        t = self.get_transport()
854
 
        t.mkdir('subdir')
855
 
        t = t.clone('subdir')
856
 
        self.assertRaises(NotBranchError, bzrdir.BzrDir.open_from_transport, t)
857
 
 
858
 
    def test_sprout_recursive(self):
859
 
        tree = self.make_branch_and_tree('tree1')
860
 
        sub_tree = self.make_branch_and_tree('tree1/subtree')
861
 
        sub_tree.set_root_id(b'subtree-root')
862
 
        tree.add_reference(sub_tree)
863
 
        tree.set_reference_info('subtree', sub_tree.branch.user_url)
864
 
        self.build_tree(['tree1/subtree/file'])
865
 
        sub_tree.add('file')
866
 
        tree.commit('Initial commit')
867
 
        tree2 = tree.controldir.sprout('tree2').open_workingtree()
868
 
        tree2.lock_read()
869
 
        self.addCleanup(tree2.unlock)
870
 
        self.assertPathExists('tree2/subtree/file')
871
 
        self.assertEqual('tree-reference', tree2.kind('subtree'))
872
 
 
873
 
    def test_cloning_metadir(self):
874
 
        """Ensure that cloning metadir is suitable"""
875
 
        bzrdir = self.make_controldir('bzrdir')
876
 
        bzrdir.cloning_metadir()
877
 
        branch = self.make_branch('branch', format='knit')
878
 
        format = branch.controldir.cloning_metadir()
879
 
        self.assertIsInstance(format.workingtree_format,
880
 
                              workingtree_4.WorkingTreeFormat6)
881
 
 
882
 
    def test_sprout_recursive_treeless(self):
883
 
        tree = self.make_branch_and_tree('tree1',
884
 
                                         format='development-subtree')
885
 
        sub_tree = self.make_branch_and_tree('tree1/subtree',
886
 
                                             format='development-subtree')
887
 
        tree.add_reference(sub_tree)
888
 
        tree.set_reference_info('subtree', sub_tree.branch.user_url)
889
 
        self.build_tree(['tree1/subtree/file'])
890
 
        sub_tree.add('file')
891
 
        tree.commit('Initial commit')
892
 
        # The following line force the orhaning to reveal bug #634470
893
 
        tree.branch.get_config_stack().set('transform.orphan_policy', 'move')
894
 
        tree.controldir.destroy_workingtree()
895
 
        # FIXME: subtree/.bzr is left here which allows the test to pass (or
896
 
        # fail :-( ) -- vila 20100909
897
 
        repo = self.make_repository('repo', shared=True,
898
 
                                    format='development-subtree')
899
 
        repo.set_make_working_trees(False)
900
 
        # FIXME: we just deleted the workingtree and now we want to use it ????
901
 
        # At a minimum, we should use tree.branch below (but this fails too
902
 
        # currently) or stop calling this test 'treeless'. Specifically, I've
903
 
        # turn the line below into an assertRaises when 'subtree/.bzr' is
904
 
        # orphaned and sprout tries to access the branch there (which is left
905
 
        # by bzrdir.BzrDirMeta1.destroy_workingtree when it ignores the
906
 
        # [DeletingParent('Not deleting', u'subtree', None)] conflict). See bug
907
 
        # #634470.  -- vila 20100909
908
 
        tree.controldir.sprout('repo/tree2')
909
 
        self.assertPathExists('repo/tree2/subtree')
910
 
        self.assertPathDoesNotExist('repo/tree2/subtree/file')
911
 
 
912
 
    def make_foo_bar_baz(self):
913
 
        foo = bzrdir.BzrDir.create_branch_convenience('foo').controldir
914
 
        bar = self.make_branch('foo/bar').controldir
915
 
        baz = self.make_branch('baz').controldir
916
 
        return foo, bar, baz
917
 
 
918
 
    def test_find_controldirs(self):
919
 
        foo, bar, baz = self.make_foo_bar_baz()
920
 
        t = self.get_transport()
921
 
        self.assertEqualBzrdirs(
922
 
            [baz, foo, bar], bzrdir.BzrDir.find_controldirs(t))
923
 
 
924
 
    def make_fake_permission_denied_transport(self, transport, paths):
925
 
        """Create a transport that raises PermissionDenied for some paths."""
926
 
        def filter(path):
927
 
            if path in paths:
928
 
                raise errors.PermissionDenied(path)
929
 
            return path
930
 
        path_filter_server = pathfilter.PathFilteringServer(transport, filter)
931
 
        path_filter_server.start_server()
932
 
        self.addCleanup(path_filter_server.stop_server)
933
 
        path_filter_transport = pathfilter.PathFilteringTransport(
934
 
            path_filter_server, '.')
935
 
        return (path_filter_server, path_filter_transport)
936
 
 
937
 
    def assertBranchUrlsEndWith(self, expect_url_suffix, actual_bzrdirs):
938
 
        """Check that each branch url ends with the given suffix."""
939
 
        for actual_bzrdir in actual_bzrdirs:
940
 
            self.assertEndsWith(actual_bzrdir.user_url, expect_url_suffix)
941
 
 
942
 
    def test_find_controldirs_permission_denied(self):
943
 
        foo, bar, baz = self.make_foo_bar_baz()
944
 
        t = self.get_transport()
945
 
        path_filter_server, path_filter_transport = \
946
 
            self.make_fake_permission_denied_transport(t, ['foo'])
947
 
        # local transport
948
 
        self.assertBranchUrlsEndWith('/baz/',
949
 
                                     bzrdir.BzrDir.find_controldirs(path_filter_transport))
950
 
        # smart server
951
 
        smart_transport = self.make_smart_server('.',
952
 
                                                 backing_server=path_filter_server)
953
 
        self.assertBranchUrlsEndWith('/baz/',
954
 
                                     bzrdir.BzrDir.find_controldirs(smart_transport))
955
 
 
956
 
    def test_find_controldirs_list_current(self):
957
 
        def list_current(transport):
958
 
            return [s for s in transport.list_dir('') if s != 'baz']
959
 
 
960
 
        foo, bar, baz = self.make_foo_bar_baz()
961
 
        t = self.get_transport()
962
 
        self.assertEqualBzrdirs(
963
 
            [foo, bar],
964
 
            bzrdir.BzrDir.find_controldirs(t, list_current=list_current))
965
 
 
966
 
    def test_find_controldirs_evaluate(self):
967
 
        def evaluate(bzrdir):
968
 
            try:
969
 
                repo = bzrdir.open_repository()
970
 
            except errors.NoRepositoryPresent:
971
 
                return True, bzrdir.root_transport.base
972
 
            else:
973
 
                return False, bzrdir.root_transport.base
974
 
 
975
 
        foo, bar, baz = self.make_foo_bar_baz()
976
 
        t = self.get_transport()
977
 
        self.assertEqual([baz.root_transport.base, foo.root_transport.base],
978
 
                         list(bzrdir.BzrDir.find_controldirs(t, evaluate=evaluate)))
979
 
 
980
 
    def assertEqualBzrdirs(self, first, second):
981
 
        first = list(first)
982
 
        second = list(second)
983
 
        self.assertEqual(len(first), len(second))
984
 
        for x, y in zip(first, second):
985
 
            self.assertEqual(x.root_transport.base, y.root_transport.base)
986
 
 
987
 
    def test_find_branches(self):
988
 
        root = self.make_repository('', shared=True)
989
 
        foo, bar, baz = self.make_foo_bar_baz()
990
 
        qux = self.make_controldir('foo/qux')
991
 
        t = self.get_transport()
992
 
        branches = bzrdir.BzrDir.find_branches(t)
993
 
        self.assertEqual(baz.root_transport.base, branches[0].base)
994
 
        self.assertEqual(foo.root_transport.base, branches[1].base)
995
 
        self.assertEqual(bar.root_transport.base, branches[2].base)
996
 
 
997
 
        # ensure this works without a top-level repo
998
 
        branches = bzrdir.BzrDir.find_branches(t.clone('foo'))
999
 
        self.assertEqual(foo.root_transport.base, branches[0].base)
1000
 
        self.assertEqual(bar.root_transport.base, branches[1].base)
1001
 
 
1002
 
 
1003
 
class TestMissingRepoBranchesSkipped(TestCaseWithMemoryTransport):
1004
 
 
1005
 
    def test_find_controldirs_missing_repo(self):
1006
 
        t = self.get_transport()
1007
 
        arepo = self.make_repository('arepo', shared=True)
1008
 
        abranch_url = arepo.user_url + '/abranch'
1009
 
        abranch = bzrdir.BzrDir.create(abranch_url).create_branch()
1010
 
        t.delete_tree('arepo/.bzr')
1011
 
        self.assertRaises(errors.NoRepositoryPresent,
1012
 
                          branch.Branch.open, abranch_url)
1013
 
        self.make_branch('baz')
1014
 
        for actual_bzrdir in bzrdir.BzrDir.find_branches(t):
1015
 
            self.assertEndsWith(actual_bzrdir.user_url, '/baz/')
1016
 
 
1017
371
 
1018
372
class TestMeta1DirFormat(TestCaseWithTransport):
1019
373
    """Tests specific to the meta1 dir format."""
1024
378
        branch_base = t.clone('branch').base
1025
379
        self.assertEqual(branch_base, dir.get_branch_transport(None).base)
1026
380
        self.assertEqual(branch_base,
1027
 
                         dir.get_branch_transport(BzrBranchFormat5()).base)
 
381
                         dir.get_branch_transport(bzrlib.branch.BzrBranchFormat5()).base)
1028
382
        repository_base = t.clone('repository').base
1029
 
        self.assertEqual(
1030
 
            repository_base, dir.get_repository_transport(None).base)
1031
 
        repository_format = repository.format_registry.get_default()
 
383
        self.assertEqual(repository_base, dir.get_repository_transport(None).base)
1032
384
        self.assertEqual(repository_base,
1033
 
                         dir.get_repository_transport(repository_format).base)
 
385
                         dir.get_repository_transport(repository.RepositoryFormat7()).base)
1034
386
        checkout_base = t.clone('checkout').base
1035
 
        self.assertEqual(
1036
 
            checkout_base, dir.get_workingtree_transport(None).base)
 
387
        self.assertEqual(checkout_base, dir.get_workingtree_transport(None).base)
1037
388
        self.assertEqual(checkout_base,
1038
 
                         dir.get_workingtree_transport(workingtree_3.WorkingTreeFormat3()).base)
 
389
                         dir.get_workingtree_transport(workingtree.WorkingTreeFormat3()).base)
1039
390
 
1040
391
    def test_meta1dir_uses_lockdir(self):
1041
392
        """Meta1 format uses a LockDir to guard the whole directory, not a file."""
1043
394
        t = dir.transport
1044
395
        self.assertIsDirectory('branch-lock', t)
1045
396
 
1046
 
    def test_comparison(self):
1047
 
        """Equality and inequality behave properly.
1048
 
 
1049
 
        Metadirs should compare equal iff they have the same repo, branch and
1050
 
        tree formats.
1051
 
        """
1052
 
        mydir = controldir.format_registry.make_controldir('knit')
1053
 
        self.assertEqual(mydir, mydir)
1054
 
        self.assertFalse(mydir != mydir)
1055
 
        otherdir = controldir.format_registry.make_controldir('knit')
1056
 
        self.assertEqual(otherdir, mydir)
1057
 
        self.assertFalse(otherdir != mydir)
1058
 
        otherdir2 = controldir.format_registry.make_controldir(
1059
 
            'development-subtree')
1060
 
        self.assertNotEqual(otherdir2, mydir)
1061
 
        self.assertFalse(otherdir2 == mydir)
1062
 
 
1063
 
    def test_with_features(self):
1064
 
        tree = self.make_branch_and_tree('tree', format='2a')
1065
 
        tree.controldir.update_feature_flags({b"bar": b"required"})
1066
 
        self.assertRaises(bzrdir.MissingFeature, bzrdir.BzrDir.open, 'tree')
1067
 
        bzrdir.BzrDirMetaFormat1.register_feature(b'bar')
1068
 
        self.addCleanup(bzrdir.BzrDirMetaFormat1.unregister_feature, b'bar')
1069
 
        dir = bzrdir.BzrDir.open('tree')
1070
 
        self.assertEqual(b"required", dir._format.features.get(b"bar"))
1071
 
        tree.controldir.update_feature_flags({
1072
 
            b"bar": None,
1073
 
            b"nonexistant": None})
1074
 
        dir = bzrdir.BzrDir.open('tree')
1075
 
        self.assertEqual({}, dir._format.features)
1076
 
 
1077
 
    def test_needs_conversion_different_working_tree(self):
1078
 
        # meta1dirs need an conversion if any element is not the default.
1079
 
        new_format = controldir.format_registry.make_controldir('dirstate')
1080
 
        tree = self.make_branch_and_tree('tree', format='knit')
1081
 
        self.assertTrue(tree.controldir.needs_format_conversion(
1082
 
            new_format))
1083
 
 
1084
 
    def test_initialize_on_format_uses_smart_transport(self):
1085
 
        self.setup_smart_server_with_call_log()
1086
 
        new_format = controldir.format_registry.make_controldir('dirstate')
1087
 
        transport = self.get_transport('target')
1088
 
        transport.ensure_base()
1089
 
        self.reset_smart_call_log()
1090
 
        instance = new_format.initialize_on_transport(transport)
1091
 
        self.assertIsInstance(instance, remote.RemoteBzrDir)
1092
 
        rpc_count = len(self.hpss_calls)
1093
 
        # This figure represent the amount of work to perform this use case. It
1094
 
        # is entirely ok to reduce this number if a test fails due to rpc_count
1095
 
        # being too low. If rpc_count increases, more network roundtrips have
1096
 
        # become necessary for this use case. Please do not adjust this number
1097
 
        # upwards without agreement from bzr's network support maintainers.
1098
 
        self.assertEqual(2, rpc_count)
 
397
        
 
398
class TestFormat5(TestCaseWithTransport):
 
399
    """Tests specific to the version 5 bzrdir format."""
 
400
 
 
401
    def test_same_lockfiles_between_tree_repo_branch(self):
 
402
        # this checks that only a single lockfiles instance is created 
 
403
        # for format 5 objects
 
404
        dir = bzrdir.BzrDirFormat5().initialize(self.get_url())
 
405
        def check_dir_components_use_same_lock(dir):
 
406
            ctrl_1 = dir.open_repository().control_files
 
407
            ctrl_2 = dir.open_branch().control_files
 
408
            ctrl_3 = dir.open_workingtree()._control_files
 
409
            self.assertTrue(ctrl_1 is ctrl_2)
 
410
            self.assertTrue(ctrl_2 is ctrl_3)
 
411
        check_dir_components_use_same_lock(dir)
 
412
        # and if we open it normally.
 
413
        dir = bzrdir.BzrDir.open(self.get_url())
 
414
        check_dir_components_use_same_lock(dir)
 
415
    
 
416
    def test_can_convert(self):
 
417
        # format 5 dirs are convertable
 
418
        dir = bzrdir.BzrDirFormat5().initialize(self.get_url())
 
419
        self.assertTrue(dir.can_convert_format())
 
420
    
 
421
    def test_needs_conversion(self):
 
422
        # format 5 dirs need a conversion if they are not the default.
 
423
        # and they start of not the default.
 
424
        old_format = bzrdir.BzrDirFormat.get_default_format()
 
425
        bzrdir.BzrDirFormat.set_default_format(bzrdir.BzrDirFormat5())
 
426
        try:
 
427
            dir = bzrdir.BzrDirFormat5().initialize(self.get_url())
 
428
            self.assertFalse(dir.needs_format_conversion())
 
429
        finally:
 
430
            bzrdir.BzrDirFormat.set_default_format(old_format)
 
431
        self.assertTrue(dir.needs_format_conversion())
 
432
 
 
433
 
 
434
class TestFormat6(TestCaseWithTransport):
 
435
    """Tests specific to the version 6 bzrdir format."""
 
436
 
 
437
    def test_same_lockfiles_between_tree_repo_branch(self):
 
438
        # this checks that only a single lockfiles instance is created 
 
439
        # for format 6 objects
 
440
        dir = bzrdir.BzrDirFormat6().initialize(self.get_url())
 
441
        def check_dir_components_use_same_lock(dir):
 
442
            ctrl_1 = dir.open_repository().control_files
 
443
            ctrl_2 = dir.open_branch().control_files
 
444
            ctrl_3 = dir.open_workingtree()._control_files
 
445
            self.assertTrue(ctrl_1 is ctrl_2)
 
446
            self.assertTrue(ctrl_2 is ctrl_3)
 
447
        check_dir_components_use_same_lock(dir)
 
448
        # and if we open it normally.
 
449
        dir = bzrdir.BzrDir.open(self.get_url())
 
450
        check_dir_components_use_same_lock(dir)
 
451
    
 
452
    def test_can_convert(self):
 
453
        # format 6 dirs are convertable
 
454
        dir = bzrdir.BzrDirFormat6().initialize(self.get_url())
 
455
        self.assertTrue(dir.can_convert_format())
 
456
    
 
457
    def test_needs_conversion(self):
 
458
        # format 6 dirs need an conversion if they are not the default.
 
459
        old_format = bzrdir.BzrDirFormat.get_default_format()
 
460
        bzrdir.BzrDirFormat.set_default_format(bzrdir.BzrDirMetaFormat1())
 
461
        try:
 
462
            dir = bzrdir.BzrDirFormat6().initialize(self.get_url())
 
463
            self.assertTrue(dir.needs_format_conversion())
 
464
        finally:
 
465
            bzrdir.BzrDirFormat.set_default_format(old_format)
1099
466
 
1100
467
 
1101
468
class NonLocalTests(TestCaseWithTransport):
1103
470
 
1104
471
    def setUp(self):
1105
472
        super(NonLocalTests, self).setUp()
1106
 
        self.vfs_transport_factory = memory.MemoryServer
1107
 
 
 
473
        self.transport_server = MemoryServer
 
474
    
1108
475
    def test_create_branch_convenience(self):
1109
476
        # outside a repo the default convenience output is a repo+branch_tree
1110
 
        format = controldir.format_registry.make_controldir('knit')
1111
 
        branch = bzrdir.BzrDir.create_branch_convenience(
1112
 
            self.get_url('foo'), format=format)
1113
 
        self.assertRaises(errors.NoWorkingTree,
1114
 
                          branch.controldir.open_workingtree)
1115
 
        branch.controldir.open_repository()
 
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)
1116
486
 
1117
487
    def test_create_branch_convenience_force_tree_not_local_fails(self):
1118
488
        # outside a repo the default convenience output is a repo+branch_tree
1119
 
        format = controldir.format_registry.make_controldir('knit')
1120
 
        self.assertRaises(errors.NotLocalUrl,
1121
 
                          bzrdir.BzrDir.create_branch_convenience,
1122
 
                          self.get_url('foo'),
1123
 
                          force_new_tree=True,
1124
 
                          format=format)
1125
 
        t = self.get_transport()
1126
 
        self.assertFalse(t.has('foo'))
 
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)
1127
500
 
1128
501
    def test_clone(self):
1129
502
        # clone into a nonlocal path works
1130
 
        format = controldir.format_registry.make_controldir('knit')
1131
 
        branch = bzrdir.BzrDir.create_branch_convenience('local',
1132
 
                                                         format=format)
1133
 
        branch.controldir.open_workingtree()
1134
 
        result = branch.controldir.clone(self.get_url('remote'))
 
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)
 
509
        branch.bzrdir.open_workingtree()
 
510
        result = branch.bzrdir.clone(self.get_url('remote'))
1135
511
        self.assertRaises(errors.NoWorkingTree,
1136
512
                          result.open_workingtree)
1137
513
        result.open_branch()
1138
514
        result.open_repository()
1139
515
 
1140
 
    def test_checkout_metadir(self):
1141
 
        # checkout_metadir has reasonable working tree format even when no
1142
 
        # working tree is present
1143
 
        self.make_branch('branch-knit2', format='dirstate-with-subtree')
1144
 
        my_bzrdir = bzrdir.BzrDir.open(self.get_url('branch-knit2'))
1145
 
        checkout_format = my_bzrdir.checkout_metadir()
1146
 
        self.assertIsInstance(checkout_format.workingtree_format,
1147
 
                              workingtree_4.WorkingTreeFormat4)
1148
 
 
1149
 
 
1150
 
class TestHTTPRedirectionsBase(object):
1151
 
    """Test redirection between two http servers.
1152
 
 
1153
 
    This MUST be used by daughter classes that also inherit from
1154
 
    TestCaseWithTwoWebservers.
1155
 
 
1156
 
    We can't inherit directly from TestCaseWithTwoWebservers or the
1157
 
    test framework will try to create an instance which cannot
1158
 
    run, its implementation being incomplete.
1159
 
    """
1160
 
 
1161
 
    def create_transport_readonly_server(self):
1162
 
        # We don't set the http protocol version, relying on the default
1163
 
        return http_utils.HTTPServerRedirecting()
1164
 
 
1165
 
    def create_transport_secondary_server(self):
1166
 
        # We don't set the http protocol version, relying on the default
1167
 
        return http_utils.HTTPServerRedirecting()
1168
 
 
1169
 
    def setUp(self):
1170
 
        super(TestHTTPRedirectionsBase, self).setUp()
1171
 
        # The redirections will point to the new server
1172
 
        self.new_server = self.get_readonly_server()
1173
 
        # The requests to the old server will be redirected
1174
 
        self.old_server = self.get_secondary_server()
1175
 
        # Configure the redirections
1176
 
        self.old_server.redirect_to(self.new_server.host, self.new_server.port)
1177
 
 
1178
 
    def test_loop(self):
1179
 
        # Both servers redirect to each other creating a loop
1180
 
        self.new_server.redirect_to(self.old_server.host, self.old_server.port)
1181
 
        # Starting from either server should loop
1182
 
        old_url = self._qualified_url(self.old_server.host,
1183
 
                                      self.old_server.port)
1184
 
        oldt = self._transport(old_url)
1185
 
        self.assertRaises(errors.NotBranchError,
1186
 
                          bzrdir.BzrDir.open_from_transport, oldt)
1187
 
        new_url = self._qualified_url(self.new_server.host,
1188
 
                                      self.new_server.port)
1189
 
        newt = self._transport(new_url)
1190
 
        self.assertRaises(errors.NotBranchError,
1191
 
                          bzrdir.BzrDir.open_from_transport, newt)
1192
 
 
1193
 
    def test_qualifier_preserved(self):
1194
 
        wt = self.make_branch_and_tree('branch')
1195
 
        old_url = self._qualified_url(self.old_server.host,
1196
 
                                      self.old_server.port)
1197
 
        start = self._transport(old_url).clone('branch')
1198
 
        bdir = bzrdir.BzrDir.open_from_transport(start)
1199
 
        # Redirection should preserve the qualifier, hence the transport class
1200
 
        # itself.
1201
 
        self.assertIsInstance(bdir.root_transport, type(start))
1202
 
 
1203
 
 
1204
 
class TestHTTPRedirections(TestHTTPRedirectionsBase,
1205
 
                           http_utils.TestCaseWithTwoWebservers):
1206
 
    """Tests redirections for urllib implementation"""
1207
 
 
1208
 
    _transport = HttpTransport
1209
 
 
1210
 
    def _qualified_url(self, host, port):
1211
 
        result = 'http://%s:%s' % (host, port)
1212
 
        self.permit_url(result)
1213
 
        return result
1214
 
 
1215
 
 
1216
 
class TestHTTPRedirections_nosmart(TestHTTPRedirectionsBase,
1217
 
                                   http_utils.TestCaseWithTwoWebservers):
1218
 
    """Tests redirections for the nosmart decorator"""
1219
 
 
1220
 
    _transport = NoSmartTransportDecorator
1221
 
 
1222
 
    def _qualified_url(self, host, port):
1223
 
        result = 'nosmart+http://%s:%s' % (host, port)
1224
 
        self.permit_url(result)
1225
 
        return result
1226
 
 
1227
 
 
1228
 
class TestHTTPRedirections_readonly(TestHTTPRedirectionsBase,
1229
 
                                    http_utils.TestCaseWithTwoWebservers):
1230
 
    """Tests redirections for readonly decoratror"""
1231
 
 
1232
 
    _transport = ReadonlyTransportDecorator
1233
 
 
1234
 
    def _qualified_url(self, host, port):
1235
 
        result = 'readonly+http://%s:%s' % (host, port)
1236
 
        self.permit_url(result)
1237
 
        return result
1238
 
 
1239
 
 
1240
 
class TestDotBzrHidden(TestCaseWithTransport):
1241
 
 
1242
 
    ls = ['ls']
1243
 
    if sys.platform == 'win32':
1244
 
        ls = [os.environ['COMSPEC'], '/C', 'dir', '/B']
1245
 
 
1246
 
    def get_ls(self):
1247
 
        f = subprocess.Popen(self.ls, stdout=subprocess.PIPE,
1248
 
                             stderr=subprocess.PIPE)
1249
 
        out, err = f.communicate()
1250
 
        self.assertEqual(0, f.returncode, 'Calling %s failed: %s'
1251
 
                         % (self.ls, err))
1252
 
        return out.splitlines()
1253
 
 
1254
 
    def test_dot_bzr_hidden(self):
1255
 
        b = bzrdir.BzrDir.create('.')
1256
 
        self.build_tree(['a'])
1257
 
        self.assertEqual([b'a'], self.get_ls())
1258
 
 
1259
 
    def test_dot_bzr_hidden_with_url(self):
1260
 
        b = bzrdir.BzrDir.create(urlutils.local_path_to_url('.'))
1261
 
        self.build_tree(['a'])
1262
 
        self.assertEqual([b'a'], self.get_ls())
1263
 
 
1264
 
 
1265
 
class _TestBzrDirFormat(bzrdir.BzrDirMetaFormat1):
1266
 
    """Test BzrDirFormat implementation for TestBzrDirSprout."""
1267
 
 
1268
 
    def _open(self, transport):
1269
 
        return _TestBzrDir(transport, self)
1270
 
 
1271
 
 
1272
 
class _TestBzrDir(bzrdir.BzrDirMeta1):
1273
 
    """Test BzrDir implementation for TestBzrDirSprout.
1274
 
 
1275
 
    When created a _TestBzrDir already has repository and a branch.  The branch
1276
 
    is a test double as well.
1277
 
    """
1278
 
 
1279
 
    def __init__(self, *args, **kwargs):
1280
 
        super(_TestBzrDir, self).__init__(*args, **kwargs)
1281
 
        self.test_branch = _TestBranch(self.transport)
1282
 
        self.test_branch.repository = self.create_repository()
1283
 
 
1284
 
    def open_branch(self, unsupported=False, possible_transports=None):
1285
 
        return self.test_branch
1286
 
 
1287
 
    def cloning_metadir(self, require_stacking=False):
1288
 
        return _TestBzrDirFormat()
1289
 
 
1290
 
 
1291
 
class _TestBranchFormat(breezy.branch.BranchFormat):
1292
 
    """Test Branch format for TestBzrDirSprout."""
1293
 
 
1294
 
 
1295
 
class _TestBranch(breezy.branch.Branch):
1296
 
    """Test Branch implementation for TestBzrDirSprout."""
1297
 
 
1298
 
    def __init__(self, transport, *args, **kwargs):
1299
 
        self._format = _TestBranchFormat()
1300
 
        self._transport = transport
1301
 
        self.base = transport.base
1302
 
        super(_TestBranch, self).__init__(*args, **kwargs)
1303
 
        self.calls = []
1304
 
        self._parent = None
1305
 
 
1306
 
    def sprout(self, *args, **kwargs):
1307
 
        self.calls.append('sprout')
1308
 
        return _TestBranch(self._transport)
1309
 
 
1310
 
    def copy_content_into(self, destination, revision_id=None):
1311
 
        self.calls.append('copy_content_into')
1312
 
 
1313
 
    def last_revision(self):
1314
 
        return _mod_revision.NULL_REVISION
1315
 
 
1316
 
    def get_parent(self):
1317
 
        return self._parent
1318
 
 
1319
 
    def _get_config(self):
1320
 
        return config.TransportConfig(self._transport, 'branch.conf')
1321
 
 
1322
 
    def _get_config_store(self):
1323
 
        return config.BranchStore(self)
1324
 
 
1325
 
    def set_parent(self, parent):
1326
 
        self._parent = parent
1327
 
 
1328
 
    def lock_read(self):
1329
 
        return lock.LogicalLockResult(self.unlock)
1330
 
 
1331
 
    def unlock(self):
1332
 
        return
1333
 
 
1334
 
 
1335
 
class TestBzrDirSprout(TestCaseWithMemoryTransport):
1336
 
 
1337
 
    def test_sprout_uses_branch_sprout(self):
1338
 
        """BzrDir.sprout calls Branch.sprout.
1339
 
 
1340
 
        Usually, BzrDir.sprout should delegate to the branch's sprout method
1341
 
        for part of the work.  This allows the source branch to control the
1342
 
        choice of format for the new branch.
1343
 
 
1344
 
        There are exceptions, but this tests avoids them:
1345
 
          - if there's no branch in the source bzrdir,
1346
 
          - or if the stacking has been requested and the format needs to be
1347
 
            overridden to satisfy that.
1348
 
        """
1349
 
        # Make an instrumented bzrdir.
1350
 
        t = self.get_transport('source')
1351
 
        t.ensure_base()
1352
 
        source_bzrdir = _TestBzrDirFormat().initialize_on_transport(t)
1353
 
        # The instrumented bzrdir has a test_branch attribute that logs calls
1354
 
        # made to the branch contained in that bzrdir.  Initially the test
1355
 
        # branch exists but no calls have been made to it.
1356
 
        self.assertEqual([], source_bzrdir.test_branch.calls)
1357
 
 
1358
 
        # Sprout the bzrdir
1359
 
        target_url = self.get_url('target')
1360
 
        result = source_bzrdir.sprout(target_url, recurse='no')
1361
 
 
1362
 
        # The bzrdir called the branch's sprout method.
1363
 
        self.assertSubset(['sprout'], source_bzrdir.test_branch.calls)
1364
 
 
1365
 
    def test_sprout_parent(self):
1366
 
        grandparent_tree = self.make_branch('grandparent')
1367
 
        parent = grandparent_tree.controldir.sprout('parent').open_branch()
1368
 
        branch_tree = parent.controldir.sprout('branch').open_branch()
1369
 
        self.assertContainsRe(branch_tree.get_parent(), '/parent/$')
1370
 
 
1371
 
 
1372
 
class TestBzrDirHooks(TestCaseWithMemoryTransport):
1373
 
 
1374
 
    def test_pre_open_called(self):
1375
 
        calls = []
1376
 
        bzrdir.BzrDir.hooks.install_named_hook('pre_open', calls.append, None)
1377
 
        transport = self.get_transport('foo')
1378
 
        url = transport.base
1379
 
        self.assertRaises(errors.NotBranchError, bzrdir.BzrDir.open, url)
1380
 
        self.assertEqual([transport.base], [t.base for t in calls])
1381
 
 
1382
 
    def test_pre_open_actual_exceptions_raised(self):
1383
 
        count = [0]
1384
 
 
1385
 
        def fail_once(transport):
1386
 
            count[0] += 1
1387
 
            if count[0] == 1:
1388
 
                raise errors.BzrError("fail")
1389
 
        bzrdir.BzrDir.hooks.install_named_hook('pre_open', fail_once, None)
1390
 
        transport = self.get_transport('foo')
1391
 
        url = transport.base
1392
 
        err = self.assertRaises(errors.BzrError, bzrdir.BzrDir.open, url)
1393
 
        self.assertEqual('fail', err._preformatted_string)
1394
 
 
1395
 
    def test_post_repo_init(self):
1396
 
        from ..controldir import RepoInitHookParams
1397
 
        calls = []
1398
 
        bzrdir.BzrDir.hooks.install_named_hook('post_repo_init',
1399
 
                                               calls.append, None)
1400
 
        self.make_repository('foo')
1401
 
        self.assertLength(1, calls)
1402
 
        params = calls[0]
1403
 
        self.assertIsInstance(params, RepoInitHookParams)
1404
 
        self.assertTrue(hasattr(params, 'controldir'))
1405
 
        self.assertTrue(hasattr(params, 'repository'))
1406
 
 
1407
 
    def test_post_repo_init_hook_repr(self):
1408
 
        param_reprs = []
1409
 
        bzrdir.BzrDir.hooks.install_named_hook('post_repo_init',
1410
 
                                               lambda params: param_reprs.append(repr(params)), None)
1411
 
        self.make_repository('foo')
1412
 
        self.assertLength(1, param_reprs)
1413
 
        param_repr = param_reprs[0]
1414
 
        self.assertStartsWith(param_repr, '<RepoInitHookParams for ')
1415
 
 
1416
 
 
1417
 
class TestGenerateBackupName(TestCaseWithMemoryTransport):
1418
 
    # FIXME: This may need to be unified with test_osutils.TestBackupNames or
1419
 
    # moved to per_bzrdir or per_transport for better coverage ?
1420
 
    # -- vila 20100909
1421
 
 
1422
 
    def setUp(self):
1423
 
        super(TestGenerateBackupName, self).setUp()
1424
 
        self._transport = self.get_transport()
1425
 
        bzrdir.BzrDir.create(self.get_url(),
1426
 
                             possible_transports=[self._transport])
1427
 
        self._bzrdir = bzrdir.BzrDir.open_from_transport(self._transport)
1428
 
 
1429
 
    def test_new(self):
1430
 
        self.assertEqual("a.~1~", self._bzrdir._available_backup_name("a"))
1431
 
 
1432
 
    def test_exiting(self):
1433
 
        self._transport.put_bytes("a.~1~", b"some content")
1434
 
        self.assertEqual("a.~2~", self._bzrdir._available_backup_name("a"))
1435
 
 
1436
 
 
1437
 
class TestMeta1DirColoFormat(TestCaseWithTransport):
1438
 
    """Tests specific to the meta1 dir with colocated branches format."""
1439
 
 
1440
 
    def test_supports_colo(self):
1441
 
        format = bzrdir.BzrDirMetaFormat1Colo()
1442
 
        self.assertTrue(format.colocated_branches)
1443
 
 
1444
 
    def test_upgrade_from_2a(self):
1445
 
        tree = self.make_branch_and_tree('.', format='2a')
1446
 
        format = bzrdir.BzrDirMetaFormat1Colo()
1447
 
        self.assertTrue(tree.controldir.needs_format_conversion(format))
1448
 
        converter = tree.controldir._format.get_converter(format)
1449
 
        result = converter.convert(tree.controldir, None)
1450
 
        self.assertIsInstance(result._format, bzrdir.BzrDirMetaFormat1Colo)
1451
 
        self.assertFalse(result.needs_format_conversion(format))
1452
 
 
1453
 
    def test_downgrade_to_2a(self):
1454
 
        tree = self.make_branch_and_tree('.', format='development-colo')
1455
 
        format = bzrdir.BzrDirMetaFormat1()
1456
 
        self.assertTrue(tree.controldir.needs_format_conversion(format))
1457
 
        converter = tree.controldir._format.get_converter(format)
1458
 
        result = converter.convert(tree.controldir, None)
1459
 
        self.assertIsInstance(result._format, bzrdir.BzrDirMetaFormat1)
1460
 
        self.assertFalse(result.needs_format_conversion(format))
1461
 
 
1462
 
    def test_downgrade_to_2a_too_many_branches(self):
1463
 
        tree = self.make_branch_and_tree('.', format='development-colo')
1464
 
        tree.controldir.create_branch(name="another-colocated-branch")
1465
 
        converter = tree.controldir._format.get_converter(
1466
 
            bzrdir.BzrDirMetaFormat1())
1467
 
        result = converter.convert(tree.controldir, bzrdir.BzrDirMetaFormat1())
1468
 
        self.assertIsInstance(result._format, bzrdir.BzrDirMetaFormat1)
1469
 
 
1470
 
    def test_nested(self):
1471
 
        tree = self.make_branch_and_tree('.', format='development-colo')
1472
 
        tree.controldir.create_branch(name='foo')
1473
 
        tree.controldir.create_branch(name='fool/bla')
1474
 
        self.assertRaises(
1475
 
            errors.ParentBranchExists, tree.controldir.create_branch,
1476
 
            name='foo/bar')
1477
 
 
1478
 
    def test_parent(self):
1479
 
        tree = self.make_branch_and_tree('.', format='development-colo')
1480
 
        tree.controldir.create_branch(name='fool/bla')
1481
 
        tree.controldir.create_branch(name='foo/bar')
1482
 
        self.assertRaises(
1483
 
            errors.AlreadyBranchError, tree.controldir.create_branch,
1484
 
            name='foo')
1485
 
 
1486
 
    def test_supports_relative_reference(self):
1487
 
        tree = self.make_branch_and_tree('.', format='development-colo')
1488
 
        target1 = tree.controldir.create_branch(name='target1')
1489
 
        target2 = tree.controldir.create_branch(name='target2')
1490
 
        source = tree.controldir.set_branch_reference(target1, name='source')
1491
 
        self.assertEqual(
1492
 
            target1.user_url, tree.controldir.open_branch('source').user_url)
1493
 
        source.controldir.get_branch_transport(None, 'source').put_bytes(
1494
 
            'location', b'file:,branch=target2')
1495
 
        self.assertEqual(
1496
 
            target2.user_url, tree.controldir.open_branch('source').user_url)
1497
 
 
1498
 
 
1499
 
class SampleBzrFormat(bzrdir.BzrFormat):
1500
 
 
1501
 
    @classmethod
1502
 
    def get_format_string(cls):
1503
 
        return b"First line\n"
1504
 
 
1505
 
 
1506
 
class TestBzrFormat(TestCase):
1507
 
    """Tests for BzrFormat."""
1508
 
 
1509
 
    def test_as_string(self):
1510
 
        format = SampleBzrFormat()
1511
 
        format.features = {b"foo": b"required"}
1512
 
        self.assertEqual(format.as_string(),
1513
 
                         b"First line\n"
1514
 
                         b"required foo\n")
1515
 
        format.features[b"another"] = b"optional"
1516
 
        self.assertEqual(format.as_string(),
1517
 
                         b"First line\n"
1518
 
                         b"optional another\n"
1519
 
                         b"required foo\n")
1520
 
 
1521
 
    def test_network_name(self):
1522
 
        # The network string should include the feature info
1523
 
        format = SampleBzrFormat()
1524
 
        format.features = {b"foo": b"required"}
1525
 
        self.assertEqual(
1526
 
            b"First line\nrequired foo\n",
1527
 
            format.network_name())
1528
 
 
1529
 
    def test_from_string_no_features(self):
1530
 
        # No features
1531
 
        format = SampleBzrFormat.from_string(
1532
 
            b"First line\n")
1533
 
        self.assertEqual({}, format.features)
1534
 
 
1535
 
    def test_from_string_with_feature(self):
1536
 
        # Proper feature
1537
 
        format = SampleBzrFormat.from_string(
1538
 
            b"First line\nrequired foo\n")
1539
 
        self.assertEqual(b"required", format.features.get(b"foo"))
1540
 
 
1541
 
    def test_from_string_format_string_mismatch(self):
1542
 
        # The first line has to match the format string
1543
 
        self.assertRaises(AssertionError, SampleBzrFormat.from_string,
1544
 
                          b"Second line\nrequired foo\n")
1545
 
 
1546
 
    def test_from_string_missing_space(self):
1547
 
        # At least one space is required in the feature lines
1548
 
        self.assertRaises(errors.ParseFormatError, SampleBzrFormat.from_string,
1549
 
                          b"First line\nfoo\n")
1550
 
 
1551
 
    def test_from_string_with_spaces(self):
1552
 
        # Feature with spaces (in case we add stuff like this in the future)
1553
 
        format = SampleBzrFormat.from_string(
1554
 
            b"First line\nrequired foo with spaces\n")
1555
 
        self.assertEqual(b"required", format.features.get(b"foo with spaces"))
1556
 
 
1557
 
    def test_eq(self):
1558
 
        format1 = SampleBzrFormat()
1559
 
        format1.features = {b"nested-trees": b"optional"}
1560
 
        format2 = SampleBzrFormat()
1561
 
        format2.features = {b"nested-trees": b"optional"}
1562
 
        self.assertEqual(format1, format1)
1563
 
        self.assertEqual(format1, format2)
1564
 
        format3 = SampleBzrFormat()
1565
 
        self.assertNotEqual(format1, format3)
1566
 
 
1567
 
    def test_check_support_status_optional(self):
1568
 
        # Optional, so silently ignore
1569
 
        format = SampleBzrFormat()
1570
 
        format.features = {b"nested-trees": b"optional"}
1571
 
        format.check_support_status(True)
1572
 
        self.addCleanup(SampleBzrFormat.unregister_feature, b"nested-trees")
1573
 
        SampleBzrFormat.register_feature(b"nested-trees")
1574
 
        format.check_support_status(True)
1575
 
 
1576
 
    def test_check_support_status_required(self):
1577
 
        # Optional, so trigger an exception
1578
 
        format = SampleBzrFormat()
1579
 
        format.features = {b"nested-trees": b"required"}
1580
 
        self.assertRaises(bzrdir.MissingFeature, format.check_support_status,
1581
 
                          True)
1582
 
        self.addCleanup(SampleBzrFormat.unregister_feature, b"nested-trees")
1583
 
        SampleBzrFormat.register_feature(b"nested-trees")
1584
 
        format.check_support_status(True)
1585
 
 
1586
 
    def test_check_support_status_unknown(self):
1587
 
        # treat unknown necessity as required
1588
 
        format = SampleBzrFormat()
1589
 
        format.features = {b"nested-trees": b"unknown"}
1590
 
        self.assertRaises(bzrdir.MissingFeature, format.check_support_status,
1591
 
                          True)
1592
 
        self.addCleanup(SampleBzrFormat.unregister_feature, b"nested-trees")
1593
 
        SampleBzrFormat.register_feature(b"nested-trees")
1594
 
        format.check_support_status(True)
1595
 
 
1596
 
    def test_feature_already_registered(self):
1597
 
        # a feature can only be registered once
1598
 
        self.addCleanup(SampleBzrFormat.unregister_feature, b"nested-trees")
1599
 
        SampleBzrFormat.register_feature(b"nested-trees")
1600
 
        self.assertRaises(bzrdir.FeatureAlreadyRegistered,
1601
 
                          SampleBzrFormat.register_feature, b"nested-trees")
1602
 
 
1603
 
    def test_feature_with_space(self):
1604
 
        # spaces are not allowed in feature names
1605
 
        self.assertRaises(ValueError, SampleBzrFormat.register_feature,
1606
 
                          b"nested trees")