~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/selftest/testfetch.py

  • Committer: Martin Pool
  • Date: 2005-09-16 09:56:24 UTC
  • Revision ID: mbp@sourcefrog.net-20050916095623-ca0dff452934f21f
- make progress bar more tolerant of out-of-range values

Show diffs side-by-side

added added

removed removed

Lines of Context:
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
import sys
17
18
import os
18
 
import sys
19
19
 
 
20
import bzrlib.errors
 
21
from bzrlib.selftest.testrevision import make_branches
 
22
from bzrlib.trace import mutter
20
23
from bzrlib.branch import Branch
21
 
from bzrlib.bzrdir import BzrDir
22
 
from bzrlib.builtins import merge
23
 
import bzrlib.errors
24
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
25
 
 
26
from bzrlib.selftest import TestCaseInTempDir
 
27
        
31
28
 
32
29
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
 
     
38
 
    # TODO RBC 20060201 make this a repository test.
39
 
    repo_b = br_b.repository
40
 
    self.assertFalse(repo_b.has_revision(br_a.revision_history()[3]))
41
 
    self.assertTrue(repo_b.has_revision(br_a.revision_history()[2]))
42
 
    self.assertEquals(len(br_b.revision_history()), 7)
43
 
    self.assertEquals(greedy_fetch(br_b, br_a, br_a.revision_history()[2])[0], 0)
44
 
    # greedy_fetch is not supposed to alter the revision history
45
 
    self.assertEquals(len(br_b.revision_history()), 7)
46
 
    self.assertFalse(repo_b.has_revision(br_a.revision_history()[3]))
47
 
 
48
 
    # fetching the next revision up in sample data copies one revision
49
 
    self.assertEquals(greedy_fetch(br_b, br_a, br_a.revision_history()[3])[0], 1)
50
 
    self.assertTrue(repo_b.has_revision(br_a.revision_history()[3]))
51
 
    self.assertFalse(has_revision(br_a, br_b.revision_history()[6]))
52
 
    self.assertTrue(br_a.repository.has_revision(br_b.revision_history()[5]))
53
 
 
54
 
    # When a non-branch ancestor is missing, it should be unlisted...
55
 
    # as its not reference from the inventory weave.
56
 
    br_b4 = self.make_branch('br_4')
57
 
    count, failures = greedy_fetch(br_b4, br_b)
58
 
    self.assertEqual(count, 7)
59
 
    self.assertEqual(failures, [])
60
 
 
61
 
    self.assertEqual(greedy_fetch(writable_a, br_b)[0], 1)
62
 
    self.assertTrue(has_revision(br_a, br_b.revision_history()[3]))
63
 
    self.assertTrue(has_revision(br_a, br_b.revision_history()[4]))
 
30
    try:
 
31
        branch.get_revision_xml_file(revision_id)
 
32
        return True
 
33
    except bzrlib.errors.NoSuchRevision:
 
34
        return False
 
35
 
 
36
 
 
37
 
 
38
class TestFetch(TestCaseInTempDir):
 
39
    def SKIPPED_old_test_fetch(self):
 
40
        """obsolete: new commit code depends on parents being present
 
41
        so the test data no longer suits this test."""
64
42
        
65
 
    br_b2 = self.make_branch('br_b2')
66
 
    self.assertEquals(greedy_fetch(br_b2, br_b)[0], 7)
67
 
    self.assertTrue(has_revision(br_b2, br_b.revision_history()[4]))
68
 
    self.assertTrue(has_revision(br_b2, br_a.revision_history()[2]))
69
 
    self.assertFalse(has_revision(br_b2, br_a.revision_history()[3]))
70
 
 
71
 
    br_a2 = self.make_branch('br_a2')
72
 
    self.assertEquals(greedy_fetch(br_a2, br_a)[0], 9)
73
 
    self.assertTrue(has_revision(br_a2, br_b.revision_history()[4]))
74
 
    self.assertTrue(has_revision(br_a2, br_a.revision_history()[3]))
