/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_bzrdir.py

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2008-07-07 08:34:51 UTC
  • mfrom: (3517.4.2 annotate)
  • Revision ID: pqm@pqm.ubuntu.com-20080707083451-33s2p0jaawgzkyfk
(mbp, for robertc) simple annotation on stacked knits

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright (C) 2005, 2006, 2007 Canonical Ltd
 
2
 
3
# This program is free software; you can redistribute it and/or modify
 
4
# it under the terms of the GNU General Public License as published by
 
5
# the Free Software Foundation; either version 2 of the License, or
 
6
# (at your option) any later version.
 
7
#
 
8
# This program is distributed in the hope that it will be useful,
 
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
11
# GNU General Public License for more details.
 
12
#
 
13
# You should have received a copy of the GNU General Public License
 
14
# along with this program; if not, write to the Free Software
 
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
16
 
 
17
"""Tests for the BzrDir facility and any format specific tests.
 
18
 
 
19
For interface contract tests, see tests/bzr_dir_implementations.
 
20
"""
 
21
 
 
22
import os
 
23
import os.path
 
24
from StringIO import StringIO
 
25
import subprocess
 
26
import sys
 
27
 
 
28
from bzrlib import (
 
29
    bzrdir,
 
30
    errors,
 
31
    help_topics,
 
32
    repository,
 
33
    symbol_versioning,
 
34
    urlutils,
 
35
    win32utils,
 
36
    workingtree,
 
37
    )
 
38
import bzrlib.branch
 
39
from bzrlib.errors import (NotBranchError,
 
40
                           UnknownFormatError,
 
41
                           UnsupportedFormatError,
 
42
                           )
 
43
from bzrlib.tests import (
 
44
    TestCase,
 
45
    TestCaseWithTransport,
 
46
    TestSkipped,
 
47
    test_sftp_transport
 
48
    )
 
49
from bzrlib.tests.http_server import HttpServer
 
50
from bzrlib.tests.http_utils import (
 
51
    TestCaseWithTwoWebservers,
 
52
    HTTPServerRedirecting,
 
53
    )
 
54
from bzrlib.tests.test_http import TestWithTransport_pycurl
 
55
from bzrlib.transport import get_transport
 
56
from bzrlib.transport.http._urllib import HttpTransport_urllib
 
57
from bzrlib.transport.memory import MemoryServer
 
58
from bzrlib.repofmt import knitrepo, weaverepo
 
59
 
 
60
 
 
61
class TestDefaultFormat(TestCase):
 
62
 
 
63
    def test_get_set_default_format(self):
 
64
        old_format = bzrdir.BzrDirFormat.get_default_format()
 
65
        # default is BzrDirFormat6
 
66
        self.failUnless(isinstance(old_format, bzrdir.BzrDirMetaFormat1))
 
67
        bzrdir.BzrDirFormat._set_default_format(SampleBzrDirFormat())
 
68
        # creating a bzr dir should now create an instrumented dir.
 
69
        try:
 
70
            result = bzrdir.BzrDir.create('memory:///')
 
71
            self.failUnless(isinstance(result, SampleBzrDir))
 
72
        finally:
 
73
            bzrdir.BzrDirFormat._set_default_format(old_format)
 
74
        self.assertEqual(old_format, bzrdir.BzrDirFormat.get_default_format())
 
75
 
 
76
 
 
77
class TestFormatRegistry(TestCase):
 
78
 
 
79
    def make_format_registry(self):
 
80
        my_format_registry = bzrdir.BzrDirFormatRegistry()
 
81
        my_format_registry.register('weave', bzrdir.BzrDirFormat6,
 
82
            'Pre-0.8 format.  Slower and does not support checkouts or shared'
 
83
            ' repositories', deprecated=True)
 
84
        my_format_registry.register_lazy('lazy', 'bzrlib.bzrdir', 
 
85
            'BzrDirFormat6', 'Format registered lazily', deprecated=True)
 
86
        my_format_registry.register_metadir('knit',
 
87
            'bzrlib.repofmt.knitrepo.RepositoryFormatKnit1',
 
88
            'Format using knits',
 
89
            )
 
90
        my_format_registry.set_default('knit')
 
91
        my_format_registry.register_metadir(
 
92
            'branch6',
 
93
            'bzrlib.repofmt.knitrepo.RepositoryFormatKnit3',
 
94
            'Experimental successor to knit.  Use at your own risk.',
 
95
            branch_format='bzrlib.branch.BzrBranchFormat6',
 
96
            experimental=True)
 
97
        my_format_registry.register_metadir(
 
98
            'hidden format',
 
99
            'bzrlib.repofmt.knitrepo.RepositoryFormatKnit3',
 
100
            'Experimental successor to knit.  Use at your own risk.',
 
101
            branch_format='bzrlib.branch.BzrBranchFormat6', hidden=True)
 
102
        my_format_registry.register('hiddenweave', bzrdir.BzrDirFormat6,
 
103
            'Pre-0.8 format.  Slower and does not support checkouts or shared'
 
104
            ' repositories', hidden=True)
 
105
        my_format_registry.register_lazy('hiddenlazy', 'bzrlib.bzrdir',
 
106
            'BzrDirFormat6', 'Format registered lazily', deprecated=True,
 
107
            hidden=True)
 
108
        return my_format_registry
 
109
 
 
110
    def test_format_registry(self):
 
111
        my_format_registry = self.make_format_registry()
 
112
        my_bzrdir = my_format_registry.make_bzrdir('lazy')
 
113
        self.assertIsInstance(my_bzrdir, bzrdir.BzrDirFormat6)
 
114
        my_bzrdir = my_format_registry.make_bzrdir('weave')
 
115
        self.assertIsInstance(my_bzrdir, bzrdir.BzrDirFormat6)
 
116
        my_bzrdir = my_format_registry.make_bzrdir('default')
 
117
        self.assertIsInstance(my_bzrdir.repository_format, 
 
118
            knitrepo.RepositoryFormatKnit1)
 
119
        my_bzrdir = my_format_registry.make_bzrdir('knit')
 
120
        self.assertIsInstance(my_bzrdir.repository_format, 
 
121
            knitrepo.RepositoryFormatKnit1)
 
122
        my_bzrdir = my_format_registry.make_bzrdir('branch6')
 
123
        self.assertIsInstance(my_bzrdir.get_branch_format(),
 
124
                              bzrlib.branch.BzrBranchFormat6)
 
125
 
 
126
    def test_get_help(self):
 
127
        my_format_registry = self.make_format_registry()
 
128
        self.assertEqual('Format registered lazily',
 
129
                         my_format_registry.get_help('lazy'))
 
130
        self.assertEqual('Format using knits', 
 
131
                         my_format_registry.get_help('knit'))
 
132
        self.assertEqual('Format using knits', 
 
133
                         my_format_registry.get_help('default'))
 
