~bzr-pqm/bzr/bzr.dev

5387.2.7 by John Arbash Meinel
Merge bzr.dev 5444 to resolve some small text conflicts.
1
# Copyright (C) 2010 Canonical Ltd
5363.2.29 by Jelmer Vernooij
Move some bzrdir-specific tests to bzrlib.tests.per_bzrdir.
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
17
"""Tests for bzrdir implementations - tests a bzrdir format."""
18
19
import errno
20
from stat import S_ISDIR
21
22
import bzrlib.branch
23
from bzrlib import (
6164.2.1 by Jelmer Vernooij
Skip tests if the repository doesn't support ghosts.
24
    bzrdir,
6472.2.1 by Jelmer Vernooij
Use bzrdir.controldir for generic access to control directories.
25
    controldir,
5363.2.29 by Jelmer Vernooij
Move some bzrdir-specific tests to bzrlib.tests.per_bzrdir.
26
    errors,
5699.4.7 by Jelmer Vernooij
Fix imports.
27
    repository,
5363.2.29 by Jelmer Vernooij
Move some bzrdir-specific tests to bzrlib.tests.per_bzrdir.
28
    revision as _mod_revision,
5363.2.30 by Jelmer Vernooij
actually run per_bzrdir tests.
29
    transport,
5699.4.7 by Jelmer Vernooij
Fix imports.
30
    workingtree,
5363.2.30 by Jelmer Vernooij
actually run per_bzrdir tests.
31
    )
6164.2.1 by Jelmer Vernooij
Skip tests if the repository doesn't support ghosts.
32
from bzrlib.remote import RemoteBzrDirFormat
5363.2.30 by Jelmer Vernooij
actually run per_bzrdir tests.
33
from bzrlib.tests import (
6164.2.1 by Jelmer Vernooij
Skip tests if the repository doesn't support ghosts.
34
    TestNotApplicable,
5363.2.30 by Jelmer Vernooij
actually run per_bzrdir tests.
35
    TestSkipped,
36
    )
5363.2.29 by Jelmer Vernooij
Move some bzrdir-specific tests to bzrlib.tests.per_bzrdir.
37
from bzrlib.tests.per_bzrdir import TestCaseWithBzrDir
5363.2.30 by Jelmer Vernooij
actually run per_bzrdir tests.
38
from bzrlib.transport.local import (
39
    LocalTransport,
40
    )
5363.2.29 by Jelmer Vernooij
Move some bzrdir-specific tests to bzrlib.tests.per_bzrdir.
41
42
5699.4.7 by Jelmer Vernooij
Fix imports.
43
class AnonymousTestBranchFormat(bzrlib.branch.BranchFormat):
44
    """An anonymous branch format (does not have a format string)"""
45
46
    def get_format_string(self):
47
        raise NotImplementedError(self.get_format_string)
48
49
50
class IdentifiableTestBranchFormat(bzrlib.branch.BranchFormat):
51
    """An identifable branch format (has a format string)"""
52
53
    def get_format_string(self):
54
        return "I have an identity"
55
56
57
class AnonymousTestRepositoryFormat(repository.RepositoryFormat):
58
    """An anonymous branch format (does not have a format string)"""
59
60
    def get_format_string(self):
61
        raise NotImplementedError(self.get_format_string)
62
63
64
class IdentifiableTestRepositoryFormat(repository.RepositoryFormat):
65
    """An identifable branch format (has a format string)"""
66
67
    def get_format_string(self):
68
        return "I have an identity"
69
70
71
class AnonymousTestWorkingTreeFormat(workingtree.WorkingTreeFormat):
72
    """An anonymous branch format (does not have a format string)"""
73
74
    def get_format_string(self):
75
        raise NotImplementedError(self.get_format_string)
76
77
78
class IdentifiableTestWorkingTreeFormat(workingtree.WorkingTreeFormat):
79
    """An identifable branch format (has a format string)"""
80
81
    def get_format_string(self):
82
        return "I have an identity"
83
84
5363.2.29 by Jelmer Vernooij
Move some bzrdir-specific tests to bzrlib.tests.per_bzrdir.
85
class TestBzrDir(TestCaseWithBzrDir):
86
87
    # Many of these tests test for disk equality rather than checking
88
    # for semantic equivalence. This works well for some tests but
89
    # is not good at handling changes in representation or the addition
90
    # or removal of control data. It would be nice to for instance:
91
    # sprout a new branch, check that the nickname has been reset by hand
92
    # and then set the nickname to match the source branch, at which point
93
    # a semantic equivalence should pass
94
95
    def assertDirectoriesEqual(self, source, target, ignore_list=[]):
