~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_bzrdir.py

  • Committer: Vincent Ladeuil
  • Date: 2010-02-10 15:46:03 UTC
  • mfrom: (4985.3.21 update)
  • mto: This revision was merged to the branch mainline in revision 5021.
  • Revision ID: v.ladeuil+lp@free.fr-20100210154603-k4no1gvfuqpzrw7p
Update performs two merges in a more logical order but stop on conflicts

Show diffs side-by-side

added added

removed removed

Lines of Context:
12
12
#
13
13
# You should have received a copy of the GNU General Public License
14
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
 
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
16
 
17
17
"""Tests for the BzrDir facility and any format specific tests.
18
18
 
19
 
For interface contract tests, see tests/bzr_dir_implementations.
 
19
For interface contract tests, see tests/per_bzr_dir.
20
20
"""
21
21
 
22
22
import os
23
 
import os.path
24
 
from StringIO import StringIO
25
23
import subprocess
26
24
import sys
27
25
 
31
29
    help_topics,
32
30
    repository,
33
31
    osutils,
34
 
    symbol_versioning,
 
32
    remote,
35
33
    urlutils,
36
34
    win32utils,
37
35
    workingtree,
46
44
    TestCaseWithMemoryTransport,
47
45
    TestCaseWithTransport,
48
46
    TestSkipped,
49
 
    test_sftp_transport
50
47
    )
