~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_remote.py

(jelmer) Reduce the number of connections made during "bzr branch
 --stacked". (Jelmer Vernooij)

Show diffs side-by-side

added added

removed removed

Lines of Context:
25
25
 
26
26
import bz2
27
27
from cStringIO import StringIO
28
 
import zlib
29
28
 
30
29
from bzrlib import (
31
30
    branch,
42
41
    transport,
43
42
    treebuilder,
44
43
    versionedfile,
45
 
    vf_search,
46
44
    )
47
45
from bzrlib.branch import Branch
48
46
from bzrlib.bzrdir import (
50
48
    BzrDirFormat,
51
49
    RemoteBzrProber,
52
50
    )
53
 
from bzrlib.chk_serializer import chk_bencode_serializer
54
51
from bzrlib.remote import (
55
52
    RemoteBranch,
56
53
    RemoteBranchFormat,
60
57
    RemoteRepositoryFormat,
61
58
    )
62
59
from bzrlib.repofmt import groupcompress_repo, knitpack_repo
63
 
from bzrlib.revision import (
64
 
    NULL_REVISION,
65
 
    Revision,
66
 
    )
 
60
from bzrlib.revision import NULL_REVISION
67
61
from bzrlib.smart import medium, request
68
62
from bzrlib.smart.client import _SmartClient
69
63
from bzrlib.smart.repository import (
70
64
    SmartServerRepositoryGetParentMap,
71
65
    SmartServerRepositoryGetStream_1_19,
72
 
    _stream_to_byte_stream,
73
66
    )
74
67
from bzrlib.symbol_versioning import deprecated_in
75
68
from bzrlib.tests import (
175
168
    def test_remote_branch_set_append_revisions_only(self):
176
169
        # Make a format 1.9 branch, which supports append_revisions_only
177
170
        branch = self.make_branch('branch', format='1.9')
 
171
        config = branch.get_config()
178
172
        branch.set_append_revisions_only(True)
179
 
        config = branch.get_config_stack()
180
173
        self.assertEqual(
181
 
            True, config.get('append_revisions_only'))
 
174
            'True', config.get_user_option('append_revisions_only'))
182
175
        branch.set_append_revisions_only(False)
183
 
        config = branch.get_config_stack()
184
176
        self.assertEqual(
185
 
            False, config.get('append_revisions_only'))
 
177
            'False', config.get_user_option('append_revisions_only'))
186
178
 
187
179
    def test_remote_branch_set_append_revisions_only_upgrade_reqd(self):
188
180
        branch = self.make_branch('branch', format='knit')
 
181
        config = branch.get_config()
189
182
        self.assertRaises(
190
183
            errors.UpgradeRequired, branch.set_append_revisions_only, True)
191
184
 
491
484
        self.assertEqual(None, result._branch_format)
492
485
        self.assertFinished(client)
493
486
 
494
 
    def test_unknown(self):
495
 
        transport = self.get_transport('quack')
496
 
        referenced = self.make_branch('referenced')
497
 
        expected = referenced.bzrdir.cloning_metadir()
498
 
        client = FakeClient(transport.base)
499
 
        client.add_expected_call(
500
 
            'BzrDir.cloning_metadir', ('quack/', 'False'),
501
 
            'success', ('unknown', 'unknown', ('branch', ''))),
502
 
        a_bzrdir = RemoteBzrDir(transport, RemoteBzrDirFormat(),
503
 
            _client=client)
504
 
        self.assertRaises(errors.UnknownFormatError, a_bzrdir.cloning_metadir)
505
 
 
506
 
 
507
 
class TestBzrDirCheckoutMetaDir(TestRemote):
508
 
 
509
 
    def test__get_checkout_format(self):
510
 
        transport = MemoryTransport()
511
 
        client = FakeClient(transport.base)
512
 
        reference_bzrdir_format = bzrdir.format_registry.get('default')()
513
 
        control_name = reference_bzrdir_format.network_name()
514
 
        client.add_expected_call(
515
 
            'BzrDir.checkout_metadir', ('quack/', ),
516
 
            'success', (control_name, '', ''))
517
 
        transport.mkdir('quack')
518
 
        transport = transport.clone('quack')
519
 
        a_bzrdir = RemoteBzrDir(transport, RemoteBzrDirFormat(),
520
 
            _client=client)
521
 
        result = a_bzrdir.checkout_metadir()
522
 
        # We should have got a reference control dir with default branch and
523
 
        # repository formats.
524
 
        self.assertEqual(bzrdir.BzrDirMetaFormat1, type(result))
525
 
        self.assertEqual(None, result._repository_format)
526
 
        self.assertEqual(None, result._branch_format)
527
 
        self.assertFinished(client)
