/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
2241.1.5 by Martin Pool
Move KnitFormat2 into repofmt
1
# Copyright (C) 2005, 2006, 2007 Canonical Ltd
1887.1.1 by Adeodato Simó
Do not separate paragraphs in the copyright statement with blank lines,
2
#
1534.4.40 by Robert Collins
Add RepositoryFormats and allow bzrdir.open or create _repository to be used.
3
# This program is free software; you can redistribute it and/or modify
4
# it under the terms of the GNU General Public License as published by
5
# the Free Software Foundation; either version 2 of the License, or
6
# (at your option) any later version.
1887.1.1 by Adeodato Simó
Do not separate paragraphs in the copyright statement with blank lines,
7
#
1534.4.40 by Robert Collins
Add RepositoryFormats and allow bzrdir.open or create _repository to be used.
8
# This program is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
# GNU General Public License for more details.
1887.1.1 by Adeodato Simó
Do not separate paragraphs in the copyright statement with blank lines,
12
#
1534.4.40 by Robert Collins
Add RepositoryFormats and allow bzrdir.open or create _repository to be used.
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
"""Tests for bzrdir implementations - tests a bzrdir format."""
18
2520.4.54 by Aaron Bentley
Hang a create_bundle method off repository
19
from cStringIO import StringIO
1666.1.6 by Robert Collins
Make knit the default format.
20
import re
1534.4.40 by Robert Collins
Add RepositoryFormats and allow bzrdir.open or create _repository to be used.
21
1534.1.31 by Robert Collins
Deprecated fetch.fetch and fetch.greedy_fetch for branch.fetch, and move the Repository.fetch internals to InterRepo and InterWeaveRepo.
22
import bzrlib
1752.2.87 by Andrew Bennetts
Make tests pass.
23
from bzrlib import (
24
    bzrdir,
25
    errors,
26
    remote,
27
    repository,
28
    )
1852.10.3 by Robert Collins
Remove all uses of compare_trees and replace with Tree.changes_from throughout bzrlib.
29
from bzrlib.delta import TreeDelta
1731.1.33 by Aaron Bentley
Revert no-special-root changes
30
from bzrlib.inventory import Inventory, InventoryDirectory
1534.4.41 by Robert Collins
Branch now uses BzrDir reasonably sanely.
31
from bzrlib.revision import NULL_REVISION
2279.7.9 by Andrew Bennetts
Remove some redundant code pointed out by Robert's review, and remove some unused imports while I'm there.
32
from bzrlib.tests import TestCaseWithTransport, TestSkipped
2485.7.1 by Robert Collins
Relocate TestCaseWithRepository to be more central.
33
from bzrlib.tests.repository_implementations import TestCaseWithRepository
1534.4.40 by Robert Collins
Add RepositoryFormats and allow bzrdir.open or create _repository to be used.
34
from bzrlib.transport import get_transport
35
from bzrlib.upgrade import upgrade
36
from bzrlib.workingtree import WorkingTree
37
38
2018.5.66 by Wouter van Heyst
Fix repository test parameterization for RemoteRepository.
39
class TestRepositoryMakeBranchAndTree(TestCaseWithRepository):
40
41
    def test_repository_format(self):
2018.5.119 by Robert Collins
Unbreak TestRepositoryMakeBranchAndTree.
42
        # make sure the repository on tree.branch is of the desired format,
43
        # because developers use this api to setup the tree, branch and 
44
        # repository for their tests: having it now give the right repository
45
        # type would invalidate the tests.
2018.5.66 by Wouter van Heyst
Fix repository test parameterization for RemoteRepository.
46
        tree = self.make_branch_and_tree('repo')
47
        self.assertIsInstance(tree.branch.repository._format,
48
            self.repository_format.__class__)
2381.1.1 by Robert Collins
Split out hpss test fixes which dont depend on new or altered API's.
49
50
1534.4.40 by Robert Collins
Add RepositoryFormats and allow bzrdir.open or create _repository to be used.
51
class TestRepository(TestCaseWithRepository):
52
1534.4.50 by Robert Collins
Got the bzrdir api straightened out, plenty of refactoring to use it pending, but the api is up and running.
53
    def test_clone_to_default_format(self):
1534.4.40 by Robert Collins
Add RepositoryFormats and allow bzrdir.open or create _repository to be used.
54
        #TODO: Test that cloning a repository preserves all the information
1534.4.50 by Robert Collins
Got the bzrdir api straightened out, plenty of refactoring to use it pending, but the api is up and running.
55
        # such as signatures[not tested yet] etc etc.
56
        # when changing to the current default format.
1534.4.41 by Robert Collins
Branch now uses BzrDir reasonably sanely.
57
        tree_a = self.make_branch_and_tree('a')
2381.1.3 by Robert Collins
Review feedback.
58
        self.build_tree(['a/foo'])
1534.4.41 by Robert Collins
Branch now uses BzrDir reasonably sanely.
59
        tree_a.add('foo', 'file1')
60
        tree_a.commit('rev1', rev_id='rev1')
61
        bzrdirb = self.make_bzrdir('b')
62
        repo_b = tree_a.branch.repository.clone(bzrdirb)
63
        tree_b = repo_b.revision_tree('rev1')
64
        tree_b.get_file_text('file1')
65
        rev1 = repo_b.get_revision('rev1')
66
1910.2.63 by Aaron Bentley
Add supports_rich_root member to repository
67
    def test_supports_rich_root(self):
68
        tree = self.make_branch_and_tree('a')
69
        tree.commit('')
70
        second_revision = tree.commit('')
71
        inv = tree.branch.repository.revision_tree(second_revision).inventory
72
        rich_root = (inv.root.revision != second_revision)
2018.5.113 by Robert Collins
Test only fixes from the ported-to-bzr.dev test-correctness branch.
73
        self.assertEqual(rich_root,
1910.2.63 by Aaron Bentley
Add supports_rich_root member to repository
74
                         tree.branch.repository.supports_rich_root())
75
1534.4.41 by Robert Collins
Branch now uses BzrDir reasonably sanely.
76
    def test_clone_specific_format(self):
77
        """todo"""
1534.4.40 by Robert Collins
Add RepositoryFormats and allow bzrdir.open or create _repository to be used.
78
79
    def test_format_initialize_find_open(self):
80
        # loopback test to check the current format initializes to itself.
81
        if not self.repository_format.is_supported():
82
            # unsupported formats are not loopback testable
83
            # because the default open will not open them and
84
            # they may not be initializable.
85
            return
86
        # supported formats must be able to init and open
87
        t = get_transport(self.get_url())
88
        readonly_t = get_transport(self.get_readonly_url())
89
        made_control = self.bzrdir_format.initialize(t.base)
90
        made_repo = self.repository_format.initialize(made_control)
91
        self.assertEqual(made_control, made_repo.bzrdir)
92
93
        # find it via bzrdir opening:
