~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_bzrdir.py

  • Committer: Patch Queue Manager
  • Date: 2014-09-22 19:14:34 UTC
  • mfrom: (6598.1.2 bzr)
  • Revision ID: pqm@pqm.ubuntu.com-20140922191434-6bbnpnxi5jab4vim
(richard-wilbur) Allows launchpad APIs to use proxies by default(Paul Gear).
 (Paul Gear)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2006-2010 Canonical Ltd
 
1
# Copyright (C) 2006-2011 Canonical Ltd
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
26
26
from bzrlib import (
27
27
    branch,
28
28
    bzrdir,
 
29
    config,
29
30
    controldir,
30
31
    errors,
31
32
    help_topics,
 
33
    lock,
32
34
    repository,
 
35
    revision as _mod_revision,
33
36
    osutils,
34
37
    remote,
 
38
    transport as _mod_transport,
35
39
    urlutils,
36
40
    win32utils,
37
 
    workingtree,
 
41
    workingtree_3,
 
42
    workingtree_4,
38
43
    )
39
44
import bzrlib.branch
40
 
from bzrlib.errors import (NotBranchError,
41
 
                           NoColocatedBranchSupport,
42
 
                           UnknownFormatError,
43
 
                           UnsupportedFormatError,
44
 
                           )
 
45
from bzrlib.branchfmt.fullhistory import BzrBranchFormat5
 
46
from bzrlib.errors import (
 
47
    NotBranchError,
 
48
    NoColocatedBranchSupport,
 
49
    UnknownFormatError,
 
50
    UnsupportedFormatError,
 
51
    )
45
52
from bzrlib.tests import (
46
53
    TestCase,
47
54
    TestCaseWithMemoryTransport,
54
61
    )
55
62
from bzrlib.tests.test_http import TestWithTransport_pycurl
56
63
from bzrlib.transport import (
57
 
    get_transport,
58
64
    memory,
59
65
    pathfilter,
60
66
    )
61
67
from bzrlib.transport.http._urllib import HttpTransport_urllib
62
68
from bzrlib.transport.nosmart import NoSmartTransportDecorator
63
69
from bzrlib.transport.readonly import ReadonlyTransportDecorator
64
 
from bzrlib.repofmt import knitrepo, weaverepo, pack_repo
 
70
from bzrlib.repofmt import knitrepo, knitpack_repo
65
71
 
66
72
 
67
73
class TestDefaultFormat(TestCase):
68
74
 
69
75
    def test_get_set_default_format(self):
70
76
        old_format = bzrdir.BzrDirFormat.get_default_format()
71
 
        # default is BzrDirFormat6
72
 
        self.failUnless(isinstance(old_format, bzrdir.BzrDirMetaFormat1))
 
77
        # default is BzrDirMetaFormat1
 
78
        self.assertIsInstance(old_format, bzrdir.BzrDirMetaFormat1)
73
79
        controldir.ControlDirFormat._set_default_format(SampleBzrDirFormat())
74
80
        # creating a bzr dir should now create an instrumented dir.
75
81
        try:
76
82
            result = bzrdir.BzrDir.create('memory:///')
77
 
            self.failUnless(isinstance(result, SampleBzrDir))
 
83
            self.assertIsInstance(result, SampleBzrDir)
78
84
        finally:
79
85
            controldir.ControlDirFormat._set_default_format(old_format)
80
86
        self.assertEqual(old_format, bzrdir.BzrDirFormat.get_default_format())
81
87
 
82
88
 
 
89
class DeprecatedBzrDirFormat(bzrdir.BzrDirFormat):
 
90
    """A deprecated bzr dir format."""
 
91
 
 
92
 
83
93
class TestFormatRegistry(TestCase):
84
94
 
85
95
    def make_format_registry(self):
86
96
        my_format_registry = controldir.ControlDirFormatRegistry()
87
 
        my_format_registry.register('weave', bzrdir.BzrDirFormat6,
88
 
            'Pre-0.8 format.  Slower and does not support checkouts or shared'
89
 
            ' repositories', deprecated=True)
90
 
        my_format_registry.register_lazy('lazy', 'bzrlib.bzrdir',
91
 
            'BzrDirFormat6', 'Format registered lazily', deprecated=True)
 
97
        my_format_registry.register('deprecated', DeprecatedBzrDirFormat,
 
98
            'Some format.  Slower and unawesome and deprecated.',
 
99
            deprecated=True)
 
100
        my_format_registry.register_lazy('lazy', 'bzrlib.tests.test_bzrdir',
 
101
            'DeprecatedBzrDirFormat', 'Format registered lazily',
 
102
            deprecated=True)
92
103
        bzrdir.register_metadir(my_format_registry, 'knit',
93
104
            'bzrlib.repofmt.knitrepo.RepositoryFormatKnit1',
94
105
            'Format using knits',
105
116
            'bzrlib.repofmt.knitrepo.RepositoryFormatKnit3',
106
117
            'Experimental successor to knit.  Use at your own risk.',
107
118
            branch_format='bzrlib.branch.BzrBranchFormat6', hidden=True)
108
 
        my_format_registry.register('hiddenweave', bzrdir.BzrDirFormat6,
109
 
            'Pre-0.8 format.  Slower and does not support checkouts or shared'
110
 
            ' repositories', hidden=True)
111
 
        my_format_registry.register_lazy('hiddenlazy', 'bzrlib.bzrdir',
112
 
            'BzrDirFormat6', 'Format registered lazily', deprecated=True,
113
 
            hidden=True)
 
119
        my_format_registry.register('hiddendeprecated', DeprecatedBzrDirFormat,
 
120
            'Old format.  Slower and does not support things. ', hidden=True)
 
121
        my_format_registry.register_lazy('hiddenlazy', 'bzrlib.tests.test_bzrdir',
 
122
            'DeprecatedBzrDirFormat', 'Format registered lazily',
 
123
            deprecated=True, hidden=True)
114
124
        return my_format_registry
115
125
 
116
126
    def test_format_registry(self):
117
127
        my_format_registry = self.make_format_registry()
118
128
        my_bzrdir = my_format_registry.make_bzrdir('lazy')
119
 
        self.assertIsInstance(my_bzrdir, bzrdir.BzrDirFormat6)
120
 
        my_bzrdir = my_format_registry.make_bzrdir('weave')
121
 
        self.assertIsInstance(my_bzrdir, bzrdir.BzrDirFormat6)
 
129
        self.assertIsInstance(my_bzrdir, DeprecatedBzrDirFormat)
 
130
        my_bzrdir = my_format_registry.make_bzrdir('deprecated')
 
131
        self.assertIsInstance(my_bzrdir, DeprecatedBzrDirFormat)
122
132
        my_bzrdir = my_format_registry.make_bzrdir('default')
123
133
        self.assertIsInstance(my_bzrdir.repository_format,
124
134
            knitrepo.RepositoryFormatKnit1)
137
147
                         my_format_registry.get_help('knit'))
138
148
        self.assertEqual('Format using knits',
139
149
                         my_format_registry.get_help('default'))
140
 
        self.assertEqual('Pre-0.8 format.  Slower and does not support'
141
 
                         ' checkouts or shared repositories',
142
 
                         my_format_registry.get_help('weave'))
 
150
        self.assertEqual('Some format.  Slower and unawesome and deprecated.',
 
151
                         my_format_registry.get_help('deprecated'))
143
152
 
144
153
    def test_help_topic(self):
145
154
        topics = help_topics.HelpTopicRegistry()
161
170
        self.assertNotContainsRe(new, 'hidden')
162
171
 
163
172
    def test_set_default_repository(self):
164
 
        default_factory = bzrdir.format_registry.get('default')
