/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: John Arbash Meinel
  • Date: 2008-07-17 01:50:02 UTC
  • mto: This revision was merged to the branch mainline in revision 3549.
  • Revision ID: john@arbash-meinel.com-20080717015002-uhhc7h8ssetsvm2c
Add extra debugging for when a deprecated function/method are called

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005 by Canonical Ltd
2
 
 
 
1
# Copyright (C) 2005, 2007 Canonical Ltd
 
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
5
5
# the Free Software Foundation; either version 2 of the License, or
6
6
# (at your option) any later version.
7
 
 
 
7
#
8
8
# This program is distributed in the hope that it will be useful,
9
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
11
# GNU General Public License for more details.
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
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
16
 
17
17
import os
 
18
import re
18
19
import sys
19
20
 
 
21
import bzrlib
 
22
from bzrlib import (
 
23
    bzrdir,
 
24
    errors,
 
25
    merge,
 
26
    repository,
 
27
    )
20
28
from bzrlib.branch import Branch
21
29
from bzrlib.bzrdir import BzrDir
22
 
from bzrlib.builtins import merge
23
 
import bzrlib.errors
 
30
from bzrlib.repofmt import knitrepo
24
31
from bzrlib.tests import TestCaseWithTransport
25
 
from bzrlib.tests.HTTPTestUtil import TestCaseWithWebserver
 
32
from bzrlib.tests.http_utils import TestCaseWithWebserver
26
33
from bzrlib.tests.test_revision import make_branches
27
34
from bzrlib.trace import mutter
 
35
from bzrlib.upgrade import Convert
28
36
from bzrlib.workingtree import WorkingTree
29
37
 
 
38
# These tests are a bit old; please instead add new tests into
 
39
# interrepository_implementations/ so they'll run on all relevant
 
40
# combinations.
 
41
 
30
42
 
31
43
def has_revision(branch, revision_id):
32
44
    return branch.repository.has_revision(revision_id)
86
98
    self.assertEquals(fetched, 3, "fetched %d instead of 3" % fetched)
87
99
    # InstallFailed should be raised if the branch is missing the revision
88
100
    # that was requested.
89
 
    self.assertRaises(bzrlib.errors.InstallFailed, br_a3.fetch, br_a2, 'pizza')
90
 
    # InstallFailed should be raised if the branch is missing a revision
91
 
    # from its own revision history
92
 
    br_a2.append_revision('a-b-c')
93
 
    self.assertRaises(bzrlib.errors.InstallFailed, br_a3.fetch, br_a2)
 
101
    self.assertRaises(errors.InstallFailed, br_a3.fetch, br_a2, 'pizza')
94
102
 
95
 
    # TODO: jam 20051218 Branch should no longer allow append_revision for revisions
96
 
    #       which don't exist. So this test needs to be rewritten
97
 
    #       RBC 20060403 the way to do this is to uncommit the revision from the
98
 
    #           repository after the commit
 
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
99
108
 
100
109
    #TODO: test that fetch correctly does reweaving when needed. RBC 20051008
101
110
    # Note that this means - updating the weave when ghosts are filled in to 
106
115
 
107
116
    def test_fetch(self):
108
117
        #highest indices a: 5, b: 7
109
 
        br_a, br_b = make_branches(self)
 
118
        br_a, br_b = make_branches(self, format='dirstate-tags')
110
119
        fetch_steps(self, br_a, br_b, br_a)
111
120
 
112
121
    def test_fetch_self(self):
113
122
        wt = self.make_branch_and_tree('br')
114
123
        self.assertEqual(wt.branch.fetch(wt.branch), (0, []))
115
124
 
 
125
    def test_fetch_root_knit(self):
 
126
        """Ensure that knit2.fetch() updates the root knit
 
127
        
 
128
        This tests the case where the root has a new revision, but there are no
 
129
        corresponding filename, parent, contents or other changes.
 
130
        """
 
131
        knit1_format = bzrdir.BzrDirMetaFormat1()
 
132
        knit1_format.repository_format = knitrepo.RepositoryFormatKnit1()
 
133
        knit2_format = bzrdir.BzrDirMetaFormat1()
 
134
        knit2_format.repository_format = knitrepo.RepositoryFormatKnit3()
 
