/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
1534.4.39 by Robert Collins
Basic BzrDir support.
1
# (C) 2005, 2006 Canonical Ltd
2
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.
7
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.
12
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
1687.1.12 by Robert Collins
Hook in the full break-lock ui.
19
from cStringIO import StringIO
1534.4.39 by Robert Collins
Basic BzrDir support.
20
import os
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.
21
from stat import *
1534.4.39 by Robert Collins
Basic BzrDir support.
22
import sys
23
1508.1.25 by Robert Collins
Update per review comments.
24
import bzrlib.branch
1534.4.39 by Robert Collins
Basic BzrDir support.
25
import bzrlib.bzrdir as bzrdir
26
from bzrlib.branch import Branch, needs_read_lock, needs_write_lock
1534.5.11 by Robert Collins
Implement upgrades to Metaformat trees.
27
from bzrlib.check import check
1534.4.39 by Robert Collins
Basic BzrDir support.
28
from bzrlib.commit import commit
29
import bzrlib.errors as errors
30
from bzrlib.errors import (FileExists,
31
                           NoSuchRevision,
32
                           NoSuchFile,
33
                           UninitializableFormat,
34
                           NotBranchError,
35
                           )
1534.4.40 by Robert Collins
Add RepositoryFormats and allow bzrdir.open or create _repository to be used.
36
import bzrlib.repository as repository
1534.6.6 by Robert Collins
Move find_repository to bzrdir, its not quite ideal there but its simpler and until someone chooses to vary the search by branch type its completely sufficient.
37
from bzrlib.tests import (
38
                          ChrootedTestCase,
39
                          TestCase,
40
                          TestCaseWithTransport,
41
                          TestSkipped,
42
                          )
1534.4.39 by Robert Collins
Basic BzrDir support.
43
from bzrlib.trace import mutter
44
import bzrlib.transactions as transactions
1534.4.44 by Robert Collins
Make a new BzrDir format that uses a versioned branch format in a branch/ subdirectory.
45
import bzrlib.transport as transport
1534.4.39 by Robert Collins
Basic BzrDir support.
46
from bzrlib.transport import get_transport
1534.5.11 by Robert Collins
Implement upgrades to Metaformat trees.
47
import bzrlib.ui as ui
1534.4.39 by Robert Collins
Basic BzrDir support.
48
from bzrlib.upgrade import upgrade
1534.4.42 by Robert Collins
add working tree to the BzrDir facilities.
49
import bzrlib.workingtree as workingtree
1534.4.39 by Robert Collins
Basic BzrDir support.
50
51
52
class TestCaseWithBzrDir(TestCaseWithTransport):
53
54
    def setUp(self):
55
        super(TestCaseWithBzrDir, self).setUp()
56
        self.bzrdir = None
57
58
    def get_bzrdir(self):
59
        if self.bzrdir is None:
60
            self.bzrdir = self.make_bzrdir(None)
61
        return self.bzrdir
62
1666.1.4 by Robert Collins
* 'Metadir' is now the default disk format. This improves behaviour in
63
    def make_bzrdir(self, relpath, format=None):
64
        return super(TestCaseWithBzrDir, self).make_bzrdir(
65
            relpath, format=self.bzrdir_format)
66
1534.4.39 by Robert Collins
Basic BzrDir support.
67
68
69
class TestBzrDir(TestCaseWithBzrDir):
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.
70
    # Many of these tests test for disk equality rather than checking
71
    # for semantic equivalence. This works well for some tests but
72
    # is not good at handling changes in representation or the addition
73
    # or removal of control data. It would be nice to for instance:
74
    # sprout a new branch, check that the nickname has been reset by hand
75
    # and then set the nickname to match the source branch, at which point
76
    # a semantic equivalence should pass
77
78
    def assertDirectoriesEqual(self, source, target, ignore_list=[]):
79
        """Assert that the content of source and target are identical.
80
81
        paths in ignore list will be completely ignored.
1666.1.16 by Robert Collins
Fix occasional test failuresin bzrdir_implementations.
82
        
83
        We ignore paths that represent data which is allowed to change during
84
        a clone or sprout: for instance, inventory.knit contains gzip fragements
85
        which have timestamps in them, and as we have read the inventory from 
86
        the source knit, the already-read data is recompressed rather than
87
        reading it again, which leads to changed timestamps. This is ok though,
88
        because the inventory.kndx file is not ignored, and the integrity of
89
        knit joins is tested by test_knit and test_versionedfile.
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.
90
        """
91
        files = []
92
        directories = ['.']
93
        while directories:
94
            dir = directories.pop()
95
            for path in source.list_dir(dir):
96
                path = dir + '/' + path
97
                if path in ignore_list:
98
                    continue
99
                stat = source.stat(path)
100
                if S_ISDIR(stat.st_mode):
101
                    self.assertTrue(S_ISDIR(target.stat(path).st_mode))
102
                    directories.append(path)
103
                else:
104
                    self.assertEqualDiff(source.get(path).read(),
105
                                         target.get(path).read(),
106
                                         "text for file %r differs:\n" % path)
107
108
    def test_clone_bzrdir_empty(self):
109
        dir = self.make_bzrdir('source')
110
        target = dir.clone(self.get_url('target'))
111
        self.assertNotEqual(dir.transport.base, target.transport.base)
112
        self.assertDirectoriesEqual(dir.root_transport, target.root_transport)
113
    
1534.6.8 by Robert Collins
Test the use of clone on empty bzrdir with force_new_repo.
114
    def test_clone_bzrdir_empty_force_new_ignored(self):
1534.6.9 by Robert Collins
sprouting into shared repositories
115
        # the force_new_repo parameter should have no effect on an empty
1534.6.8 by Robert Collins
Test the use of clone on empty bzrdir with force_new_repo.
116
        # bzrdir's clone logic
117
        dir = self.make_bzrdir('source')
118
        target = dir.clone(self.get_url('target'), force_new_repo=True)
119
        self.assertNotEqual(dir.transport.base, target.transport.base)
120
        self.assertDirectoriesEqual(dir.root_transport, target.root_transport)
121
    
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.
122
    def test_clone_bzrdir_repository(self):
1534.1.33 by Robert Collins
Move copy_content_into into InterRepository and InterWeaveRepo, and disable the default codepath test as we have optimised paths for all current combinations.
123
        tree = self.make_branch_and_tree('commit_tree')
124
        self.build_tree(['foo'], transport=tree.bzrdir.transport.clone('..'))
125
        tree.add('foo')
126
        tree.commit('revision 1', rev_id='1')
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.
127
        dir = self.make_bzrdir('source')
128
        repo = dir.create_repository()
1534.1.33 by Robert Collins
Move copy_content_into into InterRepository and InterWeaveRepo, and disable the default codepath test as we have optimised paths for all current combinations.
129
        repo.fetch(tree.branch.repository)
130
        self.assertTrue(repo.has_revision('1'))
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.
131
        target = dir.clone(self.get_url('target'))
132
        self.assertNotEqual(dir.transport.base, target.transport.base)
1666.1.16 by Robert Collins
Fix occasional test failuresin bzrdir_implementations.
133
        self.assertDirectoriesEqual(dir.root_transport, target.root_transport,
134
                                    ['./.bzr/repository/inventory.knit',
135
                                     ])
136
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.
137
1534.6.6 by Robert Collins
Move find_repository to bzrdir, its not quite ideal there but its simpler and until someone chooses to vary the search by branch type its completely sufficient.
138
    def test_clone_bzrdir_repository_under_shared(self):
1534.1.33 by Robert Collins
Move copy_content_into into InterRepository and InterWeaveRepo, and disable the default codepath test as we have optimised paths for all current combinations.
139
        tree = self.make_branch_and_tree('commit_tree')
140
        self.build_tree(['foo'], transport=tree.bzrdir.transport.clone('..'))
141
        tree.add('foo')
142
        tree.commit('revision 1', rev_id='1')
1534.6.6 by Robert Collins
Move find_repository to bzrdir, its not quite ideal there but its simpler and until someone chooses to vary the search by branch type its completely sufficient.
143
        dir = self.make_bzrdir('source')
144
        repo = dir.create_repository()
1534.1.33 by Robert Collins
Move copy_content_into into InterRepository and InterWeaveRepo, and disable the default codepath test as we have optimised paths for all current combinations.
145
        repo.fetch(tree.branch.repository)
146
        self.assertTrue(repo.has_revision('1'))
1534.6.6 by Robert Collins
Move find_repository to bzrdir, its not quite ideal there but its simpler and until someone chooses to vary the search by branch type its completely sufficient.
147
        try:
148
            self.make_repository('target', shared=True)
149
        except errors.IncompatibleFormat:
150
            return
