~bzr-pqm/bzr/bzr.dev

1115 by Martin Pool
- split fetch tests into a separate file
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
1238 by Martin Pool
- remove a lot of dead code from fetch
16
1185.1.41 by Robert Collins
massive patch from Alexander Belchenko - many PEP8 fixes, removes unused function uuid
17
import os
1238 by Martin Pool
- remove a lot of dead code from fetch
18
import sys
19
1115 by Martin Pool
- split fetch tests into a separate file
20
import bzrlib.errors
21
from bzrlib.selftest.testrevision import make_branches
22
from bzrlib.trace import mutter
23
from bzrlib.branch import Branch
1238 by Martin Pool
- remove a lot of dead code from fetch
24
from bzrlib.fetch import greedy_fetch
1185.16.94 by mbp at sourcefrog
New test that merge fetches revisions from source
25
from bzrlib.merge import merge
26
from bzrlib.clone import copy_branch
1115 by Martin Pool
- split fetch tests into a separate file
27
1141 by Martin Pool
- rename FunctionalTest to TestCaseInTempDir
28
from bzrlib.selftest import TestCaseInTempDir
1404 by Robert Collins
only pull remote text weaves once per fetch operation
29
from bzrlib.selftest.HTTPTestUtil import TestCaseWithWebserver
1185.1.41 by Robert Collins
massive patch from Alexander Belchenko - many PEP8 fixes, removes unused function uuid
30
1115 by Martin Pool
- split fetch tests into a separate file
31
1238 by Martin Pool
- remove a lot of dead code from fetch
32
def has_revision(branch, revision_id):
33
    try:
34
        branch.get_revision_xml_file(revision_id)
35
        return True
36
    except bzrlib.errors.NoSuchRevision:
37
        return False
38
1393 by Robert Collins
reenable remotebranch tests
39
def fetch_steps(self, br_a, br_b, writable_a):
40
    """A foreign test method for testing fetch locally and remotely."""
41
    def new_branch(name):
42
        os.mkdir(name)
43
        return Branch.initialize(name)
44
            
1185.16.145 by Martin Pool
Remove all assert statements from test cases.
45
    self.assertFalse(has_revision(br_b, br_a.revision_history()[3]))
46
    self.assert_(has_revision(br_b, br_a.revision_history()[2]))
47
    self.assertEquals(len(br_b.revision_history()), 7)
48
    self.assertEquals(greedy_fetch(br_b, br_a, br_a.revision_history()[2])[0], 0)
1393 by Robert Collins
reenable remotebranch tests
49
50
    # greedy_fetch is not supposed to alter the revision history
1185.16.145 by Martin Pool
Remove all assert statements from test cases.
51
    self.assertEquals(len(br_b.revision_history()), 7)
52
    self.assertFalse(has_revision(br_b, br_a.revision_history()[3]))
1393 by Robert Collins
reenable remotebranch tests
53
1185.16.145 by Martin Pool
Remove all assert statements from test cases.
54
    self.assertEquals(len(br_b.revision_history()), 7)
55
    self.assertEquals(greedy_fetch(br_b, br_a, br_a.revision_history()[3])[0], 1)
56
    self.assert_(has_revision(br_b, br_a.revision_history()[3]))
57
    self.assertFalse(has_revision(br_a, br_b.revision_history()[6]))
58
    self.assert_(has_revision(br_a, br_b.revision_history()[5]))
1393 by Robert Collins
reenable remotebranch tests
59
1092.2.28 by Robert Collins
reenable test of fetching a branch with ghosts
60
    # When a non-branch ancestor is missing, it should be unlisted...
1415 by Robert Collins
remove the ancestry weave file
61
    # as its not reference from the inventory weave.
1092.2.28 by Robert Collins
reenable test of fetching a branch with ghosts
62
    br_b4 = new_branch('br_4')
63
    count, failures = greedy_fetch(br_b4, br_b)
64
    self.assertEqual(count, 7)
65
    self.assertEqual(failures, [])
1393 by Robert Collins
reenable remotebranch tests
66
67
    self.assertEqual(greedy_fetch(writable_a, br_b)[0], 1)
1185.16.145 by Martin Pool
Remove all assert statements from test cases.
68
    self.assert_(has_revision(br_a, br_b.revision_history()[3]))