96
        """Assert that the content of source and target are identical.
97
98
        paths in ignore list will be completely ignored.
99
100
        We ignore paths that represent data which is allowed to change during
101
        a clone or sprout: for instance, inventory.knit contains gzip fragements
102
        which have timestamps in them, and as we have read the inventory from
103
        the source knit, the already-read data is recompressed rather than
104
        reading it again, which leads to changed timestamps. This is ok though,
105
        because the inventory.kndx file is not ignored, and the integrity of
106
        knit joins is tested by test_knit and test_versionedfile.
107
108
        :seealso: Additionally, assertRepositoryHasSameItems provides value
109
            rather than representation checking of repositories for
110
            equivalence.
111
        """
112
        files = []
113
        directories = ['.']
114
        while directories:
115
            dir = directories.pop()
116
            for path in set(source.list_dir(dir) + target.list_dir(dir)):
117
                path = dir + '/' + path
118
                if path in ignore_list:
119
                    continue
120
                try:
121
                    stat = source.stat(path)
122
                except errors.NoSuchFile:
123
                    self.fail('%s not in source' % path)
124
                if S_ISDIR(stat.st_mode):
125
                    self.assertTrue(S_ISDIR(target.stat(path).st_mode))
126
                    directories.append(path)
127
                else:
6437.20.5 by Wouter van Heyst
express intent more pithily with transport.get_bytes
128
                    self.assertEqualDiff(source.get_bytes(path),
129
                                         target.get_bytes(path),
5363.2.29 by Jelmer Vernooij
Move some bzrdir-specific tests to bzrlib.tests.per_bzrdir.
130
                                         "text for file %r differs:\n" % path)
131
132
    def assertRepositoryHasSameItems(self, left_repo, right_repo):
133
        """require left_repo and right_repo to contain the same data."""
134
        # XXX: TODO: Doesn't work yet, because we need to be able to compare
135
        # local repositories to remote ones...  but this is an as-yet unsolved
136
        # aspect of format management and the Remote protocols...
137
        # self.assertEqual(left_repo._format.__class__,
138
        #     right_repo._format.__class__)
139
        left_repo.lock_read()
140
        try:
141
            right_repo.lock_read()
142
            try:
143
                # revs
144
                all_revs = left_repo.all_revision_ids()
145
                self.assertEqual(left_repo.all_revision_ids(),
146
                    right_repo.all_revision_ids())
147
                for rev_id in left_repo.all_revision_ids():
148
                    self.assertEqual(left_repo.get_revision(rev_id),
149
                        right_repo.get_revision(rev_id))
150
                # Assert the revision trees (and thus the inventories) are equal
151
                sort_key = lambda rev_tree: rev_tree.get_revision_id()
152
                rev_trees_a = sorted(
153
                    left_repo.revision_trees(all_revs), key=sort_key)
154
                rev_trees_b = sorted(
155
                    right_repo.revision_trees(all_revs), key=sort_key)
156
                for tree_a, tree_b in zip(rev_trees_a, rev_trees_b):
157
                    self.assertEqual([], list(tree_a.iter_changes(tree_b)))
158
                # texts
159
                text_index = left_repo._generate_text_key_index()
160
                self.assertEqual(text_index,
161
                    right_repo._generate_text_key_index())
162
                desired_files = []
163
                for file_id, revision_id in text_index.iterkeys():
164
                    desired_files.append(
165
                        (file_id, revision_id, (file_id, revision_id)))
6280.10.21 by Jelmer Vernooij
Consume iter_files_bytes contents directly.
166
                left_texts = [(identifier, "".join(bytes_iterator)) for
167
                        (identifier, bytes_iterator) in
168
                        left_repo.iter_files_bytes(desired_files)]
169
                right_texts = [(identifier, "".join(bytes_iterator)) for
170
                        (identifier, bytes_iterator) in
171
                        right_repo.iter_files_bytes(desired_files)]
5363.2.29 by Jelmer Vernooij
Move some bzrdir-specific tests to bzrlib.tests.per_bzrdir.
172
                left_texts.sort()
173
                right_texts.sort()
174
                self.assertEqual(left_texts, right_texts)
175
                # signatures
176
                for rev_id in all_revs:
177
                    try:
178
                        left_text = left_repo.get_signature_text(rev_id)
179
                    except errors.NoSuchRevision:
180
                        continue
181
                    right_text = right_repo.get_signature_text(rev_id)
182
                    self.assertEqual(left_text, right_text)
183
            finally:
184
                right_repo.unlock()
185
        finally:
186
            left_repo.unlock()
