/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
3380.1.4 by Aaron Bentley
Split interrepository fetch tests into their own file
1
# Copyright (C) 2005, 2006, 2008 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
4183.7.1 by Sabin Iacob
update FSF mailing address
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
3380.1.4 by Aaron Bentley
Split interrepository fetch tests into their own file
16
17
18
import sys
19
20
import bzrlib
21
from bzrlib import (
22
    errors,
3735.2.135 by Robert Collins
Permit fetching bzr.dev [deal with inconsistent inventories.]
23
    inventory,
24
    osutils,
3380.1.4 by Aaron Bentley
Split interrepository fetch tests into their own file
25
    repository,
3735.2.135 by Robert Collins
Permit fetching bzr.dev [deal with inconsistent inventories.]
26
    versionedfile,
3380.1.4 by Aaron Bentley
Split interrepository fetch tests into their own file
27
    )
28
from bzrlib.errors import (
29
    NoSuchRevision,
30
    )
4476.3.11 by Andrew Bennetts
All fetch and interrepo tests passing.
31
from bzrlib.graph import (
32
    SearchResult,
33
    )
3380.1.4 by Aaron Bentley
Split interrepository fetch tests into their own file
34
from bzrlib.revision import (
35
    NULL_REVISION,
36
    Revision,
37
    )
38
from bzrlib.tests import (
39
    TestNotApplicable,
40
    )
41
from bzrlib.tests.interrepository_implementations import (
42
    TestCaseWithInterRepository,
43
    )
3616.2.3 by Mark Hammond
Fix test failures due to missing check_repo_format_for_funky_id_on_win32
44
from bzrlib.tests.interrepository_implementations.test_interrepository import (
45
    check_repo_format_for_funky_id_on_win32
46
    )
3380.1.4 by Aaron Bentley
Split interrepository fetch tests into their own file
47
48
49
class TestInterRepository(TestCaseWithInterRepository):
50
51
    def test_fetch(self):
52
        tree_a = self.make_branch_and_tree('a')
53
        self.build_tree(['a/foo'])
54
        tree_a.add('foo', 'file1')
55
        tree_a.commit('rev1', rev_id='rev1')
56
        def check_push_rev1(repo):
57
            # ensure the revision is missing.
58
            self.assertRaises(NoSuchRevision, repo.get_revision, 'rev1')
4110.2.5 by Martin Pool
Deprecate passing pbs in to fetch()
59
            # fetch with a limit of NULL_REVISION
3380.1.4 by Aaron Bentley
Split interrepository fetch tests into their own file
60
            repo.fetch(tree_a.branch.repository,
4110.2.5 by Martin Pool
Deprecate passing pbs in to fetch()
61
                       revision_id=NULL_REVISION)
3380.1.4 by Aaron Bentley
Split interrepository fetch tests into their own file
62
            # nothing should have been pushed
63
            self.assertFalse(repo.has_revision('rev1'))
64
            # fetch with a default limit (grab everything)
65
            repo.fetch(tree_a.branch.repository)
66
            # check that b now has all the data from a's first commit.
67
            rev = repo.get_revision('rev1')
68
            tree = repo.revision_tree('rev1')
69
            tree.lock_read()
70
            self.addCleanup(tree.unlock)
71
            tree.get_file_text('file1')
72
            for file_id in tree:
73
                if tree.inventory[file_id].kind == "file":
74
                    tree.get_file(file_id).read()
75
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
76
        # makes a target version repo
3380.1.4 by Aaron Bentley
Split interrepository fetch tests into their own file
77
        repo_b = self.make_to_repository('b')
78
        check_push_rev1(repo_b)
79
3735.2.135 by Robert Collins
Permit fetching bzr.dev [deal with inconsistent inventories.]
80
    def test_fetch_inconsistent_last_changed_entries(self):
81
        """If an inventory has odd data we should still get what it references.
3735.31.2 by John Arbash Meinel
Cleanup trailing whitespace, get test_source to pass by removing asserts.
82
3735.2.135 by Robert Collins
Permit fetching bzr.dev [deal with inconsistent inventories.]
83
        This test tests that we do fetch a file text created in a revision not
84
        being fetched, but referenced from the revision we are fetching when the
85
        adjacent revisions to the one being fetched do not reference that text.
86
        """
87
        tree = self.make_branch_and_tree('source')
88
        revid = tree.commit('old')
89
        to_repo = self.make_to_repository('to_repo')
90
        to_repo.fetch(tree.branch.repository, revid)
91
        # Make a broken revision and fetch it.
92
        source = tree.branch.repository
93
        source.lock_write()
94
        self.addCleanup(source.unlock)
95
        source.start_write_group()
96
        try:
97
            # We need two revisions: OLD and NEW. NEW will claim to need a file