51
48
from bzrlib.tests import(
52
49
    http_server,
58
55
from bzrlib.transport.memory import MemoryServer
59
56
from bzrlib.transport.nosmart import NoSmartTransportDecorator
60
57
from bzrlib.transport.readonly import ReadonlyTransportDecorator
61
 
from bzrlib.repofmt import knitrepo, weaverepo
 
58
from bzrlib.repofmt import knitrepo, weaverepo, pack_repo
62
59
 
63
60
 
64
61
class TestDefaultFormat(TestCase):
84
81
        my_format_registry.register('weave', bzrdir.BzrDirFormat6,
85
82
            'Pre-0.8 format.  Slower and does not support checkouts or shared'
86
83
            ' repositories', deprecated=True)
87
 
        my_format_registry.register_lazy('lazy', 'bzrlib.bzrdir', 
 
84
        my_format_registry.register_lazy('lazy', 'bzrlib.bzrdir',
88
85
            'BzrDirFormat6', 'Format registered lazily', deprecated=True)
89
86
        my_format_registry.register_metadir('knit',
90
87
            'bzrlib.repofmt.knitrepo.RepositoryFormatKnit1',
117
114
        my_bzrdir = my_format_registry.make_bzrdir('weave')
118
115
        self.assertIsInstance(my_bzrdir, bzrdir.BzrDirFormat6)
119
116
        my_bzrdir = my_format_registry.make_bzrdir('default')
120
 
        self.assertIsInstance(my_bzrdir.repository_format, 
 
117
        self.assertIsInstance(my_bzrdir.repository_format,
121
118
            knitrepo.RepositoryFormatKnit1)
122
119
        my_bzrdir = my_format_registry.make_bzrdir('knit')
123
 
        self.assertIsInstance(my_bzrdir.repository_format, 
 
120
        self.assertIsInstance(my_bzrdir.repository_format,
124
121
            knitrepo.RepositoryFormatKnit1)
125
122
        my_bzrdir = my_format_registry.make_bzrdir('branch6')
126
123
        self.assertIsInstance(my_bzrdir.get_branch_format(),
130
127
        my_format_registry = self.make_format_registry()
131
128
        self.assertEqual('Format registered lazily',
132
129
                         my_format_registry.get_help('lazy'))
133
 
        self.assertEqual('Format using knits', 
 
130
        self.assertEqual('Format using knits',
134
131
                         my_format_registry.get_help('knit'))
135
 
        self.assertEqual('Format using knits', 
 
132
        self.assertEqual('Format using knits',
136
133
                         my_format_registry.get_help('default'))
137
134
        self.assertEqual('Pre-0.8 format.  Slower and does not support'
138
 
                         ' checkouts or shared repositories', 
 
135
                         ' checkouts or shared repositories',
139
136
                         my_format_registry.get_help('weave'))
140
 
        
 
137
 
141
138
    def test_help_topic(self):
142
139
        topics = help_topics.HelpTopicRegistry()
143
140
        registry = self.make_format_registry()
144
 
        topics.register('current-formats', registry.help_topic, 
 
141
        topics.register('current-formats', registry.help_topic,
145
142
                        'Current formats')
146
 
        topics.register('other-formats', registry.help_topic, 
 
143
        topics.register('other-formats', registry.help_topic,
147
144
                        'Other formats')
148
145
        new = topics.get_detail('current-formats')
149
146
        rest = topics.get_detail('other-formats')
150
147
        experimental, deprecated = rest.split('Deprecated formats')
151
 
        self.assertContainsRe(new, 'bzr help formats')
152
 
        self.assertContainsRe(new, 
 
148
        self.assertContainsRe(new, 'formats-help')
 
149
        self.assertContainsRe(new,
153
150
                ':knit:\n    \(native\) \(default\) Format using knits\n')
154
 
        self.assertContainsRe(experimental, 
 
151
        self.assertContainsRe(experimental,
155
152
                ':branch6:\n    \(native\) Experimental successor to knit')
156
 
        self.assertContainsRe(deprecated, 
 
153
        self.assertContainsRe(deprecated,
157
154
                ':lazy:\n    \(native\) Format registered lazily\n')
158
155
        self.assertNotContainsRe(new, 'hidden')
159
156
 
219
216
class SampleBzrDirFormat(bzrdir.BzrDirFormat):
220
217
    """A sample format
221
218
 
222
 
    this format is initializable, unsupported to aid in testing the 
 
219
    this format is initializable, unsupported to aid in testing the
223
220
    open and open_downlevel routines.
224
221
    """
225
222
 
246
243
    def test_find_format(self):
247
244
        # is the right format object found for a branch?
248
245
        # create a branch with a few known format objects.
249
 
        # this is not quite the same as 
 
246
        # this is not quite the same as
250
247
        t = get_transport(self.get_url())
251
248
        self.build_tree(["foo/", "bar/"], transport=t)
252
249
        def check_format(format, url):
256
253
            self.failUnless(isinstance(found_format, format.__class__))
257
254
        check_format(bzrdir.BzrDirFormat5(), "foo")
258
255
        check_format(bzrdir.BzrDirFormat6(), "bar")
259
 
        
 
256
 
260
257
    def test_find_format_nothing_there(self):
261
258
        self.assertRaises(NotBranchError,
262
259
                          bzrdir.BzrDirFormat.find_format,
306
303
                          branch.bzrdir.open_repository)
307
304
 
308
305
    def test_create_branch_and_repo_under_shared_force_new(self):
309
 
        # creating a branch and repo in a shared repo can be forced to 
 
306
        # creating a branch and repo in a shared repo can be forced to
310
307
        # make a new repo
311
308
        format = bzrdir.format_registry.make_bzrdir('knit')
312
309
        self.make_repository('.', shared=True, format=format)
317
314
 
318
315
    def test_create_standalone_working_tree(self):
319
316
        format = SampleBzrDirFormat()
320
 
        # note this is deliberately readonly, as this failure should 
 
317
        # note this is deliberately readonly, as this failure should
321
318
        # occur before any writes.
322
319
        self.assertRaises(errors.NotLocalUrl,
323
320
                          bzrdir.BzrDir.create_standalone_workingtree,
324
321
                          self.get_readonly_url(), format=format)
325
 
        tree = bzrdir.BzrDir.create_standalone_workingtree('.', 
 
322
        tree = bzrdir.BzrDir.create_standalone_workingtree('.',
326
323
                                                           format=format)
327
324
        self.assertEqual('A tree', tree)
328
325
 
330
327
        # create standalone working tree always makes a repo.
331
328
        format = bzrdir.format_registry.make_bzrdir('knit')
332
329
        self.make_repository('.', shared=True, format=format)
333
 
        # note this is deliberately readonly, as this failure should 
 
330
        # note this is deliberately readonly, as this failure should
334
331
        # occur before any writes.
335
332
        self.assertRaises(errors.NotLocalUrl,
336
333
                          bzrdir.BzrDir.create_standalone_workingtree,
337
334
                          self.get_readonly_url('child'), format=format)
338
 
        tree = bzrdir.BzrDir.create_standalone_workingtree('child', 
 
335
        tree = bzrdir.BzrDir.create_standalone_workingtree('child',
339
336
            format=format)
340
337
        tree.bzrdir.open_repository()
341
338
 
360
357
        self.vfs_transport_factory = MemoryServer
361
358
        # outside a repo the default convenience output is a repo+branch_tree
362
359
        format = bzrdir.format_registry.make_bzrdir('knit')
363
 
        branch = bzrdir.BzrDir.create_branch_convenience(self.get_url(), 
 
360
        branch = bzrdir.BzrDir.create_branch_convenience(self.get_url(),
364
361
                                                         format=format)
365
362
        self.assertRaises(errors.NoWorkingTree,
366
363
                          branch.bzrdir.open_workingtree)
376
373
        branch.bzrdir.open_workingtree()
377
374
        self.assertRaises(errors.NoRepositoryPresent,
378
375
                          branch.bzrdir.open_repository)
379
 
            
 
376
 
380
377
    def test_create_branch_convenience_under_shared_repo_force_no_tree(self):
381
378
        # inside a repo the default convenience output is a branch+ follow the
382
379
        # repo tree policy but we can override that
388
385
                          branch.bzrdir.open_workingtree)
389
386
        self.assertRaises(errors.NoRepositoryPresent,
390
387
                          branch.bzrdir.open_repository)
391
 
            
 
388
 
392
389
    def test_create_branch_convenience_under_shared_repo_no_tree_policy(self):
393
390
        # inside a repo the default convenience output is a branch+ follow the
394
391
        # repo tree policy
395
392
        format = bzrdir.format_registry.make_bzrdir('knit')
396
393
        repo = self.make_repository('.', shared=True, format=format)
397
394
        repo.set_make_working_trees(False)
398
 
        branch = bzrdir.BzrDir.create_branch_convenience('child', 
 
395
        branch = bzrdir.BzrDir.create_branch_convenience('child',
399
396
                                                         format=format)
400
397
        self.assertRaises(errors.NoWorkingTree,
401
398
                          branch.bzrdir.open_workingtree)
431
428
        """The default acquisition policy should create a standalone branch."""
432
429
        my_bzrdir = self.make_bzrdir('.')
433
430
        repo_policy = my_bzrdir.determine_repository_policy()
434
 
        repo = repo_policy.acquire_repository()
 
431
        repo, is_new = repo_policy.acquire_repository()
435
432
        self.assertEqual(repo.bzrdir.root_transport.base,
436
433
                         my_bzrdir.root_transport.base)
437
434
        self.assertFalse(repo.is_shared())
438
435
 
439
 
 
440
436
    def test_determine_stacking_policy(self):
441
437
        parent_bzrdir = self.make_bzrdir('.')
442
438
        child_bzrdir = self.make_bzrdir('child')
466
462
        self.assertEqual(child_branch.base,
467
463
                         new_child.open_branch().get_stacked_on_url())
468
464
 
 
465
    def test_default_stacking_with_stackable_branch_unstackable_repo(self):
 
466
        # Make stackable source branch with an unstackable repo format.
 
467
        source_bzrdir = self.make_bzrdir('source')
 
468
        pack_repo.RepositoryFormatKnitPack1().initialize(source_bzrdir)
 
469
        source_branch = bzrlib.branch.BzrBranchFormat7().initialize(source_bzrdir)
 
470
        # Make a directory with a default stacking policy
 
471
        parent_bzrdir = self.make_bzrdir('parent')
 
472
        stacked_on = self.make_branch('parent/stacked-on', format='pack-0.92')
 
473
        parent_bzrdir.get_config().set_default_stack_on(stacked_on.base)
 
474
        # Clone source into directory
 
475
        target = source_bzrdir.clone(self.get_url('parent/target'))
 
476
 
469
477
    def test_sprout_obeys_stacking_policy(self):
470
478
        child_branch, new_child_transport = self.prepare_default_stacking()
471
479
        new_child = child_branch.bzrdir.sprout(new_child_transport.base)
725
733
        opened_bzrdir = bzrdir.BzrDir.open_from_transport(transport)
726
734
        self.assertEqual(transport.base, opened_bzrdir.root_transport.base)
727
735
        self.assertIsInstance(opened_bzrdir, bzrdir.BzrDir)
728
 
        
 
736
 
729
737
    def test_open_from_transport_no_bzrdir(self):
730
738
        transport = get_transport(self.get_url())
731
739
        self.assertRaises(NotBranchError, bzrdir.BzrDir.open_from_transport,
740
748
                          transport)
741
749
 
742
750
    def test_sprout_recursive(self):
743
 
        tree = self.make_branch_and_tree('tree1', format='dirstate-with-subtree')
 
751
        tree = self.make_branch_and_tree('tree1',
 
752
                                         format='dirstate-with-subtree')
744
753
        sub_tree = self.make_branch_and_tree('tree1/subtree',
745
754
            format='dirstate-with-subtree')
 
755
        sub_tree.set_root_id('subtree-root')
746
756
        tree.add_reference(sub_tree)
747
757
        self.build_tree(['tree1/subtree/file'])
748
758
        sub_tree.add('file')
749
759
        tree.commit('Initial commit')
750
 
        tree.bzrdir.sprout('tree2')
 
760
        tree2 = tree.bzrdir.sprout('tree2').open_workingtree()
 
761
        tree2.lock_read()
 
762
        self.addCleanup(tree2.unlock)
751
763
        self.failUnlessExists('tree2/subtree/file')
 
764
        self.assertEqual('tree-reference', tree2.kind('subtree-root'))
752
765
 
753
766
    def test_cloning_metadir(self):
754
767
        """Ensure that cloning metadir is suitable"""
885
898
        self.assertTrue(tree.bzrdir.needs_format_conversion(
886
899
            new_format))
887
900
 
 
901
    def test_initialize_on_format_uses_smart_transport(self):
 
902
        self.setup_smart_server_with_call_log()
 
903
        new_format = bzrdir.format_registry.make_bzrdir('dirstate')
 
904
        transport = self.get_transport('target')
 
905
        transport.ensure_base()
 
906
        self.reset_smart_call_log()
 
907
        instance = new_format.initialize_on_transport(transport)
 
908
        self.assertIsInstance(instance, remote.RemoteBzrDir)
 
909
        rpc_count = len(self.hpss_calls)
 
910
        # This figure represent the amount of work to perform this use case. It
 
911
        # is entirely ok to reduce this number if a test fails due to rpc_count
 
912
        # being too low. If rpc_count increases, more network roundtrips have
 
913
        # become necessary for this use case. Please do not adjust this number
 
914
        # upwards without agreement from bzr's network support maintainers.
 
915
        self.assertEqual(2, rpc_count)
 
916
 
888
917
 
889
918
class TestFormat5(TestCaseWithTransport):
890
919
    """Tests specific to the version 5 bzrdir format."""
891
920
 
892
921
    def test_same_lockfiles_between_tree_repo_branch(self):
893
 
        # this checks that only a single lockfiles instance is created 
 
922
        # this checks that only a single lockfiles instance is created
894
923
        # for format 5 objects
895
924
        dir = bzrdir.BzrDirFormat5().initialize(self.get_url())
896
925
        def check_dir_components_use_same_lock(dir):
903
932
        # and if we open it normally.
904
933
        dir = bzrdir.BzrDir.open(self.get_url())
905
934
        check_dir_components_use_same_lock(dir)
906
 
    
 
935
 
907
936
    def test_can_convert(self):
908
937
        # format 5 dirs are convertable
909
938
        dir = bzrdir.BzrDirFormat5().initialize(self.get_url())
910
939
        self.assertTrue(dir.can_convert_format())
911
 
    
 
940
 
912
941
    def test_needs_conversion(self):
913
942
        # format 5 dirs need a conversion if they are not the default,
914
943
        # and they aren't
924
953
    """Tests specific to the version 6 bzrdir format."""
925
954
 
926
955
    def test_same_lockfiles_between_tree_repo_branch(self):
927
 
        # this checks that only a single lockfiles instance is created 
 
956
        # this checks that only a single lockfiles instance is created
928
957
        # for format 6 objects
929
958
        dir = bzrdir.BzrDirFormat6().initialize(self.get_url())
930
959
        def check_dir_components_use_same_lock(dir):
937
966
        # and if we open it normally.
938
967
        dir = bzrdir.BzrDir.open(self.get_url())
939
968
        check_dir_components_use_same_lock(dir)
940
 
    
 
969
 
941
970
    def test_can_convert(self):
942
971
        # format 6 dirs are convertable
943
972
        dir = bzrdir.BzrDirFormat6().initialize(self.get_url())
944
973
        self.assertTrue(dir.can_convert_format())
945
 
    
 
974
 
946
975
    def test_needs_conversion(self):
947
976
        # format 6 dirs need an conversion if they are not the default.
948
977
        dir = bzrdir.BzrDirFormat6().initialize(self.get_url())
984
1013
 
985
1014
class TestNotBzrDir(TestCaseWithTransport):
986
1015
    """Tests for using the bzrdir api with a non .bzr based disk format.
987
 
    
 
1016
 
988
1017
    If/when one of these is in the core, we can let the implementation tests
989
1018
    verify this works.
990
1019
    """
991
1020
 
992
1021
    def test_create_and_find_format(self):
993
 
        # create a .notbzr dir 
 
1022
        # create a .notbzr dir
994
1023
        format = NotBzrDirFormat()
995
1024
        dir = format.initialize(self.get_url())
996
1025
        self.assertIsInstance(dir, NotBzrDir)
1021
1050
    def setUp(self):
1022
1051
        super(NonLocalTests, self).setUp()
1023
1052
        self.vfs_transport_factory = MemoryServer
1024
 
    
 
1053
 
1025
1054
    def test_create_branch_convenience(self):
1026
1055
        # outside a repo the default convenience output is a repo+branch_tree
1027
1056
        format = bzrdir.format_registry.make_bzrdir('knit')
1072
1101
 
1073
1102
    We can't inherit directly from TestCaseWithTwoWebservers or the
1074
1103
    test framework will try to create an instance which cannot
1075
 
    run, its implementation being incomplete. 
 
1104
    run, its implementation being incomplete.
1076
1105
    """
1077
1106
 
1078
1107
    def create_transport_readonly_server(self):
1123
1152
    _transport = HttpTransport_urllib
1124
1153
 
1125
1154
    def _qualified_url(self, host, port):
1126
 
        return 'http+urllib://%s:%s' % (host, port)
 
1155
        result = 'http+urllib://%s:%s' % (host, port)
 
1156
        self.permit_url(result)
 
1157
        return result
1127
1158
 
1128
1159
 
1129
1160
 
1133
1164
    """Tests redirections for pycurl implementation"""
1134
1165
 
1135
1166
    def _qualified_url(self, host, port):
1136
 
        return 'http+pycurl://%s:%s' % (host, port)
 
1167
        result = 'http+pycurl://%s:%s' % (host, port)
 
1168
        self.permit_url(result)
 
1169
        return result
1137
1170
 
1138
1171
 
1139
1172
class TestHTTPRedirections_nosmart(TestHTTPRedirections,
1143
1176
    _transport = NoSmartTransportDecorator
1144
1177
 
1145
1178
    def _qualified_url(self, host, port):
1146
 
        return 'nosmart+http://%s:%s' % (host, port)
 
1179
        result = 'nosmart+http://%s:%s' % (host, port)
 
1180
        self.permit_url(result)
 
1181
        return result
1147
1182
 
1148
1183
 
1149
1184
class TestHTTPRedirections_readonly(TestHTTPRedirections,
1153
1188
    _transport = ReadonlyTransportDecorator
1154
1189
 
1155
1190
    def _qualified_url(self, host, port):
1156
 
        return 'readonly+http://%s:%s' % (host, port)
 
1191
        result = 'readonly+http://%s:%s' % (host, port)
 
1192
        self.permit_url(result)
 
1193
        return result
1157
1194
 
1158
1195
 
1159
1196
class TestDotBzrHidden(TestCaseWithTransport):
1194
1231
 
1195
1232
class _TestBzrDir(bzrdir.BzrDirMeta1):
1196
1233
    """Test BzrDir implementation for TestBzrDirSprout.
1197
 
    
 
1234
 
1198
1235
    When created a _TestBzrDir already has repository and a branch.  The branch
1199
1236
    is a test double as well.
1200
1237
    """
1211
1248
        return _TestBzrDirFormat()
1212
1249
 
1213
1250
 
 
1251
class _TestBranchFormat(bzrlib.branch.BranchFormat):
 
1252
    """Test Branch format for TestBzrDirSprout."""
 
1253
 
 
1254
 
1214
1255
class _TestBranch(bzrlib.branch.Branch):
1215
1256
    """Test Branch implementation for TestBzrDirSprout."""
1216
1257
 
1217
1258
    def __init__(self, *args, **kwargs):
 
1259
        self._format = _TestBranchFormat()
1218
1260
        super(_TestBranch, self).__init__(*args, **kwargs)
1219
1261
        self.calls = []
1220
1262
        self._parent = None
1241
1283
        Usually, BzrDir.sprout should delegate to the branch's sprout method
1242
1284
        for part of the work.  This allows the source branch to control the
1243
1285
        choice of format for the new branch.
1244
 
        
 
1286
 
1245
1287
        There are exceptions, but this tests avoids them:
1246
1288
          - if there's no branch in the source bzrdir,
1247
1289
          - or if the stacking has been requested and the format needs to be
1268
1310
        parent = grandparent_tree.bzrdir.sprout('parent').open_branch()
1269
1311
        branch_tree = parent.bzrdir.sprout('branch').open_branch()
1270
1312
        self.assertContainsRe(branch_tree.get_parent(), '/parent/$')
 
1313
 
 
1314
 
 
1315
class TestBzrDirHooks(TestCaseWithMemoryTransport):
 
1316
 
 
1317
    def test_pre_open_called(self):
 
1318
        calls = []
 
1319
        bzrdir.BzrDir.hooks.install_named_hook('pre_open', calls.append, None)
 
1320
        transport = self.get_transport('foo')
 
1321
        url = transport.base
 
1322
        self.assertRaises(errors.NotBranchError, bzrdir.BzrDir.open, url)
 
1323
        self.assertEqual([transport.base], [t.base for t in calls])
 
1324
 
 
1325
    def test_pre_open_actual_exceptions_raised(self):
 
1326
        count = [0]
 
1327
        def fail_once(transport):
 
1328
            count[0] += 1
 
1329
            if count[0] == 1:
 
1330
                raise errors.BzrError("fail")
 
1331
        bzrdir.BzrDir.hooks.install_named_hook('pre_open', fail_once, None)
 
1332
        transport = self.get_transport('foo')
 
1333
        url = transport.base
 
1334
        err = self.assertRaises(errors.BzrError, bzrdir.BzrDir.open, url)
 
1335
        self.assertEqual('fail', err._preformatted_string)