33
from bzrlib.branch import Branch
34
from bzrlib.bzrdir import BzrDir
35
from bzrlib.memorytree import MemoryTree
36
from bzrlib.revision import NULL_REVISION
37
from bzrlib.smart import client, server
38
from bzrlib.smart.repository import SmartServerRepositoryGetParentMap
39
from bzrlib.tests.per_branch.test_branch import TestCaseWithBranch
40
from bzrlib.transport import get_transport
41
from bzrlib.transport.local import LocalURLServer
44
class TestPush(TestCaseWithBranch):
36
from bzrlib.smart import (
39
repository as _mod_smart_repo,
41
from bzrlib.tests import (
47
class TestPush(per_branch.TestCaseWithBranch):
46
49
def test_push_convergence_simple(self):
47
50
# when revisions are pushed, the left-most accessible parents must
149
152
tree = a_branch.bzrdir.create_workingtree()
150
153
except errors.NotLocalUrl:
151
if self.vfs_transport_factory is LocalURLServer:
154
if self.vfs_transport_factory is test_server.LocalURLServer:
152
155
# the branch is colocated on disk, we cannot create a checkout.
153
156
# hopefully callers will expect this.
154
local_controldir= bzrdir.BzrDir.open(self.get_vfs_only_url('repo/tree'))
157
local_controldir= bzrdir.BzrDir.open(
158
self.get_vfs_only_url('repo/tree'))
155
159
tree = local_controldir.create_workingtree()
157
161
tree = a_branch.create_checkout('repo/tree', lightweight=True)
223
227
push._show_push_branch(trunk, 'rev-2', self.get_url('remote'), output)
224
228
# Push rev-3 onto "remote". If "remote" not stacked and is missing the
225
229
# fulltext record for f-id @ rev-1, then this will fail.
226
remote_branch = Branch.open(self.get_url('remote'))
230
remote_branch = branch.Branch.open(self.get_url('remote'))
227
231
trunk.push(remote_branch)
228
232
check.check_dwim(remote_branch.base, False, True, True)
230
def test_no_get_parent_map_after_insert_stream(self):
231
# Effort test for bug 331823
232
self.setup_smart_server_with_call_log()
233
# Make a local branch with four revisions. Four revisions because:
234
# one to push, one there for _walk_to_common_revisions to find, one we
235
# don't want to access, one for luck :)
236
if isinstance(self.branch_format, branch.BranchReferenceFormat):
237
# This test could in principle apply to BranchReferenceFormat, but
238
# make_branch_builder doesn't support it.
239
raise tests.TestSkipped(
240
"BranchBuilder can't make reference branches.")
242
builder = self.make_branch_builder('local')
243
except (errors.TransportNotPossible, errors.UninitializableFormat):
244
raise tests.TestNotApplicable('format not directly constructable')
245
builder.start_series()
246
builder.build_snapshot('first', None, [
247
('add', ('', 'root-id', 'directory', ''))])
248
builder.build_snapshot('second', ['first'], [])
249
builder.build_snapshot('third', ['second'], [])
250
builder.build_snapshot('fourth', ['third'], [])
251
builder.finish_series()
252
local = builder.get_branch()
253
local = branch.Branch.open(self.get_vfs_only_url('local'))
254
# Initial push of three revisions
255
remote_bzrdir = local.bzrdir.sprout(
256
self.get_url('remote'), revision_id='third')
257
remote = remote_bzrdir.open_branch()
258
# Push fourth revision
259
self.reset_smart_call_log()
260
self.disableOptimisticGetParentMap()
261
self.assertFalse(local.is_locked())
263
hpss_call_names = [item.call.method for item in self.hpss_calls]
264
self.assertTrue('Repository.insert_stream_1.19' in hpss_call_names)
265
insert_stream_idx = hpss_call_names.index(
266
'Repository.insert_stream_1.19')
267
calls_after_insert_stream = hpss_call_names[insert_stream_idx:]
268
# After inserting the stream the client has no reason to query the
269
# remote graph any further.
271
['Repository.insert_stream_1.19', 'Repository.insert_stream_1.19',
272
'get', 'Branch.set_last_revision_info', 'Branch.unlock'],
273
calls_after_insert_stream)
275
def disableOptimisticGetParentMap(self):
276
# Tweak some class variables to stop remote get_parent_map calls asking
277
# for or receiving more data than the caller asked for.
278
old_flag = SmartServerRepositoryGetParentMap.no_extra_results
279
inter_class = repository.InterRepository
280
old_batch_size = inter_class._walk_to_common_revisions_batch_size
281
inter_class._walk_to_common_revisions_batch_size = 1
282
SmartServerRepositoryGetParentMap.no_extra_results = True
284
SmartServerRepositoryGetParentMap.no_extra_results = old_flag
285
inter_class._walk_to_common_revisions_batch_size = old_batch_size
286
self.addCleanup(reset_values)
289
class TestPushHook(TestCaseWithBranch):
235
class TestPushHook(per_branch.TestCaseWithBranch):
292
238
self.hook_calls = []
293
TestCaseWithBranch.setUp(self)
239
super(TestPushHook, self).setUp()
295
241
def capture_post_push_hook(self, result):
296
242
"""Capture post push hook calls to self.hook_calls.
314
260
def test_post_push_empty_history(self):
315
261
target = self.make_branch('target')
316
262
source = self.make_branch('source')
317
Branch.hooks.install_named_hook('post_push',
318
self.capture_post_push_hook, None)
263
branch.Branch.hooks.install_named_hook(
264
'post_push', self.capture_post_push_hook, None)
319
265
source.push(target)
320
266
# with nothing there we should still get a notification, and
321
267
# have both branches locked at the notification time.
322
268
self.assertEqual([
323
('post_push', source, None, target.base, 0, NULL_REVISION,
324
0, NULL_REVISION, True, None, True)
269
('post_push', source, None, target.base, 0, revision.NULL_REVISION,
270
0, revision.NULL_REVISION, True, None, True)
340
286
# remotebranches can't be bound. Let's instead make a new local
341
287
# branch of the default type, which does allow binding.
342
288
# See https://bugs.launchpad.net/bzr/+bug/112020
343
local = BzrDir.create_branch_convenience('local2')
289
local = bzrdir.BzrDir.create_branch_convenience('local2')
344
290
local.bind(target)
345
291
source = self.make_branch('source')
346
Branch.hooks.install_named_hook('post_push',
347
self.capture_post_push_hook, None)
292
branch.Branch.hooks.install_named_hook(
293
'post_push', self.capture_post_push_hook, None)
348
294
source.push(local)
349
295
# with nothing there we should still get a notification, and
350
296
# have both branches locked at the notification time.
351
297
self.assertEqual([
352
('post_push', source, local.base, target.base, 0, NULL_REVISION,
353
0, NULL_REVISION, True, True, True)
298
('post_push', source, local.base, target.base, 0,
299
revision.NULL_REVISION, 0, revision.NULL_REVISION,
361
308
rev1 = target.commit('rev 1')
363
310
sourcedir = target.bzrdir.clone(self.get_url('source'))
364
source = MemoryTree.create_on_branch(sourcedir.open_branch())
311
source = memorytree.MemoryTree.create_on_branch(sourcedir.open_branch())
365
312
rev2 = source.commit('rev 2')
366
Branch.hooks.install_named_hook('post_push',
367
self.capture_post_push_hook, None)
313
branch.Branch.hooks.install_named_hook(
314
'post_push', self.capture_post_push_hook, None)
368
315
source.branch.push(target.branch)
369
316
# with nothing there we should still get a notification, and
370
317
# have both branches locked at the notification time.