/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_fetch.py

  • Committer: Frank Aspell
  • Date: 2009-02-22 16:54:02 UTC
  • mto: This revision was merged to the branch mainline in revision 4256.
  • Revision ID: frankaspell@googlemail.com-20090222165402-2myrucnu7er5w4ha
Fixing various typos

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005, 2007, 2010 Canonical Ltd
 
1
# Copyright (C) 2005, 2007 Canonical Ltd
2
2
#
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
12
12
#
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
16
 
17
17
import os
18
18
import re
31
31
from bzrlib.bzrdir import BzrDir
32
32
from bzrlib.repofmt import knitrepo
33
33
from bzrlib.tests import TestCaseWithTransport
 
34
from bzrlib.tests.http_utils import TestCaseWithWebserver
34
35
from bzrlib.tests.test_revision import make_branches
35
36
from bzrlib.trace import mutter
36
37
from bzrlib.upgrade import Convert
37
38
from bzrlib.workingtree import WorkingTree
38
39
 
39
40
# These tests are a bit old; please instead add new tests into
40
 
# per_interrepository/ so they'll run on all relevant
 
41
# interrepository_implementations/ so they'll run on all relevant
41
42
# combinations.
42
43
 
43
44
 
46
47
 
47
48
def fetch_steps(self, br_a, br_b, writable_a):
48
49
    """A foreign test method for testing fetch locally and remotely."""
49
 
 
 
50
     
50
51
    # TODO RBC 20060201 make this a repository test.
51
52
    repo_b = br_b.repository
52
53
    self.assertFalse(repo_b.has_revision(br_a.revision_history()[3]))
53
54
    self.assertTrue(repo_b.has_revision(br_a.revision_history()[2]))
54
55
    self.assertEquals(len(br_b.revision_history()), 7)
55
 
    br_b.fetch(br_a, br_a.revision_history()[2])
 
56
    self.assertEquals(br_b.fetch(br_a, br_a.revision_history()[2])[0], 0)
56
57
    # branch.fetch is not supposed to alter the revision history
57
58
    self.assertEquals(len(br_b.revision_history()), 7)
58
59
    self.assertFalse(repo_b.has_revision(br_a.revision_history()[3]))
59
60
 
60
61
    # fetching the next revision up in sample data copies one revision
61
 
    br_b.fetch(br_a, br_a.revision_history()[3])
 
62
    self.assertEquals(br_b.fetch(br_a, br_a.revision_history()[3])[0], 1)
62
63
    self.assertTrue(repo_b.has_revision(br_a.revision_history()[3]))
63
64
    self.assertFalse(has_revision(br_a, br_b.revision_history()[6]))
64
65
    self.assertTrue(br_a.repository.has_revision(br_b.revision_history()[5]))
66
67
    # When a non-branch ancestor is missing, it should be unlisted...
67
68
    # as its not reference from the inventory weave.
68
69
    br_b4 = self.make_branch('br_4')
69
 
    br_b4.fetch(br_b)
 
70
    count, failures = br_b4.fetch(br_b)
 
71
    self.assertEqual(count, 7)
 
72
    self.assertEqual(failures, [])
70
73
 
71
 
    writable_a.fetch(br_b)
 
74
    self.assertEqual(writable_a.fetch(br_b)[0], 1)
72
75
    self.assertTrue(has_revision(br_a, br_b.revision_history()[3]))
73
76
    self.assertTrue(has_revision(br_a, br_b.revision_history()[4]))
74
 
 
 
77
        
75
78
    br_b2 = self.make_branch('br_b2')
76
 
    br_b2.fetch(br_b)
 
79
    self.assertEquals(br_b2.fetch(br_b)[0], 7)
77
80
    self.assertTrue(has_revision(br_b2, br_b.revision_history()[4]))
78
81
    self.assertTrue(has_revision(br_b2, br_a.revision_history()[2]))
79
82
    self.assertFalse(has_revision(br_b2, br_a.revision_history()[3]))
80
83
 
81
84
    br_a2 = self.make_branch('br_a2')