135
        # we start with a knit1 repository because that causes the
 
136
        # root revision to change for each commit, even though the content,
 
137
        # parent, name, and other attributes are unchanged.
 
138
        tree = self.make_branch_and_tree('tree', knit1_format)
 
139
        tree.set_root_id('tree-root')
 
140
        tree.commit('rev1', rev_id='rev1')
 
141
        tree.commit('rev2', rev_id='rev2')
 
142
 
 
143
        # Now we convert it to a knit2 repository so that it has a root knit
 
144
        Convert(tree.basedir, knit2_format)
 
145
        tree = WorkingTree.open(tree.basedir)
 
146
        branch = self.make_branch('branch', format=knit2_format)
 
147
        branch.pull(tree.branch, stop_revision='rev1')
 
148
        repo = branch.repository
 
149
        repo.lock_read()
 
150
        try:
 
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')]))
 
155
        finally:
 
156
            repo.unlock()
 
157
        branch.pull(tree.branch)
 
158
        # Make sure that the next revision in the root knit was retrieved,
 
159
        # even though the text, name, parent_id, etc., were unchanged.
 
160
        repo.lock_read()
 
161
        try:
 
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')]))
 
165
        finally:
 
166
            repo.unlock()
 
167
 
 
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
        self.assertRaises(errors.IncompatibleRepositories,
 
174
                          knit_tree.branch.fetch, knit3_tree.branch)
 
175
 
116
176
 
117
177
class TestMergeFetch(TestCaseWithTransport):
118
178
 
125
185
        wt2 = self.make_branch_and_tree('br2')
126
186
        br2 = wt2.branch
127
187
        wt2.commit(message='rev 2-1', rev_id='2-1')
128
 
        merge(other_revision=['br1', -1], base_revision=['br1', 0],
129
 
              this_dir='br2')
 
188
        wt2.merge_from_branch(br1, from_revision='null:')
130
189
        self._check_revs_present(br2)
131
190
 
132
191
    def test_merge_fetches(self):
137
196
        dir_2 = br1.bzrdir.sprout('br2')
138
197
        br2 = dir_2.open_branch()
139
198
        wt1.commit(message='rev 1-2', rev_id='1-2')
140
 
        dir_2.open_workingtree().commit(message='rev 2-1', rev_id='2-1')
141
 
        merge(other_revision=['br1', -1], base_revision=[None, None], 
142
 
              this_dir='br2')
 
199
        wt2 = dir_2.open_workingtree()
 
200
        wt2.commit(message='rev 2-1', rev_id='2-1')
 
201
        wt2.merge_from_branch(br1)
143
202
        self._check_revs_present(br2)
144
203
 
145
204
    def _check_revs_present(self, br2):
174
233
    def test_merge_fetches_file_history(self):
175
234
        """Merge brings across file histories"""
176
235
        br2 = Branch.open('br2')
177
 
        merge(other_revision=['br1', -1], base_revision=[None, None], 
178
 
              this_dir='br2')
 
236
        br1 = Branch.open('br1')
 
237
        wt2 = WorkingTree.open('br2').merge_from_branch(br1)
 
238
        br2.lock_read()
 
239
        self.addCleanup(br2.unlock)