151
        target = dir.clone(self.get_url('target/child'))
152
        self.assertNotEqual(dir.transport.base, target.transport.base)
153
        self.assertRaises(errors.NoRepositoryPresent, target.open_repository)
1534.6.13 by Robert Collins
Allow push/pull and branch between branches in the same shared repository.
154
155
    def test_clone_bzrdir_repository_branch_both_under_shared(self):
156
        try:
157
            shared_repo = self.make_repository('shared', shared=True)
158
        except errors.IncompatibleFormat:
159
            return
160
        tree = self.make_branch_and_tree('commit_tree')
161
        self.build_tree(['foo'], transport=tree.bzrdir.transport.clone('..'))
162
        tree.add('foo')
163
        tree.commit('revision 1', rev_id='1')
164
        tree.bzrdir.open_branch().set_revision_history([])
165
        tree.set_last_revision(None)
166
        tree.commit('revision 2', rev_id='2')
167
        tree.bzrdir.open_repository().copy_content_into(shared_repo)
168
        dir = self.make_bzrdir('shared/source')
169
        dir.create_branch()
170
        target = dir.clone(self.get_url('shared/target'))
171
        self.assertNotEqual(dir.transport.base, target.transport.base)
172
        self.assertNotEqual(dir.transport.base, shared_repo.bzrdir.transport.base)
173
        self.assertTrue(shared_repo.has_revision('1'))
1534.6.6 by Robert Collins
Move find_repository to bzrdir, its not quite ideal there but its simpler and until someone chooses to vary the search by branch type its completely sufficient.
174
        
1534.6.9 by Robert Collins
sprouting into shared repositories
175
    def test_clone_bzrdir_repository_under_shared_force_new_repo(self):
1534.1.33 by Robert Collins
Move copy_content_into into InterRepository and InterWeaveRepo, and disable the default codepath test as we have optimised paths for all current combinations.
176
        tree = self.make_branch_and_tree('commit_tree')
177
        self.build_tree(['foo'], transport=tree.bzrdir.transport.clone('..'))
178
        tree.add('foo')
179
        tree.commit('revision 1', rev_id='1')
1534.6.6 by Robert Collins
Move find_repository to bzrdir, its not quite ideal there but its simpler and until someone chooses to vary the search by branch type its completely sufficient.
180
        dir = self.make_bzrdir('source')
181
        repo = dir.create_repository()
1534.1.33 by Robert Collins
Move copy_content_into into InterRepository and InterWeaveRepo, and disable the default codepath test as we have optimised paths for all current combinations.
182
        repo.fetch(tree.branch.repository)
183
        self.assertTrue(repo.has_revision('1'))
1534.6.6 by Robert Collins
Move find_repository to bzrdir, its not quite ideal there but its simpler and until someone chooses to vary the search by branch type its completely sufficient.
184
        try:
185
            self.make_repository('target', shared=True)
186
        except errors.IncompatibleFormat:
187
            return
188
        target = dir.clone(self.get_url('target/child'), force_new_repo=True)
189
        self.assertNotEqual(dir.transport.base, target.transport.base)
1666.1.16 by Robert Collins
Fix occasional test failuresin bzrdir_implementations.
190
        self.assertDirectoriesEqual(dir.root_transport, target.root_transport,
191
                                    ['./.bzr/repository/inventory.knit',
192
                                     ])
1534.6.6 by Robert Collins
Move find_repository to bzrdir, its not quite ideal there but its simpler and until someone chooses to vary the search by branch type its completely sufficient.
193
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.
194
    def test_clone_bzrdir_repository_revision(self):
195
        # test for revision limiting, [smoke test, not corner case checks].
196
        # make a repository with some revisions,
197
        # and clone it with a revision limit.
198
        # 
199
        tree = self.make_branch_and_tree('commit_tree')
200
        self.build_tree(['foo'], transport=tree.bzrdir.transport.clone('..'))
201
        tree.add('foo')
202
        tree.commit('revision 1', rev_id='1')
203
        tree.bzrdir.open_branch().set_revision_history([])
204
        tree.set_last_revision(None)
205
        tree.commit('revision 2', rev_id='2')
206
        source = self.make_repository('source')
207
        tree.bzrdir.open_repository().copy_content_into(source)
208
        dir = source.bzrdir
209
        target = dir.clone(self.get_url('target'), revision_id='2')
210
        raise TestSkipped('revision limiting not strict yet')
211
212
    def test_clone_bzrdir_branch_and_repo(self):
213
        tree = self.make_branch_and_tree('commit_tree')
214
        self.build_tree(['foo'], transport=tree.bzrdir.transport.clone('..'))
215
        tree.add('foo')
216
        tree.commit('revision 1')
217
        source = self.make_branch('source')
218
        tree.bzrdir.open_repository().copy_content_into(source.repository)
219
        tree.bzrdir.open_branch().copy_content_into(source)
220
        dir = source.bzrdir
221
        target = dir.clone(self.get_url('target'))
222
        self.assertNotEqual(dir.transport.base, target.transport.base)
1508.1.24 by Robert Collins
Add update command for use with checkouts.
223
        self.assertDirectoriesEqual(dir.root_transport, target.root_transport,
1666.1.16 by Robert Collins
Fix occasional test failuresin bzrdir_implementations.
224
                                    ['./.bzr/stat-cache',
225
                                     './.bzr/checkout/stat-cache',
226
                                     './.bzr/repository/inventory.knit',
227
                                     ])
1534.6.6 by Robert Collins
Move find_repository to bzrdir, its not quite ideal there but its simpler and until someone chooses to vary the search by branch type its completely sufficient.
228
229
    def test_clone_bzrdir_branch_and_repo_into_shared_repo(self):
230
        # by default cloning into a shared repo uses the shared repo.
231
        tree = self.make_branch_and_tree('commit_tree')
232
        self.build_tree(['foo'], transport=tree.bzrdir.transport.clone('..'))
233
        tree.add('foo')
234
        tree.commit('revision 1')
235
        source = self.make_branch('source')
236
        tree.bzrdir.open_repository().copy_content_into(source.repository)
237
        tree.bzrdir.open_branch().copy_content_into(source)
238
        try:
239
            self.make_repository('target', shared=True)
240
        except errors.IncompatibleFormat:
241
            return
242
        dir = source.bzrdir
243
        target = dir.clone(self.get_url('target/child'))
244
        self.assertNotEqual(dir.transport.base, target.transport.base)
245
        self.assertRaises(errors.NoRepositoryPresent, target.open_repository)
246
        self.assertEqual(source.revision_history(),
247
                         target.open_branch().revision_history())
248
249
    def test_clone_bzrdir_branch_and_repo_into_shared_repo_force_new_repo(self):
250
        # by default cloning into a shared repo uses the shared repo.
251
        tree = self.make_branch_and_tree('commit_tree')
252
        self.build_tree(['foo'], transport=tree.bzrdir.transport.clone('..'))
253
        tree.add('foo')
254
        tree.commit('revision 1')
255
        source = self.make_branch('source')
256
        tree.bzrdir.open_repository().copy_content_into(source.repository)
257
        tree.bzrdir.open_branch().copy_content_into(source)
258
        try:
259
            self.make_repository('target', shared=True)
260
        except errors.IncompatibleFormat:
261
            return
262
        dir = source.bzrdir
263
        target = dir.clone(self.get_url('target/child'), force_new_repo=True)
264
        self.assertNotEqual(dir.transport.base, target.transport.base)
265
        target.open_repository()
1666.1.16 by Robert Collins
Fix occasional test failuresin bzrdir_implementations.
266
        self.assertDirectoriesEqual(dir.root_transport, target.root_transport,
267
                                    ['./.bzr/repository/inventory.knit',
268
                                     ])
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.
269
270
    def test_clone_bzrdir_branch_reference(self):
271
        # cloning should preserve the reference status of the branch in a bzrdir
272
        referenced_branch = self.make_branch('referencced')
273
        dir = self.make_bzrdir('source')
274
        try:
1508.1.25 by Robert Collins
Update per review comments.
275
            reference = bzrlib.branch.BranchReferenceFormat().initialize(dir,
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.
276
                referenced_branch)
277
        except errors.IncompatibleFormat:
278
            # this is ok too, not all formats have to support references.
279
            return
280
        target = dir.clone(self.get_url('target'))
281
        self.assertNotEqual(dir.transport.base, target.transport.base)
1666.1.16 by Robert Collins
Fix occasional test failuresin bzrdir_implementations.
282
        self.assertDirectoriesEqual(dir.root_transport, target.root_transport,
283
                                    ['./.bzr/repository/inventory.knit',
284
                                     ])
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.
285
286
    def test_clone_bzrdir_branch_revision(self):
287
        # test for revision limiting, [smoke test, not corner case checks].