134
        self.assertEqual('Pre-0.8 format.  Slower and does not support'
 
135
                         ' checkouts or shared repositories', 
 
136
                         my_format_registry.get_help('weave'))
 
137
        
 
138
    def test_help_topic(self):
 
139
        topics = help_topics.HelpTopicRegistry()
 
140
        topics.register('formats', self.make_format_registry().help_topic, 
 
141
                        'Directory formats')
 
142
        topic = topics.get_detail('formats')
 
143
        new, rest = topic.split('Experimental formats')
 
144
        experimental, deprecated = rest.split('Deprecated formats')
 
145
        self.assertContainsRe(new, 'These formats can be used')
 
146
        self.assertContainsRe(new, 
 
147
                ':knit:\n    \(native\) \(default\) Format using knits\n')
 
148
        self.assertContainsRe(experimental, 
 
149
                ':branch6:\n    \(native\) Experimental successor to knit')
 
150
        self.assertContainsRe(deprecated, 
 
151
                ':lazy:\n    \(native\) Format registered lazily\n')
 
152
        self.assertNotContainsRe(new, 'hidden')
 
153
 
 
154
    def test_set_default_repository(self):
 
155
        default_factory = bzrdir.format_registry.get('default')
 
156
        old_default = [k for k, v in bzrdir.format_registry.iteritems()
 
157
                       if v == default_factory and k != 'default'][0]
 
158
        bzrdir.format_registry.set_default_repository('dirstate-with-subtree')
 
159
        try:
 
160
            self.assertIs(bzrdir.format_registry.get('dirstate-with-subtree'),
 
161
                          bzrdir.format_registry.get('default'))
 
162
            self.assertIs(
 
163
                repository.RepositoryFormat.get_default_format().__class__,
 
164
                knitrepo.RepositoryFormatKnit3)
 
165
        finally:
 
166
            bzrdir.format_registry.set_default_repository(old_default)
 
167
 
 
168
    def test_aliases(self):
 
169
        a_registry = bzrdir.BzrDirFormatRegistry()
 
170
        a_registry.register('weave', bzrdir.BzrDirFormat6,
 
171
            'Pre-0.8 format.  Slower and does not support checkouts or shared'
 
172
            ' repositories', deprecated=True)
 
173
        a_registry.register('weavealias', bzrdir.BzrDirFormat6,
 
174
            'Pre-0.8 format.  Slower and does not support checkouts or shared'
 
175
            ' repositories', deprecated=True, alias=True)
 
176
        self.assertEqual(frozenset(['weavealias']), a_registry.aliases())
 
177
    
 
178
 
 
179
class SampleBranch(bzrlib.branch.Branch):
 
180
    """A dummy branch for guess what, dummy use."""
 
181
 
 
182
    def __init__(self, dir):
 
183
        self.bzrdir = dir
 
184
 
 
185
 
 
186
class SampleBzrDir(bzrdir.BzrDir):
 
187
    """A sample BzrDir implementation to allow testing static methods."""
 
188
 
 
189
    def create_repository(self, shared=False):
 
190
        """See BzrDir.create_repository."""
 
191
        return "A repository"
 
192
 
 
193
    def open_repository(self):
 
194
        """See BzrDir.open_repository."""
 
195
        return "A repository"
 
196
 
 
197
    def create_branch(self):
 
198
        """See BzrDir.create_branch."""
 
199
        return SampleBranch(self)
 
200
 
 
201
    def create_workingtree(self):
 
202
        """See BzrDir.create_workingtree."""
 
203
        return "A tree"
 
204
 
 
205
 
 
206
class SampleBzrDirFormat(bzrdir.BzrDirFormat):
 
207
    """A sample format
 
208
 
 
209
    this format is initializable, unsupported to aid in testing the 
 
210
    open and open_downlevel routines.
 
211
    """
 
212
 
 
213
    def get_format_string(self):
 
214
        """See BzrDirFormat.get_format_string()."""
 
215
        return "Sample .bzr dir format."
 
216
 
 
217
    def initialize_on_transport(self, t):
 
218
        """Create a bzr dir."""
 
219
        t.mkdir('.bzr')
 
220
        t.put_bytes('.bzr/branch-format', self.get_format_string())
 
221
        return SampleBzrDir(t, self)
 
222
 
 
223
    def is_supported(self):
 
224
        return False
 
225
 
 
226
    def open(self, transport, _found=None):
 
227
        return "opened branch."
 
228
 
 
229
 
 
230
class TestBzrDirFormat(TestCaseWithTransport):
 
231
    """Tests for the BzrDirFormat facility."""
 
232
 
 
233
    def test_find_format(self):
 
234
        # is the right format object found for a branch?
 
235
        # create a branch with a few known format objects.
 
236
        # this is not quite the same as 
 
237
        t = get_transport(self.get_url())
 
238
        self.build_tree(["foo/", "bar/"], transport=t)
 
239
        def check_format(format, url):
 
240
            format.initialize(url)
 
241
            t = get_transport(url)
 
242
            found_format = bzrdir.BzrDirFormat.find_format(t)
 
243
            self.failUnless(isinstance(found_format, format.__class__))
 
244
        check_format(bzrdir.BzrDirFormat5(), "foo")
 
245
        check_format(bzrdir.BzrDirFormat6(), "bar")
 
246
        
 
247
    def test_find_format_nothing_there(self):
 
248
        self.assertRaises(NotBranchError,
 
249
                          bzrdir.BzrDirFormat.find_format,
 
250
                          get_transport('.'))
 
251
 
 
252
    def test_find_format_unknown_format(self):
 
253
        t = get_transport(self.get_url())
 
254
        t.mkdir('.bzr')
 
255
        t.put_bytes('.bzr/branch-format', '')
 
256
        self.assertRaises(UnknownFormatError,
 
257
                          bzrdir.BzrDirFormat.find_format,
 
258
                          get_transport('.'))
 
259
 
 
260
    def test_register_unregister_format(self):
 
261
        format = SampleBzrDirFormat()
 
262
        url = self.get_url()
 
263
        # make a bzrdir
 
264
        format.initialize(url)
 
265
        # register a format for it.
 
266
        bzrdir.BzrDirFormat.register_format(format)
 
267
        # which bzrdir.Open will refuse (not supported)
 
268
        self.assertRaises(UnsupportedFormatError, bzrdir.BzrDir.open, url)
 
269
        # which bzrdir.open_containing will refuse (not supported)
 
270
        self.assertRaises(UnsupportedFormatError, bzrdir.BzrDir.open_containing, url)
 
271
        # but open_downlevel will work
 
272
        t = get_transport(url)
 
273
        self.assertEqual(format.open(t), bzrdir.BzrDir.open_unsupported(url))
 
274
        # unregister the format
 
275
        bzrdir.BzrDirFormat.unregister_format(format)
 
276
        # now open_downlevel should fail too.
 
277
        self.assertRaises(UnknownFormatError, bzrdir.BzrDir.open_unsupported, url)
 
