/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/tests/per_interrepository/test_fetch.py

  • Committer: Robert Collins
  • Date: 2009-08-25 19:29:41 UTC
  • mfrom: (4648 +trunk)
  • mto: This revision was merged to the branch mainline in revision 4649.
  • Revision ID: robertc@robertcollins.net-20090825192941-x2kg9ikhsapjbs7b
Merge bzr.dev.

Show diffs side-by-side

added added

removed removed

Lines of Context:
17
17
 
18
18
import sys
19
19
 
20
 
import bzrlib
21
20
from bzrlib import (
22
21
    errors,
23
22
    inventory,
28
27
from bzrlib.errors import (
29
28
    NoSuchRevision,
30
29
    )
 
30
from bzrlib.graph import (
 
31
    SearchResult,
 
32
    )
31
33
from bzrlib.revision import (
32
34
    NULL_REVISION,
33
35
    Revision,
124
126
            to_repo.texts.get_record_stream([('foo', revid)],
125
127
            'unordered', True).next().get_bytes_as('fulltext'))
126
128
 
 
129
    def test_fetch_parent_inventories_at_stacking_boundary_smart(self):
 
130
        self.setup_smart_server_with_call_log()
 
131
        self.test_fetch_parent_inventories_at_stacking_boundary()
 
132
 
 
133
    def test_fetch_parent_inventories_at_stacking_boundary_smart_old(self):
 
134
        self.setup_smart_server_with_call_log()
 
135
        self.disable_verb('Repository.insert_stream_1.19')
 
136
        self.test_fetch_parent_inventories_at_stacking_boundary()
 
137
 
127
138
    def test_fetch_parent_inventories_at_stacking_boundary(self):
128
139
        """Fetch to a stacked branch copies inventories for parents of
129
140
        revisions at the stacking boundary.
132
143
        altered by all revisions it contains, which means that it needs both
133
144
        the inventory for any revision it has, and the inventories of all that
134
145
        revision's parents.
 
146
 
 
147
        However, we should also skip any revisions which are ghosts in the
 
148
        parents.
135
149
        """
136
 
        to_repo = self.make_to_repository('to')
137
 
        if not to_repo._format.supports_external_lookups:
 
150
        if not self.repository_format_to.supports_external_lookups:
138
151
            raise TestNotApplicable("Need stacking support in the target.")
139
152
        builder = self.make_branch_builder('branch')
140
153
        builder.start_series()
141
154
        builder.build_snapshot('base', None, [
142
 
            ('add', ('', 'root-id', 'directory', ''))])
143
 
        builder.build_snapshot('left', ['base'], [])
144
 
        builder.build_snapshot('right', ['base'], [])
145
 
        builder.build_snapshot('merge', ['left', 'right'], [])
 
155
            ('add', ('', 'root-id', 'directory', '')),
 
156
            ('add', ('file', 'file-id', 'file', 'content\n'))])
 
157
        builder.build_snapshot('left', ['base'], [
 
158
            ('modify', ('file-id', 'left content\n'))])
 
159
        builder.build_snapshot('right', ['base'], [
 
160
            ('modify', ('file-id', 'right content\n'))])
 
161
        builder.build_snapshot('merge', ['left', 'right'], [
 
162
            ('modify', ('file-id', 'left and right content\n'))])
146
163
        builder.finish_series()
147
164
        branch = builder.get_branch()
148
165
        repo = self.make_to_repository('trunk')
161
178
        self.assertEqual(
162
179
            set([('left',), ('right',), ('merge',)]),
163
180
            unstacked_repo.inventories.keys())
 
181
        # And the basis inventories have been copied correctly
 
182
        trunk.lock_read()
 
183
        self.addCleanup(trunk.unlock)
 
184
        left_tree, right_tree = trunk.repository.revision_trees(
 
185
            ['left', 'right'])
 
186
        stacked_branch.lock_read()
 
187
        self.addCleanup(stacked_branch.unlock)
 
188
        (stacked_left_tree,
 
189
         stacked_right_tree) = stacked_branch.repository.revision_trees(
 
190
            ['left', 'right'])
 
191
        self.assertEqual(left_tree.inventory, stacked_left_tree.inventory)
 
192
        self.assertEqual(right_tree.inventory, stacked_right_tree.inventory)
 
193
 
 
194
        # Finally, it's not enough to see that the basis inventories are
 
195
        # present.  The texts introduced in merge (and only those) should be
 
196
        # present, and also generating a stream should succeed without blowing
 
197
        # up.
 
198
        self.assertTrue(unstacked_repo.has_revision('merge'))
 
199
        expected_texts = set([('file-id', 'merge')])
 
200
        if stacked_branch.repository.texts.get_parent_map([('root-id',
 
201
            'merge')]):
 
202
            # If a (root-id,merge) text exists, it should be in the stacked
 
203
            # repo.
 
204
            expected_texts.add(('root-id', 'merge'))
 
205
        self.assertEqual(expected_texts, unstacked_repo.texts.keys())
 