75
 
    self.assertTrue(has_revision(br_a2, br_a.revision_history()[2]))
76
 
 
77
 
    br_a3 = self.make_branch('br_a3')
78
 
    # pulling a branch with no revisions grabs nothing, regardless of 
79
 
    # whats in the inventory.
80
 
    self.assertEquals(greedy_fetch(br_a3, br_a2)[0], 0)
81
 
    for revno in range(4):
82
 
        self.assertFalse(
83
 
            br_a3.repository.has_revision(br_a.revision_history()[revno]))
84
 
    self.assertEqual(greedy_fetch(br_a3, br_a2, br_a.revision_history()[2])[0], 3)
85
 
    # pull the 3 revisions introduced by a@u-0-3
86
 
    fetched = greedy_fetch(br_a3, br_a2, br_a.revision_history()[3])[0]
87
 
    self.assertEquals(fetched, 3, "fetched %d instead of 3" % fetched)
88
 
    # InstallFailed should be raised if the branch is missing the revision
89
 
    # that was requested.
90
 
    self.assertRaises(bzrlib.errors.InstallFailed, greedy_fetch, br_a3,
91
 
                      br_a2, 'pizza')
92
 
    # InstallFailed should be raised if the branch is missing a revision
93
 
    # from its own revision history
94
 
    br_a2.append_revision('a-b-c')
95
 
    self.assertRaises(bzrlib.errors.InstallFailed, greedy_fetch, br_a3,
96
 
                      br_a2)
97
 
    #TODO: test that fetch correctly does reweaving when needed. RBC 20051008
98
 
    # Note that this means - updating the weave when ghosts are filled in to 
99
 
    # add the right parents.
100
 
 
101
 
 
102
 
class TestFetch(TestCaseWithTransport):
103
 
 
104
 
    def test_fetch(self):
105
 
        #highest indices a: 5, b: 7
106
 
        br_a, br_b = make_branches(self)
107
 
        fetch_steps(self, br_a, br_b, br_a)
108
 
 
109
 
 
110
 
class TestMergeFetch(TestCaseWithTransport):
111
 
 
112
 
    def test_merge_fetches_unrelated(self):
113
 
        """Merge brings across history from unrelated source"""
114
 
        wt1 = self.make_branch_and_tree('br1')
115
 
        br1 = wt1.branch
116
 
        wt1.commit(message='rev 1-1', rev_id='1-1')
117
 
        wt1.commit(message='rev 1-2', rev_id='1-2')
118
 
        wt2 = self.make_branch_and_tree('br2')
119
 
        br2 = wt2.branch
120
 
        wt2.commit(message='rev 2-1', rev_id='2-1')
121
 
        merge(other_revision=['br1', -1], base_revision=['br1', 0],
122
 
              this_dir='br2')
123
 
        self._check_revs_present(br2)
124
 
 
125
 
    def test_merge_fetches(self):
126
 
        """Merge brings across history from source"""
127
 
        wt1 = self.make_branch_and_tree('br1')
128
 
        br1 = wt1.branch
129
 
        wt1.commit(message='rev 1-1', rev_id='1-1')
130
 
        dir_2 = br1.bzrdir.sprout('br2')
131
 
        br2 = dir_2.open_branch()
132
 
        wt1.commit(message='rev 1-2', rev_id='1-2')
133
 
        dir_2.open_workingtree().commit(message='rev 2-1', rev_id='2-1')
134
 
        merge(other_revision=['br1', -1], base_revision=[None, None], 
135
 
              this_dir='br2')
136
 
        self._check_revs_present(br2)
137
 
 
138
 
    def _check_revs_present(self, br2):
139
 
        for rev_id in '1-1', '1-2', '2-1':
140
 
            self.assertTrue(br2.repository.has_revision(rev_id))
141
 
            rev = br2.repository.get_revision(rev_id)
142
 
            self.assertEqual(rev.revision_id, rev_id)
143
 
            self.assertTrue(br2.repository.get_inventory(rev_id))
144
 
 
145
 
 
146
 