82
 
    br_a2.fetch(br_a)
 
85
    self.assertEquals(br_a2.fetch(br_a)[0], 9)
83
86
    self.assertTrue(has_revision(br_a2, br_b.revision_history()[4]))
84
87
    self.assertTrue(has_revision(br_a2, br_a.revision_history()[3]))
85
88
    self.assertTrue(has_revision(br_a2, br_a.revision_history()[2]))
86
89
 
87
90
    br_a3 = self.make_branch('br_a3')
88
 
    # pulling a branch with no revisions grabs nothing, regardless of
 
91
    # pulling a branch with no revisions grabs nothing, regardless of 
89
92
    # whats in the inventory.
90
 
    br_a3.fetch(br_a2)
 
93
    self.assertEquals(br_a3.fetch(br_a2)[0], 0)
91
94
    for revno in range(4):
92
95
        self.assertFalse(
93
96
            br_a3.repository.has_revision(br_a.revision_history()[revno]))
94
 
    br_a3.fetch(br_a2, br_a.revision_history()[2])
 
97
    self.assertEqual(br_a3.fetch(br_a2, br_a.revision_history()[2])[0], 3)
95
98
    # pull the 3 revisions introduced by a@u-0-3
96
 
    br_a3.fetch(br_a2, br_a.revision_history()[3])
97
 
    # NoSuchRevision should be raised if the branch is missing the revision
 
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
98
102
    # that was requested.
99
 
    self.assertRaises(errors.NoSuchRevision, br_a3.fetch, br_a2, 'pizza')
 
103
    self.assertRaises(errors.InstallFailed, br_a3.fetch, br_a2, 'pizza')
100
104
 
101
105
    # TODO: Test trying to fetch from a branch that points to a revision not
102
106
    # actually present in its repository.  Not every branch format allows you
105
109
    # every branch supports that.  -- mbp 20070814
106
110
 
107
111
    #TODO: test that fetch correctly does reweaving when needed. RBC 20051008
108
 
    # Note that this means - updating the weave when ghosts are filled in to
 
112
    # Note that this means - updating the weave when ghosts are filled in to 
109
113
    # add the right parents.
110
114
 
111
115
 
118
122
 
119
123
    def test_fetch_self(self):
120
124
        wt = self.make_branch_and_tree('br')
121
 
        wt.branch.fetch(wt.branch)
 
125
        self.assertEqual(wt.branch.fetch(wt.branch), (0, []))
122
126
 
123
127
    def test_fetch_root_knit(self):
124
128
        """Ensure that knit2.fetch() updates the root knit
125
 
 
 
129
        
126
130
        This tests the case where the root has a new revision, but there are no
127
131
        corresponding filename, parent, contents or other changes.
128
132
        """
247
251
                    rev_id).get_file_text('this-file-id'), text)
248
252
 
249
253
 
 
254
class TestHttpFetch(TestCaseWithWebserver):
 
255
    # FIXME RBC 20060124 this really isn't web specific, perhaps an
 
256
    # instrumented readonly transport? Can we do an instrumented
 
257
    # adapter and use self.get_readonly_url ?
 
258
 
 
259
    def test_fetch(self):
 
260
        #highest indices a: 5, b: 7
 
261
        br_a, br_b = make_branches(self)
 
262
        br_rem_a = Branch.open(self.get_readonly_url('branch1'))
 
263
        fetch_steps(self, br_rem_a, br_b, br_a)
 
264
 
 
265
    def _count_log_matches(self, target, logs):
 
266
        """Count the number of times the target file pattern was fetched in an http log"""
 
267
        get_succeeds_re = re.compile(
 
268
            '.*"GET .*%s HTTP/1.1" 20[06] - "-" "bzr/%s' %
 
269
            (     target,                    bzrlib.__version__))
 
270
        c = 0
 
271
        for line in logs:
 
272
            if get_succeeds_re.match(line):
 
273
                c += 1
 
274
        return c
 
275
 
 
276
    def test_weaves_are_retrieved_once(self):
 
277
        self.build_tree(("source/", "source/file", "target/"))
 