278
 
 
279
    def test_create_branch_and_repo_uses_default(self):
 
280
        format = SampleBzrDirFormat()
 
281
        branch = bzrdir.BzrDir.create_branch_and_repo(self.get_url(),
 
282
                                                      format=format)
 
283
        self.assertTrue(isinstance(branch, SampleBranch))
 
284
 
 
285
    def test_create_branch_and_repo_under_shared(self):
 
286
        # creating a branch and repo in a shared repo uses the
 
287
        # shared repository
 
288
        format = bzrdir.format_registry.make_bzrdir('knit')
 
289
        self.make_repository('.', shared=True, format=format)
 
290
        branch = bzrdir.BzrDir.create_branch_and_repo(
 
291
            self.get_url('child'), format=format)
 
292
        self.assertRaises(errors.NoRepositoryPresent,
 
293
                          branch.bzrdir.open_repository)
 
294
 
 
295
    def test_create_branch_and_repo_under_shared_force_new(self):
 
296
        # creating a branch and repo in a shared repo can be forced to 
 
297
        # make a new repo
 
298
        format = bzrdir.format_registry.make_bzrdir('knit')
 
299
        self.make_repository('.', shared=True, format=format)
 
300
        branch = bzrdir.BzrDir.create_branch_and_repo(self.get_url('child'),
 
301
                                                      force_new_repo=True,
 
302
                                                      format=format)
 
303
        branch.bzrdir.open_repository()
 
304
 
 
305
    def test_create_standalone_working_tree(self):
 
306
        format = SampleBzrDirFormat()
 
307
        # note this is deliberately readonly, as this failure should 
 
308
        # occur before any writes.
 
309
        self.assertRaises(errors.NotLocalUrl,
 
310
                          bzrdir.BzrDir.create_standalone_workingtree,
 
311
                          self.get_readonly_url(), format=format)
 
312
        tree = bzrdir.BzrDir.create_standalone_workingtree('.', 
 
313
                                                           format=format)
 
314
        self.assertEqual('A tree', tree)
 
315
 
 
316
    def test_create_standalone_working_tree_under_shared_repo(self):
 
317
        # create standalone working tree always makes a repo.
 
318
        format = bzrdir.format_registry.make_bzrdir('knit')
 
319
        self.make_repository('.', shared=True, format=format)
 
320
        # note this is deliberately readonly, as this failure should 
 
321
        # occur before any writes.
 
322
        self.assertRaises(errors.NotLocalUrl,
 
323
                          bzrdir.BzrDir.create_standalone_workingtree,
 
324
                          self.get_readonly_url('child'), format=format)
 
325
        tree = bzrdir.BzrDir.create_standalone_workingtree('child', 
 
326
            format=format)
 
327
        tree.bzrdir.open_repository()
 
328
 
 
329
    def test_create_branch_convenience(self):
 
330
        # outside a repo the default convenience output is a repo+branch_tree
 
331
        format = bzrdir.format_registry.make_bzrdir('knit')
 
332
        branch = bzrdir.BzrDir.create_branch_convenience('.', format=format)
 
333
        branch.bzrdir.open_workingtree()
 
334
        branch.bzrdir.open_repository()
 
335
 
 
336
    def test_create_branch_convenience_possible_transports(self):
 
337
        """Check that the optional 'possible_transports' is recognized"""
 
338
        format = bzrdir.format_registry.make_bzrdir('knit')
 
339
        t = self.get_transport()
 
340
        branch = bzrdir.BzrDir.create_branch_convenience(
 
341
            '.', format=format, possible_transports=[t])
 
342
        branch.bzrdir.open_workingtree()
 
343
        branch.bzrdir.open_repository()
 
344
 
 
345
    def test_create_branch_convenience_root(self):
 
346
        """Creating a branch at the root of a fs should work."""
 
347
        self.vfs_transport_factory = MemoryServer
 
348
        # outside a repo the default convenience output is a repo+branch_tree
 
349
        format = bzrdir.format_registry.make_bzrdir('knit')
 
350
        branch = bzrdir.BzrDir.create_branch_convenience(self.get_url(), 
 
351
                                                         format=format)
 
352
        self.assertRaises(errors.NoWorkingTree,
 
353
                          branch.bzrdir.open_workingtree)
 
354
        branch.bzrdir.open_repository()
 
355
 
 
356
    def test_create_branch_convenience_under_shared_repo(self):
 
357
        # inside a repo the default convenience output is a branch+ follow the
 
358
        # repo tree policy
 
359
        format = bzrdir.format_registry.make_bzrdir('knit')
 
360
        self.make_repository('.', shared=True, format=format)
 
361
        branch = bzrdir.BzrDir.create_branch_convenience('child',
 
362
            format=format)
 
363
        branch.bzrdir.open_workingtree()
 
364
        self.assertRaises(errors.NoRepositoryPresent,
 
365
                          branch.bzrdir.open_repository)
 
366
            
 
367
    def test_create_branch_convenience_under_shared_repo_force_no_tree(self):
 
368
        # inside a repo the default convenience output is a branch+ follow the
 
369
        # repo tree policy but we can override that
 
370
        format = bzrdir.format_registry.make_bzrdir('knit')
 
371
        self.make_repository('.', shared=True, format=format)
 
372
        branch = bzrdir.BzrDir.create_branch_convenience('child',
 
373
            force_new_tree=False, format=format)
 
374
        self.assertRaises(errors.NoWorkingTree,
 
375
                          branch.bzrdir.open_workingtree)
 
376
        self.assertRaises(errors.NoRepositoryPresent,
 
377
                          branch.bzrdir.open_repository)
 
378
            
 
379
    def test_create_branch_convenience_under_shared_repo_no_tree_policy(self):
 
380
        # inside a repo the default convenience output is a branch+ follow the
 
381
        # repo tree policy
 
382
        format = bzrdir.format_registry.make_bzrdir('knit')
 
383
        repo = self.make_repository('.', shared=True, format=format)
 
384
        repo.set_make_working_trees(False)
 
385
        branch = bzrdir.BzrDir.create_branch_convenience('child', 
 
386
                                                         format=format)
 
387
        self.assertRaises(errors.NoWorkingTree,
 
388
                          branch.bzrdir.open_workingtree)
 
389
        self.assertRaises(errors.NoRepositoryPresent,
 
390
                          branch.bzrdir.open_repository)
 
391
 
 
392
    def test_create_branch_convenience_under_shared_repo_no_tree_policy_force_tree(self):
 
393
        # inside a repo the default convenience output is a branch+ follow the
 
394
        # repo tree policy but we can override that
 
395
        format = bzrdir.format_registry.make_bzrdir('knit')
 
396
        repo = self.make_repository('.', shared=True, format=format)
 
397
        repo.set_make_working_trees(False)
 
398
        branch = bzrdir.BzrDir.create_branch_convenience('child',
 
399
            force_new_tree=True, format=format)
 
