/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

Branch now uses BzrDir reasonably sanely.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright (C) 2005 by Canonical Ltd
 
2
 
 
3
# This program is free software; you can redistribute it and/or modify
 
4
# it under the terms of the GNU General Public License as published by
 
5
# the Free Software Foundation; either version 2 of the License, or
 
6
# (at your option) any later version.
 
7
 
 
8
# This program is distributed in the hope that it will be useful,
 
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
11
# GNU General Public License for more details.
 
12
 
 
13
# You should have received a copy of the GNU General Public License
 
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
 
16
 
 
17
import os
 
18
import sys
 
19
 
 
20
from bzrlib.branch import Branch
 
21
from bzrlib.bzrdir import BzrDir
 
22
from bzrlib.builtins import merge
 
23
import bzrlib.errors
 
24
from bzrlib.fetch import greedy_fetch
 
25
from bzrlib.tests import TestCaseWithTransport
 
26
from bzrlib.tests.HTTPTestUtil import TestCaseWithWebserver
 
27
from bzrlib.tests.test_revision import make_branches
 
28
from bzrlib.trace import mutter
 
29
from bzrlib.workingtree import WorkingTree
 
30
 
 
31
 
 
32
def has_revision(branch, revision_id):
 
33
    return branch.repository.has_revision(revision_id)
 
34
 
 
35
def fetch_steps(self, br_a, br_b, writable_a):
 
36
    """A foreign test method for testing fetch locally and remotely."""
 
37
    def new_branch(name):
 
38
        os.mkdir(name)
 
39
        return WorkingTree.create_standalone(name).branch
 
40
     
 
41
    # TODO RBC 20060201 make this a repository test.
 
42
    repo_b = br_b.repository
 
43
    self.assertFalse(repo_b.has_revision(br_a.revision_history()[3]))
 
44
    self.assertTrue(repo_b.has_revision(br_a.revision_history()[2]))
 
45
    self.assertEquals(len(br_b.revision_history()), 7)
 
46
    self.assertEquals(greedy_fetch(br_b, br_a, br_a.revision_history()[2])[0], 0)
 
47
 
 
48
    # greedy_fetch is not supposed to alter the revision history
 
49
    self.assertEquals(len(br_b.revision_history()), 7)
 
50
    self.assertFalse(repo_b.has_revision(br_a.revision_history()[3]))
 
51
 
 
52
    self.assertEquals(len(br_b.revision_history()), 7)
 
53
    self.assertEquals(greedy_fetch(br_b, br_a, br_a.revision_history()[3])[0], 1)
 
54
    self.assertTrue(repo_b.has_revision(br_a.revision_history()[3]))
 
55
    self.assertFalse(has_revision(br_a, br_b.revision_history()[6]))
 
56
    self.assertTrue(br_a.repository.has_revision(br_b.revision_history()[5]))
 
57
 
 
58
    # When a non-branch ancestor is missing, it should be unlisted...
 
59
    # as its not reference from the inventory weave.
 
60
    br_b4 = new_branch('br_4')
 
61
    count, failures = greedy_fetch(br_b4, br_b)
 
62
    self.assertEqual(count, 7)
 
63
    self.assertEqual(failures, [])
 
64
 
 
65
    self.assertEqual(greedy_fetch(writable_a, br_b)[0], 1)
 
66
    self.assertTrue(has_revision(br_a, br_b.revision_history()[3]))
 
67
    self.assertTrue(has_revision(br_a, br_b.revision_history()[4]))
 
68
        
 
69
    br_b2 = new_branch('br_b2')
 
70
    self.assertEquals(greedy_fetch(br_b2, br_b)[0], 7)
 
71
    self.assertTrue(has_revision(br_b2, br_b.revision_history()[4]))
 
72
    self.assertTrue(has_revision(br_b2, br_a.revision_history()[2]))
 
73
    self.assertFalse(has_revision(br_b2, br_a.revision_history()[3]))
 
74
 
 
75
    br_a2 = new_branch('br_a2')
 
76
    self.assertEquals(greedy_fetch(br_a2, br_a)[0], 9)
 
77
    self.assertTrue(has_revision(br_a2, br_b.revision_history()[4]))
 
78
    self.assertTrue(has_revision(br_a2, br_a.revision_history()[3]))
 
79
    self.assertTrue(has_revision(br_a2, br_a.revision_history()[2]))
 
