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