98
            # 'FOO' changed in 'OLD'. OLD will not have that file at all.
99
            source.texts.insert_record_stream([
100
                versionedfile.FulltextContentFactory(('foo', revid), (), None,
101
                'contents')])
102
            basis = source.revision_tree(revid)
103
            parent_id = basis.path2id('')
104
            entry = inventory.make_entry('file', 'foo-path', parent_id, 'foo')
105
            entry.revision = revid
106
            entry.text_size = len('contents')
107
            entry.text_sha1 = osutils.sha_string('contents')
108
            inv_sha1, _ = source.add_inventory_by_delta(revid, [
109
                (None, 'foo-path', 'foo', entry)], 'new', [revid])
110
            rev = Revision(timestamp=0,
111
                           timezone=None,
112
                           committer="Foo Bar <foo@example.com>",
113
                           message="Message",
114
                           inventory_sha1=inv_sha1,
115
                           revision_id='new',
116
                           parent_ids=[revid])
117
            source.add_revision(rev.revision_id, rev)
118
        except:
119
            source.abort_write_group()
120
            raise
121
        else:
122
            source.commit_write_group()
123
        to_repo.fetch(source, 'new')
124
        to_repo.lock_read()
125
        self.addCleanup(to_repo.unlock)
126
        self.assertEqual('contents',
127
            to_repo.texts.get_record_stream([('foo', revid)],
128
            'unordered', True).next().get_bytes_as('fulltext'))
129
4476.3.15 by Andrew Bennetts
Partially working fallback for pre-1.17 servers.
130
    def test_fetch_parent_inventories_at_stacking_boundary_smart(self):
131
        self.setup_smart_server_with_call_log()
132
        self.test_fetch_parent_inventories_at_stacking_boundary()
133
134
    def test_fetch_parent_inventories_at_stacking_boundary_smart_old(self):
135
        self.setup_smart_server_with_call_log()
4476.3.24 by Andrew Bennetts
Finish updating verb name from _1.17 to _1.18. Also, fix a typo in a comment.
136
        self.disable_verb('Repository.insert_stream_1.18')
4476.3.15 by Andrew Bennetts
Partially working fallback for pre-1.17 servers.
137
        self.test_fetch_parent_inventories_at_stacking_boundary()
138
4257.3.1 by Andrew Bennetts
Add failing test.
139
    def test_fetch_parent_inventories_at_stacking_boundary(self):
4257.3.9 by Andrew Bennetts
Add fix to InterDifferingSerializer too, although it's pretty ugly.
140
        """Fetch to a stacked branch copies inventories for parents of
141
        revisions at the stacking boundary.
142
143
        This is necessary so that the server is able to determine the file-ids
144
        altered by all revisions it contains, which means that it needs both
145
        the inventory for any revision it has, and the inventories of all that
146
        revision's parents.
147
        """
4257.3.1 by Andrew Bennetts
Add failing test.
148
        to_repo = self.make_to_repository('to')
149
        if not to_repo._format.supports_external_lookups:
150
            raise TestNotApplicable("Need stacking support in the target.")
151
        builder = self.make_branch_builder('branch')
152
        builder.start_series()
153
        builder.build_snapshot('base', None, [
154
            ('add', ('', 'root-id', 'directory', ''))])
155
        builder.build_snapshot('left', ['base'], [])
156
        builder.build_snapshot('right', ['base'], [])
157
        builder.build_snapshot('merge', ['left', 'right'], [])
158
        builder.finish_series()
159
        branch = builder.get_branch()
160
        repo = self.make_to_repository('trunk')
161
        trunk = repo.bzrdir.create_branch()
162
        trunk.repository.fetch(branch.repository, 'left')
163
        trunk.repository.fetch(branch.repository, 'right')
164
        repo = self.make_to_repository('stacked')
165
        stacked_branch = repo.bzrdir.create_branch()
166
        stacked_branch.set_stacked_on_url(trunk.base)
167
        stacked_branch.repository.fetch(branch.repository, 'merge')
168
        unstacked_repo = stacked_branch.bzrdir.open_repository()
169
        unstacked_repo.lock_read()
170
        self.addCleanup(unstacked_repo.unlock)
4476.3.16 by Andrew Bennetts
Only make inv deltas against bases we've already sent, and other tweaks.
171
        if not unstacked_repo._format.supports_chks:
172
            # these assertions aren't valid for groupcompress repos, which may
173
            # transfer data than strictly necessary to avoid breaking up an
174
            # already-compressed block of data.
175
            self.assertFalse(unstacked_repo.has_revision('left'))
176
            self.assertFalse(unstacked_repo.has_revision('right'))
4476.3.11 by Andrew Bennetts
All fetch and interrepo tests passing.
177
        self.assertTrue(unstacked_repo.has_revision('merge'))