80
 
 
81
    br_a3 = new_branch('br_a3')
 
82
    # pulling a branch with no revisions grabs nothing, regardless of 
 
83
    # whats in the inventory.
 
84
    self.assertEquals(greedy_fetch(br_a3, br_a2)[0], 0)
 
85
    for revno in range(4):
 
86
        self.assertFalse(
 
87
            br_a3.repository.has_revision(br_a.revision_history()[revno]))
 
88
    self.assertEqual(greedy_fetch(br_a3, br_a2, br_a.revision_history()[2])[0], 3)
 
89
    # pull the 3 revisions introduced by a@u-0-3
 
90
    fetched = greedy_fetch(br_a3, br_a2, br_a.revision_history()[3])[0]
 
91
    self.assertEquals(fetched, 3, "fetched %d instead of 3" % fetched)
 
92
    # InstallFailed should be raised if the branch is missing the revision
 
93
    # that was requested.
 
94
    self.assertRaises(bzrlib.errors.InstallFailed, greedy_fetch, br_a3,
 
95
                      br_a2, 'pizza')
 
96
    # InstallFailed should be raised if the branch is missing a revision
 
97
    # from its own revision history
 
98
    br_a2.append_revision('a-b-c')
 
99
    self.assertRaises(bzrlib.errors.InstallFailed, greedy_fetch, br_a3,
 
100
                      br_a2)
 
101
    #TODO: test that fetch correctly does reweaving when needed. RBC 20051008
 
102
    # Note that this means - updating the weave when ghosts are filled in to 
 
103
    # add the right parents.
 
104
 
 
105
 
 
106
class TestFetch(TestCaseWithTransport):
 
107
 
 
108
    def test_fetch(self):
 
109
        #highest indices a: 5, b: 7
 
110
        br_a, br_b = make_branches(self)
 
111
        fetch_steps(self, br_a, br_b, br_a)
 
112
 
 
113
 
 
114
class TestMergeFetch(TestCaseWithTransport):
 
115
 
 
116
    def test_merge_fetches_unrelated(self):
 
117
        """Merge brings across history from unrelated source"""
 
118
        wt1 = self.make_branch_and_tree('br1')
 
119
        br1 = wt1.branch
 
120
        wt1.commit(message='rev 1-1', rev_id='1-1')
 
121
        wt1.commit(message='rev 1-2', rev_id='1-2')
 
122
        wt2 = self.make_branch_and_tree('br2')
 
123
        br2 = wt2.branch
 
124
        wt2.commit(message='rev 2-1', rev_id='2-1')
 
125
        merge(other_revision=['br1', -1], base_revision=['br1', 0],
 
126
              this_dir='br2')
 
127
        self._check_revs_present(br2)
 
128
 
 
129
    def test_merge_fetches(self):
 
130
        """Merge brings across history from source"""
 
131
        wt1 = self.make_branch_and_tree('br1')
 
132
        br1 = wt1.branch
 
133
        wt1.commit(message='rev 1-1', rev_id='1-1')
 
134
        br2 = br1.clone('br2')
 
135
        wt1.commit(message='rev 1-2', rev_id='1-2')
 
136
        WorkingTree.create(br2, 'br2').commit(message='rev 2-1', rev_id='2-1')
 
137
        merge(other_revision=['br1', -1], base_revision=[None, None], 
 
138
              this_dir='br2')
 
139
        self._check_revs_present(br2)
 
140
 
 
141
    def _check_revs_present(self, br2):
 
142
        for rev_id in '1-1', '1-2', '2-1':
 
143
            self.assertTrue(br2.repository.has_revision(rev_id))
 
144
            rev = br2.repository.get_revision(rev_id)
 
145
            self.assertEqual(rev.revision_id, rev_id)
 
146
            self.assertTrue(br2.repository.get_inventory(rev_id))
 
147
 
 
148
 
 
149
class TestMergeFileHistory(TestCaseWithTransport):
 
150
 
 
151
    def setUp(self):
 
152
        super(TestMergeFileHistory, self).setUp()
 
153
        wt1 = self.make_branch_and_tree('br1')
 
154
        br1 = wt1.branch
 
155
        self.build_tree_contents([('br1/file', 'original contents\n')])
 
156
        wt1.add('file', 'this-file-id')
 
157
        wt1.commit(message='rev 1-1', rev_id='1-1')
 