206
        self.assertCanStreamRevision(unstacked_repo, 'merge')
 
207
 
 
208
    def assertCanStreamRevision(self, repo, revision_id):
 
209
        exclude_keys = set(repo.all_revision_ids()) - set([revision_id])
 
210
        search = SearchResult([revision_id], exclude_keys, 1, [revision_id])
 
211
        source = repo._get_source(repo._format)
 
212
        for substream_kind, substream in source.get_stream(search):
 
213
            # Consume the substream
 
214
            list(substream)
 
215
 
 
216
    def test_fetch_across_stacking_boundary_ignores_ghost(self):
 
217
        if not self.repository_format_to.supports_external_lookups:
 
218
            raise TestNotApplicable("Need stacking support in the target.")
 
219
        to_repo = self.make_to_repository('to')
 
220
        builder = self.make_branch_builder('branch')
 
221
        builder.start_series()
 
222
        builder.build_snapshot('base', None, [
 
223
            ('add', ('', 'root-id', 'directory', '')),
 
224
            ('add', ('file', 'file-id', 'file', 'content\n'))])
 
225
        builder.build_snapshot('second', ['base'], [
 
226
            ('modify', ('file-id', 'second content\n'))])
 
227
        builder.build_snapshot('third', ['second', 'ghost'], [
 
228
            ('modify', ('file-id', 'third content\n'))])
 
229
        builder.finish_series()
 
230
        branch = builder.get_branch()
 
231
        repo = self.make_to_repository('trunk')
 
232
        trunk = repo.bzrdir.create_branch()
 
233
        trunk.repository.fetch(branch.repository, 'second')
 
234
        repo = self.make_to_repository('stacked')
 
235
        stacked_branch = repo.bzrdir.create_branch()
 
236
        stacked_branch.set_stacked_on_url(trunk.base)
 
237
        stacked_branch.repository.fetch(branch.repository, 'third')
 
238
        unstacked_repo = stacked_branch.bzrdir.open_repository()
 
239
        unstacked_repo.lock_read()
 
240
        self.addCleanup(unstacked_repo.unlock)
 
241
        self.assertFalse(unstacked_repo.has_revision('second'))
 
242
        self.assertFalse(unstacked_repo.has_revision('ghost'))
 
243
        self.assertEqual(
 
244
            set([('second',), ('third',)]),
 
245
            unstacked_repo.inventories.keys())
 
246
        # And the basis inventories have been copied correctly
 
247
        trunk.lock_read()
 
248
        self.addCleanup(trunk.unlock)
 
249
        second_tree = trunk.repository.revision_tree('second')
 
250
        stacked_branch.lock_read()
 
251
        self.addCleanup(stacked_branch.unlock)
 
252
        stacked_second_tree = stacked_branch.repository.revision_tree('second')
 
253
        self.assertEqual(second_tree.inventory, stacked_second_tree.inventory)
 
254
        # Finally, it's not enough to see that the basis inventories are
 
255
        # present.  The texts introduced in merge (and only those) should be
 
256
        # present, and also generating a stream should succeed without blowing
 
257
        # up.
 
258
        self.assertTrue(unstacked_repo.has_revision('third'))
 
259
        expected_texts = set([('file-id', 'third')])
 
260
        if stacked_branch.repository.texts.get_parent_map([('root-id',
 
261
            'third')]):
 
262
            # If a (root-id,third) text exists, it should be in the stacked
 
263
            # repo.
 
264
            expected_texts.add(('root-id', 'third'))
 
265
        self.assertEqual(expected_texts, unstacked_repo.texts.keys())
 
266
        self.assertCanStreamRevision(unstacked_repo, 'third')
 
267
 
 
268
    def test_fetch_from_stacked_to_stacked_copies_parent_inventories(self):
 
269
        """Fetch from a stacked branch copies inventories for parents of
 
270
        revisions at the stacking boundary.
 
271
 
 
272
        Specifically, fetch will copy the parent inventories from the
 
273
        source for which the corresponding revisions are not present.  This
 
274
        will happen even when the source repository has no fallbacks configured
 
275
        (as is the case during upgrade).
 
276
        """
 
277
        if not self.repository_format.supports_external_lookups:
 
278
            raise TestNotApplicable("Need stacking support in the source.")
 
279
        if not self.repository_format_to.supports_external_lookups:
 
280
            raise TestNotApplicable("Need stacking support in the target.")
 
281
        builder = self.make_branch_builder('branch')
 
282
        builder.start_series()
 
283
        builder.build_snapshot('base', None, [
 
284
            ('add', ('', 'root-id', 'directory', '')),
 
285
            ('add', ('file', 'file-id', 'file', 'content\n'))])
 
286
        builder.build_snapshot('left', ['base'], [
 
287
            ('modify', ('file-id', 'left content\n'))])
 
288
        builder.build_snapshot('right', ['base'], [
 
289
            ('modify', ('file-id', 'right content\n'))])
 