165
 
        old_default = [k for k, v in bzrdir.format_registry.iteritems()
 
173
        default_factory = controldir.format_registry.get('default')
 
174
        old_default = [k for k, v in controldir.format_registry.iteritems()
166
175
                       if v == default_factory and k != 'default'][0]
167
 
        bzrdir.format_registry.set_default_repository('dirstate-with-subtree')
 
176
        controldir.format_registry.set_default_repository('dirstate-with-subtree')
168
177
        try:
169
 
            self.assertIs(bzrdir.format_registry.get('dirstate-with-subtree'),
170
 
                          bzrdir.format_registry.get('default'))
 
178
            self.assertIs(controldir.format_registry.get('dirstate-with-subtree'),
 
179
                          controldir.format_registry.get('default'))
171
180
            self.assertIs(
172
 
                repository.RepositoryFormat.get_default_format().__class__,
 
181
                repository.format_registry.get_default().__class__,
173
182
                knitrepo.RepositoryFormatKnit3)
174
183
        finally:
175
 
            bzrdir.format_registry.set_default_repository(old_default)
 
184
            controldir.format_registry.set_default_repository(old_default)
176
185
 
177
186
    def test_aliases(self):
178
187
        a_registry = controldir.ControlDirFormatRegistry()
179
 
        a_registry.register('weave', bzrdir.BzrDirFormat6,
180
 
            'Pre-0.8 format.  Slower and does not support checkouts or shared'
181
 
            ' repositories', deprecated=True)
182
 
        a_registry.register('weavealias', bzrdir.BzrDirFormat6,
183
 
            'Pre-0.8 format.  Slower and does not support checkouts or shared'
184
 
            ' repositories', deprecated=True, alias=True)
185
 
        self.assertEqual(frozenset(['weavealias']), a_registry.aliases())
 
188
        a_registry.register('deprecated', DeprecatedBzrDirFormat,
 
189
            'Old format.  Slower and does not support stuff',
 
190
            deprecated=True)
 
191
        a_registry.register('deprecatedalias', DeprecatedBzrDirFormat,
 
192
            'Old format.  Slower and does not support stuff',
 
193
            deprecated=True, alias=True)
 
194
        self.assertEqual(frozenset(['deprecatedalias']), a_registry.aliases())
186
195
 
187
196
 
188
197
class SampleBranch(bzrlib.branch.Branch):
203
212
    """A sample BzrDir implementation to allow testing static methods."""
204
213
 
205
214
    def create_repository(self, shared=False):
206
 
        """See BzrDir.create_repository."""
 
215
        """See ControlDir.create_repository."""
207
216
        return "A repository"
208
217
 
209
218
    def open_repository(self):
210
 
        """See BzrDir.open_repository."""
 
219
        """See ControlDir.open_repository."""
211
220
        return SampleRepository(self)
212
221
 
213
222
    def create_branch(self, name=None):
214
 
        """See BzrDir.create_branch."""
 
223
        """See ControlDir.create_branch."""
215
224
        if name is not None:
216
225
            raise NoColocatedBranchSupport(self)
217
226
        return SampleBranch(self)
218
227
 
219
228
    def create_workingtree(self):
220
 
        """See BzrDir.create_workingtree."""
 
229
        """See ControlDir.create_workingtree."""
221
230
        return "A tree"
222
231
 
223
232
 
244
253
    def open(self, transport, _found=None):
245
254
        return "opened branch."
246
255
 
 
256
    @classmethod
 
257
    def from_string(cls, format_string):
 
258
        return cls()
 
259
 
 
260
 
 
261
class BzrDirFormatTest1(bzrdir.BzrDirMetaFormat1):
 
262
 
 
263
    @staticmethod
 
264
    def get_format_string():
 
265
        return "Test format 1"
 
266
 
 
267
 
 
268
class BzrDirFormatTest2(bzrdir.BzrDirMetaFormat1):
 
269
 
 
270
    @staticmethod
 
271
    def get_format_string():
 
272
        return "Test format 2"
 
273
 
247
274
 
248
275
class TestBzrDirFormat(TestCaseWithTransport):
249
276
    """Tests for the BzrDirFormat facility."""
251
278
    def test_find_format(self):
252
279
        # is the right format object found for a branch?
253
280
        # create a branch with a few known format objects.
254
 
        # this is not quite the same as
255
 
        t = get_transport(self.get_url())
 
281
        bzrdir.BzrProber.formats.register(BzrDirFormatTest1.get_format_string(),
 
282
            BzrDirFormatTest1())
 
283
        self.addCleanup(bzrdir.BzrProber.formats.remove,
 
284
            BzrDirFormatTest1.get_format_string())
 
285
        bzrdir.BzrProber.formats.register(BzrDirFormatTest2.get_format_string(),
 
286
            BzrDirFormatTest2())
 
287
        self.addCleanup(bzrdir.BzrProber.formats.remove,
 
288
            BzrDirFormatTest2.get_format_string())
 
289
        t = self.get_transport()
256
290
        self.build_tree(["foo/", "bar/"], transport=t)
257
291
        def check_format(format, url):
258
292
            format.initialize(url)
259
 
            t = get_transport(url)
 
293
            t = _mod_transport.get_transport_from_path(url)
260
294
            found_format = bzrdir.BzrDirFormat.find_format(t)
261
 
            self.failUnless(isinstance(found_format, format.__class__))
262
 
        check_format(bzrdir.BzrDirFormat5(), "foo")
263
 
        check_format(bzrdir.BzrDirFormat6(), "bar")
 
295
            self.assertIsInstance(found_format, format.__class__)
 
296
        check_format(BzrDirFormatTest1(), "foo")
 
297
        check_format(BzrDirFormatTest2(), "bar")
264
298
 
265
299
    def test_find_format_nothing_there(self):
266
300
        self.assertRaises(NotBranchError,
267
301
                          bzrdir.BzrDirFormat.find_format,
268
 
                          get_transport('.'))
 
302
                          _mod_transport.get_transport_from_path('.'))
269
303
 
270
304
    def test_find_format_unknown_format(self):
271
 
        t = get_transport(self.get_url())
 
305
        t = self.get_transport()
272
306
        t.mkdir('.bzr')
273
307
        t.put_bytes('.bzr/branch-format', '')
274
308
        self.assertRaises(UnknownFormatError,
275
309
                          bzrdir.BzrDirFormat.find_format,
276
 
                          get_transport('.'))
 
310
                          _mod_transport.get_transport_from_path('.'))
277
311
 
278
312
    def test_register_unregister_format(self):
279
313
        format = SampleBzrDirFormat()
281
315
        # make a bzrdir
282
316
        format.initialize(url)
283
317
        # register a format for it.
284
 
        bzrdir.BzrDirFormat.register_format(format)
 
318
        bzrdir.BzrProber.formats.register(format.get_format_string(), format)
285
319
        # which bzrdir.Open will refuse (not supported)
286
320
        self.assertRaises(UnsupportedFormatError, bzrdir.BzrDir.open, url)
287
321
        # which bzrdir.open_containing will refuse (not supported)
288
322
        self.assertRaises(UnsupportedFormatError, bzrdir.BzrDir.open_containing, url)
289
323
        # but open_downlevel will work
290
 
        t = get_transport(url)
 
324
        t = _mod_transport.get_transport_from_url(url)
291
325
        self.assertEqual(format.open(t), bzrdir.BzrDir.open_unsupported(url))
292
326
        # unregister the format
293
 
        bzrdir.BzrDirFormat.unregister_format(format)
 
327
        bzrdir.BzrProber.formats.remove(format.get_format_string())
294
328
        # now open_downlevel should fail too.
