~bzr-pqm/bzr/bzr.dev

2697.2.2 by Martin Pool
deprecate Branch.append_revision
1
# Copyright (C) 2005, 2007 Canonical Ltd
1887.1.1 by Adeodato Simó
Do not separate paragraphs in the copyright statement with blank lines,
2
#
1115 by Martin Pool
- split fetch tests into a separate file
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.
1887.1.1 by Adeodato Simó
Do not separate paragraphs in the copyright statement with blank lines,
7
#
1115 by Martin Pool
- split fetch tests into a separate file
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.
1887.1.1 by Adeodato Simó
Do not separate paragraphs in the copyright statement with blank lines,
12
#
1115 by Martin Pool
- split fetch tests into a separate file
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
2004.1.22 by v.ladeuil+lp at free
Implements Range header handling for GET requests. Fix a test.
18
import re
1238 by Martin Pool
- remove a lot of dead code from fetch
19
import sys
20
2697.2.2 by Martin Pool
deprecate Branch.append_revision
21
import bzrlib
2323.8.2 by Aaron Bentley
Give a nicer error on fetch when repos are in incompatible formats
22
from bzrlib import (
23
    bzrdir,
24
    errors,
1551.15.70 by Aaron Bentley
Avoid using builtins.merge
25
    merge,
2323.8.2 by Aaron Bentley
Give a nicer error on fetch when repos are in incompatible formats
26
    repository,
27
    )
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
28
from bzrlib.branch import Branch
1534.4.41 by Robert Collins
Branch now uses BzrDir reasonably sanely.
29
from bzrlib.bzrdir import BzrDir
2241.1.5 by Martin Pool
Move KnitFormat2 into repofmt
30
from bzrlib.repofmt import knitrepo
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
31
from bzrlib.tests import TestCaseWithTransport
3102.1.1 by Vincent Ladeuil
Rename bzrlib/test/HTTPTestUtils.py to bzrlib/tests/http_utils.py and fix
32
from bzrlib.tests.http_utils import TestCaseWithWebserver
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
33
from bzrlib.tests.test_revision import make_branches
34
from bzrlib.trace import mutter
1551.8.42 by Aaron Bentley
Ensure that fetch properly updates inventory root knit
35
from bzrlib.upgrade import Convert
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
36
from bzrlib.workingtree import WorkingTree
1185.1.41 by Robert Collins
massive patch from Alexander Belchenko - many PEP8 fixes, removes unused function uuid
37
2696.3.3 by Martin Pool
Start setting the default format to dirstate-tags
38
# These tests are a bit old; please instead add new tests into
39
# interrepository_implementations/ so they'll run on all relevant
40
# combinations.
41
1115 by Martin Pool
- split fetch tests into a separate file
42
1238 by Martin Pool
- remove a lot of dead code from fetch
43
def has_revision(branch, revision_id):
1534.4.41 by Robert Collins
Branch now uses BzrDir reasonably sanely.
44
    return branch.repository.has_revision(revision_id)
1534.4.5 by Robert Collins
Turn branch format.open into a factory.
45
1393 by Robert Collins
reenable remotebranch tests
46
def fetch_steps(self, br_a, br_b, writable_a):
47
    """A foreign test method for testing fetch locally and remotely."""
1534.4.41 by Robert Collins
Branch now uses BzrDir reasonably sanely.
48
     
49
    # TODO RBC 20060201 make this a repository test.
50
    repo_b = br_b.repository
51
    self.assertFalse(repo_b.has_revision(br_a.revision_history()[3]))
52
    self.assertTrue(repo_b.has_revision(br_a.revision_history()[2]))
1185.16.145 by Martin Pool
Remove all assert statements from test cases.
53
    self.assertEquals(len(br_b.revision_history()), 7)
1534.1.31 by Robert Collins
Deprecated fetch.fetch and fetch.greedy_fetch for branch.fetch, and move the Repository.fetch internals to InterRepo and InterWeaveRepo.
54
    self.assertEquals(br_b.fetch(br_a, br_a.revision_history()[2])[0], 0)
55
    # branch.fetch is not supposed to alter the revision history
1185.16.145 by Martin Pool
Remove all assert statements from test cases.
56
    self.assertEquals(len(br_b.revision_history()), 7)
1534.4.41 by Robert Collins
Branch now uses BzrDir reasonably sanely.
57
    self.assertFalse(repo_b.has_revision(br_a.revision_history()[3]))
1393 by Robert Collins
reenable remotebranch tests
58
1534.4.50 by Robert Collins
Got the bzrdir api straightened out, plenty of refactoring to use it pending, but the api is up and running.
59
    # fetching the next revision up in sample data copies one revision