94
        opened_control = bzrdir.BzrDir.open(readonly_t.base)
95
        direct_opened_repo = opened_control.open_repository()
96
        self.assertEqual(direct_opened_repo.__class__, made_repo.__class__)
97
        self.assertEqual(opened_control, direct_opened_repo.bzrdir)
98
1752.2.52 by Andrew Bennetts
Flesh out more Remote* methods needed to open and initialise remote branches/trees/repositories.
99
        self.assertIsInstance(direct_opened_repo._format,
100
                              self.repository_format.__class__)
1534.4.40 by Robert Collins
Add RepositoryFormats and allow bzrdir.open or create _repository to be used.
101
        # find it via Repository.open
102
        opened_repo = repository.Repository.open(readonly_t.base)
103
        self.failUnless(isinstance(opened_repo, made_repo.__class__))
104
        self.assertEqual(made_repo._format.__class__,
105
                         opened_repo._format.__class__)
106
        # if it has a unique id string, can we probe for it ?
107
        try:
108
            self.repository_format.get_format_string()
109
        except NotImplementedError:
110
            return
111
        self.assertEqual(self.repository_format,
112
                         repository.RepositoryFormat.find_format(opened_control))
113
114
    def test_create_repository(self):
1534.6.1 by Robert Collins
allow API creation of shared repositories
115
        # bzrdir can construct a repository for itself.
1534.4.40 by Robert Collins
Add RepositoryFormats and allow bzrdir.open or create _repository to be used.
116
        if not self.bzrdir_format.is_supported():
117
            # unsupported formats are not loopback testable
118
            # because the default open will not open them and
119
            # they may not be initializable.
120
            return
121
        t = get_transport(self.get_url())
122
        made_control = self.bzrdir_format.initialize(t.base)
123
        made_repo = made_control.create_repository()
1752.2.50 by Andrew Bennetts
Implement RemoteBzrDir.create_{branch,workingtree}
124
        # Check that we have a repository object.
125
        made_repo.has_revision('foo')
1534.4.40 by Robert Collins
Add RepositoryFormats and allow bzrdir.open or create _repository to be used.
126
        self.assertEqual(made_control, made_repo.bzrdir)
1534.6.1 by Robert Collins
allow API creation of shared repositories
127
        
128
    def test_create_repository_shared(self):
129
        # bzrdir can construct a shared repository.
130
        if not self.bzrdir_format.is_supported():
131
            # unsupported formats are not loopback testable
132
            # because the default open will not open them and
133
            # they may not be initializable.
134
            return
135
        t = get_transport(self.get_url())
136
        made_control = self.bzrdir_format.initialize(t.base)
137
        try:
138
            made_repo = made_control.create_repository(shared=True)
139
        except errors.IncompatibleFormat:
140
            # not all repository formats understand being shared, or
141
            # may only be shared in some circumstances.
142
            return
1752.2.50 by Andrew Bennetts
Implement RemoteBzrDir.create_{branch,workingtree}
143
        # Check that we have a repository object.
144
        made_repo.has_revision('foo')
1534.6.1 by Robert Collins
allow API creation of shared repositories
145
        self.assertEqual(made_control, made_repo.bzrdir)
1534.6.3 by Robert Collins
find_repository sufficiently robust.
146
        self.assertTrue(made_repo.is_shared())
1534.4.41 by Robert Collins
Branch now uses BzrDir reasonably sanely.
147
148
    def test_revision_tree(self):
149
        wt = self.make_branch_and_tree('.')
1731.1.33 by Aaron Bentley
Revert no-special-root changes
150
        wt.set_root_id('fixed-root')
1534.4.41 by Robert Collins
Branch now uses BzrDir reasonably sanely.
151
        wt.commit('lala!', rev_id='revision-1', allow_pointless=True)
152
        tree = wt.branch.repository.revision_tree('revision-1')
1731.1.45 by Aaron Bentley
Merge bzr.dev
153
        self.assertEqual('revision-1', tree.inventory.root.revision) 
154
        expected = InventoryDirectory('fixed-root', '', None)
155
        expected.revision = 'revision-1'
156
        self.assertEqual([('', 'V', 'directory', 'fixed-root', expected)],
1731.1.54 by Aaron Bentley
Fix revision_tree tests
157
                         list(tree.list_files(include_root=True)))
1534.4.41 by Robert Collins
Branch now uses BzrDir reasonably sanely.
158
        tree = wt.branch.repository.revision_tree(None)
1731.1.54 by Aaron Bentley
Fix revision_tree tests
159
        self.assertEqual([], list(tree.list_files(include_root=True)))
1534.4.41 by Robert Collins
Branch now uses BzrDir reasonably sanely.
160
        tree = wt.branch.repository.revision_tree(NULL_REVISION)
1731.1.54 by Aaron Bentley
Fix revision_tree tests
161
        self.assertEqual([], list(tree.list_files(include_root=True)))
1534.4.41 by Robert Collins
Branch now uses BzrDir reasonably sanely.
162
1534.4.50 by Robert Collins
Got the bzrdir api straightened out, plenty of refactoring to use it pending, but the api is up and running.
163
    def test_fetch(self):
1534.1.29 by Robert Collins
Add a test environment for InterRepository objects, and remove the fetch corner case tests from test_repository.
164
        # smoke test fetch to ensure that the convenience function works.
165
        # it is defined as a convenience function with the underlying 
166
        # functionality provided by an InterRepository
1534.4.41 by Robert Collins
Branch now uses BzrDir reasonably sanely.
167
        tree_a = self.make_branch_and_tree('a')
2381.1.3 by Robert Collins
Review feedback.
168
        self.build_tree(['a/foo'])
1534.4.41 by Robert Collins
Branch now uses BzrDir reasonably sanely.
169
        tree_a.add('foo', 'file1')
170
        tree_a.commit('rev1', rev_id='rev1')
1534.1.29 by Robert Collins
Add a test environment for InterRepository objects, and remove the fetch corner case tests from test_repository.
171
        # fetch with a default limit (grab everything)
172
        repo = bzrdir.BzrDir.create_repository(self.get_url('b'))
2305.2.1 by Andrew Bennetts
Use repo.supports_rich_root() everywhere rather than
173
        if (tree_a.branch.repository.supports_rich_root() and not
174
            repo.supports_rich_root()):
1910.2.26 by Aaron Bentley
Fix up some test cases
175
            raise TestSkipped('Cannot fetch from model2 to model1')
1534.1.31 by Robert Collins
Deprecated fetch.fetch and fetch.greedy_fetch for branch.fetch, and move the Repository.fetch internals to InterRepo and InterWeaveRepo.
176
        repo.fetch(tree_a.branch.repository,
177
                   revision_id=None,
178
                   pb=bzrlib.progress.DummyProgress())