400
        branch.bzrdir.open_workingtree()
 
401
        self.assertRaises(errors.NoRepositoryPresent,
 
402
                          branch.bzrdir.open_repository)
 
403
 
 
404
    def test_create_branch_convenience_under_shared_repo_force_new_repo(self):
 
405
        # inside a repo the default convenience output is overridable to give
 
406
        # repo+branch+tree
 
407
        format = bzrdir.format_registry.make_bzrdir('knit')
 
408
        self.make_repository('.', shared=True, format=format)
 
409
        branch = bzrdir.BzrDir.create_branch_convenience('child',
 
410
            force_new_repo=True, format=format)
 
411
        branch.bzrdir.open_repository()
 
412
        branch.bzrdir.open_workingtree()
 
413
 
 
414
 
 
415
class TestRepositoryAcquisitionPolicy(TestCaseWithTransport):
 
416
 
 
417
    def test_acquire_repository_standalone(self):
 
418
        """The default acquisition policy should create a standalone branch."""
 
419
        my_bzrdir = self.make_bzrdir('.')
 
420
        repo_policy = my_bzrdir.determine_repository_policy()
 
421
        repo = repo_policy.acquire_repository()
 
422
        self.assertEqual(repo.bzrdir.root_transport.base,
 
423
                         my_bzrdir.root_transport.base)
 
424
        self.assertFalse(repo.is_shared())
 
425
 
 
426
 
 
427
class ChrootedTests(TestCaseWithTransport):
 
428
    """A support class that provides readonly urls outside the local namespace.
 
429
 
 
430
    This is done by checking if self.transport_server is a MemoryServer. if it
 
431
    is then we are chrooted already, if it is not then an HttpServer is used
 
432
    for readonly urls.
 
433
    """
 
434
 
 
435
    def setUp(self):
 
436
        super(ChrootedTests, self).setUp()
 
437
        if not self.vfs_transport_factory == MemoryServer:
 
438
            self.transport_readonly_server = HttpServer
 
439
 
 
440
    def local_branch_path(self, branch):
 
441
         return os.path.realpath(urlutils.local_path_from_url(branch.base))
 
442
 
 
443
    def test_open_containing(self):
 
444
        self.assertRaises(NotBranchError, bzrdir.BzrDir.open_containing,
 
445
                          self.get_readonly_url(''))
 
446
        self.assertRaises(NotBranchError, bzrdir.BzrDir.open_containing,
 
447
                          self.get_readonly_url('g/p/q'))
 
448
        control = bzrdir.BzrDir.create(self.get_url())
 
449
        branch, relpath = bzrdir.BzrDir.open_containing(self.get_readonly_url(''))
 
450
        self.assertEqual('', relpath)
 
451
        branch, relpath = bzrdir.BzrDir.open_containing(self.get_readonly_url('g/p/q'))
 
452
        self.assertEqual('g/p/q', relpath)
 
453
 
 
454
    def test_open_containing_tree_branch_or_repository_empty(self):
 
455
        self.assertRaises(errors.NotBranchError,
 
456
            bzrdir.BzrDir.open_containing_tree_branch_or_repository,
 
457
            self.get_readonly_url(''))
 
458
 
 
459
    def test_open_containing_tree_branch_or_repository_all(self):
 
460
        self.make_branch_and_tree('topdir')
 
461
        tree, branch, repo, relpath = \
 
462
            bzrdir.BzrDir.open_containing_tree_branch_or_repository(
 
463
                'topdir/foo')
 
464
        self.assertEqual(os.path.realpath('topdir'),
 
465
                         os.path.realpath(tree.basedir))
 
466
        self.assertEqual(os.path.realpath('topdir'),
 
467
                         self.local_branch_path(branch))
 
468
        self.assertEqual(
 
469
            os.path.realpath(os.path.join('topdir', '.bzr', 'repository')),
 
470
            repo.bzrdir.transport.local_abspath('repository'))
 
471
        self.assertEqual(relpath, 'foo')
 
472
 
 
473
    def test_open_containing_tree_branch_or_repository_no_tree(self):
 
474
        self.make_branch('branch')
 
475
        tree, branch, repo, relpath = \
 
476
            bzrdir.BzrDir.open_containing_tree_branch_or_repository(
 
477
                'branch/foo')
 
478
        self.assertEqual(tree, None)
 
479
        self.assertEqual(os.path.realpath('branch'),
 
480
                         self.local_branch_path(branch))
 
481
        self.assertEqual(
 
482
            os.path.realpath(os.path.join('branch', '.bzr', 'repository')),
 
483
            repo.bzrdir.transport.local_abspath('repository'))
 
484
        self.assertEqual(relpath, 'foo')
 
485
 
 
486
    def test_open_containing_tree_branch_or_repository_repo(self):
 
487
        self.make_repository('repo')
 
488
        tree, branch, repo, relpath = \
 
489
            bzrdir.BzrDir.open_containing_tree_branch_or_repository(
 
490
                'repo')
 
491
        self.assertEqual(tree, None)
 
492
        self.assertEqual(branch, None)
 
493
        self.assertEqual(
 
494
            os.path.realpath(os.path.join('repo', '.bzr', 'repository')),
 
495
            repo.bzrdir.transport.local_abspath('repository'))
 
496
        self.assertEqual(relpath, '')
 
497
 
 
498
    def test_open_containing_tree_branch_or_repository_shared_repo(self):
 
499
        self.make_repository('shared', shared=True)
 
500
        bzrdir.BzrDir.create_branch_convenience('shared/branch',
 
501
                                                force_new_tree=False)
 
502
        tree, branch, repo, relpath = \
 
503
            bzrdir.BzrDir.open_containing_tree_branch_or_repository(
 
504
                'shared/branch')
 
505
        self.assertEqual(tree, None)
 
506
        self.assertEqual(os.path.realpath('shared/branch'),
 
507
                         self.local_branch_path(branch))
 
508
        self.assertEqual(
 
509
            os.path.realpath(os.path.join('shared', '.bzr', 'repository')),
 
510
            repo.bzrdir.transport.local_abspath('repository'))
 
511
        self.assertEqual(relpath, '')
 
512
 
 
513
    def test_open_containing_tree_branch_or_repository_branch_subdir(self):
 
514
        self.make_branch_and_tree('foo')
 
515
        self.build_tree(['foo/bar/'])
 
516
        tree, branch, repo, relpath = \
 
517
            bzrdir.BzrDir.open_containing_tree_branch_or_repository(
 
518
                'foo/bar')
 
519
        self.assertEqual(os.path.realpath('foo'),
 
520
                         os.path.realpath(tree.basedir))
 
521
        self.assertEqual(os.path.realpath('foo'),
 
522
                         self.local_branch_path(branch))
 
523
        self.assertEqual(
 
524
            os.path.realpath(os.path.join('foo', '.bzr', 'repository')),
 
525
            repo.bzrdir.transport.local_abspath('repository'))
 