278
        # This test depends on knit dasta storage.
 
279
        wt = self.make_branch_and_tree('source', format='dirstate-tags')
 
280
        branch = wt.branch
 
281
        wt.add(["file"], ["id"])
 
282
        wt.commit("added file")
 
283
        open("source/file", 'w').write("blah\n")
 
284
        wt.commit("changed file")
 
285
        target = BzrDir.create_branch_and_repo("target/")
 
286
        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 
 
289
        # occur it needs to be updated. FIXME: ask the store for the
 
290
        # path.
 
291
        self.log("web server logs are:")
 
292
        http_logs = self.get_readonly_server().logs
 
293
        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 
 
296
        # repository, which would let us to this generically. RBC 20060419
 
297
        # RBC 20080408: Or perhaps we can assert that no files are fully read
 
298
        # twice?
 
299
        self.assertEqual(1, self._count_log_matches('/ce/id.kndx', http_logs))
 
300
        self.assertEqual(1, self._count_log_matches('/ce/id.knit', http_logs))
 
301
        self.assertEqual(1, self._count_log_matches('inventory.kndx', http_logs))
 
302
        # this r-h check test will prevent regressions, but it currently already 
 
303
        # passes, before the patch to cache-rh is applied :[
 
304
        self.assertTrue(1 >= self._count_log_matches('revision-history',
 
305
                                                     http_logs))
 
306
        self.assertTrue(1 >= self._count_log_matches('last-revision',
 
307
                                                     http_logs))
 
308
        # FIXME naughty poking in there.
 
309
        self.get_readonly_server().logs = []
 
310
        # check there is nothing more to fetch.  We take care to re-use the
 
311
        # existing transport so that the request logs we're about to examine
 
312
        # aren't cluttered with redundant probes for a smart server.
 
313
        # XXX: Perhaps this further parameterisation: test http with smart
 
314
        # server, and test http without smart server?
 
315
        source = Branch.open(
 
316
            self.get_readonly_url("source/"),
 
317
            possible_transports=[source.bzrdir.root_transport])
 
318
        self.assertEqual(target.fetch(source), (0, []))
 
319
        # should make just two requests
 
320
        http_logs = self.get_readonly_server().logs
 
321
        self.log("web server logs are:")
 
322
        self.log('\n'.join(http_logs))
 
323
        self.assertEqual(1, self._count_log_matches('branch-format', http_logs))
 
324
        self.assertEqual(1, self._count_log_matches('branch/format', http_logs))
 
325
        self.assertEqual(1, self._count_log_matches('repository/format',
 
326
            http_logs))
 
327
        self.assertTrue(1 >= self._count_log_matches('revision-history',
 
328
                                                     http_logs))
 
329
        self.assertTrue(1 >= self._count_log_matches('last-revision',
 
330
                                                     http_logs))
 
331
        self.assertEqual(4, len(http_logs))
 
332
 
 
333
 
250
334
class TestKnitToPackFetch(TestCaseWithTransport):
251
335
 
252
 
    def find_get_record_stream(self, calls, expected_count=1):
253
 
        """In a list of calls, find the last 'get_record_stream'.
 
336
    def find_get_record_stream(self, calls):
 
337
        """In a list of calls, find 'get_record_stream' calls.
254
338
 
255
 
        :param expected_count: The number of calls we should exepect to find.
256
 
            If a different number is found, an assertion is raised.
 
339
        This also ensures that there is only one get_record_stream call.