295
329
        self.assertRaises(UnknownFormatError, bzrdir.BzrDir.open_unsupported, url)
296
330
 
303
337
    def test_create_branch_and_repo_under_shared(self):
304
338
        # creating a branch and repo in a shared repo uses the
305
339
        # shared repository
306
 
        format = bzrdir.format_registry.make_bzrdir('knit')
 
340
        format = controldir.format_registry.make_bzrdir('knit')
307
341
        self.make_repository('.', shared=True, format=format)
308
342
        branch = bzrdir.BzrDir.create_branch_and_repo(
309
343
            self.get_url('child'), format=format)
313
347
    def test_create_branch_and_repo_under_shared_force_new(self):
314
348
        # creating a branch and repo in a shared repo can be forced to
315
349
        # make a new repo
316
 
        format = bzrdir.format_registry.make_bzrdir('knit')
 
350
        format = controldir.format_registry.make_bzrdir('knit')
317
351
        self.make_repository('.', shared=True, format=format)
318
352
        branch = bzrdir.BzrDir.create_branch_and_repo(self.get_url('child'),
319
353
                                                      force_new_repo=True,
333
367
 
334
368
    def test_create_standalone_working_tree_under_shared_repo(self):
335
369
        # create standalone working tree always makes a repo.
336
 
        format = bzrdir.format_registry.make_bzrdir('knit')
 
370
        format = controldir.format_registry.make_bzrdir('knit')
337
371
        self.make_repository('.', shared=True, format=format)
338
372
        # note this is deliberately readonly, as this failure should
339
373
        # occur before any writes.
346
380
 
347
381
    def test_create_branch_convenience(self):
348
382
        # outside a repo the default convenience output is a repo+branch_tree
349
 
        format = bzrdir.format_registry.make_bzrdir('knit')
 
383
        format = controldir.format_registry.make_bzrdir('knit')
350
384
        branch = bzrdir.BzrDir.create_branch_convenience('.', format=format)
351
385
        branch.bzrdir.open_workingtree()
352
386
        branch.bzrdir.open_repository()
353
387
 
354
388
    def test_create_branch_convenience_possible_transports(self):
355
389
        """Check that the optional 'possible_transports' is recognized"""
356
 
        format = bzrdir.format_registry.make_bzrdir('knit')
 
390
        format = controldir.format_registry.make_bzrdir('knit')
357
391
        t = self.get_transport()
358
392
        branch = bzrdir.BzrDir.create_branch_convenience(
359
393
            '.', format=format, possible_transports=[t])
364
398
        """Creating a branch at the root of a fs should work."""
365
399
        self.vfs_transport_factory = memory.MemoryServer
366
400
        # outside a repo the default convenience output is a repo+branch_tree
367
 
        format = bzrdir.format_registry.make_bzrdir('knit')
 
401
        format = controldir.format_registry.make_bzrdir('knit')
368
402
        branch = bzrdir.BzrDir.create_branch_convenience(self.get_url(),
369
403
                                                         format=format)
370
404
        self.assertRaises(errors.NoWorkingTree,
374
408
    def test_create_branch_convenience_under_shared_repo(self):
375
409
        # inside a repo the default convenience output is a branch+ follow the
376
410
        # repo tree policy
377
 
        format = bzrdir.format_registry.make_bzrdir('knit')
 
411
        format = controldir.format_registry.make_bzrdir('knit')
378
412
        self.make_repository('.', shared=True, format=format)
379
413
        branch = bzrdir.BzrDir.create_branch_convenience('child',
380
414
            format=format)
385
419
    def test_create_branch_convenience_under_shared_repo_force_no_tree(self):
386
420
        # inside a repo the default convenience output is a branch+ follow the
387
421
        # repo tree policy but we can override that
388
 
        format = bzrdir.format_registry.make_bzrdir('knit')
 
422
        format = controldir.format_registry.make_bzrdir('knit')
389
423
        self.make_repository('.', shared=True, format=format)
390
424
        branch = bzrdir.BzrDir.create_branch_convenience('child',
391
425
            force_new_tree=False, format=format)
397
431
    def test_create_branch_convenience_under_shared_repo_no_tree_policy(self):
398
432
        # inside a repo the default convenience output is a branch+ follow the
399
433
        # repo tree policy
400
 
        format = bzrdir.format_registry.make_bzrdir('knit')
 
434
        format = controldir.format_registry.make_bzrdir('knit')
401
435
        repo = self.make_repository('.', shared=True, format=format)
402
436
        repo.set_make_working_trees(False)
403
437
        branch = bzrdir.BzrDir.create_branch_convenience('child',
410
444
    def test_create_branch_convenience_under_shared_repo_no_tree_policy_force_tree(self):
411
445
        # inside a repo the default convenience output is a branch+ follow the
412
446
        # repo tree policy but we can override that
413
 
        format = bzrdir.format_registry.make_bzrdir('knit')
 
447
        format = controldir.format_registry.make_bzrdir('knit')
414
448
        repo = self.make_repository('.', shared=True, format=format)
415
449
        repo.set_make_working_trees(False)
416
450
        branch = bzrdir.BzrDir.create_branch_convenience('child',
422
456
    def test_create_branch_convenience_under_shared_repo_force_new_repo(self):
423
457
        # inside a repo the default convenience output is overridable to give
424
458
        # repo+branch+tree
425
 
        format = bzrdir.format_registry.make_bzrdir('knit')
 
459
        format = controldir.format_registry.make_bzrdir('knit')
426
460
        self.make_repository('.', shared=True, format=format)
427
461
        branch = bzrdir.BzrDir.create_branch_convenience('child',
428
462
            force_new_repo=True, format=format)
473
507
    def test_default_stacking_with_stackable_branch_unstackable_repo(self):
474
508
        # Make stackable source branch with an unstackable repo format.
475
509
        source_bzrdir = self.make_bzrdir('source')
476
 
        pack_repo.RepositoryFormatKnitPack1().initialize(source_bzrdir)
 
510
        knitpack_repo.RepositoryFormatKnitPack1().initialize(source_bzrdir)
477
511
        source_branch = bzrlib.branch.BzrBranchFormat7().initialize(
478
512
            source_bzrdir)
479
513
        # Make a directory with a default stacking policy
483
517
        # Clone source into directory
484
518
        target = source_bzrdir.clone(self.get_url('parent/target'))
485
519
 
 
520
    def test_format_initialize_on_transport_ex_stacked_on(self):
 
521
        # trunk is a stackable format.  Note that its in the same server area
 
522
        # which is what launchpad does, but not sufficient to exercise the
 
523
        # general case.
 
524
        trunk = self.make_branch('trunk', format='1.9')
 
525
        t = self.get_transport('stacked')
 
526
        old_fmt = controldir.format_registry.make_bzrdir('pack-0.92')
 
527
        repo_name = old_fmt.repository_format.network_name()
 
528
        # Should end up with a 1.9 format (stackable)
 
529
        repo, control, require_stacking, repo_policy = \
 
530
            old_fmt.initialize_on_transport_ex(t,
 
531
                    repo_format_name=repo_name, stacked_on='../trunk',
 
532
                    stack_on_pwd=t.base)
 
533
        if repo is not None:
 
534
            # Repositories are open write-locked
 
535
            self.assertTrue(repo.is_write_locked())
 
536
            self.addCleanup(repo.unlock)
 
537
        else:
 
538
            repo = control.open_repository()
 
539
        self.assertIsInstance(control, bzrdir.BzrDir)
 
540
        opened = bzrdir.BzrDir.open(t.base)
 
541
        if not isinstance(old_fmt, remote.RemoteBzrDirFormat):
 
542
            self.assertEqual(control._format.network_name(),
 
543
                old_fmt.network_name())
 
544
            self.assertEqual(control._format.network_name(),
 
545
                opened._format.network_name())
 
546
        self.assertEqual(control.__class__, opened.__class__)
 
547
        self.assertLength(1, repo._fallback_repositories)
 
548
 
486
549
    def test_sprout_obeys_stacking_policy(self):
487
550
        child_branch, new_child_transport = self.prepare_default_stacking()
488
551
        new_child = child_branch.bzrdir.sprout(new_child_transport.base)
679
742
        self.assertEqual(relpath, 'baz')
680
743
 
681
744
    def test_open_containing_from_transport(self):
682
 
        self.assertRaises(NotBranchError, bzrdir.BzrDir.open_containing_from_transport,
683
 
                          get_transport(self.get_readonly_url('')))
684
 
        self.assertRaises(NotBranchError, bzrdir.BzrDir.open_containing_from_transport,
685
 
                          get_transport(self.get_readonly_url('g/p/q')))
 
745
        self.assertRaises(NotBranchError,
 
746
            bzrdir.BzrDir.open_containing_from_transport,
 
747
            _mod_transport.get_transport_from_url(self.get_readonly_url('')))
 
748
        self.assertRaises(NotBranchError,
 
749
            bzrdir.BzrDir.open_containing_from_transport,
 
750
            _mod_transport.get_transport_from_url(
 
751
                self.get_readonly_url('g/p/q')))
686
752
        control = bzrdir.BzrDir.create(self.get_url())
687
753
        branch, relpath = bzrdir.BzrDir.open_containing_from_transport(
688
 
            get_transport(self.get_readonly_url('')))
 
754
            _mod_transport.get_transport_from_url(
 
755
                self.get_readonly_url('')))
689
756
        self.assertEqual('', relpath)
690
757
        branch, relpath = bzrdir.BzrDir.open_containing_from_transport(
691
 
            get_transport(self.get_readonly_url('g/p/q')))
 
758
            _mod_transport.get_transport_from_url(
 
759
                self.get_readonly_url('g/p/q')))
692
760
        self.assertEqual('g/p/q', relpath)
693
761
 
694
762
    def test_open_containing_tree_or_branch(self):
738
806
        # transport pointing at bzrdir should give a bzrdir with root transport
739
807
        # set to the given transport
740
808
        control = bzrdir.BzrDir.create(self.get_url())
741
 
        transport = get_transport(self.get_url())
742
 
        opened_bzrdir = bzrdir.BzrDir.open_from_transport(transport)
743
 
        self.assertEqual(transport.base, opened_bzrdir.root_transport.base)
 
809
        t = self.get_transport()
 
810
        opened_bzrdir = bzrdir.BzrDir.open_from_transport(t)
 
811
        self.assertEqual(t.base, opened_bzrdir.root_transport.base)
744
812
        self.assertIsInstance(opened_bzrdir, bzrdir.BzrDir)
745
813
 
746
814
    def test_open_from_transport_no_bzrdir(self):
747
 
        transport = get_transport(self.get_url())
748
 
        self.assertRaises(NotBranchError, bzrdir.BzrDir.open_from_transport,
749
 
                          transport)
 
815
        t = self.get_transport()
 
816
        self.assertRaises(NotBranchError, bzrdir.BzrDir.open_from_transport, t)
750
817
 
751
818
    def test_open_from_transport_bzrdir_in_parent(self):
752
819
        control = bzrdir.BzrDir.create(self.get_url())
753
 
        transport = get_transport(self.get_url())
754
 
        transport.mkdir('subdir')
755
 
        transport = transport.clone('subdir')
756
 
        self.assertRaises(NotBranchError, bzrdir.BzrDir.open_from_transport,
757
 
                          transport)
 
820
        t = self.get_transport()
 
821
        t.mkdir('subdir')
 
822
        t = t.clone('subdir')
 
823
        self.assertRaises(NotBranchError, bzrdir.BzrDir.open_from_transport, t)
758
824
 
759
825
    def test_sprout_recursive(self):
760
826
        tree = self.make_branch_and_tree('tree1',
761
 
                                         format='dirstate-with-subtree')
 
827
                                         format='development-subtree')
762
828
        sub_tree = self.make_branch_and_tree('tree1/subtree',
763
 
            format='dirstate-with-subtree')
 
829
            format='development-subtree')
