15
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
from bzrlib.branch import Branch, needs_read_lock, needs_write_lock
18
from bzrlib.branch import Branch
20
19
from bzrlib.clone import copy_branch
21
20
from bzrlib.commit import commit
22
import bzrlib.errors as errors
23
from bzrlib.errors import NoSuchRevision, UnlistableBranch, NotBranchError
25
from bzrlib.selftest import TestCase, TestCaseInTempDir
26
from bzrlib.selftest.HTTPTestUtil import TestCaseWithWebserver
21
from bzrlib.errors import NoSuchRevision, UnlistableBranch
22
from bzrlib.selftest import TestCaseInTempDir
27
23
from bzrlib.trace import mutter
28
import bzrlib.transactions as transactions
29
from bzrlib.revision import NULL_REVISION
31
# TODO: Make a branch using basis branch, and check that it
32
# doesn't request any files that could have been avoided, by
33
# hooking into the Transport.
35
26
class TestBranch(TestCaseInTempDir):
63
54
tree = b2.revision_tree('revision-1')
64
55
eq(tree.get_file_text('foo-id'), 'hello')
66
def test_revision_tree(self):
67
b1 = Branch.initialize('.')
68
b1.commit('lala!', rev_id='revision-1', allow_pointless=True)
69
tree = b1.revision_tree('revision-1')
70
tree = b1.revision_tree(None)
71
self.assertEqual(len(tree.list_files()), 0)
72
tree = b1.revision_tree(NULL_REVISION)
73
self.assertEqual(len(tree.list_files()), 0)
75
def get_unbalanced_branch_pair(self):
76
"""Return two branches, a and b, with one file in a."""
57
def test_push_stores(self):
58
"""Copy the stores from one branch to another"""
78
60
br_a = Branch.initialize("a")
79
61
file('a/b', 'wb').write('b')
81
commit(br_a, "silly commit", rev_id='A')
63
commit(br_a, "silly commit")
83
66
br_b = Branch.initialize("b")
86
def get_balanced_branch_pair(self):
87
"""Returns br_a, br_b as with one commit in a, and b has a's stores."""
88
br_a, br_b = self.get_unbalanced_branch_pair()
89
br_a.push_stores(br_b)
92
def test_push_stores(self):
93
"""Copy the stores from one branch to another"""
94
br_a, br_b = self.get_unbalanced_branch_pair()
95
# ensure the revision is missing.
96
67
self.assertRaises(NoSuchRevision, br_b.get_revision,
97
68
br_a.revision_history()[0])
98
69
br_a.push_stores(br_b)
99
# check that b now has all the data from a's first commit.
100
70
rev = br_b.get_revision(br_a.revision_history()[0])
101
71
tree = br_b.revision_tree(br_a.revision_history()[0])
102
72
for file_id in tree:
107
77
def test_copy_branch(self):
108
78
"""Copy the stores from one branch to another"""
109
br_a, br_b = self.get_balanced_branch_pair()
79
br_a, br_b = self.test_push_stores()
110
80
commit(br_b, "silly commit")
112
82
br_c = copy_branch(br_a, 'c', basis_branch=br_b)
113
83
self.assertEqual(br_a.revision_history(), br_c.revision_history())
84
## # basis branches currently disabled for weave format
85
## self.assertFalse(br_b.last_revision() in br_c.revision_history())
86
## br_c.get_revision(br_b.last_revision())
115
88
def test_copy_partial(self):
116
89
"""Copy only part of the history of a branch."""
168
138
'wibble@fofof--20050401--1928390812')
169
139
# list should be cleared when we do a commit
170
140
self.assertEquals(b.pending_merges(), [])
172
def test_sign_existing_revision(self):
173
branch = Branch.initialize('.')
174
branch.commit("base", allow_pointless=True, rev_id='A')
175
from bzrlib.testament import Testament
176
branch.sign_revision('A', bzrlib.gpg.LoopbackGPGStrategy(None))
177
self.assertEqual(Testament.from_revision(branch, 'A').as_short_text(),
178
branch.revision_store.get('A', 'sig').read())
180
def test_store_signature(self):
181
branch = Branch.initialize('.')
182
branch.store_revision_signature(bzrlib.gpg.LoopbackGPGStrategy(None),
184
self.assertEqual('FOO', branch.revision_store.get('A', 'sig').read())
186
def test__relcontrolfilename(self):
187
branch = Branch.initialize('.')
188
self.assertEqual('.bzr/%25', branch._rel_controlfilename('%'))
190
def test__relcontrolfilename_empty(self):
191
branch = Branch.initialize('.')
192
self.assertEqual('.bzr', branch._rel_controlfilename(''))
195
class TestRemote(TestCaseWithWebserver):
197
def test_open_containing(self):
198
self.assertRaises(NotBranchError, Branch.open_containing,
199
self.get_remote_url(''))
200
self.assertRaises(NotBranchError, Branch.open_containing,
201
self.get_remote_url('g/p/q'))
202
b = Branch.initialize('.')
203
branch, relpath = Branch.open_containing(self.get_remote_url(''))
204
self.assertEqual('', relpath)
205
branch, relpath = Branch.open_containing(self.get_remote_url('g/p/q'))
206
self.assertEqual('g/p/q', relpath)
208
143
# TODO: rewrite this as a regular unittest, without relying on the displayed output
209
144
# >>> from bzrlib.commit import commit
210
145
# >>> bzrlib.trace.silent = True
223
158
# Added 0 revisions.
224
159
# >>> br1.text_store.total_size() == br2.text_store.total_size()
227
class InstrumentedTransaction(object):
230
self.calls.append('finish')
236
class TestDecorator(object):
242
self._calls.append('lr')
244
def lock_write(self):
245
self._calls.append('lw')
248
self._calls.append('ul')
251
def do_with_read(self):
255
def except_with_read(self):
259
def do_with_write(self):
263
def except_with_write(self):
267
class TestDecorators(TestCase):
269
def test_needs_read_lock(self):
270
branch = TestDecorator()
271
self.assertEqual(1, branch.do_with_read())
272
self.assertEqual(['lr', 'ul'], branch._calls)
274
def test_excepts_in_read_lock(self):
275
branch = TestDecorator()
276
self.assertRaises(RuntimeError, branch.except_with_read)
277
self.assertEqual(['lr', 'ul'], branch._calls)
279
def test_needs_write_lock(self):
280
branch = TestDecorator()
281
self.assertEqual(2, branch.do_with_write())
282
self.assertEqual(['lw', 'ul'], branch._calls)
284
def test_excepts_in_write_lock(self):
285
branch = TestDecorator()
286
self.assertRaises(RuntimeError, branch.except_with_write)
287
self.assertEqual(['lw', 'ul'], branch._calls)
290
class TestBranchTransaction(TestCaseInTempDir):
293
super(TestBranchTransaction, self).setUp()
294
self.branch = Branch.initialize('.')
296
def test_default_get_transaction(self):
297
"""branch.get_transaction on a new branch should give a PassThrough."""
298
self.failUnless(isinstance(self.branch.get_transaction(),
299
transactions.PassThroughTransaction))
301
def test__set_new_transaction(self):
302
self.branch._set_transaction(transactions.ReadOnlyTransaction())
304
def test__set_over_existing_transaction_raises(self):
305
self.branch._set_transaction(transactions.ReadOnlyTransaction())
306
self.assertRaises(errors.LockError,
307
self.branch._set_transaction,
308
transactions.ReadOnlyTransaction())
310
def test_finish_no_transaction_raises(self):
311
self.assertRaises(errors.LockError, self.branch._finish_transaction)
313
def test_finish_readonly_transaction_works(self):
314
self.branch._set_transaction(transactions.ReadOnlyTransaction())
315
self.branch._finish_transaction()
316
self.assertEqual(None, self.branch._transaction)
318
def test_unlock_calls_finish(self):
319
self.branch.lock_read()
320
transaction = InstrumentedTransaction()
321
self.branch._transaction = transaction
323
self.assertEqual(['finish'], transaction.calls)
325
def test_lock_read_acquires_ro_transaction(self):
326
self.branch.lock_read()
327
self.failUnless(isinstance(self.branch.get_transaction(),
328
transactions.ReadOnlyTransaction))
331
def test_lock_write_acquires_passthrough_transaction(self):
332
self.branch.lock_write()
333
# cannot use get_transaction as its magic
334
self.failUnless(isinstance(self.branch._transaction,
335
transactions.PassThroughTransaction))
339
class TestBranchPushLocations(TestCaseInTempDir):
342
super(TestBranchPushLocations, self).setUp()
343
self.branch = Branch.initialize('.')
345
def test_get_push_location_unset(self):
346
self.assertEqual(None, self.branch.get_push_location())
348
def test_get_push_location_exact(self):
349
self.build_tree(['.bazaar/'])
350
print >> open('.bazaar/branches.conf', 'wt'), ("[%s]\n"
351
"push_location=foo" %
353
self.assertEqual("foo", self.branch.get_push_location())
355
def test_set_push_location(self):
356
self.branch.set_push_location('foo')
357
self.assertFileEqual("[%s]\n"
358
"push_location = foo" % os.getcwdu(),
359
'.bazaar/branches.conf')
361
# TODO RBC 20051029 test getting a push location from a branch in a
362
# recursive section - that is, it appends the branch name.