1534.1.31 by Robert Collins
Deprecated fetch.fetch and fetch.greedy_fetch for branch.fetch, and move the Repository.fetch internals to InterRepo and InterWeaveRepo.
60
    self.assertEquals(br_b.fetch(br_a, br_a.revision_history()[3])[0], 1)
1534.4.41 by Robert Collins
Branch now uses BzrDir reasonably sanely.
61
    self.assertTrue(repo_b.has_revision(br_a.revision_history()[3]))
1185.16.145 by Martin Pool
Remove all assert statements from test cases.
62
    self.assertFalse(has_revision(br_a, br_b.revision_history()[6]))
1534.4.41 by Robert Collins
Branch now uses BzrDir reasonably sanely.
63
    self.assertTrue(br_a.repository.has_revision(br_b.revision_history()[5]))
1393 by Robert Collins
reenable remotebranch tests
64
1092.2.28 by Robert Collins
reenable test of fetching a branch with ghosts
65
    # When a non-branch ancestor is missing, it should be unlisted...
1415 by Robert Collins
remove the ancestry weave file
66
    # as its not reference from the inventory weave.
1534.4.50 by Robert Collins
Got the bzrdir api straightened out, plenty of refactoring to use it pending, but the api is up and running.
67
    br_b4 = self.make_branch('br_4')
1534.1.31 by Robert Collins
Deprecated fetch.fetch and fetch.greedy_fetch for branch.fetch, and move the Repository.fetch internals to InterRepo and InterWeaveRepo.
68
    count, failures = br_b4.fetch(br_b)
1092.2.28 by Robert Collins
reenable test of fetching a branch with ghosts
69
    self.assertEqual(count, 7)
70
    self.assertEqual(failures, [])
1393 by Robert Collins
reenable remotebranch tests
71
1534.1.31 by Robert Collins
Deprecated fetch.fetch and fetch.greedy_fetch for branch.fetch, and move the Repository.fetch internals to InterRepo and InterWeaveRepo.
72
    self.assertEqual(writable_a.fetch(br_b)[0], 1)
1534.4.41 by Robert Collins
Branch now uses BzrDir reasonably sanely.
73
    self.assertTrue(has_revision(br_a, br_b.revision_history()[3]))
74
    self.assertTrue(has_revision(br_a, br_b.revision_history()[4]))
1393 by Robert Collins
reenable remotebranch tests
75
        
1534.4.50 by Robert Collins
Got the bzrdir api straightened out, plenty of refactoring to use it pending, but the api is up and running.
76
    br_b2 = self.make_branch('br_b2')
1534.1.31 by Robert Collins
Deprecated fetch.fetch and fetch.greedy_fetch for branch.fetch, and move the Repository.fetch internals to InterRepo and InterWeaveRepo.
77
    self.assertEquals(br_b2.fetch(br_b)[0], 7)
1534.4.41 by Robert Collins
Branch now uses BzrDir reasonably sanely.
78
    self.assertTrue(has_revision(br_b2, br_b.revision_history()[4]))
79
    self.assertTrue(has_revision(br_b2, br_a.revision_history()[2]))
1185.16.145 by Martin Pool
Remove all assert statements from test cases.
80
    self.assertFalse(has_revision(br_b2, br_a.revision_history()[3]))
1393 by Robert Collins
reenable remotebranch tests
81
1534.4.50 by Robert Collins
Got the bzrdir api straightened out, plenty of refactoring to use it pending, but the api is up and running.
82
    br_a2 = self.make_branch('br_a2')
1534.1.31 by Robert Collins
Deprecated fetch.fetch and fetch.greedy_fetch for branch.fetch, and move the Repository.fetch internals to InterRepo and InterWeaveRepo.
83
    self.assertEquals(br_a2.fetch(br_a)[0], 9)
1534.4.41 by Robert Collins
Branch now uses BzrDir reasonably sanely.
84
    self.assertTrue(has_revision(br_a2, br_b.revision_history()[4]))
85
    self.assertTrue(has_revision(br_a2, br_a.revision_history()[3]))
86
    self.assertTrue(has_revision(br_a2, br_a.revision_history()[2]))
1393 by Robert Collins
reenable remotebranch tests
87
1534.4.50 by Robert Collins
Got the bzrdir api straightened out, plenty of refactoring to use it pending, but the api is up and running.
88
    br_a3 = self.make_branch('br_a3')
1534.4.41 by Robert Collins
Branch now uses BzrDir reasonably sanely.
89
    # pulling a branch with no revisions grabs nothing, regardless of 
