~bzr-pqm/bzr/bzr.dev

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