class TestMergeFileHistory(TestCaseWithTransport):
147
 
 
148
 
    def setUp(self):
149
 
        super(TestMergeFileHistory, self).setUp()
150
 
        wt1 = self.make_branch_and_tree('br1')
151
 
        br1 = wt1.branch
152
 
        self.build_tree_contents([('br1/file', 'original contents\n')])
153
 
        wt1.add('file', 'this-file-id')
154
 
        wt1.commit(message='rev 1-1', rev_id='1-1')
155
 
        dir_2 = br1.bzrdir.sprout('br2')
156
 
        br2 = dir_2.open_branch()
157
 
        wt2 = dir_2.open_workingtree()
158
 
        self.build_tree_contents([('br1/file', 'original from 1\n')])
159
 
        wt1.commit(message='rev 1-2', rev_id='1-2')
160
 
        self.build_tree_contents([('br1/file', 'agreement\n')])
161
 
        wt1.commit(message='rev 1-3', rev_id='1-3')
162
 
        self.build_tree_contents([('br2/file', 'contents in 2\n')])
163
 
        wt2.commit(message='rev 2-1', rev_id='2-1')
164
 
        self.build_tree_contents([('br2/file', 'agreement\n')])
165
 
        wt2.commit(message='rev 2-2', rev_id='2-2')
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(
177
 
                br2.repository.revision_tree(
178
 
                    rev_id).get_file_text('this-file-id'), text)
179
 
 
180
 
 
181
 
class TestHttpFetch(TestCaseWithWebserver):
182
 
    # FIXME RBC 20060124 this really isn't web specific, perhaps an
183
 
    # instrumented readonly transport? Can we do an instrumented
184
 
    # adapter and use self.get_readonly_url ?
185
 
 
186
 
    def test_fetch(self):
187
 
        #highest indices a: 5, b: 7
188
 
        br_a, br_b = make_branches(self)
189
 
        br_rem_a = Branch.open(self.get_readonly_url('branch1'))
190
 
        fetch_steps(self, br_rem_a, br_b, br_a)
191
 
 
192
 
    def test_weaves_are_retrieved_once(self):
193
 
        self.build_tree(("source/", "source/file", "target/"))
194
 
        wt = self.make_branch_and_tree('source')
195
 
        branch = wt.branch
196
 
        wt.add(["file"], ["id"])
197
 
        wt.commit("added file")
198
 
        print >>open("source/file", 'w'), "blah"
199
 
        wt.commit("changed file")
200
 
        target = BzrDir.create_branch_and_repo("target/")
201
 
        source = Branch.open(self.get_readonly_url("source/"))
202
 
        self.assertEqual(greedy_fetch(target, source), (2, []))
203
 
        # this is the path to the literal file. As format changes 
204
 
        # occur it needs to be updated. FIXME: ask the store for the
205
 
        # path.
206
 
        weave_suffix = 'weaves/ce/id.weave HTTP/1.1" 200 -'
207
 
        self.assertEqual(1,
208
 
            len([log for log in self.get_readonly_server().logs if log.endswith(weave_suffix)]))
209
 
        inventory_weave_suffix = 'inventory.weave HTTP/1.1" 200 -'
210
 
        self.assertEqual(1,
211
 
            len([log for log in self.get_readonly_server().logs if log.endswith(
212
 
                inventory_weave_suffix)]))
213
 
        # this r-h check test will prevent regressions, but it currently already 
214
 
        # passes, before the patch to cache-rh is applied :[
215
 
        revision_history_suffix = 'revision-history HTTP/1.1" 200 -'
216
 
        self.assertEqual(1,
217
 
            len([log for log in self.get_readonly_server().logs if log.endswith(
218
 
                revision_history_suffix)]))
219
 
        # FIXME naughty poking in there.
220
 
        self.get_readonly_server().logs = []
221
 
        # check there is nothing more to fetch
222
 
        source = Branch.open(self.get_readonly_url("source/"))
223
 
        self.assertEqual(greedy_fetch(target, source), (0, []))
