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