178
        # We used to check for the presence of parent invs here, but what
179
        # really matters is that the repo can stream the new revision without
180
        # the help of any fallback repos.
181
        self.assertCanStreamRevision(unstacked_repo, 'merge')
182
183
    def assertCanStreamRevision(self, repo, revision_id):
184
        exclude_keys = set(repo.all_revision_ids()) - set([revision_id])
185
        search = SearchResult([revision_id], exclude_keys, 1, [revision_id])
186
        source = repo._get_source(repo._format)
187
        for substream_kind, substream in source.get_stream(search):
188
            # Consume the substream
189
            list(substream)
4257.3.1 by Andrew Bennetts
Add failing test.
190
3380.1.4 by Aaron Bentley
Split interrepository fetch tests into their own file
191
    def test_fetch_missing_basis_text(self):
192
        """If fetching a delta, we should die if a basis is not present."""
193
        tree = self.make_branch_and_tree('tree')
194
        self.build_tree(['tree/a'])
195
        tree.add(['a'], ['a-id'])
196
        tree.commit('one', rev_id='rev-one')
197
        self.build_tree_contents([('tree/a', 'new contents\n')])
198
        tree.commit('two', rev_id='rev-two')
199
200
        to_repo = self.make_to_repository('to_repo')
201
        # We build a broken revision so that we can test the fetch code dies
202
        # properly. So copy the inventory and revision, but not the text.
203
        to_repo.lock_write()
204
        try:
205
            to_repo.start_write_group()
206
            inv = tree.branch.repository.get_inventory('rev-one')
207
            to_repo.add_inventory('rev-one', inv, [])
208
            rev = tree.branch.repository.get_revision('rev-one')
209
            to_repo.add_revision('rev-one', rev, inv=inv)
210
            to_repo.commit_write_group()
211
        finally:
212
            to_repo.unlock()
213
3350.3.21 by Robert Collins
Merge bzr.dev.
214
        # Implementations can either ensure that the target of the delta is
215
        # reconstructable, or raise an exception (which stream based copies
216
        # generally do).
3380.1.4 by Aaron Bentley
Split interrepository fetch tests into their own file
217
        try:
218
            to_repo.fetch(tree.branch.repository, 'rev-two')
3830.3.12 by Martin Pool
Review cleanups: unify has_key impls, add missing_keys(), clean up exception blocks
219
        except (errors.BzrCheckError, errors.RevisionNotPresent), e:
220
            # If an exception is raised, the revision should not be in the
221
            # target.
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
222
            #
3830.3.9 by Martin Pool
Simplify kvf insert_record_stream; add has_key shorthand methods; update stacking effort tests
223
            # Can also just raise a generic check errors; stream insertion
224
            # does this to include all the missing data
225
            self.assertRaises((errors.NoSuchRevision, errors.RevisionNotPresent),
226
                              to_repo.revision_tree, 'rev-two')
3380.1.4 by Aaron Bentley
Split interrepository fetch tests into their own file
227
        else:
3350.3.21 by Robert Collins
Merge bzr.dev.
228
            # If not exception is raised, then the text should be
3380.1.4 by Aaron Bentley
Split interrepository fetch tests into their own file
229
            # available.
230
            to_repo.lock_read()
231
            try:
3350.3.21 by Robert Collins
Merge bzr.dev.
232
                rt = to_repo.revision_tree('rev-two')
233
                self.assertEqual('new contents\n',
3380.1.4 by Aaron Bentley
Split interrepository fetch tests into their own file
234
                                 rt.get_file_text('a-id'))
235
            finally:
236
                to_repo.unlock()
237
238
    def test_fetch_missing_revision_same_location_fails(self):
239
        repo_a = self.make_repository('.')
240
        repo_b = repository.Repository.open('.')
241
        try:
3350.3.21 by Robert Collins
Merge bzr.dev.
242
            self.assertRaises(errors.NoSuchRevision, repo_b.fetch, repo_a, revision_id='XXX')
3380.1.4 by Aaron Bentley
Split interrepository fetch tests into their own file
243
        except errors.LockError, e:
244
            check_old_format_lock_error(self.repository_format)
245
246
    def test_fetch_same_location_trivial_works(self):
247
        repo_a = self.make_repository('.')
248
        repo_b = repository.Repository.open('.')
249
        try:
250
            repo_a.fetch(repo_b)
251
        except errors.LockError, e:
252
            check_old_format_lock_error(self.repository_format)
253
254
    def test_fetch_missing_text_other_location_fails(self):
255
        source_tree = self.make_branch_and_tree('source')
256
        source = source_tree.branch.repository
257
        target = self.make_to_repository('target')
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
258
3380.1.4 by Aaron Bentley
Split interrepository fetch tests into their own file
259
        # start by adding a file so the data knit for the file exists in