526
        self.assertEqual(relpath, 'bar')
 
527
 
 
528
    def test_open_containing_tree_branch_or_repository_repo_subdir(self):
 
529
        self.make_repository('bar')
 
530
        self.build_tree(['bar/baz/'])
 
531
        tree, branch, repo, relpath = \
 
532
            bzrdir.BzrDir.open_containing_tree_branch_or_repository(
 
533
                'bar/baz')
 
534
        self.assertEqual(tree, None)
 
535
        self.assertEqual(branch, None)
 
536
        self.assertEqual(
 
537
            os.path.realpath(os.path.join('bar', '.bzr', 'repository')),
 
538
            repo.bzrdir.transport.local_abspath('repository'))
 
539
        self.assertEqual(relpath, 'baz')
 
540
 
 
541
    def test_open_containing_from_transport(self):
 
542
        self.assertRaises(NotBranchError, bzrdir.BzrDir.open_containing_from_transport,
 
543
                          get_transport(self.get_readonly_url('')))
 
544
        self.assertRaises(NotBranchError, bzrdir.BzrDir.open_containing_from_transport,
 
545
                          get_transport(self.get_readonly_url('g/p/q')))
 
546
        control = bzrdir.BzrDir.create(self.get_url())
 
547
        branch, relpath = bzrdir.BzrDir.open_containing_from_transport(
 
548
            get_transport(self.get_readonly_url('')))
 
549
        self.assertEqual('', relpath)
 
550
        branch, relpath = bzrdir.BzrDir.open_containing_from_transport(
 
551
            get_transport(self.get_readonly_url('g/p/q')))
 
552
        self.assertEqual('g/p/q', relpath)
 
553
 
 
554
    def test_open_containing_tree_or_branch(self):
 
555
        self.make_branch_and_tree('topdir')
 
556
        tree, branch, relpath = bzrdir.BzrDir.open_containing_tree_or_branch(
 
557
            'topdir/foo')
 
558
        self.assertEqual(os.path.realpath('topdir'),
 
559
                         os.path.realpath(tree.basedir))
 
560
        self.assertEqual(os.path.realpath('topdir'),
 
561
                         self.local_branch_path(branch))
 
562
        self.assertIs(tree.bzrdir, branch.bzrdir)
 
563
        self.assertEqual('foo', relpath)
 
564
        # opening from non-local should not return the tree
 
565
        tree, branch, relpath = bzrdir.BzrDir.open_containing_tree_or_branch(
 
566
            self.get_readonly_url('topdir/foo'))
 
567
        self.assertEqual(None, tree)
 
568
        self.assertEqual('foo', relpath)
 
569
        # without a tree:
 
570
        self.make_branch('topdir/foo')
 
571
        tree, branch, relpath = bzrdir.BzrDir.open_containing_tree_or_branch(
 
572
            'topdir/foo')
 
573
        self.assertIs(tree, None)
 
574
        self.assertEqual(os.path.realpath('topdir/foo'),
 
575
                         self.local_branch_path(branch))
 
576
        self.assertEqual('', relpath)
 
577
 
 
578
    def test_open_tree_or_branch(self):
 
579
        self.make_branch_and_tree('topdir')
 
580
        tree, branch = bzrdir.BzrDir.open_tree_or_branch('topdir')
 
581
        self.assertEqual(os.path.realpath('topdir'),
 
582
                         os.path.realpath(tree.basedir))
 
583
        self.assertEqual(os.path.realpath('topdir'),
 
584
                         self.local_branch_path(branch))
 
585
        self.assertIs(tree.bzrdir, branch.bzrdir)
 
586
        # opening from non-local should not return the tree
 
587
        tree, branch = bzrdir.BzrDir.open_tree_or_branch(
 
588
            self.get_readonly_url('topdir'))
 
589
        self.assertEqual(None, tree)
 
590
        # without a tree:
 
591
        self.make_branch('topdir/foo')
 
592
        tree, branch = bzrdir.BzrDir.open_tree_or_branch('topdir/foo')
 
593
        self.assertIs(tree, None)
 
594
        self.assertEqual(os.path.realpath('topdir/foo'),
 
595
                         self.local_branch_path(branch))
 
596
 
 
597
    def test_open_from_transport(self):
 
598
        # transport pointing at bzrdir should give a bzrdir with root transport
 
599
        # set to the given transport
 
600
        control = bzrdir.BzrDir.create(self.get_url())
 
601
        transport = get_transport(self.get_url())
 
602
        opened_bzrdir = bzrdir.BzrDir.open_from_transport(transport)
 
603
        self.assertEqual(transport.base, opened_bzrdir.root_transport.base)
 
604
        self.assertIsInstance(opened_bzrdir, bzrdir.BzrDir)
 
605
        
 
606
    def test_open_from_transport_no_bzrdir(self):
 
607
        transport = get_transport(self.get_url())
 
608
        self.assertRaises(NotBranchError, bzrdir.BzrDir.open_from_transport,
 
609
                          transport)
 
610
 
 
611
    def test_open_from_transport_bzrdir_in_parent(self):
 
612
        control = bzrdir.BzrDir.create(self.get_url())
 
613
        transport = get_transport(self.get_url())
 
614
        transport.mkdir('subdir')
 
615
        transport = transport.clone('subdir')
 
616
        self.assertRaises(NotBranchError, bzrdir.BzrDir.open_from_transport,
 
617
                          transport)
 
618
 
 
619
    def test_sprout_recursive(self):
 
620
        tree = self.make_branch_and_tree('tree1', format='dirstate-with-subtree')
 
621
        sub_tree = self.make_branch_and_tree('tree1/subtree',
 
622
            format='dirstate-with-subtree')
 
623
        tree.add_reference(sub_tree)
 
624
        self.build_tree(['tree1/subtree/file'])
 
625
        sub_tree.add('file')
 
626
        tree.commit('Initial commit')
 
627
        tree.bzrdir.sprout('tree2')
 
628
        self.failUnlessExists('tree2/subtree/file')
 
629
 
 
630
    def test_cloning_metadir(self):
 
631
        """Ensure that cloning metadir is suitable"""
 
632
        bzrdir = self.make_bzrdir('bzrdir')
 
633
        bzrdir.cloning_metadir()
 
634
        branch = self.make_branch('branch', format='knit')
 
635
        format = branch.bzrdir.cloning_metadir()
 
636
        self.assertIsInstance(format.workingtree_format,
 
637
            workingtree.WorkingTreeFormat3)
 
638
 
 
639
    def test_sprout_recursive_treeless(self):
 
640
        tree = self.make_branch_and_tree('tree1',
 
641
            format='dirstate-with-subtree')
 
642
        sub_tree = self.make_branch_and_tree('tree1/subtree',
 
643
            format='dirstate-with-subtree')
 
644
        tree.add_reference(sub_tree)
 
645
        self.build_tree(['tree1/subtree/file'])
 