1534.4.41 by Robert Collins
Branch now uses BzrDir reasonably sanely.
179
2018.5.118 by Robert Collins
Fix RemoteRepositoryFormat to have appropriate rich_root_data and support_tree_reference.
180
    def test_fetch_knit3(self):
181
        # create a repository of the sort we are testing.
2100.3.20 by Aaron Bentley
Implement tree comparison for tree references
182
        tree_a = self.make_branch_and_tree('a', '')
2381.1.3 by Robert Collins
Review feedback.
183
        self.build_tree(['a/foo'])
1910.2.17 by Aaron Bentley
Get fetching from 1 to 2 under test
184
        tree_a.add('foo', 'file1')
185
        tree_a.commit('rev1', rev_id='rev1')
2018.5.118 by Robert Collins
Fix RemoteRepositoryFormat to have appropriate rich_root_data and support_tree_reference.
186
        # create a knit-3 based format to fetch into
2255.2.208 by Robert Collins
Remove more references to 'experimental' formats.
187
        f = bzrdir.format_registry.make_bzrdir('dirstate-with-subtree')
2100.3.20 by Aaron Bentley
Implement tree comparison for tree references
188
        try:
189
            format = tree_a.branch.repository._format
190
            format.check_conversion_target(f.repository_format)
2018.5.118 by Robert Collins
Fix RemoteRepositoryFormat to have appropriate rich_root_data and support_tree_reference.
191
            # if we cannot convert data to knit3, skip the test.
2100.3.20 by Aaron Bentley
Implement tree comparison for tree references
192
        except errors.BadConversionTarget, e:
193
            raise TestSkipped(str(e))
2018.5.82 by Andrew Bennetts
Merge from bzr.dev. Breaks a few tests because there are new methods not yet implemented.
194
        self.get_transport().mkdir('b')
1910.2.17 by Aaron Bentley
Get fetching from 1 to 2 under test
195
        b_bzrdir = f.initialize(self.get_url('b'))
2018.5.118 by Robert Collins
Fix RemoteRepositoryFormat to have appropriate rich_root_data and support_tree_reference.
196
        knit3_repo = b_bzrdir.create_repository()
197
        # fetch with a default limit (grab everything)
198
        knit3_repo.fetch(tree_a.branch.repository, revision_id=None)
199
        rev1_tree = knit3_repo.revision_tree('rev1')
1910.2.19 by Aaron Bentley
Test whether revision id for root is retained
200
        lines = rev1_tree.get_file_lines(rev1_tree.inventory.root.file_id)
201
        self.assertEqual([], lines)
202
        b_branch = b_bzrdir.create_branch()
203
        b_branch.pull(tree_a.branch)
1752.2.87 by Andrew Bennetts
Make tests pass.
204
        try:
205
            tree_b = b_bzrdir.create_workingtree()
206
        except errors.NotLocalUrl:
207
            raise TestSkipped("cannot make working tree with transport %r"
208
                              % b_bzrdir.transport)
1910.2.19 by Aaron Bentley
Test whether revision id for root is retained
209
        tree_b.commit('no change', rev_id='rev2')
2018.5.118 by Robert Collins
Fix RemoteRepositoryFormat to have appropriate rich_root_data and support_tree_reference.
210
        rev2_tree = knit3_repo.revision_tree('rev2')
1910.2.22 by Aaron Bentley
Make commits preserve root entry data
211
        self.assertEqual('rev1', rev2_tree.inventory.root.revision)
1910.2.17 by Aaron Bentley
Get fetching from 1 to 2 under test
212
2668.2.1 by Andrew Bennetts
Split out fetch refactoring from repo-refactor, adding Repository.get_data_about_revision_ids.
213
    def makeARepoWithSignatures(self):
214
        wt = self.make_branch_and_tree('a-repo-with-sigs')
215
        wt.commit('rev1', allow_pointless=True, rev_id='rev1')
216
        repo = wt.branch.repository
217
        repo.sign_revision('rev1', bzrlib.gpg.LoopbackGPGStrategy(None))
218
        return repo
219
220
    def test_fetch_copies_signatures(self):
221
        source_repo = self.makeARepoWithSignatures()
222
        target_repo = self.make_repository('target')
223
        target_repo.fetch(source_repo, revision_id=None)
224
        self.assertEqual(
225
            source_repo.get_signature_text('rev1'),
226
            target_repo.get_signature_text('rev1'))
227
1770.3.3 by Jelmer Vernooij
Add tests for Branch.get_revision_delta() and Repository.get_revision_delta().
228
    def test_get_revision_delta(self):
229
        tree_a = self.make_branch_and_tree('a')
2381.1.3 by Robert Collins
Review feedback.
230
        self.build_tree(['a/foo'])
1770.3.3 by Jelmer Vernooij
Add tests for Branch.get_revision_delta() and Repository.get_revision_delta().
231
        tree_a.add('foo', 'file1')
232
        tree_a.commit('rev1', rev_id='rev1')
2381.1.3 by Robert Collins
Review feedback.
233
        self.build_tree(['a/vla'])
1770.3.3 by Jelmer Vernooij
Add tests for Branch.get_revision_delta() and Repository.get_revision_delta().
234
        tree_a.add('vla', 'file2')
235
        tree_a.commit('rev2', rev_id='rev2')
236
237
        delta = tree_a.branch.repository.get_revision_delta('rev1')
238
        self.assertIsInstance(delta, TreeDelta)
239
        self.assertEqual([('foo', 'file1', 'file')], delta.added)
240
        delta = tree_a.branch.repository.get_revision_delta('rev2')
241
        self.assertIsInstance(delta, TreeDelta)
242
        self.assertEqual([('vla', 'file2', 'file')], delta.added)
243
1534.4.50 by Robert Collins
Got the bzrdir api straightened out, plenty of refactoring to use it pending, but the api is up and running.
244
    def test_clone_bzrdir_repository_revision(self):
245
        # make a repository with some revisions,
246
        # and clone it, this should not have unreferenced revisions.
247
        # also: test cloning with a revision id of NULL_REVISION -> empty repo.
248
        raise TestSkipped('revision limiting is not implemented yet.')
249
250
    def test_clone_repository_basis_revision(self):
251
        raise TestSkipped('the use of a basis should not add noise data to the result.')
252
1534.6.5 by Robert Collins
Cloning of repos preserves shared and make-working-tree attributes.
253
    def test_clone_shared_no_tree(self):
254
        # cloning a shared repository keeps it shared
255
        # and preserves the make_working_tree setting.
256
        made_control = self.make_bzrdir('source')
257
        try:
258
            made_repo = made_control.create_repository(shared=True)
259
        except errors.IncompatibleFormat:
260
            # not all repository formats understand being shared, or
261
            # may only be shared in some circumstances.
262
            return
2018.14.2 by Andrew Bennetts
All but one repository_implementation tests for RemoteRepository passing.
263
        try:
264
            made_repo.set_make_working_trees(False)
265
        except NotImplementedError:
2018.5.120 by Robert Collins
The Repository API ``make_working_trees`` is now permitted to return
266
            # the repository does not support having its tree-making flag
267
            # toggled.
268
            return
1534.6.5 by Robert Collins
Cloning of repos preserves shared and make-working-tree attributes.
269
        result = made_control.clone(self.get_url('target'))
1752.2.55 by Andrew Bennetts
Replace another isinstance(made_repo, Repository) check.
270
        # Check that we have a repository object.
271
        made_repo.has_revision('foo')
272
1534.6.5 by Robert Collins
Cloning of repos preserves shared and make-working-tree attributes.
273
        self.assertEqual(made_control, made_repo.bzrdir)
274
        self.assertTrue(result.open_repository().is_shared())
275
        self.assertFalse(result.open_repository().make_working_trees())
276
2018.5.90 by Andrew Bennetts
Fix test_upgrade_preserves_signatures; it incorrectly assumed that upgrade(wt, ...) would necessarily affect the repository.
277
    def test_upgrade_preserves_signatures(self):
1556.1.4 by Robert Collins
Add a new format for what will become knit, and the surrounding logic to upgrade repositories within metadirs, and tests for the same.
278
        wt = self.make_branch_and_tree('source')
279
        wt.commit('A', allow_pointless=True, rev_id='A')
2018.5.90 by Andrew Bennetts
Fix test_upgrade_preserves_signatures; it incorrectly assumed that upgrade(wt, ...) would necessarily affect the repository.
280
        repo = wt.branch.repository
2617.6.4 by Robert Collins
Update tests with things that break when a repository requires write groups to be used.
281
        repo.lock_write()
282
        repo.start_write_group()
2018.5.90 by Andrew Bennetts
Fix test_upgrade_preserves_signatures; it incorrectly assumed that upgrade(wt, ...) would necessarily affect the repository.
283
        repo.sign_revision('A', bzrlib.gpg.LoopbackGPGStrategy(None))
2617.6.4 by Robert Collins
Update tests with things that break when a repository requires write groups to be used.
284
        repo.commit_write_group()
285
        repo.unlock()
2018.5.90 by Andrew Bennetts
Fix test_upgrade_preserves_signatures; it incorrectly assumed that upgrade(wt, ...) would necessarily affect the repository.
286
        old_signature = repo.get_signature_text('A')
1556.1.4 by Robert Collins
Add a new format for what will become knit, and the surrounding logic to upgrade repositories within metadirs, and tests for the same.
287
        try:
288
            old_format = bzrdir.BzrDirFormat.get_default_format()
289
            # This gives metadir branches something they can convert to.
290
            # it would be nice to have a 'latest' vs 'default' concept.
2255.2.208 by Robert Collins
Remove more references to 'experimental' formats.
291
            format = bzrdir.format_registry.make_bzrdir('dirstate-with-subtree')
2018.5.90 by Andrew Bennetts
Fix test_upgrade_preserves_signatures; it incorrectly assumed that upgrade(wt, ...) would necessarily affect the repository.
292
            upgrade(repo.bzrdir.root_transport.base, format=format)
1556.1.4 by Robert Collins
Add a new format for what will become knit, and the surrounding logic to upgrade repositories within metadirs, and tests for the same.
293
        except errors.UpToDateFormat:
294
            # this is in the most current format already.
295
            return
1910.2.12 by Aaron Bentley
Implement knit repo format 2
296
        except errors.BadConversionTarget, e:
297
            raise TestSkipped(str(e))
1556.1.4 by Robert Collins
Add a new format for what will become knit, and the surrounding logic to upgrade repositories within metadirs, and tests for the same.
298
        wt = WorkingTree.open(wt.basedir)
1563.2.31 by Robert Collins
Convert Knit repositories to use knits.
299
        new_signature = wt.branch.repository.get_signature_text('A')
1556.1.4 by Robert Collins
Add a new format for what will become knit, and the surrounding logic to upgrade repositories within metadirs, and tests for the same.
300
        self.assertEqual(old_signature, new_signature)
301
1594.2.23 by Robert Collins
Test versioned file storage handling of clean/dirty status for accessed versioned files.
302
    def test_exposed_versioned_files_are_marked_dirty(self):
303
        repo = self.make_repository('.')
304
        repo.lock_write()
305
        inv = repo.get_inventory_weave()
306
        repo.unlock()
307
        self.assertRaises(errors.OutSideTransaction, inv.add_lines, 'foo', [], [])
308
1624.3.19 by Olaf Conradi
New call get_format_description to give a user-friendly description of a
309
    def test_format_description(self):
310
        repo = self.make_repository('.')
311
        text = repo._format.get_format_description()
312
        self.failUnless(len(text))
313
1666.1.6 by Robert Collins
Make knit the default format.
314
    def assertMessageRoundtrips(self, message):
315
        """Assert that message roundtrips to a repository and back intact."""
316
        tree = self.make_branch_and_tree('.')
317
        tree.commit(message, rev_id='a', allow_pointless=True)
318
        rev = tree.branch.repository.get_revision('a')
319
        # we have to manually escape this as we dont try to
320
        # roundtrip xml invalid characters at this point.
321
        # when escaping is moved to the serialiser, this test
322
        # can check against the literal message rather than
323
        # this escaped version.
324
        escaped_message, escape_count = re.subn(
325
            u'[^\x09\x0A\x0D\u0020-\uD7FF\uE000-\uFFFD]+',
326
            lambda match: match.group(0).encode('unicode_escape'),
327
            message)
328
        escaped_message= re.sub('\r', '\n', escaped_message)
329
        self.assertEqual(rev.message, escaped_message)
330
        # insist the class is unicode no matter what came in for 
331
        # consistency.
332
        self.assertIsInstance(rev.message, unicode)
333
334
    def test_commit_unicode_message(self):
335
        # a siple unicode message should be preserved
336
        self.assertMessageRoundtrips(u'foo bar gamm\xae plop')
337
338
    def test_commit_unicode_control_characters(self):
339
        # a unicode message with control characters should roundtrip too.
340
        self.assertMessageRoundtrips(
341
            "All 8-bit chars: " +  ''.join([unichr(x) for x in range(256)]))
1534.4.41 by Robert Collins
Branch now uses BzrDir reasonably sanely.
342
1732.2.4 by Martin Pool
Split check into Branch.check and Repository.check
343
    def test_check_repository(self):
344
        """Check a fairly simple repository's history"""
345
        tree = self.make_branch_and_tree('.')
346
        tree.commit('initial empty commit', rev_id='a-rev',
347
                    allow_pointless=True)
348
        result = tree.branch.repository.check(['a-rev'])
349
        # writes to log; should accept both verbose or non-verbose
350
        result.report_results(verbose=True)
351
        result.report_results(verbose=False)
352
1756.1.5 by Aaron Bentley
Test get_revisions with all repository types (and fix bug...)
353
    def test_get_revisions(self):