257
340
        """
258
341
        get_record_call = None
259
 
        call_count = 0
260
342
        for call in calls:
261
343
            if call[0] == 'get_record_stream':
262
 
                call_count += 1
 
344
                self.assertIs(None, get_record_call,
 
345
                              "there should only be one call to"
 
346
                              " get_record_stream")
263
347
                get_record_call = call
264
 
        self.assertEqual(expected_count, call_count)
 
348
        self.assertIsNot(None, get_record_call,
 
349
                         "there should be exactly one call to "
 
350
                         " get_record_stream")
265
351
        return get_record_call
266
352
 
267
353
    def test_fetch_with_deltas_no_delta_closure(self):
281
367
        source.inventories = versionedfile.RecordingVersionedFilesDecorator(
282
368
                        source.inventories)
283
369
        # precondition
284
 
        self.assertTrue(target._format._fetch_uses_deltas)
 
370
        self.assertTrue(target._fetch_uses_deltas)
285
371
        target.fetch(source, revision_id='rev-one')
286
372
        self.assertEqual(('get_record_stream', [('file-id', 'rev-one')],
287
 
                          target._format._fetch_order, False),
 
373
                          target._fetch_order, False),
288
374
                         self.find_get_record_stream(source.texts.calls))
289
375
        self.assertEqual(('get_record_stream', [('rev-one',)],
290
 
          target._format._fetch_order, False),
291
 
          self.find_get_record_stream(source.inventories.calls, 2))
 
376
                          target._fetch_order, False),
 
377
                         self.find_get_record_stream(source.inventories.calls))
292
378
        self.assertEqual(('get_record_stream', [('rev-one',)],
293
 
                          target._format._fetch_order, False),
 
379
                          target._fetch_order, False),
294
380
                         self.find_get_record_stream(source.revisions.calls))
295
381
        # XXX: Signatures is special, and slightly broken. The
296
382
        # standard item_keys_introduced_by actually does a lookup for every
301
387
        # we care about.
302
388
        signature_calls = source.signatures.calls[-1:]
303
389
        self.assertEqual(('get_record_stream', [('rev-one',)],
304
 
                          target._format._fetch_order, False),
 
390
                          target._fetch_order, False),
305
391
                         self.find_get_record_stream(signature_calls))
306
392
 
307
393
    def test_fetch_no_deltas_with_delta_closure(self):
320
406
                        source.revisions)
321
407
        source.inventories = versionedfile.RecordingVersionedFilesDecorator(
322
408
                        source.inventories)
323
 
        # XXX: This won't work in general, but for the dirstate format it does.
324
 
        self.overrideAttr(target._format, '_fetch_uses_deltas', False)
 
409
        target._fetch_uses_deltas = False
325
410
        target.fetch(source, revision_id='rev-one')
326
411
        self.assertEqual(('get_record_stream', [('file-id', 'rev-one')],
327
 
                          target._format._fetch_order, True),
 
412
                          target._fetch_order, True),
328
413
                         self.find_get_record_stream(source.texts.calls))
329
414
        self.assertEqual(('get_record_stream', [('rev-one',)],
330
 
            target._format._fetch_order, True),
331
 
            self.find_get_record_stream(source.inventories.calls, 2))
 
415
                          target._fetch_order, True),
 
416
                         self.find_get_record_stream(source.inventories.calls))
332
417
        self.assertEqual(('get_record_stream', [('rev-one',)],
333
 
                          target._format._fetch_order, True),
 
418
                          target._fetch_order, True),
334
419
                         self.find_get_record_stream(source.revisions.calls))
335
420
        # XXX: Signatures is special, and slightly broken. The
336
421
        # standard item_keys_introduced_by actually does a lookup for every
341
426
        # we care about.
342
427
        signature_calls = source.signatures.calls[-1:]
343
428
        self.assertEqual(('get_record_stream', [('rev-one',)],
344
 
                          target._format._fetch_order, True),
 
429
                          target._fetch_order, True),
345
430
                         self.find_get_record_stream(signature_calls))
346
431
 
347
432
    def test_fetch_revisions_with_deltas_into_pack(self):
491
576
        self.repo.fetch(self.tree.branch.repository, 'second-id')
492
577
        root_id = self.tree.get_root_id()
493
578
        self.assertEqual(
494
 
            ((root_id, 'left-parent'), (root_id, 'not-ghost-parent')),
 
579
            ((root_id, 'left-parent'), (root_id, 'ghost-parent'),
 
580
             (root_id, 'not-ghost-parent')),
495
581
            self.get_parents(root_id, 'second-id'))
496
582
 
497
583
    def make_two_commits(self, change_root, fetch_twice):