646
        sub_tree.add('file')
 
647
        tree.commit('Initial commit')
 
648
        tree.bzrdir.destroy_workingtree()
 
649
        repo = self.make_repository('repo', shared=True,
 
650
            format='dirstate-with-subtree')
 
651
        repo.set_make_working_trees(False)
 
652
        tree.bzrdir.sprout('repo/tree2')
 
653
        self.failUnlessExists('repo/tree2/subtree')
 
654
        self.failIfExists('repo/tree2/subtree/file')
 
655
 
 
656
    def make_foo_bar_baz(self):
 
657
        foo = bzrdir.BzrDir.create_branch_convenience('foo').bzrdir
 
658
        bar = self.make_branch('foo/bar').bzrdir
 
659
        baz = self.make_branch('baz').bzrdir
 
660
        return foo, bar, baz
 
661
 
 
662
    def test_find_bzrdirs(self):
 
663
        foo, bar, baz = self.make_foo_bar_baz()
 
664
        transport = get_transport(self.get_url())
 
665
        self.assertEqualBzrdirs([baz, foo, bar],
 
666
                                bzrdir.BzrDir.find_bzrdirs(transport))
 
667
 
 
668
    def test_find_bzrdirs_list_current(self):
 
669
        def list_current(transport):
 
670
            return [s for s in transport.list_dir('') if s != 'baz']
 
671
 
 
672
        foo, bar, baz = self.make_foo_bar_baz()
 
673
        transport = get_transport(self.get_url())
 
674
        self.assertEqualBzrdirs([foo, bar],
 
675
                                bzrdir.BzrDir.find_bzrdirs(transport,
 
676
                                    list_current=list_current))
 
677
 
 
678
 
 
679
    def test_find_bzrdirs_evaluate(self):
 
680
        def evaluate(bzrdir):
 
681
            try:
 
682
                repo = bzrdir.open_repository()
 
683
            except NoRepositoryPresent:
 
684
                return True, bzrdir.root_transport.base
 
685
            else:
 
686
                return False, bzrdir.root_transport.base
 
687
 
 
688
        foo, bar, baz = self.make_foo_bar_baz()
 
689
        transport = get_transport(self.get_url())
 
690
        self.assertEqual([baz.root_transport.base, foo.root_transport.base],
 
691
                         list(bzrdir.BzrDir.find_bzrdirs(transport,
 
692
                                                         evaluate=evaluate)))
 
693
 
 
694
    def assertEqualBzrdirs(self, first, second):
 
695
        first = list(first)
 
696
        second = list(second)
 
697
        self.assertEqual(len(first), len(second))
 
698
        for x, y in zip(first, second):
 
699
            self.assertEqual(x.root_transport.base, y.root_transport.base)
 
700
 
 
701
    def test_find_branches(self):
 
702
        root = self.make_repository('', shared=True)
 
703
        foo, bar, baz = self.make_foo_bar_baz()
 
704
        qux = self.make_bzrdir('foo/qux')
 
705
        transport = get_transport(self.get_url())
 
706
        branches = bzrdir.BzrDir.find_branches(transport)
 
707
        self.assertEqual(baz.root_transport.base, branches[0].base)
 
708
        self.assertEqual(foo.root_transport.base, branches[1].base)
 
709
        self.assertEqual(bar.root_transport.base, branches[2].base)
 
710
 
 
711
        # ensure this works without a top-level repo
 
712
        branches = bzrdir.BzrDir.find_branches(transport.clone('foo'))
 
713
        self.assertEqual(foo.root_transport.base, branches[0].base)
 
714
        self.assertEqual(bar.root_transport.base, branches[1].base)
 
715
 
 
716
 
 
717
class TestMeta1DirFormat(TestCaseWithTransport):
 
718
    """Tests specific to the meta1 dir format."""
 
719
 
 
720
    def test_right_base_dirs(self):
 
721
        dir = bzrdir.BzrDirMetaFormat1().initialize(self.get_url())
 
722
        t = dir.transport
 
723
        branch_base = t.clone('branch').base
 
724
        self.assertEqual(branch_base, dir.get_branch_transport(None).base)
 
725
        self.assertEqual(branch_base,
 
726
                         dir.get_branch_transport(bzrlib.branch.BzrBranchFormat5()).base)
 
727
        repository_base = t.clone('repository').base
 
728
        self.assertEqual(repository_base, dir.get_repository_transport(None).base)
 
729
        self.assertEqual(repository_base,
 
730
                         dir.get_repository_transport(weaverepo.RepositoryFormat7()).base)
 
731
        checkout_base = t.clone('checkout').base
 
732
        self.assertEqual(checkout_base, dir.get_workingtree_transport(None).base)
 
733
        self.assertEqual(checkout_base,
 
734
                         dir.get_workingtree_transport(workingtree.WorkingTreeFormat3()).base)
 
735
 
 
736
    def test_meta1dir_uses_lockdir(self):
 
737
        """Meta1 format uses a LockDir to guard the whole directory, not a file."""
 
738
        dir = bzrdir.BzrDirMetaFormat1().initialize(self.get_url())
 
739
        t = dir.transport
 
740
        self.assertIsDirectory('branch-lock', t)
 
741
 
 
742
    def test_comparison(self):
 
743
        """Equality and inequality behave properly.
 
744
 
 
745
        Metadirs should compare equal iff they have the same repo, branch and
 
746
        tree formats.
 
747
        """
 
748
        mydir = bzrdir.format_registry.make_bzrdir('knit')
 
749
        self.assertEqual(mydir, mydir)
 
750
        self.assertFalse(mydir != mydir)
 
751
        otherdir = bzrdir.format_registry.make_bzrdir('knit')
 
752
        self.assertEqual(otherdir, mydir)
 
753
        self.assertFalse(otherdir != mydir)
 
754
        otherdir2 = bzrdir.format_registry.make_bzrdir('dirstate-with-subtree')
 
755
        self.assertNotEqual(otherdir2, mydir)
 
756
        self.assertFalse(otherdir2 == mydir)
 
757
 
 
758
    def test_needs_conversion_different_working_tree(self):
 
759
        # meta1dirs need an conversion if any element is not the default.
 
760
        old_format = bzrdir.BzrDirFormat.get_default_format()
 
761
        # test with 
 
762
        new_default = bzrdir.format_registry.make_bzrdir('dirstate')
 
763
        bzrdir.BzrDirFormat._set_default_format(new_default)
 
764
        try:
 
765
            tree = self.make_branch_and_tree('tree', format='knit')
 
766
            self.assertTrue(tree.bzrdir.needs_format_conversion())
 
767
        finally:
 
768
            bzrdir.BzrDirFormat._set_default_format(old_format)
 
769
 
 
770
 
 
771
class TestFormat5(TestCaseWithTransport):
 
772
    """Tests specific to the version 5 bzrdir format."""
 
773
 
 
774
    def test_same_lockfiles_between_tree_repo_branch(self):
 