288
        # make a branch with some revisions,
289
        # and clone it with a revision limit.
290
        # 
291
        tree = self.make_branch_and_tree('commit_tree')
292
        self.build_tree(['foo'], transport=tree.bzrdir.transport.clone('..'))
293
        tree.add('foo')
294
        tree.commit('revision 1', rev_id='1')
295
        tree.commit('revision 2', rev_id='2', allow_pointless=True)
296
        source = self.make_branch('source')
297
        tree.bzrdir.open_repository().copy_content_into(source.repository)
298
        tree.bzrdir.open_branch().copy_content_into(source)
299
        dir = source.bzrdir
300
        target = dir.clone(self.get_url('target'), revision_id='1')
301
        self.assertEqual('1', target.open_branch().last_revision())
302
        
303
    def test_clone_bzrdir_tree_branch_repo(self):
304
        tree = self.make_branch_and_tree('sourcce')
305
        self.build_tree(['foo'], transport=tree.bzrdir.transport.clone('..'))
306
        tree.add('foo')
307
        tree.commit('revision 1')
308
        dir = tree.bzrdir
309
        target = dir.clone(self.get_url('target'))
310
        self.assertNotEqual(dir.transport.base, target.transport.base)
311
        self.assertDirectoriesEqual(dir.root_transport, target.root_transport,
1666.1.16 by Robert Collins
Fix occasional test failuresin bzrdir_implementations.
312
                                    ['./.bzr/stat-cache',
313
                                     './.bzr/checkout/stat-cache',
314
                                     './.bzr/repository/inventory.knit',
315
                                     ])
316
1534.7.175 by Aaron Bentley
Ensured revert writes a normal inventory
317
        target.open_workingtree().revert([])
318
319
    def test_revert_inventory(self):
320
        tree = self.make_branch_and_tree('sourcce')
321
        self.build_tree(['foo'], transport=tree.bzrdir.transport.clone('..'))
322
        tree.add('foo')
323
        tree.commit('revision 1')
324
        dir = tree.bzrdir
325
        target = dir.clone(self.get_url('target'))
326
        self.assertDirectoriesEqual(dir.root_transport, target.root_transport,
1666.1.16 by Robert Collins
Fix occasional test failuresin bzrdir_implementations.
327
                                    ['./.bzr/stat-cache',
328
                                     './.bzr/checkout/stat-cache',
329
                                     './.bzr/repository/inventory.knit',
330
                                     ])
331
1534.7.175 by Aaron Bentley
Ensured revert writes a normal inventory
332
        target.open_workingtree().revert([])
333
        self.assertDirectoriesEqual(dir.root_transport, target.root_transport,
1666.1.16 by Robert Collins
Fix occasional test failuresin bzrdir_implementations.
334
                                    ['./.bzr/stat-cache',
335
                                     './.bzr/checkout/stat-cache',
336
                                     './.bzr/repository/inventory.knit',
337
                                     ])
338
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.
339
340
    def test_clone_bzrdir_tree_branch_reference(self):
341
        # a tree with a branch reference (aka a checkout) 
342
        # should stay a checkout on clone.
343
        referenced_branch = self.make_branch('referencced')
344
        dir = self.make_bzrdir('source')
345
        try:
1508.1.25 by Robert Collins
Update per review comments.
346
            reference = bzrlib.branch.BranchReferenceFormat().initialize(dir,
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.
347
                referenced_branch)
348
        except errors.IncompatibleFormat:
349
            # this is ok too, not all formats have to support references.
350
            return
351
        dir.create_workingtree()
352
        target = dir.clone(self.get_url('target'))
353
        self.assertNotEqual(dir.transport.base, target.transport.base)
354
        self.assertDirectoriesEqual(dir.root_transport, target.root_transport,
1666.1.16 by Robert Collins
Fix occasional test failuresin bzrdir_implementations.
355
                                    ['./.bzr/stat-cache',
356
                                     './.bzr/checkout/stat-cache',
357
                                     './.bzr/repository/inventory.knit',
358
                                     ])
359
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.
360
361
    def test_clone_bzrdir_tree_revision(self):
362
        # test for revision limiting, [smoke test, not corner case checks].
363
        # make a tree with a revision with a last-revision
364
        # and clone it with a revision limit.
365
        # This smoke test just checks the revision-id is right. Tree specific
366
        # tests will check corner cases.
367
        tree = self.make_branch_and_tree('source')
368
        self.build_tree(['foo'], transport=tree.bzrdir.transport.clone('..'))
369
        tree.add('foo')
370
        tree.commit('revision 1', rev_id='1')
371
        tree.commit('revision 2', rev_id='2', allow_pointless=True)
372
        dir = tree.bzrdir
373
        target = dir.clone(self.get_url('target'), revision_id='1')
374
        self.assertEqual('1', target.open_workingtree().last_revision())
375
376
    def test_clone_bzrdir_incomplete_source_with_basis(self):
377
        # ensure that basis really does grab from the basis by having incomplete source
378
        tree = self.make_branch_and_tree('commit_tree')
379
        self.build_tree(['foo'], transport=tree.bzrdir.transport.clone('..'))
380
        tree.add('foo')
381
        tree.commit('revision 1', rev_id='1')
382
        source = self.make_branch_and_tree('source')
383
        # this gives us an incomplete repository
384
        tree.bzrdir.open_repository().copy_content_into(source.branch.repository)
385
        tree.commit('revision 2', rev_id='2', allow_pointless=True)
386
        tree.bzrdir.open_branch().copy_content_into(source.branch)
387
        tree.copy_content_into(source)
388
        self.assertFalse(source.branch.repository.has_revision('2'))
389
        dir = source.bzrdir
390
        target = dir.clone(self.get_url('target'), basis=tree.bzrdir)
391
        self.assertEqual('2', target.open_branch().last_revision())
392
        self.assertEqual('2', target.open_workingtree().last_revision())
393
        self.assertTrue(target.open_branch().repository.has_revision('2'))
394
395
    def test_sprout_bzrdir_empty(self):
396
        dir = self.make_bzrdir('source')
397
        target = dir.sprout(self.get_url('target'))
398
        self.assertNotEqual(dir.transport.base, target.transport.base)
399
        # creates a new repository branch and tree
400
        target.open_repository()
401
        target.open_branch()
402
        target.open_workingtree()
1534.6.9 by Robert Collins
sprouting into shared repositories
403
404
    def test_sprout_bzrdir_empty_under_shared_repo(self):
405
        # sprouting an empty dir into a repo uses the repo
406
        dir = self.make_bzrdir('source')
407
        try:
408
            self.make_repository('target', shared=True)
409
        except errors.IncompatibleFormat:
410
            return
411
        target = dir.sprout(self.get_url('target/child'))
412
        self.assertRaises(errors.NoRepositoryPresent, target.open_repository)
413
        target.open_branch()
414
        target.open_workingtree()
415
416
    def test_sprout_bzrdir_empty_under_shared_repo(self):
417
        # the force_new_repo parameter should force use of a new repo in an empty
418
        # bzrdir's sprout logic
419
        dir = self.make_bzrdir('source')
420
        try:
421
            self.make_repository('target', shared=True)
422
        except errors.IncompatibleFormat:
423
            return
424
        target = dir.sprout(self.get_url('target/child'), force_new_repo=True)
425
        target.open_repository()
426
        target.open_branch()
427
        target.open_workingtree()
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.
428
    
429
    def test_sprout_bzrdir_repository(self):
1534.1.33 by Robert Collins
Move copy_content_into into InterRepository and InterWeaveRepo, and disable the default codepath test as we have optimised paths for all current combinations.
430
        tree = self.make_branch_and_tree('commit_tree')
431
        self.build_tree(['foo'], transport=tree.bzrdir.transport.clone('..'))
432
        tree.add('foo')
433
        tree.commit('revision 1', rev_id='1')
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.
434
        dir = self.make_bzrdir('source')
435
        repo = dir.create_repository()
1534.1.33 by Robert Collins
Move copy_content_into into InterRepository and InterWeaveRepo, and disable the default codepath test as we have optimised paths for all current combinations.
436
        repo.fetch(tree.branch.repository)
437
        self.assertTrue(repo.has_revision('1'))
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.
438
        target = dir.sprout(self.get_url('target'))
439
        self.assertNotEqual(dir.transport.base, target.transport.base)
1666.1.16 by Robert Collins
Fix occasional test failuresin bzrdir_implementations.
440
        self.assertDirectoriesEqual(dir.root_transport, target.root_transport,
441
                                    ['./.bzr/repository/inventory.knit',
442
                                     ])
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.
443
1534.6.13 by Robert Collins
Allow push/pull and branch between branches in the same shared repository.
444
    def test_sprout_bzrdir_with_repository_to_shared(self):