764
830
        sub_tree.set_root_id('subtree-root')
765
831
        tree.add_reference(sub_tree)
766
832
        self.build_tree(['tree1/subtree/file'])
769
835
        tree2 = tree.bzrdir.sprout('tree2').open_workingtree()
770
836
        tree2.lock_read()
771
837
        self.addCleanup(tree2.unlock)
772
 
        self.failUnlessExists('tree2/subtree/file')
 
838
        self.assertPathExists('tree2/subtree/file')
773
839
        self.assertEqual('tree-reference', tree2.kind('subtree-root'))
774
840
 
775
841
    def test_cloning_metadir(self):
779
845
        branch = self.make_branch('branch', format='knit')
780
846
        format = branch.bzrdir.cloning_metadir()
781
847
        self.assertIsInstance(format.workingtree_format,
782
 
            workingtree.WorkingTreeFormat3)
 
848
            workingtree_4.WorkingTreeFormat6)
783
849
 
784
850
    def test_sprout_recursive_treeless(self):
785
851
        tree = self.make_branch_and_tree('tree1',
786
 
            format='dirstate-with-subtree')
 
852
            format='development-subtree')
787
853
        sub_tree = self.make_branch_and_tree('tree1/subtree',
788
 
            format='dirstate-with-subtree')
 
854
            format='development-subtree')
789
855
        tree.add_reference(sub_tree)
790
856
        self.build_tree(['tree1/subtree/file'])
791
857
        sub_tree.add('file')
792
858
        tree.commit('Initial commit')
 
859
        # The following line force the orhaning to reveal bug #634470
 
860
        tree.branch.get_config_stack().set(
 
861
            'bzr.transform.orphan_policy', 'move')
793
862
        tree.bzrdir.destroy_workingtree()
 
863
        # FIXME: subtree/.bzr is left here which allows the test to pass (or
 
864
        # fail :-( ) -- vila 20100909
794
865
        repo = self.make_repository('repo', shared=True,
795
 
            format='dirstate-with-subtree')
 
866
            format='development-subtree')
796
867
        repo.set_make_working_trees(False)
797
 
        tree.bzrdir.sprout('repo/tree2')
798
 
        self.failUnlessExists('repo/tree2/subtree')
799
 
        self.failIfExists('repo/tree2/subtree/file')
 
868
        # FIXME: we just deleted the workingtree and now we want to use it ????
 
869
        # At a minimum, we should use tree.branch below (but this fails too
 
870
        # currently) or stop calling this test 'treeless'. Specifically, I've
 
871
        # turn the line below into an assertRaises when 'subtree/.bzr' is
 
872
        # orphaned and sprout tries to access the branch there (which is left
 
873
        # by bzrdir.BzrDirMeta1.destroy_workingtree when it ignores the
 
874
        # [DeletingParent('Not deleting', u'subtree', None)] conflict). See bug
 
875
        # #634470.  -- vila 20100909
 
876
        self.assertRaises(errors.NotBranchError,
 
877
                          tree.bzrdir.sprout, 'repo/tree2')
 
878
#        self.assertPathExists('repo/tree2/subtree')
 
879
#        self.assertPathDoesNotExist('repo/tree2/subtree/file')
800
880
 
801
881
    def make_foo_bar_baz(self):
802
882
        foo = bzrdir.BzrDir.create_branch_convenience('foo').bzrdir
806
886
 
807
887
    def test_find_bzrdirs(self):