187
5363.2.30 by Jelmer Vernooij
actually run per_bzrdir tests.
188
    def sproutOrSkip(self, from_bzrdir, to_url, revision_id=None,
189
                     force_new_repo=False, accelerator_tree=None,
190
                     create_tree_if_local=True):
191
        """Sprout from_bzrdir into to_url, or raise TestSkipped.
192
193
        A simple wrapper for from_bzrdir.sprout that translates NotLocalUrl into
194
        TestSkipped.  Returns the newly sprouted bzrdir.
195
        """
196
        to_transport = transport.get_transport(to_url)
197
        if not isinstance(to_transport, LocalTransport):
198
            raise TestSkipped('Cannot sprout to remote bzrdirs.')
199
        target = from_bzrdir.sprout(to_url, revision_id=revision_id,
200
                                    force_new_repo=force_new_repo,
201
                                    possible_transports=[to_transport],
202
                                    accelerator_tree=accelerator_tree,
203
                                    create_tree_if_local=create_tree_if_local)
204
        return target
205
206
    def skipIfNoWorkingTree(self, a_bzrdir):
207
        """Raises TestSkipped if a_bzrdir doesn't have a working tree.
208
209
        If the bzrdir does have a workingtree, this is a no-op.
210
        """
211
        try:
212
            a_bzrdir.open_workingtree()
213
        except (errors.NotLocalUrl, errors.NoWorkingTree):
214
            raise TestSkipped("bzrdir on transport %r has no working tree"
215
                              % a_bzrdir.transport)
216
217
    def createWorkingTreeOrSkip(self, a_bzrdir):
218
        """Create a working tree on a_bzrdir, or raise TestSkipped.
219
220
        A simple wrapper for create_workingtree that translates NotLocalUrl into
221
        TestSkipped.  Returns the newly created working tree.
222
        """
223
        try:
5042.1.3 by Martin Pool
Update a test for BzrDir.create_workingtree so that it covers bug 524627
224
            # This passes in many named options to make sure they're
225
            # understood by subclasses: see
226
            # <https://bugs.launchpad.net/bzr/+bug/524627>.
227
            return a_bzrdir.create_workingtree(
228
                revision_id=None,
229
                from_branch=None,
230
                accelerator_tree=None,
231
                hardlink=False)
5363.2.30 by Jelmer Vernooij
actually run per_bzrdir tests.
232
        except errors.NotLocalUrl:
233
            raise TestSkipped("cannot make working tree with transport %r"
234
                              % a_bzrdir.transport)
235
5363.2.29 by Jelmer Vernooij
Move some bzrdir-specific tests to bzrlib.tests.per_bzrdir.
236
    def test_clone_bzrdir_repository_under_shared_force_new_repo(self):
237
        tree = self.make_branch_and_tree('commit_tree')
238
        self.build_tree(['commit_tree/foo'])
239
        tree.add('foo')
240
        tree.commit('revision 1', rev_id='1')
241
        dir = self.make_bzrdir('source')
242
        repo = dir.create_repository()
243
        repo.fetch(tree.branch.repository)
244
        self.assertTrue(repo.has_revision('1'))
245
        try:
246
            self.make_repository('target', shared=True)
247
        except errors.IncompatibleFormat:
248
            return
249
        target = dir.clone(self.get_url('target/child'), force_new_repo=True)
250
        self.assertNotEqual(dir.transport.base, target.transport.base)
251
        self.assertDirectoriesEqual(dir.root_transport, target.root_transport,
252
                                    ['./.bzr/repository',
253
                                     ])
254
        self.assertRepositoryHasSameItems(tree.branch.repository, repo)
255
256
    def test_clone_bzrdir_branch_and_repo(self):
257
        tree = self.make_branch_and_tree('commit_tree')
258
        self.build_tree(['commit_tree/foo'])
259
        tree.add('foo')
260
        tree.commit('revision 1')
261
        source = self.make_branch('source')
262
        tree.branch.repository.copy_content_into(source.repository)
263
        tree.branch.copy_content_into(source)
264
        dir = source.bzrdir
265
        target = dir.clone(self.get_url('target'))
266
        self.assertNotEqual(dir.transport.base, target.transport.base)
267
        self.assertDirectoriesEqual(dir.root_transport, target.root_transport,
268
                                    [
269
                                     './.bzr/basis-inventory-cache',
270
                                     './.bzr/checkout/stat-cache',
271
                                     './.bzr/merge-hashes',
272
                                     './.bzr/repository',
273
                                     './.bzr/stat-cache',
274
                                    ])
275
        self.assertRepositoryHasSameItems(
276
            tree.branch.repository, target.open_repository())
277
278
    def test_clone_on_transport(self):
279
        a_dir = self.make_bzrdir('source')