1534.6.9 by Robert Collins
sprouting into shared repositories
445
        tree = self.make_branch_and_tree('commit_tree')
446
        self.build_tree(['foo'], transport=tree.bzrdir.transport.clone('..'))
447
        tree.add('foo')
448
        tree.commit('revision 1', rev_id='1')
449
        tree.bzrdir.open_branch().set_revision_history([])
450
        tree.set_last_revision(None)
451
        tree.commit('revision 2', rev_id='2')
452
        source = self.make_repository('source')
453
        tree.bzrdir.open_repository().copy_content_into(source)
454
        dir = source.bzrdir
455
        try:
456
            shared_repo = self.make_repository('target', shared=True)
457
        except errors.IncompatibleFormat:
458
            return
459
        target = dir.sprout(self.get_url('target/child'))
460
        self.assertNotEqual(dir.transport.base, target.transport.base)
461
        self.assertTrue(shared_repo.has_revision('1'))
462
1534.6.13 by Robert Collins
Allow push/pull and branch between branches in the same shared repository.
463
    def test_sprout_bzrdir_repository_branch_both_under_shared(self):
464
        try:
465
            shared_repo = self.make_repository('shared', shared=True)
466
        except errors.IncompatibleFormat:
467
            return
468
        tree = self.make_branch_and_tree('commit_tree')
469
        self.build_tree(['foo'], transport=tree.bzrdir.transport.clone('..'))
470
        tree.add('foo')
471
        tree.commit('revision 1', rev_id='1')
472
        tree.bzrdir.open_branch().set_revision_history([])
473
        tree.set_last_revision(None)
474
        tree.commit('revision 2', rev_id='2')
475
        tree.bzrdir.open_repository().copy_content_into(shared_repo)
476
        dir = self.make_bzrdir('shared/source')
477
        dir.create_branch()
478
        target = dir.sprout(self.get_url('shared/target'))
479
        self.assertNotEqual(dir.transport.base, target.transport.base)
480
        self.assertNotEqual(dir.transport.base, shared_repo.bzrdir.transport.base)
481
        self.assertTrue(shared_repo.has_revision('1'))
482
1534.6.9 by Robert Collins
sprouting into shared repositories
483
    def test_sprout_bzrdir_repository_under_shared_force_new_repo(self):
484
        tree = self.make_branch_and_tree('commit_tree')
485
        self.build_tree(['foo'], transport=tree.bzrdir.transport.clone('..'))
486
        tree.add('foo')
487
        tree.commit('revision 1', rev_id='1')
488
        tree.bzrdir.open_branch().set_revision_history([])
489
        tree.set_last_revision(None)
490
        tree.commit('revision 2', rev_id='2')
491
        source = self.make_repository('source')
492
        tree.bzrdir.open_repository().copy_content_into(source)
493
        dir = source.bzrdir
494
        try:
495
            shared_repo = self.make_repository('target', shared=True)
496
        except errors.IncompatibleFormat:
497
            return
498
        target = dir.sprout(self.get_url('target/child'), force_new_repo=True)
499
        self.assertNotEqual(dir.transport.base, target.transport.base)
500
        self.assertFalse(shared_repo.has_revision('1'))
501
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.
502
    def test_sprout_bzrdir_repository_revision(self):
503
        # test for revision limiting, [smoke test, not corner case checks].
504
        # make a repository with some revisions,
505
        # and sprout it with a revision limit.
506
        # 
507
        tree = self.make_branch_and_tree('commit_tree')
508
        self.build_tree(['foo'], transport=tree.bzrdir.transport.clone('..'))
509
        tree.add('foo')
510
        tree.commit('revision 1', rev_id='1')
511
        tree.bzrdir.open_branch().set_revision_history([])
512
        tree.set_last_revision(None)
513
        tree.commit('revision 2', rev_id='2')
514
        source = self.make_repository('source')
515
        tree.bzrdir.open_repository().copy_content_into(source)
516
        dir = source.bzrdir
517
        target = dir.sprout(self.get_url('target'), revision_id='2')
518
        raise TestSkipped('revision limiting not strict yet')
519
520
    def test_sprout_bzrdir_branch_and_repo(self):
521
        tree = self.make_branch_and_tree('commit_tree')
522
        self.build_tree(['foo'], transport=tree.bzrdir.transport.clone('..'))
523
        tree.add('foo')
524
        tree.commit('revision 1')
525
        source = self.make_branch('source')
526
        tree.bzrdir.open_repository().copy_content_into(source.repository)
527
        tree.bzrdir.open_branch().copy_content_into(source)
528
        dir = source.bzrdir
529
        target = dir.sprout(self.get_url('target'))
530
        self.assertNotEqual(dir.transport.base, target.transport.base)
1587.1.5 by Robert Collins
Put bzr branch behaviour back to the 0.7 ignore-working-tree state.
531
        self.assertDirectoriesEqual(dir.root_transport, target.root_transport,
532
                                    ['./.bzr/stat-cache',
533
                                     './.bzr/checkout/stat-cache',
534
                                     './.bzr/inventory',
535
                                     './.bzr/checkout/inventory',
1666.1.16 by Robert Collins
Fix occasional test failuresin bzrdir_implementations.
536
                                     './.bzr/repository/inventory.knit',
1587.1.5 by Robert Collins
Put bzr branch behaviour back to the 0.7 ignore-working-tree state.
537
                                     ])
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.
538
1534.6.9 by Robert Collins
sprouting into shared repositories
539
    def test_sprout_bzrdir_branch_and_repo_shared(self):
540
        # sprouting a branch with a repo into a shared repo uses the shared
541
        # repo
542
        tree = self.make_branch_and_tree('commit_tree')
543
        self.build_tree(['foo'], transport=tree.bzrdir.transport.clone('..'))
544
        tree.add('foo')
545
        tree.commit('revision 1', rev_id='1')
546
        source = self.make_branch('source')
547
        tree.bzrdir.open_repository().copy_content_into(source.repository)
548
        tree.bzrdir.open_branch().copy_content_into(source)
549
        dir = source.bzrdir
550
        try:
551
            shared_repo = self.make_repository('target', shared=True)
552
        except errors.IncompatibleFormat:
553
            return
554
        target = dir.sprout(self.get_url('target/child'))
555
        self.assertTrue(shared_repo.has_revision('1'))
556
557
    def test_sprout_bzrdir_branch_and_repo_shared_force_new_repo(self):
558
        # sprouting a branch with a repo into a shared repo uses the shared
559
        # repo
560
        tree = self.make_branch_and_tree('commit_tree')
561
        self.build_tree(['foo'], transport=tree.bzrdir.transport.clone('..'))
562
        tree.add('foo')
563
        tree.commit('revision 1', rev_id='1')
564
        source = self.make_branch('source')
565
        tree.bzrdir.open_repository().copy_content_into(source.repository)
566
        tree.bzrdir.open_branch().copy_content_into(source)
567
        dir = source.bzrdir
568
        try:
569
            shared_repo = self.make_repository('target', shared=True)
570
        except errors.IncompatibleFormat:
571
            return
572
        target = dir.sprout(self.get_url('target/child'), force_new_repo=True)
573
        self.assertNotEqual(dir.transport.base, target.transport.base)
574
        self.assertFalse(shared_repo.has_revision('1'))
575
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.
576
    def test_sprout_bzrdir_branch_reference(self):
577
        # sprouting should create a repository if needed and a sprouted branch.
578
        referenced_branch = self.make_branch('referencced')
579
        dir = self.make_bzrdir('source')
580
        try:
1508.1.25 by Robert Collins
Update per review comments.
581
            reference = bzrlib.branch.BranchReferenceFormat().initialize(dir,
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.
582
                referenced_branch)
583
        except errors.IncompatibleFormat:
584
            # this is ok too, not all formats have to support references.
585
            return
586
        self.assertRaises(errors.NoRepositoryPresent, dir.open_repository)
587
        target = dir.sprout(self.get_url('target'))
588
        self.assertNotEqual(dir.transport.base, target.transport.base)
589
        # we want target to have a branch that is in-place.
590
        self.assertEqual(target, target.open_branch().bzrdir)
591
        # and as we dont support repositories being detached yet, a repo in 
592
        # place
593
        target.open_repository()
594
1534.6.9 by Robert Collins
sprouting into shared repositories
595
    def test_sprout_bzrdir_branch_reference_shared(self):
596
        # sprouting should create a repository if needed and a sprouted branch.
597
        referenced_tree = self.make_branch_and_tree('referenced')
598
        referenced_tree.commit('1', rev_id='1', allow_pointless=True)
599
        dir = self.make_bzrdir('source')
600
        try:
601
            reference = bzrlib.branch.BranchReferenceFormat().initialize(dir,
602
                referenced_tree.branch)
603
        except errors.IncompatibleFormat:
604
            # this is ok too, not all formats have to support references.
605
            return
606
        self.assertRaises(errors.NoRepositoryPresent, dir.open_repository)
607
        try:
608
            shared_repo = self.make_repository('target', shared=True)
609
        except errors.IncompatibleFormat:
610
            return
611
        target = dir.sprout(self.get_url('target/child'))
612
        self.assertNotEqual(dir.transport.base, target.transport.base)
613
        # we want target to have a branch that is in-place.
614
        self.assertEqual(target, target.open_branch().bzrdir)
615
        # and we want no repository as the target is shared
616
        self.assertRaises(errors.NoRepositoryPresent, 
617
                          target.open_repository)
618
        # and we want revision '1' in the shared repo
619
        self.assertTrue(shared_repo.has_revision('1'))
620
621
    def test_sprout_bzrdir_branch_reference_shared_force_new_repo(self):
622
        # sprouting should create a repository if needed and a sprouted branch.
623
        referenced_tree = self.make_branch_and_tree('referenced')
624
        referenced_tree.commit('1', rev_id='1', allow_pointless=True)
625
        dir = self.make_bzrdir('source')
626
        try:
627
            reference = bzrlib.branch.BranchReferenceFormat().initialize(dir,
628
                referenced_tree.branch)
629
        except errors.IncompatibleFormat:
630
            # this is ok too, not all formats have to support references.
631
            return
632
        self.assertRaises(errors.NoRepositoryPresent, dir.open_repository)
633
        try:
634
            shared_repo = self.make_repository('target', shared=True)
635
        except errors.IncompatibleFormat:
636
            return
637
        target = dir.sprout(self.get_url('target/child'), force_new_repo=True)
638
        self.assertNotEqual(dir.transport.base, target.transport.base)
639
        # we want target to have a branch that is in-place.
640
        self.assertEqual(target, target.open_branch().bzrdir)
641
        # and we want revision '1' in the new repo
642
        self.assertTrue(target.open_repository().has_revision('1'))
643
        # but not the shared one
644
        self.assertFalse(shared_repo.has_revision('1'))
645
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.
646
    def test_sprout_bzrdir_branch_revision(self):
647
        # test for revision limiting, [smoke test, not corner case checks].
648
        # make a repository with some revisions,
649
        # and sprout it with a revision limit.
650
        # 
651
        tree = self.make_branch_and_tree('commit_tree')
652
        self.build_tree(['foo'], transport=tree.bzrdir.transport.clone('..'))
653
        tree.add('foo')
654
        tree.commit('revision 1', rev_id='1')
655
        tree.commit('revision 2', rev_id='2', allow_pointless=True)
656
        source = self.make_branch('source')
657
        tree.bzrdir.open_repository().copy_content_into(source.repository)
658
        tree.bzrdir.open_branch().copy_content_into(source)
659
        dir = source.bzrdir
660
        target = dir.sprout(self.get_url('target'), revision_id='1')
661
        self.assertEqual('1', target.open_branch().last_revision())
662
        
663
    def test_sprout_bzrdir_tree_branch_repo(self):
664
        tree = self.make_branch_and_tree('sourcce')
665
        self.build_tree(['foo'], transport=tree.bzrdir.transport.clone('..'))
666
        tree.add('foo')
667
        tree.commit('revision 1')
668
        dir = tree.bzrdir
669
        target = dir.sprout(self.get_url('target'))
670
        self.assertNotEqual(dir.transport.base, target.transport.base)
671
        self.assertDirectoriesEqual(dir.root_transport, target.root_transport,
1587.1.5 by Robert Collins
Put bzr branch behaviour back to the 0.7 ignore-working-tree state.
672
                                    ['./.bzr/stat-cache',
673
                                     './.bzr/checkout/stat-cache',
674
                                     './.bzr/inventory',
675
                                     './.bzr/checkout/inventory',
1666.1.16 by Robert Collins
Fix occasional test failuresin bzrdir_implementations.
676
                                     './.bzr/repository/inventory.knit',
1587.1.5 by Robert Collins
Put bzr branch behaviour back to the 0.7 ignore-working-tree state.
677
                                     ])
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.
678
679
    def test_sprout_bzrdir_tree_branch_reference(self):
680
        # sprouting should create a repository if needed and a sprouted branch.
1587.1.5 by Robert Collins
Put bzr branch behaviour back to the 0.7 ignore-working-tree state.
681
        # the tree state should not be copied.
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.
682
        referenced_branch = self.make_branch('referencced')
683
        dir = self.make_bzrdir('source')
684
        try:
1508.1.25 by Robert Collins
Update per review comments.
685
            reference = bzrlib.branch.BranchReferenceFormat().initialize(dir,
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.
686
                referenced_branch)
687
        except errors.IncompatibleFormat:
688
            # this is ok too, not all formats have to support references.
689
            return
690
        self.assertRaises(errors.NoRepositoryPresent, dir.open_repository)
1587.1.5 by Robert Collins
Put bzr branch behaviour back to the 0.7 ignore-working-tree state.
691
        tree = dir.create_workingtree()
692
        tree.bzrdir.root_transport.mkdir('subdir')
693
        tree.add('subdir')
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.
694
        target = dir.sprout(self.get_url('target'))
695
        self.assertNotEqual(dir.transport.base, target.transport.base)
696
        # we want target to have a branch that is in-place.
697
        self.assertEqual(target, target.open_branch().bzrdir)
698
        # and as we dont support repositories being detached yet, a repo in 
699
        # place
700
        target.open_repository()
1587.1.5 by Robert Collins
Put bzr branch behaviour back to the 0.7 ignore-working-tree state.
701
        result_tree = target.open_workingtree()
702
        self.assertFalse(result_tree.has_filename('subdir'))
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.
703
704
    def test_sprout_bzrdir_tree_branch_reference_revision(self):
705
        # sprouting should create a repository if needed and a sprouted branch.
1587.1.5 by Robert Collins
Put bzr branch behaviour back to the 0.7 ignore-working-tree state.
706
        # the tree state should not be copied but the revision changed,
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.
707
        # and the likewise the new branch should be truncated too
708
        referenced_branch = self.make_branch('referencced')
709
        dir = self.make_bzrdir('source')
710
        try:
1508.1.25 by Robert Collins
Update per review comments.
711
            reference = bzrlib.branch.BranchReferenceFormat().initialize(dir,
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.
712
                referenced_branch)
713
        except errors.IncompatibleFormat:
714
            # this is ok too, not all formats have to support references.
715
            return
716
        self.assertRaises(errors.NoRepositoryPresent, dir.open_repository)
717
        tree = dir.create_workingtree()
718
        self.build_tree(['foo'], transport=dir.root_transport)
719
        tree.add('foo')
720
        tree.commit('revision 1', rev_id='1')
721
        tree.commit('revision 2', rev_id='2', allow_pointless=True)
722
        target = dir.sprout(self.get_url('target'), revision_id='1')
723
        self.assertNotEqual(dir.transport.base, target.transport.base)
724
        # we want target to have a branch that is in-place.
725
        self.assertEqual(target, target.open_branch().bzrdir)
726
        # and as we dont support repositories being detached yet, a repo in 
727
        # place
728
        target.open_repository()
729
        # we trust that the working tree sprouting works via the other tests.
730
        self.assertEqual('1', target.open_workingtree().last_revision())
731
        self.assertEqual('1', target.open_branch().last_revision())
732
733
    def test_sprout_bzrdir_tree_revision(self):
734
        # test for revision limiting, [smoke test, not corner case checks].
735
        # make a tree with a revision with a last-revision
736
        # and sprout it with a revision limit.
737
        # This smoke test just checks the revision-id is right. Tree specific
738
        # tests will check corner cases.
739
        tree = self.make_branch_and_tree('source')
740
        self.build_tree(['foo'], transport=tree.bzrdir.root_transport)
741
        tree.add('foo')
742
        tree.commit('revision 1', rev_id='1')
743
        tree.commit('revision 2', rev_id='2', allow_pointless=True)
744
        dir = tree.bzrdir
745
        target = dir.sprout(self.get_url('target'), revision_id='1')
746
        self.assertEqual('1', target.open_workingtree().last_revision())
747
748
    def test_sprout_bzrdir_incomplete_source_with_basis(self):
749
        # ensure that basis really does grab from the basis by having incomplete source
750
        tree = self.make_branch_and_tree('commit_tree')
751
        self.build_tree(['foo'], transport=tree.bzrdir.root_transport)
752
        tree.add('foo')
753
        tree.commit('revision 1', rev_id='1')
