~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_fetch.py

  • Committer: Robert Collins
  • Date: 2006-02-15 08:11:37 UTC
  • mto: (1534.1.24 integration)
  • mto: This revision was merged to the branch mainline in revision 1554.
  • Revision ID: robertc@robertcollins.net-20060215081137-4c27377517e96dd1
Make format 4/5/6 branches share a single LockableFiles instance across wt/branch/repository.

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
20
23
import bzrlib.errors
21
 
from bzrlib.selftest.testrevision import make_branches
 
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
22
28
from bzrlib.trace import mutter
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
from bzrlib.workingtree import WorkingTree
30
30
 
31
31
 
32
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
 
33
    return branch.repository.has_revision(revision_id)
38
34
 
39
35
def fetch_steps(self, br_a, br_b, writable_a):
40
36
    """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
 
            
45
 
    self.assertFalse(has_revision(br_b, br_a.revision_history()[3]))
46
 
    self.assert_(has_revision(br_b, br_a.revision_history()[2]))
 
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]))
47
42
    self.assertEquals(len(br_b.revision_history()), 7)
48
43
    self.assertEquals(greedy_fetch(br_b, br_a, br_a.revision_history()[2])[0], 0)
49
 
 
50
44
    # greedy_fetch is not supposed to alter the revision history
51
45
    self.assertEquals(len(br_b.revision_history()), 7)
52
 
    self.assertFalse(has_revision(br_b, br_a.revision_history()[3]))
 
46
    self.assertFalse(repo_b.has_revision(br_a.revision_history()[3]))
53
47
 
54
 
    self.assertEquals(len(br_b.revision_history()), 7)
 
48
    # fetching the next revision up in sample data copies one revision
55
49
    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
    self.assertTrue(repo_b.has_revision(br_a.revision_history()[3]))
57
51
    self.assertFalse(has_revision(br_a, br_b.revision_history()[6]))
58
 
    self.assert_(has_revision(br_a, br_b.revision_history()[5]))
 
52
    self.assertTrue(br_a.repository.has_revision(br_b.revision_history()[5]))
59
53
 
60
54
    # When a non-branch ancestor is missing, it should be unlisted...
61
55
    # as its not reference from the inventory weave.
62
 
    br_b4 = new_branch('br_4')
 
56
    br_b4 = self.make_branch('br_4')
63
57
    count, failures = greedy_fetch(br_b4, br_b)
64
58
    self.assertEqual(count, 7)
65
59
    self.assertEqual(failures, [])
66
60
 
67
61
    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]))
 
62
    self.assertTrue(has_revision(br_a, br_b.revision_history()[3]))
 
63
    self.assertTrue(has_revision(br_a, br_b.revision_history()[4]))
70
64
        
71
 
    br_b2 = new_branch('br_b2')
 
65
    br_b2 = self.make_branch('br_b2')
72
66
    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]))
 
67
    self.assertTrue(has_revision(br_b2, br_b.revision_history()[4]))
 
68
    self.assertTrue(has_revision(br_b2, br_a.revision_history()[2]))
75
69
    self.assertFalse(has_revision(br_b2, br_a.revision_history()[3]))
76
70
 
77
 
    br_a2 = new_branch('br_a2')
 
71
    br_a2 = self.make_branch('br_a2')
78
72
    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]))
 
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]))
82
76
 
83
 
    br_a3 = new_branch('br_a3')
 
77
    br_a3 = self.make_branch('br_a3')
 
78
    # pulling a branch with no revisions grabs nothing, regardless of 
 
79
    # whats in the inventory.
84
80
    self.assertEquals(greedy_fetch(br_a3, br_a2)[0], 0)
85
81
    for revno in range(4):
86
 
        self.assertFalse(has_revision(br_a3, br_a.revision_history()[revno]))
 
82
        self.assertFalse(
 
83
            br_a3.repository.has_revision(br_a.revision_history()[revno]))
87
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
88
86
    fetched = greedy_fetch(br_a3, br_a2, br_a.revision_history()[3])[0]
89
87
    self.assertEquals(fetched, 3, "fetched %d instead of 3" % fetched)
90
88
    # InstallFailed should be raised if the branch is missing the revision
96
94
    br_a2.append_revision('a-b-c')
97
95
    self.assertRaises(bzrlib.errors.InstallFailed, greedy_fetch, br_a3,
98
96
                      br_a2)
99
 
 
100
 
 
101
97
    #TODO: test that fetch correctly does reweaving when needed. RBC 20051008
102
 
 
103
 
class TestFetch(TestCaseInTempDir):
 
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):
104
103
 
105
104
    def test_fetch(self):
106
105
        #highest indices a: 5, b: 7
108
107
        fetch_steps(self, br_a, br_b, br_a)
109
108
 
110
109
 
111
 
class TestMergeFetch(TestCaseInTempDir):
 
110
class TestMergeFetch(TestCaseWithTransport):
112
111
 
113
112
    def test_merge_fetches_unrelated(self):
114
113
        """Merge brings across history from unrelated source"""
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')
 
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')
122
121
        merge(other_revision=['br1', -1], base_revision=['br1', 0],
123
122
              this_dir='br2')
124
123
        self._check_revs_present(br2)
125
124
 
126
125
    def test_merge_fetches(self):
127
126
        """Merge brings across history from source"""
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')
 
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')
135
134
        merge(other_revision=['br1', -1], base_revision=[None, None], 
136
135
              this_dir='br2')
137
136
        self._check_revs_present(br2)
138
137
 
139
138
    def _check_revs_present(self, br2):
140
139
        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)
 
140
            self.assertTrue(br2.repository.has_revision(rev_id))
 
141
            rev = br2.repository.get_revision(rev_id)
143
142
            self.assertEqual(rev.revision_id, rev_id)
144
 
            self.assertTrue(br2.get_inventory(rev_id))
145
 
 
146
 
 
147
 
 
148
 
class TestMergeFileHistory(TestCaseInTempDir):
 
143
            self.assertTrue(br2.repository.get_inventory(rev_id))
 
144
 
 
145
 
 
146
class TestMergeFileHistory(TestCaseWithTransport):
 
147
 
149
148
    def setUp(self):
150
 
        TestCaseInTempDir.setUp(self)
151
 
        os.mkdir('br1')
152
 
        br1 = Branch.initialize('br1')
 
149
        super(TestMergeFileHistory, self).setUp()
 
150
        wt1 = self.make_branch_and_tree('br1')
 
151
        br1 = wt1.branch
153
152
        self.build_tree_contents([('br1/file', 'original contents\n')])
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')
 
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
158
        self.build_tree_contents([('br1/file', 'original from 1\n')])
159
 
        br1.working_tree().commit(message='rev 1-2', rev_id='1-2')
 
159
        wt1.commit(message='rev 1-2', rev_id='1-2')
160
160
        self.build_tree_contents([('br1/file', 'agreement\n')])
161
 
        br1.working_tree().commit(message='rev 1-3', rev_id='1-3')
 
161
        wt1.commit(message='rev 1-3', rev_id='1-3')
162
162
        self.build_tree_contents([('br2/file', 'contents in 2\n')])
163
 
        br2.working_tree().commit(message='rev 2-1', rev_id='2-1')
 
163
        wt2.commit(message='rev 2-1', rev_id='2-1')
164
164
        self.build_tree_contents([('br2/file', 'agreement\n')])
165
 
        br2.working_tree().commit(message='rev 2-2', rev_id='2-2')
 
165
        wt2.commit(message='rev 2-2', rev_id='2-2')
166
166
 
167
167
    def test_merge_fetches_file_history(self):
168
168
        """Merge brings across file histories"""
173
173
                             ('1-3', 'agreement\n'),
174
174
                             ('2-1', 'contents in 2\n'),
175
175
                             ('2-2', 'agreement\n')]:
176
 
            self.assertEqualDiff(br2.revision_tree(rev_id).get_file_text('this-file-id'),
177
 
                                 text)
178
 
 
179
 
 
 
176
            self.assertEqualDiff(
 
177
                br2.repository.revision_tree(
 
178
                    rev_id).get_file_text('this-file-id'), text)
180
179
 
181
180
 
182
181
class TestHttpFetch(TestCaseWithWebserver):
183
 
 
184
 
    def setUp(self):
185
 
        super(TestHttpFetch, self).setUp()
186
 
        self.weblogs = []
 
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 ?
187
185
 
188
186
    def test_fetch(self):
189
187
        #highest indices a: 5, b: 7
190
188
        br_a, br_b = make_branches(self)
191
 
        br_rem_a = Branch.open(self.get_remote_url(br_a._transport.base))
 
189
        br_rem_a = Branch.open(self.get_readonly_url('branch1'))
192
190
        fetch_steps(self, br_rem_a, br_b, br_a)
193
191
 
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
192
    def test_weaves_are_retrieved_once(self):
201
193
        self.build_tree(("source/", "source/file", "target/"))
202
 
        branch = Branch.initialize("source")
203
 
        branch.add(["file"], ["id"])
204
 
        branch.working_tree().commit("added file")
 
194
        wt = self.make_branch_and_tree('source')
 
195
        branch = wt.branch
 
196
        wt.add(["file"], ["id"])
 
197
        wt.commit("added file")
205
198
        print >>open("source/file", 'w'), "blah"
206
 
        branch.working_tree().commit("changed file")
207
 
        target = Branch.initialize("target/")
208
 
        source = Branch.open(self.get_remote_url("source/"))
 
199
        wt.commit("changed file")
 
200
        target = BzrDir.create_branch_and_repo("target/")
 
201
        source = Branch.open(self.get_readonly_url("source/"))
209
202
        self.assertEqual(greedy_fetch(target, source), (2, []))
210
203
        # this is the path to the literal file. As format changes 
211
204
        # occur it needs to be updated. FIXME: ask the store for the
212
205
        # path.
213
206
        weave_suffix = 'weaves/ce/id.weave HTTP/1.1" 200 -'
214
207
        self.assertEqual(1,
215
 
            len([log for log in self.weblogs if log.endswith(weave_suffix)]))
 
208
            len([log for log in self.get_readonly_server().logs if log.endswith(weave_suffix)]))
216
209
        inventory_weave_suffix = 'inventory.weave HTTP/1.1" 200 -'
217
210
        self.assertEqual(1,
218
 
            len([log for log in self.weblogs if log.endswith(
 
211
            len([log for log in self.get_readonly_server().logs if log.endswith(
219
212
                inventory_weave_suffix)]))
220
213
        # this r-h check test will prevent regressions, but it currently already 
221
214
        # passes, before the patch to cache-rh is applied :[
222
215
        revision_history_suffix = 'revision-history HTTP/1.1" 200 -'
223
216
        self.assertEqual(1,
224
 
            len([log for log in self.weblogs if log.endswith(
 
217
            len([log for log in self.get_readonly_server().logs if log.endswith(
225
218
                revision_history_suffix)]))
226
 
        self.weblogs = []
 
219
        # FIXME naughty poking in there.
 
220
        self.get_readonly_server().logs = []
227
221
        # check there is nothing more to fetch
228
 
        source = Branch.open(self.get_remote_url("source/"))
 
222
        source = Branch.open(self.get_readonly_url("source/"))
229
223
        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))
 
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))