/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
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
17
18
import sys
19
20
import bzrlib
21
from bzrlib import (
22
    errors,
4098.4.1 by Robert Collins
Handle inconsistent inventory data more gracefully at a small performance cost during fetch.
23
    inventory,
24
    osutils,
3380.1.4 by Aaron Bentley
Split interrepository fetch tests into their own file
25
    repository,
4098.4.1 by Robert Collins
Handle inconsistent inventory data more gracefully at a small performance cost during fetch.
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
    )
31
from bzrlib.revision import (
32
    NULL_REVISION,
33
    Revision,
34
    )
35
from bzrlib.tests import (
36
    TestNotApplicable,
37
    )
38
from bzrlib.tests.interrepository_implementations import (
39
    TestCaseWithInterRepository,
40
    )
3616.2.3 by Mark Hammond
Fix test failures due to missing check_repo_format_for_funky_id_on_win32
41
from bzrlib.tests.interrepository_implementations.test_interrepository import (
42
    check_repo_format_for_funky_id_on_win32
43
    )
3380.1.4 by Aaron Bentley
Split interrepository fetch tests into their own file
44
45
46
class TestInterRepository(TestCaseWithInterRepository):
47
48
    def test_fetch(self):
49
        tree_a = self.make_branch_and_tree('a')
50
        self.build_tree(['a/foo'])
51
        tree_a.add('foo', 'file1')
52
        tree_a.commit('rev1', rev_id='rev1')
53
        def check_push_rev1(repo):
54
            # ensure the revision is missing.
55
            self.assertRaises(NoSuchRevision, repo.get_revision, 'rev1')
56
            # fetch with a limit of NULL_REVISION and an explicit progress bar.
57
            repo.fetch(tree_a.branch.repository,
58
                       revision_id=NULL_REVISION,
59
                       pb=bzrlib.progress.DummyProgress())
60
            # nothing should have been pushed
61
            self.assertFalse(repo.has_revision('rev1'))
62
            # fetch with a default limit (grab everything)
63
            repo.fetch(tree_a.branch.repository)
64
            # check that b now has all the data from a's first commit.
65
            rev = repo.get_revision('rev1')
66
            tree = repo.revision_tree('rev1')
67
            tree.lock_read()
68
            self.addCleanup(tree.unlock)
69
            tree.get_file_text('file1')
70
            for file_id in tree:
71
                if tree.inventory[file_id].kind == "file":
72
                    tree.get_file(file_id).read()
73
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
74
        # makes a target version repo
3380.1.4 by Aaron Bentley
Split interrepository fetch tests into their own file
75
        repo_b = self.make_to_repository('b')
76
        check_push_rev1(repo_b)
77
4098.4.1 by Robert Collins
Handle inconsistent inventory data more gracefully at a small performance cost during fetch.
78
    def test_fetch_inconsistent_last_changed_entries(self):
79
        """If an inventory has odd data we should still get what it references.
80
        
81
        This test tests that we do fetch a file text created in a revision not
82
        being fetched, but referenced from the revision we are fetching when the
83
        adjacent revisions to the one being fetched do not reference that text.
84
        """
85
        tree = self.make_branch_and_tree('source')
86
        revid = tree.commit('old')
87
        to_repo = self.make_to_repository('to_repo')
88
        to_repo.fetch(tree.branch.repository, revid)
89
        # Make a broken revision and fetch it.
90
        source = tree.branch.repository
91
        source.lock_write()
92
        self.addCleanup(source.unlock)
93
        source.start_write_group()
94
        try:
95
            # We need two revisions: OLD and NEW. NEW will claim to need a file
96
            # 'FOO' changed in 'OLD'. OLD will not have that file at all.
97
            source.texts.insert_record_stream([
98
                versionedfile.FulltextContentFactory(('foo', revid), (), None,
99
                'contents')])
100
            basis = source.revision_tree(revid)
101
            parent_id = basis.path2id('')
102
            entry = inventory.make_entry('file', 'foo-path', parent_id, 'foo')
103
            entry.revision = revid
104
            entry.text_size = len('contents')
105
            entry.text_sha1 = osutils.sha_string('contents')
106
            inv_sha1, _ = source.add_inventory_by_delta(revid, [
107
                (None, 'foo-path', 'foo', entry)], 'new', [revid])