808
888
        foo, bar, baz = self.make_foo_bar_baz()
809
 
        transport = get_transport(self.get_url())
810
 
        self.assertEqualBzrdirs([baz, foo, bar],
811
 
                                bzrdir.BzrDir.find_bzrdirs(transport))
 
889
        t = self.get_transport()
 
890
        self.assertEqualBzrdirs([baz, foo, bar], bzrdir.BzrDir.find_bzrdirs(t))
812
891
 
813
892
    def make_fake_permission_denied_transport(self, transport, paths):
814
893
        """Create a transport that raises PermissionDenied for some paths."""
830
909
 
831
910
    def test_find_bzrdirs_permission_denied(self):
832
911
        foo, bar, baz = self.make_foo_bar_baz()
833
 
        transport = get_transport(self.get_url())
 
912
        t = self.get_transport()
834
913
        path_filter_server, path_filter_transport = \
835
 
            self.make_fake_permission_denied_transport(transport, ['foo'])
 
914
            self.make_fake_permission_denied_transport(t, ['foo'])
836
915
        # local transport
837
916
        self.assertBranchUrlsEndWith('/baz/',
838
917
            bzrdir.BzrDir.find_bzrdirs(path_filter_transport))
847
926
            return [s for s in transport.list_dir('') if s != 'baz']
848
927
 
849
928
        foo, bar, baz = self.make_foo_bar_baz()
850
 
        transport = get_transport(self.get_url())
851
 
        self.assertEqualBzrdirs([foo, bar],
852
 
                                bzrdir.BzrDir.find_bzrdirs(transport,
853
 
                                    list_current=list_current))
 
929
        t = self.get_transport()
 
930
        self.assertEqualBzrdirs(
 
931
            [foo, bar],
 
932
            bzrdir.BzrDir.find_bzrdirs(t, list_current=list_current))
854
933
 
855
934
    def test_find_bzrdirs_evaluate(self):
856
935
        def evaluate(bzrdir):
857
936
            try:
858
937
                repo = bzrdir.open_repository()
859
 
            except NoRepositoryPresent:
 
938
            except errors.NoRepositoryPresent:
860
939
                return True, bzrdir.root_transport.base
861
940
            else:
862
941
                return False, bzrdir.root_transport.base
863
942
 
864
943
        foo, bar, baz = self.make_foo_bar_baz()
865
 
        transport = get_transport(self.get_url())
 
944
        t = self.get_transport()
866
945
        self.assertEqual([baz.root_transport.base, foo.root_transport.base],
867
 
                         list(bzrdir.BzrDir.find_bzrdirs(transport,
868
 
                                                         evaluate=evaluate)))
 
946
                         list(bzrdir.BzrDir.find_bzrdirs(t, evaluate=evaluate)))
869
947
 
870
948
    def assertEqualBzrdirs(self, first, second):
871
949
        first = list(first)
878
956
        root = self.make_repository('', shared=True)
879
957
        foo, bar, baz = self.make_foo_bar_baz()
880
958
        qux = self.make_bzrdir('foo/qux')
881
 
        transport = get_transport(self.get_url())
882
 
        branches = bzrdir.BzrDir.find_branches(transport)
 
959
        t = self.get_transport()
 
960
        branches = bzrdir.BzrDir.find_branches(t)
883
961
        self.assertEqual(baz.root_transport.base, branches[0].base)
884
962
        self.assertEqual(foo.root_transport.base, branches[1].base)
885
963
        self.assertEqual(bar.root_transport.base, branches[2].base)
886
964
 
887
965
        # ensure this works without a top-level repo
888
 
        branches = bzrdir.BzrDir.find_branches(transport.clone('foo'))
 
966
        branches = bzrdir.BzrDir.find_branches(t.clone('foo'))
889
967
        self.assertEqual(foo.root_transport.base, branches[0].base)
890
968
        self.assertEqual(bar.root_transport.base, branches[1].base)
891
969
 
893
971
class TestMissingRepoBranchesSkipped(TestCaseWithMemoryTransport):
894
972
 
895
973
    def test_find_bzrdirs_missing_repo(self):
896
 
        transport = get_transport(self.get_url())
 
974
        t = self.get_transport()
897
975
        arepo = self.make_repository('arepo', shared=True)
898
976
        abranch_url = arepo.user_url + '/abranch'
899
977
        abranch = bzrdir.BzrDir.create(abranch_url).create_branch()
900
 
        transport.delete_tree('arepo/.bzr')
 
978
        t.delete_tree('arepo/.bzr')
901
979
        self.assertRaises(errors.NoRepositoryPresent,
902
980
            branch.Branch.open, abranch_url)
903
981
        self.make_branch('baz')
904
 
        for actual_bzrdir in bzrdir.BzrDir.find_branches(transport):
 
982
        for actual_bzrdir in bzrdir.BzrDir.find_branches(t):
905
983
            self.assertEndsWith(actual_bzrdir.user_url, '/baz/')
906
984
 
907
985
 
914
992
        branch_base = t.clone('branch').base
915
993
        self.assertEqual(branch_base, dir.get_branch_transport(None).base)
916
994
        self.assertEqual(branch_base,
917
 
                         dir.get_branch_transport(bzrlib.branch.BzrBranchFormat5()).base)
 
995
                         dir.get_branch_transport(BzrBranchFormat5()).base)
918
996
        repository_base = t.clone('repository').base
919
997
        self.assertEqual(repository_base, dir.get_repository_transport(None).base)
 
998
        repository_format = repository.format_registry.get_default()
920
999
        self.assertEqual(repository_base,
921
 
                         dir.get_repository_transport(weaverepo.RepositoryFormat7()).base)
 
1000
                         dir.get_repository_transport(repository_format).base)
922
1001
        checkout_base = t.clone('checkout').base
923
1002
        self.assertEqual(checkout_base, dir.get_workingtree_transport(None).base)
924
1003
        self.assertEqual(checkout_base,
925
 
                         dir.get_workingtree_transport(workingtree.WorkingTreeFormat3()).base)
 
1004
                         dir.get_workingtree_transport(workingtree_3.WorkingTreeFormat3()).base)
926
1005
 
927
1006
    def test_meta1dir_uses_lockdir(self):
928
1007
        """Meta1 format uses a LockDir to guard the whole directory, not a file."""
936
1015
        Metadirs should compare equal iff they have the same repo, branch and
937
1016
        tree formats.