90
    # whats in the inventory.
1534.1.31 by Robert Collins
Deprecated fetch.fetch and fetch.greedy_fetch for branch.fetch, and move the Repository.fetch internals to InterRepo and InterWeaveRepo.
91
    self.assertEquals(br_a3.fetch(br_a2)[0], 0)
1393 by Robert Collins
reenable remotebranch tests
92
    for revno in range(4):
1534.4.41 by Robert Collins
Branch now uses BzrDir reasonably sanely.
93
        self.assertFalse(
94
            br_a3.repository.has_revision(br_a.revision_history()[revno]))
1534.1.31 by Robert Collins
Deprecated fetch.fetch and fetch.greedy_fetch for branch.fetch, and move the Repository.fetch internals to InterRepo and InterWeaveRepo.
95
    self.assertEqual(br_a3.fetch(br_a2, br_a.revision_history()[2])[0], 3)
1534.4.41 by Robert Collins
Branch now uses BzrDir reasonably sanely.
96
    # pull the 3 revisions introduced by a@u-0-3
1534.1.31 by Robert Collins
Deprecated fetch.fetch and fetch.greedy_fetch for branch.fetch, and move the Repository.fetch internals to InterRepo and InterWeaveRepo.
97
    fetched = br_a3.fetch(br_a2, br_a.revision_history()[3])[0]
1534.4.41 by Robert Collins
Branch now uses BzrDir reasonably sanely.
98
    self.assertEquals(fetched, 3, "fetched %d instead of 3" % fetched)
1393 by Robert Collins
reenable remotebranch tests
99
    # InstallFailed should be raised if the branch is missing the revision
100
    # that was requested.
2697.2.2 by Martin Pool
deprecate Branch.append_revision
101
    self.assertRaises(errors.InstallFailed, br_a3.fetch, br_a2, 'pizza')
102
2697.2.5 by Martin Pool
Kill off append_revision
103
    # TODO: Test trying to fetch from a branch that points to a revision not
104
    # actually present in its repository.  Not every branch format allows you
105
    # to directly point to such revisions, so it's a bit complicated to
106
    # construct.  One way would be to uncommit and gc the revision, but not
107
    # every branch supports that.  -- mbp 20070814
1638.1.2 by Robert Collins
Change the basis-inventory file to not have the revision-id in the file name.
108
1185.13.4 by Robert Collins
make reweave visible as a weave method, and quickly integrate into fetch
109
    #TODO: test that fetch correctly does reweaving when needed. RBC 20051008
1534.4.41 by Robert Collins
Branch now uses BzrDir reasonably sanely.
110
    # Note that this means - updating the weave when ghosts are filled in to 
111
    # add the right parents.
112
1185.13.4 by Robert Collins
make reweave visible as a weave method, and quickly integrate into fetch
113
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
114
class TestFetch(TestCaseWithTransport):
1392 by Robert Collins
reinstate testfetch test case
115
116
    def test_fetch(self):
1115 by Martin Pool
- split fetch tests into a separate file
117
        #highest indices a: 5, b: 7
2696.3.3 by Martin Pool
Start setting the default format to dirstate-tags
118
        br_a, br_b = make_branches(self, format='dirstate-tags')
1393 by Robert Collins
reenable remotebranch tests
119
        fetch_steps(self, br_a, br_b, br_a)
1404 by Robert Collins
only pull remote text weaves once per fetch operation
120
1558.4.11 by Aaron Bentley
Allow merge against self, make fetching self a noop
121
    def test_fetch_self(self):
122
        wt = self.make_branch_and_tree('br')
123
        self.assertEqual(wt.branch.fetch(wt.branch), (0, []))
124
1551.8.42 by Aaron Bentley
Ensure that fetch properly updates inventory root knit
125
    def test_fetch_root_knit(self):
1551.8.43 by Aaron Bentley
Update from reviews
126
        """Ensure that knit2.fetch() updates the root knit
1551.8.42 by Aaron Bentley
Ensure that fetch properly updates inventory root knit
127
        
1551.8.43 by Aaron Bentley
Update from reviews
128
        This tests the case where the root has a new revision, but there are no
129
        corresponding filename, parent, contents or other changes.
1551.8.42 by Aaron Bentley
Ensure that fetch properly updates inventory root knit
130
        """
1551.8.43 by Aaron Bentley
Update from reviews
131
        knit1_format = bzrdir.BzrDirMetaFormat1()
2241.1.6 by Martin Pool
Move Knit repositories into the submodule bzrlib.repofmt.knitrepo and
132
        knit1_format.repository_format = knitrepo.RepositoryFormatKnit1()