754
        source = self.make_branch_and_tree('source')
755
        # this gives us an incomplete repository
756
        tree.bzrdir.open_repository().copy_content_into(source.branch.repository)
757
        tree.commit('revision 2', rev_id='2', allow_pointless=True)
758
        tree.bzrdir.open_branch().copy_content_into(source.branch)
759
        tree.copy_content_into(source)
760
        self.assertFalse(source.branch.repository.has_revision('2'))
761
        dir = source.bzrdir
762
        target = dir.sprout(self.get_url('target'), basis=tree.bzrdir)
763
        self.assertEqual('2', target.open_branch().last_revision())
764
        self.assertEqual('2', target.open_workingtree().last_revision())
765
        self.assertTrue(target.open_branch().repository.has_revision('2'))
1534.4.39 by Robert Collins
Basic BzrDir support.
766
767
    def test_format_initialize_find_open(self):
768
        # loopback test to check the current format initializes to itself.
769
        if not self.bzrdir_format.is_supported():
770
            # unsupported formats are not loopback testable
771
            # because the default open will not open them and
772
            # they may not be initializable.
773
            return
774
        # supported formats must be able to init and open
775
        t = get_transport(self.get_url())
776
        readonly_t = get_transport(self.get_readonly_url())
777
        made_control = self.bzrdir_format.initialize(t.base)
778
        self.failUnless(isinstance(made_control, bzrdir.BzrDir))
779
        self.assertEqual(self.bzrdir_format,
780
                         bzrdir.BzrDirFormat.find_format(readonly_t))
781
        direct_opened_dir = self.bzrdir_format.open(readonly_t)
782
        opened_dir = bzrdir.BzrDir.open(t.base)
783
        self.assertEqual(made_control._format,
784
                         opened_dir._format)
785
        self.assertEqual(direct_opened_dir._format,
786
                         opened_dir._format)
787
        self.failUnless(isinstance(opened_dir, bzrdir.BzrDir))
788
789
    def test_open_not_bzrdir(self):
790
        # test the formats specific behaviour for no-content or similar dirs.
791
        self.assertRaises(NotBranchError,
792
                          self.bzrdir_format.open,
793
                          get_transport(self.get_readonly_url()))
1534.4.40 by Robert Collins
Add RepositoryFormats and allow bzrdir.open or create _repository to be used.
794
1534.4.41 by Robert Collins
Branch now uses BzrDir reasonably sanely.
795
    def test_create_branch(self):
1534.6.6 by Robert Collins
Move find_repository to bzrdir, its not quite ideal there but its simpler and until someone chooses to vary the search by branch type its completely sufficient.
796
        # a bzrdir can construct a branch and repository for itself.
1534.4.41 by Robert Collins
Branch now uses BzrDir reasonably sanely.
797
        if not self.bzrdir_format.is_supported():
798
            # unsupported formats are not loopback testable
799
            # because the default open will not open them and
800
            # they may not be initializable.
801
            return
802
        t = get_transport(self.get_url())
803
        made_control = self.bzrdir_format.initialize(t.base)
804
        made_repo = made_control.create_repository()
805
        made_branch = made_control.create_branch()
1508.1.25 by Robert Collins
Update per review comments.
806
        self.failUnless(isinstance(made_branch, bzrlib.branch.Branch))
1534.4.41 by Robert Collins
Branch now uses BzrDir reasonably sanely.
807
        self.assertEqual(made_control, made_branch.bzrdir)
808
        
809
    def test_open_branch(self):
810
        if not self.bzrdir_format.is_supported():
811
            # unsupported formats are not loopback testable
812
            # because the default open will not open them and
813
            # they may not be initializable.
814
            return
815
        t = get_transport(self.get_url())
816
        made_control = self.bzrdir_format.initialize(t.base)
817
        made_repo = made_control.create_repository()
818
        made_branch = made_control.create_branch()
819
        opened_branch = made_control.open_branch()
820
        self.assertEqual(made_control, opened_branch.bzrdir)
821
        self.failUnless(isinstance(opened_branch, made_branch.__class__))
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
822
        self.failUnless(isinstance(opened_branch._format, made_branch._format.__class__))
1534.4.41 by Robert Collins
Branch now uses BzrDir reasonably sanely.
823
1534.4.40 by Robert Collins
Add RepositoryFormats and allow bzrdir.open or create _repository to be used.
824
    def test_create_repository(self):
825
        # a bzrdir can construct a repository for itself.
826
        if not self.bzrdir_format.is_supported():
827
            # unsupported formats are not loopback testable
828
            # because the default open will not open them and
829
            # they may not be initializable.
830
            return
831
        t = get_transport(self.get_url())
832
        made_control = self.bzrdir_format.initialize(t.base)
833
        made_repo = made_control.create_repository()
834
        self.failUnless(isinstance(made_repo, repository.Repository))
835
        self.assertEqual(made_control, made_repo.bzrdir)
836
        
837
    def test_open_repository(self):
838
        if not self.bzrdir_format.is_supported():
839
            # unsupported formats are not loopback testable
840
            # because the default open will not open them and
841
            # they may not be initializable.
842
            return
843
        t = get_transport(self.get_url())
844
        made_control = self.bzrdir_format.initialize(t.base)
845
        made_repo = made_control.create_repository()
846
        opened_repo = made_control.open_repository()
847
        self.assertEqual(made_control, opened_repo.bzrdir)
848
        self.failUnless(isinstance(opened_repo, made_repo.__class__))
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
849
        self.failUnless(isinstance(opened_repo._format, made_repo._format.__class__))
1534.4.42 by Robert Collins
add working tree to the BzrDir facilities.
850
851
    def test_create_workingtree(self):
852
        # a bzrdir can construct a working tree for itself.
853
        if not self.bzrdir_format.is_supported():
854
            # unsupported formats are not loopback testable
855
            # because the default open will not open them and
856
            # they may not be initializable.
857
            return
858
        # this has to be tested with local access as we still support creating 
859
        # format 6 bzrdirs
860
        t = get_transport('.')
861
        made_control = self.bzrdir_format.initialize(t.base)
862
        made_repo = made_control.create_repository()
863
        made_branch = made_control.create_branch()
864
        made_tree = made_control.create_workingtree()
865
        self.failUnless(isinstance(made_tree, workingtree.WorkingTree))
866
        self.assertEqual(made_control, made_tree.bzrdir)
867
        
1508.1.21 by Robert Collins
Implement -r limit for checkout command.
868
    def test_create_workingtree_revision(self):
869
        # a bzrdir can construct a working tree for itself @ a specific revision.
870
        source = self.make_branch_and_tree('source')
871
        source.commit('a', rev_id='a', allow_pointless=True)
872
        source.commit('b', rev_id='b', allow_pointless=True)
873
        self.build_tree(['new/'])
874
        made_control = self.bzrdir_format.initialize('new')
875
        source.branch.repository.clone(made_control)
876
        source.branch.clone(made_control)
877
        made_tree = made_control.create_workingtree(revision_id='a')
878
        self.assertEqual('a', made_tree.last_revision())
879
        
1534.4.42 by Robert Collins
add working tree to the BzrDir facilities.
880
    def test_open_workingtree(self):
881
        if not self.bzrdir_format.is_supported():
882
            # unsupported formats are not loopback testable
883
            # because the default open will not open them and
884
            # they may not be initializable.
885
            return
886
        # this has to be tested with local access as we still support creating 
887
        # format 6 bzrdirs
888
        t = get_transport('.')
889
        made_control = self.bzrdir_format.initialize(t.base)
890
        made_repo = made_control.create_repository()
891
        made_branch = made_control.create_branch()
892
        made_tree = made_control.create_workingtree()
893
        opened_tree = made_control.open_workingtree()
894
        self.assertEqual(made_control, opened_tree.bzrdir)
895
        self.failUnless(isinstance(opened_tree, made_tree.__class__))
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
896
        self.failUnless(isinstance(opened_tree._format, made_tree._format.__class__))
1534.4.42 by Robert Collins
add working tree to the BzrDir facilities.
897
1534.4.44 by Robert Collins
Make a new BzrDir format that uses a versioned branch format in a branch/ subdirectory.
898
    def test_get_branch_transport(self):
899
        dir = self.make_bzrdir('.')
900
        # without a format, get_branch_transport gives use a transport
901
        # which -may- point to an existing dir.
902
        self.assertTrue(isinstance(dir.get_branch_transport(None),
903
                                   transport.Transport))
904
        # with a given format, either the bzr dir supports identifiable
905
        # branches, or it supports anonymous  branch formats, but not both.
1508.1.25 by Robert Collins
Update per review comments.
906
        anonymous_format = bzrlib.branch.BzrBranchFormat4()
907
        identifiable_format = bzrlib.branch.BzrBranchFormat5()