354
        tree = self.make_branch_and_tree('.')
355
        tree.commit('initial empty commit', rev_id='a-rev',
356
                    allow_pointless=True)
357
        tree.commit('second empty commit', rev_id='b-rev',
358
                    allow_pointless=True)
359
        tree.commit('third empty commit', rev_id='c-rev',
360
                    allow_pointless=True)
361
        repo = tree.branch.repository
362
        revision_ids = ['a-rev', 'b-rev', 'c-rev']
363
        revisions = repo.get_revisions(revision_ids)
364
        assert len(revisions) == 3, repr(revisions)
365
        zipped = zip(revisions, revision_ids)
366
        self.assertEqual(len(zipped), 3)
367
        for revision, revision_id in zipped:
368
            self.assertEqual(revision.revision_id, revision_id)
369
            self.assertEqual(revision, repo.get_revision(revision_id))
1732.2.4 by Martin Pool
Split check into Branch.check and Repository.check
370
1910.2.1 by Aaron Bentley
Ensure root entry always has a revision
371
    def test_root_entry_has_revision(self):
372
        tree = self.make_branch_and_tree('.')
373
        tree.commit('message', rev_id='rev_id')
2255.7.65 by Robert Collins
Split test_root_revision_entry into tree and repository portions.
374
        rev_tree = tree.branch.repository.revision_tree(tree.last_revision())
1910.2.6 by Aaron Bentley
Update for merge review, handle deprecations
375
        self.assertEqual('rev_id', rev_tree.inventory.root.revision)
1910.2.1 by Aaron Bentley
Ensure root entry always has a revision
376
2255.7.64 by Robert Collins
Disabled test_repository.test_create_basis_inventory, a test that tests tree behaviour in the wrong place - its future is being discussed.
377
    def DISABLED_DELETE_OR_FIX_BEFORE_MERGE_test_create_basis_inventory(self):
1910.2.31 by Aaron Bentley
Fix bugs in basis inventory handling, change filename
378
        # Needs testing here because differences between repo and working tree
379
        # basis inventory formats can lead to bugs.
380
        t = self.make_branch_and_tree('.')
381
        b = t.branch
382
        open('a', 'wb').write('a\n')
383
        t.add('a')
384
        t.commit('a', rev_id='r1')
385
386
        t._control_files.get_utf8('basis-inventory-cache')
387
388
        basis_inv = t.basis_tree().inventory
389
        self.assertEquals('r1', basis_inv.revision_id)
390
        
391
        store_inv = b.repository.get_inventory('r1')
392
        self.assertEquals(store_inv._byid, basis_inv._byid)
393
394
        open('b', 'wb').write('b\n')
395
        t.add('b')
396
        t.commit('b', rev_id='r2')
397
398
        t._control_files.get_utf8('basis-inventory-cache')
399
400
        basis_inv_txt = t.read_basis_inventory()
2100.3.15 by Aaron Bentley
get test suite passing
401
        basis_inv = bzrlib.xml7.serializer_v7.read_inventory_from_string(basis_inv_txt)
1910.2.31 by Aaron Bentley
Fix bugs in basis inventory handling, change filename
402
        self.assertEquals('r2', basis_inv.revision_id)
403
        store_inv = b.repository.get_inventory('r2')
404
405
        self.assertEquals(store_inv._byid, basis_inv._byid)
406
1910.2.36 by Aaron Bentley
Get upgrade from format4 under test and fixed for all formats
407
    def test_upgrade_from_format4(self):
408
        from bzrlib.tests.test_upgrade import _upgrade_dir_template
2241.1.4 by Martin Pool
Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.
409
        if self.repository_format.get_format_description() \
410
            == "Repository format 4":
1910.2.36 by Aaron Bentley
Get upgrade from format4 under test and fixed for all formats
411
            raise TestSkipped('Cannot convert format-4 to itself')
1752.2.89 by Andrew Bennetts
Skip test_upgrade_from_format4 for RemoteRepositoryFormat.
412
        if isinstance(self.repository_format, remote.RemoteRepositoryFormat):
413
            return # local conversion to/from RemoteObjects is irrelevant.
1910.2.36 by Aaron Bentley
Get upgrade from format4 under test and fixed for all formats
414
        self.build_tree_contents(_upgrade_dir_template)
415
        old_repodir = bzrlib.bzrdir.BzrDir.open_unsupported('.')
416
        old_repo_format = old_repodir.open_repository()._format
417
        format = self.repository_format._matchingbzrdir
418
        try:
419
            format.repository_format = self.repository_format
420
        except AttributeError:
421
            pass
422
        upgrade('.', format)
423
1910.2.37 by Aaron Bentley
Handle empty commits, fix test
424
    def test_pointless_commit(self):
425
        tree = self.make_branch_and_tree('.')
426
        self.assertRaises(errors.PointlessCommit, tree.commit, 'pointless',
427
                          allow_pointless=False)
428
        tree.commit('pointless', allow_pointless=True)
429
2323.5.17 by Martin Pool
Add supports_tree_reference to all repo formats (robert)
430
    def test_format_attributes(self):
431
        """All repository formats should have some basic attributes."""
432
        # create a repository to get a real format instance, not the 
433
        # template from the test suite parameterisation.
434
        repo = self.make_repository('.')
435
        repo._format.rich_root_data
436
        repo._format.supports_tree_reference
437
2520.4.113 by Aaron Bentley
Avoid peeking at Repository._serializer
438
    def test_get_serializer_format(self):
439
        repo = self.make_repository('.')
440
        format = repo.get_serializer_format()
441
        self.assertEqual(repo._serializer.format_num, format)
442
1852.9.6 by Robert Collins
Merge the change from Tree.compare to Tree.changes_from.
443
2018.5.75 by Andrew Bennetts
Add Repository.{dont_,}leave_lock_in_place.
444
class TestRepositoryLocking(TestCaseWithRepository):
445
446
    def test_leave_lock_in_place(self):
447
        repo = self.make_repository('r')
448
        # Lock the repository, then use leave_lock_in_place so that when we
449
        # unlock the repository the lock is still held on disk.
2018.5.76 by Andrew Bennetts
Testing that repository.{dont_,}leave_lock_in_place raises NotImplementedError if lock_write returns None.
450
        token = repo.lock_write()
2018.5.75 by Andrew Bennetts
Add Repository.{dont_,}leave_lock_in_place.
451
        try:
2018.5.76 by Andrew Bennetts
Testing that repository.{dont_,}leave_lock_in_place raises NotImplementedError if lock_write returns None.
452
            if token is None:
453
                # This test does not apply, because this repository refuses lock
454
                # tokens.
455
                self.assertRaises(NotImplementedError, repo.leave_lock_in_place)
2018.5.75 by Andrew Bennetts
Add Repository.{dont_,}leave_lock_in_place.
456
                return