1551.8.43 by Aaron Bentley
Update from reviews
133
        knit2_format = bzrdir.BzrDirMetaFormat1()
2255.2.211 by Robert Collins
Remove knit2 repository format- it has never been supported.
134
        knit2_format.repository_format = knitrepo.RepositoryFormatKnit3()
1551.8.43 by Aaron Bentley
Update from reviews
135
        # we start with a knit1 repository because that causes the
136
        # root revision to change for each commit, even though the content,
137
        # parent, name, and other attributes are unchanged.
138
        tree = self.make_branch_and_tree('tree', knit1_format)
1551.8.42 by Aaron Bentley
Ensure that fetch properly updates inventory root knit
139
        tree.set_root_id('tree-root')
140
        tree.commit('rev1', rev_id='rev1')
141
        tree.commit('rev2', rev_id='rev2')
1551.8.43 by Aaron Bentley
Update from reviews
142
143
        # Now we convert it to a knit2 repository so that it has a root knit
144
        Convert(tree.basedir, knit2_format)
1551.8.42 by Aaron Bentley
Ensure that fetch properly updates inventory root knit
145
        tree = WorkingTree.open(tree.basedir)
1551.8.43 by Aaron Bentley
Update from reviews
146
        branch = self.make_branch('branch', format=knit2_format)
1551.8.42 by Aaron Bentley
Ensure that fetch properly updates inventory root knit
147
        branch.pull(tree.branch, stop_revision='rev1')
148
        repo = branch.repository
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
149
        repo.lock_read()
150
        try:
151
            # Make sure fetch retrieved only what we requested
152
            self.assertEqual({('tree-root', 'rev1'):()},
153
                repo.texts.get_parent_map(
154
                    [('tree-root', 'rev1'), ('tree-root', 'rev2')]))
155
        finally:
156
            repo.unlock()
1551.8.42 by Aaron Bentley
Ensure that fetch properly updates inventory root knit
157
        branch.pull(tree.branch)
1551.8.43 by Aaron Bentley
Update from reviews
158
        # Make sure that the next revision in the root knit was retrieved,
159
        # even though the text, name, parent_id, etc., were unchanged.
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
160
        repo.lock_read()
161
        try:
162
            # Make sure fetch retrieved only what we requested
163
            self.assertEqual({('tree-root', 'rev2'):(('tree-root', 'rev1'),)},
164
                repo.texts.get_parent_map([('tree-root', 'rev2')]))
165
        finally:
166
            repo.unlock()
1551.8.42 by Aaron Bentley
Ensure that fetch properly updates inventory root knit
167
2323.8.2 by Aaron Bentley
Give a nicer error on fetch when repos are in incompatible formats
168
    def test_fetch_incompatible(self):
169
        knit_tree = self.make_branch_and_tree('knit', format='knit')
170
        knit3_tree = self.make_branch_and_tree('knit3',
171
            format='dirstate-with-subtree')
172
        knit3_tree.commit('blah')
3582.1.2 by Martin Pool
Default InterRepository.fetch raises IncompatibleRepositories
173
        e = self.assertRaises(errors.IncompatibleRepositories,
174
                              knit_tree.branch.fetch, knit3_tree.branch)
175
        self.assertContainsRe(str(e),
176
            r"(?m).*/knit.*\nis not compatible with\n.*/knit3/.*\n"
177
            r"different rich-root support")
2323.8.2 by Aaron Bentley
Give a nicer error on fetch when repos are in incompatible formats
178
1185.16.96 by mbp at sourcefrog
More merge/fetch tests
179
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
180
class TestMergeFetch(TestCaseWithTransport):
1185.16.96 by mbp at sourcefrog
More merge/fetch tests
181
182
    def test_merge_fetches_unrelated(self):
183
        """Merge brings across history from unrelated source"""
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
184
        wt1 = self.make_branch_and_tree('br1')
185
        br1 = wt1.branch
186
        wt1.commit(message='rev 1-1', rev_id='1-1')
187
        wt1.commit(message='rev 1-2', rev_id='1-2')
188
        wt2 = self.make_branch_and_tree('br2')
189
        br2 = wt2.branch
190
        wt2.commit(message='rev 2-1', rev_id='2-1')
1551.15.70 by Aaron Bentley
Avoid using builtins.merge
191
        wt2.merge_from_branch(br1, from_revision='null:')
1185.16.96 by mbp at sourcefrog
More merge/fetch tests
192
        self._check_revs_present(br2)
193
1185.16.94 by mbp at sourcefrog
New test that merge fetches revisions from source
194
    def test_merge_fetches(self):