528
 
 
529
 
    def test_unknown_format(self):
530
 
        transport = MemoryTransport()
531
 
        client = FakeClient(transport.base)
532
 
        client.add_expected_call(
533
 
            'BzrDir.checkout_metadir', ('quack/',),
534
 
            'success', ('dontknow', '', ''))
535
 
        transport.mkdir('quack')
536
 
        transport = transport.clone('quack')
537
 
        a_bzrdir = RemoteBzrDir(transport, RemoteBzrDirFormat(),
538
 
            _client=client)
539
 
        self.assertRaises(errors.UnknownFormatError,
540
 
            a_bzrdir.checkout_metadir)
541
 
        self.assertFinished(client)
542
 
 
543
487
 
544
488
class TestBzrDirDestroyBranch(TestRemote):
545
489
 
2411
2355
            client._calls)
2412
2356
 
2413
2357
 
2414
 
class TestRepositoryReconcile(TestRemoteRepository):
2415
 
 
2416
 
    def test_reconcile(self):
2417
 
        transport_path = 'hill'
2418
 
        repo, client = self.setup_fake_client_and_repository(transport_path)
2419
 
        body = ("garbage_inventories: 2\n"
2420
 
                "inconsistent_parents: 3\n")
2421
 
        client.add_expected_call(
2422
 
            'Repository.lock_write', ('hill/', ''),
2423
 
            'success', ('ok', 'a token'))
2424
 
        client.add_success_response_with_body(body, 'ok')
2425
 
        reconciler = repo.reconcile()
2426
 
        self.assertEqual(
2427
 
            [('call', 'Repository.lock_write', ('hill/', '')),
2428
 
             ('call_expecting_body', 'Repository.reconcile',
2429
 
                ('hill/', 'a token'))],
2430
 
            client._calls)
2431
 
        self.assertEquals(2, reconciler.garbage_inventories)
2432
 
        self.assertEquals(3, reconciler.inconsistent_parents)
2433
 
 
2434
 
 
2435
 
class TestRepositoryGetRevisionSignatureText(TestRemoteRepository):
2436
 
 
2437
 
    def test_text(self):
2438
 
        # ('ok',), body with signature text
2439
 
        transport_path = 'quack'
2440
 
        repo, client = self.setup_fake_client_and_repository(transport_path)
2441
 
        client.add_success_response_with_body(
2442
 
            'THETEXT', 'ok')
2443
 
        self.assertEquals("THETEXT", repo.get_signature_text("revid"))
2444
 
        self.assertEqual(
2445
 
            [('call_expecting_body', 'Repository.get_revision_signature_text',
2446
 
             ('quack/', 'revid'))],
2447
 
            client._calls)
2448
 
 
2449
 
    def test_no_signature(self):
2450
 
        transport_path = 'quick'
2451
 
        repo, client = self.setup_fake_client_and_repository(transport_path)
2452
 
        client.add_error_response('nosuchrevision', 'unknown')
2453
 
        self.assertRaises(errors.NoSuchRevision, repo.get_signature_text,
2454
 
                "unknown")
2455
 
        self.assertEqual(
2456
 
            [('call_expecting_body', 'Repository.get_revision_signature_text',
2457
 
              ('quick/', 'unknown'))],
2458
 
            client._calls)
2459
 
 
2460
 
 
2461
2358
class TestRepositoryGetGraph(TestRemoteRepository):
2462
2359
 
2463
2360
    def test_get_graph(self):
2473
2370
    def test_add_signature_text(self):
2474
2371
        transport_path = 'quack'
2475
2372
        repo, client = self.setup_fake_client_and_repository(transport_path)
2476
 
        client.add_expected_call(
2477
 
            'Repository.lock_write', ('quack/', ''),
2478
 
            'success', ('ok', 'a token'))
2479
 
        client.add_expected_call(
2480
 
            'Repository.start_write_group', ('quack/', 'a token'),
2481
 
            'success', ('ok', ('token1', )))
2482
 
        client.add_expected_call(
2483
 
            'Repository.add_signature_text', ('quack/', 'a token', 'rev1',
2484
 
                'token1'),
2485
 
            'success', ('ok', ), None)
2486
 
        repo.lock_write()
2487
 
        repo.start_write_group()
 
2373
        client.add_success_response('ok')
2488
2374
        self.assertIs(None,
2489
2375
            repo.add_signature_text("rev1", "every bloody emperor"))
2490
2376
        self.assertEqual(
2491
 
            ('call_with_body_bytes_expecting_body',
2492
 
              'Repository.add_signature_text',
2493
 
                ('quack/', 'a token', 'rev1', 'token1'),
2494
 
              'every bloody emperor'),
2495
 
            client._calls[-1])
 