69
    self.assert_(has_revision(br_a, br_b.revision_history()[4]))
1393 by Robert Collins
reenable remotebranch tests
70
        
71
    br_b2 = new_branch('br_b2')
1185.16.145 by Martin Pool
Remove all assert statements from test cases.
72
    self.assertEquals(greedy_fetch(br_b2, br_b)[0], 7)
73
    self.assert_(has_revision(br_b2, br_b.revision_history()[4]))
74
    self.assert_(has_revision(br_b2, br_a.revision_history()[2]))
75
    self.assertFalse(has_revision(br_b2, br_a.revision_history()[3]))
1393 by Robert Collins
reenable remotebranch tests
76
77
    br_a2 = new_branch('br_a2')
1185.16.145 by Martin Pool
Remove all assert statements from test cases.
78
    self.assertEquals(greedy_fetch(br_a2, br_a)[0], 9)
79
    self.assert_(has_revision(br_a2, br_b.revision_history()[4]))
80
    self.assert_(has_revision(br_a2, br_a.revision_history()[3]))
81
    self.assert_(has_revision(br_a2, br_a.revision_history()[2]))
1393 by Robert Collins
reenable remotebranch tests
82
83
    br_a3 = new_branch('br_a3')
1185.16.145 by Martin Pool
Remove all assert statements from test cases.
84
    self.assertEquals(greedy_fetch(br_a3, br_a2)[0], 0)
1393 by Robert Collins
reenable remotebranch tests
85
    for revno in range(4):
1185.16.145 by Martin Pool
Remove all assert statements from test cases.
86
        self.assertFalse(has_revision(br_a3, br_a.revision_history()[revno]))
1393 by Robert Collins
reenable remotebranch tests
87
    self.assertEqual(greedy_fetch(br_a3, br_a2, br_a.revision_history()[2])[0], 3)
88
    fetched = greedy_fetch(br_a3, br_a2, br_a.revision_history()[3])[0]
1185.16.145 by Martin Pool
Remove all assert statements from test cases.
89
    self.assertEquals(fetched, 3, "fetched %d instead of 3" % fetched)
1393 by Robert Collins
reenable remotebranch tests
90
    # InstallFailed should be raised if the branch is missing the revision
91
    # that was requested.
92
    self.assertRaises(bzrlib.errors.InstallFailed, greedy_fetch, br_a3,
93
                      br_a2, 'pizza')
94
    # InstallFailed should be raised if the branch is missing a revision
95
    # from its own revision history
96
    br_a2.append_revision('a-b-c')
97
    self.assertRaises(bzrlib.errors.InstallFailed, greedy_fetch, br_a3,
98
                      br_a2)
99
1238 by Martin Pool
- remove a lot of dead code from fetch
100
1185.13.4 by Robert Collins
make reweave visible as a weave method, and quickly integrate into fetch
101
    #TODO: test that fetch correctly does reweaving when needed. RBC 20051008
102
1141 by Martin Pool
- rename FunctionalTest to TestCaseInTempDir
103
class TestFetch(TestCaseInTempDir):
1392 by Robert Collins
reinstate testfetch test case
104
105
    def test_fetch(self):
1115 by Martin Pool
- split fetch tests into a separate file
106
        #highest indices a: 5, b: 7
1185.16.145 by Martin Pool
Remove all assert statements from test cases.
107
        br_a, br_b = make_branches(self)
1393 by Robert Collins
reenable remotebranch tests
108
        fetch_steps(self, br_a, br_b, br_a)
1404 by Robert Collins
only pull remote text weaves once per fetch operation
109
1185.16.96 by mbp at sourcefrog
More merge/fetch tests
110
111
class TestMergeFetch(TestCaseInTempDir):
112
113
    def test_merge_fetches_unrelated(self):
114
        """Merge brings across history from unrelated source"""
115
        os.mkdir('br1')
116
        br1 = Branch.initialize('br1')
1457.1.17 by Robert Collins
Branch.commit() has moved to WorkingTree.commit(). (Robert Collins)
117
        br1.working_tree().commit(message='rev 1-1', rev_id='1-1')
118
        br1.working_tree().commit(message='rev 1-2', rev_id='1-2')
1185.16.96 by mbp at sourcefrog
More merge/fetch tests
119
        os.mkdir('br2')