195
        """Merge brings across history from source"""
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
196
        wt1 = self.make_branch_and_tree('br1')
197
        br1 = wt1.branch
198
        wt1.commit(message='rev 1-1', rev_id='1-1')
1534.4.50 by Robert Collins
Got the bzrdir api straightened out, plenty of refactoring to use it pending, but the api is up and running.
199
        dir_2 = br1.bzrdir.sprout('br2')
200
        br2 = dir_2.open_branch()
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
201
        wt1.commit(message='rev 1-2', rev_id='1-2')
1551.15.70 by Aaron Bentley
Avoid using builtins.merge
202
        wt2 = dir_2.open_workingtree()
203
        wt2.commit(message='rev 2-1', rev_id='2-1')
204
        wt2.merge_from_branch(br1)
1185.16.96 by mbp at sourcefrog
More merge/fetch tests
205
        self._check_revs_present(br2)
206
207
    def _check_revs_present(self, br2):
1185.16.94 by mbp at sourcefrog
New test that merge fetches revisions from source
208
        for rev_id in '1-1', '1-2', '2-1':
1185.67.2 by Aaron Bentley
Renamed Branch.storage to Branch.repository
209
            self.assertTrue(br2.repository.has_revision(rev_id))
210
            rev = br2.repository.get_revision(rev_id)
1185.16.94 by mbp at sourcefrog
New test that merge fetches revisions from source
211
            self.assertEqual(rev.revision_id, rev_id)
1185.67.2 by Aaron Bentley
Renamed Branch.storage to Branch.repository
212
            self.assertTrue(br2.repository.get_inventory(rev_id))
1185.16.94 by mbp at sourcefrog
New test that merge fetches revisions from source
213
1185.16.96 by mbp at sourcefrog
More merge/fetch tests
214
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
215
class TestMergeFileHistory(TestCaseWithTransport):
216
1185.16.96 by mbp at sourcefrog
More merge/fetch tests
217
    def setUp(self):
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
218
        super(TestMergeFileHistory, self).setUp()
219
        wt1 = self.make_branch_and_tree('br1')
220
        br1 = wt1.branch
1185.16.96 by mbp at sourcefrog
More merge/fetch tests
221
        self.build_tree_contents([('br1/file', 'original contents\n')])
1534.4.28 by Robert Collins
first cut at merge from integration.
222
        wt1.add('file', 'this-file-id')
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
223
        wt1.commit(message='rev 1-1', rev_id='1-1')
1534.4.50 by Robert Collins
Got the bzrdir api straightened out, plenty of refactoring to use it pending, but the api is up and running.
224
        dir_2 = br1.bzrdir.sprout('br2')
225
        br2 = dir_2.open_branch()
226
        wt2 = dir_2.open_workingtree()
1185.16.96 by mbp at sourcefrog
More merge/fetch tests
227
        self.build_tree_contents([('br1/file', 'original from 1\n')])
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
228
        wt1.commit(message='rev 1-2', rev_id='1-2')
1185.16.96 by mbp at sourcefrog
More merge/fetch tests
229
        self.build_tree_contents([('br1/file', 'agreement\n')])
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
230
        wt1.commit(message='rev 1-3', rev_id='1-3')
1185.16.96 by mbp at sourcefrog
More merge/fetch tests
231
        self.build_tree_contents([('br2/file', 'contents in 2\n')])
1534.4.28 by Robert Collins
first cut at merge from integration.
232
        wt2.commit(message='rev 2-1', rev_id='2-1')
1185.16.96 by mbp at sourcefrog
More merge/fetch tests
233
        self.build_tree_contents([('br2/file', 'agreement\n')])
1534.4.28 by Robert Collins
first cut at merge from integration.
234
        wt2.commit(message='rev 2-2', rev_id='2-2')
1185.16.96 by mbp at sourcefrog
More merge/fetch tests
235
236
    def test_merge_fetches_file_history(self):
237
        """Merge brings across file histories"""
238
        br2 = Branch.open('br2')
1551.15.70 by Aaron Bentley
Avoid using builtins.merge
239
        br1 = Branch.open('br1')
240
        wt2 = WorkingTree.open('br2').merge_from_branch(br1)
3010.1.4 by Robert Collins
Make the knit specific fetch tests knit specific, and lock the branch when looking at historical texts in test_fetch.
241
        br2.lock_read()
242
        self.addCleanup(br2.unlock)
1185.16.96 by mbp at sourcefrog
More merge/fetch tests
243
        for rev_id, text in [('1-2', 'original from 1\n'),
244
                             ('1-3', 'agreement\n'),
245
                             ('2-1', 'contents in 2\n'),
246
                             ('2-2', 'agreement\n')]:
1185.65.1 by Aaron Bentley
Refactored out ControlFiles and RevisionStore from _Branch
247
            self.assertEqualDiff(
1185.67.2 by Aaron Bentley
Renamed Branch.storage to Branch.repository
248
                br2.repository.revision_tree(
1185.65.1 by Aaron Bentley
Refactored out ControlFiles and RevisionStore from _Branch
249
                    rev_id).get_file_text('this-file-id'), text)
1185.16.96 by mbp at sourcefrog
More merge/fetch tests
250
251
1404 by Robert Collins
only pull remote text weaves once per fetch operation
252
class TestHttpFetch(TestCaseWithWebserver):
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
253
    # FIXME RBC 20060124 this really isn't web specific, perhaps an
254
    # instrumented readonly transport? Can we do an instrumented
255
    # adapter and use self.get_readonly_url ?
1404 by Robert Collins
only pull remote text weaves once per fetch operation
256
257
    def test_fetch(self):
258
        #highest indices a: 5, b: 7
1185.16.145 by Martin Pool
Remove all assert statements from test cases.
259
        br_a, br_b = make_branches(self)
1534.4.50 by Robert Collins
Got the bzrdir api straightened out, plenty of refactoring to use it pending, but the api is up and running.
260
        br_rem_a = Branch.open(self.get_readonly_url('branch1'))
1404 by Robert Collins
only pull remote text weaves once per fetch operation
261
        fetch_steps(self, br_rem_a, br_b, br_a)
262
1540.3.15 by Martin Pool
[merge] large merge to sync with bzr.dev
263
    def _count_log_matches(self, target, logs):
264
        """Count the number of times the target file pattern was fetched in an http log"""
2004.1.22 by v.ladeuil+lp at free
Implements Range header handling for GET requests. Fix a test.
265
        get_succeeds_re = re.compile(
266
            '.*"GET .*%s HTTP/1.1" 20[06] - "-" "bzr/%s' %
267
            (     target,                    bzrlib.__version__))
1540.3.15 by Martin Pool
[merge] large merge to sync with bzr.dev
268
        c = 0
269
        for line in logs:
2004.1.22 by v.ladeuil+lp at free
Implements Range header handling for GET requests. Fix a test.
270
            if get_succeeds_re.match(line):
1540.3.15 by Martin Pool
[merge] large merge to sync with bzr.dev
271
                c += 1
272
        return c
273
1404 by Robert Collins
only pull remote text weaves once per fetch operation
274
    def test_weaves_are_retrieved_once(self):
275
        self.build_tree(("source/", "source/file", "target/"))
3010.1.4 by Robert Collins
Make the knit specific fetch tests knit specific, and lock the branch when looking at historical texts in test_fetch.
276
        # This test depends on knit dasta storage.
277
        wt = self.make_branch_and_tree('source', format='dirstate-tags')
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
278
        branch = wt.branch
279
        wt.add(["file"], ["id"])
280
        wt.commit("added file")
2911.6.1 by Blake Winton
Change 'print >> f,'s to 'f.write('s.
281
        open("source/file", 'w').write("blah\n")
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
282
        wt.commit("changed file")
1534.4.41 by Robert Collins
Branch now uses BzrDir reasonably sanely.
283
        target = BzrDir.create_branch_and_repo("target/")
1534.4.50 by Robert Collins
Got the bzrdir api straightened out, plenty of refactoring to use it pending, but the api is up and running.
284
        source = Branch.open(self.get_readonly_url("source/"))
1534.1.31 by Robert Collins
Deprecated fetch.fetch and fetch.greedy_fetch for branch.fetch, and move the Repository.fetch internals to InterRepo and InterWeaveRepo.
285
        self.assertEqual(target.fetch(source), (2, []))
1430 by Robert Collins
touchup the prefixed-store patch
286
        # this is the path to the literal file. As format changes 
287
        # occur it needs to be updated. FIXME: ask the store for the
288
        # path.
1540.3.15 by Martin Pool
[merge] large merge to sync with bzr.dev
289
        self.log("web server logs are:")
290
        http_logs = self.get_readonly_server().logs
291
        self.log('\n'.join(http_logs))
1666.1.6 by Robert Collins
Make knit the default format.
292
        # unfortunately this log entry is branch format specific. We could 
293
        # factor out the 'what files does this format use' to a method on the 
294
        # repository, which would let us to this generically. RBC 20060419