2018.5.76 by Andrew Bennetts
Testing that repository.{dont_,}leave_lock_in_place raises NotImplementedError if lock_write returns None.
457
            repo.leave_lock_in_place()
2018.5.75 by Andrew Bennetts
Add Repository.{dont_,}leave_lock_in_place.
458
        finally:
459
            repo.unlock()
460
        # We should be unable to relock the repo.
461
        self.assertRaises(errors.LockContention, repo.lock_write)
462
463
    def test_dont_leave_lock_in_place(self):
464
        repo = self.make_repository('r')
465
        # Create a lock on disk.
466
        token = repo.lock_write()
467
        try:
468
            if token is None:
469
                # This test does not apply, because this repository refuses lock
470
                # tokens.
2018.5.76 by Andrew Bennetts
Testing that repository.{dont_,}leave_lock_in_place raises NotImplementedError if lock_write returns None.
471
                self.assertRaises(NotImplementedError,
472
                                  repo.dont_leave_lock_in_place)
2018.5.75 by Andrew Bennetts
Add Repository.{dont_,}leave_lock_in_place.
473
                return
474
            try:
475
                repo.leave_lock_in_place()
476
            except NotImplementedError:
477
                # This repository doesn't support this API.
478
                return
479
        finally:
480
            repo.unlock()
481
        # Reacquire the lock (with a different repository object) by using the
482
        # token.
483
        new_repo = repo.bzrdir.open_repository()
484
        new_repo.lock_write(token=token)
485
        # Call dont_leave_lock_in_place, so that the lock will be released by
486
        # this instance, even though the lock wasn't originally acquired by it.
487
        new_repo.dont_leave_lock_in_place()
488
        new_repo.unlock()
489
        # Now the repository is unlocked.  Test this by locking it (without a
490
        # token).
491
        repo.lock_write()
492
        repo.unlock()
493
2018.5.78 by Andrew Bennetts
Implement RemoteRepository.lock_write/unlock to expect and send tokens over the
494
    def test_lock_read_then_unlock(self):
495
        # Calling lock_read then unlocking should work without errors.
496
        repo = self.make_repository('r')
497
        repo.lock_read()
498
        repo.unlock()
499
2018.5.75 by Andrew Bennetts
Add Repository.{dont_,}leave_lock_in_place.
500
1534.4.41 by Robert Collins
Branch now uses BzrDir reasonably sanely.
501
class TestCaseWithComplexRepository(TestCaseWithRepository):
502
503
    def setUp(self):
504
        super(TestCaseWithComplexRepository, self).setUp()
505
        tree_a = self.make_branch_and_tree('a')
506
        self.bzrdir = tree_a.branch.bzrdir
507
        # add a corrupt inventory 'orphan'
1534.1.34 by Robert Collins
Move missing_revision_ids from Repository to InterRepository, and eliminate the now unused Repository._compatible_formats method.
508
        # this may need some generalising for knits.
1563.2.10 by Robert Collins
Change weave store to be a versioned store, using WeaveFiles which maintain integrity without needing explicit 'put' operations.
509
        inv_file = tree_a.branch.repository.control_weaves.get_weave(
510
            'inventory', 
1534.4.41 by Robert Collins
Branch now uses BzrDir reasonably sanely.
511
            tree_a.branch.repository.get_transaction())
1563.2.10 by Robert Collins
Change weave store to be a versioned store, using WeaveFiles which maintain integrity without needing explicit 'put' operations.
512
        inv_file.add_lines('orphan', [], [])
1534.4.41 by Robert Collins
Branch now uses BzrDir reasonably sanely.
513
        # add a real revision 'rev1'
514
        tree_a.commit('rev1', rev_id='rev1', allow_pointless=True)
515
        # add a real revision 'rev2' based on rev1
516
        tree_a.commit('rev2', rev_id='rev2', allow_pointless=True)