280
        target_transport = a_dir.root_transport.clone('..').clone('target')
281
        target = a_dir.clone_on_transport(target_transport)
282
        self.assertNotEqual(a_dir.transport.base, target.transport.base)
283
        self.assertDirectoriesEqual(a_dir.root_transport, target.root_transport,
284
                                    ['./.bzr/merge-hashes'])
285
286
    def test_clone_bzrdir_empty(self):
287
        dir = self.make_bzrdir('source')
288
        target = dir.clone(self.get_url('target'))
289
        self.assertNotEqual(dir.transport.base, target.transport.base)
290
        self.assertDirectoriesEqual(dir.root_transport, target.root_transport,
291
                                    ['./.bzr/merge-hashes'])
292
293
    def test_clone_bzrdir_empty_force_new_ignored(self):
294
        # the force_new_repo parameter should have no effect on an empty
295
        # bzrdir's clone logic
296
        dir = self.make_bzrdir('source')
297
        target = dir.clone(self.get_url('target'), force_new_repo=True)
298
        self.assertNotEqual(dir.transport.base, target.transport.base)
299
        self.assertDirectoriesEqual(dir.root_transport, target.root_transport,
300
                                    ['./.bzr/merge-hashes'])
301
302
    def test_clone_bzrdir_repository(self):
303
        tree = self.make_branch_and_tree('commit_tree')
304
        self.build_tree(['foo'], transport=tree.bzrdir.transport.clone('..'))
305
        tree.add('foo')
306
        tree.commit('revision 1', rev_id='1')
307
        dir = self.make_bzrdir('source')
308
        repo = dir.create_repository()
309
        repo.fetch(tree.branch.repository)
310
        self.assertTrue(repo.has_revision('1'))
311
        target = dir.clone(self.get_url('target'))
312
        self.assertNotEqual(dir.transport.base, target.transport.base)
313
        self.assertDirectoriesEqual(dir.root_transport, target.root_transport,
314
                                    [
315
                                     './.bzr/merge-hashes',
316
                                     './.bzr/repository',
317
                                     ])
318
        self.assertRepositoryHasSameItems(tree.branch.repository,
319
            target.open_repository())
320
321
    def test_clone_bzrdir_tree_branch_repo(self):
322
        tree = self.make_branch_and_tree('source')
323
        self.build_tree(['source/foo'])
324
        tree.add('foo')
325
        tree.commit('revision 1')
326
        dir = tree.bzrdir
327
        target = dir.clone(self.get_url('target'))
328
        self.skipIfNoWorkingTree(target)
329
        self.assertNotEqual(dir.transport.base, target.transport.base)
330
        self.assertDirectoriesEqual(dir.root_transport, target.root_transport,
331
                                    ['./.bzr/stat-cache',
332
                                     './.bzr/checkout/dirstate',
333
                                     './.bzr/checkout/stat-cache',
334
                                     './.bzr/checkout/merge-hashes',
335
                                     './.bzr/merge-hashes',
336
                                     './.bzr/repository',
337
                                     ])
338
        self.assertRepositoryHasSameItems(tree.branch.repository,
6182.1.9 by Jelmer Vernooij
More test fixes.
339
            target.open_branch().repository)
5363.2.29 by Jelmer Vernooij
Move some bzrdir-specific tests to bzrlib.tests.per_bzrdir.
340
        target.open_workingtree().revert()
341
342
    def test_revert_inventory(self):
343
        tree = self.make_branch_and_tree('source')
344
        self.build_tree(['source/foo'])
345
        tree.add('foo')
346
        tree.commit('revision 1')
347
        dir = tree.bzrdir
348
        target = dir.clone(self.get_url('target'))
349
        self.skipIfNoWorkingTree(target)
350
        self.assertDirectoriesEqual(dir.root_transport, target.root_transport,
351
                                    ['./.bzr/stat-cache',
352
                                     './.bzr/checkout/dirstate',
353
                                     './.bzr/checkout/stat-cache',
354
                                     './.bzr/checkout/merge-hashes',
355
                                     './.bzr/merge-hashes',
356
                                     './.bzr/repository',
357
                                     ])
358
        self.assertRepositoryHasSameItems(tree.branch.repository,
6182.1.9 by Jelmer Vernooij
More test fixes.
359
            target.open_branch().repository)
5363.2.29 by Jelmer Vernooij
Move some bzrdir-specific tests to bzrlib.tests.per_bzrdir.
360
361
        target.open_workingtree().revert()