3422.1.1 by John Arbash Meinel
merge in bzr-1.5rc1, revert the transaction cache change
295
        # RBC 20080408: Or perhaps we can assert that no files are fully read
296
        # twice?
1666.1.6 by Robert Collins
Make knit the default format.
297
        self.assertEqual(1, self._count_log_matches('/ce/id.kndx', http_logs))
298
        self.assertEqual(1, self._count_log_matches('/ce/id.knit', http_logs))
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
299
        self.assertEqual(1, self._count_log_matches('inventory.kndx', http_logs))
1417.1.12 by Robert Collins
cache revision history during read transactions
300
        # this r-h check test will prevent regressions, but it currently already 
301
        # passes, before the patch to cache-rh is applied :[
2230.3.10 by Aaron Bentley
Genericised test_fetch to handle branch 6 retrieval patterns
302
        self.assertTrue(1 >= self._count_log_matches('revision-history',
303
                                                     http_logs))
304
        self.assertTrue(1 >= self._count_log_matches('last-revision',
305
                                                     http_logs))
1530.1.18 by Robert Collins
unbreak test_fetch
306
        # FIXME naughty poking in there.
1534.4.50 by Robert Collins
Got the bzrdir api straightened out, plenty of refactoring to use it pending, but the api is up and running.
307
        self.get_readonly_server().logs = []
3241.1.4 by Andrew Bennetts
Use get_smart_medium as suggested by Robert, and deal with the fallout.
308
        # check there is nothing more to fetch.  We take care to re-use the
309
        # existing transport so that the request logs we're about to examine
310
        # aren't cluttered with redundant probes for a smart server.
3241.1.5 by Andrew Bennetts
Add comment suggested by Robert.
311
        # XXX: Perhaps this further parameterisation: test http with smart
312
        # server, and test http without smart server?
3241.1.4 by Andrew Bennetts
Use get_smart_medium as suggested by Robert, and deal with the fallout.
313
        source = Branch.open(
314
            self.get_readonly_url("source/"),
315
            possible_transports=[source.bzrdir.root_transport])
1534.1.31 by Robert Collins
Deprecated fetch.fetch and fetch.greedy_fetch for branch.fetch, and move the Repository.fetch internals to InterRepo and InterWeaveRepo.
316
        self.assertEqual(target.fetch(source), (0, []))
1540.3.15 by Martin Pool
[merge] large merge to sync with bzr.dev
317
        # should make just two requests
318
        http_logs = self.get_readonly_server().logs
319
        self.log("web server logs are:")
320
        self.log('\n'.join(http_logs))
1666.1.4 by Robert Collins
* 'Metadir' is now the default disk format. This improves behaviour in
321
        self.assertEqual(1, self._count_log_matches('branch-format', http_logs))
322
        self.assertEqual(1, self._count_log_matches('branch/format', http_logs))
3422.1.1 by John Arbash Meinel
merge in bzr-1.5rc1, revert the transaction cache change
323
        self.assertEqual(1, self._count_log_matches('repository/format',
324
            http_logs))
2230.3.11 by Aaron Bentley
Fix line endings
325
        self.assertTrue(1 >= self._count_log_matches('revision-history',
326
                                                     http_logs))
327
        self.assertTrue(1 >= self._count_log_matches('last-revision',
328
                                                     http_logs))
1666.1.4 by Robert Collins
* 'Metadir' is now the default disk format. This improves behaviour in
329
        self.assertEqual(4, len(http_logs))
3380.1.1 by Aaron Bentley
Fix inventory insertion to work in topological order
330
331
332
class Test1To2Fetch(TestCaseWithTransport):
3380.1.3 by Aaron Bentley
Fix model-change fetching with ghosts and when fetch is resumed
333
    """Tests for Model1To2 failure modes"""
3380.1.1 by Aaron Bentley
Fix inventory insertion to work in topological order
334
3380.2.4 by Aaron Bentley
Updates from review
335
    def make_tree_and_repo(self):
336
        self.tree = self.make_branch_and_tree('tree', format='pack-0.92')
337
        self.repo = self.make_repository('rich-repo', format='rich-root-pack')
338
        self.repo.lock_write()
339
        self.addCleanup(self.repo.unlock)
340
341
    def do_fetch_order_test(self, first, second):
3380.1.3 by Aaron Bentley
Fix model-change fetching with ghosts and when fetch is resumed
342
        """Test that fetch works no matter what the set order of revision is.
3380.1.1 by Aaron Bentley
Fix inventory insertion to work in topological order
343
344
        This test depends on the order of items in a set, which is
345
        implementation-dependant, so we test A, B and then B, A.
346
        """
