~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/selftest/testfetch.py

  • Committer: John Arbash Meinel
  • Date: 2005-11-14 17:02:35 UTC
  • mto: (1587.1.6 bound-branches)
  • mto: This revision was merged to the branch mainline in revision 1590.
  • Revision ID: john@arbash-meinel.com-20051114170235-f85afa458bae956e
Fixing up the error message for a failed bind.

Show diffs side-by-side

added added

removed removed

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