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