3380.1.3 by Aaron Bentley
Fix model-change fetching with ghosts and when fetch is resumed
347
        self.make_tree_and_repo()
348
        self.tree.commit('Commit 1', rev_id=first)
349
        self.tree.commit('Commit 2', rev_id=second)
350
        self.repo.fetch(self.tree.branch.repository, second)
351
3380.2.4 by Aaron Bentley
Updates from review
352
    def test_fetch_order_AB(self):
3380.2.7 by Aaron Bentley
Update docs
353
        """See do_fetch_order_test"""
3380.2.4 by Aaron Bentley
Updates from review
354
        self.do_fetch_order_test('A', 'B')
355
356
    def test_fetch_order_BA(self):
3380.2.7 by Aaron Bentley
Update docs
357
        """See do_fetch_order_test"""
3380.2.4 by Aaron Bentley
Updates from review
358
        self.do_fetch_order_test('B', 'A')
359
3380.1.3 by Aaron Bentley
Fix model-change fetching with ghosts and when fetch is resumed
360
    def get_parents(self, file_id, revision_id):
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
361
        self.repo.lock_read()
362
        try:
363
            parent_map = self.repo.texts.get_parent_map([(file_id, revision_id)])
364
            return parent_map[(file_id, revision_id)]
365
        finally:
366
            self.repo.unlock()
3380.1.3 by Aaron Bentley
Fix model-change fetching with ghosts and when fetch is resumed
367
3380.1.2 by Aaron Bentley
Improve handling ghosts and changing root_ids
368
    def test_fetch_ghosts(self):
3380.1.3 by Aaron Bentley
Fix model-change fetching with ghosts and when fetch is resumed
369
        self.make_tree_and_repo()
370
        self.tree.commit('first commit', rev_id='left-parent')
371
        self.tree.add_parent_tree_id('ghost-parent')
372
        fork = self.tree.bzrdir.sprout('fork', 'null:').open_workingtree()
3380.1.2 by Aaron Bentley
Improve handling ghosts and changing root_ids
373
        fork.commit('not a ghost', rev_id='not-ghost-parent')
3380.1.3 by Aaron Bentley
Fix model-change fetching with ghosts and when fetch is resumed
374
        self.tree.branch.repository.fetch(fork.branch.repository,
3380.1.2 by Aaron Bentley
Improve handling ghosts and changing root_ids
375
                                     'not-ghost-parent')
3380.1.3 by Aaron Bentley
Fix model-change fetching with ghosts and when fetch is resumed
376
        self.tree.add_parent_tree_id('not-ghost-parent')
377
        self.tree.commit('second commit', rev_id='second-id')
378
        self.repo.fetch(self.tree.branch.repository, 'second-id')
379
        root_id = self.tree.get_root_id()
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
380
        self.assertEqual(
381
            ((root_id, 'left-parent'), (root_id, 'ghost-parent'),
382
             (root_id, 'not-ghost-parent')),
383
            self.get_parents(root_id, 'second-id'))
3380.1.3 by Aaron Bentley
Fix model-change fetching with ghosts and when fetch is resumed
384
385
    def make_two_commits(self, change_root, fetch_twice):
386
        self.make_tree_and_repo()
387
        self.tree.commit('first commit', rev_id='first-id')
388
        if change_root:
389
            self.tree.set_root_id('unique-id')
390
        self.tree.commit('second commit', rev_id='second-id')
391
        if fetch_twice:
392
            self.repo.fetch(self.tree.branch.repository, 'first-id')
393
        self.repo.fetch(self.tree.branch.repository, 'second-id')
3380.1.2 by Aaron Bentley
Improve handling ghosts and changing root_ids
394
395
    def test_fetch_changed_root(self):
3380.1.3 by Aaron Bentley
Fix model-change fetching with ghosts and when fetch is resumed
396
        self.make_two_commits(change_root=True, fetch_twice=False)
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
397
        self.assertEqual((), self.get_parents('unique-id', 'second-id'))
3380.1.3 by Aaron Bentley
Fix model-change fetching with ghosts and when fetch is resumed
398
399
    def test_two_fetch_changed_root(self):
400
        self.make_two_commits(change_root=True, fetch_twice=True)
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
401
        self.assertEqual((), self.get_parents('unique-id', 'second-id'))
3380.1.3 by Aaron Bentley
Fix model-change fetching with ghosts and when fetch is resumed
402
403
    def test_two_fetches(self):
404
        self.make_two_commits(change_root=False, fetch_twice=True)
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
405
        self.assertEqual((('TREE_ROOT', 'first-id'),),
406
            self.get_parents('TREE_ROOT', 'second-id'))