/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
2052.3.1 by John Arbash Meinel
Add tests to cleanup the copyright of all source files
1
# Copyright (C) 2005, 2006 Canonical Ltd
1887.1.1 by Adeodato Simó
Do not separate paragraphs in the copyright statement with blank lines,
2
#
1534.1.29 by Robert Collins
Add a test environment for InterRepository objects, and remove the fetch corner case tests from test_repository.
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.1.29 by Robert Collins
Add a test environment for InterRepository objects, and remove the fetch corner case tests from test_repository.
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.1.29 by Robert Collins
Add a test environment for InterRepository objects, and remove the fetch corner case tests from test_repository.
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 InterRepository implementastions."""
18
1711.7.18 by John Arbash Meinel
Old repository formats didn't support double locking on win32, don't raise errors
19
import sys
1534.1.29 by Robert Collins
Add a test environment for InterRepository objects, and remove the fetch corner case tests from test_repository.
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
1534.1.29 by Robert Collins
Add a test environment for InterRepository objects, and remove the fetch corner case tests from test_repository.
22
import bzrlib.bzrdir as bzrdir
23
from bzrlib.branch import Branch, needs_read_lock, needs_write_lock
24
import bzrlib.errors as errors
25
from bzrlib.errors import (FileExists,
26
                           NoSuchRevision,
27
                           NoSuchFile,
28
                           UninitializableFormat,
29
                           NotBranchError,
30
                           )
1731.1.1 by Aaron Bentley
Make root entry an InventoryDirectory, make EmptyTree really empty
31
from bzrlib.inventory import Inventory
1534.1.29 by Robert Collins
Add a test environment for InterRepository objects, and remove the fetch corner case tests from test_repository.
32
import bzrlib.repository as repository
1694.2.6 by Martin Pool
[merge] bzr.dev
33
from bzrlib.revision import NULL_REVISION, Revision
1534.1.29 by Robert Collins
Add a test environment for InterRepository objects, and remove the fetch corner case tests from test_repository.
34
from bzrlib.tests import TestCase, TestCaseWithTransport, TestSkipped
35
from bzrlib.tests.bzrdir_implementations.test_bzrdir import TestCaseWithBzrDir
36
from bzrlib.transport import get_transport
37
38
39
class TestCaseWithInterRepository(TestCaseWithBzrDir):
40
41
    def setUp(self):
42
        super(TestCaseWithInterRepository, self).setUp()
43
1666.1.4 by Robert Collins
* 'Metadir' is now the default disk format. This improves behaviour in
44
    def make_branch(self, relpath, format=None):
45
        repo = self.make_repository(relpath, format=format)
1534.1.29 by Robert Collins
Add a test environment for InterRepository objects, and remove the fetch corner case tests from test_repository.
46
        return repo.bzrdir.create_branch()
47
1666.1.4 by Robert Collins
* 'Metadir' is now the default disk format. This improves behaviour in
48
    def make_bzrdir(self, relpath, format=None):
1534.1.29 by Robert Collins
Add a test environment for InterRepository objects, and remove the fetch corner case tests from test_repository.
49
        try:
50
            url = self.get_url(relpath)
51
            segments = url.split('/')
52
            if segments and segments[-1] not in ('', '.'):
53
                parent = '/'.join(segments[:-1])
54
                t = get_transport(parent)
55
                try:
56
                    t.mkdir(segments[-1])
57
                except FileExists:
58
                    pass
1666.1.4 by Robert Collins
* 'Metadir' is now the default disk format. This improves behaviour in
59
            if format is None:
60
                format = self.repository_format._matchingbzrdir
61
            return format.initialize(url)
1534.1.29 by Robert Collins
Add a test environment for InterRepository objects, and remove the fetch corner case tests from test_repository.
62
        except UninitializableFormat:
1684.1.4 by Martin Pool
(patch) better warnings when tests are skipped (Alexander)
63
            raise TestSkipped("Format %s is not initializable." % format)
1534.1.29 by Robert Collins
Add a test environment for InterRepository objects, and remove the fetch corner case tests from test_repository.
64
1666.1.4 by Robert Collins
* 'Metadir' is now the default disk format. This improves behaviour in
65
    def make_repository(self, relpath, format=None):
66
        made_control = self.make_bzrdir(relpath, format=format)
1534.1.29 by Robert Collins
Add a test environment for InterRepository objects, and remove the fetch corner case tests from test_repository.
67
        return self.repository_format.initialize(made_control)
68
69
    def make_to_repository(self, relpath):
70
        made_control = self.make_bzrdir(relpath,
71
            self.repository_format_to._matchingbzrdir)
1534.1.30 by Robert Collins
Test that we get the right optimiser back in the InterRepository tests.
72
        return self.repository_format_to.initialize(made_control)
1534.1.29 by Robert Collins
Add a test environment for InterRepository objects, and remove the fetch corner case tests from test_repository.
73
74
1711.7.18 by John Arbash Meinel
Old repository formats didn't support double locking on win32, don't raise errors
75
def check_old_format_lock_error(repository_format):
76
    """Potentially ignore LockError on old formats.