775
        # this checks that only a single lockfiles instance is created 
 
776
        # for format 5 objects
 
777
        dir = bzrdir.BzrDirFormat5().initialize(self.get_url())
 
778
        def check_dir_components_use_same_lock(dir):
 
779
            ctrl_1 = dir.open_repository().control_files
 
780
            ctrl_2 = dir.open_branch().control_files
 
781
            ctrl_3 = dir.open_workingtree()._control_files
 
782
            self.assertTrue(ctrl_1 is ctrl_2)
 
783
            self.assertTrue(ctrl_2 is ctrl_3)
 
784
        check_dir_components_use_same_lock(dir)
 
785
        # and if we open it normally.
 
786
        dir = bzrdir.BzrDir.open(self.get_url())
 
787
        check_dir_components_use_same_lock(dir)
 
788
    
 
789
    def test_can_convert(self):
 
790
        # format 5 dirs are convertable
 
791
        dir = bzrdir.BzrDirFormat5().initialize(self.get_url())
 
792
        self.assertTrue(dir.can_convert_format())
 
793
    
 
794
    def test_needs_conversion(self):
 
795
        # format 5 dirs need a conversion if they are not the default.
 
796
        # and they start of not the default.
 
797
        old_format = bzrdir.BzrDirFormat.get_default_format()
 
798
        bzrdir.BzrDirFormat._set_default_format(bzrdir.BzrDirFormat5())
 
799
        try:
 
800
            dir = bzrdir.BzrDirFormat5().initialize(self.get_url())
 
801
            self.assertFalse(dir.needs_format_conversion())
 
802
        finally:
 
803
            bzrdir.BzrDirFormat._set_default_format(old_format)
 
804
        self.assertTrue(dir.needs_format_conversion())
 
805
 
 
806
 
 
807
class TestFormat6(TestCaseWithTransport):
 
808
    """Tests specific to the version 6 bzrdir format."""
 
809
 
 
810
    def test_same_lockfiles_between_tree_repo_branch(self):
 
811
        # this checks that only a single lockfiles instance is created 
 
812
        # for format 6 objects
 
813
        dir = bzrdir.BzrDirFormat6().initialize(self.get_url())
 
814
        def check_dir_components_use_same_lock(dir):
 
815
            ctrl_1 = dir.open_repository().control_files
 
816
            ctrl_2 = dir.open_branch().control_files
 
817
            ctrl_3 = dir.open_workingtree()._control_files
 
818
            self.assertTrue(ctrl_1 is ctrl_2)
 
819
            self.assertTrue(ctrl_2 is ctrl_3)
 
820
        check_dir_components_use_same_lock(dir)
 
821
        # and if we open it normally.
 
822
        dir = bzrdir.BzrDir.open(self.get_url())
 
823
        check_dir_components_use_same_lock(dir)
 
824
    
 
825
    def test_can_convert(self):
 
826
        # format 6 dirs are convertable
 
827
        dir = bzrdir.BzrDirFormat6().initialize(self.get_url())
 
828
        self.assertTrue(dir.can_convert_format())
 
829
    
 
830
    def test_needs_conversion(self):
 
831
        # format 6 dirs need an conversion if they are not the default.
 
832
        old_format = bzrdir.BzrDirFormat.get_default_format()
 
833
        bzrdir.BzrDirFormat._set_default_format(bzrdir.BzrDirMetaFormat1())
 
834
        try:
 
835
            dir = bzrdir.BzrDirFormat6().initialize(self.get_url())
 
836
            self.assertTrue(dir.needs_format_conversion())
 
837
        finally:
 
838
            bzrdir.BzrDirFormat._set_default_format(old_format)
 
839
 
 
840
 
 
841
class NotBzrDir(bzrlib.bzrdir.BzrDir):
 
842
    """A non .bzr based control directory."""
 
843
 
 
844
    def __init__(self, transport, format):
 
845
        self._format = format
 
846
        self.root_transport = transport
 
847
        self.transport = transport.clone('.not')
 
848
 
 
849
 
 
850
class NotBzrDirFormat(bzrlib.bzrdir.BzrDirFormat):
 
851
    """A test class representing any non-.bzr based disk format."""
 
852
 
 
853
    def initialize_on_transport(self, transport):
 
854
        """Initialize a new .not dir in the base directory of a Transport."""
 
855
        transport.mkdir('.not')
 
856
        return self.open(transport)
 
857
 
 
858
    def open(self, transport):
 
859
        """Open this directory."""
 
860
        return NotBzrDir(transport, self)
 
861
 
 
862
    @classmethod
 
863
    def _known_formats(self):
 
864
        return set([NotBzrDirFormat()])
 
865
 
 
866
    @classmethod
 
867
    def probe_transport(self, transport):
 
868
        """Our format is present if the transport ends in '.not/'."""
 
869
        if transport.has('.not'):
 
870
            return NotBzrDirFormat()
 
871
 
 
872
 
 
873
class TestNotBzrDir(TestCaseWithTransport):
 
874
    """Tests for using the bzrdir api with a non .bzr based disk format.
 
875
    
 
876
    If/when one of these is in the core, we can let the implementation tests
 
877
    verify this works.
 
878
    """
 
879
 
 
880
    def test_create_and_find_format(self):
 
881
        # create a .notbzr dir 
 
882
        format = NotBzrDirFormat()
 
883
        dir = format.initialize(self.get_url())
 
884
        self.assertIsInstance(dir, NotBzrDir)
 
885
        # now probe for it.
 
886
        bzrlib.bzrdir.BzrDirFormat.register_control_format(format)
 
887
        try:
 
888
            found = bzrlib.bzrdir.BzrDirFormat.find_format(
 
889
                get_transport(self.get_url()))
 
890
            self.assertIsInstance(found, NotBzrDirFormat)
 
891
        finally:
 
892
            bzrlib.bzrdir.BzrDirFormat.unregister_control_format(format)
 
893
 
 
894
    def test_included_in_known_formats(self):
 
895
        bzrlib.bzrdir.BzrDirFormat.register_control_format(NotBzrDirFormat)
 
896
        try:
 
897
            formats = bzrlib.bzrdir.BzrDirFormat.known_formats()
 
898
            for format in formats:
 
899
                if isinstance(format, NotBzrDirFormat):
 
900
                    return
 
901
            self.fail("No NotBzrDirFormat in %s" % formats)
 
902
        finally:
 
903
            bzrlib.bzrdir.BzrDirFormat.unregister_control_format(NotBzrDirFormat)
 
904
 
 
905
 
 
906
class NonLocalTests(TestCaseWithTransport):
 
907
    """Tests for bzrdir static behaviour on non local paths."""
 
908
 
 
909
    def setUp(self):
 
910
        super(NonLocalTests, self).setUp()
 
911
        self.vfs_transport_factory = MemoryServer
 
912
    
 
913
    def test_create_branch_convenience(self):
 