362
        self.assertDirectoriesEqual(dir.root_transport, target.root_transport,
363
                                    ['./.bzr/stat-cache',
364
                                     './.bzr/checkout/dirstate',
365
                                     './.bzr/checkout/stat-cache',
366
                                     './.bzr/checkout/merge-hashes',
367
                                     './.bzr/merge-hashes',
368
                                     './.bzr/repository',
369
                                     ])
370
        self.assertRepositoryHasSameItems(tree.branch.repository,
6182.1.9 by Jelmer Vernooij
More test fixes.
371
            target.open_branch().repository)
5363.2.29 by Jelmer Vernooij
Move some bzrdir-specific tests to bzrlib.tests.per_bzrdir.
372
373
    def test_clone_bzrdir_tree_branch_reference(self):
374
        # a tree with a branch reference (aka a checkout)
375
        # should stay a checkout on clone.
376
        referenced_branch = self.make_branch('referencced')
377
        dir = self.make_bzrdir('source')
378
        try:
6437.7.3 by Jelmer Vernooij
Use ControlDir.set_branch_reference.
379
            dir.set_branch_reference(referenced_branch)
5363.2.29 by Jelmer Vernooij
Move some bzrdir-specific tests to bzrlib.tests.per_bzrdir.
380
        except errors.IncompatibleFormat:
381
            # this is ok too, not all formats have to support references.
382
            return
383
        self.createWorkingTreeOrSkip(dir)
384
        target = dir.clone(self.get_url('target'))
385
        self.skipIfNoWorkingTree(target)
386
        self.assertNotEqual(dir.transport.base, target.transport.base)
387
        self.assertDirectoriesEqual(dir.root_transport, target.root_transport,
388
                                    ['./.bzr/stat-cache',
389
                                     './.bzr/checkout/stat-cache',
390
                                     './.bzr/checkout/merge-hashes',
391
                                     './.bzr/merge-hashes',
392
                                     './.bzr/repository/inventory.knit',
393
                                     ])
394
395
    def test_clone_bzrdir_branch_and_repo_into_shared_repo_force_new_repo(self):
396
        # by default cloning into a shared repo uses the shared repo.
397
        tree = self.make_branch_and_tree('commit_tree')
398
        self.build_tree(['commit_tree/foo'])
399
        tree.add('foo')
400
        tree.commit('revision 1')
401
        source = self.make_branch('source')
402
        tree.branch.repository.copy_content_into(source.repository)
403
        tree.branch.copy_content_into(source)
404
        try:
405
            self.make_repository('target', shared=True)
406
        except errors.IncompatibleFormat:
407
            return
408
        dir = source.bzrdir
409
        target = dir.clone(self.get_url('target/child'), force_new_repo=True)
410
        self.assertNotEqual(dir.transport.base, target.transport.base)
411
        repo = target.open_repository()
412
        self.assertDirectoriesEqual(dir.root_transport, target.root_transport,
413
                                    ['./.bzr/repository',
414
                                     ])
415
        self.assertRepositoryHasSameItems(tree.branch.repository, repo)
416
417
    def test_clone_bzrdir_branch_reference(self):
418
        # cloning should preserve the reference status of the branch in a bzrdir
419
        referenced_branch = self.make_branch('referencced')
420
        dir = self.make_bzrdir('source')
421
        try:
6437.7.3 by Jelmer Vernooij
Use ControlDir.set_branch_reference.
422
            dir.set_branch_reference(referenced_branch)
5363.2.29 by Jelmer Vernooij
Move some bzrdir-specific tests to bzrlib.tests.per_bzrdir.
423
        except errors.IncompatibleFormat:
424
            # this is ok too, not all formats have to support references.
425
            return
426
        target = dir.clone(self.get_url('target'))
427
        self.assertNotEqual(dir.transport.base, target.transport.base)
428
        self.assertDirectoriesEqual(dir.root_transport, target.root_transport)
429
430
    def test_sprout_bzrdir_repository(self):
431
        tree = self.make_branch_and_tree('commit_tree')
432
        self.build_tree(['foo'], transport=tree.bzrdir.transport.clone('..'))
433
        tree.add('foo')
434
        tree.commit('revision 1', rev_id='1')
435
        dir = self.make_bzrdir('source')
436
        repo = dir.create_repository()
437
        repo.fetch(tree.branch.repository)
438
        self.assertTrue(repo.has_revision('1'))
439
        try:
440
            self.assertTrue(
441
                _mod_revision.is_null(_mod_revision.ensure_null(
442
                dir.open_branch().last_revision())))
443
        except errors.NotBranchError:
444
            pass
445
        target = dir.sprout(self.get_url('target'))
446
        self.assertNotEqual(dir.transport.base, target.transport.base)
447
        # testing inventory isn't reasonable for repositories