260
        # repositories that have specific files for each fileid.
261
        self.build_tree(['source/id'])
262
        source_tree.add(['id'], ['id'])
263
        source_tree.commit('a', rev_id='a')
264
        # now we manually insert a revision with an inventory referencing
265
        # 'id' at revision 'b', but we do not insert revision b.
266
        # this should ensure that the new versions of files are being checked
267
        # for during pull operations
268
        inv = source.get_inventory('a')
269
        source.lock_write()
3380.1.5 by Aaron Bentley
Merge with make-it-work
270
        self.addCleanup(source.unlock)
3380.1.4 by Aaron Bentley
Split interrepository fetch tests into their own file
271
        source.start_write_group()
272
        inv['id'].revision = 'b'
273
        inv.revision_id = 'b'
274
        sha1 = source.add_inventory('b', inv, ['a'])
275
        rev = Revision(timestamp=0,
276
                       timezone=None,
277
                       committer="Foo Bar <foo@example.com>",
278
                       message="Message",
279
                       inventory_sha1=sha1,
280
                       revision_id='b')
281
        rev.parent_ids = ['a']
282
        source.add_revision('b', rev)
283
        source.commit_write_group()
284
        self.assertRaises(errors.RevisionNotPresent, target.fetch, source)
285
        self.assertFalse(target.has_revision('b'))
286
287
    def test_fetch_funky_file_id(self):
288
        from_tree = self.make_branch_and_tree('tree')
289
        if sys.platform == 'win32':
290
            from_repo = from_tree.branch.repository
291
            check_repo_format_for_funky_id_on_win32(from_repo)
292
        self.build_tree(['tree/filename'])
293
        from_tree.add('filename', 'funky-chars<>%&;"\'')
294
        from_tree.commit('commit filename')
295
        to_repo = self.make_to_repository('to')
3350.3.21 by Robert Collins
Merge bzr.dev.
296
        to_repo.fetch(from_tree.branch.repository, from_tree.get_parent_ids()[0])
3380.1.4 by Aaron Bentley
Split interrepository fetch tests into their own file
297
3380.1.6 by Aaron Bentley
Ensure fetching munges sha1s
298
    def test_fetch_revision_hash(self):
299
        """Ensure that inventory hashes are updated by fetch"""
300
        from_tree = self.make_branch_and_tree('tree')
301
        from_tree.commit('foo', rev_id='foo-id')
302
        to_repo = self.make_to_repository('to')
303
        to_repo.fetch(from_tree.branch.repository)
304
        recorded_inv_sha1 = to_repo.get_inventory_sha1('foo-id')
4476.3.4 by Andrew Bennetts
Network serialisation, and most tests passing with InterDifferingSerializer commented out.
305
        try:
306
            xml = to_repo.get_inventory_xml('foo-id')
307
        except NotImplementedError:
308
            raise TestNotApplicable('repo does not provide get_inventory_xml')
3380.1.6 by Aaron Bentley
Ensure fetching munges sha1s
309
        computed_inv_sha1 = osutils.sha_string(xml)
310
        self.assertEqual(computed_inv_sha1, recorded_inv_sha1)
311
3380.1.4 by Aaron Bentley
Split interrepository fetch tests into their own file
312
313
class TestFetchDependentData(TestCaseWithInterRepository):
314
315
    def test_reference(self):
316
        from_tree = self.make_branch_and_tree('tree')
317
        to_repo = self.make_to_repository('to')
318
        if (not from_tree.supports_tree_reference() or
319
            not from_tree.branch.repository._format.supports_tree_reference or
320
            not to_repo._format.supports_tree_reference):
321
            raise TestNotApplicable("Need subtree support.")
322
        subtree = self.make_branch_and_tree('tree/subtree')
323
        subtree.commit('subrev 1')
324
        from_tree.add_reference(subtree)
325
        tree_rev = from_tree.commit('foo')
326
        # now from_tree has a last-modified of subtree of the rev id of the
327
        # commit for foo, and a reference revision of the rev id of the commit
328
        # for subrev 1
329
        to_repo.fetch(from_tree.branch.repository, tree_rev)
330
        # to_repo should have a file_graph for from_tree.path2id('subtree') and
331
        # revid tree_rev.
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.
332
        file_id = from_tree.path2id('subtree')
3380.1.4 by Aaron Bentley
Split interrepository fetch tests into their own file
333
        to_repo.lock_read()
334
        try:
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.
335
            self.assertEqual({(file_id, tree_rev):()},
336
                to_repo.texts.get_parent_map([(file_id, tree_rev)]))
3380.1.4 by Aaron Bentley
Split interrepository fetch tests into their own file
337
        finally:
338
            to_repo.unlock()