120
        br2 = Branch.initialize('br2')
1457.1.17 by Robert Collins
Branch.commit() has moved to WorkingTree.commit(). (Robert Collins)
121
        br2.working_tree().commit(message='rev 2-1', rev_id='2-1')
1185.16.96 by mbp at sourcefrog
More merge/fetch tests
122
        merge(other_revision=['br1', -1], base_revision=['br1', 0],
123
              this_dir='br2')
124
        self._check_revs_present(br2)
125
1185.16.94 by mbp at sourcefrog
New test that merge fetches revisions from source
126
    def test_merge_fetches(self):
127
        """Merge brings across history from source"""
128
        os.mkdir('br1')
129
        br1 = Branch.initialize('br1')
1457.1.17 by Robert Collins
Branch.commit() has moved to WorkingTree.commit(). (Robert Collins)
130
        br1.working_tree().commit(message='rev 1-1', rev_id='1-1')
1185.16.94 by mbp at sourcefrog
New test that merge fetches revisions from source
131
        copy_branch(br1, 'br2')
132
        br2 = Branch.open('br2')
1457.1.17 by Robert Collins
Branch.commit() has moved to WorkingTree.commit(). (Robert Collins)
133
        br1.working_tree().commit(message='rev 1-2', rev_id='1-2')
134
        br2.working_tree().commit(message='rev 2-1', rev_id='2-1')
1185.16.94 by mbp at sourcefrog
New test that merge fetches revisions from source
135
        merge(other_revision=['br1', -1], base_revision=[None, None], 
136
              this_dir='br2')
1185.16.96 by mbp at sourcefrog
More merge/fetch tests
137
        self._check_revs_present(br2)
138
139
    def _check_revs_present(self, br2):
1185.16.94 by mbp at sourcefrog
New test that merge fetches revisions from source
140
        for rev_id in '1-1', '1-2', '2-1':
141
            self.assertTrue(br2.has_revision(rev_id))
142
            rev = br2.get_revision(rev_id)
143
            self.assertEqual(rev.revision_id, rev_id)
144
            self.assertTrue(br2.get_inventory(rev_id))
145
1404 by Robert Collins
only pull remote text weaves once per fetch operation
146
1185.16.96 by mbp at sourcefrog
More merge/fetch tests
147
148
class TestMergeFileHistory(TestCaseInTempDir):
149
    def setUp(self):
150
        TestCaseInTempDir.setUp(self)
151
        os.mkdir('br1')
152
        br1 = Branch.initialize('br1')
153
        self.build_tree_contents([('br1/file', 'original contents\n')])
154
        br1.add(['file'], ['this-file-id'])
1457.1.17 by Robert Collins
Branch.commit() has moved to WorkingTree.commit(). (Robert Collins)
155
        br1.working_tree().commit(message='rev 1-1', rev_id='1-1')
1185.16.96 by mbp at sourcefrog
More merge/fetch tests
156
        copy_branch(br1, 'br2')
157
        br2 = Branch.open('br2')
158
        self.build_tree_contents([('br1/file', 'original from 1\n')])
1457.1.17 by Robert Collins
Branch.commit() has moved to WorkingTree.commit(). (Robert Collins)
159
        br1.working_tree().commit(message='rev 1-2', rev_id='1-2')
1185.16.96 by mbp at sourcefrog
More merge/fetch tests
160
        self.build_tree_contents([('br1/file', 'agreement\n')])
1457.1.17 by Robert Collins
Branch.commit() has moved to WorkingTree.commit(). (Robert Collins)
161
        br1.working_tree().commit(message='rev 1-3', rev_id='1-3')
1185.16.96 by mbp at sourcefrog
More merge/fetch tests
162
        self.build_tree_contents([('br2/file', 'contents in 2\n')])
1457.1.17 by Robert Collins
Branch.commit() has moved to WorkingTree.commit(). (Robert Collins)
163
        br2.working_tree().commit(message='rev 2-1', rev_id='2-1')
1185.16.96 by mbp at sourcefrog
More merge/fetch tests
164
        self.build_tree_contents([('br2/file', 'agreement\n')])
1457.1.17 by Robert Collins
Branch.commit() has moved to WorkingTree.commit(). (Robert Collins)
165
        br2.working_tree().commit(message='rev 2-2', rev_id='2-2')