77
78
    On win32, with the old OS locks, we get a failure of double-lock when
79
    we open a object in 2 objects and try to lock both.
80
81
    On new formats, LockError would be invalid, but for old formats
82
    this was not supported on Win32.
83
    """
84
    if sys.platform != 'win32':
85
        raise
86
87
    description = repository_format.get_format_description()
88
    if description in ("Repository format 4",
89
                       "Weave repository format 5",
90
                       "Weave repository format 6"):
1711.7.30 by John Arbash Meinel
Switch to using TestSkipped for old win32 problems
91
        # jam 20060701
92
        # win32 OS locks are not re-entrant. So one process cannot
93
        # open the same repository twice and lock them both.
94
        raise TestSkipped('%s on win32 cannot open the same'
95
                          ' repository twice in different objects'
96
                          % description)
1711.7.18 by John Arbash Meinel
Old repository formats didn't support double locking on win32, don't raise errors
97
    raise
98
99
2240.1.3 by Alexander Belchenko
win32: skip tests that try to use funky chars in fileid in Weave-based repositories
100
def check_repo_format_for_funky_id_on_win32(repo):
101
    if sys.platform == 'win32':
102
        if isinstance(repo, (repository.AllInOneRepository,
103
                             repository.WeaveMetaDirRepository)):
104
            raise TestSkipped("funky chars does not permitted"
105
                              " on this platform in repository"
106
                              " %s" % repo.__class__.__name__)
107
108
1534.1.29 by Robert Collins
Add a test environment for InterRepository objects, and remove the fetch corner case tests from test_repository.
109
class TestInterRepository(TestCaseWithInterRepository):
110
1534.1.30 by Robert Collins
Test that we get the right optimiser back in the InterRepository tests.
111
    def test_interrepository_get_returns_correct_optimiser(self):
112
        # we assume the optimising code paths are triggered
113
        # by the type of the repo not the transport - at this point.
114
        # we may need to update this test if this changes.
115
        source_repo = self.make_repository("source")
116
        target_repo = self.make_to_repository("target")
117
        interrepo = repository.InterRepository.get(source_repo, target_repo)
118
        self.assertEqual(self.interrepo_class, interrepo.__class__)
119
1534.1.29 by Robert Collins
Add a test environment for InterRepository objects, and remove the fetch corner case tests from test_repository.
120
    def test_fetch(self):
121
        tree_a = self.make_branch_and_tree('a')
122
        self.build_tree(['a/foo'])
123
        tree_a.add('foo', 'file1')
124
        tree_a.commit('rev1', rev_id='rev1')
125
        def check_push_rev1(repo):
126
            # ensure the revision is missing.
127
            self.assertRaises(NoSuchRevision, repo.get_revision, 'rev1')
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.
128
            # fetch with a limit of NULL_REVISION and an explicit progress bar.
129
            repo.fetch(tree_a.branch.repository,
130
                       revision_id=NULL_REVISION,
131
                       pb=bzrlib.progress.DummyProgress())
1534.1.29 by Robert Collins
Add a test environment for InterRepository objects, and remove the fetch corner case tests from test_repository.
132
            # nothing should have been pushed
133
            self.assertFalse(repo.has_revision('rev1'))
134
            # fetch with a default limit (grab everything)
135
            repo.fetch(tree_a.branch.repository)
136
            # check that b now has all the data from a's first commit.
137
            rev = repo.get_revision('rev1')
138
            tree = repo.revision_tree('rev1')
139
            tree.get_file_text('file1')
140
            for file_id in tree:
141
                if tree.inventory[file_id].kind == "file":
142
                    tree.get_file(file_id).read()
143
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.
144
        # makes a target version repo 
145
        repo_b = self.make_to_repository('b')
1534.1.29 by Robert Collins
Add a test environment for InterRepository objects, and remove the fetch corner case tests from test_repository.
146
        check_push_rev1(repo_b)
147
        
148
    def test_fetch_missing_revision_same_location_fails(self):
149
        repo_a = self.make_repository('.')
150
        repo_b = repository.Repository.open('.')
1711.7.18 by John Arbash Meinel
Old repository formats didn't support double locking on win32, don't raise errors
151
        try:
152
            self.assertRaises(errors.NoSuchRevision, repo_b.fetch, repo_a, revision_id='XXX')
153
        except errors.LockError, e:
154
            check_old_format_lock_error(self.repository_format)
1534.1.29 by Robert Collins
Add a test environment for InterRepository objects, and remove the fetch corner case tests from test_repository.
155
156
    def test_fetch_same_location_trivial_works(self):
157
        repo_a = self.make_repository('.')
158
        repo_b = repository.Repository.open('.')
1711.7.18 by John Arbash Meinel
Old repository formats didn't support double locking on win32, don't raise errors
159
        try:
160
            repo_a.fetch(repo_b)
161
        except errors.LockError, e:
162
            check_old_format_lock_error(self.repository_format)
1534.1.34 by Robert Collins
Move missing_revision_ids from Repository to InterRepository, and eliminate the now unused Repository._compatible_formats method.
163
1694.2.6 by Martin Pool
[merge] bzr.dev
164
    def test_fetch_missing_text_other_location_fails(self):
165
        source_tree = self.make_branch_and_tree('source')
166
        source = source_tree.branch.repository
167
        target = self.make_to_repository('target')
168
    
169
        # start by adding a file so the data for hte file exists.
170
        self.build_tree(['source/id'])
171
        source_tree.add(['id'], ['id'])
172
        source_tree.commit('a', rev_id='a')
173
        # now we manually insert a revision with an inventory referencing
174
        # 'id' at revision 'b', but we do not insert revision b.
175
        # this should ensure that the new versions of files are being checked
176
        # for during pull operations
177
        inv = source.get_inventory('a')
178
        inv['id'].revision = 'b'
1740.2.6 by Aaron Bentley
Update test for new interface
179
        inv.revision_id = 'b'
1694.2.6 by Martin Pool
[merge] bzr.dev
180
        sha1 = source.add_inventory('b', inv, ['a'])
181
        rev = Revision(timestamp=0,
182
                       timezone=None,
183
                       committer="Foo Bar <foo@example.com>",
184
                       message="Message",
185
                       inventory_sha1=sha1,
186
                       revision_id='b')
187
        rev.parent_ids = ['a']
188
        source.add_revision('b', rev)
189
        self.assertRaises(errors.RevisionNotPresent, target.fetch, source)
190
        self.assertFalse(target.has_revision('b'))
191
1843.2.1 by Aaron Bentley
Add failing tests for funky ids
192
    def test_fetch_funky_file_id(self):
193
        from_tree = self.make_branch_and_tree('tree')
2240.1.3 by Alexander Belchenko
win32: skip tests that try to use funky chars in fileid in Weave-based repositories
194
        if sys.platform == 'win32':
195
            from_repo = from_tree.branch.repository
196
            check_repo_format_for_funky_id_on_win32(from_repo)
1843.2.1 by Aaron Bentley
Add failing tests for funky ids
197
        self.build_tree(['tree/filename'])
198
        from_tree.add('filename', 'funky-chars<>%&;"\'')
199
        from_tree.commit('commit filename')
200
        to_repo = self.make_to_repository('to')
1908.7.6 by Robert Collins
Deprecate WorkingTree.last_revision.
201
        to_repo.fetch(from_tree.branch.repository, from_tree.get_parent_ids()[0])
1843.2.1 by Aaron Bentley
Add failing tests for funky ids
202
1910.8.1 by Aaron Bentley
Handle inventories with no revision_ids
203
    def test_fetch_no_inventory_revision(self):
204
        """Old inventories lack revision_ids, so simulate this"""
205
        from_tree = self.make_branch_and_tree('tree')
2240.1.3 by Alexander Belchenko
win32: skip tests that try to use funky chars in fileid in Weave-based repositories
206
        if sys.platform == 'win32':
207
            from_repo = from_tree.branch.repository
208
            check_repo_format_for_funky_id_on_win32(from_repo)
1910.8.1 by Aaron Bentley
Handle inventories with no revision_ids
209
        self.build_tree(['tree/filename'])
210
        from_tree.add('filename', 'funky-chars<>%&;"\'')
211
        from_tree.commit('commit filename')
212
        old_deserialise = from_tree.branch.repository.deserialise_inventory
213
        def deserialise(revision_id, text):
214
            inventory = old_deserialise(revision_id, text)
215
            inventory.revision_id = None
216
            return inventory
217
        from_tree.branch.repository.deserialise_inventory = deserialise
218
        to_repo = self.make_to_repository('to')
219
        to_repo.fetch(from_tree.branch.repository, from_tree.last_revision())
220
1534.1.34 by Robert Collins
Move missing_revision_ids from Repository to InterRepository, and eliminate the now unused Repository._compatible_formats method.
221
222
class TestCaseWithComplexRepository(TestCaseWithInterRepository):
223
224
    def setUp(self):
225
        super(TestCaseWithComplexRepository, self).setUp()
226
        tree_a = self.make_branch_and_tree('a')
227
        self.bzrdir = tree_a.branch.bzrdir
228
        # add a corrupt inventory 'orphan'
1563.2.10 by Robert Collins
Change weave store to be a versioned store, using WeaveFiles which maintain integrity without needing explicit 'put' operations.
229
        inv_file = tree_a.branch.repository.control_weaves.get_weave(
230
            'inventory', 
1534.1.34 by Robert Collins
Move missing_revision_ids from Repository to InterRepository, and eliminate the now unused Repository._compatible_formats method.
231
            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.
232
        inv_file.add_lines('orphan', [], [])
1534.1.34 by Robert Collins
Move missing_revision_ids from Repository to InterRepository, and eliminate the now unused Repository._compatible_formats method.
233
        # add a real revision 'rev1'
234
        tree_a.commit('rev1', rev_id='rev1', allow_pointless=True)
235
        # add a real revision 'rev2' based on rev1
236
        tree_a.commit('rev2', rev_id='rev2', allow_pointless=True)
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.
237
        # and sign 'rev2'
238
        tree_a.branch.repository.sign_revision('rev2',
239
            bzrlib.gpg.LoopbackGPGStrategy(None))
1534.1.34 by Robert Collins
Move missing_revision_ids from Repository to InterRepository, and eliminate the now unused Repository._compatible_formats method.
240
241
    def test_missing_revision_ids(self):
242
        # revision ids in repository A but not B are returned, fake ones
243
        # are stripped. (fake meaning no revision object, but an inventory 
244
        # as some formats keyed off inventory data in the past.
245
        # make a repository to compare against that claims to have rev1
246
        repo_b = self.make_to_repository('rev1_only')
247
        repo_a = self.bzrdir.open_repository()
248
        repo_b.fetch(repo_a, 'rev1')
249
        # check the test will be valid
250
        self.assertFalse(repo_b.has_revision('rev2'))
251
        self.assertEqual(['rev2'],
252
                         repo_b.missing_revision_ids(repo_a))
253
254
    def test_missing_revision_ids_revision_limited(self):
255
        # revision ids in repository A that are not referenced by the
256
        # requested revision are not returned.
257
        # make a repository to compare against that is empty
258
        repo_b = self.make_to_repository('empty')
259
        repo_a = self.bzrdir.open_repository()
260
        self.assertEqual(['rev1'],
261
                         repo_b.missing_revision_ids(repo_a, revision_id='rev1'))
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.
262
        
263
    def test_fetch_preserves_signatures(self):
264
        from_repo = self.bzrdir.open_repository()
1563.2.31 by Robert Collins
Convert Knit repositories to use knits.
265
        from_signature = from_repo.get_signature_text('rev2')
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.
266
        to_repo = self.make_to_repository('target')
267
        to_repo.fetch(from_repo)
1563.2.31 by Robert Collins
Convert Knit repositories to use knits.
268
        to_signature = to_repo.get_signature_text('rev2')
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.
269
        self.assertEqual(from_signature, to_signature)
270
1570.1.14 by Robert Collins
Enforce repository consistency during 'fetch' operations.
271
272
class TestCaseWithGhosts(TestCaseWithInterRepository):
273
274
    def setUp(self):
275
        super(TestCaseWithGhosts, self).setUp()
276
        # we want two repositories at this point
277
        # one with a revision that is a ghost in the other
278
        # repository.
279
280
        # 'ghost' is a ghost in missing_ghost and not in with_ghost_rev
1910.2.26 by Aaron Bentley
Fix up some test cases
281
        inv = Inventory(revision_id='ghost')
282
        inv.root.revision = 'ghost'
1570.1.14 by Robert Collins
Enforce repository consistency during 'fetch' operations.
283
        repo = self.make_repository('with_ghost_rev')
1907.1.1 by Aaron Bentley
Unshelved all changes except those related to removing RootEntry
284
        sha1 = repo.add_inventory('ghost', inv, [])
1570.1.14 by Robert Collins
Enforce repository consistency during 'fetch' operations.
285
        rev = bzrlib.revision.Revision(timestamp=0,
286
                                       timezone=None,
287
                                       committer="Foo Bar <foo@example.com>",
288
                                       message="Message",
289
                                       inventory_sha1=sha1,
290
                                       revision_id='ghost')
291
        rev.parent_ids = []
292
        repo.add_revision('ghost', rev)
293
         
294
        repo = self.make_to_repository('missing_ghost')
1910.2.26 by Aaron Bentley
Fix up some test cases
295
        inv = Inventory(revision_id='with_ghost')
296
        inv.root.revision = 'with_ghost'
1907.1.1 by Aaron Bentley
Unshelved all changes except those related to removing RootEntry
297
        sha1 = repo.add_inventory('with_ghost', inv, [])
1570.1.14 by Robert Collins
Enforce repository consistency during 'fetch' operations.
298
        rev = bzrlib.revision.Revision(timestamp=0,
299
                                       timezone=None,
300
                                       committer="Foo Bar <foo@example.com>",
301
                                       message="Message",
302
                                       inventory_sha1=sha1,
303
                                       revision_id='with_ghost')
304
        rev.parent_ids = ['ghost']
305
        repo.add_revision('with_ghost', rev)
306
307
    def test_fetch_all_fixes_up_ghost(self):
308
        # fetching from a repo with a current ghost unghosts it in referencing
309
        # revisions.
310
        repo = repository.Repository.open('missing_ghost')
311
        rev = repo.get_revision('with_ghost')
312
        from_repo = repository.Repository.open('with_ghost_rev')
313
        repo.fetch(from_repo)
314
        # rev must not be corrupt now
315
        rev = repo.get_revision('with_ghost')
316
        self.assertEqual([None, 'ghost', 'with_ghost'], repo.get_ancestry('with_ghost'))