108
            rev = Revision(timestamp=0,
109
                           timezone=None,
110
                           committer="Foo Bar <foo@example.com>",
111
                           message="Message",
112
                           inventory_sha1=inv_sha1,
113
                           revision_id='new',
114
                           parent_ids=[revid])
115
            source.add_revision(rev.revision_id, rev)
116
        except:
117
            source.abort_write_group()
118
            raise
119
        else:
120
            source.commit_write_group()
121
        to_repo.fetch(source, 'new')
122
        to_repo.lock_read()
123
        self.addCleanup(to_repo.unlock)
124
        self.assertEqual('contents',
125
            to_repo.texts.get_record_stream([('foo', revid)],
126
            'unordered', True).next().get_bytes_as('fulltext'))
127
3380.1.4 by Aaron Bentley
Split interrepository fetch tests into their own file
128
    def test_fetch_missing_basis_text(self):
129
        """If fetching a delta, we should die if a basis is not present."""
130
        tree = self.make_branch_and_tree('tree')
131
        self.build_tree(['tree/a'])
132
        tree.add(['a'], ['a-id'])
133
        tree.commit('one', rev_id='rev-one')
134
        self.build_tree_contents([('tree/a', 'new contents\n')])
135
        tree.commit('two', rev_id='rev-two')
136
137
        to_repo = self.make_to_repository('to_repo')
138
        # We build a broken revision so that we can test the fetch code dies
139
        # properly. So copy the inventory and revision, but not the text.
140
        to_repo.lock_write()
141
        try:
142
            to_repo.start_write_group()
143
            inv = tree.branch.repository.get_inventory('rev-one')
144
            to_repo.add_inventory('rev-one', inv, [])
145
            rev = tree.branch.repository.get_revision('rev-one')
146
            to_repo.add_revision('rev-one', rev, inv=inv)
147
            to_repo.commit_write_group()
148
        finally:
149
            to_repo.unlock()
150
3350.3.21 by Robert Collins
Merge bzr.dev.
151
        # Implementations can either ensure that the target of the delta is
152
        # reconstructable, or raise an exception (which stream based copies
153
        # generally do).
3380.1.4 by Aaron Bentley
Split interrepository fetch tests into their own file
154
        try:
155
            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
156
        except (errors.BzrCheckError, errors.RevisionNotPresent), e:
157
            # If an exception is raised, the revision should not be in the
158
            # target.
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
159
            #
3830.3.9 by Martin Pool
Simplify kvf insert_record_stream; add has_key shorthand methods; update stacking effort tests
160
            # Can also just raise a generic check errors; stream insertion
161
            # does this to include all the missing data
162
            self.assertRaises((errors.NoSuchRevision, errors.RevisionNotPresent),
163
                              to_repo.revision_tree, 'rev-two')
3380.1.4 by Aaron Bentley
Split interrepository fetch tests into their own file
164
        else:
3350.3.21 by Robert Collins
Merge bzr.dev.
165
            # If not exception is raised, then the text should be
3380.1.4 by Aaron Bentley
Split interrepository fetch tests into their own file
166
            # available.
167
            to_repo.lock_read()
168
            try:
3350.3.21 by Robert Collins
Merge bzr.dev.
169
                rt = to_repo.revision_tree('rev-two')
170
                self.assertEqual('new contents\n',
3380.1.4 by Aaron Bentley
Split interrepository fetch tests into their own file
171
                                 rt.get_file_text('a-id'))
172
            finally:
173
                to_repo.unlock()
174
175
    def test_fetch_missing_revision_same_location_fails(self):
176
        repo_a = self.make_repository('.')
177
        repo_b = repository.Repository.open('.')
178
        try:
3350.3.21 by Robert Collins
Merge bzr.dev.
179
            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
180
        except errors.LockError, e:
181
            check_old_format_lock_error(self.repository_format)
182
183
    def test_fetch_same_location_trivial_works(self):
184
        repo_a = self.make_repository('.')
185
        repo_b = repository.Repository.open('.')
186
        try:
187
            repo_a.fetch(repo_b)
188
        except errors.LockError, e:
189
            check_old_format_lock_error(self.repository_format)
190
191
    def test_fetch_missing_text_other_location_fails(self):
192
        source_tree = self.make_branch_and_tree('source')
193
        source = source_tree.branch.repository
