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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
48
48
def fetch_steps(self, br_a, br_b, writable_a):
49
49
"""A foreign test method for testing fetch locally and remotely."""
51
51
# TODO RBC 20060201 make this a repository test.
52
52
repo_b = br_b.repository
53
53
self.assertFalse(repo_b.has_revision(br_a.revision_history()[3]))
54
54
self.assertTrue(repo_b.has_revision(br_a.revision_history()[2]))
55
55
self.assertEquals(len(br_b.revision_history()), 7)
56
self.assertEquals(br_b.fetch(br_a, br_a.revision_history()[2])[0], 0)
56
br_b.fetch(br_a, br_a.revision_history()[2])
57
57
# branch.fetch is not supposed to alter the revision history
58
58
self.assertEquals(len(br_b.revision_history()), 7)
59
59
self.assertFalse(repo_b.has_revision(br_a.revision_history()[3]))
61
61
# fetching the next revision up in sample data copies one revision
62
self.assertEquals(br_b.fetch(br_a, br_a.revision_history()[3])[0], 1)
62
br_b.fetch(br_a, br_a.revision_history()[3])
63
63
self.assertTrue(repo_b.has_revision(br_a.revision_history()[3]))
64
64
self.assertFalse(has_revision(br_a, br_b.revision_history()[6]))
65
65
self.assertTrue(br_a.repository.has_revision(br_b.revision_history()[5]))
67
67
# When a non-branch ancestor is missing, it should be unlisted...
68
68
# as its not reference from the inventory weave.
69
69
br_b4 = self.make_branch('br_4')
70
count, failures = br_b4.fetch(br_b)
71
self.assertEqual(count, 7)
72
self.assertEqual(failures, [])
74
self.assertEqual(writable_a.fetch(br_b)[0], 1)
72
writable_a.fetch(br_b)
75
73
self.assertTrue(has_revision(br_a, br_b.revision_history()[3]))
76
74
self.assertTrue(has_revision(br_a, br_b.revision_history()[4]))
78
76
br_b2 = self.make_branch('br_b2')
79
self.assertEquals(br_b2.fetch(br_b)[0], 7)
80
78
self.assertTrue(has_revision(br_b2, br_b.revision_history()[4]))
81
79
self.assertTrue(has_revision(br_b2, br_a.revision_history()[2]))
82
80
self.assertFalse(has_revision(br_b2, br_a.revision_history()[3]))
84
82
br_a2 = self.make_branch('br_a2')
85
self.assertEquals(br_a2.fetch(br_a)[0], 9)
86
84
self.assertTrue(has_revision(br_a2, br_b.revision_history()[4]))
87
85
self.assertTrue(has_revision(br_a2, br_a.revision_history()[3]))
88
86
self.assertTrue(has_revision(br_a2, br_a.revision_history()[2]))
90
88
br_a3 = self.make_branch('br_a3')
91
# pulling a branch with no revisions grabs nothing, regardless of
89
# pulling a branch with no revisions grabs nothing, regardless of
92
90
# whats in the inventory.
93
self.assertEquals(br_a3.fetch(br_a2)[0], 0)
94
92
for revno in range(4):
96
94
br_a3.repository.has_revision(br_a.revision_history()[revno]))
97
self.assertEqual(br_a3.fetch(br_a2, br_a.revision_history()[2])[0], 3)
95
br_a3.fetch(br_a2, br_a.revision_history()[2])
98
96
# pull the 3 revisions introduced by a@u-0-3
99
fetched = br_a3.fetch(br_a2, br_a.revision_history()[3])[0]
100
self.assertEquals(fetched, 3, "fetched %d instead of 3" % fetched)
101
# InstallFailed should be raised if the branch is missing the revision
97
br_a3.fetch(br_a2, br_a.revision_history()[3])
98
# NoSuchRevision should be raised if the branch is missing the revision
102
99
# that was requested.
103
self.assertRaises(errors.InstallFailed, br_a3.fetch, br_a2, 'pizza')
100
self.assertRaises(errors.NoSuchRevision, br_a3.fetch, br_a2, 'pizza')
105
102
# TODO: Test trying to fetch from a branch that points to a revision not
106
103
# actually present in its repository. Not every branch format allows you
123
120
def test_fetch_self(self):
124
121
wt = self.make_branch_and_tree('br')
125
self.assertEqual(wt.branch.fetch(wt.branch), (0, []))
122
wt.branch.fetch(wt.branch)
127
124
def test_fetch_root_knit(self):
128
125
"""Ensure that knit2.fetch() updates the root knit
130
127
This tests the case where the root has a new revision, but there are no
131
128
corresponding filename, parent, contents or other changes.
284
281
wt.commit("changed file")
285
282
target = BzrDir.create_branch_and_repo("target/")
286
283
source = Branch.open(self.get_readonly_url("source/"))
287
self.assertEqual(target.fetch(source), (2, []))
288
# this is the path to the literal file. As format changes
285
# this is the path to the literal file. As format changes
289
286
# occur it needs to be updated. FIXME: ask the store for the
291
288
self.log("web server logs are:")
292
289
http_logs = self.get_readonly_server().logs
293
290
self.log('\n'.join(http_logs))
294
# unfortunately this log entry is branch format specific. We could
295
# factor out the 'what files does this format use' to a method on the
291
# unfortunately this log entry is branch format specific. We could
292
# factor out the 'what files does this format use' to a method on the
296
293
# repository, which would let us to this generically. RBC 20060419
297
294
# RBC 20080408: Or perhaps we can assert that no files are fully read
299
296
self.assertEqual(1, self._count_log_matches('/ce/id.kndx', http_logs))
300
297
self.assertEqual(1, self._count_log_matches('/ce/id.knit', http_logs))
301
298
self.assertEqual(1, self._count_log_matches('inventory.kndx', http_logs))
302
# this r-h check test will prevent regressions, but it currently already
299
# this r-h check test will prevent regressions, but it currently already
303
300
# passes, before the patch to cache-rh is applied :[
304
301
self.assertTrue(1 >= self._count_log_matches('revision-history',
315
312
source = Branch.open(
316
313
self.get_readonly_url("source/"),
317
314
possible_transports=[source.bzrdir.root_transport])
318
self.assertEqual(target.fetch(source), (0, []))
319
316
# should make just two requests
320
317
http_logs = self.get_readonly_server().logs
321
318
self.log("web server logs are:")
324
321
self.assertEqual(1, self._count_log_matches('branch/format', http_logs))
325
322
self.assertEqual(1, self._count_log_matches('repository/format',
324
self.assertEqual(1, self._count_log_matches('revisions.kndx',
327
326
self.assertTrue(1 >= self._count_log_matches('revision-history',
329
328
self.assertTrue(1 >= self._count_log_matches('last-revision',
331
self.assertEqual(4, len(http_logs))
330
self.assertLength(5, http_logs)
334
333
class TestKnitToPackFetch(TestCaseWithTransport):
336
def find_get_record_stream(self, calls):
337
"""In a list of calls, find 'get_record_stream' calls.
335
def find_get_record_stream(self, calls, expected_count=1):
336
"""In a list of calls, find the last 'get_record_stream'.
339
This also ensures that there is only one get_record_stream call.
338
:param expected_count: The number of calls we should exepect to find.
339
If a different number is found, an assertion is raised.
341
341
get_record_call = None
342
343
for call in calls:
343
344
if call[0] == 'get_record_stream':
344
self.assertIs(None, get_record_call,
345
"there should only be one call to"
346
" get_record_stream")
347
346
get_record_call = call
348
self.assertIsNot(None, get_record_call,
349
"there should be exactly one call to "
350
" get_record_stream")
347
self.assertEqual(expected_count, call_count)
351
348
return get_record_call
353
350
def test_fetch_with_deltas_no_delta_closure(self):
367
364
source.inventories = versionedfile.RecordingVersionedFilesDecorator(
368
365
source.inventories)
370
self.assertTrue(target._fetch_uses_deltas)
367
self.assertTrue(target._format._fetch_uses_deltas)
371
368
target.fetch(source, revision_id='rev-one')
372
369
self.assertEqual(('get_record_stream', [('file-id', 'rev-one')],
373
target._fetch_order, False),
370
target._format._fetch_order, False),
374
371
self.find_get_record_stream(source.texts.calls))
375
372
self.assertEqual(('get_record_stream', [('rev-one',)],
376
target._fetch_order, False),
377
self.find_get_record_stream(source.inventories.calls))
373
target._format._fetch_order, False),
374
self.find_get_record_stream(source.inventories.calls, 2))
378
375
self.assertEqual(('get_record_stream', [('rev-one',)],
379
target._fetch_order, False),
376
target._format._fetch_order, False),
380
377
self.find_get_record_stream(source.revisions.calls))
381
378
# XXX: Signatures is special, and slightly broken. The
382
379
# standard item_keys_introduced_by actually does a lookup for every
388
385
signature_calls = source.signatures.calls[-1:]
389
386
self.assertEqual(('get_record_stream', [('rev-one',)],
390
target._fetch_order, False),
387
target._format._fetch_order, False),
391
388
self.find_get_record_stream(signature_calls))
393
390
def test_fetch_no_deltas_with_delta_closure(self):
406
403
source.revisions)
407
404
source.inventories = versionedfile.RecordingVersionedFilesDecorator(
408
405
source.inventories)
409
target._fetch_uses_deltas = False
406
# XXX: This won't work in general, but for the dirstate format it does.
407
self.overrideAttr(target._format, '_fetch_uses_deltas', False)
410
408
target.fetch(source, revision_id='rev-one')
411
409
self.assertEqual(('get_record_stream', [('file-id', 'rev-one')],
412
target._fetch_order, True),
410
target._format._fetch_order, True),
413
411
self.find_get_record_stream(source.texts.calls))
414
412
self.assertEqual(('get_record_stream', [('rev-one',)],
415
target._fetch_order, True),
416
self.find_get_record_stream(source.inventories.calls))
413
target._format._fetch_order, True),
414
self.find_get_record_stream(source.inventories.calls, 2))
417
415
self.assertEqual(('get_record_stream', [('rev-one',)],
418
target._fetch_order, True),
416
target._format._fetch_order, True),
419
417
self.find_get_record_stream(source.revisions.calls))
420
418
# XXX: Signatures is special, and slightly broken. The
421
419
# standard item_keys_introduced_by actually does a lookup for every
427
425
signature_calls = source.signatures.calls[-1:]
428
426
self.assertEqual(('get_record_stream', [('rev-one',)],
429
target._fetch_order, True),
427
target._format._fetch_order, True),
430
428
self.find_get_record_stream(signature_calls))
432
430
def test_fetch_revisions_with_deltas_into_pack(self):
576
574
self.repo.fetch(self.tree.branch.repository, 'second-id')
577
575
root_id = self.tree.get_root_id()
578
576
self.assertEqual(
579
((root_id, 'left-parent'), (root_id, 'ghost-parent'),
580
(root_id, 'not-ghost-parent')),
577
((root_id, 'left-parent'), (root_id, 'not-ghost-parent')),
581
578
self.get_parents(root_id, 'second-id'))
583
580
def make_two_commits(self, change_root, fetch_twice):