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
17
17
"""Tests for the BzrDir facility and any format specific tests.
19
For interface contract tests, see tests/per_bzr_dir.
19
For interface contract tests, see tests/bzr_dir_implementations.
23
from StringIO import StringIO
26
25
from bzrlib import (
34
revision as _mod_revision,
38
transport as _mod_transport,
44
34
import bzrlib.branch
45
from bzrlib.errors import (
47
NoColocatedBranchSupport,
49
UnsupportedFormatError,
35
from bzrlib.errors import (NotBranchError,
37
UnsupportedFormatError,
51
39
from bzrlib.tests import (
53
TestCaseWithMemoryTransport,
54
41
TestCaseWithTransport,
57
from bzrlib.tests import(
44
from bzrlib.tests.HttpServer import HttpServer
45
from bzrlib.tests.HTTPTestUtil import (
46
TestCaseWithTwoWebservers,
47
HTTPServerRedirecting,
61
49
from bzrlib.tests.test_http import TestWithTransport_pycurl
62
from bzrlib.transport import (
50
from bzrlib.transport import get_transport
66
51
from bzrlib.transport.http._urllib import HttpTransport_urllib
67
from bzrlib.transport.nosmart import NoSmartTransportDecorator
68
from bzrlib.transport.readonly import ReadonlyTransportDecorator
69
from bzrlib.repofmt import knitrepo, knitpack_repo
52
from bzrlib.transport.memory import MemoryServer
53
from bzrlib.repofmt import knitrepo, weaverepo
72
56
class TestDefaultFormat(TestCase):
74
58
def test_get_set_default_format(self):
75
59
old_format = bzrdir.BzrDirFormat.get_default_format()
76
# default is BzrDirMetaFormat1
77
self.assertIsInstance(old_format, bzrdir.BzrDirMetaFormat1)
78
controldir.ControlDirFormat._set_default_format(SampleBzrDirFormat())
60
# default is BzrDirFormat6
61
self.failUnless(isinstance(old_format, bzrdir.BzrDirMetaFormat1))
62
self.applyDeprecated(symbol_versioning.zero_fourteen,
63
bzrdir.BzrDirFormat.set_default_format,
79
65
# creating a bzr dir should now create an instrumented dir.
81
67
result = bzrdir.BzrDir.create('memory:///')
82
self.assertIsInstance(result, SampleBzrDir)
68
self.failUnless(isinstance(result, SampleBzrDir))
84
controldir.ControlDirFormat._set_default_format(old_format)
70
self.applyDeprecated(symbol_versioning.zero_fourteen,
71
bzrdir.BzrDirFormat.set_default_format, old_format)
85
72
self.assertEqual(old_format, bzrdir.BzrDirFormat.get_default_format())
88
class DeprecatedBzrDirFormat(bzrdir.BzrDirFormat):
89
"""A deprecated bzr dir format."""
92
75
class TestFormatRegistry(TestCase):
94
77
def make_format_registry(self):
95
my_format_registry = controldir.ControlDirFormatRegistry()
96
my_format_registry.register('deprecated', DeprecatedBzrDirFormat,
97
'Some format. Slower and unawesome and deprecated.',
99
my_format_registry.register_lazy('lazy', 'bzrlib.tests.test_bzrdir',
100
'DeprecatedBzrDirFormat', 'Format registered lazily',
102
bzrdir.register_metadir(my_format_registry, 'knit',
78
my_format_registry = bzrdir.BzrDirFormatRegistry()
79
my_format_registry.register('weave', bzrdir.BzrDirFormat6,
80
'Pre-0.8 format. Slower and does not support checkouts or shared'
81
' repositories', deprecated=True)
82
my_format_registry.register_lazy('lazy', 'bzrlib.bzrdir',
83
'BzrDirFormat6', 'Format registered lazily', deprecated=True)
84
my_format_registry.register_metadir('knit',
103
85
'bzrlib.repofmt.knitrepo.RepositoryFormatKnit1',
104
86
'Format using knits',
106
88
my_format_registry.set_default('knit')
107
bzrdir.register_metadir(my_format_registry,
89
my_format_registry.register_metadir(
109
91
'bzrlib.repofmt.knitrepo.RepositoryFormatKnit3',
110
92
'Experimental successor to knit. Use at your own risk.',
111
branch_format='bzrlib.branch.BzrBranchFormat6',
113
bzrdir.register_metadir(my_format_registry,
93
branch_format='bzrlib.branch.BzrBranchFormat6')
94
my_format_registry.register_metadir(
115
96
'bzrlib.repofmt.knitrepo.RepositoryFormatKnit3',
116
97
'Experimental successor to knit. Use at your own risk.',
117
98
branch_format='bzrlib.branch.BzrBranchFormat6', hidden=True)
118
my_format_registry.register('hiddendeprecated', DeprecatedBzrDirFormat,
119
'Old format. Slower and does not support things. ', hidden=True)
120
my_format_registry.register_lazy('hiddenlazy', 'bzrlib.tests.test_bzrdir',
121
'DeprecatedBzrDirFormat', 'Format registered lazily',
122
deprecated=True, hidden=True)
99
my_format_registry.register('hiddenweave', bzrdir.BzrDirFormat6,
100
'Pre-0.8 format. Slower and does not support checkouts or shared'
101
' repositories', hidden=True)
102
my_format_registry.register_lazy('hiddenlazy', 'bzrlib.bzrdir',
103
'BzrDirFormat6', 'Format registered lazily', deprecated=True,
123
105
return my_format_registry
125
107
def test_format_registry(self):
126
108
my_format_registry = self.make_format_registry()
127
109
my_bzrdir = my_format_registry.make_bzrdir('lazy')
128
self.assertIsInstance(my_bzrdir, DeprecatedBzrDirFormat)
129
my_bzrdir = my_format_registry.make_bzrdir('deprecated')
130
self.assertIsInstance(my_bzrdir, DeprecatedBzrDirFormat)
110
self.assertIsInstance(my_bzrdir, bzrdir.BzrDirFormat6)
111
my_bzrdir = my_format_registry.make_bzrdir('weave')
112
self.assertIsInstance(my_bzrdir, bzrdir.BzrDirFormat6)
131
113
my_bzrdir = my_format_registry.make_bzrdir('default')
132
self.assertIsInstance(my_bzrdir.repository_format,
114
self.assertIsInstance(my_bzrdir.repository_format,
133
115
knitrepo.RepositoryFormatKnit1)
134
116
my_bzrdir = my_format_registry.make_bzrdir('knit')
135
self.assertIsInstance(my_bzrdir.repository_format,
117
self.assertIsInstance(my_bzrdir.repository_format,
136
118
knitrepo.RepositoryFormatKnit1)
137
119
my_bzrdir = my_format_registry.make_bzrdir('branch6')
138
120
self.assertIsInstance(my_bzrdir.get_branch_format(),
142
124
my_format_registry = self.make_format_registry()
143
125
self.assertEqual('Format registered lazily',
144
126
my_format_registry.get_help('lazy'))
145
self.assertEqual('Format using knits',
127
self.assertEqual('Format using knits',
146
128
my_format_registry.get_help('knit'))
147
self.assertEqual('Format using knits',
129
self.assertEqual('Format using knits',
148
130
my_format_registry.get_help('default'))
149
self.assertEqual('Some format. Slower and unawesome and deprecated.',
150
my_format_registry.get_help('deprecated'))
131
self.assertEqual('Pre-0.8 format. Slower and does not support'
132
' checkouts or shared repositories',
133
my_format_registry.get_help('weave'))
152
135
def test_help_topic(self):
153
136
topics = help_topics.HelpTopicRegistry()
154
registry = self.make_format_registry()
155
topics.register('current-formats', registry.help_topic,
157
topics.register('other-formats', registry.help_topic,
159
new = topics.get_detail('current-formats')
160
rest = topics.get_detail('other-formats')
161
experimental, deprecated = rest.split('Deprecated formats')
162
self.assertContainsRe(new, 'formats-help')
163
self.assertContainsRe(new,
164
':knit:\n \(native\) \(default\) Format using knits\n')
165
self.assertContainsRe(experimental,
166
':branch6:\n \(native\) Experimental successor to knit')
167
self.assertContainsRe(deprecated,
168
':lazy:\n \(native\) Format registered lazily\n')
137
topics.register('formats', self.make_format_registry().help_topic,
139
topic = topics.get_detail('formats')
140
new, deprecated = topic.split('Deprecated formats')
141
self.assertContainsRe(new, 'Bazaar directory formats')
142
self.assertContainsRe(new,
143
' knit/default:\n \(native\) Format using knits\n')
144
self.assertContainsRe(deprecated,
145
' lazy:\n \(native\) Format registered lazily\n')
169
146
self.assertNotContainsRe(new, 'hidden')
171
148
def test_set_default_repository(self):
311
249
format.initialize(url)
312
250
# register a format for it.
313
bzrdir.BzrProber.formats.register(format.get_format_string(), format)
251
bzrdir.BzrDirFormat.register_format(format)
314
252
# which bzrdir.Open will refuse (not supported)
315
253
self.assertRaises(UnsupportedFormatError, bzrdir.BzrDir.open, url)
316
254
# which bzrdir.open_containing will refuse (not supported)
317
255
self.assertRaises(UnsupportedFormatError, bzrdir.BzrDir.open_containing, url)
318
256
# but open_downlevel will work
319
t = _mod_transport.get_transport(url)
257
t = get_transport(url)
320
258
self.assertEqual(format.open(t), bzrdir.BzrDir.open_unsupported(url))
321
259
# unregister the format
322
bzrdir.BzrProber.formats.remove(format.get_format_string())
260
bzrdir.BzrDirFormat.unregister_format(format)
323
261
# now open_downlevel should fail too.
324
262
self.assertRaises(UnknownFormatError, bzrdir.BzrDir.open_unsupported, url)
264
def test_create_repository(self):
265
format = SampleBzrDirFormat()
266
repo = bzrdir.BzrDir.create_repository(self.get_url(), format=format)
267
self.assertEqual('A repository', repo)
269
def test_create_repository_shared(self):
270
old_format = bzrdir.BzrDirFormat.get_default_format()
271
repo = bzrdir.BzrDir.create_repository('.', shared=True)
272
self.assertTrue(repo.is_shared())
274
def test_create_repository_nonshared(self):
275
old_format = bzrdir.BzrDirFormat.get_default_format()
276
repo = bzrdir.BzrDir.create_repository('.')
277
self.assertFalse(repo.is_shared())
279
def test_create_repository_under_shared(self):
280
# an explicit create_repository always does so.
281
# we trust the format is right from the 'create_repository test'
282
format = bzrdir.format_registry.make_bzrdir('knit')
283
self.make_repository('.', shared=True, format=format)
284
repo = bzrdir.BzrDir.create_repository(self.get_url('child'),
286
self.assertTrue(isinstance(repo, repository.Repository))
287
self.assertTrue(repo.bzrdir.root_transport.base.endswith('child/'))
326
289
def test_create_branch_and_repo_uses_default(self):
327
290
format = SampleBzrDirFormat()
328
branch = bzrdir.BzrDir.create_branch_and_repo(self.get_url(),
291
branch = bzrdir.BzrDir.create_branch_and_repo(self.get_url(),
330
293
self.assertTrue(isinstance(branch, SampleBranch))
459
413
branch.bzrdir.open_workingtree()
462
class TestRepositoryAcquisitionPolicy(TestCaseWithTransport):
464
def test_acquire_repository_standalone(self):
465
"""The default acquisition policy should create a standalone branch."""
466
my_bzrdir = self.make_bzrdir('.')
467
repo_policy = my_bzrdir.determine_repository_policy()
468
repo, is_new = repo_policy.acquire_repository()
469
self.assertEqual(repo.bzrdir.root_transport.base,
470
my_bzrdir.root_transport.base)
471
self.assertFalse(repo.is_shared())
473
def test_determine_stacking_policy(self):
474
parent_bzrdir = self.make_bzrdir('.')
475
child_bzrdir = self.make_bzrdir('child')
476
parent_bzrdir.get_config().set_default_stack_on('http://example.org')
477
repo_policy = child_bzrdir.determine_repository_policy()
478
self.assertEqual('http://example.org', repo_policy._stack_on)
480
def test_determine_stacking_policy_relative(self):
481
parent_bzrdir = self.make_bzrdir('.')
482
child_bzrdir = self.make_bzrdir('child')
483
parent_bzrdir.get_config().set_default_stack_on('child2')
484
repo_policy = child_bzrdir.determine_repository_policy()
485
self.assertEqual('child2', repo_policy._stack_on)
486
self.assertEqual(parent_bzrdir.root_transport.base,
487
repo_policy._stack_on_pwd)
489
def prepare_default_stacking(self, child_format='1.6'):
490
parent_bzrdir = self.make_bzrdir('.')
491
child_branch = self.make_branch('child', format=child_format)
492
parent_bzrdir.get_config().set_default_stack_on(child_branch.base)
493
new_child_transport = parent_bzrdir.transport.clone('child2')
494
return child_branch, new_child_transport
496
def test_clone_on_transport_obeys_stacking_policy(self):
497
child_branch, new_child_transport = self.prepare_default_stacking()
498
new_child = child_branch.bzrdir.clone_on_transport(new_child_transport)
499
self.assertEqual(child_branch.base,
500
new_child.open_branch().get_stacked_on_url())
502
def test_default_stacking_with_stackable_branch_unstackable_repo(self):
503
# Make stackable source branch with an unstackable repo format.
504
source_bzrdir = self.make_bzrdir('source')
505
knitpack_repo.RepositoryFormatKnitPack1().initialize(source_bzrdir)
506
source_branch = bzrlib.branch.BzrBranchFormat7().initialize(
508
# Make a directory with a default stacking policy
509
parent_bzrdir = self.make_bzrdir('parent')
510
stacked_on = self.make_branch('parent/stacked-on', format='pack-0.92')
511
parent_bzrdir.get_config().set_default_stack_on(stacked_on.base)
512
# Clone source into directory
513
target = source_bzrdir.clone(self.get_url('parent/target'))
515
def test_sprout_obeys_stacking_policy(self):
516
child_branch, new_child_transport = self.prepare_default_stacking()
517
new_child = child_branch.bzrdir.sprout(new_child_transport.base)
518
self.assertEqual(child_branch.base,
519
new_child.open_branch().get_stacked_on_url())
521
def test_clone_ignores_policy_for_unsupported_formats(self):
522
child_branch, new_child_transport = self.prepare_default_stacking(
523
child_format='pack-0.92')
524
new_child = child_branch.bzrdir.clone_on_transport(new_child_transport)
525
self.assertRaises(errors.UnstackableBranchFormat,
526
new_child.open_branch().get_stacked_on_url)
528
def test_sprout_ignores_policy_for_unsupported_formats(self):
529
child_branch, new_child_transport = self.prepare_default_stacking(
530
child_format='pack-0.92')
531
new_child = child_branch.bzrdir.sprout(new_child_transport.base)
532
self.assertRaises(errors.UnstackableBranchFormat,
533
new_child.open_branch().get_stacked_on_url)
535
def test_sprout_upgrades_format_if_stacked_specified(self):
536
child_branch, new_child_transport = self.prepare_default_stacking(
537
child_format='pack-0.92')
538
new_child = child_branch.bzrdir.sprout(new_child_transport.base,
540
self.assertEqual(child_branch.bzrdir.root_transport.base,
541
new_child.open_branch().get_stacked_on_url())
542
repo = new_child.open_repository()
543
self.assertTrue(repo._format.supports_external_lookups)
544
self.assertFalse(repo.supports_rich_root())
546
def test_clone_on_transport_upgrades_format_if_stacked_on_specified(self):
547
child_branch, new_child_transport = self.prepare_default_stacking(
548
child_format='pack-0.92')
549
new_child = child_branch.bzrdir.clone_on_transport(new_child_transport,
550
stacked_on=child_branch.bzrdir.root_transport.base)
551
self.assertEqual(child_branch.bzrdir.root_transport.base,
552
new_child.open_branch().get_stacked_on_url())
553
repo = new_child.open_repository()
554
self.assertTrue(repo._format.supports_external_lookups)
555
self.assertFalse(repo.supports_rich_root())
557
def test_sprout_upgrades_to_rich_root_format_if_needed(self):
558
child_branch, new_child_transport = self.prepare_default_stacking(
559
child_format='rich-root-pack')
560
new_child = child_branch.bzrdir.sprout(new_child_transport.base,
562
repo = new_child.open_repository()
563
self.assertTrue(repo._format.supports_external_lookups)
564
self.assertTrue(repo.supports_rich_root())
566
def test_add_fallback_repo_handles_absolute_urls(self):
567
stack_on = self.make_branch('stack_on', format='1.6')
568
repo = self.make_repository('repo', format='1.6')
569
policy = bzrdir.UseExistingRepository(repo, stack_on.base)
570
policy._add_fallback(repo)
572
def test_add_fallback_repo_handles_relative_urls(self):
573
stack_on = self.make_branch('stack_on', format='1.6')
574
repo = self.make_repository('repo', format='1.6')
575
policy = bzrdir.UseExistingRepository(repo, '.', stack_on.base)
576
policy._add_fallback(repo)
578
def test_configure_relative_branch_stacking_url(self):
579
stack_on = self.make_branch('stack_on', format='1.6')
580
stacked = self.make_branch('stack_on/stacked', format='1.6')
581
policy = bzrdir.UseExistingRepository(stacked.repository,
583
policy.configure_branch(stacked)
584
self.assertEqual('..', stacked.get_stacked_on_url())
586
def test_relative_branch_stacking_to_absolute(self):
587
stack_on = self.make_branch('stack_on', format='1.6')
588
stacked = self.make_branch('stack_on/stacked', format='1.6')
589
policy = bzrdir.UseExistingRepository(stacked.repository,
590
'.', self.get_readonly_url('stack_on'))
591
policy.configure_branch(stacked)
592
self.assertEqual(self.get_readonly_url('stack_on'),
593
stacked.get_stacked_on_url())
596
416
class ChrootedTests(TestCaseWithTransport):
597
417
"""A support class that provides readonly urls outside the local namespace.
620
437
branch, relpath = bzrdir.BzrDir.open_containing(self.get_readonly_url('g/p/q'))
621
438
self.assertEqual('g/p/q', relpath)
623
def test_open_containing_tree_branch_or_repository_empty(self):
624
self.assertRaises(errors.NotBranchError,
625
bzrdir.BzrDir.open_containing_tree_branch_or_repository,
626
self.get_readonly_url(''))
628
def test_open_containing_tree_branch_or_repository_all(self):
629
self.make_branch_and_tree('topdir')
630
tree, branch, repo, relpath = \
631
bzrdir.BzrDir.open_containing_tree_branch_or_repository(
633
self.assertEqual(os.path.realpath('topdir'),
634
os.path.realpath(tree.basedir))
635
self.assertEqual(os.path.realpath('topdir'),
636
self.local_branch_path(branch))
638
osutils.realpath(os.path.join('topdir', '.bzr', 'repository')),
639
repo.bzrdir.transport.local_abspath('repository'))
640
self.assertEqual(relpath, 'foo')
642
def test_open_containing_tree_branch_or_repository_no_tree(self):
643
self.make_branch('branch')
644
tree, branch, repo, relpath = \
645
bzrdir.BzrDir.open_containing_tree_branch_or_repository(
647
self.assertEqual(tree, None)
648
self.assertEqual(os.path.realpath('branch'),
649
self.local_branch_path(branch))
651
osutils.realpath(os.path.join('branch', '.bzr', 'repository')),
652
repo.bzrdir.transport.local_abspath('repository'))
653
self.assertEqual(relpath, 'foo')
655
def test_open_containing_tree_branch_or_repository_repo(self):
656
self.make_repository('repo')
657
tree, branch, repo, relpath = \
658
bzrdir.BzrDir.open_containing_tree_branch_or_repository(
660
self.assertEqual(tree, None)
661
self.assertEqual(branch, None)
663
osutils.realpath(os.path.join('repo', '.bzr', 'repository')),
664
repo.bzrdir.transport.local_abspath('repository'))
665
self.assertEqual(relpath, '')
667
def test_open_containing_tree_branch_or_repository_shared_repo(self):
668
self.make_repository('shared', shared=True)
669
bzrdir.BzrDir.create_branch_convenience('shared/branch',
670
force_new_tree=False)
671
tree, branch, repo, relpath = \
672
bzrdir.BzrDir.open_containing_tree_branch_or_repository(
674
self.assertEqual(tree, None)
675
self.assertEqual(os.path.realpath('shared/branch'),
676
self.local_branch_path(branch))
678
osutils.realpath(os.path.join('shared', '.bzr', 'repository')),
679
repo.bzrdir.transport.local_abspath('repository'))
680
self.assertEqual(relpath, '')
682
def test_open_containing_tree_branch_or_repository_branch_subdir(self):
683
self.make_branch_and_tree('foo')
684
self.build_tree(['foo/bar/'])
685
tree, branch, repo, relpath = \
686
bzrdir.BzrDir.open_containing_tree_branch_or_repository(
688
self.assertEqual(os.path.realpath('foo'),
689
os.path.realpath(tree.basedir))
690
self.assertEqual(os.path.realpath('foo'),
691
self.local_branch_path(branch))
693
osutils.realpath(os.path.join('foo', '.bzr', 'repository')),
694
repo.bzrdir.transport.local_abspath('repository'))
695
self.assertEqual(relpath, 'bar')
697
def test_open_containing_tree_branch_or_repository_repo_subdir(self):
698
self.make_repository('bar')
699
self.build_tree(['bar/baz/'])
700
tree, branch, repo, relpath = \
701
bzrdir.BzrDir.open_containing_tree_branch_or_repository(
703
self.assertEqual(tree, None)
704
self.assertEqual(branch, None)
706
osutils.realpath(os.path.join('bar', '.bzr', 'repository')),
707
repo.bzrdir.transport.local_abspath('repository'))
708
self.assertEqual(relpath, 'baz')
710
440
def test_open_containing_from_transport(self):
711
self.assertRaises(NotBranchError,
712
bzrdir.BzrDir.open_containing_from_transport,
713
_mod_transport.get_transport(self.get_readonly_url('')))
714
self.assertRaises(NotBranchError,
715
bzrdir.BzrDir.open_containing_from_transport,
716
_mod_transport.get_transport(self.get_readonly_url('g/p/q')))
441
self.assertRaises(NotBranchError, bzrdir.BzrDir.open_containing_from_transport,
442
get_transport(self.get_readonly_url('')))
443
self.assertRaises(NotBranchError, bzrdir.BzrDir.open_containing_from_transport,
444
get_transport(self.get_readonly_url('g/p/q')))
717
445
control = bzrdir.BzrDir.create(self.get_url())
718
446
branch, relpath = bzrdir.BzrDir.open_containing_from_transport(
719
_mod_transport.get_transport(self.get_readonly_url('')))
447
get_transport(self.get_readonly_url('')))
720
448
self.assertEqual('', relpath)
721
449
branch, relpath = bzrdir.BzrDir.open_containing_from_transport(
722
_mod_transport.get_transport(self.get_readonly_url('g/p/q')))
450
get_transport(self.get_readonly_url('g/p/q')))
723
451
self.assertEqual('g/p/q', relpath)
725
453
def test_open_containing_tree_or_branch(self):
454
def local_branch_path(branch):
455
return os.path.realpath(
456
urlutils.local_path_from_url(branch.base))
726
458
self.make_branch_and_tree('topdir')
727
459
tree, branch, relpath = bzrdir.BzrDir.open_containing_tree_or_branch(
729
461
self.assertEqual(os.path.realpath('topdir'),
730
462
os.path.realpath(tree.basedir))
731
463
self.assertEqual(os.path.realpath('topdir'),
732
self.local_branch_path(branch))
464
local_branch_path(branch))
733
465
self.assertIs(tree.bzrdir, branch.bzrdir)
734
466
self.assertEqual('foo', relpath)
735
467
# opening from non-local should not return the tree
744
476
self.assertIs(tree, None)
745
477
self.assertEqual(os.path.realpath('topdir/foo'),
746
self.local_branch_path(branch))
478
local_branch_path(branch))
747
479
self.assertEqual('', relpath)
749
def test_open_tree_or_branch(self):
750
self.make_branch_and_tree('topdir')
751
tree, branch = bzrdir.BzrDir.open_tree_or_branch('topdir')
752
self.assertEqual(os.path.realpath('topdir'),
753
os.path.realpath(tree.basedir))
754
self.assertEqual(os.path.realpath('topdir'),
755
self.local_branch_path(branch))
756
self.assertIs(tree.bzrdir, branch.bzrdir)
757
# opening from non-local should not return the tree
758
tree, branch = bzrdir.BzrDir.open_tree_or_branch(
759
self.get_readonly_url('topdir'))
760
self.assertEqual(None, tree)
762
self.make_branch('topdir/foo')
763
tree, branch = bzrdir.BzrDir.open_tree_or_branch('topdir/foo')
764
self.assertIs(tree, None)
765
self.assertEqual(os.path.realpath('topdir/foo'),
766
self.local_branch_path(branch))
768
481
def test_open_from_transport(self):
769
482
# transport pointing at bzrdir should give a bzrdir with root transport
770
483
# set to the given transport
771
484
control = bzrdir.BzrDir.create(self.get_url())
772
t = self.get_transport()
773
opened_bzrdir = bzrdir.BzrDir.open_from_transport(t)
774
self.assertEqual(t.base, opened_bzrdir.root_transport.base)
485
transport = get_transport(self.get_url())
486
opened_bzrdir = bzrdir.BzrDir.open_from_transport(transport)
487
self.assertEqual(transport.base, opened_bzrdir.root_transport.base)
775
488
self.assertIsInstance(opened_bzrdir, bzrdir.BzrDir)
777
490
def test_open_from_transport_no_bzrdir(self):
778
t = self.get_transport()
779
self.assertRaises(NotBranchError, bzrdir.BzrDir.open_from_transport, t)
491
transport = get_transport(self.get_url())
492
self.assertRaises(NotBranchError, bzrdir.BzrDir.open_from_transport,
781
495
def test_open_from_transport_bzrdir_in_parent(self):
782
496
control = bzrdir.BzrDir.create(self.get_url())
783
t = self.get_transport()
785
t = t.clone('subdir')
786
self.assertRaises(NotBranchError, bzrdir.BzrDir.open_from_transport, t)
497
transport = get_transport(self.get_url())
498
transport.mkdir('subdir')
499
transport = transport.clone('subdir')
500
self.assertRaises(NotBranchError, bzrdir.BzrDir.open_from_transport,
788
503
def test_sprout_recursive(self):
789
tree = self.make_branch_and_tree('tree1',
790
format='dirstate-with-subtree')
504
tree = self.make_branch_and_tree('tree1', format='dirstate-with-subtree')
791
505
sub_tree = self.make_branch_and_tree('tree1/subtree',
792
506
format='dirstate-with-subtree')
793
sub_tree.set_root_id('subtree-root')
794
507
tree.add_reference(sub_tree)
795
508
self.build_tree(['tree1/subtree/file'])
796
509
sub_tree.add('file')
797
510
tree.commit('Initial commit')
798
tree2 = tree.bzrdir.sprout('tree2').open_workingtree()
800
self.addCleanup(tree2.unlock)
801
self.assertPathExists('tree2/subtree/file')
802
self.assertEqual('tree-reference', tree2.kind('subtree-root'))
511
tree.bzrdir.sprout('tree2')
512
self.failUnlessExists('tree2/subtree/file')
804
514
def test_cloning_metadir(self):
805
515
"""Ensure that cloning metadir is suitable"""
819
529
self.build_tree(['tree1/subtree/file'])
820
530
sub_tree.add('file')
821
531
tree.commit('Initial commit')
822
# The following line force the orhaning to reveal bug #634470
823
tree.branch.get_config().set_user_option(
824
'bzr.transform.orphan_policy', 'move')
825
532
tree.bzrdir.destroy_workingtree()
826
# FIXME: subtree/.bzr is left here which allows the test to pass (or
827
# fail :-( ) -- vila 20100909
828
533
repo = self.make_repository('repo', shared=True,
829
534
format='dirstate-with-subtree')
830
535
repo.set_make_working_trees(False)
831
# FIXME: we just deleted the workingtree and now we want to use it ????
832
# At a minimum, we should use tree.branch below (but this fails too
833
# currently) or stop calling this test 'treeless'. Specifically, I've
834
# turn the line below into an assertRaises when 'subtree/.bzr' is
835
# orphaned and sprout tries to access the branch there (which is left
836
# by bzrdir.BzrDirMeta1.destroy_workingtree when it ignores the
837
# [DeletingParent('Not deleting', u'subtree', None)] conflict). See bug
838
# #634470. -- vila 20100909
839
self.assertRaises(errors.NotBranchError,
840
tree.bzrdir.sprout, 'repo/tree2')
841
# self.assertPathExists('repo/tree2/subtree')
842
# self.assertPathDoesNotExist('repo/tree2/subtree/file')
844
def make_foo_bar_baz(self):
845
foo = bzrdir.BzrDir.create_branch_convenience('foo').bzrdir
846
bar = self.make_branch('foo/bar').bzrdir
847
baz = self.make_branch('baz').bzrdir
850
def test_find_bzrdirs(self):
851
foo, bar, baz = self.make_foo_bar_baz()
852
t = self.get_transport()
853
self.assertEqualBzrdirs([baz, foo, bar], bzrdir.BzrDir.find_bzrdirs(t))
855
def make_fake_permission_denied_transport(self, transport, paths):
856
"""Create a transport that raises PermissionDenied for some paths."""
859
raise errors.PermissionDenied(path)
861
path_filter_server = pathfilter.PathFilteringServer(transport, filter)
862
path_filter_server.start_server()
863
self.addCleanup(path_filter_server.stop_server)
864
path_filter_transport = pathfilter.PathFilteringTransport(
865
path_filter_server, '.')
866
return (path_filter_server, path_filter_transport)
868
def assertBranchUrlsEndWith(self, expect_url_suffix, actual_bzrdirs):
869
"""Check that each branch url ends with the given suffix."""
870
for actual_bzrdir in actual_bzrdirs:
871
self.assertEndsWith(actual_bzrdir.user_url, expect_url_suffix)
873
def test_find_bzrdirs_permission_denied(self):
874
foo, bar, baz = self.make_foo_bar_baz()
875
t = self.get_transport()
876
path_filter_server, path_filter_transport = \
877
self.make_fake_permission_denied_transport(t, ['foo'])
879
self.assertBranchUrlsEndWith('/baz/',
880
bzrdir.BzrDir.find_bzrdirs(path_filter_transport))
882
smart_transport = self.make_smart_server('.',
883
backing_server=path_filter_server)
884
self.assertBranchUrlsEndWith('/baz/',
885
bzrdir.BzrDir.find_bzrdirs(smart_transport))
887
def test_find_bzrdirs_list_current(self):
888
def list_current(transport):
889
return [s for s in transport.list_dir('') if s != 'baz']
891
foo, bar, baz = self.make_foo_bar_baz()
892
t = self.get_transport()
893
self.assertEqualBzrdirs(
895
bzrdir.BzrDir.find_bzrdirs(t, list_current=list_current))
897
def test_find_bzrdirs_evaluate(self):
898
def evaluate(bzrdir):
900
repo = bzrdir.open_repository()
901
except NoRepositoryPresent:
902
return True, bzrdir.root_transport.base
904
return False, bzrdir.root_transport.base
906
foo, bar, baz = self.make_foo_bar_baz()
907
t = self.get_transport()
908
self.assertEqual([baz.root_transport.base, foo.root_transport.base],
909
list(bzrdir.BzrDir.find_bzrdirs(t, evaluate=evaluate)))
911
def assertEqualBzrdirs(self, first, second):
913
second = list(second)
914
self.assertEqual(len(first), len(second))
915
for x, y in zip(first, second):
916
self.assertEqual(x.root_transport.base, y.root_transport.base)
918
def test_find_branches(self):
919
root = self.make_repository('', shared=True)
920
foo, bar, baz = self.make_foo_bar_baz()
921
qux = self.make_bzrdir('foo/qux')
922
t = self.get_transport()
923
branches = bzrdir.BzrDir.find_branches(t)
924
self.assertEqual(baz.root_transport.base, branches[0].base)
925
self.assertEqual(foo.root_transport.base, branches[1].base)
926
self.assertEqual(bar.root_transport.base, branches[2].base)
928
# ensure this works without a top-level repo
929
branches = bzrdir.BzrDir.find_branches(t.clone('foo'))
930
self.assertEqual(foo.root_transport.base, branches[0].base)
931
self.assertEqual(bar.root_transport.base, branches[1].base)
934
class TestMissingRepoBranchesSkipped(TestCaseWithMemoryTransport):
936
def test_find_bzrdirs_missing_repo(self):
937
t = self.get_transport()
938
arepo = self.make_repository('arepo', shared=True)
939
abranch_url = arepo.user_url + '/abranch'
940
abranch = bzrdir.BzrDir.create(abranch_url).create_branch()
941
t.delete_tree('arepo/.bzr')
942
self.assertRaises(errors.NoRepositoryPresent,
943
branch.Branch.open, abranch_url)
944
self.make_branch('baz')
945
for actual_bzrdir in bzrdir.BzrDir.find_branches(t):
946
self.assertEndsWith(actual_bzrdir.user_url, '/baz/')
536
tree.bzrdir.sprout('repo/tree2')
537
self.failUnlessExists('repo/tree2/subtree')
538
self.failIfExists('repo/tree2/subtree/file')
949
541
class TestMeta1DirFormat(TestCaseWithTransport):
991
582
def test_needs_conversion_different_working_tree(self):
992
583
# meta1dirs need an conversion if any element is not the default.
993
new_format = bzrdir.format_registry.make_bzrdir('dirstate')
994
tree = self.make_branch_and_tree('tree', format='knit')
995
self.assertTrue(tree.bzrdir.needs_format_conversion(
998
def test_initialize_on_format_uses_smart_transport(self):
999
self.setup_smart_server_with_call_log()
1000
new_format = bzrdir.format_registry.make_bzrdir('dirstate')
1001
transport = self.get_transport('target')
1002
transport.ensure_base()
1003
self.reset_smart_call_log()
1004
instance = new_format.initialize_on_transport(transport)
1005
self.assertIsInstance(instance, remote.RemoteBzrDir)
1006
rpc_count = len(self.hpss_calls)
1007
# This figure represent the amount of work to perform this use case. It
1008
# is entirely ok to reduce this number if a test fails due to rpc_count
1009
# being too low. If rpc_count increases, more network roundtrips have
1010
# become necessary for this use case. Please do not adjust this number
1011
# upwards without agreement from bzr's network support maintainers.
1012
self.assertEqual(2, rpc_count)
584
old_format = bzrdir.BzrDirFormat.get_default_format()
586
new_default = bzrdir.format_registry.make_bzrdir('dirstate')
587
bzrdir.BzrDirFormat._set_default_format(new_default)
589
tree = self.make_branch_and_tree('tree', format='knit')
590
self.assertTrue(tree.bzrdir.needs_format_conversion())
592
bzrdir.BzrDirFormat._set_default_format(old_format)
595
class TestFormat5(TestCaseWithTransport):
596
"""Tests specific to the version 5 bzrdir format."""
598
def test_same_lockfiles_between_tree_repo_branch(self):
599
# this checks that only a single lockfiles instance is created
600
# for format 5 objects
601
dir = bzrdir.BzrDirFormat5().initialize(self.get_url())
602
def check_dir_components_use_same_lock(dir):
603
ctrl_1 = dir.open_repository().control_files
604
ctrl_2 = dir.open_branch().control_files
605
ctrl_3 = dir.open_workingtree()._control_files
606
self.assertTrue(ctrl_1 is ctrl_2)
607
self.assertTrue(ctrl_2 is ctrl_3)
608
check_dir_components_use_same_lock(dir)
609
# and if we open it normally.
610
dir = bzrdir.BzrDir.open(self.get_url())
611
check_dir_components_use_same_lock(dir)
613
def test_can_convert(self):
614
# format 5 dirs are convertable
615
dir = bzrdir.BzrDirFormat5().initialize(self.get_url())
616
self.assertTrue(dir.can_convert_format())
618
def test_needs_conversion(self):
619
# format 5 dirs need a conversion if they are not the default.
620
# and they start of not the default.
621
old_format = bzrdir.BzrDirFormat.get_default_format()
622
bzrdir.BzrDirFormat._set_default_format(bzrdir.BzrDirFormat5())
624
dir = bzrdir.BzrDirFormat5().initialize(self.get_url())
625
self.assertFalse(dir.needs_format_conversion())
627
bzrdir.BzrDirFormat._set_default_format(old_format)
628
self.assertTrue(dir.needs_format_conversion())
631
class TestFormat6(TestCaseWithTransport):
632
"""Tests specific to the version 6 bzrdir format."""
634
def test_same_lockfiles_between_tree_repo_branch(self):
635
# this checks that only a single lockfiles instance is created
636
# for format 6 objects
637
dir = bzrdir.BzrDirFormat6().initialize(self.get_url())
638
def check_dir_components_use_same_lock(dir):
639
ctrl_1 = dir.open_repository().control_files
640
ctrl_2 = dir.open_branch().control_files
641
ctrl_3 = dir.open_workingtree()._control_files
642
self.assertTrue(ctrl_1 is ctrl_2)
643
self.assertTrue(ctrl_2 is ctrl_3)
644
check_dir_components_use_same_lock(dir)
645
# and if we open it normally.
646
dir = bzrdir.BzrDir.open(self.get_url())
647
check_dir_components_use_same_lock(dir)
649
def test_can_convert(self):
650
# format 6 dirs are convertable
651
dir = bzrdir.BzrDirFormat6().initialize(self.get_url())
652
self.assertTrue(dir.can_convert_format())
654
def test_needs_conversion(self):
655
# format 6 dirs need an conversion if they are not the default.
656
old_format = bzrdir.BzrDirFormat.get_default_format()
657
bzrdir.BzrDirFormat._set_default_format(bzrdir.BzrDirMetaFormat1())
659
dir = bzrdir.BzrDirFormat6().initialize(self.get_url())
660
self.assertTrue(dir.needs_format_conversion())
662
bzrdir.BzrDirFormat._set_default_format(old_format)
665
class NotBzrDir(bzrlib.bzrdir.BzrDir):
666
"""A non .bzr based control directory."""
668
def __init__(self, transport, format):
669
self._format = format
670
self.root_transport = transport
671
self.transport = transport.clone('.not')
674
class NotBzrDirFormat(bzrlib.bzrdir.BzrDirFormat):
675
"""A test class representing any non-.bzr based disk format."""
677
def initialize_on_transport(self, transport):
678
"""Initialize a new .not dir in the base directory of a Transport."""
679
transport.mkdir('.not')
680
return self.open(transport)
682
def open(self, transport):
683
"""Open this directory."""
684
return NotBzrDir(transport, self)
687
def _known_formats(self):
688
return set([NotBzrDirFormat()])
691
def probe_transport(self, transport):
692
"""Our format is present if the transport ends in '.not/'."""
693
if transport.has('.not'):
694
return NotBzrDirFormat()
697
class TestNotBzrDir(TestCaseWithTransport):
698
"""Tests for using the bzrdir api with a non .bzr based disk format.
700
If/when one of these is in the core, we can let the implementation tests
704
def test_create_and_find_format(self):
705
# create a .notbzr dir
706
format = NotBzrDirFormat()
707
dir = format.initialize(self.get_url())
708
self.assertIsInstance(dir, NotBzrDir)
710
bzrlib.bzrdir.BzrDirFormat.register_control_format(format)
712
found = bzrlib.bzrdir.BzrDirFormat.find_format(
713
get_transport(self.get_url()))
714
self.assertIsInstance(found, NotBzrDirFormat)
716
bzrlib.bzrdir.BzrDirFormat.unregister_control_format(format)
718
def test_included_in_known_formats(self):
719
bzrlib.bzrdir.BzrDirFormat.register_control_format(NotBzrDirFormat)
721
formats = bzrlib.bzrdir.BzrDirFormat.known_formats()
722
for format in formats:
723
if isinstance(format, NotBzrDirFormat):
725
self.fail("No NotBzrDirFormat in %s" % formats)
727
bzrlib.bzrdir.BzrDirFormat.unregister_control_format(NotBzrDirFormat)
1015
730
class NonLocalTests(TestCaseWithTransport):
1058
773
my_bzrdir = bzrdir.BzrDir.open(self.get_url('branch-knit2'))
1059
774
checkout_format = my_bzrdir.checkout_metadir()
1060
775
self.assertIsInstance(checkout_format.workingtree_format,
1061
workingtree_4.WorkingTreeFormat4)
1064
class TestHTTPRedirections(object):
1065
"""Test redirection between two http servers.
776
workingtree.WorkingTreeFormat3)
779
class TestHTTPRedirectionLoop(object):
780
"""Test redirection loop between two http servers.
1067
782
This MUST be used by daughter classes that also inherit from
1068
783
TestCaseWithTwoWebservers.
1070
785
We can't inherit directly from TestCaseWithTwoWebservers or the
1071
786
test framework will try to create an instance which cannot
1072
run, its implementation being incomplete.
787
run, its implementation being incomplete.
790
# Should be defined by daughter classes to ensure redirection
791
# still use the same transport implementation (not currently
792
# enforced as it's a bit tricky to get right (see the FIXME
793
# in BzrDir.open_from_transport for the unique use case so
1075
797
def create_transport_readonly_server(self):
1076
# We don't set the http protocol version, relying on the default
1077
return http_utils.HTTPServerRedirecting()
798
return HTTPServerRedirecting()
1079
800
def create_transport_secondary_server(self):
1080
# We don't set the http protocol version, relying on the default
1081
return http_utils.HTTPServerRedirecting()
801
return HTTPServerRedirecting()
1083
803
def setUp(self):
1084
super(TestHTTPRedirections, self).setUp()
804
# Both servers redirect to each server creating a loop
805
super(TestHTTPRedirectionLoop, self).setUp()
1085
806
# The redirections will point to the new server
1086
807
self.new_server = self.get_readonly_server()
1087
808
# The requests to the old server will be redirected
1088
809
self.old_server = self.get_secondary_server()
1089
810
# Configure the redirections
1090
811
self.old_server.redirect_to(self.new_server.host, self.new_server.port)
812
self.new_server.redirect_to(self.old_server.host, self.old_server.port)
814
def _qualified_url(self, host, port):
815
return 'http+%s://%s:%s' % (self._qualifier, host, port)
1092
817
def test_loop(self):
1093
# Both servers redirect to each other creating a loop
1094
self.new_server.redirect_to(self.old_server.host, self.old_server.port)
1095
818
# Starting from either server should loop
1096
old_url = self._qualified_url(self.old_server.host,
819
old_url = self._qualified_url(self.old_server.host,
1097
820
self.old_server.port)
1098
821
oldt = self._transport(old_url)
1099
822
self.assertRaises(errors.NotBranchError,
1100
823
bzrdir.BzrDir.open_from_transport, oldt)
1101
new_url = self._qualified_url(self.new_server.host,
824
new_url = self._qualified_url(self.new_server.host,
1102
825
self.new_server.port)
1103
826
newt = self._transport(new_url)
1104
827
self.assertRaises(errors.NotBranchError,
1105
828
bzrdir.BzrDir.open_from_transport, newt)
1107
def test_qualifier_preserved(self):
1108
wt = self.make_branch_and_tree('branch')
1109
old_url = self._qualified_url(self.old_server.host,
1110
self.old_server.port)
1111
start = self._transport(old_url).clone('branch')
1112
bdir = bzrdir.BzrDir.open_from_transport(start)
1113
# Redirection should preserve the qualifier, hence the transport class
1115
self.assertIsInstance(bdir.root_transport, type(start))
1118
class TestHTTPRedirections_urllib(TestHTTPRedirections,
1119
http_utils.TestCaseWithTwoWebservers):
831
class TestHTTPRedirections_urllib(TestHTTPRedirectionLoop,
832
TestCaseWithTwoWebservers):
1120
833
"""Tests redirections for urllib implementation"""
835
_qualifier = 'urllib'
1122
836
_transport = HttpTransport_urllib
1124
def _qualified_url(self, host, port):
1125
result = 'http+urllib://%s:%s' % (host, port)
1126
self.permit_url(result)
1131
840
class TestHTTPRedirections_pycurl(TestWithTransport_pycurl,
1132
TestHTTPRedirections,
1133
http_utils.TestCaseWithTwoWebservers):
841
TestHTTPRedirectionLoop,
842
TestCaseWithTwoWebservers):
1134
843
"""Tests redirections for pycurl implementation"""
1136
def _qualified_url(self, host, port):
1137
result = 'http+pycurl://%s:%s' % (host, port)
1138
self.permit_url(result)
1142
class TestHTTPRedirections_nosmart(TestHTTPRedirections,
1143
http_utils.TestCaseWithTwoWebservers):
1144
"""Tests redirections for the nosmart decorator"""
1146
_transport = NoSmartTransportDecorator
1148
def _qualified_url(self, host, port):
1149
result = 'nosmart+http://%s:%s' % (host, port)
1150
self.permit_url(result)
1154
class TestHTTPRedirections_readonly(TestHTTPRedirections,
1155
http_utils.TestCaseWithTwoWebservers):
1156
"""Tests redirections for readonly decoratror"""
1158
_transport = ReadonlyTransportDecorator
1160
def _qualified_url(self, host, port):
1161
result = 'readonly+http://%s:%s' % (host, port)
1162
self.permit_url(result)
1166
class TestDotBzrHidden(TestCaseWithTransport):
1169
if sys.platform == 'win32':
1170
ls = [os.environ['COMSPEC'], '/C', 'dir', '/B']
1173
f = subprocess.Popen(self.ls, stdout=subprocess.PIPE,
1174
stderr=subprocess.PIPE)
1175
out, err = f.communicate()
1176
self.assertEqual(0, f.returncode, 'Calling %s failed: %s'
1178
return out.splitlines()
1180
def test_dot_bzr_hidden(self):
1181
if sys.platform == 'win32' and not win32utils.has_win32file:
1182
raise TestSkipped('unable to make file hidden without pywin32 library')
1183
b = bzrdir.BzrDir.create('.')
1184
self.build_tree(['a'])
1185
self.assertEquals(['a'], self.get_ls())
1187
def test_dot_bzr_hidden_with_url(self):
1188
if sys.platform == 'win32' and not win32utils.has_win32file:
1189
raise TestSkipped('unable to make file hidden without pywin32 library')
1190
b = bzrdir.BzrDir.create(urlutils.local_path_to_url('.'))
1191
self.build_tree(['a'])
1192
self.assertEquals(['a'], self.get_ls())
1195
class _TestBzrDirFormat(bzrdir.BzrDirMetaFormat1):
1196
"""Test BzrDirFormat implementation for TestBzrDirSprout."""
1198
def _open(self, transport):
1199
return _TestBzrDir(transport, self)
1202
class _TestBzrDir(bzrdir.BzrDirMeta1):
1203
"""Test BzrDir implementation for TestBzrDirSprout.
1205
When created a _TestBzrDir already has repository and a branch. The branch
1206
is a test double as well.
1209
def __init__(self, *args, **kwargs):
1210
super(_TestBzrDir, self).__init__(*args, **kwargs)
1211
self.test_branch = _TestBranch()
1212
self.test_branch.repository = self.create_repository()
1214
def open_branch(self, unsupported=False):
1215
return self.test_branch
1217
def cloning_metadir(self, require_stacking=False):
1218
return _TestBzrDirFormat()
1221
class _TestBranchFormat(bzrlib.branch.BranchFormat):
1222
"""Test Branch format for TestBzrDirSprout."""
1225
class _TestBranch(bzrlib.branch.Branch):
1226
"""Test Branch implementation for TestBzrDirSprout."""
1228
def __init__(self, *args, **kwargs):
1229
self._format = _TestBranchFormat()
1230
super(_TestBranch, self).__init__(*args, **kwargs)
1234
def sprout(self, *args, **kwargs):
1235
self.calls.append('sprout')
1236
return _TestBranch()
1238
def copy_content_into(self, destination, revision_id=None):
1239
self.calls.append('copy_content_into')
1241
def last_revision(self):
1242
return _mod_revision.NULL_REVISION
1244
def get_parent(self):
1247
def set_parent(self, parent):
1248
self._parent = parent
1250
def lock_read(self):
1251
return lock.LogicalLockResult(self.unlock)
1257
class TestBzrDirSprout(TestCaseWithMemoryTransport):
1259
def test_sprout_uses_branch_sprout(self):
1260
"""BzrDir.sprout calls Branch.sprout.
1262
Usually, BzrDir.sprout should delegate to the branch's sprout method
1263
for part of the work. This allows the source branch to control the
1264
choice of format for the new branch.
1266
There are exceptions, but this tests avoids them:
1267
- if there's no branch in the source bzrdir,
1268
- or if the stacking has been requested and the format needs to be
1269
overridden to satisfy that.
1271
# Make an instrumented bzrdir.
1272
t = self.get_transport('source')
1274
source_bzrdir = _TestBzrDirFormat().initialize_on_transport(t)
1275
# The instrumented bzrdir has a test_branch attribute that logs calls
1276
# made to the branch contained in that bzrdir. Initially the test
1277
# branch exists but no calls have been made to it.
1278
self.assertEqual([], source_bzrdir.test_branch.calls)
1281
target_url = self.get_url('target')
1282
result = source_bzrdir.sprout(target_url, recurse='no')
1284
# The bzrdir called the branch's sprout method.
1285
self.assertSubset(['sprout'], source_bzrdir.test_branch.calls)
1287
def test_sprout_parent(self):
1288
grandparent_tree = self.make_branch('grandparent')
1289
parent = grandparent_tree.bzrdir.sprout('parent').open_branch()
1290
branch_tree = parent.bzrdir.sprout('branch').open_branch()
1291
self.assertContainsRe(branch_tree.get_parent(), '/parent/$')
1294
class TestBzrDirHooks(TestCaseWithMemoryTransport):
1296
def test_pre_open_called(self):
1298
bzrdir.BzrDir.hooks.install_named_hook('pre_open', calls.append, None)
1299
transport = self.get_transport('foo')
1300
url = transport.base
1301
self.assertRaises(errors.NotBranchError, bzrdir.BzrDir.open, url)
1302
self.assertEqual([transport.base], [t.base for t in calls])
1304
def test_pre_open_actual_exceptions_raised(self):
1306
def fail_once(transport):
1309
raise errors.BzrError("fail")
1310
bzrdir.BzrDir.hooks.install_named_hook('pre_open', fail_once, None)
1311
transport = self.get_transport('foo')
1312
url = transport.base
1313
err = self.assertRaises(errors.BzrError, bzrdir.BzrDir.open, url)
1314
self.assertEqual('fail', err._preformatted_string)
1316
def test_post_repo_init(self):
1317
from bzrlib.bzrdir import RepoInitHookParams
1319
bzrdir.BzrDir.hooks.install_named_hook('post_repo_init',
1321
self.make_repository('foo')
1322
self.assertLength(1, calls)
1324
self.assertIsInstance(params, RepoInitHookParams)
1325
self.assertTrue(hasattr(params, 'bzrdir'))
1326
self.assertTrue(hasattr(params, 'repository'))
1328
def test_post_repo_init_hook_repr(self):
1330
bzrdir.BzrDir.hooks.install_named_hook('post_repo_init',
1331
lambda params: param_reprs.append(repr(params)), None)
1332
self.make_repository('foo')
1333
self.assertLength(1, param_reprs)
1334
param_repr = param_reprs[0]
1335
self.assertStartsWith(param_repr, '<RepoInitHookParams for ')
1338
class TestGenerateBackupName(TestCaseWithMemoryTransport):
1339
# FIXME: This may need to be unified with test_osutils.TestBackupNames or
1340
# moved to per_bzrdir or per_transport for better coverage ?
1344
super(TestGenerateBackupName, self).setUp()
1345
self._transport = self.get_transport()
1346
bzrdir.BzrDir.create(self.get_url(),
1347
possible_transports=[self._transport])
1348
self._bzrdir = bzrdir.BzrDir.open_from_transport(self._transport)
1350
def test_deprecated_generate_backup_name(self):
1351
res = self.applyDeprecated(
1352
symbol_versioning.deprecated_in((2, 3, 0)),
1353
self._bzrdir.generate_backup_name, 'whatever')
1356
self.assertEqual("a.~1~", self._bzrdir._available_backup_name("a"))
1358
def test_exiting(self):
1359
self._transport.put_bytes("a.~1~", "some content")
1360
self.assertEqual("a.~2~", self._bzrdir._available_backup_name("a"))
845
_qualifier = 'pycurl'