~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/per_repository/test_repository.py

  • Committer: Patch Queue Manager
  • Date: 2016-01-31 13:36:59 UTC
  • mfrom: (6613.1.5 1538480-match-hostname)
  • Revision ID: pqm@pqm.ubuntu.com-20160131133659-ouy92ee2wlv9xz8m
(vila) Use ssl.match_hostname instead of our own. (Vincent Ladeuil)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2006-2010 Canonical Ltd
 
1
# Copyright (C) 2006-2011 Canonical Ltd
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
21
21
 
22
22
from bzrlib import (
23
23
    branch as _mod_branch,
24
 
    bzrdir,
 
24
    controldir,
25
25
    delta as _mod_delta,
26
26
    errors,
27
27
    gpg,
28
 
    graph,
29
28
    info,
30
29
    inventory,
31
 
    osutils,
32
30
    remote,
33
31
    repository,
34
32
    revision as _mod_revision,
35
33
    tests,
36
34
    transport,
37
35
    upgrade,
38
 
    versionedfile,
39
36
    workingtree,
40
 
    xml_serializer,
41
37
    )
42
38
from bzrlib.repofmt import (
43
 
    pack_repo,
44
 
    weaverepo,
 
39
    knitpack_repo,
45
40
    )
46
41
from bzrlib.tests import (
47
42
    per_repository,
69
64
        repo = self.make_repository('repo')
70
65
        self.assertSubset([getattr(repo._format, attribute)], allowed_values)
71
66
 
72
 
    def test_attribute__fetch_order(self):
73
 
        """Test the _fetch_order attribute."""
74
 
        self.assertFormatAttribute('_fetch_order', ('topological', 'unordered'))
75
 
 
76
 
    def test_attribute__fetch_uses_deltas(self):
77
 
        """Test the _fetch_uses_deltas attribute."""
78
 
        self.assertFormatAttribute('_fetch_uses_deltas', (True, False))
79
 
 
80
67
    def test_attribute_fast_deltas(self):
81
68
        """Test the format.fast_deltas attribute."""
82
69
        self.assertFormatAttribute('fast_deltas', (True, False))
83
70
 
 
71
    def test_attribute_supports_nesting_repositories(self):
 
72
        """Test the format.supports_nesting_repositories."""
 
73
        self.assertFormatAttribute('supports_nesting_repositories',
 
74
            (True, False))
 
75
 
 
76
    def test_attribute_supports_unreferenced_revisions(self):
 
77
        """Test the format.supports_unreferenced_revisions."""
 
78
        self.assertFormatAttribute('supports_unreferenced_revisions',
 
79
            (True, False))
 
80
 
84
81
    def test_attribute__fetch_reconcile(self):
85
82
        """Test the _fetch_reconcile attribute."""
86
83
        self.assertFormatAttribute('_fetch_reconcile', (True, False))
91
88
    def test_attribute_format_pack_compresses(self):
92
89
        self.assertFormatAttribute('pack_compresses', (True, False))
93
90
 
94
 
    def test_attribute_inventories_store(self):
95
 
        """Test the existence of the inventories attribute."""
96
 
        tree = self.make_branch_and_tree('tree')
97
 
        repo = tree.branch.repository
98
 
        self.assertIsInstance(repo.inventories, versionedfile.VersionedFiles)
99
 
 
100
 
    def test_attribute_inventories_basics(self):
101
 
        """Test basic aspects of the inventories attribute."""
102
 
        tree = self.make_branch_and_tree('tree')
103
 
        repo = tree.branch.repository
104
 
        rev_id = (tree.commit('a'),)
105
 
        tree.lock_read()
106
 
        self.addCleanup(tree.unlock)
107
 
        self.assertEqual(set([rev_id]), set(repo.inventories.keys()))
108
 
 
109
 
    def test_attribute_revision_store(self):
110
 
        """Test the existence of the revisions attribute."""
111
 
        tree = self.make_branch_and_tree('tree')
112
 
        repo = tree.branch.repository
113
 
        self.assertIsInstance(repo.revisions,
114
 
            versionedfile.VersionedFiles)
115
 
 
116
 
    def test_attribute_revision_store_basics(self):
117
 
        """Test the basic behaviour of the revisions attribute."""
118
 
        tree = self.make_branch_and_tree('tree')
119
 
        repo = tree.branch.repository
120
 
        repo.lock_write()
121
 
        try:
122
 
            self.assertEqual(set(), set(repo.revisions.keys()))
123
 
            revid = (tree.commit("foo"),)
124
 
            self.assertEqual(set([revid]), set(repo.revisions.keys()))
125
 
            self.assertEqual({revid:()},
126
 
                repo.revisions.get_parent_map([revid]))
127
 
        finally:
128
 
            repo.unlock()
129
 
        tree2 = self.make_branch_and_tree('tree2')
130
 
        tree2.pull(tree.branch)
131
 
        left_id = (tree2.commit('left'),)
132
 
        right_id = (tree.commit('right'),)
133
 
        tree.merge_from_branch(tree2.branch)
134
 
        merge_id = (tree.commit('merged'),)
135
 
        repo.lock_read()
136
 
        self.addCleanup(repo.unlock)
137
 
        self.assertEqual(set([revid, left_id, right_id, merge_id]),
138
 
            set(repo.revisions.keys()))
139
 
        self.assertEqual({revid:(), left_id:(revid,), right_id:(revid,),
140
 
             merge_id:(right_id, left_id)},
141
 
            repo.revisions.get_parent_map(repo.revisions.keys()))
142
 
 
143
 
    def test_attribute_signature_store(self):
144
 
        """Test the existence of the signatures attribute."""
145
 
        tree = self.make_branch_and_tree('tree')
146
 
        repo = tree.branch.repository
147
 
        self.assertIsInstance(repo.signatures,
148
 
            versionedfile.VersionedFiles)
149
 
 
150
 
    def test_attribute_text_store_basics(self):
151
 
        """Test the basic behaviour of the text store."""
152
 
        tree = self.make_branch_and_tree('tree')
153
 
        repo = tree.branch.repository
154
 
        file_id = "Foo:Bar"
155
 
        file_key = (file_id,)
156
 
        tree.lock_write()
157
 
        try:
158
 
            self.assertEqual(set(), set(repo.texts.keys()))
159
 
            tree.add(['foo'], [file_id], ['file'])
160
 
            tree.put_file_bytes_non_atomic(file_id, 'content\n')
161
 
            try:
162
 
                rev_key = (tree.commit("foo"),)
163
 
            except errors.IllegalPath:
164
 
                raise tests.TestNotApplicable(
165
 
                    'file_id %r cannot be stored on this'
166
 
                    ' platform for this repo format' % (file_id,))
167
 
            if repo._format.rich_root_data:
168
 
                root_commit = (tree.get_root_id(),) + rev_key
169
 
                keys = set([root_commit])
170
 
                parents = {root_commit:()}
171
 
            else:
172
 
                keys = set()
173
 
                parents = {}
174
 
            keys.add(file_key + rev_key)
175
 
            parents[file_key + rev_key] = ()
176
 
            self.assertEqual(keys, set(repo.texts.keys()))
177
 
            self.assertEqual(parents,
178
 
                repo.texts.get_parent_map(repo.texts.keys()))
179
 
        finally:
180
 
            tree.unlock()
181
 
        tree2 = self.make_branch_and_tree('tree2')
182
 
        tree2.pull(tree.branch)
183
 
        tree2.put_file_bytes_non_atomic('Foo:Bar', 'right\n')
184
 
        right_key = (tree2.commit('right'),)
185
 
        keys.add(file_key + right_key)
186
 
        parents[file_key + right_key] = (file_key + rev_key,)
187
 
        tree.put_file_bytes_non_atomic('Foo:Bar', 'left\n')
188
 
        left_key = (tree.commit('left'),)
189
 
        keys.add(file_key + left_key)
190
 
        parents[file_key + left_key] = (file_key + rev_key,)
191
 
        tree.merge_from_branch(tree2.branch)
192
 
        tree.put_file_bytes_non_atomic('Foo:Bar', 'merged\n')
193
 
        try:
194
 
            tree.auto_resolve()
195
 
        except errors.UnsupportedOperation:
196
 
            pass
197
 
        merge_key = (tree.commit('merged'),)
198
 
        keys.add(file_key + merge_key)
199
 
        parents[file_key + merge_key] = (file_key + left_key,
200
 
                                         file_key + right_key)
201
 
        repo.lock_read()
202
 
        self.addCleanup(repo.unlock)
203
 
        self.assertEqual(keys, set(repo.texts.keys()))
204
 
        self.assertEqual(parents, repo.texts.get_parent_map(repo.texts.keys()))
205
 
 
206
 
    def test_attribute_text_store(self):
207
 
        """Test the existence of the texts attribute."""
208
 
        tree = self.make_branch_and_tree('tree')
209
 
        repo = tree.branch.repository
210
 
        self.assertIsInstance(repo.texts,
211
 
            versionedfile.VersionedFiles)
212
 
 
213
 
    def test_exposed_versioned_files_are_marked_dirty(self):
214
 
        repo = self.make_repository('.')
215
 
        repo.lock_write()
216
 
        signatures = repo.signatures
217
 
        revisions = repo.revisions
218
 
        inventories = repo.inventories
219
 
        repo.unlock()
220
 
        self.assertRaises(errors.ObjectNotLocked,
221
 
            signatures.keys)
222
 
        self.assertRaises(errors.ObjectNotLocked,
223
 
            revisions.keys)
224
 
        self.assertRaises(errors.ObjectNotLocked,
225
 
            inventories.keys)
226
 
        self.assertRaises(errors.ObjectNotLocked,
227
 
            signatures.add_lines, ('foo',), [], [])
228
 
        self.assertRaises(errors.ObjectNotLocked,
229
 
            revisions.add_lines, ('foo',), [], [])
230
 
        self.assertRaises(errors.ObjectNotLocked,
231
 
            inventories.add_lines, ('foo',), [], [])
 
91
    def test_attribute_format_supports_full_versioned_files(self):
 
92
        self.assertFormatAttribute('supports_full_versioned_files',
 
93
            (True, False))
 
94
 
 
95
    def test_attribute_format_supports_funky_characters(self):
 
96
        self.assertFormatAttribute('supports_funky_characters',
 
97
            (True, False))
 
98
 
 
99
    def test_attribute_format_supports_leaving_lock(self):
 
100
        self.assertFormatAttribute('supports_leaving_lock',
 
101
            (True, False))
 
102
 
 
103
    def test_attribute_format_versioned_directories(self):
 
104
        self.assertFormatAttribute('supports_versioned_directories', (True, False))
 
105
 
 
106
    def test_attribute_format_revision_graph_can_have_wrong_parents(self):
 
107
        self.assertFormatAttribute('revision_graph_can_have_wrong_parents',
 
108
            (True, False))
 
109
 
 
110
    def test_format_is_deprecated(self):
 
111
        repo = self.make_repository('repo')
 
112
        self.assertSubset([repo._format.is_deprecated()], (True, False))
 
113
 
 
114
    def test_format_is_supported(self):
 
115
        repo = self.make_repository('repo')
 
116
        self.assertSubset([repo._format.is_supported()], (True, False))
232
117
 
233
118
    def test_clone_to_default_format(self):
234
119
        #TODO: Test that cloning a repository preserves all the information
246
131
        tree_b.get_file_text('file1')
247
132
        rev1 = repo_b.get_revision('rev1')
248
133
 
249
 
    def test_iter_inventories_is_ordered(self):
250
 
        # just a smoke test
251
 
        tree = self.make_branch_and_tree('a')
252
 
        first_revision = tree.commit('')
253
 
        second_revision = tree.commit('')
254
 
        tree.lock_read()
255
 
        self.addCleanup(tree.unlock)
256
 
        revs = (first_revision, second_revision)
257
 
        invs = tree.branch.repository.iter_inventories(revs)
258
 
        for rev_id, inv in zip(revs, invs):
259
 
            self.assertEqual(rev_id, inv.revision_id)
260
 
            self.assertIsInstance(inv, inventory.CommonInventory)
261
 
 
262
134
    def test_supports_rich_root(self):
263
135
        tree = self.make_branch_and_tree('a')
264
136
        tree.commit('')
266
138
        rev_tree = tree.branch.repository.revision_tree(second_revision)
267
139
        rev_tree.lock_read()
268
140
        self.addCleanup(rev_tree.unlock)
269
 
        inv = rev_tree.inventory
270
 
        rich_root = (inv.root.revision != second_revision)
 
141
        root_revision = rev_tree.get_file_revision(rev_tree.get_root_id())
 
142
        rich_root = (root_revision != second_revision)
271
143
        self.assertEqual(rich_root,
272
144
                         tree.branch.repository.supports_rich_root())
273
145
 
282
154
            # they may not be initializable.
283
155
            return
284
156
        # supported formats must be able to init and open
285
 
        t = transport.get_transport(self.get_url())
286
 
        readonly_t = transport.get_transport(self.get_readonly_url())
 
157
        t = self.get_transport()
 
158
        readonly_t = self.get_readonly_transport()
287
159
        made_control = self.bzrdir_format.initialize(t.base)
288
160
        made_repo = self.repository_format.initialize(made_control)
289
161
        self.assertEqual(made_control, made_repo.bzrdir)
290
162
 
291
 
        # find it via bzrdir opening:
292
 
        opened_control = bzrdir.BzrDir.open(readonly_t.base)
 
163
        # find it via controldir opening:
 
164
        opened_control = controldir.ControlDir.open(readonly_t.base)
293
165
        direct_opened_repo = opened_control.open_repository()
294
166
        self.assertEqual(direct_opened_repo.__class__, made_repo.__class__)
295
167
        self.assertEqual(opened_control, direct_opened_repo.bzrdir)
298
170
                              self.repository_format.__class__)
