1
# Copyright (C) 2005, 2006, 2007, 2008 Canonical Ltd
1
# Copyright (C) 2005-2010 Canonical Ltd
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
17
17
"""Tests for branch implementations - tests a branch format."""
22
19
from bzrlib import (
20
branch as _mod_branch,
34
from bzrlib.branch import Branch, needs_read_lock, needs_write_lock
35
from bzrlib.delta import TreeDelta
36
from bzrlib.errors import (FileExists,
39
UninitializableFormat,
42
from bzrlib.osutils import getcwd
43
import bzrlib.revision
44
34
from bzrlib.symbol_versioning import deprecated_in
45
from bzrlib.tests import TestCase, TestCaseWithTransport, TestSkipped
35
from bzrlib.tests import (
46
39
from bzrlib.tests.http_server import HttpServer
47
from bzrlib.tests.per_branch import TestCaseWithBranch
48
from bzrlib.trace import mutter
49
from bzrlib.transport import get_transport
50
from bzrlib.transport.memory import MemoryServer
51
from bzrlib.upgrade import upgrade
52
from bzrlib.workingtree import WorkingTree
55
class TestTestCaseWithBranch(TestCaseWithBranch):
40
from bzrlib.transport import memory
43
class TestTestCaseWithBranch(per_branch.TestCaseWithBranch):
57
45
def test_branch_format_matches_bzrdir_branch_format(self):
58
46
bzrdir_branch_format = self.bzrdir_format.get_branch_format()
65
53
branch._format.__class__)
68
class TestBranch(TestCaseWithBranch):
56
class TestBranch(per_branch.TestCaseWithBranch):
70
58
def test_create_tree_with_merge(self):
71
59
tree = self.create_tree_with_merge()
128
116
tree_a.commit('rev2', rev_id='rev2')
130
118
delta = tree_a.branch.get_revision_delta(1)
131
self.assertIsInstance(delta, TreeDelta)
119
self.assertIsInstance(delta, _mod_delta.TreeDelta)
132
120
self.assertEqual([('foo', 'file1', 'file')], delta.added)
133
121
delta = tree_a.branch.get_revision_delta(2)
134
self.assertIsInstance(delta, TreeDelta)
122
self.assertIsInstance(delta, _mod_delta.TreeDelta)
135
123
self.assertEqual([('vla', 'file2', 'file')], delta.added)
137
125
def get_unbalanced_tree_pair(self):
187
175
def test_clone_branch_nickname(self):
188
176
# test the nick name is preserved always
189
raise TestSkipped('XXX branch cloning is not yet tested.')
177
raise tests.TestSkipped('XXX branch cloning is not yet tested.')
191
179
def test_clone_branch_parent(self):
192
180
# test the parent is preserved always
358
346
explicit nickname is set. That is, an explicit nickname always
359
347
overrides the implicit one.
361
t = get_transport(self.get_url())
349
t = transport.get_transport(self.get_url())
362
350
branch = self.make_branch('bzr.dev')
363
351
# The nick will be 'bzr.dev', because there is no explicit nick set.
364
352
self.assertEqual(branch.nick, 'bzr.dev')
365
353
# Move the branch to a different directory, 'bzr.ab'. Now that branch
366
354
# will report its nick as 'bzr.ab'.
367
355
t.move('bzr.dev', 'bzr.ab')
368
branch = Branch.open(self.get_url('bzr.ab'))
356
branch = _mod_branch.Branch.open(self.get_url('bzr.ab'))
369
357
self.assertEqual(branch.nick, 'bzr.ab')
370
358
# Set the branch nick explicitly. This will ensure there's a branch
371
359
# config file in the branch.
376
364
# "Aaron's branch", regardless of directory name.
377
365
self.assertEqual(branch.nick, "Aaron's branch")
378
366
t.move('bzr.ab', 'integration')
379
branch = Branch.open(self.get_url('integration'))
367
branch = _mod_branch.Branch.open(self.get_url('integration'))
380
368
self.assertEqual(branch.nick, "Aaron's branch")
381
369
branch.nick = u"\u1234"
382
370
self.assertEqual(branch.nick, u"\u1234")
407
395
self.assertEqual(repo.bzrdir.root_transport.base,
408
396
child_branch.repository.bzrdir.root_transport.base)
409
child_branch = branch.Branch.open(self.get_url('child'))
397
child_branch = _mod_branch.Branch.open(self.get_url('child'))
410
398
self.assertEqual(repo.bzrdir.root_transport.base,
411
399
child_branch.repository.bzrdir.root_transport.base)
435
423
def test_generate_revision_history_NULL_REVISION(self):
436
424
tree = self.make_branch_and_tree('.')
437
425
rev1 = tree.commit('foo')
438
tree.branch.generate_revision_history(bzrlib.revision.NULL_REVISION)
426
tree.branch.generate_revision_history(revision.NULL_REVISION)
439
427
self.assertEqual([], tree.branch.revision_history())
441
429
def test_create_checkout(self):
453
441
self.assertEqual('rev2', branch_a.last_revision())
454
442
self.assertEqual(checkout_c.branch.base, branch_a.base)
457
444
checkout_d = branch_a.create_checkout('d', lightweight=True)
458
445
self.assertEqual('rev2', checkout_d.last_revision())
460
446
checkout_e = branch_a.create_checkout('e')
461
447
self.assertEqual('rev2', checkout_e.last_revision())
465
451
tree_a = self.make_branch_and_tree('a')
466
452
rev_id = tree_a.commit('put some content in the branch')
467
453
# open the branch via a readonly transport
468
source_branch = bzrlib.branch.Branch.open(self.get_readonly_url('a'))
454
source_branch = _mod_branch.Branch.open(self.get_readonly_url('a'))
469
455
# sanity check that the test will be valid
470
456
self.assertRaises((errors.LockError, errors.TransportNotPossible),
471
457
source_branch.lock_write)
477
463
tree_a = self.make_branch_and_tree('a')
478
464
rev_id = tree_a.commit('put some content in the branch')
479
465
# open the branch via a readonly transport
480
source_branch = bzrlib.branch.Branch.open(self.get_readonly_url('a'))
466
source_branch = _mod_branch.Branch.open(self.get_readonly_url('a'))
481
467
# sanity check that the test will be valid
482
468
self.assertRaises((errors.LockError, errors.TransportNotPossible),
483
469
source_branch.lock_write)
494
480
self.assertEquals(br.revision_history(), [])
497
class TestBranchFormat(TestCaseWithBranch):
483
class TestBranchFormat(per_branch.TestCaseWithBranch):
499
485
def test_branch_format_network_name(self):
500
486
br = self.make_branch('.')
511
497
real_branch = br._real_branch
512
498
self.assertEqual(real_branch._format.network_name(), network_name)
514
registry = branch.network_format_registry
500
registry = _mod_branch.network_format_registry
515
501
looked_up_format = registry.get(network_name)
516
502
self.assertEqual(format.__class__, looked_up_format.__class__)
519
class ChrootedTests(TestCaseWithBranch):
505
class ChrootedTests(per_branch.TestCaseWithBranch):
520
506
"""A support class that provides readonly urls outside the local namespace.
522
508
This is done by checking if self.transport_server is a MemoryServer. if it
528
514
super(ChrootedTests, self).setUp()
529
if not self.vfs_transport_factory == MemoryServer:
515
if not self.vfs_transport_factory == memory.MemoryServer:
530
516
self.transport_readonly_server = HttpServer
532
518
def test_open_containing(self):
533
self.assertRaises(NotBranchError, Branch.open_containing,
519
self.assertRaises(errors.NotBranchError,
520
_mod_branch.Branch.open_containing,
534
521
self.get_readonly_url(''))
535
self.assertRaises(NotBranchError, Branch.open_containing,
522
self.assertRaises(errors.NotBranchError,
523
_mod_branch.Branch.open_containing,
536
524
self.get_readonly_url('g/p/q'))
537
525
branch = self.make_branch('.')
538
branch, relpath = Branch.open_containing(self.get_readonly_url(''))
526
branch, relpath = _mod_branch.Branch.open_containing(
527
self.get_readonly_url(''))
539
528
self.assertEqual('', relpath)
540
branch, relpath = Branch.open_containing(self.get_readonly_url('g/p/q'))
529
branch, relpath = _mod_branch.Branch.open_containing(
530
self.get_readonly_url('g/p/q'))
541
531
self.assertEqual('g/p/q', relpath)
564
554
def unlock(self):
565
555
self._calls.append('ul')
557
@_mod_branch.needs_read_lock
568
558
def do_with_read(self):
561
@_mod_branch.needs_read_lock
572
562
def except_with_read(self):
573
563
raise RuntimeError
565
@_mod_branch.needs_write_lock
576
566
def do_with_write(self):
569
@_mod_branch.needs_write_lock
580
570
def except_with_write(self):
581
571
raise RuntimeError
584
class TestDecorators(TestCase):
574
class TestDecorators(tests.TestCase):
586
576
def test_needs_read_lock(self):
587
577
branch = TestDecorator()
604
594
self.assertEqual(['lw', 'ul'], branch._calls)
607
class TestBranchPushLocations(TestCaseWithBranch):
597
class TestBranchPushLocations(per_branch.TestCaseWithBranch):
609
599
def test_get_push_location_unset(self):
610
600
self.assertEqual(None, self.get_branch().get_push_location())
625
615
self.assertEqual('foo', branch.get_push_location())
628
class TestChildSubmitFormats(TestCaseWithBranch):
618
class TestChildSubmitFormats(per_branch.TestCaseWithBranch):
630
620
def test_get_child_submit_format_default(self):
631
621
self.assertEqual(None, self.get_branch().get_child_submit_format())
637
627
self.assertEqual('10', branch.get_child_submit_format())
640
class TestFormat(TestCaseWithBranch):
630
class TestFormat(per_branch.TestCaseWithBranch):
641
631
"""Tests for the format itself."""
643
633
def test_get_reference(self):
677
667
# they may not be initializable.
679
669
# supported formats must be able to init and open
680
t = get_transport(self.get_url())
681
readonly_t = get_transport(self.get_readonly_url())
670
t = transport.get_transport(self.get_url())
671
readonly_t = transport.get_transport(self.get_readonly_url())
682
672
made_branch = self.make_branch('.')
683
self.failUnless(isinstance(made_branch, branch.Branch))
673
self.failUnless(isinstance(made_branch, _mod_branch.Branch))
685
675
# find it via bzrdir opening:
686
676
opened_control = bzrdir.BzrDir.open(readonly_t.base)
691
681
self.branch_format.__class__))
693
683
# find it via Branch.open
694
opened_branch = branch.Branch.open(readonly_t.base)
684
opened_branch = _mod_branch.Branch.open(readonly_t.base)
695
685
self.failUnless(isinstance(opened_branch, made_branch.__class__))
696
686
self.assertEqual(made_branch._format.__class__,
697
687
opened_branch._format.__class__)
704
694
opened_control.find_branch_format())
707
class TestBound(TestCaseWithBranch):
697
class TestBound(per_branch.TestCaseWithBranch):
709
699
def test_bind_unbind(self):
710
700
branch = self.make_branch('1')
742
732
raise tests.TestNotApplicable('Format does not support binding')
745
class TestStrict(TestCaseWithBranch):
735
class TestStrict(per_branch.TestCaseWithBranch):
747
737
def test_strict_history(self):
748
738
tree1 = self.make_branch_and_tree('tree1')
750
740
tree1.branch.set_append_revisions_only(True)
751
741
except errors.UpgradeRequired:
752
raise TestSkipped('Format does not support strict history')
742
raise tests.TestSkipped('Format does not support strict history')
753
743
tree1.commit('empty commit')
754
744
tree2 = tree1.bzrdir.sprout('tree2').open_workingtree()
755
745
tree2.commit('empty commit 2')
789
779
self.assertLength(1, reopened.repository._fallback_repositories)
792
class TestReferenceLocation(TestCaseWithBranch):
782
class TestReferenceLocation(per_branch.TestCaseWithBranch):
794
784
def test_reference_parent(self):
795
785
tree = self.make_branch_and_tree('tree')
797
787
subtree.set_root_id('subtree-id')
799
789
tree.add_reference(subtree)
800
except bzrlib.errors.UnsupportedOperation:
790
except errors.UnsupportedOperation:
801
791
raise tests.TestNotApplicable('Tree cannot hold references.')
802
792
reference_parent = tree.branch.reference_parent('subtree-id',
809
799
subtree.set_root_id('subtree-id')
811
801
tree.add_reference(subtree)
812
except bzrlib.errors.UnsupportedOperation:
802
except errors.UnsupportedOperation:
813
803
raise tests.TestNotApplicable('Tree cannot hold references.')
814
804
reference_parent = tree.branch.reference_parent('subtree-id',
815
805
'subtree', possible_transports=[subtree.bzrdir.root_transport])
818
808
branch = self.make_branch('branch')
820
810
path, loc = branch.get_reference_info('file-id')
821
except bzrlib.errors.UnsupportedOperation:
811
except errors.UnsupportedOperation:
822
812
raise tests.TestNotApplicable('Branch cannot hold references.')
823
813
self.assertIs(None, path)
824
814
self.assertIs(None, loc)
829
819
branch.set_reference_info('file-id', 'path/to/location',
831
except bzrlib.errors.UnsupportedOperation:
821
except errors.UnsupportedOperation:
832
822
raise tests.TestNotApplicable('Branch cannot hold references.')
834
824
def test_set_get_reference_info(self):
837
827
branch.set_reference_info('file-id', 'path/to/file',
838
828
'path/to/location')
839
except bzrlib.errors.UnsupportedOperation:
829
except errors.UnsupportedOperation:
840
830
raise tests.TestNotApplicable('Branch cannot hold references.')
841
831
# Create a new instance to ensure storage is permanent
842
branch = Branch.open('branch')
832
branch = _mod_branch.Branch.open('branch')
843
833
tree_path, branch_location = branch.get_reference_info('file-id')
844
834
self.assertEqual('path/to/location', branch_location)
849
839
branch.set_reference_info('file-id', 'path/to/file',
850
840
'path/to/location')
851
except bzrlib.errors.UnsupportedOperation:
841
except errors.UnsupportedOperation:
852
842
raise tests.TestNotApplicable('Branch cannot hold references.')
853
843
branch.set_reference_info('file-id', None, None)
854
844
tree_path, branch_location = branch.get_reference_info('file-id')
859
849
branch = self.make_branch('branch')
861
851
tree_path, branch_location = branch.get_reference_info('file-id')
862
except bzrlib.errors.UnsupportedOperation:
852
except errors.UnsupportedOperation:
863
853
raise tests.TestNotApplicable('Branch cannot hold references.')
864
854
self.assertIs(None, tree_path)
865
855
self.assertIs(None, branch_location)
871
861
e = self.assertRaises(ValueError, branch.set_reference_info,
872
862
'file-id', 'path', None)
873
except bzrlib.errors.UnsupportedOperation:
863
except errors.UnsupportedOperation:
874
864
raise tests.TestNotApplicable('Branch cannot hold references.')
875
865
self.assertEqual('tree_path must be None when branch_location is'
876
866
' None.', str(e))
886
876
branch.set_reference_info(file_id, 'path/to/file',
887
877
reference_location)
888
except bzrlib.errors.UnsupportedOperation:
878
except errors.UnsupportedOperation:
889
879
raise tests.TestNotApplicable('Branch cannot hold references.')
902
892
branch.set_reference_info('file-id', 'path/to/file',
903
893
'../reference_branch')
904
except bzrlib.errors.UnsupportedOperation:
894
except errors.UnsupportedOperation:
905
895
raise tests.TestNotApplicable('Branch cannot hold references.')
906
896
referenced_branch = self.make_branch('reference_branch')
907
897
parent = branch.reference_parent('file-id', 'path/to/file')