224
 
        self.failUnless(self.get_readonly_server().logs[0].endswith('branch-format HTTP/1.1" 200 -'))
225
 
        self.failUnless(self.get_readonly_server().logs[1].endswith('revision-history HTTP/1.1" 200 -'))
226
 
        self.assertEqual(2, len(self.get_readonly_server().logs))
 
43
        def new_branch(name):
 
44
            os.mkdir(name)
 
45
            return Branch(name, init=True)
 
46
            
 
47
        #highest indices a: 5, b: 7
 
48
        br_a, br_b = make_branches()
 
49
        assert not has_revision(br_b, br_a.revision_history()[3])
 
50
        assert has_revision(br_b, br_a.revision_history()[2])
 
51
        assert len(br_b.revision_history()) == 7
 
52
        assert greedy_fetch(br_b, br_a, br_a.revision_history()[2])[0] == 0
 
53
 
 
54
        # greedy_fetch is not supposed to alter the revision history
 
55
        assert len(br_b.revision_history()) == 7
 
56
        assert not has_revision(br_b, br_a.revision_history()[3])
 
57
 
 
58
        assert len(br_b.revision_history()) == 7
 
59
        assert greedy_fetch(br_b, br_a, br_a.revision_history()[3])[0] == 1
 
60
        assert has_revision(br_b, br_a.revision_history()[3])
 
61
        assert not has_revision(br_a, br_b.revision_history()[3])
 
62
        assert not has_revision(br_a, br_b.revision_history()[4])
 
63
 
 
64
        # When a non-branch ancestor is missing, it should be a failure, not
 
65
        # exception
 
66
        br_a4 = new_branch('br_a4')
 
67
        count, failures = greedy_fetch(br_a4, br_a)
 
68
        assert count == 6
 
69
        assert failures == set((br_b.revision_history()[4],
 
70
                                br_b.revision_history()[5])) 
 
71
 
 
72
        assert greedy_fetch(br_a, br_b)[0] == 4
 
73
        assert has_revision(br_a, br_b.revision_history()[3])
 
74
        assert has_revision(br_a, br_b.revision_history()[4])
 
75
 
 
76
        br_b2 = new_branch('br_b2')
 
77
        assert greedy_fetch(br_b2, br_b)[0] == 7
 
78
        assert has_revision(br_b2, br_b.revision_history()[4])
 
79
        assert has_revision(br_b2, br_a.revision_history()[2])
 
80
        assert not has_revision(br_b2, br_a.revision_history()[3])
 
81
 
 
82
        br_a2 = new_branch('br_a2')
 
83
        assert greedy_fetch(br_a2, br_a)[0] == 9
 
84
        assert has_revision(br_a2, br_b.revision_history()[4])
 
85
        assert has_revision(br_a2, br_a.revision_history()[3])
 
86
 
 
87
        br_a3 = new_branch('br_a3')
 
88
        assert greedy_fetch(br_a3, br_a2)[0] == 0
 
89
        for revno in range(4):
 
90
            assert not has_revision(br_a3, br_a.revision_history()[revno])
 
91
        assert greedy_fetch(br_a3, br_a2, br_a.revision_history()[2])[0] == 3
 
92
        fetched = greedy_fetch(br_a3, br_a2, br_a.revision_history()[3])[0]
 
93
        assert fetched == 3, "fetched %d instead of 3" % fetched
 
94
        # InstallFailed should be raised if the branch is missing the revision
 
95
        # that was requested.
 
96
        self.assertRaises(bzrlib.errors.InstallFailed, greedy_fetch, br_a3,
 
97
                          br_a2, 'pizza')
 
98
        # InstallFailed should be raised if the branch is missing a revision
 
99
        # from its own revision history
 
100
        br_a2.append_revision('a-b-c')
 
101
        self.assertRaises(bzrlib.errors.InstallFailed, greedy_fetch, br_a3,
 
102
                          br_a2)
 
103
 
 
104
 
 
105
 
 
106
if __name__ == '__main__':
 
107
    import unittest
 
108
    unittest.main()
 
109