290
        builder.build_snapshot('merge', ['left', 'right'], [
 
291
            ('modify', ('file-id', 'left and right content\n'))])
 
292
        builder.finish_series()
 
293
        branch = builder.get_branch()
 
294
        repo = self.make_repository('old-trunk')
 
295
        # Make a pair of equivalent trunk repos in the from and to formats.
 
296
        old_trunk = repo.bzrdir.create_branch()
 
297
        old_trunk.repository.fetch(branch.repository, 'left')
 
298
        old_trunk.repository.fetch(branch.repository, 'right')
 
299
        repo = self.make_to_repository('new-trunk')
 
300
        new_trunk = repo.bzrdir.create_branch()
 
301
        new_trunk.repository.fetch(branch.repository, 'left')
 
302
        new_trunk.repository.fetch(branch.repository, 'right')
 
303
        # Make the source; a repo stacked on old_trunk contained just the data
 
304
        # for 'merge'.
 
305
        repo = self.make_repository('old-stacked')
 
306
        old_stacked_branch = repo.bzrdir.create_branch()
 
307
        old_stacked_branch.set_stacked_on_url(old_trunk.base)
 
308
        old_stacked_branch.repository.fetch(branch.repository, 'merge')
 
309
        # Make the target, a repo stacked on new_trunk.
 
310
        repo = self.make_to_repository('new-stacked')
 
311
        new_stacked_branch = repo.bzrdir.create_branch()
 
312
        new_stacked_branch.set_stacked_on_url(new_trunk.base)
 
313
        old_unstacked_repo = old_stacked_branch.bzrdir.open_repository()
 
314
        new_unstacked_repo = new_stacked_branch.bzrdir.open_repository()
 
315
        # Reopen the source and target repos without any fallbacks, and fetch
 
316
        # 'merge'.
 
317
        new_unstacked_repo.fetch(old_unstacked_repo, 'merge')
 
318
        # Now check the results.  new_unstacked_repo should contain all the
 
319
        # data necessary to stream 'merge' (i.e. the parent inventories).
 
320
        new_unstacked_repo.lock_read()
 
321
        self.addCleanup(new_unstacked_repo.unlock)
 
322
        self.assertFalse(new_unstacked_repo.has_revision('left'))
 
323
        self.assertFalse(new_unstacked_repo.has_revision('right'))
 
324
        self.assertEqual(
 
325
            set([('left',), ('right',), ('merge',)]),
 
326
            new_unstacked_repo.inventories.keys())
 
327
        # And the basis inventories have been copied correctly
 
328
        new_trunk.lock_read()
 
329
        self.addCleanup(new_trunk.unlock)
 
330
        left_tree, right_tree = new_trunk.repository.revision_trees(
 
331
            ['left', 'right'])
 
332
        new_stacked_branch.lock_read()
 
333
        self.addCleanup(new_stacked_branch.unlock)
 
334
        (stacked_left_tree,
 
335
         stacked_right_tree) = new_stacked_branch.repository.revision_trees(
 
336
            ['left', 'right'])
 
337
        self.assertEqual(left_tree.inventory, stacked_left_tree.inventory)
 
338
        self.assertEqual(right_tree.inventory, stacked_right_tree.inventory)
 
339
        # Finally, it's not enough to see that the basis inventories are
 
340
        # present.  The texts introduced in merge (and only those) should be
 
341
        # present, and also generating a stream should succeed without blowing
 
342
        # up.
 
343
        self.assertTrue(new_unstacked_repo.has_revision('merge'))
 
344
        expected_texts = set([('file-id', 'merge')])
 
345
        if new_stacked_branch.repository.texts.get_parent_map([('root-id',
 
346
            'merge')]):
 
347
            # If a (root-id,merge) text exists, it should be in the stacked
 
348
            # repo.
 
349
            expected_texts.add(('root-id', 'merge'))
 
350
        self.assertEqual(expected_texts, new_unstacked_repo.texts.keys())
 
351
        self.assertCanStreamRevision(new_unstacked_repo, 'merge')
164
352
 
165
353
    def test_fetch_missing_basis_text(self):
166
354
        """If fetching a delta, we should die if a basis is not present."""
276
464
        to_repo = self.make_to_repository('to')
277
465
        to_repo.fetch(from_tree.branch.repository)
278
466
        recorded_inv_sha1 = to_repo.get_inventory_sha1('foo-id')
279
 
        xml = to_repo.get_inventory_xml('foo-id')
280
 
        computed_inv_sha1 = osutils.sha_string(xml)
 
467
        to_repo.lock_read()
 
468
        self.addCleanup(to_repo.unlock)
 
469
        stream = to_repo.inventories.get_record_stream([('foo-id',)],
 
470
                                                       'unordered', True)
 
471
        bytes = stream.next().get_bytes_as('fulltext')
 
472
        computed_inv_sha1 = osutils.sha_string(bytes)
281
473
        self.assertEqual(computed_inv_sha1, recorded_inv_sha1)
282
474
 
283
475