448
        self.assertDirectoriesEqual(dir.root_transport, target.root_transport,
449
                                    [
450
                                     './.bzr/branch',
451
                                     './.bzr/checkout',
452
                                     './.bzr/inventory',
453
                                     './.bzr/parent',
454
                                     './.bzr/repository/inventory.knit',
455
                                     ])
456
        try:
457
            local_inventory = dir.transport.local_abspath('inventory')
458
        except errors.NotLocalUrl:
459
            return
460
        try:
461
            # If we happen to have a tree, we'll guarantee everything
462
            # except for the tree root is the same.
463
            inventory_f = file(local_inventory, 'rb')
464
            self.addCleanup(inventory_f.close)
465
            self.assertContainsRe(inventory_f.read(),
466
                                  '<inventory format="5">\n</inventory>\n')
467
        except IOError, e:
468
            if e.errno != errno.ENOENT:
469
                raise
470
471
    def test_sprout_bzrdir_branch_and_repo(self):
472
        tree = self.make_branch_and_tree('commit_tree')
473
        self.build_tree(['commit_tree/foo'])
474
        tree.add('foo')
475
        tree.commit('revision 1')
476
        source = self.make_branch('source')
477
        tree.branch.repository.copy_content_into(source.repository)
478
        tree.bzrdir.open_branch().copy_content_into(source)
479
        dir = source.bzrdir
480
        target = dir.sprout(self.get_url('target'))
481
        self.assertNotEqual(dir.transport.base, target.transport.base)
482
        target_repo = target.open_repository()
483
        self.assertRepositoryHasSameItems(source.repository, target_repo)
484
        self.assertDirectoriesEqual(dir.root_transport, target.root_transport,
485
                                    [
486
                                     './.bzr/basis-inventory-cache',
487
                                     './.bzr/branch/branch.conf',
488
                                     './.bzr/branch/parent',
489
                                     './.bzr/checkout',
490
                                     './.bzr/checkout/inventory',
491
                                     './.bzr/checkout/stat-cache',
492
                                     './.bzr/inventory',
493
                                     './.bzr/parent',
494
                                     './.bzr/repository',
495
                                     './.bzr/stat-cache',
496
                                     './foo',
497
                                     ])
498
499
    def test_sprout_bzrdir_tree_branch_repo(self):
500
        tree = self.make_branch_and_tree('source')
501
        self.build_tree(['foo'], transport=tree.bzrdir.transport.clone('..'))
502
        tree.add('foo')
503
        tree.commit('revision 1')
504
        dir = tree.bzrdir
505
        target = self.sproutOrSkip(dir, self.get_url('target'))
506
        self.assertNotEqual(dir.transport.base, target.transport.base)
507
        self.assertDirectoriesEqual(dir.root_transport, target.root_transport,
508
                                    [
6182.1.10 by Jelmer Vernooij
Fix test.
509
                                     './.bzr/branch',
5363.2.29 by Jelmer Vernooij
Move some bzrdir-specific tests to bzrlib.tests.per_bzrdir.
510
                                     './.bzr/checkout/dirstate',
511
                                     './.bzr/checkout/stat-cache',
512
                                     './.bzr/checkout/inventory',
513
                                     './.bzr/inventory',
514
                                     './.bzr/parent',
515
                                     './.bzr/repository',
516
                                     './.bzr/stat-cache',
517
                                     ])
518
        self.assertRepositoryHasSameItems(
519
            tree.branch.repository, target.open_repository())
520
521
522
    def test_retire_bzrdir(self):
523
        bd = self.make_bzrdir('.')
524
        transport = bd.root_transport
525
        # must not overwrite existing directories
526
        self.build_tree(['.bzr.retired.0/', '.bzr.retired.0/junk',],
527
            transport=transport)
5784.1.1 by Martin Pool
Stop using failIf, failUnless, etc
528
        self.assertTrue(transport.has('.bzr'))
5363.2.29 by Jelmer Vernooij
Move some bzrdir-specific tests to bzrlib.tests.per_bzrdir.
529
        bd.retire_bzrdir()
5784.1.1 by Martin Pool
Stop using failIf, failUnless, etc
530
        self.assertFalse(transport.has('.bzr'))
531
        self.assertTrue(transport.has('.bzr.retired.1'))
5363.2.29 by Jelmer Vernooij
Move some bzrdir-specific tests to bzrlib.tests.per_bzrdir.
532
533
    def test_retire_bzrdir_limited(self):
534
        bd = self.make_bzrdir('.')
535
        transport = bd.root_transport
536
        # must not overwrite existing directories
537
        self.build_tree(['.bzr.retired.0/', '.bzr.retired.0/junk',],
538
            transport=transport)