179
240
        for rev_id, text in [('1-2', 'original from 1\n'),
180
241
                             ('1-3', 'agreement\n'),
181
242
                             ('2-1', 'contents in 2\n'),
198
259
 
199
260
    def _count_log_matches(self, target, logs):
200
261
        """Count the number of times the target file pattern was fetched in an http log"""
201
 
        log_pattern = '%s HTTP/1.1" 200 - "-" "bzr/%s' % \
202
 
            (target, bzrlib.__version__)
 
262
        get_succeeds_re = re.compile(
 
263
            '.*"GET .*%s HTTP/1.1" 20[06] - "-" "bzr/%s' %
 
264
            (     target,                    bzrlib.__version__))
203
265
        c = 0
204
266
        for line in logs:
205
 
            # TODO: perhaps use a regexp instead so we can match more
206
 
            # precisely?
207
 
            if line.find(log_pattern) > -1:
 
267
            if get_succeeds_re.match(line):
208
268
                c += 1
209
269
        return c
210
270
 
211
271
    def test_weaves_are_retrieved_once(self):
212
272
        self.build_tree(("source/", "source/file", "target/"))
213
 
        wt = self.make_branch_and_tree('source')
 
273
        # This test depends on knit dasta storage.
 
274
        wt = self.make_branch_and_tree('source', format='dirstate-tags')
214
275
        branch = wt.branch
215
276
        wt.add(["file"], ["id"])
216
277
        wt.commit("added file")
217
 
        print >>open("source/file", 'w'), "blah"
 
278
        open("source/file", 'w').write("blah\n")
218
279
        wt.commit("changed file")
219
280
        target = BzrDir.create_branch_and_repo("target/")
220
281
        source = Branch.open(self.get_readonly_url("source/"))
221
282
        self.assertEqual(target.fetch(source), (2, []))
222
 
        log_pattern = '%%s HTTP/1.1" 200 - "-" "bzr/%s' % bzrlib.__version__
223
283
        # this is the path to the literal file. As format changes 
224
284
        # occur it needs to be updated. FIXME: ask the store for the
225
285
        # path.
226
286
        self.log("web server logs are:")
227
287
        http_logs = self.get_readonly_server().logs
228
288
        self.log('\n'.join(http_logs))
229
 
        self.assertEqual(1, self._count_log_matches('weaves/ce/id.weave', http_logs))
230
 
        self.assertEqual(1, self._count_log_matches('inventory.weave', http_logs))
 
289
        # unfortunately this log entry is branch format specific. We could 
 
290
        # factor out the 'what files does this format use' to a method on the 
 
291
        # repository, which would let us to this generically. RBC 20060419
 
292
        # RBC 20080408: Or perhaps we can assert that no files are fully read
 
293
        # twice?
 
294
        self.assertEqual(1, self._count_log_matches('/ce/id.kndx', http_logs))
 
295
        self.assertEqual(1, self._count_log_matches('/ce/id.knit', http_logs))
 
296
        self.assertEqual(1, self._count_log_matches('inventory.kndx', http_logs))
231
297
        # this r-h check test will prevent regressions, but it currently already 
232
298
        # passes, before the patch to cache-rh is applied :[
233
 
        self.assertEqual(1, self._count_log_matches('revision-history', http_logs))
 
299
        self.assertTrue(1 >= self._count_log_matches('revision-history',
 
300
                                                     http_logs))
 
301
        self.assertTrue(1 >= self._count_log_matches('last-revision',
 
302
                                                     http_logs))
234
303
        # FIXME naughty poking in there.
235
304
        self.get_readonly_server().logs = []
236
 
        # check there is nothing more to fetch
237
 
        source = Branch.open(self.get_readonly_url("source/"))
 
305
        # check there is nothing more to fetch.  We take care to re-use the
 
306
        # existing transport so that the request logs we're about to examine
 
307
        # aren't cluttered with redundant probes for a smart server.
 
308
        # XXX: Perhaps this further parameterisation: test http with smart
 
309
        # server, and test http without smart server?
 
310
        source = Branch.open(
 
311
            self.get_readonly_url("source/"),
 
312
            possible_transports=[source.bzrdir.root_transport])
238
313
        self.assertEqual(target.fetch(source), (0, []))
239
314
        # should make just two requests
240
315
        http_logs = self.get_readonly_server().logs
241
316
        self.log("web server logs are:")
242
317
        self.log('\n'.join(http_logs))
243
 
        self.assertEqual(1, self._count_log_matches('branch-format', http_logs[0:1]))
244
 
        self.assertEqual(1, self._count_log_matches('revision-history', http_logs[1:2]))
245
 
        self.assertEqual(2, len(http_logs))
 
318
        self.assertEqual(1, self._count_log_matches('branch-format', http_logs))
 
319
        self.assertEqual(1, self._count_log_matches('branch/format', http_logs))
 
320
        self.assertEqual(1, self._count_log_matches('repository/format',
 
321
            http_logs))
 
322
        self.assertTrue(1 >= self._count_log_matches('revision-history',
 
323
                                                     http_logs))
 
324
        self.assertTrue(1 >= self._count_log_matches('last-revision',
 
325
                                                     http_logs))
 
326
        self.assertEqual(4, len(http_logs))
 
327
 
 
328
 
 
329
class Test1To2Fetch(TestCaseWithTransport):
 
330
    """Tests for Model1To2 failure modes"""
 
331
 
 
332
    def make_tree_and_repo(self):
 
333
        self.tree = self.make_branch_and_tree('tree', format='pack-0.92')
 
334
        self.repo = self.make_repository('rich-repo', format='rich-root-pack')
 
335
        self.repo.lock_write()
 
336
        self.addCleanup(self.repo.unlock)
 
337
 
 
338
    def do_fetch_order_test(self, first, second):
 
339
        """Test that fetch works no matter what the set order of revision is.
 
340
 
 
341
        This test depends on the order of items in a set, which is
 
342
        implementation-dependant, so we test A, B and then B, A.
 
343
        """
 
344
        self.make_tree_and_repo()
 
345
        self.tree.commit('Commit 1', rev_id=first)
 
346
        self.tree.commit('Commit 2', rev_id=second)
 
347
        self.repo.fetch(self.tree.branch.repository, second)
 
348
 
 
349
    def test_fetch_order_AB(self):
 
350
        """See do_fetch_order_test"""
 
351
        self.do_fetch_order_test('A', 'B')
 
352
 
 
353
    def test_fetch_order_BA(self):
 
354
        """See do_fetch_order_test"""
 
355
        self.do_fetch_order_test('B', 'A')
 
356
 
 
357
    def get_parents(self, file_id, revision_id):
 
358
        self.repo.lock_read()
 
359
        try:
 
360
            parent_map = self.repo.texts.get_parent_map([(file_id, revision_id)])
 
361
            return parent_map[(file_id, revision_id)]
 
362
        finally:
 
363
            self.repo.unlock()
 
364
 
 
365
    def test_fetch_ghosts(self):
 
366
        self.make_tree_and_repo()
 
367
        self.tree.commit('first commit', rev_id='left-parent')
 
368
        self.tree.add_parent_tree_id('ghost-parent')
 
369
        fork = self.tree.bzrdir.sprout('fork', 'null:').open_workingtree()
 
370
        fork.commit('not a ghost', rev_id='not-ghost-parent')
 
371
        self.tree.branch.repository.fetch(fork.branch.repository,
 
372
                                     'not-ghost-parent')
 
373
        self.tree.add_parent_tree_id('not-ghost-parent')
 
374
        self.tree.commit('second commit', rev_id='second-id')
 
375
        self.repo.fetch(self.tree.branch.repository, 'second-id')
 
376
        root_id = self.tree.get_root_id()
 
377
        self.assertEqual(
 
378
            ((root_id, 'left-parent'), (root_id, 'ghost-parent'),
 
379
             (root_id, 'not-ghost-parent')),
 
380
            self.get_parents(root_id, 'second-id'))
 
381
 
 
382
    def make_two_commits(self, change_root, fetch_twice):
 
383
        self.make_tree_and_repo()
 
384
        self.tree.commit('first commit', rev_id='first-id')
 
385
        if change_root:
 
386
            self.tree.set_root_id('unique-id')
 
387
        self.tree.commit('second commit', rev_id='second-id')
 
388
        if fetch_twice:
 
389
            self.repo.fetch(self.tree.branch.repository, 'first-id')
 
390
        self.repo.fetch(self.tree.branch.repository, 'second-id')
 
391
 
 
392
    def test_fetch_changed_root(self):
 
393
        self.make_two_commits(change_root=True, fetch_twice=False)
 
394
        self.assertEqual((), self.get_parents('unique-id', 'second-id'))
 
395
 
 
396
    def test_two_fetch_changed_root(self):
 
397
        self.make_two_commits(change_root=True, fetch_twice=True)
 
398
        self.assertEqual((), self.get_parents('unique-id', 'second-id'))
 
399
 
 
400
    def test_two_fetches(self):
 
401
        self.make_two_commits(change_root=False, fetch_twice=True)
 
402
        self.assertEqual((('TREE_ROOT', 'first-id'),),
 
403
            self.get_parents('TREE_ROOT', 'second-id'))