299
171
        # find it via Repository.open
300
172
        opened_repo = repository.Repository.open(readonly_t.base)
301
 
        self.failUnless(isinstance(opened_repo, made_repo.__class__))
 
173
        self.assertIsInstance(opened_repo, made_repo.__class__)
302
174
        self.assertEqual(made_repo._format.__class__,
303
175
                         opened_repo._format.__class__)
304
176
        # if it has a unique id string, can we probe for it ?
307
179
        except NotImplementedError:
308
180
            return
309
181
        self.assertEqual(self.repository_format,
310
 
                         repository.RepositoryFormat.find_format(opened_control))
 
182
             repository.RepositoryFormatMetaDir.find_format(opened_control))
311
183
 
312
184
    def test_format_matchingbzrdir(self):
313
185
        self.assertEqual(self.repository_format,
342
214
            # because the default open will not open them and
343
215
            # they may not be initializable.
344
216
            return
345
 
        t = transport.get_transport(self.get_url())
 
217
        t = self.get_transport()
346
218
        made_control = self.bzrdir_format.initialize(t.base)
347
219
        made_repo = made_control.create_repository()
348
220
        # Check that we have a repository object.
356
228
            # because the default open will not open them and
357
229
            # they may not be initializable.
358
230
            return
359
 
        t = transport.get_transport(self.get_url())
 
231
        t = self.get_transport()
360
232
        made_control = self.bzrdir_format.initialize(t.base)
361
233
        try:
362
234
            made_repo = made_control.create_repository(shared=True)
376
248
        tree = wt.branch.repository.revision_tree('revision-1')
377
249
        tree.lock_read()
378
250
        try:
379
 
            self.assertEqual('revision-1', tree.inventory.root.revision)
 
251
            self.assertEqual('revision-1',
 
252
                tree.get_file_revision(tree.get_root_id()))
380
253
            expected = inventory.InventoryDirectory('fixed-root', '', None)
381
254
            expected.revision = 'revision-1'
382
255
            self.assertEqual([('', 'V', 'directory', 'fixed-root', expected)],
414
287
        self.assertIsInstance(delta, _mod_delta.TreeDelta)
415
288
        self.assertEqual([('vla', 'file2', 'file')], delta.added)
416
289
 
417
 
    def test_get_revision_delta_filtered(self):
418
 
        tree_a = self.make_branch_and_tree('a')
419
 
        self.build_tree(['a/foo', 'a/bar/', 'a/bar/b1', 'a/bar/b2', 'a/baz'])
420
 
        tree_a.add(['foo', 'bar', 'bar/b1', 'bar/b2', 'baz'],
421
 
                   ['foo-id', 'bar-id', 'b1-id', 'b2-id', 'baz-id'])
422
 
        tree_a.commit('rev1', rev_id='rev1')
423
 
        self.build_tree(['a/bar/b3'])
424
 
        tree_a.add('bar/b3', 'b3-id')
425
 
        tree_a.commit('rev2', rev_id='rev2')
426
 
 
427
 
        # Test multiple files
428
 
        delta = tree_a.branch.repository.get_revision_delta('rev1',
429
 
            specific_fileids=['foo-id', 'baz-id'])
430
 
        self.assertIsInstance(delta, _mod_delta.TreeDelta)
431
 
        self.assertEqual([
432
 
            ('baz', 'baz-id', 'file'),
433
 
            ('foo', 'foo-id', 'file'),
434
 
            ], delta.added)
435
 
        # Test a directory
436
 
        delta = tree_a.branch.repository.get_revision_delta('rev1',
437
 
            specific_fileids=['bar-id'])
438
 
        self.assertIsInstance(delta, _mod_delta.TreeDelta)
439
 
        self.assertEqual([
440
 
            ('bar', 'bar-id', 'directory'),
441
 
            ('bar/b1', 'b1-id', 'file'),
442
 
            ('bar/b2', 'b2-id', 'file'),
443
 
            ], delta.added)
444
 
        # Test a file in a directory
445
 
        delta = tree_a.branch.repository.get_revision_delta('rev1',
446
 
            specific_fileids=['b2-id'])
447
 
        self.assertIsInstance(delta, _mod_delta.TreeDelta)
448
 
        self.assertEqual([
449
 
            ('bar', 'bar-id', 'directory'),
450
 
            ('bar/b2', 'b2-id', 'file'),
451
 
            ], delta.added)
452
 
        # Try another revision
453
 
        delta = tree_a.branch.repository.get_revision_delta('rev2',
454
 
                specific_fileids=['b3-id'])
455
 
        self.assertIsInstance(delta, _mod_delta.TreeDelta)
456
 
        self.assertEqual([
457
 
            ('bar', 'bar-id', 'directory'),
458
 
            ('bar/b3', 'b3-id', 'file'),
459
 
            ], delta.added)
460
 
        delta = tree_a.branch.repository.get_revision_delta('rev2',
461
 
                specific_fileids=['foo-id'])
462
 
        self.assertIsInstance(delta, _mod_delta.TreeDelta)
463
 
        self.assertEqual([], delta.added)
464
 
 
465
290
    def test_clone_bzrdir_repository_revision(self):
466
291
        # make a repository with some revisions,
467
292
        # and clone it, this should not have unreferenced revisions.
484
309
            return
485
310
        try:
486
311
            made_repo.set_make_working_trees(False)
487
 
        except NotImplementedError:
 
312
        except errors.UnsupportedOperation:
488
313
            # the repository does not support having its tree-making flag
489
314
            # toggled.
490
315
            return
497
322
        self.assertFalse(result.open_repository().make_working_trees())
498
323
 
499
324
    def test_upgrade_preserves_signatures(self):
 
325
        if not self.repository_format.supports_revision_signatures:
 
326
            raise tests.TestNotApplicable(
 
327
                "repository does not support signing revisions")
500
328
        wt = self.make_branch_and_tree('source')
501
329
        wt.commit('A', allow_pointless=True, rev_id='A')
502
330
        repo = wt.branch.repository
503
331
        repo.lock_write()
504
332
        repo.start_write_group()
505
 
        repo.sign_revision('A', gpg.LoopbackGPGStrategy(None))
 
333
        try:
 
334
            repo.sign_revision('A', gpg.LoopbackGPGStrategy(None))
 
335
        except errors.UnsupportedOperation:
 
336
            self.assertFalse(repo._format.supports_revision_signatures)
 
337
            raise tests.TestNotApplicable("signatures not supported by repository format")
506
338
        repo.commit_write_group()
507
339
        repo.unlock()
508
340
        old_signature = repo.get_signature_text('A')
509
341
        try:
510
 
            old_format = bzrdir.BzrDirFormat.get_default_format()
 
342
            old_format = controldir.ControlDirFormat.get_default_format()
511
343
            # This gives metadir branches something they can convert to.
512
344
            # it would be nice to have a 'latest' vs 'default' concept.
513
 
            format = bzrdir.format_registry.make_bzrdir('dirstate-with-subtree')
 
345
            format = controldir.format_registry.make_bzrdir(
 
346
                'development-subtree')
514
347
            upgrade.upgrade(repo.bzrdir.root_transport.base, format=format)
515
348
        except errors.UpToDateFormat:
516
349
            # this is in the most current format already.
524
357
    def test_format_description(self):
525
358
        repo = self.make_repository('.')
526
359
        text = repo._format.get_format_description()
527
 
        self.failUnless(len(text))
 
360
        self.assertTrue(len(text))
528
361
 
529
362
    def test_format_supports_external_lookups(self):
530
363
        repo = self.make_repository('.')
536
369
        tree = self.make_branch_and_tree('.')
537
370
        tree.commit(message, rev_id='a', allow_pointless=True)
538
371
        rev = tree.branch.repository.get_revision('a')
539
 
        if tree.branch.repository._serializer.squashes_xml_invalid_characters:
 
372
        serializer = getattr(tree.branch.repository, "_serializer", None)
 
373
        if serializer is not None and serializer.squashes_xml_invalid_characters:
540
374
            # we have to manually escape this as we dont try to
541
375
            # roundtrip xml invalid characters in the xml-based serializers.
542
376
            escaped_message, escape_count = re.subn(
597
431
        rev_tree = tree.branch.repository.revision_tree(tree.last_revision())
598
432
        rev_tree.lock_read()
599
433
        self.addCleanup(rev_tree.unlock)
600
 
        self.assertEqual('rev_id', rev_tree.inventory.root.revision)
601
 
 
602
 
    def test_upgrade_from_format4(self):
603
 
        from bzrlib.tests.test_upgrade import _upgrade_dir_template
604
 
        if isinstance(self.repository_format, remote.RemoteRepositoryFormat):
605
 
            return # local conversion to/from RemoteObjects is irrelevant.
606
 
        if self.repository_format.get_format_description() \
607
 
            == "Repository format 4":
608
 
            raise tests.TestSkipped('Cannot convert format-4 to itself')
609
 
        self.build_tree_contents(_upgrade_dir_template)
610
 
        old_repodir = bzrdir.BzrDir.open_unsupported('.')
611
 
        old_repo_format = old_repodir.open_repository()._format
612
 
        format = self.repository_format._matchingbzrdir
613
 
        try:
614
 
            format.repository_format = self.repository_format
615
 
        except AttributeError:
616
 
            pass
617
 
        upgrade.upgrade('.', format)
 
434
        root_id = rev_tree.get_root_id()
 
435
        self.assertEqual('rev_id', rev_tree.get_file_revision(root_id))
618
436
 
619
437
    def test_pointless_commit(self):
620
438
        tree = self.make_branch_and_tree('.')
630
448
        repo._format.rich_root_data
631
449
        repo._format.supports_tree_reference
632
450
 
633
 
    def test_get_serializer_format(self):
634
 
        repo = self.make_repository('.')
635
 
        format = repo.get_serializer_format()
636
 
        self.assertEqual(repo._serializer.format_num, format)
637
 
 
638
451
    def test_iter_files_bytes(self):
639
452
        tree = self.make_branch_and_tree('tree')
640
453
        self.build_tree_contents([('tree/file1', 'foo'),
662
475
                          repository.iter_files_bytes(
663
476
                          [('file3-id', 'rev3', 'file1-notpresent')]))
664
477
 
665
 
    def test_item_keys_introduced_by(self):
666
 
        # Make a repo with one revision and one versioned file.
667
 
        tree = self.make_branch_and_tree('t')
668
 
        self.build_tree(['t/foo'])
669
 
        tree.add('foo', 'file1')
670
 
        tree.commit('message', rev_id='rev_id')
671
 
        repo = tree.branch.repository
672
 
        repo.lock_write()
673
 
        repo.start_write_group()
674
 
        repo.sign_revision('rev_id', gpg.LoopbackGPGStrategy(None))
675
 
        repo.commit_write_group()
676
 
        repo.unlock()
677
 
        repo.lock_read()
678
 
        self.addCleanup(repo.unlock)
679
 
 
680
 
        # Item keys will be in this order, for maximum convenience for
681
 
        # generating data to insert into knit repository:
682
 
        #   * files
683
 
        #   * inventory
684
 
        #   * signatures
685
 
        #   * revisions
686
 
        expected_item_keys = [
687
 
            ('file', 'file1', ['rev_id']),
688
 
            ('inventory', None, ['rev_id']),
689
 
            ('signatures', None, ['rev_id']),
690
 
            ('revisions', None, ['rev_id'])]
691
 
        item_keys = list(repo.item_keys_introduced_by(['rev_id']))
692
 
        item_keys = [
693
 
            (kind, file_id, list(versions))
694
 
            for (kind, file_id, versions) in item_keys]
695
 
 
696
 
        if repo.supports_rich_root():
697
 
            # Check for the root versioned file in the item_keys, then remove
698
 
            # it from streamed_names so we can compare that with
699
 
            # expected_record_names.
700
 
            # Note that the file keys can be in any order, so this test is
701
 
            # written to allow that.
702
 
            inv = repo.get_inventory('rev_id')
703
 
            root_item_key = ('file', inv.root.file_id, ['rev_id'])
704
 
            self.assertTrue(root_item_key in item_keys)
705
 
            item_keys.remove(root_item_key)
706
 
 
707
 
        self.assertEqual(expected_item_keys, item_keys)
708
 
 
709
478
    def test_get_graph(self):
710
479
        """Bare-bones smoketest that all repositories implement get_graph."""
711
480
        repo = self.make_repository('repo')
763
532
        """
764
533
        repo = self.make_repository('.')
765
534
        # This should work, not raise NotImplementedError:
766
 
        if not repo.revision_graph_can_have_wrong_parents():
 
535
        if not repo._format.revision_graph_can_have_wrong_parents:
767
536
            return
768
537
        repo.lock_read()
769
538
        self.addCleanup(repo.unlock)
775
544
        repo._check_for_inconsistent_revision_parents()
776
545
 
777
546
    def test_add_signature_text(self):
778
 
        repo = self.make_repository('repo')
779
 
        repo.lock_write()
780
 
        self.addCleanup(repo.unlock)
781
 
        repo.start_write_group()
782
 
        self.addCleanup(repo.abort_write_group)
783
 
        inv = inventory.Inventory(revision_id='A')
784
 
        inv.root.revision = 'A'
785
 
        repo.add_inventory('A', inv, [])
786
 
        repo.add_revision('A', _mod_revision.Revision(
787
 
                'A', committer='A', timestamp=0,
788
 
                inventory_sha1='', timezone=0, message='A'))
789
 
        repo.add_signature_text('A', 'This might be a signature')
790
 
        self.assertEqual('This might be a signature',
791
 
                         repo.get_signature_text('A'))
792
 
 
793
 
    def test_add_revision_inventory_sha1(self):
794
 
        inv = inventory.Inventory(revision_id='A')
795
 
        inv.root.revision = 'A'
796
 
        inv.root.file_id = 'fixed-root'
797
 
        # Insert the inventory on its own to an identical repository, to get
798
 
        # its sha1.
799
 
        reference_repo = self.make_repository('reference_repo')
800
 
        reference_repo.lock_write()
801
 
        reference_repo.start_write_group()
802
 
        inv_sha1 = reference_repo.add_inventory('A', inv, [])
803
 
        reference_repo.abort_write_group()
804
 
        reference_repo.unlock()
805
 
        # Now insert a revision with this inventory, and it should get the same
806
 
        # sha1.
807
 
        repo = self.make_repository('repo')
808
 
        repo.lock_write()
809
 
        repo.start_write_group()
810
 
        root_id = inv.root.file_id
811
 
        repo.texts.add_lines(('fixed-root', 'A'), [], [])
812
 
        repo.add_revision('A', _mod_revision.Revision(
813
 
                'A', committer='B', timestamp=0,
814
 
                timezone=0, message='C'), inv=inv)
815
 
        repo.commit_write_group()
816
 
        repo.unlock()
817
 
        repo.lock_read()
818
 
        self.assertEquals(inv_sha1, repo.get_revision('A').inventory_sha1)
819
 
        repo.unlock()
820
 
 
821
 
    def test_install_revisions(self):
822
 
        wt = self.make_branch_and_tree('source')
823
 
        wt.commit('A', allow_pointless=True, rev_id='A')
824
 
        repo = wt.branch.repository
825
 
        repo.lock_write()
826
 
        repo.start_write_group()
827
 
        repo.sign_revision('A', gpg.LoopbackGPGStrategy(None))
828
 
        repo.commit_write_group()
829
 
        repo.unlock()
830
 
        repo.lock_read()
831
 
        self.addCleanup(repo.unlock)
832
 
        repo2 = self.make_repository('repo2')
833
 
        revision = repo.get_revision('A')
834
 
        tree = repo.revision_tree('A')
835
 
        signature = repo.get_signature_text('A')
836
 
        repo2.lock_write()
837
 
        self.addCleanup(repo2.unlock)
838
 
        repository.install_revisions(repo2, [(revision, tree, signature)])
839
 
        self.assertEqual(revision, repo2.get_revision('A'))
840
 
        self.assertEqual(signature, repo2.get_signature_text('A'))
 
547
        builder = self.make_branch_builder('.')
 
548
        builder.start_series()
 
549
        builder.build_snapshot('A', None, [
 
550
            ('add', ('', 'root-id', 'directory', None))])
 
551
        builder.finish_series()
 
552
        b = builder.get_branch()
 
553
        b.lock_write()
 
554
        self.addCleanup(b.unlock)
 
555
        if b.repository._format.supports_revision_signatures:
 
556
            b.repository.start_write_group()
 
557
            b.repository.add_signature_text('A', 'This might be a signature')
 
558
            b.repository.commit_write_group()
 
559
            self.assertEqual('This might be a signature',
 
560
                             b.repository.get_signature_text('A'))
 
561
        else:
 
562
            b.repository.start_write_group()
 
563
            self.addCleanup(b.repository.abort_write_group)
 
564
            self.assertRaises(errors.UnsupportedOperation,
 
565
                b.repository.add_signature_text, 'A',
 
566
                'This might be a signature')
841
567
 
842
568
    # XXX: this helper duplicated from tests.test_repository
843
 
    def make_remote_repository(self, path, shared=False):
 
569
    def make_remote_repository(self, path, shared=None):
844
570
        """Make a RemoteRepository object backed by a real repository that will
845
571
        be created at the given path."""
846
572
        repo = self.make_repository(path, shared=shared)
847
573
        smart_server = test_server.SmartTCPServer_for_testing()
848
574
        self.start_server(smart_server, self.get_server())
849
 
        remote_transport = transport.get_transport(
 
575
        remote_transport = transport.get_transport_from_url(
850
576
            smart_server.get_url()).clone(path)
851
 
        remote_bzrdir = bzrdir.BzrDir.open_from_transport(remote_transport)
 
577
        if not repo.bzrdir._format.supports_transport(remote_transport):
 
578
            raise tests.TestNotApplicable(
 
579
                "format does not support transport")
 
580
        remote_bzrdir = controldir.ControlDir.open_from_transport(
 
581
            remote_transport)
852
582
        remote_repo = remote_bzrdir.open_repository()
853
583
        return remote_repo
854
584
 
855
585
    def test_sprout_from_hpss_preserves_format(self):
856
586
        """repo.sprout from a smart server preserves the repository format."""
857
 
        if self.repository_format == weaverepo.RepositoryFormat7():
858
 
            raise tests.TestNotApplicable(
859
 
                "Cannot fetch weaves over smart protocol.")
860
587
        remote_repo = self.make_remote_repository('remote')
861
588
        local_bzrdir = self.make_bzrdir('local')
862
589
        try:
864
591
        except errors.TransportNotPossible:
865
592
            raise tests.TestNotApplicable(
866
593
                "Cannot lock_read old formats like AllInOne over HPSS.")
867
 
        remote_backing_repo = bzrdir.BzrDir.open(
 
594
        remote_backing_repo = controldir.ControlDir.open(
868
595
            self.get_vfs_only_url('remote')).open_repository()
869
 
        self.assertEqual(remote_backing_repo._format, local_repo._format)
 
596
        self.assertEqual(
 
597
            remote_backing_repo._format.network_name(),
 
598
            local_repo._format.network_name())
870
599
 
871
600
    def test_sprout_branch_from_hpss_preserves_repo_format(self):
872
601
        """branch.sprout from a smart server preserves the repository format.
873
602
        """
874
 
        weave_formats = [weaverepo.RepositoryFormat5(),
875
 
                         weaverepo.RepositoryFormat6(),
876
 
                         weaverepo.RepositoryFormat7()]
877
 
        if self.repository_format in weave_formats:
 
603
        if not self.repository_format.supports_leaving_lock:
878
604
            raise tests.TestNotApplicable(
879
 
                "Cannot fetch weaves over smart protocol.")
 
605
                "Format can not be used over HPSS")
880
606
        remote_repo = self.make_remote_repository('remote')
881
607
        remote_branch = remote_repo.bzrdir.create_branch()
882
608
        try:
885
611
            raise tests.TestNotApplicable(
886
612
                "Cannot lock_read old formats like AllInOne over HPSS.")
887
613
        local_repo = local_bzrdir.open_repository()
888
 
        remote_backing_repo = bzrdir.BzrDir.open(
 
614
        remote_backing_repo = controldir.ControlDir.open(
889
615
            self.get_vfs_only_url('remote')).open_repository()
890
616
        self.assertEqual(remote_backing_repo._format, local_repo._format)
891
617
 
893
619
        """branch.sprout from a smart server preserves the repository format of
894
620
        a branch from a shared repository.
895
621
        """
896
 
        weave_formats = [weaverepo.RepositoryFormat5(),
897
 
                         weaverepo.RepositoryFormat6(),
898
 
                         weaverepo.RepositoryFormat7()]
899
 
        if self.repository_format in weave_formats:
 
622
        if not self.repository_format.supports_leaving_lock:
900
623
            raise tests.TestNotApplicable(
901
 
                "Cannot fetch weaves over smart protocol.")
 
624
                "Format can not be used over HPSS")
902
625
        # Make a shared repo
903
626
        remote_repo = self.make_remote_repository('remote', shared=True)
904
 
        remote_backing_repo = bzrdir.BzrDir.open(
 
627
        remote_backing_repo = controldir.ControlDir.open(
905
628
            self.get_vfs_only_url('remote')).open_repository()
906
629
        # Make a branch in that repo in an old format that isn't the default
907
630
        # branch format for the repo.
908
 
        from bzrlib.branch import BzrBranchFormat5
 
631
        from bzrlib.branchfmt.fullhistory import BzrBranchFormat5
909
632
        format = remote_backing_repo.bzrdir.cloning_metadir()
910
633
        format._branch_format = BzrBranchFormat5()
911
634
        remote_transport = remote_repo.bzrdir.root_transport.clone('branch')
912
 
        remote_backing_repo.bzrdir.create_branch_convenience(
 
635
        controldir.ControlDir.create_branch_convenience(
913
636
            remote_transport.base, force_new_repo=False, format=format)
914
 
        remote_branch = bzrdir.BzrDir.open_from_transport(
 
637
        remote_branch = controldir.ControlDir.open_from_transport(
915
638
            remote_transport).open_branch()
916
639
        try:
917
640
            local_bzrdir = remote_branch.bzrdir.sprout('local')
922
645
        self.assertEqual(remote_backing_repo._format, local_repo._format)
923
646
 
924
647
    def test_clone_to_hpss(self):
925
 
        pre_metadir_formats = [weaverepo.RepositoryFormat5(),
926
 
                               weaverepo.RepositoryFormat6()]
927
 
        if self.repository_format in pre_metadir_formats:
 
648
        if not self.repository_format.supports_leaving_lock:
928
649
            raise tests.TestNotApplicable(
929
650
                "Cannot lock pre_metadir_formats remotely.")
930
651
        remote_transport = self.make_smart_server('remote')
943
664
            repo = self.make_repository('repo', shared=True)
944
665
        except errors.IncompatibleFormat:
945
666
            raise tests.TestNotApplicable('Cannot make a shared repository')
946
 
        if isinstance(repo.bzrdir, bzrdir.BzrDirPreSplitOut):
947
 
            raise tests.KnownFailure(
 
667
        if repo.bzrdir._format.fixed_components:
 
668
            self.knownFailure(
948
669
                "pre metadir branches do not upgrade on push "
949
670
                "with stacking policy")
950
671
        if isinstance(repo._format,
951
 
                      pack_repo.RepositoryFormatKnitPack5RichRootBroken):
 
672
                      knitpack_repo.RepositoryFormatKnitPack5RichRootBroken):
952
673
            raise tests.TestNotApplicable("unsupported format")
953
674
        # Make a source branch in 'repo' in an unstackable branch format
954
675
        bzrdir_format = self.repository_format._matchingbzrdir
993
714
        else:
994
715
            self.assertEqual(stack_on.repository._format, target_repo._format)
995
716
 
996
 
    def test__get_sink(self):
997
 
        repo = self.make_repository('repo')
998
 
        sink = repo._get_sink()
999
 
        self.assertIsInstance(sink, repository.StreamSink)
1000
 
 
1001
717
    def test__make_parents_provider(self):
1002
718
        """Repositories must have a _make_parents_provider method that returns
1003
719
        an object with a get_parent_map method.
1005
721
        repo = self.make_repository('repo')
1006
722
        repo._make_parents_provider().get_parent_map
1007
723
 
1008
 
    def make_repository_and_foo_bar(self, shared):
 
724
    def make_repository_and_foo_bar(self, shared=None):
1009
725
        made_control = self.make_bzrdir('repository')
1010
726
        repo = made_control.create_repository(shared=shared)
1011
 
        bzrdir.BzrDir.create_branch_convenience(self.get_url('repository/foo'),
1012
 
                                                force_new_repo=False)
1013
 
        bzrdir.BzrDir.create_branch_convenience(self.get_url('repository/bar'),
1014
 
                                                force_new_repo=True)
 
727
        if not repo._format.supports_nesting_repositories:
 
728
            raise tests.TestNotApplicable("repository does not support "
 
729
                "nesting repositories")
 
730
        controldir.ControlDir.create_branch_convenience(
 
731
            self.get_url('repository/foo'), force_new_repo=False)
 
732
        controldir.ControlDir.create_branch_convenience(
 
733
            self.get_url('repository/bar'), force_new_repo=True)
1015
734
        baz = self.make_bzrdir('repository/baz')
1016
735
        qux = self.make_branch('repository/baz/qux')
1017
736
        quxx = self.make_branch('repository/baz/qux/quxx')
1018
737
        return repo
1019
738
 
1020
739
    def test_find_branches(self):
1021
 
        repo = self.make_repository_and_foo_bar(shared=False)
 
740
        repo = self.make_repository_and_foo_bar()
1022
741
        branches = repo.find_branches()
1023
742
        self.assertContainsRe(branches[-1].base, 'repository/foo/$')
1024
743
        self.assertContainsRe(branches[-3].base, 'repository/baz/qux/$')
1047
766
 
1048
767
    def test_find_branches_using_standalone(self):
1049
768
        branch = self.make_branch('branch')
 
769
        if not branch.repository._format.supports_nesting_repositories:
 
770
            raise tests.TestNotApplicable("format does not support nesting "
 
771
                "repositories")
1050
772
        contained = self.make_branch('branch/contained')
1051
773
        branches = branch.repository.find_branches(using=True)
1052
774
        self.assertEqual([branch.base], [b.base for b in branches])
1055
777
                         [b.base for b in branches])
1056
778
 
1057
779
    def test_find_branches_using_empty_standalone_repo(self):
1058
 
        repo = self.make_repository('repo')
1059
 
        self.assertFalse(repo.is_shared())
 
780
        try:
 
781
            repo = self.make_repository('repo', shared=False)
 
782
        except errors.IncompatibleFormat:
 
783
            raise tests.TestNotApplicable("format does not support standalone "
 
784
                "repositories")
1060
785
        try:
1061
786
            repo.bzrdir.open_branch()
1062
787
        except errors.NotBranchError:
1069
794
        repo = self.make_repository('repo')
1070
795
        try:
1071
796
            repo.set_make_working_trees(True)
1072
 
        except errors.RepositoryUpgradeRequired, e:
 
797
        except (errors.RepositoryUpgradeRequired, errors.UnsupportedOperation), e:
1073
798
            raise tests.TestNotApplicable('Format does not support this flag.')
1074
799
        self.assertTrue(repo.make_working_trees())
1075
800
 
1077
802
        repo = self.make_repository('repo')
1078
803
        try:
1079
804
            repo.set_make_working_trees(False)
1080
 
        except errors.RepositoryUpgradeRequired, e:
 
805
        except (errors.RepositoryUpgradeRequired, errors.UnsupportedOperation), e:
1081
806
            raise tests.TestNotApplicable('Format does not support this flag.')
1082
807
        self.assertFalse(repo.make_working_trees())
1083
808
 
1151
876
        self.assertThat(repo.lock_write, ReturnsUnlockable(repo))
1152
877
 
1153
878
 
1154
 
class TestCaseWithComplexRepository(per_repository.TestCaseWithRepository):
1155
 
 
1156
 
    def setUp(self):
1157
 
        super(TestCaseWithComplexRepository, self).setUp()
1158
 
        tree_a = self.make_branch_and_tree('a')
1159
 
        self.bzrdir = tree_a.branch.bzrdir
1160
 
        # add a corrupt inventory 'orphan'
1161
 
        # this may need some generalising for knits.
1162
 
        tree_a.lock_write()
1163
 
        try:
1164
 
            tree_a.branch.repository.start_write_group()
1165
 
            try:
1166
 
                inv_file = tree_a.branch.repository.inventories
1167
 
                inv_file.add_lines(('orphan',), [], [])
1168
 
            except:
1169
 
                tree_a.branch.repository.commit_write_group()
1170
 
                raise
1171
 
            else:
1172
 
                tree_a.branch.repository.abort_write_group()
1173
 
        finally:
1174
 
            tree_a.unlock()
1175
 
        # add a real revision 'rev1'
1176
 
        tree_a.commit('rev1', rev_id='rev1', allow_pointless=True)
1177
 
        # add a real revision 'rev2' based on rev1
1178
 
        tree_a.commit('rev2', rev_id='rev2', allow_pointless=True)
1179
 
        # add a reference to a ghost
1180
 
        tree_a.add_parent_tree_id('ghost1')
1181
 
        try:
1182
 
            tree_a.commit('rev3', rev_id='rev3', allow_pointless=True)
1183
 
        except errors.RevisionNotPresent:
1184
 
            raise tests.TestNotApplicable(
1185
 
                "Cannot test with ghosts for this format.")
1186
 
        # add another reference to a ghost, and a second ghost.
1187
 
        tree_a.add_parent_tree_id('ghost1')
1188
 
        tree_a.add_parent_tree_id('ghost2')
1189
 
        tree_a.commit('rev4', rev_id='rev4', allow_pointless=True)
1190
 
 
1191
 
    def test_revision_trees(self):
1192
 
        revision_ids = ['rev1', 'rev2', 'rev3', 'rev4']
1193
 
        repository = self.bzrdir.open_repository()
1194
 
        repository.lock_read()
1195
 
        self.addCleanup(repository.unlock)
1196
 
        trees1 = list(repository.revision_trees(revision_ids))
1197
 
        trees2 = [repository.revision_tree(t) for t in revision_ids]
1198
 
        self.assertEqual(len(trees1), len(trees2))
1199
 
        for tree1, tree2 in zip(trees1, trees2):
1200
 
            self.assertFalse(tree2.changes_from(tree1).has_changed())
1201
 
 
1202
 
    def test_get_deltas_for_revisions(self):
1203
 
        repository = self.bzrdir.open_repository()
1204
 
        repository.lock_read()
1205
 
        self.addCleanup(repository.unlock)
1206
 
        revisions = [repository.get_revision(r) for r in
1207
 
                     ['rev1', 'rev2', 'rev3', 'rev4']]
1208
 
        deltas1 = list(repository.get_deltas_for_revisions(revisions))
1209
 
        deltas2 = [repository.get_revision_delta(r.revision_id) for r in
1210
 
                   revisions]
1211
 
        self.assertEqual(deltas1, deltas2)
1212
 
 
1213
 
    def test_all_revision_ids(self):
1214
 
        # all_revision_ids -> all revisions
1215
 
        self.assertEqual(set(['rev1', 'rev2', 'rev3', 'rev4']),
1216
 
            set(self.bzrdir.open_repository().all_revision_ids()))
1217
 
 
1218
 
    def test_get_ancestry_missing_revision(self):
1219
 
        # get_ancestry(revision that is in some data but not fully installed
1220
 
        # -> NoSuchRevision
1221
 
        self.assertRaises(errors.NoSuchRevision,
1222
 
                          self.bzrdir.open_repository().get_ancestry, 'orphan')
1223
 
 
1224
 
    def test_get_unordered_ancestry(self):
1225
 
        repo = self.bzrdir.open_repository()
1226
 
        self.assertEqual(set(repo.get_ancestry('rev3')),
1227
 
                         set(repo.get_ancestry('rev3', topo_sorted=False)))
1228
 
 
1229
 
    def test_reserved_id(self):
1230
 
        repo = self.make_repository('repository')
1231
 
        repo.lock_write()
1232
 
        repo.start_write_group()
1233
 
        try:
1234
 
            self.assertRaises(errors.ReservedId, repo.add_inventory, 'reserved:',
1235
 
                              None, None)
1236
 
            self.assertRaises(errors.ReservedId, repo.add_inventory_by_delta,
1237
 
                "foo", [], 'reserved:', None)
1238
 
            self.assertRaises(errors.ReservedId, repo.add_revision, 'reserved:',
1239
 
                              None)
1240
 
        finally:
1241
 
            repo.abort_write_group()
1242
 
            repo.unlock()
1243
 
 
1244
 
 
1245
 
class TestCaseWithCorruptRepository(per_repository.TestCaseWithRepository):
1246
 
 
1247
 
    def setUp(self):
1248
 
        super(TestCaseWithCorruptRepository, self).setUp()
1249
 
        # a inventory with no parents and the revision has parents..
1250
 
        # i.e. a ghost.
1251
 
        repo = self.make_repository('inventory_with_unnecessary_ghost')
1252
 
        repo.lock_write()
1253
 
        repo.start_write_group()
1254
 
        inv = inventory.Inventory(revision_id = 'ghost')
1255
 
        inv.root.revision = 'ghost'
1256
 
        if repo.supports_rich_root():
1257
 
            root_id = inv.root.file_id
1258
 
            repo.texts.add_lines((root_id, 'ghost'), [], [])
1259
 
        sha1 = repo.add_inventory('ghost', inv, [])
1260
 
        rev = _mod_revision.Revision(
1261
 
            timestamp=0, timezone=None, committer="Foo Bar <foo@example.com>",
1262
 
            message="Message", inventory_sha1=sha1, revision_id='ghost')
1263
 
        rev.parent_ids = ['the_ghost']
1264
 
        try:
1265
 
            repo.add_revision('ghost', rev)
1266
 
        except (errors.NoSuchRevision, errors.RevisionNotPresent):
1267
 
            raise tests.TestNotApplicable(
1268
 
                "Cannot test with ghosts for this format.")
1269
 
 
1270
 
        inv = inventory.Inventory(revision_id = 'the_ghost')
1271
 
        inv.root.revision = 'the_ghost'
1272
 
        if repo.supports_rich_root():
1273
 
            root_id = inv.root.file_id
1274
 
            repo.texts.add_lines((root_id, 'the_ghost'), [], [])
1275
 
        sha1 = repo.add_inventory('the_ghost', inv, [])
1276
 
        rev = _mod_revision.Revision(
1277
 
            timestamp=0, timezone=None, committer="Foo Bar <foo@example.com>",
1278
 
            message="Message", inventory_sha1=sha1, revision_id='the_ghost')
1279
 
        rev.parent_ids = []
1280
 
        repo.add_revision('the_ghost', rev)
1281
 
        # check its setup usefully
1282
 
        inv_weave = repo.inventories
1283
 
        possible_parents = (None, (('ghost',),))
1284
 
        self.assertSubset(inv_weave.get_parent_map([('ghost',)])[('ghost',)],
1285
 
            possible_parents)
1286
 
        repo.commit_write_group()
1287
 
        repo.unlock()
1288
 
 
1289
 
    def test_corrupt_revision_access_asserts_if_reported_wrong(self):
1290
 
        repo_url = self.get_url('inventory_with_unnecessary_ghost')
1291
 
        repo = repository.Repository.open(repo_url)
1292
 
        reported_wrong = False
1293
 
        try:
1294
 
            if repo.get_ancestry('ghost') != [None, 'the_ghost', 'ghost']:
1295
 
                reported_wrong = True
1296
 
        except errors.CorruptRepository:
1297
 
            # caught the bad data:
1298
 
            return
1299
 
        if not reported_wrong:
1300
 
            return
1301
 
        self.assertRaises(errors.CorruptRepository, repo.get_revision, 'ghost')
1302
 
 
1303
 
    def test_corrupt_revision_get_revision_reconcile(self):
1304
 
        repo_url = self.get_url('inventory_with_unnecessary_ghost')
1305
 
        repo = repository.Repository.open(repo_url)
1306
 
        repo.get_revision_reconcile('ghost')
1307
 
 
1308
 
 
1309
879
# FIXME: document why this is a TestCaseWithTransport rather than a
1310
880
#        TestCaseWithRepository
1311
881
class TestEscaping(tests.TestCaseWithTransport):
1336
906
        wt.add(['foo'], [FOO_ID])
1337
907
        wt.commit('this is my new commit', rev_id=REV_ID)
1338
908
        # now access over vfat; should be safe
1339
 
        branch = bzrdir.BzrDir.open(self.get_url('repo')).open_branch()
 
909
        branch = controldir.ControlDir.open(self.get_url('repo')).open_branch()
1340
910
        revtree = branch.repository.revision_tree(REV_ID)
1341
911
        revtree.lock_read()
1342
912
        self.addCleanup(revtree.unlock)
1353
923
            'rev1', _mod_revision.NULL_REVISION, fileobj)
1354
924
 
1355
925
 
1356
 
 
1357
 
 
1358
926
class TestRepositoryControlComponent(per_repository.TestCaseWithRepository):
1359
927
    """Repository implementations adequately implement ControlComponent."""
1360
 
    
 
928
 
1361
929
    def test_urls(self):
1362
930
        repo = self.make_repository('repo')
1363
931
        self.assertIsInstance(repo.user_url, str)
1364
932
        self.assertEqual(repo.user_url, repo.user_transport.base)
1365
 
        # for all current bzrdir implementations the user dir must be 
 
933
        # for all current bzrdir implementations the user dir must be
1366
934
        # above the control dir but we might need to relax that?
1367
935
        self.assertEqual(repo.control_url.find(repo.user_url), 0)
1368
936
        self.assertEqual(repo.control_url, repo.control_transport.base)
 
937
 
 
938
 
 
939
class TestDeltaRevisionFiltered(per_repository.TestCaseWithRepository):
 
940
 
 
941
    def setUp(self):
 
942
        super(TestDeltaRevisionFiltered, self).setUp()
 
943
        tree_a = self.make_branch_and_tree('a')
 
944
        self.build_tree(['a/foo', 'a/bar/', 'a/bar/b1', 'a/bar/b2', 'a/baz'])
 
945
        tree_a.add(['foo', 'bar', 'bar/b1', 'bar/b2', 'baz'],
 
946
                   ['foo-id', 'bar-id', 'b1-id', 'b2-id', 'baz-id'])
 
947
        tree_a.commit('rev1', rev_id='rev1')
 
948
        self.build_tree(['a/bar/b3'])
 
949
        tree_a.add('bar/b3', 'b3-id')
 
950
        tree_a.commit('rev2', rev_id='rev2')
 
951
        self.repository = tree_a.branch.repository
 
952
 
 
953
    def test_multiple_files(self):
 
954
        # Test multiple files
 
955
        delta = self.repository.get_revision_delta('rev1',
 
956
            specific_fileids=['foo-id', 'baz-id'])
 
957
        self.assertIsInstance(delta, _mod_delta.TreeDelta)
 
958
        self.assertEqual([
 
959
            ('baz', 'baz-id', 'file'),
 
960
            ('foo', 'foo-id', 'file'),
 
961
            ], delta.added)
 
962
 
 
963
    def test_directory(self):
 
964
        # Test a directory
 
965
        delta = self.repository.get_revision_delta('rev1',
 
966
            specific_fileids=['bar-id'])
 
967
        self.assertIsInstance(delta, _mod_delta.TreeDelta)
 
968
        self.assertEqual([
 
969
            ('bar', 'bar-id', 'directory'),
 
970
            ('bar/b1', 'b1-id', 'file'),
 
971
            ('bar/b2', 'b2-id', 'file'),
 
972
            ], delta.added)
 
973
 
 
974
    def test_unrelated(self):
 
975
        # Try another revision
 
976
        delta = self.repository.get_revision_delta('rev2',
 
977
                specific_fileids=['foo-id'])
 
978
        self.assertIsInstance(delta, _mod_delta.TreeDelta)
 
979
        self.assertEqual([], delta.added)
 
980
 
 
981
    def test_file_in_directory(self):
 
982
        # Test a file in a directory, both of which were added
 
983
        delta = self.repository.get_revision_delta('rev1',
 
984
            specific_fileids=['b2-id'])
 
985
        self.assertIsInstance(delta, _mod_delta.TreeDelta)
 
986
        self.assertEqual([
 
987
            ('bar', 'bar-id', 'directory'),
 
988
            ('bar/b2', 'b2-id', 'file'),
 
989
            ], delta.added)
 
990
 
 
991
    def test_file_in_unchanged_directory(self):
 
992
        delta = self.repository.get_revision_delta('rev2',
 
993
            specific_fileids=['b3-id'])
 
994
        self.assertIsInstance(delta, _mod_delta.TreeDelta)
 
995
        if delta.added == [
 
996
            ('bar', 'bar-id', 'directory'),
 
997
            ('bar/b3', 'b3-id', 'file')]:
 
998
            self.knownFailure("bzr incorrectly reports 'bar' as added - "
 
999
                              "bug 878217")
 
1000
        self.assertEqual([
 
1001
            ('bar/b3', 'b3-id', 'file'),
 
1002
            ], delta.added)