2377
            [('call_with_body_bytes',
 
2378
              'Repository.add_signature_text', ('quack/', 'rev1', ),
 
2379
              'every bloody emperor')],
 
2380
            client._calls)
2496
2381
 
2497
2382
 
2498
2383
class TestRepositoryGetParentMap(TestRemoteRepository):
2723
2608
        self.assertEqual({'rev1': ('null:',)}, graph.get_parent_map(['rev1']))
2724
2609
 
2725
2610
 
2726
 
class TestRepositoryGetRevisions(TestRemoteRepository):
2727
 
 
2728
 
    def test_hpss_missing_revision(self):
2729
 
        transport_path = 'quack'
2730
 
        repo, client = self.setup_fake_client_and_repository(transport_path)
2731
 
        client.add_success_response_with_body(
2732
 
            '', 'ok', '10')
2733
 
        self.assertRaises(errors.NoSuchRevision, repo.get_revisions,
2734
 
            ['somerev1', 'anotherrev2'])
2735
 
        self.assertEqual(
2736
 
            [('call_with_body_bytes_expecting_body', 'Repository.iter_revisions',
2737
 
             ('quack/', ), "somerev1\nanotherrev2")],
2738
 
            client._calls)
2739
 
 
2740
 
    def test_hpss_get_single_revision(self):
2741
 
        transport_path = 'quack'
2742
 
        repo, client = self.setup_fake_client_and_repository(transport_path)
2743
 
        somerev1 = Revision("somerev1")
2744
 
        somerev1.committer = "Joe Committer <joe@example.com>"
2745
 
        somerev1.timestamp = 1321828927
2746
 
        somerev1.timezone = -60
2747
 
        somerev1.inventory_sha1 = "691b39be74c67b1212a75fcb19c433aaed903c2b"
2748
 
        somerev1.message = "Message"
2749
 
        body = zlib.compress(chk_bencode_serializer.write_revision_to_string(
2750
 
            somerev1))
2751
 
        # Split up body into two bits to make sure the zlib compression object
2752
 
        # gets data fed twice.
2753
 
        client.add_success_response_with_body(
2754
 
                [body[:10], body[10:]], 'ok', '10')
2755
 
        revs = repo.get_revisions(['somerev1'])
2756
 
        self.assertEquals(revs, [somerev1])
2757
 
        self.assertEqual(
2758
 
            [('call_with_body_bytes_expecting_body', 'Repository.iter_revisions',
2759
 
             ('quack/', ), "somerev1")],
2760
 
            client._calls)
2761
 
 
2762
 
 
2763
2611
class TestRepositoryGetRevisionGraph(TestRemoteRepository):
2764
2612
 
2765
2613
    def test_null_revision(self):
3059
2907
            'success', ('ok', 'a token'))
3060
2908
        client.add_expected_call(
3061
2909
            'Repository.start_write_group', ('quack/', 'a token'),
3062
 
            'success', ('ok', ('token1', )))
 
2910
            'success', ('ok', 'token1'))
3063
2911
        repo.lock_write()
3064
2912
        repo.start_write_group()
3065
2913
 
3198
3046
        self.assertEqual([], client._calls)
3199
3047
 
3200
3048
 
3201
 
class TestRepositoryIterFilesBytes(TestRemoteRepository):
3202
 
    """Test Repository.iter_file_bytes."""
3203
 
 
3204
 
    def test_single(self):
3205
 
        transport_path = 'quack'
3206
 
        repo, client = self.setup_fake_client_and_repository(transport_path)
3207
 
        client.add_expected_call(
3208
 
            'Repository.iter_files_bytes', ('quack/', ),
3209
 
            'success', ('ok',), iter(["ok\x000", "\n", zlib.compress("mydata" * 10)]))
3210
 
        for (identifier, byte_stream) in repo.iter_files_bytes([("somefile",
3211
 
                "somerev", "myid")]):
3212
 
            self.assertEquals("myid", identifier)
3213
 
            self.assertEquals("".join(byte_stream), "mydata" * 10)
3214
 
 
3215
 
    def test_missing(self):
3216
 
        transport_path = 'quack'
3217
 
        repo, client = self.setup_fake_client_and_repository(transport_path)
3218
 
        client.add_expected_call(
3219
 
            'Repository.iter_files_bytes',
3220
 
                ('quack/', ),
3221
 
            'error', ('RevisionNotPresent', 'somefile', 'somerev'),
3222
 
            iter(["absent\0somefile\0somerev\n"]))
3223
 
        self.assertRaises(errors.RevisionNotPresent, list,
3224
 
                repo.iter_files_bytes(
3225
 
                [("somefile", "somerev", "myid")]))