1185.16.96 by mbp at sourcefrog
More merge/fetch tests
166
167
    def test_merge_fetches_file_history(self):
168
        """Merge brings across file histories"""
169
        br2 = Branch.open('br2')
170
        merge(other_revision=['br1', -1], base_revision=[None, None], 
171
              this_dir='br2')
172
        for rev_id, text in [('1-2', 'original from 1\n'),
173
                             ('1-3', 'agreement\n'),
174
                             ('2-1', 'contents in 2\n'),
175
                             ('2-2', 'agreement\n')]:
176
            self.assertEqualDiff(br2.revision_tree(rev_id).get_file_text('this-file-id'),
177
                                 text)
178
179
180
181
1404 by Robert Collins
only pull remote text weaves once per fetch operation
182
class TestHttpFetch(TestCaseWithWebserver):
183
184
    def setUp(self):
185
        super(TestHttpFetch, self).setUp()
186
        self.weblogs = []
187
188
    def test_fetch(self):
189
        #highest indices a: 5, b: 7
1185.16.145 by Martin Pool
Remove all assert statements from test cases.
190
        br_a, br_b = make_branches(self)
1404 by Robert Collins
only pull remote text weaves once per fetch operation
191
        br_rem_a = Branch.open(self.get_remote_url(br_a._transport.base))
192
        fetch_steps(self, br_rem_a, br_b, br_a)
193
194
    def log(self, *args):
195
        """Capture web server log messages for introspection."""
196
        super(TestHttpFetch, self).log(*args)
197
        if args[0].startswith("webserver"):
198
            self.weblogs.append(args[0])
199
200
    def test_weaves_are_retrieved_once(self):
201
        self.build_tree(("source/", "source/file", "target/"))
202
        branch = Branch.initialize("source")
203
        branch.add(["file"], ["id"])
1457.1.17 by Robert Collins
Branch.commit() has moved to WorkingTree.commit(). (Robert Collins)
204
        branch.working_tree().commit("added file")
1404 by Robert Collins
only pull remote text weaves once per fetch operation
205
        print >>open("source/file", 'w'), "blah"
1457.1.17 by Robert Collins
Branch.commit() has moved to WorkingTree.commit(). (Robert Collins)
206
        branch.working_tree().commit("changed file")
1404 by Robert Collins
only pull remote text weaves once per fetch operation
207
        target = Branch.initialize("target/")
208
        source = Branch.open(self.get_remote_url("source/"))
209
        self.assertEqual(greedy_fetch(target, source), (2, []))
1430 by Robert Collins
touchup the prefixed-store patch
210
        # this is the path to the literal file. As format changes 
211
        # occur it needs to be updated. FIXME: ask the store for the
212
        # path.
213
        weave_suffix = 'weaves/ce/id.weave HTTP/1.1" 200 -'
1404 by Robert Collins
only pull remote text weaves once per fetch operation
214
        self.assertEqual(1,
215
            len([log for log in self.weblogs if log.endswith(weave_suffix)]))
1437 by Robert Collins
lock during fetch, which is a separate code path to the special case of cloning
216
        inventory_weave_suffix = 'inventory.weave HTTP/1.1" 200 -'
217
        self.assertEqual(1,
218
            len([log for log in self.weblogs if log.endswith(
219
                inventory_weave_suffix)]))
1417.1.12 by Robert Collins
cache revision history during read transactions
220
        # this r-h check test will prevent regressions, but it currently already 
221
        # passes, before the patch to cache-rh is applied :[
222
        revision_history_suffix = 'revision-history HTTP/1.1" 200 -'
223
        self.assertEqual(1,
224
            len([log for log in self.weblogs if log.endswith(
225
                revision_history_suffix)]))
1417.1.13 by Robert Collins
do not download remote ancestry.weave if the target revision we are stopping at is in our local store
226
        self.weblogs = []
227
        # check there is nothing more to fetch
228
        source = Branch.open(self.get_remote_url("source/"))
229
        self.assertEqual(greedy_fetch(target, source), (0, []))
230
        self.failUnless(self.weblogs[0].endswith('branch-format HTTP/1.1" 200 -'))
231
        self.failUnless(self.weblogs[1].endswith('revision-history HTTP/1.1" 200 -'))
232
        self.assertEqual(2, len(self.weblogs))