5784.1.1 by Martin Pool
Stop using failIf, failUnless, etc
539
        self.assertTrue(transport.has('.bzr'))
5363.2.29 by Jelmer Vernooij
Move some bzrdir-specific tests to bzrlib.tests.per_bzrdir.
540
        self.assertRaises((errors.FileExists, errors.DirectoryNotEmpty),
541
            bd.retire_bzrdir, limit=0)
5699.4.1 by Jelmer Vernooij
Move get_branch_transport, .get_workingtree_transport and .get_repository_transport
542
543
    def test_get_branch_transport(self):
544
        dir = self.make_bzrdir('.')
545
        # without a format, get_branch_transport gives use a transport
546
        # which -may- point to an existing dir.
547
        self.assertTrue(isinstance(dir.get_branch_transport(None),
548
                                   transport.Transport))
549
        # with a given format, either the bzr dir supports identifiable
550
        # branches, or it supports anonymous branch formats, but not both.
551
        anonymous_format = AnonymousTestBranchFormat()
552
        identifiable_format = IdentifiableTestBranchFormat()
553
        try:
554
            found_transport = dir.get_branch_transport(anonymous_format)
555
            self.assertRaises(errors.IncompatibleFormat,
556
                              dir.get_branch_transport,
557
                              identifiable_format)
558
        except errors.IncompatibleFormat:
559
            found_transport = dir.get_branch_transport(identifiable_format)
560
        self.assertTrue(isinstance(found_transport, transport.Transport))
561
        # and the dir which has been initialized for us must exist.
562
        found_transport.list_dir('.')
563
564
    def test_get_repository_transport(self):
565
        dir = self.make_bzrdir('.')
566
        # without a format, get_repository_transport gives use a transport
567
        # which -may- point to an existing dir.
568
        self.assertTrue(isinstance(dir.get_repository_transport(None),
569
                                   transport.Transport))
570
        # with a given format, either the bzr dir supports identifiable
571
        # repositories, or it supports anonymous repository formats, but not both.
572
        anonymous_format = AnonymousTestRepositoryFormat()
573
        identifiable_format = IdentifiableTestRepositoryFormat()
574
        try:
575
            found_transport = dir.get_repository_transport(anonymous_format)
576
            self.assertRaises(errors.IncompatibleFormat,
577
                              dir.get_repository_transport,
578
                              identifiable_format)
579
        except errors.IncompatibleFormat:
580
            found_transport = dir.get_repository_transport(identifiable_format)
581
        self.assertTrue(isinstance(found_transport, transport.Transport))
582
        # and the dir which has been initialized for us must exist.
583
        found_transport.list_dir('.')
584
585
    def test_get_workingtree_transport(self):
586
        dir = self.make_bzrdir('.')
587
        # without a format, get_workingtree_transport gives use a transport
588
        # which -may- point to an existing dir.
589
        self.assertTrue(isinstance(dir.get_workingtree_transport(None),
590
                                   transport.Transport))
591
        # with a given format, either the bzr dir supports identifiable
592
        # trees, or it supports anonymous tree formats, but not both.
593
        anonymous_format = AnonymousTestWorkingTreeFormat()
594
        identifiable_format = IdentifiableTestWorkingTreeFormat()
595
        try:
596
            found_transport = dir.get_workingtree_transport(anonymous_format)
597
            self.assertRaises(errors.IncompatibleFormat,
598
                              dir.get_workingtree_transport,
599
                              identifiable_format)
600
        except errors.IncompatibleFormat:
601
            found_transport = dir.get_workingtree_transport(identifiable_format)
602
        self.assertTrue(isinstance(found_transport, transport.Transport))
603
        # and the dir which has been initialized for us must exist.
604
        found_transport.list_dir('.')
6164.2.5 by Jelmer Vernooij
Move some stacking tests specific to bzr formats to per_bzrdir.
605
606
    def assertInitializeEx(self, t, need_meta=False, **kwargs):
607
        """Execute initialize_on_transport_ex and check it succeeded correctly.
608
609
        This involves checking that the disk objects were created, open with
610
        the same format returned, and had the expected disk format.
611
612
        :param t: The transport to initialize on.
613
        :param **kwargs: Additional arguments to pass to
614
            initialize_on_transport_ex.
615
        :return: the resulting repo, control dir tuple.
616
        """
617
        if not self.bzrdir_format.is_initializable():
618
            raise TestNotApplicable("control dir format is not "
619
                "initializable")
620
        repo, control, require_stacking, repo_policy = \
621
            self.bzrdir_format.initialize_on_transport_ex(t, **kwargs)
622
        if repo is not None:
623
            # Repositories are open write-locked