158
        br2 = br1.clone('br2')
 
159
        wt2 = WorkingTree('br2', br2)
 
160
        self.build_tree_contents([('br1/file', 'original from 1\n')])
 
161
        wt1.commit(message='rev 1-2', rev_id='1-2')
 
162
        self.build_tree_contents([('br1/file', 'agreement\n')])
 
163
        wt1.commit(message='rev 1-3', rev_id='1-3')
 
164
        self.build_tree_contents([('br2/file', 'contents in 2\n')])
 
165
        wt2.commit(message='rev 2-1', rev_id='2-1')
 
166
        self.build_tree_contents([('br2/file', 'agreement\n')])
 
167
        wt2.commit(message='rev 2-2', rev_id='2-2')
 
168
 
 
169
    def test_merge_fetches_file_history(self):
 
170
        """Merge brings across file histories"""
 
171
        br2 = Branch.open('br2')
 
172
        merge(other_revision=['br1', -1], base_revision=[None, None], 
 
173
              this_dir='br2')
 
174
        for rev_id, text in [('1-2', 'original from 1\n'),
 
175
                             ('1-3', 'agreement\n'),
 
176
                             ('2-1', 'contents in 2\n'),
 
177
                             ('2-2', 'agreement\n')]:
 
178
            self.assertEqualDiff(
 
179
                br2.repository.revision_tree(
 
180
                    rev_id).get_file_text('this-file-id'), text)
 
181
 
 
182
 
 
183
class TestHttpFetch(TestCaseWithWebserver):
 
184
    # FIXME RBC 20060124 this really isn't web specific, perhaps an
 
185
    # instrumented readonly transport? Can we do an instrumented
 
186
    # adapter and use self.get_readonly_url ?
 
187
 
 
188
    def test_fetch(self):
 
189
        #highest indices a: 5, b: 7
 
190
        print "TestHttpFetch.test_fetch disabled during transition."
 
191
        return
 
192
        br_a, br_b = make_branches(self)
 
193
        br_rem_a = Branch.open(self.get_remote_url(br_a.base))
 
194
        fetch_steps(self, br_rem_a, br_b, br_a)
 
195
 
 
196
    def test_weaves_are_retrieved_once(self):
 
197
        self.build_tree(("source/", "source/file", "target/"))
 
198
        wt = WorkingTree.create_standalone('source')
 
199
        branch = wt.branch
 
200
        wt.add(["file"], ["id"])
 
201
        wt.commit("added file")
 
202
        print >>open("source/file", 'w'), "blah"
 
203
        wt.commit("changed file")
 
204
        target = BzrDir.create_branch_and_repo("target/")
 
205
        source = Branch.open(self.get_remote_url("source/"))
 
206
        self.assertEqual(greedy_fetch(target, source), (2, []))
 
207
        # this is the path to the literal file. As format changes 
 
208
        # occur it needs to be updated. FIXME: ask the store for the
 
209
        # path.
 
210
        weave_suffix = 'weaves/ce/id.weave HTTP/1.1" 200 -'
 
211
        self.assertEqual(1,
 
212
            len([log for log in self.server.logs if log.endswith(weave_suffix)]))
 
213
        inventory_weave_suffix = 'inventory.weave HTTP/1.1" 200 -'
 
214
        self.assertEqual(1,
 
215
            len([log for log in self.server.logs if log.endswith(
 
216
                inventory_weave_suffix)]))
 
217
        # this r-h check test will prevent regressions, but it currently already 
 
218
        # passes, before the patch to cache-rh is applied :[
 
219
        revision_history_suffix = 'revision-history HTTP/1.1" 200 -'
 
220
        self.assertEqual(1,
 
221
            len([log for log in self.server.logs if log.endswith(
 
222
                revision_history_suffix)]))
 
223
        # FIXME naughty poking in there.
 
224
        self.server.logs = []
 
225
        # check there is nothing more to fetch
 
226
        source = Branch.open(self.get_remote_url("source/"))
 
227
        self.assertEqual(greedy_fetch(target, source), (0, []))
 
228
        self.failUnless(self.server.logs[0].endswith('branch-format HTTP/1.1" 200 -'))
 
229
        self.failUnless(self.server.logs[1].endswith('revision-history HTTP/1.1" 200 -'))
 
230
        self.assertEqual(2, len(self.server.logs))