1534.4.44 by Robert Collins
Make a new BzrDir format that uses a versioned branch format in a branch/ subdirectory.
908
        try:
909
            found_transport = dir.get_branch_transport(anonymous_format)
910
            self.assertRaises(errors.IncompatibleFormat,
911
                              dir.get_branch_transport,
912
                              identifiable_format)
913
        except errors.IncompatibleFormat:
914
            found_transport = dir.get_branch_transport(identifiable_format)
915
        self.assertTrue(isinstance(found_transport, transport.Transport))
916
        # and the dir which has been initialized for us must be statable.
917
        found_transport.stat('.')
1534.4.45 by Robert Collins
Start WorkingTree -> .bzr/checkout transition
918
1534.4.47 by Robert Collins
Split out repository into .bzr/repository
919
    def test_get_repository_transport(self):
920
        dir = self.make_bzrdir('.')
921
        # without a format, get_repository_transport gives use a transport
922
        # which -may- point to an existing dir.
923
        self.assertTrue(isinstance(dir.get_repository_transport(None),
924
                                   transport.Transport))
925
        # with a given format, either the bzr dir supports identifiable
926
        # repositoryes, or it supports anonymous  repository formats, but not both.
927
        anonymous_format = repository.RepositoryFormat6()
928
        identifiable_format = repository.RepositoryFormat7()
929
        try:
930
            found_transport = dir.get_repository_transport(anonymous_format)
931
            self.assertRaises(errors.IncompatibleFormat,
932
                              dir.get_repository_transport,
933
                              identifiable_format)
934
        except errors.IncompatibleFormat:
935
            found_transport = dir.get_repository_transport(identifiable_format)
936
        self.assertTrue(isinstance(found_transport, transport.Transport))
937
        # and the dir which has been initialized for us must be statable.
938
        found_transport.stat('.')
939
1534.4.45 by Robert Collins
Start WorkingTree -> .bzr/checkout transition
940
    def test_get_workingtree_transport(self):
941
        dir = self.make_bzrdir('.')
942
        # without a format, get_workingtree_transport gives use a transport
943
        # which -may- point to an existing dir.
944
        self.assertTrue(isinstance(dir.get_workingtree_transport(None),
945
                                   transport.Transport))
946
        # with a given format, either the bzr dir supports identifiable
947
        # trees, or it supports anonymous tree formats, but not both.
948
        anonymous_format = workingtree.WorkingTreeFormat2()
949
        identifiable_format = workingtree.WorkingTreeFormat3()
950
        try:
951
            found_transport = dir.get_workingtree_transport(anonymous_format)
952
            self.assertRaises(errors.IncompatibleFormat,
953
                              dir.get_workingtree_transport,
954
                              identifiable_format)
955
        except errors.IncompatibleFormat:
956
            found_transport = dir.get_workingtree_transport(identifiable_format)
957
        self.assertTrue(isinstance(found_transport, transport.Transport))
958
        # and the dir which has been initialized for us must be statable.
959
        found_transport.stat('.')
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.
960
961
    def test_root_transport(self):
962
        dir = self.make_bzrdir('.')
963
        self.assertEqual(dir.root_transport.base,
964
                         get_transport(self.get_url('.')).base)
965
1534.6.6 by Robert Collins
Move find_repository to bzrdir, its not quite ideal there but its simpler and until someone chooses to vary the search by branch type its completely sufficient.
966
    def test_find_repository_no_repo_under_standalone_branch(self):
967
        # finding a repo stops at standalone branches even if there is a
968
        # higher repository available.
969
        try:
970
            repo = self.make_repository('.', shared=True)
971
        except errors.IncompatibleFormat:
972
            # need a shared repository to test this.
973
            return
974
        url = self.get_url('intermediate')
975
        get_transport(self.get_url()).mkdir('intermediate')
976
        get_transport(self.get_url()).mkdir('intermediate/child')
977
        made_control = self.bzrdir_format.initialize(url)
978
        made_control.create_repository()
979
        innermost_control = self.bzrdir_format.initialize(
980
            self.get_url('intermediate/child'))
981
        try:
982
            child_repo = innermost_control.open_repository()
983
            # if there is a repository, then the format cannot ever hit this 
984
            # code path.
985
            return
986
        except errors.NoRepositoryPresent:
987
            pass
988
        self.assertRaises(errors.NoRepositoryPresent,
989
                          innermost_control.find_repository)
990
991
    def test_find_repository_containing_shared_repository(self):
992
        # find repo inside a shared repo with an empty control dir
993
        # returns the shared repo.
994
        try:
995
            repo = self.make_repository('.', shared=True)
996
        except errors.IncompatibleFormat:
997
            # need a shared repository to test this.
998
            return
999
        url = self.get_url('childbzrdir')
1000
        get_transport(self.get_url()).mkdir('childbzrdir')
1001
        made_control = self.bzrdir_format.initialize(url)
1002
        try:
1003
            child_repo = made_control.open_repository()
1004
            # if there is a repository, then the format cannot ever hit this 
1005
            # code path.
1006
            return
1007
        except errors.NoRepositoryPresent:
1008
            pass
1009
        found_repo = made_control.find_repository()
1010
        self.assertEqual(repo.bzrdir.root_transport.base,
1011
                         found_repo.bzrdir.root_transport.base)
1012
        
1013
    def test_find_repository_standalone_with_containing_shared_repository(self):
1014
        # find repo inside a standalone repo inside a shared repo finds the standalone repo
1015
        try:
1016
            containing_repo = self.make_repository('.', shared=True)
1017
        except errors.IncompatibleFormat:
1018
            # need a shared repository to test this.
1019
            return
1020
        child_repo = self.make_repository('childrepo')
1021
        opened_control = bzrdir.BzrDir.open(self.get_url('childrepo'))
1022
        found_repo = opened_control.find_repository()
1023
        self.assertEqual(child_repo.bzrdir.root_transport.base,
1024
                         found_repo.bzrdir.root_transport.base)
1025
1026
    def test_find_repository_shared_within_shared_repository(self):
1027
        # find repo at a shared repo inside a shared repo finds the inner repo
1028
        try:
1029
            containing_repo = self.make_repository('.', shared=True)
1030
        except errors.IncompatibleFormat:
1031
            # need a shared repository to test this.
1032
            return
1033
        url = self.get_url('childrepo')
1034
        get_transport(self.get_url()).mkdir('childrepo')
1035
        child_control = self.bzrdir_format.initialize(url)
1036
        child_repo = child_control.create_repository(shared=True)
1037
        opened_control = bzrdir.BzrDir.open(self.get_url('childrepo'))
1038
        found_repo = opened_control.find_repository()
1039
        self.assertEqual(child_repo.bzrdir.root_transport.base,
1040
                         found_repo.bzrdir.root_transport.base)
1041
        self.assertNotEqual(child_repo.bzrdir.root_transport.base,
1042
                            containing_repo.bzrdir.root_transport.base)
1043
1044
    def test_find_repository_with_nested_dirs_works(self):
1045
        # find repo inside a bzrdir inside a bzrdir inside a shared repo 
1046
        # finds the outer shared repo.
1047
        try:
1048
            repo = self.make_repository('.', shared=True)
1049
        except errors.IncompatibleFormat:
1050
            # need a shared repository to test this.
1051
            return
1052
        url = self.get_url('intermediate')
1053
        get_transport(self.get_url()).mkdir('intermediate')
1054
        get_transport(self.get_url()).mkdir('intermediate/child')
1055
        made_control = self.bzrdir_format.initialize(url)
1056
        try:
1057
            child_repo = made_control.open_repository()
1058
            # if there is a repository, then the format cannot ever hit this 
1059
            # code path.
1060
            return
1061
        except errors.NoRepositoryPresent:
1062
            pass
1063
        innermost_control = self.bzrdir_format.initialize(
1064
            self.get_url('intermediate/child'))
1065
        try:
1066
            child_repo = innermost_control.open_repository()
1067
            # if there is a repository, then the format cannot ever hit this 
1068
            # code path.
1069
            return
1070
        except errors.NoRepositoryPresent:
1071
            pass
1072
        found_repo = innermost_control.find_repository()
1073
        self.assertEqual(repo.bzrdir.root_transport.base,
1074
                         found_repo.bzrdir.root_transport.base)
1075
        
1534.5.16 by Robert Collins
Review feedback.
1076
    def test_can_and_needs_format_conversion(self):
1534.5.8 by Robert Collins
Ensure that bzrdir implementations offer the can_update_format and needs_format_update api.
1077
        # check that we can ask an instance if its upgradable
1078
        dir = self.make_bzrdir('.')
1534.5.16 by Robert Collins
Review feedback.
1079
        if dir.can_convert_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.