938
1017
        """
939
 
        mydir = bzrdir.format_registry.make_bzrdir('knit')
 
1018
        mydir = controldir.format_registry.make_bzrdir('knit')
940
1019
        self.assertEqual(mydir, mydir)
941
1020
        self.assertFalse(mydir != mydir)
942
 
        otherdir = bzrdir.format_registry.make_bzrdir('knit')
 
1021
        otherdir = controldir.format_registry.make_bzrdir('knit')
943
1022
        self.assertEqual(otherdir, mydir)
944
1023
        self.assertFalse(otherdir != mydir)
945
 
        otherdir2 = bzrdir.format_registry.make_bzrdir('dirstate-with-subtree')
 
1024
        otherdir2 = controldir.format_registry.make_bzrdir('development-subtree')
946
1025
        self.assertNotEqual(otherdir2, mydir)
947
1026
        self.assertFalse(otherdir2 == mydir)
948
1027
 
 
1028
    def test_with_features(self):
 
1029
        tree = self.make_branch_and_tree('tree', format='2a')
 
1030
        tree.bzrdir.update_feature_flags({"bar": "required"})
 
1031
        self.assertRaises(errors.MissingFeature, bzrdir.BzrDir.open, 'tree')
 
1032
        bzrdir.BzrDirMetaFormat1.register_feature('bar')
 
1033
        self.addCleanup(bzrdir.BzrDirMetaFormat1.unregister_feature, 'bar')
 
1034
        dir = bzrdir.BzrDir.open('tree')
 
1035
        self.assertEquals("required", dir._format.features.get("bar"))
 
1036
        tree.bzrdir.update_feature_flags({"bar": None, "nonexistant": None})
 
1037
        dir = bzrdir.BzrDir.open('tree')
 
1038
        self.assertEquals({}, dir._format.features)
 
1039
 
949
1040
    def test_needs_conversion_different_working_tree(self):
950
1041
        # meta1dirs need an conversion if any element is not the default.
951
 
        new_format = bzrdir.format_registry.make_bzrdir('dirstate')
 
1042
        new_format = controldir.format_registry.make_bzrdir('dirstate')
952
1043
        tree = self.make_branch_and_tree('tree', format='knit')
953
1044
        self.assertTrue(tree.bzrdir.needs_format_conversion(
954
1045
            new_format))
955
1046
 
956
1047
    def test_initialize_on_format_uses_smart_transport(self):
957
1048
        self.setup_smart_server_with_call_log()
958
 
        new_format = bzrdir.format_registry.make_bzrdir('dirstate')
 
1049
        new_format = controldir.format_registry.make_bzrdir('dirstate')
959
1050
        transport = self.get_transport('target')
960
1051
        transport.ensure_base()
961
1052
        self.reset_smart_call_log()
970
1061
        self.assertEqual(2, rpc_count)
971
1062
 
972
1063
 
973
 
class TestFormat5(TestCaseWithTransport):
974
 
    """Tests specific to the version 5 bzrdir format."""
975
 
 
976
 
    def test_same_lockfiles_between_tree_repo_branch(self):
977
 
        # this checks that only a single lockfiles instance is created
978
 
        # for format 5 objects
979
 
        dir = bzrdir.BzrDirFormat5().initialize(self.get_url())
980
 
        def check_dir_components_use_same_lock(dir):
981
 
            ctrl_1 = dir.open_repository().control_files
982
 
            ctrl_2 = dir.open_branch().control_files
983
 
            ctrl_3 = dir.open_workingtree()._control_files
984
 
            self.assertTrue(ctrl_1 is ctrl_2)
985
 
            self.assertTrue(ctrl_2 is ctrl_3)
986
 
        check_dir_components_use_same_lock(dir)
987
 
        # and if we open it normally.
988
 
        dir = bzrdir.BzrDir.open(self.get_url())
989
 
        check_dir_components_use_same_lock(dir)
990
 
 
991
 
    def test_can_convert(self):
992
 
        # format 5 dirs are convertable
993
 
        dir = bzrdir.BzrDirFormat5().initialize(self.get_url())
994
 
        self.assertTrue(dir.can_convert_format())
995
 
 
996
 
    def test_needs_conversion(self):
997
 
        # format 5 dirs need a conversion if they are not the default,
998
 
        # and they aren't
999
 
        dir = bzrdir.BzrDirFormat5().initialize(self.get_url())
1000
 
        # don't need to convert it to itself
1001
 
        self.assertFalse(dir.needs_format_conversion(bzrdir.BzrDirFormat5()))
1002
 
        # do need to convert it to the current default
1003
 
        self.assertTrue(dir.needs_format_conversion(
1004
 
            bzrdir.BzrDirFormat.get_default_format()))
1005
 
 
1006
 
 
1007
 
class TestFormat6(TestCaseWithTransport):
1008
 
    """Tests specific to the version 6 bzrdir format."""
1009
 
 
1010
 
    def test_same_lockfiles_between_tree_repo_branch(self):
1011
 
        # this checks that only a single lockfiles instance is created
1012
 
        # for format 6 objects
1013
 
        dir = bzrdir.BzrDirFormat6().initialize(self.get_url())
1014
 
        def check_dir_components_use_same_lock(dir):
1015
 
            ctrl_1 = dir.open_repository().control_files
1016
 
            ctrl_2 = dir.open_branch().control_files
1017
 
            ctrl_3 = dir.open_workingtree()._control_files
1018
 
            self.assertTrue(ctrl_1 is ctrl_2)
1019
 
            self.assertTrue(ctrl_2 is ctrl_3)
1020
 
        check_dir_components_use_same_lock(dir)
1021
 
        # and if we open it normally.
1022
 
        dir = bzrdir.BzrDir.open(self.get_url())
1023
 
        check_dir_components_use_same_lock(dir)
1024
 
 
1025
 
    def test_can_convert(self):
1026
 
        # format 6 dirs are convertable
1027
 
        dir = bzrdir.BzrDirFormat6().initialize(self.get_url())
1028
 
        self.assertTrue(dir.can_convert_format())
1029
 
 
1030
 
    def test_needs_conversion(self):
1031
 
        # format 6 dirs need an conversion if they are not the default.
1032
 
        dir = bzrdir.BzrDirFormat6().initialize(self.get_url())
1033
 
        self.assertTrue(dir.needs_format_conversion(
1034
 
            bzrdir.BzrDirFormat.get_default_format()))
1035
 
 
1036
 
 
1037
 
class NotBzrDir(bzrlib.bzrdir.BzrDir):
1038
 
    """A non .bzr based control directory."""
1039
 
 
1040
 
    def __init__(self, transport, format):
1041
 
        self._format = format
1042
 
        self.root_transport = transport
1043
 
        self.transport = transport.clone('.not')
1044
 
 
1045
 
 
1046
 
class NotBzrDirFormat(bzrlib.bzrdir.BzrDirFormat):
1047
 
    """A test class representing any non-.bzr based disk format."""
1048
 
 
1049
 
    def initialize_on_transport(self, transport):
1050
 
        """Initialize a new .not dir in the base directory of a Transport."""
1051
 
        transport.mkdir('.not')
1052
 
        return self.open(transport)
1053
 
 
1054
 
    def open(self, transport):
1055
 
        """Open this directory."""
1056
 
        return NotBzrDir(transport, self)
1057
 
 
1058
 
    @classmethod
1059
 
    def _known_formats(self):
1060
 
        return set([NotBzrDirFormat()])
1061
 
 
1062
 
 
1063
 
class NotBzrDirProber(controldir.Prober):
1064
 
 
1065
 
    def probe_transport(self, transport):
1066
 
        """Our format is present if the transport ends in '.not/'."""
1067
 
        if transport.has('.not'):
1068
 
            return NotBzrDirFormat()
1069
 
 
1070
 
 
1071
 
class TestNotBzrDir(TestCaseWithTransport):
1072
 
    """Tests for using the bzrdir api with a non .bzr based disk format.
1073
 
 
1074
 
    If/when one of these is in the core, we can let the implementation tests
1075
 
    verify this works.