1594.2.3 by Robert Collins
bugfix revision.MultipleRevisionSources.get_revision_graph to integrate ghosts between sources. [slow on weaves, fast on knits.
517
        # add a reference to a ghost
1908.6.7 by Robert Collins
Remove all users of set_pending_merges and add_pending_merge except tests that they work correctly.
518
        tree_a.add_parent_tree_id('ghost1')
1594.2.3 by Robert Collins
bugfix revision.MultipleRevisionSources.get_revision_graph to integrate ghosts between sources. [slow on weaves, fast on knits.
519
        tree_a.commit('rev3', rev_id='rev3', allow_pointless=True)
520
        # add another reference to a ghost, and a second ghost.
1908.6.7 by Robert Collins
Remove all users of set_pending_merges and add_pending_merge except tests that they work correctly.
521
        tree_a.add_parent_tree_id('ghost1')
522
        tree_a.add_parent_tree_id('ghost2')
1594.2.3 by Robert Collins
bugfix revision.MultipleRevisionSources.get_revision_graph to integrate ghosts between sources. [slow on weaves, fast on knits.
523
        tree_a.commit('rev4', rev_id='rev4', allow_pointless=True)
1534.4.41 by Robert Collins
Branch now uses BzrDir reasonably sanely.
524
1756.3.20 by Aaron Bentley
Tests for get_revision_deltas and revisions_trees
525
    def test_revision_trees(self):
526
        revision_ids = ['rev1', 'rev2', 'rev3', 'rev4']
527
        repository = self.bzrdir.open_repository()
528
        trees1 = list(repository.revision_trees(revision_ids))
529
        trees2 = [repository.revision_tree(t) for t in revision_ids]
530
        assert len(trees1) == len(trees2)
531
        for tree1, tree2 in zip(trees1, trees2):
1852.10.3 by Robert Collins
Remove all uses of compare_trees and replace with Tree.changes_from throughout bzrlib.
532
            assert not tree2.changes_from(tree1).has_changed()
1756.3.20 by Aaron Bentley
Tests for get_revision_deltas and revisions_trees
533
1756.3.22 by Aaron Bentley
Tweaks from review
534
    def test_get_deltas_for_revisions(self):
1756.3.20 by Aaron Bentley
Tests for get_revision_deltas and revisions_trees
535
        repository = self.bzrdir.open_repository()
536
        revisions = [repository.get_revision(r) for r in 
537
                     ['rev1', 'rev2', 'rev3', 'rev4']]
1756.3.22 by Aaron Bentley
Tweaks from review
538
        deltas1 = list(repository.get_deltas_for_revisions(revisions))
1756.3.20 by Aaron Bentley
Tests for get_revision_deltas and revisions_trees
539
        deltas2 = [repository.get_revision_delta(r.revision_id) for r in
540
                   revisions]
541
        assert deltas1 == deltas2
542
1534.4.41 by Robert Collins
Branch now uses BzrDir reasonably sanely.
543
    def test_all_revision_ids(self):
544
        # all_revision_ids -> all revisions
1594.2.3 by Robert Collins
bugfix revision.MultipleRevisionSources.get_revision_graph to integrate ghosts between sources. [slow on weaves, fast on knits.
545
        self.assertEqual(['rev1', 'rev2', 'rev3', 'rev4'],
1534.4.50 by Robert Collins
Got the bzrdir api straightened out, plenty of refactoring to use it pending, but the api is up and running.
546
                         self.bzrdir.open_repository().all_revision_ids())
547
1534.4.41 by Robert Collins
Branch now uses BzrDir reasonably sanely.
548
    def test_get_ancestry_missing_revision(self):
1534.1.34 by Robert Collins
Move missing_revision_ids from Repository to InterRepository, and eliminate the now unused Repository._compatible_formats method.
549
        # get_ancestry(revision that is in some data but not fully installed
550
        # -> NoSuchRevision
1534.4.41 by Robert Collins
Branch now uses BzrDir reasonably sanely.
551
        self.assertRaises(errors.NoSuchRevision,
552
                          self.bzrdir.open_repository().get_ancestry, 'orphan')
1570.1.13 by Robert Collins
Check for incorrect revision parentage in the weave during revision access.
553
2530.1.1 by Aaron Bentley
Make topological sorting optional for get_ancestry
554
    def test_get_unsorted_ancestry(self):
555
        repo = self.bzrdir.open_repository()
556
        self.assertEqual(set(repo.get_ancestry('rev3')),
557
                         set(repo.get_ancestry('rev3', topo_sorted=False)))
558
1590.1.1 by Robert Collins
Improve common_ancestor performance.
559
    def test_get_revision_graph(self):
560
        # we can get a mapping of id->parents for the entire revision graph or bits thereof.
2625.8.1 by Robert Collins
LIBRARY API BREAKS:
561
        self.assertEqual({'rev1':(),
562
                          'rev2':('rev1', ),
563
                          'rev3':('rev2', ),
564
                          'rev4':('rev3', ),
1594.2.3 by Robert Collins
bugfix revision.MultipleRevisionSources.get_revision_graph to integrate ghosts between sources. [slow on weaves, fast on knits.
565
                          },
1590.1.1 by Robert Collins
Improve common_ancestor performance.
566
                         self.bzrdir.open_repository().get_revision_graph(None))
2625.8.1 by Robert Collins
LIBRARY API BREAKS:
567
        self.assertEqual({'rev1':()},
1590.1.1 by Robert Collins
Improve common_ancestor performance.
568
                         self.bzrdir.open_repository().get_revision_graph('rev1'))
2625.8.1 by Robert Collins
LIBRARY API BREAKS:
569
        self.assertEqual({'rev1':(),
570
                          'rev2':('rev1', )},
1590.1.1 by Robert Collins
Improve common_ancestor performance.
571
                         self.bzrdir.open_repository().get_revision_graph('rev2'))
2279.7.9 by Andrew Bennetts
Remove some redundant code pointed out by Robert's review, and remove some unused imports while I'm there.
572
        self.assertRaises(errors.NoSuchRevision,
1590.1.1 by Robert Collins
Improve common_ancestor performance.
573
                          self.bzrdir.open_repository().get_revision_graph,
574
                          'orphan')
1594.2.3 by Robert Collins
bugfix revision.MultipleRevisionSources.get_revision_graph to integrate ghosts between sources. [slow on weaves, fast on knits.
575
        # and ghosts are not mentioned
2625.8.1 by Robert Collins
LIBRARY API BREAKS:
576
        self.assertEqual({'rev1':(),
577
                          'rev2':('rev1', ),
578
                          'rev3':('rev2', ),
1594.2.3 by Robert Collins
bugfix revision.MultipleRevisionSources.get_revision_graph to integrate ghosts between sources. [slow on weaves, fast on knits.
579
                          },
580
                         self.bzrdir.open_repository().get_revision_graph('rev3'))
1836.3.1 by Robert Collins
(robertc) Teach repository.get_revision_graph, and revision.common_ancestor, about NULL_REVISION.
581
        # and we can ask for the NULLREVISION graph
582
        self.assertEqual({},
583
            self.bzrdir.open_repository().get_revision_graph(NULL_REVISION))
1594.2.3 by Robert Collins
bugfix revision.MultipleRevisionSources.get_revision_graph to integrate ghosts between sources. [slow on weaves, fast on knits.
584
585
    def test_get_revision_graph_with_ghosts(self):
586
        # we can get a graph object with roots, ghosts, ancestors and
587
        # descendants.
588
        repo = self.bzrdir.open_repository()
589
        graph = repo.get_revision_graph_with_ghosts([])
590
        self.assertEqual(set(['rev1']), graph.roots)
591
        self.assertEqual(set(['ghost1', 'ghost2']), graph.ghosts)
592
        self.assertEqual({'rev1':[],
593
                          'rev2':['rev1'],
594
                          'rev3':['rev2', 'ghost1'],
595
                          'rev4':['rev3', 'ghost1', 'ghost2'],
596
                          },
597
                          graph.get_ancestors())
598
        self.assertEqual({'ghost1':{'rev3':1, 'rev4':1},
599
                          'ghost2':{'rev4':1},
600
                          'rev1':{'rev2':1},
601
                          'rev2':{'rev3':1},
602
                          'rev3':{'rev4':1},
603
                          'rev4':{},
604
                          },
605
                          graph.get_descendants())
1836.3.1 by Robert Collins
(robertc) Teach repository.get_revision_graph, and revision.common_ancestor, about NULL_REVISION.
606
        # and we can ask for the NULLREVISION graph
607
        graph = repo.get_revision_graph_with_ghosts([NULL_REVISION])
608
        self.assertEqual({}, graph.get_ancestors())
609
        self.assertEqual({}, graph.get_descendants())
1590.1.1 by Robert Collins
Improve common_ancestor performance.
610
2229.2.1 by Aaron Bentley
Reject reserved ids in versiondfile, tree, branch and repository
611
    def test_reserved_id(self):
612
        repo = self.make_repository('repository')
613
        self.assertRaises(errors.ReservedId, repo.add_inventory, 'reserved:',
614
                          None, None)
615
        self.assertRaises(errors.ReservedId, repo.add_revision, 'reserved:',
616
                          None)
2229.2.3 by Aaron Bentley
change reserved_id to is_reserved_id, add check_not_reserved for DRY
617
1570.1.13 by Robert Collins
Check for incorrect revision parentage in the weave during revision access.
618
619
class TestCaseWithCorruptRepository(TestCaseWithRepository):
620
621
    def setUp(self):
622
        super(TestCaseWithCorruptRepository, self).setUp()
623
        # a inventory with no parents and the revision has parents..
624
        # i.e. a ghost.
625
        repo = self.make_repository('inventory_with_unnecessary_ghost')
2617.6.4 by Robert Collins
Update tests with things that break when a repository requires write groups to be used.
626
        repo.lock_write()
627
        repo.start_write_group()
1910.2.23 by Aaron Bentley
Fix up test cases that manually construct inventories
628
        inv = Inventory(revision_id = 'ghost')
629
        inv.root.revision = 'ghost'
1907.1.1 by Aaron Bentley
Unshelved all changes except those related to removing RootEntry
630
        sha1 = repo.add_inventory('ghost', inv, [])
1570.1.13 by Robert Collins
Check for incorrect revision parentage in the weave during revision access.
631
        rev = bzrlib.revision.Revision(timestamp=0,
632
                                       timezone=None,
633
                                       committer="Foo Bar <foo@example.com>",
634
                                       message="Message",
635
                                       inventory_sha1=sha1,
636
                                       revision_id='ghost')
637
        rev.parent_ids = ['the_ghost']
638
        repo.add_revision('ghost', rev)
639
         
1910.2.23 by Aaron Bentley
Fix up test cases that manually construct inventories
640
        inv = Inventory(revision_id = 'the_ghost')
641
        inv.root.revision = 'the_ghost'
1907.1.1 by Aaron Bentley
Unshelved all changes except those related to removing RootEntry
642
        sha1 = repo.add_inventory('the_ghost', inv, [])
1570.1.13 by Robert Collins
Check for incorrect revision parentage in the weave during revision access.
643
        rev = bzrlib.revision.Revision(timestamp=0,
644
                                       timezone=None,
645
                                       committer="Foo Bar <foo@example.com>",
646
                                       message="Message",
647
                                       inventory_sha1=sha1,
648
                                       revision_id='the_ghost')
649
        rev.parent_ids = []
650
        repo.add_revision('the_ghost', rev)
651
        # check its setup usefully
652
        inv_weave = repo.get_inventory_weave()
1563.2.30 by Robert Collins
Remove all but fetch references to revision_store, making the repository references that are weave specific use the RevisionTextStore.text_store attribute.
653
        self.assertEqual(['ghost'], inv_weave.get_ancestry(['ghost']))
2617.6.4 by Robert Collins
Update tests with things that break when a repository requires write groups to be used.
654
        repo.commit_write_group()
655
        repo.unlock()
1570.1.13 by Robert Collins
Check for incorrect revision parentage in the weave during revision access.
656
1594.2.10 by Robert Collins
Teach knit fetching and branching to only duplicate relevant data avoiding unnecessary reconciles.
657
    def test_corrupt_revision_access_asserts_if_reported_wrong(self):
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
658
        repo_url = self.get_url('inventory_with_unnecessary_ghost')
659
        repo = repository.Repository.open(repo_url)
1594.2.10 by Robert Collins
Teach knit fetching and branching to only duplicate relevant data avoiding unnecessary reconciles.
660
        reported_wrong = False
661
        try:
662
            if repo.get_ancestry('ghost') != [None, 'the_ghost', 'ghost']:
663
                reported_wrong = True
664
        except errors.CorruptRepository:
665
            # caught the bad data:
666
            return
667
        if not reported_wrong:
668
            return
1570.1.13 by Robert Collins
Check for incorrect revision parentage in the weave during revision access.
669
        self.assertRaises(errors.CorruptRepository, repo.get_revision, 'ghost')
670
1594.2.3 by Robert Collins
bugfix revision.MultipleRevisionSources.get_revision_graph to integrate ghosts between sources. [slow on weaves, fast on knits.
671
    def test_corrupt_revision_get_revision_reconcile(self):
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
672
        repo_url = self.get_url('inventory_with_unnecessary_ghost')
673
        repo = repository.Repository.open(repo_url)
1570.1.13 by Robert Collins
Check for incorrect revision parentage in the weave during revision access.
674
        repo.get_revision_reconcile('ghost')
1986.1.1 by Robert Collins
Move test_branch_on_vfat into a repository implementation test, to ensure that all repository formats are safe on vfat.
675
676
2018.5.29 by Robert Collins
Dont run the vfat repository test on RemoteRepositories as there is no point.
677
# FIXME: document why this is a TestCaseWithTransport rather than a
678
#        TestCaseWithRepository
1986.1.1 by Robert Collins
Move test_branch_on_vfat into a repository implementation test, to ensure that all repository formats are safe on vfat.
679
class TestEscaping(TestCaseWithTransport):
680
    """Test that repositories can be stored correctly on VFAT transports.
681
    
682
    Makes sure we have proper escaping of invalid characters, etc.
683
684
    It'd be better to test all operations on the FakeVFATTransportDecorator,
685
    but working trees go straight to the os not through the Transport layer.
686
    Therefore we build some history first in the regular way and then 
687
    check it's safe to access for vfat.
688
    """
689
690
    def test_on_vfat(self):
2018.5.29 by Robert Collins
Dont run the vfat repository test on RemoteRepositories as there is no point.
691
        # dont bother with remote repository testing, because this test is
692
        # about local disk layout/support.
693
        from bzrlib.remote import RemoteRepositoryFormat
694
        if isinstance(self.repository_format, RemoteRepositoryFormat):
695
            return
1986.1.1 by Robert Collins
Move test_branch_on_vfat into a repository implementation test, to ensure that all repository formats are safe on vfat.
696
        FOO_ID = 'foo<:>ID'
2018.5.29 by Robert Collins
Dont run the vfat repository test on RemoteRepositories as there is no point.
697
        REV_ID = 'revid-1' 
698
        # this makes a default format repository always, which is wrong: 
699
        # it should be a TestCaseWithRepository in order to get the 
700
        # default format.
1986.1.1 by Robert Collins
Move test_branch_on_vfat into a repository implementation test, to ensure that all repository formats are safe on vfat.
701
        wt = self.make_branch_and_tree('repo')
2052.2.1 by Alexander Belchenko
test_on_vfat win32 fix: use binary line-endings
702
        self.build_tree(["repo/foo"], line_endings='binary')
1986.1.1 by Robert Collins
Move test_branch_on_vfat into a repository implementation test, to ensure that all repository formats are safe on vfat.
703
        # add file with id containing wierd characters
704
        wt.add(['foo'], [FOO_ID])
705
        wt.commit('this is my new commit', rev_id=REV_ID)
706
        # now access over vfat; should be safe
707
        branch = bzrdir.BzrDir.open('vfat+' + self.get_url('repo')).open_branch()
708
        revtree = branch.repository.revision_tree(REV_ID)
709
        contents = revtree.get_file_text(FOO_ID)
710
        self.assertEqual(contents, 'contents of repo/foo\n')
2520.4.54 by Aaron Bentley
Hang a create_bundle method off repository
711
712
    def test_create_bundle(self):
713
        wt = self.make_branch_and_tree('repo')
714
        self.build_tree(['repo/file1'])
715
        wt.add('file1')
716
        wt.commit('file1', rev_id='rev1')
717
        fileobj = StringIO()
718
        wt.branch.repository.create_bundle('rev1', NULL_REVISION, fileobj)