1080
            # if its default updatable there must be an updater 
1081
            # (we change the default to match the lastest known format
1082
            # as downgrades may not be available
1083
            old_format = bzrdir.BzrDirFormat.get_default_format()
1084
            bzrdir.BzrDirFormat.set_default_format(dir._format)
1085
            try:
1086
                self.assertTrue(isinstance(dir._format.get_converter(),
1087
                                           bzrdir.Converter))
1088
            finally:
1089
                bzrdir.BzrDirFormat.set_default_format(old_format)
1534.5.16 by Robert Collins
Review feedback.
1090
        dir.needs_format_conversion(None)
1534.6.6 by Robert Collins
Move find_repository to bzrdir, its not quite ideal there but its simpler and until someone chooses to vary the search by branch type its completely sufficient.
1091
1534.5.11 by Robert Collins
Implement upgrades to Metaformat trees.
1092
    def test_upgrade_new_instance(self):
1093
        """Does an available updater work ?."""
1094
        dir = self.make_bzrdir('.')
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.
1095
        # for now, check is not ready for partial bzrdirs.
1096
        dir.create_repository()
1097
        dir.create_branch()
1098
        dir.create_workingtree()
1534.5.16 by Robert Collins
Review feedback.
1099
        if dir.can_convert_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.
1100
            # if its default updatable there must be an updater 
1101
            # (we change the default to match the lastest known format
1102
            # as downgrades may not be available
1103
            old_format = bzrdir.BzrDirFormat.get_default_format()
1104
            bzrdir.BzrDirFormat.set_default_format(dir._format)
1594.1.3 by Robert Collins
Fixup pb usage to use nested_progress_bar.
1105
            pb = ui.ui_factory.nested_progress_bar()
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.
1106
            try:
1594.1.3 by Robert Collins
Fixup pb usage to use nested_progress_bar.
1107
                dir._format.get_converter(None).convert(dir, pb)
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.
1108
            finally:
1109
                bzrdir.BzrDirFormat.set_default_format(old_format)
1594.1.3 by Robert Collins
Fixup pb usage to use nested_progress_bar.
1110
                pb.finished()
1534.5.11 by Robert Collins
Implement upgrades to Metaformat trees.
1111
            # and it should pass 'check' now.
1112
            check(bzrdir.BzrDir.open(self.get_url('.')).open_branch(), False)
1113
1624.3.19 by Olaf Conradi
New call get_format_description to give a user-friendly description of a
1114
    def test_format_description(self):
1115
        dir = self.make_bzrdir('.')
1116
        text = dir._format.get_format_description()
1117
        self.failUnless(len(text))
1118
1534.6.6 by Robert Collins
Move find_repository to bzrdir, its not quite ideal there but its simpler and until someone chooses to vary the search by branch type its completely sufficient.
1119
1687.1.12 by Robert Collins
Hook in the full break-lock ui.
1120
class TestBreakLock(TestCaseWithBzrDir):
1121
1122
    def setUp(self):
1123
        super(TestBreakLock, self).setUp()
1124
        # we want a UI factory that accepts canned input for the tests:
1125
        # while SilentUIFactory still accepts stdin, we need to customise
1126
        # ours
1127
        self.old_factory = bzrlib.ui.ui_factory
1687.1.15 by Robert Collins
Review comments.
1128
        self.addCleanup(self.restoreFactory)
1687.1.12 by Robert Collins
Hook in the full break-lock ui.
1129
        bzrlib.ui.ui_factory = bzrlib.ui.SilentUIFactory()
1130
1687.1.15 by Robert Collins
Review comments.
1131
    def restoreFactory(self):
1687.1.12 by Robert Collins
Hook in the full break-lock ui.
1132
        bzrlib.ui.ui_factory = self.old_factory
1133
1134
    def test_break_lock_empty(self):
1135
        # break lock on an empty bzrdir should work silently.
1136
        dir = self.make_bzrdir('.')
1137
        try:
1138
            dir.break_lock()
1139
        except NotImplementedError:
1140
            pass
1141
1142
    def test_break_lock_repository(self):
1143
        # break lock with just a repo should unlock the repo.
1144
        repo = self.make_repository('.')
1145
        repo.lock_write()
1146
        # only one yes needed here: it should only be unlocking
1147
        # the repo
1148
        bzrlib.ui.ui_factory.stdin = StringIO("y\n")
1149
        try:
1150
            repo.bzrdir.break_lock()
1151
        except NotImplementedError:
1152
            # this bzrdir does not implement break_lock - so we cant test it.
1153
            repo.unlock()
1154
            return
1155
        lock_repo = repo.bzrdir.open_repository()
1156
        lock_repo.lock_write()
1157
        lock_repo.unlock()
1158
        self.assertRaises(errors.LockBroken, repo.unlock)
1159
1160
    def test_break_lock_branch(self):
1161
        # break lock with just a repo should unlock the branch.
1162
        # and not directly try the repository.
1163
        # we test this by making a branch reference to a branch
1164
        # and repository in another bzrdir
1165
        # for pre-metadir formats this will fail, thats ok.
1166
        master = self.make_branch('branch')
1167
        thisdir = self.make_bzrdir('this')
1168
        try:
1169
            bzrlib.branch.BranchReferenceFormat().initialize(
1170
                thisdir, master)
1171
        except errors.IncompatibleFormat:
1172
            return
1173
        unused_repo = thisdir.create_repository()
1174
        master.lock_write()
1175
        unused_repo.lock_write()
1176
        # two yes's : branch and repository. If the repo in this
1177
        # dir is inappropriately accessed, 3 will be needed, and
1178
        # we'll see that because the stream will be fully consumed
1179
        bzrlib.ui.ui_factory.stdin = StringIO("y\ny\ny\n")
1180
        master.bzrdir.break_lock()
1181
        # only two ys should have been read
1182
        self.assertEqual("y\n", bzrlib.ui.ui_factory.stdin.read())
1183
        # we should be able to lock a newly opened branch now
1184
        branch = master.bzrdir.open_branch()
1185
        branch.lock_write()
1186
        branch.unlock()
1187
        # we should not be able to lock the repository in thisdir as its still
1188
        # held by the explicit lock we took, and the break lock should not have
1189
        # touched it.
1190
        repo = thisdir.open_repository()
1191
        self.assertRaises(errors.LockContention, repo.lock_write)
1192
        unused_repo.unlock()
1193
        self.assertRaises(errors.LockBroken, master.unlock)
1194
1195
    def test_break_lock_tree(self):
1196
        # break lock with a tree should unlock the tree but not try the 
1197
        # branch explicitly. However this is very hard to test for as we 
1198
        # dont have a tree reference class, nor is one needed; 
1199
        # the worst case if this code unlocks twice is an extra question
1200
        # being asked.
1201
        tree = self.make_branch_and_tree('.')
1202
        tree.lock_write()
1203
        # three yes's : tree, branch and repository.
1204
        bzrlib.ui.ui_factory.stdin = StringIO("y\ny\ny\ny\n")
1205
        try:
1206
            tree.bzrdir.break_lock()
1207
        except NotImplementedError:
1208
            # bzrdir does not support break_lock
1209
            tree.unlock()
1210
            return
1211
        self.assertEqual("y\n", bzrlib.ui.ui_factory.stdin.read())
1212
        lock_tree = tree.bzrdir.open_workingtree()
1213
        lock_tree.lock_write()
1214
        lock_tree.unlock()
1215
        self.assertRaises(errors.LockBroken, tree.unlock)
1216
1217
1534.6.6 by Robert Collins
Move find_repository to bzrdir, its not quite ideal there but its simpler and until someone chooses to vary the search by branch type its completely sufficient.
1218
class ChrootedBzrDirTests(ChrootedTestCase):
1219
1220
    def test_find_repository_no_repository(self):
1221
        # loopback test to check the current format fails to find a 
1222
        # share repository correctly.
1223
        if not self.bzrdir_format.is_supported():
1224
            # unsupported formats are not loopback testable
1225
            # because the default open will not open them and
1226
            # they may not be initializable.
1227
            return
1228
        # supported formats must be able to init and open
1229
        url = self.get_url('subdir')
1230
        get_transport(self.get_url()).mkdir('subdir')
1231
        made_control = self.bzrdir_format.initialize(url)
1232
        try:
1233
            repo = made_control.open_repository()
1234
            # if there is a repository, then the format cannot ever hit this 
1235
            # code path.
1236
            return
1237
        except errors.NoRepositoryPresent:
1238
            pass
1239
        opened_control = bzrdir.BzrDir.open(self.get_readonly_url('subdir'))
1240
        self.assertRaises(errors.NoRepositoryPresent,
1241
                          opened_control.find_repository)
1242