1076
 
    """
1077
 
 
1078
 
    def test_create_and_find_format(self):
1079
 
        # create a .notbzr dir
1080
 
        format = NotBzrDirFormat()
1081
 
        dir = format.initialize(self.get_url())
1082
 
        self.assertIsInstance(dir, NotBzrDir)
1083
 
        # now probe for it.
1084
 
        controldir.ControlDirFormat.register_prober(NotBzrDirProber)
1085
 
        try:
1086
 
            found = bzrlib.bzrdir.BzrDirFormat.find_format(
1087
 
                get_transport(self.get_url()))
1088
 
            self.assertIsInstance(found, NotBzrDirFormat)
1089
 
        finally:
1090
 
            controldir.ControlDirFormat.unregister_prober(NotBzrDirProber)
1091
 
 
1092
 
    def test_included_in_known_formats(self):
1093
 
        not_format = NotBzrDirFormat()
1094
 
        bzrlib.controldir.ControlDirFormat.register_format(not_format)
1095
 
        try:
1096
 
            formats = bzrlib.bzrdir.BzrDirFormat.known_formats()
1097
 
            for format in formats:
1098
 
                if isinstance(format, NotBzrDirFormat):
1099
 
                    return
1100
 
            self.fail("No NotBzrDirFormat in %s" % formats)
1101
 
        finally:
1102
 
            bzrlib.controldir.ControlDirFormat.unregister_format(not_format)
1103
 
 
1104
 
 
1105
1064
class NonLocalTests(TestCaseWithTransport):
1106
1065
    """Tests for bzrdir static behaviour on non local paths."""
1107
1066
 
1111
1070
 
1112
1071
    def test_create_branch_convenience(self):
1113
1072
        # outside a repo the default convenience output is a repo+branch_tree
1114
 
        format = bzrdir.format_registry.make_bzrdir('knit')
 
1073
        format = controldir.format_registry.make_bzrdir('knit')
1115
1074
        branch = bzrdir.BzrDir.create_branch_convenience(
1116
1075
            self.get_url('foo'), format=format)
1117
1076
        self.assertRaises(errors.NoWorkingTree,
1120
1079
 
1121
1080
    def test_create_branch_convenience_force_tree_not_local_fails(self):
1122
1081
        # outside a repo the default convenience output is a repo+branch_tree
1123
 
        format = bzrdir.format_registry.make_bzrdir('knit')
 
1082
        format = controldir.format_registry.make_bzrdir('knit')
1124
1083
        self.assertRaises(errors.NotLocalUrl,
1125
1084
            bzrdir.BzrDir.create_branch_convenience,
1126
1085
            self.get_url('foo'),
1127
1086
            force_new_tree=True,
1128
1087
            format=format)
1129
 
        t = get_transport(self.get_url('.'))
 
1088
        t = self.get_transport()
1130
1089
        self.assertFalse(t.has('foo'))
1131
1090
 
1132
1091
    def test_clone(self):
1133
1092
        # clone into a nonlocal path works
1134
 
        format = bzrdir.format_registry.make_bzrdir('knit')
 
1093
        format = controldir.format_registry.make_bzrdir('knit')
1135
1094
        branch = bzrdir.BzrDir.create_branch_convenience('local',
1136
1095
                                                         format=format)
1137
1096
        branch.bzrdir.open_workingtree()
1148
1107
        my_bzrdir = bzrdir.BzrDir.open(self.get_url('branch-knit2'))
1149
1108
        checkout_format = my_bzrdir.checkout_metadir()
1150
1109
        self.assertIsInstance(checkout_format.workingtree_format,
1151
 
                              workingtree.WorkingTreeFormat3)
 
1110
                              workingtree_4.WorkingTreeFormat4)
1152
1111
 
1153
1112
 
1154
1113
class TestHTTPRedirections(object):
1298
1257
 
1299
1258
    def __init__(self, *args, **kwargs):
1300
1259
        super(_TestBzrDir, self).__init__(*args, **kwargs)
1301
 
        self.test_branch = _TestBranch()
 
1260
        self.test_branch = _TestBranch(self.transport)
1302
1261
        self.test_branch.repository = self.create_repository()
1303
1262
 
1304
 
    def open_branch(self, unsupported=False):
 
1263
    def open_branch(self, unsupported=False, possible_transports=None):
1305
1264
        return self.test_branch
1306
1265
 
1307
1266
    def cloning_metadir(self, require_stacking=False):
1315
1274
class _TestBranch(bzrlib.branch.Branch):
1316
1275
    """Test Branch implementation for TestBzrDirSprout."""
1317
1276
 
1318
 
    def __init__(self, *args, **kwargs):
 
1277
    def __init__(self, transport, *args, **kwargs):
1319
1278
        self._format = _TestBranchFormat()
 
1279
        self._transport = transport
 
1280
        self.base = transport.base
1320
1281
        super(_TestBranch, self).__init__(*args, **kwargs)
1321
1282
        self.calls = []
1322
1283
        self._parent = None
1323
1284
 
1324
1285
    def sprout(self, *args, **kwargs):
1325
1286
        self.calls.append('sprout')
1326
 
        return _TestBranch()
 
1287
        return _TestBranch(self._transport)
1327
1288
 
1328
1289
    def copy_content_into(self, destination, revision_id=None):
1329
1290
        self.calls.append('copy_content_into')
1330
1291
 
 
1292
    def last_revision(self):
 
1293
        return _mod_revision.NULL_REVISION
 
1294
 
1331
1295
    def get_parent(self):
1332
1296
        return self._parent
1333
1297
 
 
1298
    def _get_config(self):
 
1299
        return config.TransportConfig(self._transport, 'branch.conf')
 
1300
 
 
1301
    def _get_config_store(self):
 
1302
        return config.BranchStore(self)
 
1303
 
1334
1304
    def set_parent(self, parent):
1335
1305
        self._parent = parent
1336
1306
 
 
1307
    def lock_read(self):
 
1308
        return lock.LogicalLockResult(self.unlock)
 
1309
 
 
1310
    def unlock(self):
 
1311
        return
 
1312
 
1337
1313
 
1338
1314
class TestBzrDirSprout(TestCaseWithMemoryTransport):
1339
1315
 
1395
1371
        self.assertEqual('fail', err._preformatted_string)
1396
1372
 
1397
1373
    def test_post_repo_init(self):
1398
 
        from bzrlib.bzrdir import RepoInitHookParams
 
1374
        from bzrlib.controldir import RepoInitHookParams
1399
1375
        calls = []
1400
1376
        bzrdir.BzrDir.hooks.install_named_hook('post_repo_init',
1401
1377
            calls.append, None)
1417
1393
 
1418
1394
 
1419
1395
class TestGenerateBackupName(TestCaseWithMemoryTransport):
 
1396
    # FIXME: This may need to be unified with test_osutils.TestBackupNames or
 
1397
    # moved to per_bzrdir or per_transport for better coverage ?
 
1398
    # -- vila 20100909
1420
1399
 
1421
1400
    def setUp(self):
1422
1401
        super(TestGenerateBackupName, self).setUp()
1423
 
        self._transport = get_transport(self.get_url())
 
1402
        self._transport = self.get_transport()
1424
1403
        bzrdir.BzrDir.create(self.get_url(),
1425
1404
            possible_transports=[self._transport])
1426
1405
        self._bzrdir = bzrdir.BzrDir.open_from_transport(self._transport)
1427
1406
 
1428
1407
    def test_new(self):
1429
 
        self.assertEqual("a.~1~", self._bzrdir.generate_backup_name("a"))
 
1408
        self.assertEqual("a.~1~", self._bzrdir._available_backup_name("a"))
1430
1409
 
1431
1410
    def test_exiting(self):
1432
1411
        self._transport.put_bytes("a.~1~", "some content")
1433
 
        self.assertEqual("a.~2~", self._bzrdir.generate_backup_name("a"))
 
1412
        self.assertEqual("a.~2~", self._bzrdir._available_backup_name("a"))
 
1413
 
 
1414
 
 
1415
class TestMeta1DirColoFormat(TestCaseWithTransport):
 
1416
    """Tests specific to the meta1 dir with colocated branches format."""
 
1417
 
 
1418
    def test_supports_colo(self):
 
1419
        format = bzrdir.BzrDirMetaFormat1Colo()
 
1420
        self.assertTrue(format.colocated_branches)
 
1421
 
 
1422
    def test_upgrade_from_2a(self):
 
1423
        tree = self.make_branch_and_tree('.', format='2a')
 
1424
        format = bzrdir.BzrDirMetaFormat1Colo()
 
1425
        self.assertTrue(tree.bzrdir.needs_format_conversion(format))
 
1426
        converter = tree.bzrdir._format.get_converter(format)
 
1427
        result = converter.convert(tree.bzrdir, None)
 
1428
        self.assertIsInstance(result._format, bzrdir.BzrDirMetaFormat1Colo)
 
1429
        self.assertFalse(result.needs_format_conversion(format))
 
1430
 
 
1431
    def test_downgrade_to_2a(self):
 
1432
        tree = self.make_branch_and_tree('.', format='development-colo')
 
1433
        format = bzrdir.BzrDirMetaFormat1()
 
1434
        self.assertTrue(tree.bzrdir.needs_format_conversion(format))
 
1435
        converter = tree.bzrdir._format.get_converter(format)
 
1436
        result = converter.convert(tree.bzrdir, None)
 
1437
        self.assertIsInstance(result._format, bzrdir.BzrDirMetaFormat1)
 
1438
        self.assertFalse(result.needs_format_conversion(format))
 
1439
 
 
1440
    def test_downgrade_to_2a_too_many_branches(self):
 
1441
        tree = self.make_branch_and_tree('.', format='development-colo')
 
1442
        tree.bzrdir.create_branch(name="another-colocated-branch")
 
1443
        converter = tree.bzrdir._format.get_converter(
 
1444
            bzrdir.BzrDirMetaFormat1())
 
1445
        result = converter.convert(tree.bzrdir, bzrdir.BzrDirMetaFormat1())
 
1446
        self.assertIsInstance(result._format, bzrdir.BzrDirMetaFormat1)
 
1447
 
 
1448
    def test_nested(self):
 
1449
        tree = self.make_branch_and_tree('.', format='development-colo')
 
1450
        tree.bzrdir.create_branch(name='foo')
 
1451
        tree.bzrdir.create_branch(name='fool/bla')
 
1452
        self.assertRaises(
 
1453
            errors.ParentBranchExists, tree.bzrdir.create_branch,
 
1454
            name='foo/bar')
 
1455
 
 
1456
    def test_parent(self):
 
1457
        tree = self.make_branch_and_tree('.', format='development-colo')
 
1458
        tree.bzrdir.create_branch(name='fool/bla')
 
1459
        tree.bzrdir.create_branch(name='foo/bar')
 
1460
        self.assertRaises(
 
1461
            errors.AlreadyBranchError, tree.bzrdir.create_branch,
 
1462
            name='foo')
 
1463
 
 
1464
 
 
1465
class SampleBzrFormat(bzrdir.BzrFormat):
 
1466
 
 
1467
    @classmethod
 
1468
    def get_format_string(cls):
 
1469
        return "First line\n"
 
1470
 
 
1471
 
 
1472
class TestBzrFormat(TestCase):
 
1473
    """Tests for BzrFormat."""
 
1474
 
 
1475
    def test_as_string(self):
 
1476
        format = SampleBzrFormat()
 
1477
        format.features = {"foo": "required"}
 
1478
        self.assertEquals(format.as_string(),
 
1479
            "First line\n"
 
1480
            "required foo\n")
 
1481
        format.features["another"] = "optional"
 
1482
        self.assertEquals(format.as_string(),
 
1483
            "First line\n"
 
1484
            "required foo\n"
 
1485
            "optional another\n")
 
1486
 
 
1487
    def test_network_name(self):
 
1488
        # The network string should include the feature info
 
1489
        format = SampleBzrFormat()
 
1490
        format.features = {"foo": "required"}
 
1491
        self.assertEquals(
 
1492
            "First line\nrequired foo\n",
 
1493
            format.network_name())
 
1494
 
 
1495
    def test_from_string_no_features(self):
 
1496
        # No features
 
1497
        format = SampleBzrFormat.from_string(
 
1498
            "First line\n")
 
1499
        self.assertEquals({}, format.features)
 
1500
 
 
1501
    def test_from_string_with_feature(self):
 
1502
        # Proper feature
 
1503
        format = SampleBzrFormat.from_string(
 
1504
            "First line\nrequired foo\n")
 
1505
        self.assertEquals("required", format.features.get("foo"))
 
1506
 
 
1507
    def test_from_string_format_string_mismatch(self):
 
1508
        # The first line has to match the format string
 
1509
        self.assertRaises(AssertionError, SampleBzrFormat.from_string,
 
1510
            "Second line\nrequired foo\n")
 
1511
 
 
1512
    def test_from_string_missing_space(self):
 
1513
        # At least one space is required in the feature lines
 
1514
        self.assertRaises(errors.ParseFormatError, SampleBzrFormat.from_string,
 
1515
            "First line\nfoo\n")
 
1516
 
 
1517
    def test_from_string_with_spaces(self):
 
1518
        # Feature with spaces (in case we add stuff like this in the future)
 
1519
        format = SampleBzrFormat.from_string(
 
1520
            "First line\nrequired foo with spaces\n")
 
1521
        self.assertEquals("required", format.features.get("foo with spaces"))
 
1522
 
 
1523
    def test_eq(self):
 
1524
        format1 = SampleBzrFormat()
 
1525
        format1.features = {"nested-trees": "optional"}
 
1526
        format2 = SampleBzrFormat()
 
1527
        format2.features = {"nested-trees": "optional"}
 
1528
        self.assertEquals(format1, format1)
 
1529
        self.assertEquals(format1, format2)
 
1530
        format3 = SampleBzrFormat()
 
1531
        self.assertNotEquals(format1, format3)
 
1532
 
 
1533
    def test_check_support_status_optional(self):
 
1534
        # Optional, so silently ignore
 
1535
        format = SampleBzrFormat()
 
1536
        format.features = {"nested-trees": "optional"}
 
1537
        format.check_support_status(True)
 
1538
        self.addCleanup(SampleBzrFormat.unregister_feature, "nested-trees")
 
1539
        SampleBzrFormat.register_feature("nested-trees")
 
1540
        format.check_support_status(True)
 
1541
 
 
1542
    def test_check_support_status_required(self):
 
1543
        # Optional, so trigger an exception
 
1544
        format = SampleBzrFormat()
 
1545
        format.features = {"nested-trees": "required"}
 
1546
        self.assertRaises(errors.MissingFeature, format.check_support_status,
 
1547
            True)
 
1548
        self.addCleanup(SampleBzrFormat.unregister_feature, "nested-trees")
 
1549
        SampleBzrFormat.register_feature("nested-trees")
 
1550
        format.check_support_status(True)
 
1551
 
 
1552
    def test_check_support_status_unknown(self):
 
1553
        # treat unknown necessity as required
 
1554
        format = SampleBzrFormat()
 
1555
        format.features = {"nested-trees": "unknown"}
 
1556
        self.assertRaises(errors.MissingFeature, format.check_support_status,
 
1557
            True)
 
1558
        self.addCleanup(SampleBzrFormat.unregister_feature, "nested-trees")
 
1559
        SampleBzrFormat.register_feature("nested-trees")
 
1560
        format.check_support_status(True)
 
1561
 
 
1562
    def test_feature_already_registered(self):
 
1563
        # a feature can only be registered once
 
1564
        self.addCleanup(SampleBzrFormat.unregister_feature, "nested-trees")
 
1565
        SampleBzrFormat.register_feature("nested-trees")
 
1566
        self.assertRaises(errors.FeatureAlreadyRegistered,
 
1567
            SampleBzrFormat.register_feature, "nested-trees")
 
1568
 
 
1569
    def test_feature_with_space(self):
 
1570
        # spaces are not allowed in feature names
 
1571
        self.assertRaises(ValueError, SampleBzrFormat.register_feature,
 
1572
            "nested trees")