3226
 
 
3227
 
 
3228
3049
class TestRepositoryInsertStreamBase(TestRemoteRepository):
3229
3050
    """Base class for Repository.insert_stream and .insert_stream_1.19
3230
3051
    tests.
3951
3772
        revs = [r for (r,ps) in graph.iter_ancestry([tip])
3952
3773
                if r != NULL_REVISION]
3953
3774
        revs.reverse()
3954
 
        search = vf_search.PendingAncestryResult([tip], stacked.repository)
 
3775
        search = _mod_graph.PendingAncestryResult([tip], stacked.repository)
3955
3776
        self.reset_smart_call_log()
3956
3777
        stream = source.get_stream(search)
3957
3778
        # We trust that if a revision is in the stream the rest of the new
4063
3884
        self.hpss_calls = []
4064
3885
        local.repository.fetch(
4065
3886
            remote_branch.repository,
4066
 
            fetch_spec=vf_search.EverythingResult(remote_branch.repository))
 
3887
            fetch_spec=_mod_graph.EverythingResult(remote_branch.repository))
4067
3888
        self.assertEqual(['Repository.get_stream_1.19'], self.hpss_calls)
4068
3889
 
4069
3890
    def override_verb(self, verb_name, verb):
4070
3891
        request_handlers = request.request_handlers
4071
3892
        orig_verb = request_handlers.get(verb_name)
4072
 
        orig_info = request_handlers.get_info(verb_name)
4073
3893
        request_handlers.register(verb_name, verb, override_existing=True)
4074
3894
        self.addCleanup(request_handlers.register, verb_name, orig_verb,
4075
 
                override_existing=True, info=orig_info)
 
3895
                override_existing=True)
4076
3896
 
4077
3897
    def test_fetch_everything_backwards_compat(self):
4078
3898
        """Can fetch with EverythingResult even with pre 2.4 servers.
4103
3923
        self.hpss_calls = []
4104
3924
        local.repository.fetch(
4105
3925
            remote_branch.repository,
4106
 
            fetch_spec=vf_search.EverythingResult(remote_branch.repository))
 
3926
            fetch_spec=_mod_graph.EverythingResult(remote_branch.repository))
4107
3927
        # make sure the overridden verb was used
4108
3928
        self.assertLength(1, verb_log)
4109
3929
        # more than one HPSS call is needed, but because it's a VFS callback
4234
4054
            'Repository.unlock', ('quack/', 'token', 'False'),
4235
4055
            'success', ('ok', ))
4236
4056
        repo.pack(['hinta', 'hintb'])
4237
 
 
4238
 
 
4239
 
class TestRepositoryIterInventories(TestRemoteRepository):
4240
 
    """Test Repository.iter_inventories."""
4241
 
 
4242
 
    def _serialize_inv_delta(self, old_name, new_name, delta):
4243
 
        serializer = inventory_delta.InventoryDeltaSerializer(True, False)
4244
 
        return "".join(serializer.delta_to_lines(old_name, new_name, delta))
4245
 
 
4246
 
    def test_single_empty(self):
4247
 
        transport_path = 'quack'
4248
 
        repo, client = self.setup_fake_client_and_repository(transport_path)
4249
 
        fmt = bzrdir.format_registry.get('2a')().repository_format
4250
 
        repo._format = fmt
4251
 
        stream = [('inventory-deltas', [
4252
 
            versionedfile.FulltextContentFactory('somerevid', None, None,
4253
 
                self._serialize_inv_delta('null:', 'somerevid', []))])]
4254
 
        client.add_expected_call(
4255
 
            'VersionedFileRepository.get_inventories', ('quack/', 'unordered'),
4256
 
            'success', ('ok', ),
4257
 
            _stream_to_byte_stream(stream, fmt))
4258
 
        ret = list(repo.iter_inventories(["somerevid"]))
4259
 
        self.assertLength(1, ret)
4260
 
        inv = ret[0]
4261
 
        self.assertEquals("somerevid", inv.revision_id)
4262
 
 
4263
 
    def test_empty(self):
4264
 
        transport_path = 'quack'
4265
 
        repo, client = self.setup_fake_client_and_repository(transport_path)
4266
 
        ret = list(repo.iter_inventories([]))
4267
 
        self.assertEquals(ret, [])
4268
 
 
4269
 
    def test_missing(self):
4270
 
        transport_path = 'quack'
4271
 
        repo, client = self.setup_fake_client_and_repository(transport_path)
4272
 
        client.add_expected_call(
4273
 
            'VersionedFileRepository.get_inventories', ('quack/', 'unordered'),
4274
 
            'success', ('ok', ), iter([]))
4275
 
        self.assertRaises(errors.NoSuchRevision, list, repo.iter_inventories(
4276
 
            ["somerevid"]))