194
        target = self.make_to_repository('target')
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
195
3380.1.4 by Aaron Bentley
Split interrepository fetch tests into their own file
196
        # start by adding a file so the data knit for the file exists in
197
        # repositories that have specific files for each fileid.
198
        self.build_tree(['source/id'])
199
        source_tree.add(['id'], ['id'])
200
        source_tree.commit('a', rev_id='a')
201
        # now we manually insert a revision with an inventory referencing
202
        # 'id' at revision 'b', but we do not insert revision b.
203
        # this should ensure that the new versions of files are being checked
204
        # for during pull operations
205
        inv = source.get_inventory('a')
206
        source.lock_write()
3380.1.5 by Aaron Bentley
Merge with make-it-work
207
        self.addCleanup(source.unlock)
3380.1.4 by Aaron Bentley
Split interrepository fetch tests into their own file
208
        source.start_write_group()
209
        inv['id'].revision = 'b'
210
        inv.revision_id = 'b'
211
        sha1 = source.add_inventory('b', inv, ['a'])
212
        rev = Revision(timestamp=0,
213
                       timezone=None,
214
                       committer="Foo Bar <foo@example.com>",
215
                       message="Message",
216
                       inventory_sha1=sha1,
217
                       revision_id='b')
218
        rev.parent_ids = ['a']
219
        source.add_revision('b', rev)
220
        source.commit_write_group()
221
        self.assertRaises(errors.RevisionNotPresent, target.fetch, source)
222
        self.assertFalse(target.has_revision('b'))
223
224
    def test_fetch_funky_file_id(self):
225
        from_tree = self.make_branch_and_tree('tree')
226
        if sys.platform == 'win32':
227
            from_repo = from_tree.branch.repository
228
            check_repo_format_for_funky_id_on_win32(from_repo)
229
        self.build_tree(['tree/filename'])
230
        from_tree.add('filename', 'funky-chars<>%&;"\'')
231
        from_tree.commit('commit filename')
232
        to_repo = self.make_to_repository('to')
3350.3.21 by Robert Collins
Merge bzr.dev.
233
        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
234
3380.1.6 by Aaron Bentley
Ensure fetching munges sha1s
235
    def test_fetch_revision_hash(self):
236
        """Ensure that inventory hashes are updated by fetch"""
237
        from_tree = self.make_branch_and_tree('tree')
238
        from_tree.commit('foo', rev_id='foo-id')
239
        to_repo = self.make_to_repository('to')
240
        to_repo.fetch(from_tree.branch.repository)
241
        recorded_inv_sha1 = to_repo.get_inventory_sha1('foo-id')
242
        xml = to_repo.get_inventory_xml('foo-id')
243
        computed_inv_sha1 = osutils.sha_string(xml)
244
        self.assertEqual(computed_inv_sha1, recorded_inv_sha1)
245
3380.1.4 by Aaron Bentley
Split interrepository fetch tests into their own file
246
247
class TestFetchDependentData(TestCaseWithInterRepository):
248
249
    def test_reference(self):
250
        from_tree = self.make_branch_and_tree('tree')
251
        to_repo = self.make_to_repository('to')
252
        if (not from_tree.supports_tree_reference() or
253
            not from_tree.branch.repository._format.supports_tree_reference or
254
            not to_repo._format.supports_tree_reference):
255
            raise TestNotApplicable("Need subtree support.")
256
        subtree = self.make_branch_and_tree('tree/subtree')
257
        subtree.commit('subrev 1')
258
        from_tree.add_reference(subtree)
259
        tree_rev = from_tree.commit('foo')
260
        # now from_tree has a last-modified of subtree of the rev id of the
261
        # commit for foo, and a reference revision of the rev id of the commit
262
        # for subrev 1
263
        to_repo.fetch(from_tree.branch.repository, tree_rev)
264
        # to_repo should have a file_graph for from_tree.path2id('subtree') and
265
        # 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.
266
        file_id = from_tree.path2id('subtree')
3380.1.4 by Aaron Bentley
Split interrepository fetch tests into their own file
267
        to_repo.lock_read()
268
        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.
269
            self.assertEqual({(file_id, tree_rev):()},
270
                to_repo.texts.get_parent_map([(file_id, tree_rev)]))
3380.1.4 by Aaron Bentley
Split interrepository fetch tests into their own file
271
        finally:
272
            to_repo.unlock()