624
            self.assertTrue(repo.is_write_locked())
625
            self.addCleanup(repo.unlock)
626
        self.assertIsInstance(control, bzrdir.BzrDir)
627
        opened = bzrdir.BzrDir.open(t.base)
628
        expected_format = self.bzrdir_format
629
        if need_meta and expected_format.fixed_components:
630
            # Pre-metadir formats change when we are making something that
631
            # needs a metaformat, because clone is used for push.
632
            expected_format = bzrdir.BzrDirMetaFormat1()
633
        if not isinstance(expected_format, RemoteBzrDirFormat):
634
            self.assertEqual(control._format.network_name(),
635
                expected_format.network_name())
636
            self.assertEqual(control._format.network_name(),
637
                opened._format.network_name())
638
        self.assertEqual(control.__class__, opened.__class__)
639
        return repo, control
640
641
    def test_format_initialize_on_transport_ex_default_stack_on(self):
642
        # When initialize_on_transport_ex uses a stacked-on branch because of
643
        # a stacking policy on the target, the location of the fallback
644
        # repository is the same as the external location of the stacked-on
645
        # branch.
646
        balloon = self.make_bzrdir('balloon')
647
        if isinstance(balloon._format, bzrdir.BzrDirMetaFormat1):
648
            stack_on = self.make_branch('stack-on', format='1.9')
649
        else:
650
            stack_on = self.make_branch('stack-on')
6164.2.10 by Jelmer Vernooij
Merge more-foreign-tests-fixes-7
651
        if not stack_on.repository._format.supports_nesting_repositories:
652
            raise TestNotApplicable("requires nesting repositories")
6164.2.5 by Jelmer Vernooij
Move some stacking tests specific to bzr formats to per_bzrdir.
653
        config = self.make_bzrdir('.').get_config()
654
        try:
655
            config.set_default_stack_on('stack-on')
656
        except errors.BzrError:
657
            raise TestNotApplicable('Only relevant for stackable formats.')
658
        # Initialize a bzrdir subject to the policy.
659
        t = self.get_transport('stacked')
6472.2.1 by Jelmer Vernooij
Use bzrdir.controldir for generic access to control directories.
660
        repo_fmt = controldir.format_registry.make_bzrdir('1.9')
6164.2.5 by Jelmer Vernooij
Move some stacking tests specific to bzr formats to per_bzrdir.
661
        repo_name = repo_fmt.repository_format.network_name()
662
        repo, control = self.assertInitializeEx(
663
            t, need_meta=True, repo_format_name=repo_name, stacked_on=None)
664
        # self.addCleanup(repo.unlock)
665
        # There's one fallback repo, with a public location.
666
        self.assertLength(1, repo._fallback_repositories)
667
        fallback_repo = repo._fallback_repositories[0]
668
        self.assertEqual(
669
            stack_on.base, fallback_repo.bzrdir.root_transport.base)
670
        # The bzrdir creates a branch in stacking-capable format.
671
        new_branch = control.create_branch()
672
        self.assertTrue(new_branch._format.supports_stacking())
673
6239.1.2 by Jelmer Vernooij
Move test to per_bzrdir.
674
    def test_no_leftover_dirs(self):
675
        # bug 886196: development-colo uses a branch-lock directory
676
        # in the user directory rather than the control directory.
677
        if not self.bzrdir_format.colocated_branches:
678
            raise TestNotApplicable(
679
                "format does not support colocated branches")
680
        branch = self.make_branch('.', format='development-colo')
681
        branch.bzrdir.create_branch(name="another-colocated-branch")
682
        self.assertEquals(
683
            branch.bzrdir.user_transport.list_dir("."),
684
            [".bzr"])
6282.5.8 by Neil Martinsen-Burrell
refine tests
685
686
    def test_get_branches(self):
687
        repo = self.make_repository('branch-1')
6437.21.7 by Jelmer Vernooij
Fix remaining tests.
688
        if not repo.bzrdir._format.colocated_branches:
6282.5.11 by Jelmer Vernooij
Review tweaks.
689
            raise TestNotApplicable('Format does not support colocation')
6437.21.7 by Jelmer Vernooij
Fix remaining tests.
690
        target_branch = repo.bzrdir.create_branch(name='foo')
6437.7.3 by Jelmer Vernooij
Use ControlDir.set_branch_reference.
691
        repo.bzrdir.set_branch_reference(target_branch)
6436.1.3 by Jelmer Vernooij
Fix remaining tests.
692
        self.assertEqual(set(["", 'foo']),
6282.5.11 by Jelmer Vernooij
Review tweaks.
693
                         set(repo.bzrdir.get_branches().keys()))