914
        # outside a repo the default convenience output is a repo+branch_tree
 
915
        format = bzrdir.format_registry.make_bzrdir('knit')
 
916
        branch = bzrdir.BzrDir.create_branch_convenience(
 
917
            self.get_url('foo'), format=format)
 
918
        self.assertRaises(errors.NoWorkingTree,
 
919
                          branch.bzrdir.open_workingtree)
 
920
        branch.bzrdir.open_repository()
 
921
 
 
922
    def test_create_branch_convenience_force_tree_not_local_fails(self):
 
923
        # outside a repo the default convenience output is a repo+branch_tree
 
924
        format = bzrdir.format_registry.make_bzrdir('knit')
 
925
        self.assertRaises(errors.NotLocalUrl,
 
926
            bzrdir.BzrDir.create_branch_convenience,
 
927
            self.get_url('foo'),
 
928
            force_new_tree=True,
 
929
            format=format)
 
930
        t = get_transport(self.get_url('.'))
 
931
        self.assertFalse(t.has('foo'))
 
932
 
 
933
    def test_clone(self):
 
934
        # clone into a nonlocal path works
 
935
        format = bzrdir.format_registry.make_bzrdir('knit')
 
936
        branch = bzrdir.BzrDir.create_branch_convenience('local',
 
937
                                                         format=format)
 
938
        branch.bzrdir.open_workingtree()
 
939
        result = branch.bzrdir.clone(self.get_url('remote'))
 
940
        self.assertRaises(errors.NoWorkingTree,
 
941
                          result.open_workingtree)
 
942
        result.open_branch()
 
943
        result.open_repository()
 
944
 
 
945
    def test_checkout_metadir(self):
 
946
        # checkout_metadir has reasonable working tree format even when no
 
947
        # working tree is present
 
948
        self.make_branch('branch-knit2', format='dirstate-with-subtree')
 
949
        my_bzrdir = bzrdir.BzrDir.open(self.get_url('branch-knit2'))
 
950
        checkout_format = my_bzrdir.checkout_metadir()
 
951
        self.assertIsInstance(checkout_format.workingtree_format,
 
952
                              workingtree.WorkingTreeFormat3)
 
953
 
 
954
 
 
955
class TestHTTPRedirectionLoop(object):
 
956
    """Test redirection loop between two http servers.
 
957
 
 
958
    This MUST be used by daughter classes that also inherit from
 
959
    TestCaseWithTwoWebservers.
 
960
 
 
961
    We can't inherit directly from TestCaseWithTwoWebservers or the
 
962
    test framework will try to create an instance which cannot
 
963
    run, its implementation being incomplete. 
 
964
    """
 
965
 
 
966
    # Should be defined by daughter classes to ensure redirection
 
967
    # still use the same transport implementation (not currently
 
968
    # enforced as it's a bit tricky to get right (see the FIXME
 
969
    # in BzrDir.open_from_transport for the unique use case so
 
970
    # far)
 
971
    _qualifier = None
 
972
 
 
973
    def create_transport_readonly_server(self):
 
974
        return HTTPServerRedirecting()
 
975
 
 
976
    def create_transport_secondary_server(self):
 
977
        return HTTPServerRedirecting()
 
978
 
 
979
    def setUp(self):
 
980
        # Both servers redirect to each server creating a loop
 
981
        super(TestHTTPRedirectionLoop, self).setUp()
 
982
        # The redirections will point to the new server
 
983
        self.new_server = self.get_readonly_server()
 
984
        # The requests to the old server will be redirected
 
985
        self.old_server = self.get_secondary_server()
 
986
        # Configure the redirections
 
987
        self.old_server.redirect_to(self.new_server.host, self.new_server.port)
 
988
        self.new_server.redirect_to(self.old_server.host, self.old_server.port)
 
989
 
 
990
    def _qualified_url(self, host, port):
 
991
        return 'http+%s://%s:%s' % (self._qualifier, host, port)
 
992
 
 
993
    def test_loop(self):
 
994
        # Starting from either server should loop
 
995
        old_url = self._qualified_url(self.old_server.host, 
 
996
                                      self.old_server.port)
 
997
        oldt = self._transport(old_url)
 
998
        self.assertRaises(errors.NotBranchError,
 
999
                          bzrdir.BzrDir.open_from_transport, oldt)
 
1000
        new_url = self._qualified_url(self.new_server.host, 
 
1001
                                      self.new_server.port)
 
1002
        newt = self._transport(new_url)
 
1003
        self.assertRaises(errors.NotBranchError,
 
1004
                          bzrdir.BzrDir.open_from_transport, newt)
 
1005
 
 
1006
 
 
1007
class TestHTTPRedirections_urllib(TestHTTPRedirectionLoop,
 
1008
                                  TestCaseWithTwoWebservers):
 
1009
    """Tests redirections for urllib implementation"""
 
1010
 
 
1011
    _qualifier = 'urllib'
 
1012
    _transport = HttpTransport_urllib
 
1013
 
 
1014
 
 
1015
 
 
1016
class TestHTTPRedirections_pycurl(TestWithTransport_pycurl,
 
1017
                                  TestHTTPRedirectionLoop,
 
1018
                                  TestCaseWithTwoWebservers):
 
1019
    """Tests redirections for pycurl implementation"""
 
1020
 
 
1021
    _qualifier = 'pycurl'
 
1022
 
 
1023
 
 
1024
class TestDotBzrHidden(TestCaseWithTransport):
 
1025
 
 
1026
    ls = ['ls']
 
1027
    if sys.platform == 'win32':
 
1028
        ls = [os.environ['COMSPEC'], '/C', 'dir', '/B']
 
1029
 
 
1030
    def get_ls(self):
 
1031
        f = subprocess.Popen(self.ls, stdout=subprocess.PIPE,
 
1032
            stderr=subprocess.PIPE)
 
1033
        out, err = f.communicate()
 
1034
        self.assertEqual(0, f.returncode, 'Calling %s failed: %s'
 
1035
                         % (self.ls, err))
 
1036
        return out.splitlines()
 
1037
 
 
1038
    def test_dot_bzr_hidden(self):
 
1039
        if sys.platform == 'win32' and not win32utils.has_win32file:
 
1040
            raise TestSkipped('unable to make file hidden without pywin32 library')
 
1041
        b = bzrdir.BzrDir.create('.')
 
1042
        self.build_tree(['a'])
 
1043
        self.assertEquals(['a'], self.get_ls())
 
1044
 
 
1045
    def test_dot_bzr_hidden_with_url(self):
 
1046
        if sys.platform == 'win32' and not win32utils.has_win32file:
 
1047
            raise TestSkipped('unable to make file hidden without pywin32 library')
 
1048
        b = bzrdir.BzrDir.create(urlutils.local_path_to_url('.'))
 
1049
        self.build_tree(['a'])
 
1050
        self.assertEquals(['a'], self.get_ls())