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
27
from bzrlib import (
35
revision as _mod_revision,
39
transport as _mod_transport,
45
37
import bzrlib.branch
46
from bzrlib.errors import (
48
NoColocatedBranchSupport,
50
UnsupportedFormatError,
38
from bzrlib.errors import (NotBranchError,
40
UnsupportedFormatError,
42
from bzrlib.symbol_versioning import (
52
45
from bzrlib.tests import (
54
TestCaseWithMemoryTransport,
55
47
TestCaseWithTransport,
58
from bzrlib.tests import(
51
from bzrlib.tests.http_server import HttpServer
52
from bzrlib.tests.http_utils import (
53
TestCaseWithTwoWebservers,
54
HTTPServerRedirecting,
62
56
from bzrlib.tests.test_http import TestWithTransport_pycurl
63
from bzrlib.transport import (
57
from bzrlib.transport import get_transport
67
58
from bzrlib.transport.http._urllib import HttpTransport_urllib
68
from bzrlib.transport.nosmart import NoSmartTransportDecorator
69
from bzrlib.transport.readonly import ReadonlyTransportDecorator
70
from bzrlib.repofmt import knitrepo, knitpack_repo
59
from bzrlib.transport.memory import MemoryServer
60
from bzrlib.repofmt import knitrepo, weaverepo
73
63
class TestDefaultFormat(TestCase):
75
65
def test_get_set_default_format(self):
76
66
old_format = bzrdir.BzrDirFormat.get_default_format()
77
# default is BzrDirMetaFormat1
78
self.assertIsInstance(old_format, bzrdir.BzrDirMetaFormat1)
79
controldir.ControlDirFormat._set_default_format(SampleBzrDirFormat())
67
# default is BzrDirFormat6
68
self.failUnless(isinstance(old_format, bzrdir.BzrDirMetaFormat1))
69
self.applyDeprecated(symbol_versioning.zero_fourteen,
70
bzrdir.BzrDirFormat.set_default_format,
80
72
# creating a bzr dir should now create an instrumented dir.
82
74
result = bzrdir.BzrDir.create('memory:///')
83
self.assertIsInstance(result, SampleBzrDir)
75
self.failUnless(isinstance(result, SampleBzrDir))
85
controldir.ControlDirFormat._set_default_format(old_format)
77
self.applyDeprecated(symbol_versioning.zero_fourteen,
78
bzrdir.BzrDirFormat.set_default_format, old_format)
86
79
self.assertEqual(old_format, bzrdir.BzrDirFormat.get_default_format())
89
class DeprecatedBzrDirFormat(bzrdir.BzrDirFormat):
90
"""A deprecated bzr dir format."""
93
82
class TestFormatRegistry(TestCase):
95
84
def make_format_registry(self):
96
my_format_registry = controldir.ControlDirFormatRegistry()
97
my_format_registry.register('deprecated', DeprecatedBzrDirFormat,
98
'Some format. Slower and unawesome and deprecated.',
100
my_format_registry.register_lazy('lazy', 'bzrlib.tests.test_bzrdir',
101
'DeprecatedBzrDirFormat', 'Format registered lazily',
103
bzrdir.register_metadir(my_format_registry, 'knit',
85
my_format_registry = bzrdir.BzrDirFormatRegistry()
86
my_format_registry.register('weave', bzrdir.BzrDirFormat6,
87
'Pre-0.8 format. Slower and does not support checkouts or shared'
88
' repositories', deprecated=True)
89
my_format_registry.register_lazy('lazy', 'bzrlib.bzrdir',
90
'BzrDirFormat6', 'Format registered lazily', deprecated=True)
91
my_format_registry.register_metadir('knit',
104
92
'bzrlib.repofmt.knitrepo.RepositoryFormatKnit1',
105
93
'Format using knits',
107
95
my_format_registry.set_default('knit')
108
bzrdir.register_metadir(my_format_registry,
96
my_format_registry.register_metadir(
110
98
'bzrlib.repofmt.knitrepo.RepositoryFormatKnit3',
111
99
'Experimental successor to knit. Use at your own risk.',
112
100
branch_format='bzrlib.branch.BzrBranchFormat6',
113
101
experimental=True)
114
bzrdir.register_metadir(my_format_registry,
102
my_format_registry.register_metadir(
116
104
'bzrlib.repofmt.knitrepo.RepositoryFormatKnit3',
117
105
'Experimental successor to knit. Use at your own risk.',
118
106
branch_format='bzrlib.branch.BzrBranchFormat6', 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)
107
my_format_registry.register('hiddenweave', bzrdir.BzrDirFormat6,
108
'Pre-0.8 format. Slower and does not support checkouts or shared'
109
' repositories', hidden=True)
110
my_format_registry.register_lazy('hiddenlazy', 'bzrlib.bzrdir',
111
'BzrDirFormat6', 'Format registered lazily', deprecated=True,
124
113
return my_format_registry
126
115
def test_format_registry(self):
127
116
my_format_registry = self.make_format_registry()
128
117
my_bzrdir = my_format_registry.make_bzrdir('lazy')
129
self.assertIsInstance(my_bzrdir, DeprecatedBzrDirFormat)
130
my_bzrdir = my_format_registry.make_bzrdir('deprecated')
131
self.assertIsInstance(my_bzrdir, DeprecatedBzrDirFormat)
118
self.assertIsInstance(my_bzrdir, bzrdir.BzrDirFormat6)
119
my_bzrdir = my_format_registry.make_bzrdir('weave')
120
self.assertIsInstance(my_bzrdir, bzrdir.BzrDirFormat6)
132
121
my_bzrdir = my_format_registry.make_bzrdir('default')
133
self.assertIsInstance(my_bzrdir.repository_format,
122
self.assertIsInstance(my_bzrdir.repository_format,
134
123
knitrepo.RepositoryFormatKnit1)
135
124
my_bzrdir = my_format_registry.make_bzrdir('knit')
136
self.assertIsInstance(my_bzrdir.repository_format,
125
self.assertIsInstance(my_bzrdir.repository_format,
137
126
knitrepo.RepositoryFormatKnit1)
138
127
my_bzrdir = my_format_registry.make_bzrdir('branch6')
139
128
self.assertIsInstance(my_bzrdir.get_branch_format(),
143
132
my_format_registry = self.make_format_registry()
144
133
self.assertEqual('Format registered lazily',
145
134
my_format_registry.get_help('lazy'))
146
self.assertEqual('Format using knits',
135
self.assertEqual('Format using knits',
147
136
my_format_registry.get_help('knit'))
148
self.assertEqual('Format using knits',
137
self.assertEqual('Format using knits',
149
138
my_format_registry.get_help('default'))
150
self.assertEqual('Some format. Slower and unawesome and deprecated.',
151
my_format_registry.get_help('deprecated'))
139
self.assertEqual('Pre-0.8 format. Slower and does not support'
140
' checkouts or shared repositories',
141
my_format_registry.get_help('weave'))
153
143
def test_help_topic(self):
154
144
topics = help_topics.HelpTopicRegistry()
155
registry = self.make_format_registry()
156
topics.register('current-formats', registry.help_topic,
158
topics.register('other-formats', registry.help_topic,
160
new = topics.get_detail('current-formats')
161
rest = topics.get_detail('other-formats')
145
topics.register('formats', self.make_format_registry().help_topic,
147
topic = topics.get_detail('formats')
148
new, rest = topic.split('Experimental formats')
162
149
experimental, deprecated = rest.split('Deprecated formats')
163
self.assertContainsRe(new, 'formats-help')
164
self.assertContainsRe(new,
150
self.assertContainsRe(new, 'These formats can be used')
151
self.assertContainsRe(new,
165
152
':knit:\n \(native\) \(default\) Format using knits\n')
166
self.assertContainsRe(experimental,
153
self.assertContainsRe(experimental,
167
154
':branch6:\n \(native\) Experimental successor to knit')
168
self.assertContainsRe(deprecated,
155
self.assertContainsRe(deprecated,
169
156
':lazy:\n \(native\) Format registered lazily\n')
170
157
self.assertNotContainsRe(new, 'hidden')
178
165
self.assertIs(bzrdir.format_registry.get('dirstate-with-subtree'),
179
166
bzrdir.format_registry.get('default'))
181
repository.format_registry.get_default().__class__,
168
repository.RepositoryFormat.get_default_format().__class__,
182
169
knitrepo.RepositoryFormatKnit3)
184
171
bzrdir.format_registry.set_default_repository(old_default)
186
173
def test_aliases(self):
187
a_registry = controldir.ControlDirFormatRegistry()
188
a_registry.register('deprecated', DeprecatedBzrDirFormat,
189
'Old format. Slower and does not support stuff',
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())
174
a_registry = bzrdir.BzrDirFormatRegistry()
175
a_registry.register('weave', bzrdir.BzrDirFormat6,
176
'Pre-0.8 format. Slower and does not support checkouts or shared'
177
' repositories', deprecated=True)
178
a_registry.register('weavealias', bzrdir.BzrDirFormat6,
179
'Pre-0.8 format. Slower and does not support checkouts or shared'
180
' repositories', deprecated=True, alias=True)
181
self.assertEqual(frozenset(['weavealias']), a_registry.aliases())
197
184
class SampleBranch(bzrlib.branch.Branch):
198
185
"""A dummy branch for guess what, dummy use."""
254
232
return "opened branch."
257
class BzrDirFormatTest1(bzrdir.BzrDirMetaFormat1):
260
def get_format_string():
261
return "Test format 1"
264
class BzrDirFormatTest2(bzrdir.BzrDirMetaFormat1):
267
def get_format_string():
268
return "Test format 2"
271
235
class TestBzrDirFormat(TestCaseWithTransport):
272
236
"""Tests for the BzrDirFormat facility."""
274
238
def test_find_format(self):
275
239
# is the right format object found for a branch?
276
240
# create a branch with a few known format objects.
277
bzrdir.BzrProber.formats.register(BzrDirFormatTest1.get_format_string(),
279
self.addCleanup(bzrdir.BzrProber.formats.remove,
280
BzrDirFormatTest1.get_format_string())
281
bzrdir.BzrProber.formats.register(BzrDirFormatTest2.get_format_string(),
283
self.addCleanup(bzrdir.BzrProber.formats.remove,
284
BzrDirFormatTest2.get_format_string())
285
t = self.get_transport()
241
# this is not quite the same as
242
t = get_transport(self.get_url())
286
243
self.build_tree(["foo/", "bar/"], transport=t)
287
244
def check_format(format, url):
288
245
format.initialize(url)
289
t = _mod_transport.get_transport_from_path(url)
246
t = get_transport(url)
290
247
found_format = bzrdir.BzrDirFormat.find_format(t)
291
self.assertIsInstance(found_format, format.__class__)
292
check_format(BzrDirFormatTest1(), "foo")
293
check_format(BzrDirFormatTest2(), "bar")
248
self.failUnless(isinstance(found_format, format.__class__))
249
check_format(bzrdir.BzrDirFormat5(), "foo")
250
check_format(bzrdir.BzrDirFormat6(), "bar")
295
252
def test_find_format_nothing_there(self):
296
253
self.assertRaises(NotBranchError,
297
254
bzrdir.BzrDirFormat.find_format,
298
_mod_transport.get_transport_from_path('.'))
300
257
def test_find_format_unknown_format(self):
301
t = self.get_transport()
258
t = get_transport(self.get_url())
303
260
t.put_bytes('.bzr/branch-format', '')
304
261
self.assertRaises(UnknownFormatError,
305
262
bzrdir.BzrDirFormat.find_format,
306
_mod_transport.get_transport_from_path('.'))
308
265
def test_register_unregister_format(self):
309
266
format = SampleBzrDirFormat()
312
269
format.initialize(url)
313
270
# register a format for it.
314
bzrdir.BzrProber.formats.register(format.get_format_string(), format)
271
bzrdir.BzrDirFormat.register_format(format)
315
272
# which bzrdir.Open will refuse (not supported)
316
273
self.assertRaises(UnsupportedFormatError, bzrdir.BzrDir.open, url)
317
274
# which bzrdir.open_containing will refuse (not supported)
318
275
self.assertRaises(UnsupportedFormatError, bzrdir.BzrDir.open_containing, url)
319
276
# but open_downlevel will work
320
t = _mod_transport.get_transport_from_url(url)
277
t = get_transport(url)
321
278
self.assertEqual(format.open(t), bzrdir.BzrDir.open_unsupported(url))
322
279
# unregister the format
323
bzrdir.BzrProber.formats.remove(format.get_format_string())
280
bzrdir.BzrDirFormat.unregister_format(format)
324
281
# now open_downlevel should fail too.
325
282
self.assertRaises(UnknownFormatError, bzrdir.BzrDir.open_unsupported, url)
284
def test_create_repository_deprecated(self):
285
# new interface is to make the bzrdir, then a repository within that.
286
format = SampleBzrDirFormat()
287
repo = self.applyDeprecated(zero_ninetyone,
288
bzrdir.BzrDir.create_repository,
289
self.get_url(), format=format)
290
self.assertEqual('A repository', repo)
292
def test_create_repository_shared(self):
293
# new interface is to make the bzrdir, then a repository within that.
294
old_format = bzrdir.BzrDirFormat.get_default_format()
295
repo = self.applyDeprecated(zero_ninetyone,
296
bzrdir.BzrDir.create_repository,
298
self.assertTrue(repo.is_shared())
300
def test_create_repository_nonshared(self):
301
# new interface is to make the bzrdir, then a repository within that.
302
old_format = bzrdir.BzrDirFormat.get_default_format()
303
repo = self.applyDeprecated(zero_ninetyone,
304
bzrdir.BzrDir.create_repository,
306
self.assertFalse(repo.is_shared())
308
def test_create_repository_under_shared(self):
309
# an explicit create_repository always does so.
310
# we trust the format is right from the 'create_repository test'
311
# new interface is to make the bzrdir, then a repository within that.
312
format = bzrdir.format_registry.make_bzrdir('knit')
313
self.make_repository('.', shared=True, format=format)
314
repo = self.applyDeprecated(zero_ninetyone,
315
bzrdir.BzrDir.create_repository,
316
self.get_url('child'),
318
self.assertTrue(isinstance(repo, repository.Repository))
319
self.assertTrue(repo.bzrdir.root_transport.base.endswith('child/'))
327
321
def test_create_branch_and_repo_uses_default(self):
328
322
format = SampleBzrDirFormat()
329
323
branch = bzrdir.BzrDir.create_branch_and_repo(self.get_url(),
460
454
branch.bzrdir.open_workingtree()
463
class TestRepositoryAcquisitionPolicy(TestCaseWithTransport):
465
def test_acquire_repository_standalone(self):
466
"""The default acquisition policy should create a standalone branch."""
467
my_bzrdir = self.make_bzrdir('.')
468
repo_policy = my_bzrdir.determine_repository_policy()
469
repo, is_new = repo_policy.acquire_repository()
470
self.assertEqual(repo.bzrdir.root_transport.base,
471
my_bzrdir.root_transport.base)
472
self.assertFalse(repo.is_shared())
474
def test_determine_stacking_policy(self):
475
parent_bzrdir = self.make_bzrdir('.')
476
child_bzrdir = self.make_bzrdir('child')
477
parent_bzrdir.get_config().set_default_stack_on('http://example.org')
478
repo_policy = child_bzrdir.determine_repository_policy()
479
self.assertEqual('http://example.org', repo_policy._stack_on)
481
def test_determine_stacking_policy_relative(self):
482
parent_bzrdir = self.make_bzrdir('.')
483
child_bzrdir = self.make_bzrdir('child')
484
parent_bzrdir.get_config().set_default_stack_on('child2')
485
repo_policy = child_bzrdir.determine_repository_policy()
486
self.assertEqual('child2', repo_policy._stack_on)
487
self.assertEqual(parent_bzrdir.root_transport.base,
488
repo_policy._stack_on_pwd)
490
def prepare_default_stacking(self, child_format='1.6'):
491
parent_bzrdir = self.make_bzrdir('.')
492
child_branch = self.make_branch('child', format=child_format)
493
parent_bzrdir.get_config().set_default_stack_on(child_branch.base)
494
new_child_transport = parent_bzrdir.transport.clone('child2')
495
return child_branch, new_child_transport
497
def test_clone_on_transport_obeys_stacking_policy(self):
498
child_branch, new_child_transport = self.prepare_default_stacking()
499
new_child = child_branch.bzrdir.clone_on_transport(new_child_transport)
500
self.assertEqual(child_branch.base,
501
new_child.open_branch().get_stacked_on_url())
503
def test_default_stacking_with_stackable_branch_unstackable_repo(self):
504
# Make stackable source branch with an unstackable repo format.
505
source_bzrdir = self.make_bzrdir('source')
506
knitpack_repo.RepositoryFormatKnitPack1().initialize(source_bzrdir)
507
source_branch = bzrlib.branch.BzrBranchFormat7().initialize(
509
# Make a directory with a default stacking policy
510
parent_bzrdir = self.make_bzrdir('parent')
511
stacked_on = self.make_branch('parent/stacked-on', format='pack-0.92')
512
parent_bzrdir.get_config().set_default_stack_on(stacked_on.base)
513
# Clone source into directory
514
target = source_bzrdir.clone(self.get_url('parent/target'))
516
def test_format_initialize_on_transport_ex_stacked_on(self):
517
# trunk is a stackable format. Note that its in the same server area
518
# which is what launchpad does, but not sufficient to exercise the
520
trunk = self.make_branch('trunk', format='1.9')
521
t = self.get_transport('stacked')
522
old_fmt = bzrdir.format_registry.make_bzrdir('pack-0.92')
523
repo_name = old_fmt.repository_format.network_name()
524
# Should end up with a 1.9 format (stackable)
525
repo, control, require_stacking, repo_policy = \
526
old_fmt.initialize_on_transport_ex(t,
527
repo_format_name=repo_name, stacked_on='../trunk',
530
# Repositories are open write-locked
531
self.assertTrue(repo.is_write_locked())
532
self.addCleanup(repo.unlock)
534
repo = control.open_repository()
535
self.assertIsInstance(control, bzrdir.BzrDir)
536
opened = bzrdir.BzrDir.open(t.base)
537
if not isinstance(old_fmt, remote.RemoteBzrDirFormat):
538
self.assertEqual(control._format.network_name(),
539
old_fmt.network_name())
540
self.assertEqual(control._format.network_name(),
541
opened._format.network_name())
542
self.assertEqual(control.__class__, opened.__class__)
543
self.assertLength(1, repo._fallback_repositories)
545
def test_sprout_obeys_stacking_policy(self):
546
child_branch, new_child_transport = self.prepare_default_stacking()
547
new_child = child_branch.bzrdir.sprout(new_child_transport.base)
548
self.assertEqual(child_branch.base,
549
new_child.open_branch().get_stacked_on_url())
551
def test_clone_ignores_policy_for_unsupported_formats(self):
552
child_branch, new_child_transport = self.prepare_default_stacking(
553
child_format='pack-0.92')
554
new_child = child_branch.bzrdir.clone_on_transport(new_child_transport)
555
self.assertRaises(errors.UnstackableBranchFormat,
556
new_child.open_branch().get_stacked_on_url)
558
def test_sprout_ignores_policy_for_unsupported_formats(self):
559
child_branch, new_child_transport = self.prepare_default_stacking(
560
child_format='pack-0.92')
561
new_child = child_branch.bzrdir.sprout(new_child_transport.base)
562
self.assertRaises(errors.UnstackableBranchFormat,
563
new_child.open_branch().get_stacked_on_url)
565
def test_sprout_upgrades_format_if_stacked_specified(self):
566
child_branch, new_child_transport = self.prepare_default_stacking(
567
child_format='pack-0.92')
568
new_child = child_branch.bzrdir.sprout(new_child_transport.base,
570
self.assertEqual(child_branch.bzrdir.root_transport.base,
571
new_child.open_branch().get_stacked_on_url())
572
repo = new_child.open_repository()
573
self.assertTrue(repo._format.supports_external_lookups)
574
self.assertFalse(repo.supports_rich_root())
576
def test_clone_on_transport_upgrades_format_if_stacked_on_specified(self):
577
child_branch, new_child_transport = self.prepare_default_stacking(
578
child_format='pack-0.92')
579
new_child = child_branch.bzrdir.clone_on_transport(new_child_transport,
580
stacked_on=child_branch.bzrdir.root_transport.base)
581
self.assertEqual(child_branch.bzrdir.root_transport.base,
582
new_child.open_branch().get_stacked_on_url())
583
repo = new_child.open_repository()
584
self.assertTrue(repo._format.supports_external_lookups)
585
self.assertFalse(repo.supports_rich_root())
587
def test_sprout_upgrades_to_rich_root_format_if_needed(self):
588
child_branch, new_child_transport = self.prepare_default_stacking(
589
child_format='rich-root-pack')
590
new_child = child_branch.bzrdir.sprout(new_child_transport.base,
592
repo = new_child.open_repository()
593
self.assertTrue(repo._format.supports_external_lookups)
594
self.assertTrue(repo.supports_rich_root())
596
def test_add_fallback_repo_handles_absolute_urls(self):
597
stack_on = self.make_branch('stack_on', format='1.6')
598
repo = self.make_repository('repo', format='1.6')
599
policy = bzrdir.UseExistingRepository(repo, stack_on.base)
600
policy._add_fallback(repo)
602
def test_add_fallback_repo_handles_relative_urls(self):
603
stack_on = self.make_branch('stack_on', format='1.6')
604
repo = self.make_repository('repo', format='1.6')
605
policy = bzrdir.UseExistingRepository(repo, '.', stack_on.base)
606
policy._add_fallback(repo)
608
def test_configure_relative_branch_stacking_url(self):
609
stack_on = self.make_branch('stack_on', format='1.6')
610
stacked = self.make_branch('stack_on/stacked', format='1.6')
611
policy = bzrdir.UseExistingRepository(stacked.repository,
613
policy.configure_branch(stacked)
614
self.assertEqual('..', stacked.get_stacked_on_url())
616
def test_relative_branch_stacking_to_absolute(self):
617
stack_on = self.make_branch('stack_on', format='1.6')
618
stacked = self.make_branch('stack_on/stacked', format='1.6')
619
policy = bzrdir.UseExistingRepository(stacked.repository,
620
'.', self.get_readonly_url('stack_on'))
621
policy.configure_branch(stacked)
622
self.assertEqual(self.get_readonly_url('stack_on'),
623
stacked.get_stacked_on_url())
626
457
class ChrootedTests(TestCaseWithTransport):
627
458
"""A support class that provides readonly urls outside the local namespace.
650
478
branch, relpath = bzrdir.BzrDir.open_containing(self.get_readonly_url('g/p/q'))
651
479
self.assertEqual('g/p/q', relpath)
653
def test_open_containing_tree_branch_or_repository_empty(self):
654
self.assertRaises(errors.NotBranchError,
655
bzrdir.BzrDir.open_containing_tree_branch_or_repository,
656
self.get_readonly_url(''))
658
def test_open_containing_tree_branch_or_repository_all(self):
659
self.make_branch_and_tree('topdir')
660
tree, branch, repo, relpath = \
661
bzrdir.BzrDir.open_containing_tree_branch_or_repository(
663
self.assertEqual(os.path.realpath('topdir'),
664
os.path.realpath(tree.basedir))
665
self.assertEqual(os.path.realpath('topdir'),
666
self.local_branch_path(branch))
668
osutils.realpath(os.path.join('topdir', '.bzr', 'repository')),
669
repo.bzrdir.transport.local_abspath('repository'))
670
self.assertEqual(relpath, 'foo')
672
def test_open_containing_tree_branch_or_repository_no_tree(self):
673
self.make_branch('branch')
674
tree, branch, repo, relpath = \
675
bzrdir.BzrDir.open_containing_tree_branch_or_repository(
677
self.assertEqual(tree, None)
678
self.assertEqual(os.path.realpath('branch'),
679
self.local_branch_path(branch))
681
osutils.realpath(os.path.join('branch', '.bzr', 'repository')),
682
repo.bzrdir.transport.local_abspath('repository'))
683
self.assertEqual(relpath, 'foo')
685
def test_open_containing_tree_branch_or_repository_repo(self):
686
self.make_repository('repo')
687
tree, branch, repo, relpath = \
688
bzrdir.BzrDir.open_containing_tree_branch_or_repository(
690
self.assertEqual(tree, None)
691
self.assertEqual(branch, None)
693
osutils.realpath(os.path.join('repo', '.bzr', 'repository')),
694
repo.bzrdir.transport.local_abspath('repository'))
695
self.assertEqual(relpath, '')
697
def test_open_containing_tree_branch_or_repository_shared_repo(self):
698
self.make_repository('shared', shared=True)
699
bzrdir.BzrDir.create_branch_convenience('shared/branch',
700
force_new_tree=False)
701
tree, branch, repo, relpath = \
702
bzrdir.BzrDir.open_containing_tree_branch_or_repository(
704
self.assertEqual(tree, None)
705
self.assertEqual(os.path.realpath('shared/branch'),
706
self.local_branch_path(branch))
708
osutils.realpath(os.path.join('shared', '.bzr', 'repository')),
709
repo.bzrdir.transport.local_abspath('repository'))
710
self.assertEqual(relpath, '')
712
def test_open_containing_tree_branch_or_repository_branch_subdir(self):
713
self.make_branch_and_tree('foo')
714
self.build_tree(['foo/bar/'])
715
tree, branch, repo, relpath = \
716
bzrdir.BzrDir.open_containing_tree_branch_or_repository(
718
self.assertEqual(os.path.realpath('foo'),
719
os.path.realpath(tree.basedir))
720
self.assertEqual(os.path.realpath('foo'),
721
self.local_branch_path(branch))
723
osutils.realpath(os.path.join('foo', '.bzr', 'repository')),
724
repo.bzrdir.transport.local_abspath('repository'))
725
self.assertEqual(relpath, 'bar')
727
def test_open_containing_tree_branch_or_repository_repo_subdir(self):
728
self.make_repository('bar')
729
self.build_tree(['bar/baz/'])
730
tree, branch, repo, relpath = \
731
bzrdir.BzrDir.open_containing_tree_branch_or_repository(
733
self.assertEqual(tree, None)
734
self.assertEqual(branch, None)
736
osutils.realpath(os.path.join('bar', '.bzr', 'repository')),
737
repo.bzrdir.transport.local_abspath('repository'))
738
self.assertEqual(relpath, 'baz')
740
481
def test_open_containing_from_transport(self):
741
self.assertRaises(NotBranchError,
742
bzrdir.BzrDir.open_containing_from_transport,
743
_mod_transport.get_transport_from_url(self.get_readonly_url('')))
744
self.assertRaises(NotBranchError,
745
bzrdir.BzrDir.open_containing_from_transport,
746
_mod_transport.get_transport_from_url(
747
self.get_readonly_url('g/p/q')))
482
self.assertRaises(NotBranchError, bzrdir.BzrDir.open_containing_from_transport,
483
get_transport(self.get_readonly_url('')))
484
self.assertRaises(NotBranchError, bzrdir.BzrDir.open_containing_from_transport,
485
get_transport(self.get_readonly_url('g/p/q')))
748
486
control = bzrdir.BzrDir.create(self.get_url())
749
487
branch, relpath = bzrdir.BzrDir.open_containing_from_transport(
750
_mod_transport.get_transport_from_url(
751
self.get_readonly_url('')))
488
get_transport(self.get_readonly_url('')))
752
489
self.assertEqual('', relpath)
753
490
branch, relpath = bzrdir.BzrDir.open_containing_from_transport(
754
_mod_transport.get_transport_from_url(
755
self.get_readonly_url('g/p/q')))
491
get_transport(self.get_readonly_url('g/p/q')))
756
492
self.assertEqual('g/p/q', relpath)
758
494
def test_open_containing_tree_or_branch(self):
495
def local_branch_path(branch):
496
return os.path.realpath(
497
urlutils.local_path_from_url(branch.base))
759
499
self.make_branch_and_tree('topdir')
760
500
tree, branch, relpath = bzrdir.BzrDir.open_containing_tree_or_branch(
762
502
self.assertEqual(os.path.realpath('topdir'),
763
503
os.path.realpath(tree.basedir))
764
504
self.assertEqual(os.path.realpath('topdir'),
765
self.local_branch_path(branch))
505
local_branch_path(branch))
766
506
self.assertIs(tree.bzrdir, branch.bzrdir)
767
507
self.assertEqual('foo', relpath)
768
508
# opening from non-local should not return the tree
796
540
tree, branch = bzrdir.BzrDir.open_tree_or_branch('topdir/foo')
797
541
self.assertIs(tree, None)
798
542
self.assertEqual(os.path.realpath('topdir/foo'),
799
self.local_branch_path(branch))
543
local_branch_path(branch))
801
545
def test_open_from_transport(self):
802
546
# transport pointing at bzrdir should give a bzrdir with root transport
803
547
# set to the given transport
804
548
control = bzrdir.BzrDir.create(self.get_url())
805
t = self.get_transport()
806
opened_bzrdir = bzrdir.BzrDir.open_from_transport(t)
807
self.assertEqual(t.base, opened_bzrdir.root_transport.base)
549
transport = get_transport(self.get_url())
550
opened_bzrdir = bzrdir.BzrDir.open_from_transport(transport)
551
self.assertEqual(transport.base, opened_bzrdir.root_transport.base)
808
552
self.assertIsInstance(opened_bzrdir, bzrdir.BzrDir)
810
554
def test_open_from_transport_no_bzrdir(self):
811
t = self.get_transport()
812
self.assertRaises(NotBranchError, bzrdir.BzrDir.open_from_transport, t)
555
transport = get_transport(self.get_url())
556
self.assertRaises(NotBranchError, bzrdir.BzrDir.open_from_transport,
814
559
def test_open_from_transport_bzrdir_in_parent(self):
815
560
control = bzrdir.BzrDir.create(self.get_url())
816
t = self.get_transport()
818
t = t.clone('subdir')
819
self.assertRaises(NotBranchError, bzrdir.BzrDir.open_from_transport, t)
561
transport = get_transport(self.get_url())
562
transport.mkdir('subdir')
563
transport = transport.clone('subdir')
564
self.assertRaises(NotBranchError, bzrdir.BzrDir.open_from_transport,
821
567
def test_sprout_recursive(self):
822
tree = self.make_branch_and_tree('tree1',
823
format='dirstate-with-subtree')
568
tree = self.make_branch_and_tree('tree1', format='dirstate-with-subtree')
824
569
sub_tree = self.make_branch_and_tree('tree1/subtree',
825
570
format='dirstate-with-subtree')
826
sub_tree.set_root_id('subtree-root')
827
571
tree.add_reference(sub_tree)
828
572
self.build_tree(['tree1/subtree/file'])
829
573
sub_tree.add('file')
830
574
tree.commit('Initial commit')
831
tree2 = tree.bzrdir.sprout('tree2').open_workingtree()
833
self.addCleanup(tree2.unlock)
834
self.assertPathExists('tree2/subtree/file')
835
self.assertEqual('tree-reference', tree2.kind('subtree-root'))
575
tree.bzrdir.sprout('tree2')
576
self.failUnlessExists('tree2/subtree/file')
837
578
def test_cloning_metadir(self):
838
579
"""Ensure that cloning metadir is suitable"""
852
593
self.build_tree(['tree1/subtree/file'])
853
594
sub_tree.add('file')
854
595
tree.commit('Initial commit')
855
# The following line force the orhaning to reveal bug #634470
856
tree.branch.get_config().set_user_option(
857
'bzr.transform.orphan_policy', 'move')
858
596
tree.bzrdir.destroy_workingtree()
859
# FIXME: subtree/.bzr is left here which allows the test to pass (or
860
# fail :-( ) -- vila 20100909
861
597
repo = self.make_repository('repo', shared=True,
862
598
format='dirstate-with-subtree')
863
599
repo.set_make_working_trees(False)
864
# FIXME: we just deleted the workingtree and now we want to use it ????
865
# At a minimum, we should use tree.branch below (but this fails too
866
# currently) or stop calling this test 'treeless'. Specifically, I've
867
# turn the line below into an assertRaises when 'subtree/.bzr' is
868
# orphaned and sprout tries to access the branch there (which is left
869
# by bzrdir.BzrDirMeta1.destroy_workingtree when it ignores the
870
# [DeletingParent('Not deleting', u'subtree', None)] conflict). See bug
871
# #634470. -- vila 20100909
872
self.assertRaises(errors.NotBranchError,
873
tree.bzrdir.sprout, 'repo/tree2')
874
# self.assertPathExists('repo/tree2/subtree')
875
# self.assertPathDoesNotExist('repo/tree2/subtree/file')
600
tree.bzrdir.sprout('repo/tree2')
601
self.failUnlessExists('repo/tree2/subtree')
602
self.failIfExists('repo/tree2/subtree/file')
877
604
def make_foo_bar_baz(self):
878
605
foo = bzrdir.BzrDir.create_branch_convenience('foo').bzrdir
883
610
def test_find_bzrdirs(self):
884
611
foo, bar, baz = self.make_foo_bar_baz()
885
t = self.get_transport()
886
self.assertEqualBzrdirs([baz, foo, bar], bzrdir.BzrDir.find_bzrdirs(t))
888
def make_fake_permission_denied_transport(self, transport, paths):
889
"""Create a transport that raises PermissionDenied for some paths."""
892
raise errors.PermissionDenied(path)
894
path_filter_server = pathfilter.PathFilteringServer(transport, filter)
895
path_filter_server.start_server()
896
self.addCleanup(path_filter_server.stop_server)
897
path_filter_transport = pathfilter.PathFilteringTransport(
898
path_filter_server, '.')
899
return (path_filter_server, path_filter_transport)
901
def assertBranchUrlsEndWith(self, expect_url_suffix, actual_bzrdirs):
902
"""Check that each branch url ends with the given suffix."""
903
for actual_bzrdir in actual_bzrdirs:
904
self.assertEndsWith(actual_bzrdir.user_url, expect_url_suffix)
906
def test_find_bzrdirs_permission_denied(self):
907
foo, bar, baz = self.make_foo_bar_baz()
908
t = self.get_transport()
909
path_filter_server, path_filter_transport = \
910
self.make_fake_permission_denied_transport(t, ['foo'])
912
self.assertBranchUrlsEndWith('/baz/',
913
bzrdir.BzrDir.find_bzrdirs(path_filter_transport))
915
smart_transport = self.make_smart_server('.',
916
backing_server=path_filter_server)
917
self.assertBranchUrlsEndWith('/baz/',
918
bzrdir.BzrDir.find_bzrdirs(smart_transport))
612
transport = get_transport(self.get_url())
613
self.assertEqualBzrdirs([baz, foo, bar],
614
bzrdir.BzrDir.find_bzrdirs(transport))
920
616
def test_find_bzrdirs_list_current(self):
921
617
def list_current(transport):
922
618
return [s for s in transport.list_dir('') if s != 'baz']
924
620
foo, bar, baz = self.make_foo_bar_baz()
925
t = self.get_transport()
926
self.assertEqualBzrdirs(
928
bzrdir.BzrDir.find_bzrdirs(t, list_current=list_current))
621
transport = get_transport(self.get_url())
622
self.assertEqualBzrdirs([foo, bar],
623
bzrdir.BzrDir.find_bzrdirs(transport,
624
list_current=list_current))
930
627
def test_find_bzrdirs_evaluate(self):
931
628
def evaluate(bzrdir):
933
630
repo = bzrdir.open_repository()
934
except errors.NoRepositoryPresent:
631
except NoRepositoryPresent:
935
632
return True, bzrdir.root_transport.base
937
634
return False, bzrdir.root_transport.base
939
636
foo, bar, baz = self.make_foo_bar_baz()
940
t = self.get_transport()
637
transport = get_transport(self.get_url())
941
638
self.assertEqual([baz.root_transport.base, foo.root_transport.base],
942
list(bzrdir.BzrDir.find_bzrdirs(t, evaluate=evaluate)))
639
list(bzrdir.BzrDir.find_bzrdirs(transport,
944
642
def assertEqualBzrdirs(self, first, second):
945
643
first = list(first)
952
650
root = self.make_repository('', shared=True)
953
651
foo, bar, baz = self.make_foo_bar_baz()
954
652
qux = self.make_bzrdir('foo/qux')
955
t = self.get_transport()
956
branches = bzrdir.BzrDir.find_branches(t)
653
transport = get_transport(self.get_url())
654
branches = bzrdir.BzrDir.find_branches(transport)
957
655
self.assertEqual(baz.root_transport.base, branches[0].base)
958
656
self.assertEqual(foo.root_transport.base, branches[1].base)
959
657
self.assertEqual(bar.root_transport.base, branches[2].base)
961
659
# ensure this works without a top-level repo
962
branches = bzrdir.BzrDir.find_branches(t.clone('foo'))
660
branches = bzrdir.BzrDir.find_branches(transport.clone('foo'))
963
661
self.assertEqual(foo.root_transport.base, branches[0].base)
964
662
self.assertEqual(bar.root_transport.base, branches[1].base)
967
class TestMissingRepoBranchesSkipped(TestCaseWithMemoryTransport):
969
def test_find_bzrdirs_missing_repo(self):
970
t = self.get_transport()
971
arepo = self.make_repository('arepo', shared=True)
972
abranch_url = arepo.user_url + '/abranch'
973
abranch = bzrdir.BzrDir.create(abranch_url).create_branch()
974
t.delete_tree('arepo/.bzr')
975
self.assertRaises(errors.NoRepositoryPresent,
976
branch.Branch.open, abranch_url)
977
self.make_branch('baz')
978
for actual_bzrdir in bzrdir.BzrDir.find_branches(t):
979
self.assertEndsWith(actual_bzrdir.user_url, '/baz/')
982
665
class TestMeta1DirFormat(TestCaseWithTransport):
983
666
"""Tests specific to the meta1 dir format."""
1024
706
def test_needs_conversion_different_working_tree(self):
1025
707
# meta1dirs need an conversion if any element is not the default.
1026
new_format = bzrdir.format_registry.make_bzrdir('dirstate')
1027
tree = self.make_branch_and_tree('tree', format='knit')
1028
self.assertTrue(tree.bzrdir.needs_format_conversion(
1031
def test_initialize_on_format_uses_smart_transport(self):
1032
self.setup_smart_server_with_call_log()
1033
new_format = bzrdir.format_registry.make_bzrdir('dirstate')
1034
transport = self.get_transport('target')
1035
transport.ensure_base()
1036
self.reset_smart_call_log()
1037
instance = new_format.initialize_on_transport(transport)
1038
self.assertIsInstance(instance, remote.RemoteBzrDir)
1039
rpc_count = len(self.hpss_calls)
1040
# This figure represent the amount of work to perform this use case. It
1041
# is entirely ok to reduce this number if a test fails due to rpc_count
1042
# being too low. If rpc_count increases, more network roundtrips have
1043
# become necessary for this use case. Please do not adjust this number
1044
# upwards without agreement from bzr's network support maintainers.
1045
self.assertEqual(2, rpc_count)
708
old_format = bzrdir.BzrDirFormat.get_default_format()
710
new_default = bzrdir.format_registry.make_bzrdir('dirstate')
711
bzrdir.BzrDirFormat._set_default_format(new_default)
713
tree = self.make_branch_and_tree('tree', format='knit')
714
self.assertTrue(tree.bzrdir.needs_format_conversion())
716
bzrdir.BzrDirFormat._set_default_format(old_format)
719
class TestFormat5(TestCaseWithTransport):
720
"""Tests specific to the version 5 bzrdir format."""
722
def test_same_lockfiles_between_tree_repo_branch(self):
723
# this checks that only a single lockfiles instance is created
724
# for format 5 objects
725
dir = bzrdir.BzrDirFormat5().initialize(self.get_url())
726
def check_dir_components_use_same_lock(dir):
727
ctrl_1 = dir.open_repository().control_files
728
ctrl_2 = dir.open_branch().control_files
729
ctrl_3 = dir.open_workingtree()._control_files
730
self.assertTrue(ctrl_1 is ctrl_2)
731
self.assertTrue(ctrl_2 is ctrl_3)
732
check_dir_components_use_same_lock(dir)
733
# and if we open it normally.
734
dir = bzrdir.BzrDir.open(self.get_url())
735
check_dir_components_use_same_lock(dir)
737
def test_can_convert(self):
738
# format 5 dirs are convertable
739
dir = bzrdir.BzrDirFormat5().initialize(self.get_url())
740
self.assertTrue(dir.can_convert_format())
742
def test_needs_conversion(self):
743
# format 5 dirs need a conversion if they are not the default.
744
# and they start of not the default.
745
old_format = bzrdir.BzrDirFormat.get_default_format()
746
bzrdir.BzrDirFormat._set_default_format(bzrdir.BzrDirFormat5())
748
dir = bzrdir.BzrDirFormat5().initialize(self.get_url())
749
self.assertFalse(dir.needs_format_conversion())
751
bzrdir.BzrDirFormat._set_default_format(old_format)
752
self.assertTrue(dir.needs_format_conversion())
755
class TestFormat6(TestCaseWithTransport):
756
"""Tests specific to the version 6 bzrdir format."""
758
def test_same_lockfiles_between_tree_repo_branch(self):
759
# this checks that only a single lockfiles instance is created
760
# for format 6 objects
761
dir = bzrdir.BzrDirFormat6().initialize(self.get_url())
762
def check_dir_components_use_same_lock(dir):
763
ctrl_1 = dir.open_repository().control_files
764
ctrl_2 = dir.open_branch().control_files
765
ctrl_3 = dir.open_workingtree()._control_files
766
self.assertTrue(ctrl_1 is ctrl_2)
767
self.assertTrue(ctrl_2 is ctrl_3)
768
check_dir_components_use_same_lock(dir)
769
# and if we open it normally.
770
dir = bzrdir.BzrDir.open(self.get_url())
771
check_dir_components_use_same_lock(dir)
773
def test_can_convert(self):
774
# format 6 dirs are convertable
775
dir = bzrdir.BzrDirFormat6().initialize(self.get_url())
776
self.assertTrue(dir.can_convert_format())
778
def test_needs_conversion(self):
779
# format 6 dirs need an conversion if they are not the default.
780
old_format = bzrdir.BzrDirFormat.get_default_format()
781
bzrdir.BzrDirFormat._set_default_format(bzrdir.BzrDirMetaFormat1())
783
dir = bzrdir.BzrDirFormat6().initialize(self.get_url())
784
self.assertTrue(dir.needs_format_conversion())
786
bzrdir.BzrDirFormat._set_default_format(old_format)
789
class NotBzrDir(bzrlib.bzrdir.BzrDir):
790
"""A non .bzr based control directory."""
792
def __init__(self, transport, format):
793
self._format = format
794
self.root_transport = transport
795
self.transport = transport.clone('.not')
798
class NotBzrDirFormat(bzrlib.bzrdir.BzrDirFormat):
799
"""A test class representing any non-.bzr based disk format."""
801
def initialize_on_transport(self, transport):
802
"""Initialize a new .not dir in the base directory of a Transport."""
803
transport.mkdir('.not')
804
return self.open(transport)
806
def open(self, transport):
807
"""Open this directory."""
808
return NotBzrDir(transport, self)
811
def _known_formats(self):
812
return set([NotBzrDirFormat()])
815
def probe_transport(self, transport):
816
"""Our format is present if the transport ends in '.not/'."""
817
if transport.has('.not'):
818
return NotBzrDirFormat()
821
class TestNotBzrDir(TestCaseWithTransport):
822
"""Tests for using the bzrdir api with a non .bzr based disk format.
824
If/when one of these is in the core, we can let the implementation tests
828
def test_create_and_find_format(self):
829
# create a .notbzr dir
830
format = NotBzrDirFormat()
831
dir = format.initialize(self.get_url())
832
self.assertIsInstance(dir, NotBzrDir)
834
bzrlib.bzrdir.BzrDirFormat.register_control_format(format)
836
found = bzrlib.bzrdir.BzrDirFormat.find_format(
837
get_transport(self.get_url()))
838
self.assertIsInstance(found, NotBzrDirFormat)
840
bzrlib.bzrdir.BzrDirFormat.unregister_control_format(format)
842
def test_included_in_known_formats(self):
843
bzrlib.bzrdir.BzrDirFormat.register_control_format(NotBzrDirFormat)
845
formats = bzrlib.bzrdir.BzrDirFormat.known_formats()
846
for format in formats:
847
if isinstance(format, NotBzrDirFormat):
849
self.fail("No NotBzrDirFormat in %s" % formats)
851
bzrlib.bzrdir.BzrDirFormat.unregister_control_format(NotBzrDirFormat)
1048
854
class NonLocalTests(TestCaseWithTransport):
1091
897
my_bzrdir = bzrdir.BzrDir.open(self.get_url('branch-knit2'))
1092
898
checkout_format = my_bzrdir.checkout_metadir()
1093
899
self.assertIsInstance(checkout_format.workingtree_format,
1094
workingtree_4.WorkingTreeFormat4)
1097
class TestHTTPRedirections(object):
1098
"""Test redirection between two http servers.
900
workingtree.WorkingTreeFormat3)
903
class TestHTTPRedirectionLoop(object):
904
"""Test redirection loop between two http servers.
1100
906
This MUST be used by daughter classes that also inherit from
1101
907
TestCaseWithTwoWebservers.
1103
909
We can't inherit directly from TestCaseWithTwoWebservers or the
1104
910
test framework will try to create an instance which cannot
1105
run, its implementation being incomplete.
911
run, its implementation being incomplete.
914
# Should be defined by daughter classes to ensure redirection
915
# still use the same transport implementation (not currently
916
# enforced as it's a bit tricky to get right (see the FIXME
917
# in BzrDir.open_from_transport for the unique use case so
1108
921
def create_transport_readonly_server(self):
1109
# We don't set the http protocol version, relying on the default
1110
return http_utils.HTTPServerRedirecting()
922
return HTTPServerRedirecting()
1112
924
def create_transport_secondary_server(self):
1113
# We don't set the http protocol version, relying on the default
1114
return http_utils.HTTPServerRedirecting()
925
return HTTPServerRedirecting()
1116
927
def setUp(self):
1117
super(TestHTTPRedirections, self).setUp()
928
# Both servers redirect to each server creating a loop
929
super(TestHTTPRedirectionLoop, self).setUp()
1118
930
# The redirections will point to the new server
1119
931
self.new_server = self.get_readonly_server()
1120
932
# The requests to the old server will be redirected
1121
933
self.old_server = self.get_secondary_server()
1122
934
# Configure the redirections
1123
935
self.old_server.redirect_to(self.new_server.host, self.new_server.port)
936
self.new_server.redirect_to(self.old_server.host, self.old_server.port)
938
def _qualified_url(self, host, port):
939
return 'http+%s://%s:%s' % (self._qualifier, host, port)
1125
941
def test_loop(self):
1126
# Both servers redirect to each other creating a loop
1127
self.new_server.redirect_to(self.old_server.host, self.old_server.port)
1128
942
# Starting from either server should loop
1129
old_url = self._qualified_url(self.old_server.host,
943
old_url = self._qualified_url(self.old_server.host,
1130
944
self.old_server.port)
1131
945
oldt = self._transport(old_url)
1132
946
self.assertRaises(errors.NotBranchError,
1133
947
bzrdir.BzrDir.open_from_transport, oldt)
1134
new_url = self._qualified_url(self.new_server.host,
948
new_url = self._qualified_url(self.new_server.host,
1135
949
self.new_server.port)
1136
950
newt = self._transport(new_url)
1137
951
self.assertRaises(errors.NotBranchError,
1138
952
bzrdir.BzrDir.open_from_transport, newt)
1140
def test_qualifier_preserved(self):
1141
wt = self.make_branch_and_tree('branch')
1142
old_url = self._qualified_url(self.old_server.host,
1143
self.old_server.port)
1144
start = self._transport(old_url).clone('branch')
1145
bdir = bzrdir.BzrDir.open_from_transport(start)
1146
# Redirection should preserve the qualifier, hence the transport class
1148
self.assertIsInstance(bdir.root_transport, type(start))
1151
class TestHTTPRedirections_urllib(TestHTTPRedirections,
1152
http_utils.TestCaseWithTwoWebservers):
955
class TestHTTPRedirections_urllib(TestHTTPRedirectionLoop,
956
TestCaseWithTwoWebservers):
1153
957
"""Tests redirections for urllib implementation"""
959
_qualifier = 'urllib'
1155
960
_transport = HttpTransport_urllib
1157
def _qualified_url(self, host, port):
1158
result = 'http+urllib://%s:%s' % (host, port)
1159
self.permit_url(result)
1164
964
class TestHTTPRedirections_pycurl(TestWithTransport_pycurl,
1165
TestHTTPRedirections,
1166
http_utils.TestCaseWithTwoWebservers):
965
TestHTTPRedirectionLoop,
966
TestCaseWithTwoWebservers):
1167
967
"""Tests redirections for pycurl implementation"""
1169
def _qualified_url(self, host, port):
1170
result = 'http+pycurl://%s:%s' % (host, port)
1171
self.permit_url(result)
1175
class TestHTTPRedirections_nosmart(TestHTTPRedirections,
1176
http_utils.TestCaseWithTwoWebservers):
1177
"""Tests redirections for the nosmart decorator"""
1179
_transport = NoSmartTransportDecorator
1181
def _qualified_url(self, host, port):
1182
result = 'nosmart+http://%s:%s' % (host, port)
1183
self.permit_url(result)
1187
class TestHTTPRedirections_readonly(TestHTTPRedirections,
1188
http_utils.TestCaseWithTwoWebservers):
1189
"""Tests redirections for readonly decoratror"""
1191
_transport = ReadonlyTransportDecorator
1193
def _qualified_url(self, host, port):
1194
result = 'readonly+http://%s:%s' % (host, port)
1195
self.permit_url(result)
969
_qualifier = 'pycurl'
1199
972
class TestDotBzrHidden(TestCaseWithTransport):
1223
996
b = bzrdir.BzrDir.create(urlutils.local_path_to_url('.'))
1224
997
self.build_tree(['a'])
1225
998
self.assertEquals(['a'], self.get_ls())
1228
class _TestBzrDirFormat(bzrdir.BzrDirMetaFormat1):
1229
"""Test BzrDirFormat implementation for TestBzrDirSprout."""
1231
def _open(self, transport):
1232
return _TestBzrDir(transport, self)
1235
class _TestBzrDir(bzrdir.BzrDirMeta1):
1236
"""Test BzrDir implementation for TestBzrDirSprout.
1238
When created a _TestBzrDir already has repository and a branch. The branch
1239
is a test double as well.
1242
def __init__(self, *args, **kwargs):
1243
super(_TestBzrDir, self).__init__(*args, **kwargs)
1244
self.test_branch = _TestBranch(self.transport)
1245
self.test_branch.repository = self.create_repository()
1247
def open_branch(self, unsupported=False):
1248
return self.test_branch
1250
def cloning_metadir(self, require_stacking=False):
1251
return _TestBzrDirFormat()
1254
class _TestBranchFormat(bzrlib.branch.BranchFormat):
1255
"""Test Branch format for TestBzrDirSprout."""
1258
class _TestBranch(bzrlib.branch.Branch):
1259
"""Test Branch implementation for TestBzrDirSprout."""
1261
def __init__(self, transport, *args, **kwargs):
1262
self._format = _TestBranchFormat()
1263
self._transport = transport
1264
self.base = transport.base
1265
super(_TestBranch, self).__init__(*args, **kwargs)
1269
def sprout(self, *args, **kwargs):
1270
self.calls.append('sprout')
1271
return _TestBranch(self._transport)
1273
def copy_content_into(self, destination, revision_id=None):
1274
self.calls.append('copy_content_into')
1276
def last_revision(self):
1277
return _mod_revision.NULL_REVISION
1279
def get_parent(self):
1282
def _get_config(self):
1283
return config.TransportConfig(self._transport, 'branch.conf')
1285
def set_parent(self, parent):
1286
self._parent = parent
1288
def lock_read(self):
1289
return lock.LogicalLockResult(self.unlock)
1295
class TestBzrDirSprout(TestCaseWithMemoryTransport):
1297
def test_sprout_uses_branch_sprout(self):
1298
"""BzrDir.sprout calls Branch.sprout.
1300
Usually, BzrDir.sprout should delegate to the branch's sprout method
1301
for part of the work. This allows the source branch to control the
1302
choice of format for the new branch.
1304
There are exceptions, but this tests avoids them:
1305
- if there's no branch in the source bzrdir,
1306
- or if the stacking has been requested and the format needs to be
1307
overridden to satisfy that.
1309
# Make an instrumented bzrdir.
1310
t = self.get_transport('source')
1312
source_bzrdir = _TestBzrDirFormat().initialize_on_transport(t)
1313
# The instrumented bzrdir has a test_branch attribute that logs calls
1314
# made to the branch contained in that bzrdir. Initially the test
1315
# branch exists but no calls have been made to it.
1316
self.assertEqual([], source_bzrdir.test_branch.calls)
1319
target_url = self.get_url('target')
1320
result = source_bzrdir.sprout(target_url, recurse='no')
1322
# The bzrdir called the branch's sprout method.
1323
self.assertSubset(['sprout'], source_bzrdir.test_branch.calls)
1325
def test_sprout_parent(self):
1326
grandparent_tree = self.make_branch('grandparent')
1327
parent = grandparent_tree.bzrdir.sprout('parent').open_branch()
1328
branch_tree = parent.bzrdir.sprout('branch').open_branch()
1329
self.assertContainsRe(branch_tree.get_parent(), '/parent/$')
1332
class TestBzrDirHooks(TestCaseWithMemoryTransport):
1334
def test_pre_open_called(self):
1336
bzrdir.BzrDir.hooks.install_named_hook('pre_open', calls.append, None)
1337
transport = self.get_transport('foo')
1338
url = transport.base
1339
self.assertRaises(errors.NotBranchError, bzrdir.BzrDir.open, url)
1340
self.assertEqual([transport.base], [t.base for t in calls])
1342
def test_pre_open_actual_exceptions_raised(self):
1344
def fail_once(transport):
1347
raise errors.BzrError("fail")
1348
bzrdir.BzrDir.hooks.install_named_hook('pre_open', fail_once, None)
1349
transport = self.get_transport('foo')
1350
url = transport.base
1351
err = self.assertRaises(errors.BzrError, bzrdir.BzrDir.open, url)
1352
self.assertEqual('fail', err._preformatted_string)
1354
def test_post_repo_init(self):
1355
from bzrlib.controldir import RepoInitHookParams
1357
bzrdir.BzrDir.hooks.install_named_hook('post_repo_init',
1359
self.make_repository('foo')
1360
self.assertLength(1, calls)
1362
self.assertIsInstance(params, RepoInitHookParams)
1363
self.assertTrue(hasattr(params, 'bzrdir'))
1364
self.assertTrue(hasattr(params, 'repository'))
1366
def test_post_repo_init_hook_repr(self):
1368
bzrdir.BzrDir.hooks.install_named_hook('post_repo_init',
1369
lambda params: param_reprs.append(repr(params)), None)
1370
self.make_repository('foo')
1371
self.assertLength(1, param_reprs)
1372
param_repr = param_reprs[0]
1373
self.assertStartsWith(param_repr, '<RepoInitHookParams for ')
1376
class TestGenerateBackupName(TestCaseWithMemoryTransport):
1377
# FIXME: This may need to be unified with test_osutils.TestBackupNames or
1378
# moved to per_bzrdir or per_transport for better coverage ?
1382
super(TestGenerateBackupName, self).setUp()
1383
self._transport = self.get_transport()
1384
bzrdir.BzrDir.create(self.get_url(),
1385
possible_transports=[self._transport])
1386
self._bzrdir = bzrdir.BzrDir.open_from_transport(self._transport)
1388
def test_deprecated_generate_backup_name(self):
1389
res = self.applyDeprecated(
1390
symbol_versioning.deprecated_in((2, 3, 0)),
1391
self._bzrdir.generate_backup_name, 'whatever')
1394
self.assertEqual("a.~1~", self._bzrdir._available_backup_name("a"))
1396
def test_exiting(self):
1397
self._transport.put_bytes("a.~1~", "some content")
1398
self.assertEqual("a.~2~", self._bzrdir._available_backup_name("a"))
1401
class TestMeta1DirColoFormat(TestCaseWithTransport):
1402
"""Tests specific to the meta1 dir with colocated branches format."""
1404
def test_supports_colo(self):
1405
format = bzrdir.BzrDirMetaFormat1Colo()
1406
self.assertTrue(format.colocated_branches)
1408
def test_upgrade_from_2a(self):
1409
tree = self.make_branch_and_tree('.', format='2a')
1410
format = bzrdir.BzrDirMetaFormat1Colo()
1411
self.assertTrue(tree.bzrdir.needs_format_conversion(format))
1412
converter = tree.bzrdir._format.get_converter(format)
1413
result = converter.convert(tree.bzrdir, None)
1414
self.assertIsInstance(result._format, bzrdir.BzrDirMetaFormat1Colo)
1415
self.assertFalse(result.needs_format_conversion(format))
1417
def test_downgrade_to_2a(self):
1418
tree = self.make_branch_and_tree('.', format='development-colo')
1419
format = bzrdir.BzrDirMetaFormat1()
1420
self.assertTrue(tree.bzrdir.needs_format_conversion(format))
1421
converter = tree.bzrdir._format.get_converter(format)
1422
result = converter.convert(tree.bzrdir, None)
1423
self.assertIsInstance(result._format, bzrdir.BzrDirMetaFormat1)
1424
self.assertFalse(result.needs_format_conversion(format))
1426
def test_downgrade_to_2a_too_many_branches(self):
1427
tree = self.make_branch_and_tree('.', format='development-colo')
1428
tree.bzrdir.create_branch(name="another-colocated-branch")
1429
converter = tree.bzrdir._format.get_converter(
1430
bzrdir.BzrDirMetaFormat1())
1431
self.assertRaises(errors.BzrError, converter.convert, tree.bzrdir,