21
from bzrlib import bzrdir, repository
28
22
from bzrlib.branch import Branch
29
23
from bzrlib.bzrdir import BzrDir
30
from bzrlib.repofmt import knitrepo
24
from bzrlib.builtins import merge
31
26
from bzrlib.tests import TestCaseWithTransport
32
from bzrlib.tests.http_utils import TestCaseWithWebserver
27
from bzrlib.tests.HTTPTestUtil import TestCaseWithWebserver
33
28
from bzrlib.tests.test_revision import make_branches
34
29
from bzrlib.trace import mutter
35
30
from bzrlib.upgrade import Convert
36
31
from bzrlib.workingtree import WorkingTree
38
# These tests are a bit old; please instead add new tests into
39
# interrepository_implementations/ so they'll run on all relevant
43
34
def has_revision(branch, revision_id):
44
35
return branch.repository.has_revision(revision_id)
98
89
self.assertEquals(fetched, 3, "fetched %d instead of 3" % fetched)
99
90
# InstallFailed should be raised if the branch is missing the revision
100
91
# that was requested.
101
self.assertRaises(errors.InstallFailed, br_a3.fetch, br_a2, 'pizza')
92
self.assertRaises(bzrlib.errors.InstallFailed, br_a3.fetch, br_a2, 'pizza')
93
# InstallFailed should be raised if the branch is missing a revision
94
# from its own revision history
95
br_a2.append_revision('a-b-c')
96
self.assertRaises(bzrlib.errors.InstallFailed, br_a3.fetch, br_a2)
103
# TODO: Test trying to fetch from a branch that points to a revision not
104
# actually present in its repository. Not every branch format allows you
105
# to directly point to such revisions, so it's a bit complicated to
106
# construct. One way would be to uncommit and gc the revision, but not
107
# every branch supports that. -- mbp 20070814
98
# TODO: jam 20051218 Branch should no longer allow append_revision for revisions
99
# which don't exist. So this test needs to be rewritten
100
# RBC 20060403 the way to do this is to uncommit the revision from the
101
# repository after the commit
109
103
#TODO: test that fetch correctly does reweaving when needed. RBC 20051008
110
104
# Note that this means - updating the weave when ghosts are filled in to
146
140
branch = self.make_branch('branch', format=knit2_format)
147
141
branch.pull(tree.branch, stop_revision='rev1')
148
142
repo = branch.repository
151
# Make sure fetch retrieved only what we requested
152
self.assertEqual({('tree-root', 'rev1'):()},
153
repo.texts.get_parent_map(
154
[('tree-root', 'rev1'), ('tree-root', 'rev2')]))
143
root_knit = repo.weave_store.get_weave('tree-root',
144
repo.get_transaction())
145
# Make sure fetch retrieved only what we requested
146
self.assertTrue('rev1' in root_knit)
147
self.assertTrue('rev2' not in root_knit)
157
148
branch.pull(tree.branch)
149
root_knit = repo.weave_store.get_weave('tree-root',
150
repo.get_transaction())
158
151
# Make sure that the next revision in the root knit was retrieved,
159
152
# even though the text, name, parent_id, etc., were unchanged.
162
# Make sure fetch retrieved only what we requested
163
self.assertEqual({('tree-root', 'rev2'):(('tree-root', 'rev1'),)},
164
repo.texts.get_parent_map([('tree-root', 'rev2')]))
168
def test_fetch_incompatible(self):
169
knit_tree = self.make_branch_and_tree('knit', format='knit')
170
knit3_tree = self.make_branch_and_tree('knit3',
171
format='dirstate-with-subtree')
172
knit3_tree.commit('blah')
173
e = self.assertRaises(errors.IncompatibleRepositories,
174
knit_tree.branch.fetch, knit3_tree.branch)
175
self.assertContainsRe(str(e),
176
r"(?m).*/knit.*\nis not compatible with\n.*/knit3/.*\n"
177
r"different rich-root support")
153
self.assertTrue('rev2' in root_knit)
180
156
class TestMergeFetch(TestCaseWithTransport):
292
266
# unfortunately this log entry is branch format specific. We could
293
267
# factor out the 'what files does this format use' to a method on the
294
268
# repository, which would let us to this generically. RBC 20060419
295
# RBC 20080408: Or perhaps we can assert that no files are fully read
297
269
self.assertEqual(1, self._count_log_matches('/ce/id.kndx', http_logs))
298
270
self.assertEqual(1, self._count_log_matches('/ce/id.knit', http_logs))
299
271
self.assertEqual(1, self._count_log_matches('inventory.kndx', http_logs))
300
272
# this r-h check test will prevent regressions, but it currently already
301
273
# passes, before the patch to cache-rh is applied :[
302
self.assertTrue(1 >= self._count_log_matches('revision-history',
304
self.assertTrue(1 >= self._count_log_matches('last-revision',
274
self.assertEqual(1, self._count_log_matches('revision-history', http_logs))
306
275
# FIXME naughty poking in there.
307
276
self.get_readonly_server().logs = []
308
# check there is nothing more to fetch. We take care to re-use the
309
# existing transport so that the request logs we're about to examine
310
# aren't cluttered with redundant probes for a smart server.
311
# XXX: Perhaps this further parameterisation: test http with smart
312
# server, and test http without smart server?
313
source = Branch.open(
314
self.get_readonly_url("source/"),
315
possible_transports=[source.bzrdir.root_transport])
277
# check there is nothing more to fetch
278
source = Branch.open(self.get_readonly_url("source/"))
316
279
self.assertEqual(target.fetch(source), (0, []))
317
280
# should make just two requests
318
281
http_logs = self.get_readonly_server().logs
320
283
self.log('\n'.join(http_logs))
321
284
self.assertEqual(1, self._count_log_matches('branch-format', http_logs))
322
285
self.assertEqual(1, self._count_log_matches('branch/format', http_logs))
323
self.assertEqual(1, self._count_log_matches('repository/format',
325
self.assertTrue(1 >= self._count_log_matches('revision-history',
327
self.assertTrue(1 >= self._count_log_matches('last-revision',
286
self.assertEqual(1, self._count_log_matches('repository/format', http_logs))
287
self.assertEqual(1, self._count_log_matches('revision-history', http_logs))
329
288
self.assertEqual(4, len(http_logs))
332
class Test1To2Fetch(TestCaseWithTransport):
333
"""Tests for Model1To2 failure modes"""
335
def make_tree_and_repo(self):
336
self.tree = self.make_branch_and_tree('tree', format='pack-0.92')
337
self.repo = self.make_repository('rich-repo', format='rich-root-pack')
338
self.repo.lock_write()
339
self.addCleanup(self.repo.unlock)
341
def do_fetch_order_test(self, first, second):
342
"""Test that fetch works no matter what the set order of revision is.
344
This test depends on the order of items in a set, which is
345
implementation-dependant, so we test A, B and then B, A.
347
self.make_tree_and_repo()
348
self.tree.commit('Commit 1', rev_id=first)
349
self.tree.commit('Commit 2', rev_id=second)
350
self.repo.fetch(self.tree.branch.repository, second)
352
def test_fetch_order_AB(self):
353
"""See do_fetch_order_test"""
354
self.do_fetch_order_test('A', 'B')
356
def test_fetch_order_BA(self):
357
"""See do_fetch_order_test"""
358
self.do_fetch_order_test('B', 'A')
360
def get_parents(self, file_id, revision_id):
361
self.repo.lock_read()
363
parent_map = self.repo.texts.get_parent_map([(file_id, revision_id)])
364
return parent_map[(file_id, revision_id)]
368
def test_fetch_ghosts(self):
369
self.make_tree_and_repo()
370
self.tree.commit('first commit', rev_id='left-parent')
371
self.tree.add_parent_tree_id('ghost-parent')
372
fork = self.tree.bzrdir.sprout('fork', 'null:').open_workingtree()
373
fork.commit('not a ghost', rev_id='not-ghost-parent')
374
self.tree.branch.repository.fetch(fork.branch.repository,
376
self.tree.add_parent_tree_id('not-ghost-parent')
377
self.tree.commit('second commit', rev_id='second-id')
378
self.repo.fetch(self.tree.branch.repository, 'second-id')
379
root_id = self.tree.get_root_id()
381
((root_id, 'left-parent'), (root_id, 'ghost-parent'),
382
(root_id, 'not-ghost-parent')),
383
self.get_parents(root_id, 'second-id'))
385
def make_two_commits(self, change_root, fetch_twice):
386
self.make_tree_and_repo()
387
self.tree.commit('first commit', rev_id='first-id')
389
self.tree.set_root_id('unique-id')
390
self.tree.commit('second commit', rev_id='second-id')
392
self.repo.fetch(self.tree.branch.repository, 'first-id')
393
self.repo.fetch(self.tree.branch.repository, 'second-id')
395
def test_fetch_changed_root(self):
396
self.make_two_commits(change_root=True, fetch_twice=False)
397
self.assertEqual((), self.get_parents('unique-id', 'second-id'))
399
def test_two_fetch_changed_root(self):
400
self.make_two_commits(change_root=True, fetch_twice=True)
401
self.assertEqual((), self.get_parents('unique-id', 'second-id'))
403
def test_two_fetches(self):
404
self.make_two_commits(change_root=False, fetch_twice=True)
405
self.assertEqual((('TREE_ROOT', 'first-id'),),
406
self.get_parents('TREE_ROOT', 'second-id'))