/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 breezy/tests/test_remote.py

  • Committer: Jelmer Vernooij
  • Date: 2019-05-29 03:22:34 UTC
  • mfrom: (7303 work)
  • mto: This revision was merged to the branch mainline in revision 7306.
  • Revision ID: jelmer@jelmer.uk-20190529032234-mt3fuws8gq03tapi
Merge trunk.

Show diffs side-by-side

added added

removed removed

Lines of Context:
100
100
 
101
101
    scenarios = [
102
102
        ('HPSS-v2',
103
 
            {'transport_server': test_server.SmartTCPServer_for_testing_v2_only}),
 
103
            {'transport_server':
 
104
                test_server.SmartTCPServer_for_testing_v2_only}),
104
105
        ('HPSS-v3',
105
106
            {'transport_server': test_server.SmartTCPServer_for_testing})]
106
107
 
107
 
 
108
108
    def setUp(self):
109
109
        super(BasicRemoteObjectTests, self).setUp()
110
110
        self.transport = self.get_transport()
164
164
        bd = self.make_controldir('unstackable', format='pack-0.92')
165
165
        r = bd.create_repository()
166
166
        self.assertFalse(r._format.supports_external_lookups)
167
 
        r = BzrDir.open_from_transport(t.clone('unstackable')).open_repository()
 
167
        r = BzrDir.open_from_transport(
 
168
            t.clone('unstackable')).open_repository()
168
169
        self.assertFalse(r._format.supports_external_lookups)
169
170
        bd = self.make_controldir('stackable', format='1.9')
170
171
        r = bd.create_repository()
229
230
        _SmartClient.__init__(self, FakeMedium(self._calls, fake_medium_base))
230
231
 
231
232
    def add_expected_call(self, call_name, call_args, response_type,
232
 
        response_args, response_body=None):
 
233
                          response_args, response_body=None):
233
234
        if self._expected_calls is None:
234
235
            self._expected_calls = []
235
236
        self._expected_calls.append((call_name, call_args))
252
253
    def finished_test(self):
253
254
        if self._expected_calls:
254
255
            raise AssertionError("%r finished but was still expecting %r"
255
 
                % (self, self._expected_calls[0]))
 
256
                                 % (self, self._expected_calls[0]))
256
257
 
257
258
    def _get_next_response(self):
258
259
        try:
259
260
            response_tuple = self.responses.pop(0)
260
 
        except IndexError as e:
261
 
            raise AssertionError("%r didn't expect any more calls"
262
 
                % (self,))
 
261
        except IndexError:
 
262
            raise AssertionError("%r didn't expect any more calls" % (self,))
263
263
        if response_tuple[0] == b'unknown':
264
264
            raise errors.UnknownSmartMethod(response_tuple[1])
265
265
        elif response_tuple[0] == b'error':
274
274
            next_call = self._expected_calls.pop(0)
275
275
        except IndexError:
276
276
            raise AssertionError("%r didn't expect any more calls "
277
 
                "but got %r%r"
278
 
                % (self, method, args,))
 
277
                                 "but got %r%r"
 
278
                                 % (self, method, args,))
279
279
        if next_call is None:
280
280
            return
281
281
        if method != next_call[0] or args != next_call[1]:
282
 
            raise AssertionError("%r expected %r%r "
283
 
                "but got %r%r"
284
 
                % (self, next_call[0], next_call[1], method, args,))
 
282
            raise AssertionError(
 
283
                "%r expected %r%r but got %r%r" %
 
284
                (self, next_call[0], next_call[1], method, args,))
285
285
 
286
286
    def call(self, method, *args):
287
287
        self._check_call(method, args)
304
304
    def call_with_body_bytes_expecting_body(self, method, args, body):
305
305
        self._check_call(method, args)
306
306
        self._calls.append(('call_with_body_bytes_expecting_body', method,
307
 
            args, body))
 
307
                            args, body))
308
308
        result = self._get_next_response()
309
309
        self.expecting_body = True
310
310
        return result[1], FakeProtocol(result[2], self)
314
314
        # that's what happens a real medium.
315
315
        stream = list(stream)
316
316
        self._check_call(args[0], args[1:])
317
 
        self._calls.append(('call_with_body_stream', args[0], args[1:], stream))
 
317
        self._calls.append(
 
318
            ('call_with_body_stream', args[0], args[1:], stream))
318
319
        result = self._get_next_response()
319
320
        # The second value returned from call_with_body_stream is supposed to
320
321
        # be a response_handler object, but so far no tests depend on that.
321
 
        response_handler = None 
 
322
        response_handler = None
322
323
        return result[1], response_handler
323
324
 
324
325
 
448
449
        self.reset_smart_call_log()
449
450
        verb = b'BzrDir.cloning_metadir'
450
451
        self.disable_verb(verb)
451
 
        format = a_dir.cloning_metadir()
 
452
        a_dir.cloning_metadir()
452
453
        call_count = len([call for call in self.hpss_calls if
453
 
            call.call.method == verb])
 
454
                          call.call.method == verb])
454
455
        self.assertEqual(1, call_count)
455
456
 
456
457
    def test_branch_reference(self):
465
466
            b'BzrDir.open_branchV3', (b'quack/',),
466
467
            b'success', (b'ref', self.get_url('referenced').encode('utf-8'))),
467
468
        a_controldir = RemoteBzrDir(transport, RemoteBzrDirFormat(),
468
 
            _client=client)
 
469
                                    _client=client)
469
470
        result = a_controldir.cloning_metadir()
470
471
        # We should have got a control dir matching the referenced branch.
471
472
        self.assertEqual(bzrdir.BzrDirMetaFormat1, type(result))
472
 
        self.assertEqual(expected._repository_format, result._repository_format)
 
473
        self.assertEqual(expected._repository_format,
 
474
                         result._repository_format)
473
475
        self.assertEqual(expected._branch_format, result._branch_format)
474
476
        self.assertFinished(client)
475
477
 
484
486
            b'BzrDir.cloning_metadir', (b'quack/', b'False'),
485
487
            b'success', (control_name, b'', (b'branch', b''))),
486
488
        a_controldir = RemoteBzrDir(transport, RemoteBzrDirFormat(),
487
 
            _client=client)
 
489
                                    _client=client)
488
490
        result = a_controldir.cloning_metadir()
489
491
        # We should have got a reference control dir with default branch and
490
492
        # repository formats.
497
499
    def test_unknown(self):
498
500
        transport = self.get_transport('quack')
499
501
        referenced = self.make_branch('referenced')
500
 
        expected = referenced.controldir.cloning_metadir()
 
502
        referenced.controldir.cloning_metadir()
501
503
        client = FakeClient(transport.base)
502
504
        client.add_expected_call(
503
505
            b'BzrDir.cloning_metadir', (b'quack/', b'False'),
504
506
            b'success', (b'unknown', b'unknown', (b'branch', b''))),
505
507
        a_controldir = RemoteBzrDir(transport, RemoteBzrDirFormat(),
506
 
            _client=client)
507
 
        self.assertRaises(errors.UnknownFormatError, a_controldir.cloning_metadir)
 
508
                                    _client=client)
 
509
        self.assertRaises(errors.UnknownFormatError,
 
510
                          a_controldir.cloning_metadir)
508
511
 
509
512
 
510
513
class TestBzrDirCheckoutMetaDir(TestRemote):
520
523
        transport.mkdir('quack')
521
524
        transport = transport.clone('quack')
522
525
        a_controldir = RemoteBzrDir(transport, RemoteBzrDirFormat(),
523
 
            _client=client)
 
526
                                    _client=client)
524
527
        result = a_controldir.checkout_metadir()
525
528
        # We should have got a reference control dir with default branch and
526
529
        # repository formats.
538
541
        transport.mkdir('quack')
539
542
        transport = transport.clone('quack')
540
543
        a_controldir = RemoteBzrDir(transport, RemoteBzrDirFormat(),
541
 
            _client=client)
 
544
                                    _client=client)
542
545
        self.assertRaises(errors.UnknownFormatError,
543
 
            a_controldir.checkout_metadir)
 
546
                          a_controldir.checkout_metadir)
544
547
        self.assertFinished(client)
545
548
 
546
549
 
557
560
                b"": (b"branch", branch_name)}), b"success")
558
561
        client.add_success_response(
559
562
            b'ok', b'', b'no', b'no', b'no',
560
 
                reference_bzrdir_format.repository_format.network_name())
 
563
            reference_bzrdir_format.repository_format.network_name())
561
564
        client.add_error_response(b'NotStacked')
562
565
        client.add_success_response(
563
566
            b'ok', b'', b'no', b'no', b'no',
564
 
                reference_bzrdir_format.repository_format.network_name())
 
567
            reference_bzrdir_format.repository_format.network_name())
565
568
        client.add_error_response(b'NotStacked')
566
569
        transport.mkdir('quack')
567
570
        transport = transport.clone('quack')
568
571
        a_controldir = RemoteBzrDir(transport, RemoteBzrDirFormat(),
569
 
            _client=client)
 
572
                                    _client=client)
570
573
        result = a_controldir.get_branches()
571
574
        self.assertEqual({"", "foo"}, set(result.keys()))
572
575
        self.assertEqual(
582
585
 
583
586
    def test_destroy_default(self):
584
587
        transport = self.get_transport('quack')
585
 
        referenced = self.make_branch('referenced')
 
588
        self.make_branch('referenced')
586
589
        client = FakeClient(transport.base)
587
590
        client.add_expected_call(
588
591
            b'BzrDir.destroy_branch', (b'quack/', ),
589
592
            b'success', (b'ok',)),
590
593
        a_controldir = RemoteBzrDir(transport, RemoteBzrDirFormat(),
591
 
            _client=client)
 
594
                                    _client=client)
592
595
        a_controldir.destroy_branch()
593
596
        self.assertFinished(client)
594
597
 
602
605
            b'BzrDir.has_workingtree', (b'quack/',),
603
606
            b'success', (b'yes',)),
604
607
        a_controldir = RemoteBzrDir(transport, RemoteBzrDirFormat(),
605
 
            _client=client)
 
608
                                    _client=client)
606
609
        self.assertTrue(a_controldir.has_workingtree())
607
610
        self.assertFinished(client)
608
611
 
613
616
            b'BzrDir.has_workingtree', (b'quack/',),
614
617
            b'success', (b'no',)),
615
618
        a_controldir = RemoteBzrDir(transport, RemoteBzrDirFormat(),
616
 
            _client=client)
 
619
                                    _client=client)
617
620
        self.assertFalse(a_controldir.has_workingtree())
618
621
        self.assertFinished(client)
619
622
 
627
630
            b'BzrDir.destroy_repository', (b'quack/',),
628
631
            b'success', (b'ok',)),
629
632
        a_controldir = RemoteBzrDir(transport, RemoteBzrDirFormat(),
630
 
            _client=client)
 
633
                                    _client=client)
631
634
        a_controldir.destroy_repository()
632
635
        self.assertFinished(client)
633
636
 
646
649
        client.add_expected_call(
647
650
            b'BzrDir.open_2.1', (b'quack/',), b'success', (b'no',))
648
651
        self.assertRaises(errors.NotBranchError, RemoteBzrDir, transport,
649
 
                RemoteBzrDirFormat(), _client=client, _force_probe=True)
 
652
                          RemoteBzrDirFormat(), _client=client,
 
653
                          _force_probe=True)
650
654
        self.assertFinished(client)
651
655
 
652
656
    def test_present_without_workingtree(self):
654
658
        client.add_expected_call(
655
659
            b'BzrDir.open_2.1', (b'quack/',), b'success', (b'yes', b'no'))
656
660
        bd = RemoteBzrDir(transport, RemoteBzrDirFormat(),
657
 
            _client=client, _force_probe=True)
 
661
                          _client=client, _force_probe=True)
658
662
        self.assertIsInstance(bd, RemoteBzrDir)
659
663
        self.assertFalse(bd.has_workingtree())
660
664
        self.assertRaises(errors.NoWorkingTree, bd.open_workingtree)
665
669
        client.add_expected_call(
666
670
            b'BzrDir.open_2.1', (b'quack/',), b'success', (b'yes', b'yes'))
667
671
        bd = RemoteBzrDir(transport, RemoteBzrDirFormat(),
668
 
            _client=client, _force_probe=True)
 
672
                          _client=client, _force_probe=True)
669
673
        self.assertIsInstance(bd, RemoteBzrDir)
670
674
        self.assertTrue(bd.has_workingtree())
671
675
        self.assertRaises(errors.NotLocalUrl, bd.open_workingtree)
674
678
    def test_backwards_compat(self):
675
679
        client, transport = self.make_fake_client_and_transport()
676
680
        client.add_expected_call(
677
 
            b'BzrDir.open_2.1', (b'quack/',), b'unknown', (b'BzrDir.open_2.1',))
 
681
            b'BzrDir.open_2.1', (b'quack/',), b'unknown',
 
682
            (b'BzrDir.open_2.1',))
678
683
        client.add_expected_call(
679
684
            b'BzrDir.open', (b'quack/',), b'success', (b'yes',))
680
685
        bd = RemoteBzrDir(transport, RemoteBzrDirFormat(),
681
 
            _client=client, _force_probe=True)
 
686
                          _client=client, _force_probe=True)
682
687
        self.assertIsInstance(bd, RemoteBzrDir)
683
688
        self.assertFinished(client)
684
689
 
689
694
        # the version is 2 also do _remember_remote_is_before((1, 6)) before
690
695
        # continuing with the RPC.
691
696
        orig_check_call = client._check_call
 
697
 
692
698
        def check_call(method, args):
693
699
            client._medium._protocol_version = 2
694
700
            client._medium._remember_remote_is_before((1, 6))
696
702
            client._check_call(method, args)
697
703
        client._check_call = check_call
698
704
        client.add_expected_call(
699
 
            b'BzrDir.open_2.1', (b'quack/',), b'unknown', (b'BzrDir.open_2.1',))
 
705
            b'BzrDir.open_2.1', (b'quack/',), b'unknown',
 
706
            (b'BzrDir.open_2.1',))
700
707
        client.add_expected_call(
701
708
            b'BzrDir.open', (b'quack/',), b'success', (b'yes',))
702
709
        bd = RemoteBzrDir(transport, RemoteBzrDirFormat(),
703
 
            _client=client, _force_probe=True)
 
710
                          _client=client, _force_probe=True)
704
711
        self.assertIsInstance(bd, RemoteBzrDir)
705
712
        self.assertFinished(client)
706
713
 
714
721
        self.reset_smart_call_log()
715
722
        verb = b'BzrDir.open_branchV3'
716
723
        self.disable_verb(verb)
717
 
        format = a_dir.open_branch()
 
724
        a_dir.open_branch()
718
725
        call_count = len([call for call in self.hpss_calls if
719
 
            call.call.method == verb])
 
726
                          call.call.method == verb])
720
727
        self.assertEqual(1, call_count)
721
728
 
722
729
    def test_branch_present(self):
737
744
            b'Branch.get_stacked_on_url', (b'quack/',),
738
745
            b'error', (b'NotStacked',))
739
746
        bzrdir = RemoteBzrDir(transport, RemoteBzrDirFormat(),
740
 
            _client=client)
 
747
                              _client=client)
741
748
        result = bzrdir.open_branch()
742
749
        self.assertIsInstance(result, RemoteBranch)
743
750
        self.assertEqual(bzrdir, result.controldir)
750
757
        client = FakeClient(transport.base)
751
758
        client.add_error_response(b'nobranch')
752
759
        bzrdir = RemoteBzrDir(transport, RemoteBzrDirFormat(),
753
 
            _client=client)
 
760
                              _client=client)
754
761
        self.assertRaises(errors.NotBranchError, bzrdir.open_branch)
755
762
        self.assertEqual(
756
763
            [('call', b'BzrDir.open_branchV3', (b'quack/',))],
760
767
        # _get_tree_branch is a form of open_branch, but it should only ask for
761
768
        # branch opening, not any other network requests.
762
769
        calls = []
 
770
 
763
771
        def open_branch(name=None, possible_transports=None):
764
772
            calls.append("Called")
765
773
            return "a-branch"
767
775
        # no requests on the network - catches other api calls being made.
768
776
        client = FakeClient(transport.base)
769
777
        bzrdir = RemoteBzrDir(transport, RemoteBzrDirFormat(),
770
 
            _client=client)
 
778
                              _client=client)
771
779
        # patch the open_branch call to record that it was called.
772
780
        bzrdir.open_branch = open_branch
773
781
        self.assertEqual((None, "a-branch"), bzrdir._get_tree_branch())
792
800
            b'Branch.get_stacked_on_url', (b'~hello/',),
793
801
            b'error', (b'NotStacked',))
794
802
        bzrdir = RemoteBzrDir(transport, RemoteBzrDirFormat(),
795
 
            _client=client)
796
 
        result = bzrdir.open_branch()
 
803
                              _client=client)
 
804
        bzrdir.open_branch()
797
805
        self.assertFinished(client)
798
806
 
799
 
    def check_open_repository(self, rich_root, subtrees, external_lookup=b'no'):
 
807
    def check_open_repository(self, rich_root, subtrees,
 
808
                              external_lookup=b'no'):
800
809
        reference_format = self.get_repo_format()
801
810
        network_name = reference_format.network_name()
802
811
        transport = MemoryTransport()
815
824
            b'ok', b'', rich_response, subtree_response, external_lookup,
816
825
            network_name)
817
826
        bzrdir = RemoteBzrDir(transport, RemoteBzrDirFormat(),
818
 
            _client=client)
 
827
                              _client=client)
819
828
        result = bzrdir.open_repository()
820
829
        self.assertEqual(
821
830
            [('call', b'BzrDir.find_repositoryV3', (b'quack/',))],
836
845
        """RemoteBzrDirFormat should fail to probe if the server version is too
837
846
        old.
838
847
        """
839
 
        self.assertRaises(errors.NotBranchError,
 
848
        self.assertRaises(
 
849
            errors.NotBranchError,
840
850
            RemoteBzrProber.probe_transport, OldServerTransport())
841
851
 
842
852
 
847
857
        repo = self.make_repository('.')
848
858
        self.reset_smart_call_log()
849
859
        self.disable_verb(b'BzrDir.create_branch')
850
 
        branch = repo.controldir.create_branch()
851
 
        create_branch_call_count = len([call for call in self.hpss_calls if
852
 
            call.call.method == b'BzrDir.create_branch'])
 
860
        repo.controldir.create_branch()
 
861
        create_branch_call_count = len(
 
862
            [call for call in self.hpss_calls
 
863
             if call.call.method == b'BzrDir.create_branch'])
853
864
        self.assertEqual(1, create_branch_call_count)
854
865
 
855
866
    def test_current_server(self):
865
876
        client.add_expected_call(
866
877
            b'BzrDir.create_branch', (b'quack/', network_name),
867
878
            b'success', (b'ok', network_name, b'', b'no', b'no', b'yes',
868
 
            reference_repo_name))
 
879
                         reference_repo_name))
869
880
        a_controldir = RemoteBzrDir(transport, RemoteBzrDirFormat(),
870
 
            _client=client)
 
881
                                    _client=client)
871
882
        branch = a_controldir.create_branch()
872
883
        # We should have got a remote branch
873
884
        self.assertIsInstance(branch, remote.RemoteBranch)
893
904
        client.add_expected_call(
894
905
            b'BzrDir.create_branch', (b'extra/quack/', network_name),
895
906
            b'success', (b'ok', network_name, b'', b'no', b'no', b'yes',
896
 
            reference_repo_name))
 
907
                         reference_repo_name))
897
908
        a_controldir = RemoteBzrDir(transport, RemoteBzrDirFormat(),
898
 
            _client=client)
 
909
                                    _client=client)
899
910
        branch = a_controldir.create_branch(repository=repo)
900
911
        # We should have got a remote branch
901
912
        self.assertIsInstance(branch, remote.RemoteBranch)
911
922
        bzrdir = self.make_controldir('.')
912
923
        self.reset_smart_call_log()
913
924
        self.disable_verb(b'BzrDir.create_repository')
914
 
        repo = bzrdir.create_repository()
 
925
        bzrdir.create_repository()
915
926
        create_repo_call_count = len([call for call in self.hpss_calls if
916
 
            call.call.method == b'BzrDir.create_repository'])
 
927
                                      call.call.method == b'BzrDir.create_repository'])
917
928
        self.assertEqual(1, create_repo_call_count)
918
929
 
919
930
    def test_current_server(self):
926
937
        network_name = reference_format.network_name()
927
938
        client.add_expected_call(
928
939
            b'BzrDir.create_repository', (b'quack/',
929
 
                b'Bazaar repository format 2a (needs bzr 1.16 or later)\n',
930
 
                b'False'),
 
940
                                          b'Bazaar repository format 2a (needs bzr 1.16 or later)\n',
 
941
                                          b'False'),
931
942
            b'success', (b'ok', b'yes', b'yes', b'yes', network_name))
932
943
        a_controldir = RemoteBzrDir(transport, RemoteBzrDirFormat(),
933
 
            _client=client)
 
944
                                    _client=client)
934
945
        repo = a_controldir.create_repository()
935
946
        # We should have got a remote repository
936
947
        self.assertIsInstance(repo, remote.RemoteRepository)
964
975
        # PackRepository wants to do a stat
965
976
        client.add_success_response(b'stat', b'0', b'65535')
966
977
        remote_transport = RemoteTransport(server_url + 'quack/', medium=False,
967
 
            _client=client)
 
978
                                           _client=client)
968
979
        bzrdir = RemoteBzrDir(remote_transport, RemoteBzrDirFormat(),
969
 
            _client=client)
 
980
                              _client=client)
970
981
        repo = bzrdir.open_repository()
971
982
        self.assertEqual(
972
983
            [('call', b'BzrDir.find_repositoryV3', (b'quack/',)),
999
1010
        # PackRepository wants to do a stat
1000
1011
        client.add_success_response(b'stat', b'0', b'65535')
1001
1012
        remote_transport = RemoteTransport(server_url + 'quack/', medium=False,
1002
 
            _client=client)
 
1013
                                           _client=client)
1003
1014
        bzrdir = RemoteBzrDir(remote_transport, RemoteBzrDirFormat(),
1004
 
            _client=client)
 
1015
                              _client=client)
1005
1016
        repo = bzrdir.open_repository()
1006
1017
        self.assertEqual(
1007
1018
            [('call', b'BzrDir.find_repositoryV3', (b'quack/',)),
1008
1019
             ('call', b'BzrDir.find_repositoryV2', (b'quack/',)),
1009
1020
             ('call_expecting_body', b'get', (b'/quack/.bzr/branch-format',)),
1010
1021
             ('call', b'stat', (b'/quack/.bzr',)),
1011
 
             ('call_expecting_body', b'get', (b'/quack/.bzr/repository/format',)),
 
1022
             ('call_expecting_body', b'get',
 
1023
                 (b'/quack/.bzr/repository/format',)),
1012
1024
             ('call', b'stat', (b'/quack/.bzr/repository',)),
1013
1025
             ],
1014
1026
            client._calls)
1021
1033
        transport.mkdir('quack')
1022
1034
        transport = transport.clone('quack')
1023
1035
        client = FakeClient(transport.base)
1024
 
        client.add_success_response(b'ok', b'', b'no', b'no', b'no', network_name)
 
1036
        client.add_success_response(
 
1037
            b'ok', b'', b'no', b'no', b'no', network_name)
1025
1038
        bzrdir = RemoteBzrDir(transport, RemoteBzrDirFormat(),
1026
 
            _client=client)
 
1039
                              _client=client)
1027
1040
        repo = bzrdir.open_repository()
1028
1041
        self.assertEqual(
1029
1042
            [('call', b'BzrDir.find_repositoryV3', (b'quack/',))],
1041
1054
        client = FakeClient(transport.base)
1042
1055
        client.add_expected_call(
1043
1056
            b'BzrDirFormat.initialize_ex_1.16',
1044
 
                (default_format_name, b'path', b'False', b'False', b'False', b'',
1045
 
                 b'', b'', b'', b'False'),
 
1057
            (default_format_name, b'path', b'False', b'False', b'False', b'',
 
1058
             b'', b'', b'', b'False'),
1046
1059
            b'success',
1047
 
                (b'.', b'no', b'no', b'yes', b'repo fmt', b'repo bzrdir fmt',
1048
 
                 b'bzrdir fmt', b'False', b'', b'', b'repo lock token'))
 
1060
            (b'.', b'no', b'no', b'yes', b'repo fmt', b'repo bzrdir fmt',
 
1061
             b'bzrdir fmt', b'False', b'', b'', b'repo lock token'))
1049
1062
        # XXX: It would be better to call fmt.initialize_on_transport_ex, but
1050
1063
        # it's currently hard to test that without supplying a real remote
1051
1064
        # transport connected to a real server.
1052
 
        result = fmt._initialize_on_transport_ex_rpc(client, b'path',
1053
 
            transport, False, False, False, None, None, None, None, False)
 
1065
        fmt._initialize_on_transport_ex_rpc(
 
1066
            client, b'path', transport, False, False, False, None, None, None,
 
1067
            None, False)
1054
1068
        self.assertFinished(client)
1055
1069
 
1056
1070
    def test_error(self):
1063
1077
        client = FakeClient(transport.base)
1064
1078
        client.add_expected_call(
1065
1079
            b'BzrDirFormat.initialize_ex_1.16',
1066
 
                (default_format_name, b'path', b'False', b'False', b'False', b'',
1067
 
                 b'', b'', b'', b'False'),
 
1080
            (default_format_name, b'path', b'False', b'False', b'False', b'',
 
1081
             b'', b'', b'', b'False'),
1068
1082
            b'error',
1069
 
                (b'PermissionDenied', b'path', b'extra info'))
 
1083
            (b'PermissionDenied', b'path', b'extra info'))
1070
1084
        # XXX: It would be better to call fmt.initialize_on_transport_ex, but
1071
1085
        # it's currently hard to test that without supplying a real remote
1072
1086
        # transport connected to a real server.
1073
 
        err = self.assertRaises(errors.PermissionDenied,
 
1087
        err = self.assertRaises(
 
1088
            errors.PermissionDenied,
1074
1089
            fmt._initialize_on_transport_ex_rpc, client, b'path', transport,
1075
1090
            False, False, False, None, None, None, None, False)
1076
1091
        self.assertEqual('path', err.path)
1082
1097
        transport = self.make_smart_server('foo')
1083
1098
        transport = transport.clone('no-such-path')
1084
1099
        fmt = RemoteBzrDirFormat()
1085
 
        err = self.assertRaises(errors.NoSuchFile,
1086
 
            fmt.initialize_on_transport_ex, transport, create_prefix=False)
 
1100
        self.assertRaises(
 
1101
            errors.NoSuchFile, fmt.initialize_on_transport_ex, transport,
 
1102
            create_prefix=False)
1087
1103
 
1088
1104
 
1089
1105
class OldSmartClient(object):
1119
1135
    def make_remote_bzrdir(self, transport, client):
1120
1136
        """Make a RemotebzrDir using 'client' as the _client."""
1121
1137
        return RemoteBzrDir(transport, RemoteBzrDirFormat(),
1122
 
            _client=client)
 
1138
                            _client=client)
1123
1139
 
1124
1140
 
1125
1141
class RemoteBranchTestCase(RemoteBzrDirTestCase):
1153
1169
class TestBranchBreakLock(RemoteBranchTestCase):
1154
1170
 
1155
1171
    def test_break_lock(self):
1156
 
        transport_path = 'quack'
1157
1172
        transport = MemoryTransport()
1158
1173
        client = FakeClient(transport.base)
1159
1174
        client.add_expected_call(
1312
1327
        self.disable_verb(verb)
1313
1328
        branch.tags.get_tag_dict()
1314
1329
        call_count = len([call for call in self.hpss_calls if
1315
 
            call.call.method == verb])
 
1330
                          call.call.method == verb])
1316
1331
        self.assertEqual(1, call_count)
1317
1332
 
1318
1333
    def test_trivial(self):
1341
1356
            b'Branch.get_stacked_on_url', (b'quack/',),
1342
1357
            b'error', (b'NotStacked',))
1343
1358
        client.add_expected_call(
1344
 
            b'Branch.set_tags_bytes', (b'quack/', b'branch token', b'repo token'),
 
1359
            b'Branch.set_tags_bytes', (b'quack/',
 
1360
                                       b'branch token', b'repo token'),
1345
1361
            b'success', ('',))
1346
1362
        transport.mkdir('quack')
1347
1363
        transport = transport.clone('quack')
1358
1374
            b'Branch.get_stacked_on_url', (b'quack/',),
1359
1375
            b'error', (b'NotStacked',))
1360
1376
        client.add_expected_call(
1361
 
            b'Branch.set_tags_bytes', (b'quack/', b'branch token', b'repo token'),
 
1377
            b'Branch.set_tags_bytes', (b'quack/',
 
1378
                                       b'branch token', b'repo token'),
1362
1379
            b'unknown', (b'Branch.set_tags_bytes',))
1363
1380
        transport.mkdir('quack')
1364
1381
        transport = transport.clone('quack')
1365
1382
        branch = self.make_remote_branch(transport, client)
1366
1383
        self.lock_remote_branch(branch)
 
1384
 
1367
1385
        class StubRealBranch(object):
1368
1386
            def __init__(self):
1369
1387
                self.calls = []
 
1388
 
1370
1389
            def _set_tags_bytes(self, bytes):
1371
1390
                self.calls.append(('set_tags_bytes', bytes))
1372
1391
        real_branch = StubRealBranch()
1534
1553
        # doesn't just open in - this test probably needs to be rewritten using
1535
1554
        # a spawn()ed server.
1536
1555
        stacked_branch = self.make_branch('stacked', format='1.9')
1537
 
        memory_branch = self.make_branch('base', format='1.9')
 
1556
        self.make_branch('base', format='1.9')
1538
1557
        vfs_url = self.get_vfs_only_url('base')
1539
1558
        stacked_branch.set_stacked_on_url(vfs_url)
1540
1559
        transport = stacked_branch.controldir.root_transport
1548
1567
            b'Branch.get_stacked_on_url', (b'stacked/',),
1549
1568
            b'success', (b'ok', vfs_url.encode('utf-8')))
1550
1569
        bzrdir = RemoteBzrDir(transport, RemoteBzrDirFormat(),
1551
 
            _client=client)
 
1570
                              _client=client)
1552
1571
        repo_fmt = remote.RemoteRepositoryFormat()
1553
1572
        repo_fmt._custom_format = stacked_branch.repository._format
1554
1573
        branch = RemoteBranch(bzrdir, RemoteRepository(bzrdir, repo_fmt),
1555
 
            _client=client)
 
1574
                              _client=client)
1556
1575
        result = branch.get_stacked_on_url()
1557
1576
        self.assertEqual(vfs_url, result)
1558
1577
 
1559
1578
    def test_backwards_compatible(self):
1560
1579
        # like with bzr1.6 with no Branch.get_stacked_on_url rpc
1561
 
        base_branch = self.make_branch('base', format='1.6')
 
1580
        self.make_branch('base', format='1.6')
1562
1581
        stacked_branch = self.make_branch('stacked', format='1.6')
1563
1582
        stacked_branch.set_stacked_on_url('../base')
1564
1583
        client = FakeClient(self.get_url())
1569
1588
        client.add_expected_call(
1570
1589
            b'BzrDir.find_repositoryV3', (b'stacked/',),
1571
1590
            b'success', (b'ok', b'', b'no', b'no', b'yes',
1572
 
                stacked_branch.repository._format.network_name()))
 
1591
                         stacked_branch.repository._format.network_name()))
1573
1592
        # called twice, once from constructor and then again by us
1574
1593
        client.add_expected_call(
1575
1594
            b'Branch.get_stacked_on_url', (b'stacked/',),
1580
1599
        # this will also do vfs access, but that goes direct to the transport
1581
1600
        # and isn't seen by the FakeClient.
1582
1601
        bzrdir = RemoteBzrDir(self.get_transport('stacked'),
1583
 
            RemoteBzrDirFormat(), _client=client)
 
1602
                              RemoteBzrDirFormat(), _client=client)
1584
1603
        branch = bzrdir.open_branch()
1585
1604
        result = branch.get_stacked_on_url()
1586
1605
        self.assertEqual('../base', result)
1589
1608
        # repository
1590
1609
        self.assertEqual(1, len(branch.repository._fallback_repositories))
1591
1610
        self.assertEqual(1,
1592
 
            len(branch.repository._real_repository._fallback_repositories))
 
1611
                         len(branch.repository._real_repository._fallback_repositories))
1593
1612
 
1594
1613
    def test_get_stacked_on_real_branch(self):
1595
 
        base_branch = self.make_branch('base')
 
1614
        self.make_branch('base')
1596
1615
        stacked_branch = self.make_branch('stacked')
1597
1616
        stacked_branch.set_stacked_on_url('../base')
1598
1617
        reference_format = self.get_repo_format()
1613
1632
            b'Branch.get_stacked_on_url', (b'stacked/',),
1614
1633
            b'success', (b'ok', b'../base'))
1615
1634
        bzrdir = RemoteBzrDir(self.get_transport('stacked'),
1616
 
            RemoteBzrDirFormat(), _client=client)
 
1635
                              RemoteBzrDirFormat(), _client=client)
1617
1636
        branch = bzrdir.open_branch()
1618
1637
        result = branch.get_stacked_on_url()
1619
1638
        self.assertEqual('../base', result)
1645
1664
            (b'branch/',),
1646
1665
            b'success', (b'ok', b'0', b'null:'))
1647
1666
        client.add_expected_call(
1648
 
            b'Branch.set_last_revision', (b'branch/', b'branch token', b'repo token', b'null:',),
 
1667
            b'Branch.set_last_revision', (b'branch/',
 
1668
                                          b'branch token', b'repo token', b'null:',),
1649
1669
            b'success', (b'ok',))
1650
1670
        client.add_expected_call(
1651
1671
            b'Branch.unlock', (b'branch/', b'branch token', b'repo token'),
1679
1699
        encoded_body = bz2.compress(b'\n'.join(lines))
1680
1700
        client.add_success_response_with_body(encoded_body, b'ok')
1681
1701
        client.add_expected_call(
1682
 
            b'Branch.set_last_revision', (b'branch/', b'branch token', b'repo token', b'rev-id2',),
 
1702
            b'Branch.set_last_revision', (b'branch/',
 
1703
                                          b'branch token', b'repo token', b'rev-id2',),
1683
1704
            b'success', (b'ok',))
1684
1705
        client.add_expected_call(
1685
1706
            b'Branch.unlock', (b'branch/', b'branch token', b'repo token'),
1714
1735
        encoded_body = bz2.compress(b'\n'.join(lines))
1715
1736
        client.add_success_response_with_body(encoded_body, b'ok')
1716
1737
        client.add_expected_call(
1717
 
            b'Branch.set_last_revision', (b'branch/', b'branch token', b'repo token', b'rev-id',),
 
1738
            b'Branch.set_last_revision', (b'branch/',
 
1739
                                          b'branch token', b'repo token', b'rev-id',),
1718
1740
            b'error', (b'NoSuchRevision', b'rev-id'))
1719
1741
        client.add_expected_call(
1720
1742
            b'Branch.unlock', (b'branch/', b'branch token', b'repo token'),
1751
1773
        encoded_body = bz2.compress(b'\n'.join(lines))
1752
1774
        client.add_success_response_with_body(encoded_body, b'ok')
1753
1775
        client.add_expected_call(
1754
 
            b'Branch.set_last_revision', (b'branch/', b'branch token', b'repo token', b'rev-id',),
 
1776
            b'Branch.set_last_revision', (b'branch/',
 
1777
                                          b'branch token', b'repo token', b'rev-id',),
1755
1778
            b'error', (b'TipChangeRejected', rejection_msg_utf8))
1756
1779
        client.add_expected_call(
1757
1780
            b'Branch.unlock', (b'branch/', b'branch token', b'repo token'),
1857
1880
            b'unknown', b'Branch.set_last_revision_info')
1858
1881
 
1859
1882
        branch = self.make_remote_branch(transport, client)
 
1883
 
1860
1884
        class StubRealBranch(object):
1861
1885
            def __init__(self):
1862
1886
                self.calls = []
 
1887
 
1863
1888
            def set_last_revision_info(self, revno, revision_id):
1864
1889
                self.calls.append(
1865
1890
                    ('set_last_revision_info', revno, revision_id))
 
1891
 
1866
1892
            def _clear_cached_state(self):
1867
1893
                pass
1868
1894
        real_branch = StubRealBranch()
1870
1896
        self.lock_remote_branch(branch)
1871
1897
 
1872
1898
        # Call set_last_revision_info, and verify it behaved as expected.
1873
 
        result = branch.set_last_revision_info(1234, b'a-revision-id')
 
1899
        branch.set_last_revision_info(1234, b'a-revision-id')
1874
1900
        self.assertEqual(
1875
1901
            [('set_last_revision_info', 1234, b'a-revision-id')],
1876
1902
            real_branch.calls)
1977
2003
            b'success', (b'ok', b'branch token', b'repo token'))
1978
2004
        client.add_expected_call(
1979
2005
            b'Branch.set_config_option', (b'memory:///', b'branch token',
1980
 
            b'repo token', b'foo', b'bar', b''),
 
2006
                                          b'repo token', b'foo', b'bar', b''),
1981
2007
            b'success', ())
1982
2008
        client.add_expected_call(
1983
2009
            b'Branch.unlock', (b'memory:///', b'branch token', b'repo token'),
2001
2027
        encoded_dict_value = b'd5:ascii1:a11:unicode \xe2\x8c\x9a3:\xe2\x80\xbde'
2002
2028
        client.add_expected_call(
2003
2029
            b'Branch.set_config_option_dict', (b'memory:///', b'branch token',
2004
 
            b'repo token', encoded_dict_value, b'foo', b''),
 
2030
                                               b'repo token', encoded_dict_value, b'foo', b''),
2005
2031
            b'success', ())
2006
2032
        client.add_expected_call(
2007
2033
            b'Branch.unlock', (b'memory:///', b'branch token', b'repo token'),
2016
2042
        branch.unlock()
2017
2043
        self.assertFinished(client)
2018
2044
 
 
2045
    def test_set_option_with_bool(self):
 
2046
        client = FakeClient()
 
2047
        client.add_expected_call(
 
2048
            b'Branch.get_stacked_on_url', (b'memory:///',),
 
2049
            b'error', (b'NotStacked',),)
 
2050
        client.add_expected_call(
 
2051
            b'Branch.lock_write', (b'memory:///', b'', b''),
 
2052
            b'success', (b'ok', b'branch token', b'repo token'))
 
2053
        client.add_expected_call(
 
2054
            b'Branch.set_config_option', (b'memory:///', b'branch token',
 
2055
                                          b'repo token', b'True', b'foo', b''),
 
2056
            b'success', ())
 
2057
        client.add_expected_call(
 
2058
            b'Branch.unlock', (b'memory:///', b'branch token', b'repo token'),
 
2059
            b'success', (b'ok',))
 
2060
        transport = MemoryTransport()
 
2061
        branch = self.make_remote_branch(transport, client)
 
2062
        branch.lock_write()
 
2063
        config = branch._get_config()
 
2064
        config.set_option(True, 'foo')
 
2065
        branch.unlock()
 
2066
        self.assertFinished(client)
 
2067
 
2019
2068
    def test_backwards_compat_set_option(self):
2020
2069
        self.setup_smart_server_with_call_log()
2021
2070
        branch = self.make_branch('.')
2078
2127
            b'success', (b'ok', ), b"# line 1\n")
2079
2128
        client.add_expected_call(
2080
2129
            b'Branch.put_config_file', (b'memory:///', b'branch token',
2081
 
            b'repo token'),
 
2130
                                        b'repo token'),
2082
2131
            b'success', (b'ok',))
2083
2132
        client.add_expected_call(
2084
2133
            b'Branch.unlock', (b'memory:///', b'branch token', b'repo token'),
2093
2142
        self.assertEqual(
2094
2143
            [('call', b'Branch.get_stacked_on_url', (b'memory:///',)),
2095
2144
             ('call', b'Branch.lock_write', (b'memory:///', b'', b'')),
2096
 
             ('call_expecting_body', b'Branch.get_config_file', (b'memory:///',)),
2097
 
             ('call_expecting_body', b'Branch.get_config_file', (b'memory:///',)),
 
2145
             ('call_expecting_body', b'Branch.get_config_file',
 
2146
                 (b'memory:///',)),
 
2147
             ('call_expecting_body', b'Branch.get_config_file',
 
2148
                 (b'memory:///',)),
2098
2149
             ('call_with_body_bytes_expecting_body', b'Branch.put_config_file',
2099
2150
                 (b'memory:///', b'branch token', b'repo token'),
2100
2151
                 b'# line 1\nemail = The Dude <lebowski@example.com>\n'),
2101
 
             ('call', b'Branch.unlock', (b'memory:///', b'branch token', b'repo token'))],
 
2152
             ('call', b'Branch.unlock',
 
2153
                 (b'memory:///', b'branch token', b'repo token'))],
2102
2154
            client._calls)
2103
2155
 
2104
2156
 
2139
2191
        branch = self.make_remote_branch(transport, client)
2140
2192
        self.assertEqual(0, branch.revision_id_to_revno(b'null:'))
2141
2193
        self.assertRaises(errors.NoSuchRevision,
2142
 
            branch.revision_id_to_revno, b'unknown')
 
2194
                          branch.revision_id_to_revno, b'unknown')
2143
2195
        self.assertFinished(client)
2144
2196
 
2145
2197
    def test_dotted(self):
2159
2211
        branch = self.make_remote_branch(transport, client)
2160
2212
        self.assertEqual((0, ), branch.revision_id_to_dotted_revno(b'null:'))
2161
2213
        self.assertRaises(errors.NoSuchRevision,
2162
 
            branch.revision_id_to_dotted_revno, b'unknown')
 
2214
                          branch.revision_id_to_dotted_revno, b'unknown')
2163
2215
        self.assertFinished(client)
2164
2216
 
2165
2217
    def test_dotted_no_smart_verb(self):
2168
2220
        self.disable_verb(b'Branch.revision_id_to_revno')
2169
2221
        self.reset_smart_call_log()
2170
2222
        self.assertEqual((0, ),
2171
 
            branch.revision_id_to_dotted_revno(b'null:'))
 
2223
                         branch.revision_id_to_dotted_revno(b'null:'))
2172
2224
        self.assertLength(8, self.hpss_calls)
2173
2225
 
2174
2226
 
2182
2234
        config = bzrdir.get_config()
2183
2235
        self.assertEqual('/', config.get_default_stack_on())
2184
2236
        self.assertEqual(
2185
 
            [('call_expecting_body', b'BzrDir.get_config_file', (b'memory:///',))],
 
2237
            [('call_expecting_body', b'BzrDir.get_config_file',
 
2238
                (b'memory:///',))],
2186
2239
            client._calls)
2187
2240
 
2188
2241
    def test_set_option_uses_vfs(self):
2200
2253
        self.disable_verb(verb)
2201
2254
        self.reset_smart_call_log()
2202
2255
        self.assertEqual(None,
2203
 
            bzrdir._get_config().get_option('default_stack_on'))
 
2256
                         bzrdir._get_config().get_option('default_stack_on'))
2204
2257
        self.assertLength(4, self.hpss_calls)
2205
2258
 
2206
2259
 
2247
2300
 
2248
2301
    def test_permissiondenied(self):
2249
2302
        client = FakeClient()
2250
 
        client.add_error_response(b'PermissionDenied', b'remote path', b'extra')
 
2303
        client.add_error_response(
 
2304
            b'PermissionDenied', b'remote path', b'extra')
2251
2305
        transport = RemoteTransport('bzr://example.com/', medium=False,
2252
2306
                                    _client=client)
2253
2307
        exc = self.assertRaises(
2266
2320
        conf = config.AuthenticationConfig()
2267
2321
        conf._get_config().update(
2268
2322
            {'bzr+sshtest': {'scheme': 'ssh', 'user': 'bar', 'host':
2269
 
            'example.com'}})
 
2323
                             'example.com'}})
2270
2324
        conf._save()
2271
2325
        t = RemoteSSHTransport('bzr+ssh://example.com')
2272
2326
        self.assertEqual('bar', t._get_credentials()[0])
2295
2349
        transport = transport.clone(transport_path)
2296
2350
        # we do not want bzrdir to make any remote calls
2297
2351
        bzrdir = RemoteBzrDir(transport, RemoteBzrDirFormat(),
2298
 
            _client=False)
 
2352
                              _client=False)
2299
2353
        repo = RemoteRepository(bzrdir, None, _client=client)
2300
2354
        return repo, client
2301
2355
 
2311
2365
        real_format = branch.format_registry.get_default()
2312
2366
        remote_format._network_name = real_format.network_name()
2313
2367
        self.assertEqual(remoted_description(real_format),
2314
 
            remote_format.get_format_description())
 
2368
                         remote_format.get_format_description())
2315
2369
 
2316
2370
 
2317
2371
class TestRepositoryFormat(TestRemoteRepository):
2331
2385
        real_format = repository.format_registry.get_default()
2332
2386
        remote_repo_format._network_name = real_format.network_name()
2333
2387
        self.assertEqual(remoted_description(real_format),
2334
 
            remote_repo_format.get_format_description())
 
2388
                         remote_repo_format.get_format_description())
2335
2389
 
2336
2390
 
2337
2391
class TestRepositoryAllRevisionIds(TestRemoteRepository):
2343
2397
        self.assertEqual([], repo.all_revision_ids())
2344
2398
        self.assertEqual(
2345
2399
            [('call_expecting_body', b'Repository.all_revision_ids',
2346
 
             (b'quack/',))],
 
2400
              (b'quack/',))],
2347
2401
            client._calls)
2348
2402
 
2349
2403
    def test_with_some_content(self):
2356
2410
            set(repo.all_revision_ids()))
2357
2411
        self.assertEqual(
2358
2412
            [('call_expecting_body', b'Repository.all_revision_ids',
2359
 
             (b'quack/',))],
 
2413
              (b'quack/',))],
2360
2414
            client._calls)
2361
2415
 
2362
2416
 
2371
2425
        result = repo.gather_stats(None)
2372
2426
        self.assertEqual(
2373
2427
            [('call_expecting_body', b'Repository.gather_stats',
2374
 
             (b'quack/', b'', b'no'))],
 
2428
              (b'quack/', b'', b'no'))],
2375
2429
            client._calls)
2376
2430
        self.assertEqual({'revisions': 2, 'size': 18}, result)
2377
2431
 
2392
2446
            client._calls)
2393
2447
        self.assertEqual({'revisions': 2, 'size': 18,
2394
2448
                          'firstrev': (123456.300, 3600),
2395
 
                          'latestrev': (654231.400, 0),},
 
2449
                          'latestrev': (654231.400, 0), },
2396
2450
                         result)
2397
2451
 
2398
2452
    def test_revid_with_committers(self):
2414
2468
        self.assertEqual({'revisions': 2, 'size': 18,
2415
2469
                          'committers': 128,
2416
2470
                          'firstrev': (123456.300, 3600),
2417
 
                          'latestrev': (654231.400, 0),},
 
2471
                          'latestrev': (654231.400, 0), },
2418
2472
                         result)
2419
2473
 
2420
2474
 
2475
2529
        self.assertEqual(b"THETEXT", repo.get_signature_text(b"revid"))
2476
2530
        self.assertEqual(
2477
2531
            [('call_expecting_body', b'Repository.get_revision_signature_text',
2478
 
             (b'quack/', b'revid'))],
 
2532
              (b'quack/', b'revid'))],
2479
2533
            client._calls)
2480
2534
 
2481
2535
    def test_no_signature(self):
2483
2537
        repo, client = self.setup_fake_client_and_repository(transport_path)
2484
2538
        client.add_error_response(b'nosuchrevision', b'unknown')
2485
2539
        self.assertRaises(errors.NoSuchRevision, repo.get_signature_text,
2486
 
                b"unknown")
 
2540
                          b"unknown")
2487
2541
        self.assertEqual(
2488
2542
            [('call_expecting_body', b'Repository.get_revision_signature_text',
2489
2543
              (b'quick/', b'unknown'))],
2513
2567
            b'success', (b'ok', (b'token1', )))
2514
2568
        client.add_expected_call(
2515
2569
            b'Repository.add_signature_text', (b'quack/', b'a token', b'rev1',
2516
 
                b'token1'),
 
2570
                                               b'token1'),
2517
2571
            b'success', (b'ok', ), None)
2518
2572
        repo.lock_write()
2519
2573
        repo.start_write_group()
2520
 
        self.assertIs(None,
2521
 
            repo.add_signature_text(b"rev1", b"every bloody emperor"))
 
2574
        self.assertIs(
 
2575
            None, repo.add_signature_text(b"rev1", b"every bloody emperor"))
2522
2576
        self.assertEqual(
2523
2577
            ('call_with_body_bytes_expecting_body',
2524
 
              b'Repository.add_signature_text',
 
2578
             b'Repository.add_signature_text',
2525
2579
                (b'quack/', b'a token', b'rev1', b'token1'),
2526
 
              b'every bloody emperor'),
 
2580
             b'every bloody emperor'),
2527
2581
            client._calls[-1])
2528
2582
 
2529
2583
 
2552
2606
        self.assertEqual({r1: (NULL_REVISION,)}, parents)
2553
2607
        self.assertEqual(
2554
2608
            [('call_with_body_bytes_expecting_body',
2555
 
              b'Repository.get_parent_map', (b'quack/', b'include-missing:', r2),
 
2609
              b'Repository.get_parent_map', (b'quack/',
 
2610
                                             b'include-missing:', r2),
2556
2611
              b'\n\n0')],
2557
2612
            client._calls)
2558
2613
        repo.unlock()
2563
2618
        self.assertEqual({r1: (NULL_REVISION,)}, parents)
2564
2619
        self.assertEqual(
2565
2620
            [('call_with_body_bytes_expecting_body',
2566
 
              b'Repository.get_parent_map', (b'quack/', b'include-missing:', r2),
 
2621
              b'Repository.get_parent_map', (b'quack/',
 
2622
                                             b'include-missing:', r2),
2567
2623
              b'\n\n0'),
2568
2624
             ('call_with_body_bytes_expecting_body',
2569
 
              b'Repository.get_parent_map', (b'quack/', b'include-missing:', r1),
 
2625
              b'Repository.get_parent_map', (b'quack/',
 
2626
                                             b'include-missing:', r1),
2570
2627
              b'\n\n0'),
2571
 
            ],
 
2628
             ],
2572
2629
            client._calls)
2573
2630
        repo.unlock()
2574
2631
 
2611
2668
        parents = repo.get_parent_map([rev_id])
2612
2669
        self.assertEqual(
2613
2670
            [('call_expecting_body', b'Repository.get_revision_graph',
2614
 
             (b'quack/', b''))],
 
2671
              (b'quack/', b''))],
2615
2672
            client._calls)
2616
2673
        self.assertEqual({rev_id: (b'null:',)}, parents)
2617
2674
 
2630
2687
        self.addCleanup(repo.unlock)
2631
2688
        self.reset_smart_call_log()
2632
2689
        graph = repo.get_graph()
2633
 
        self.assertEqual({},
2634
 
            graph.get_parent_map([b'some-missing', b'other-missing']))
 
2690
        self.assertEqual(
 
2691
            {}, graph.get_parent_map([b'some-missing', b'other-missing']))
2635
2692
        self.assertLength(1, self.hpss_calls)
2636
2693
        # No call if we repeat this
2637
2694
        self.reset_smart_call_log()
2638
2695
        graph = repo.get_graph()
2639
 
        self.assertEqual({},
2640
 
            graph.get_parent_map([b'some-missing', b'other-missing']))
 
2696
        self.assertEqual(
 
2697
            {}, graph.get_parent_map([b'some-missing', b'other-missing']))
2641
2698
        self.assertLength(0, self.hpss_calls)
2642
2699
        # Asking for more unknown keys makes a request.
2643
2700
        self.reset_smart_call_log()
2644
2701
        graph = repo.get_graph()
2645
 
        self.assertEqual({},
2646
 
            graph.get_parent_map([b'some-missing', b'other-missing',
2647
 
                b'more-missing']))
 
2702
        self.assertEqual(
 
2703
            {}, graph.get_parent_map([b'some-missing', b'other-missing',
 
2704
                                     b'more-missing']))
2648
2705
        self.assertLength(1, self.hpss_calls)
2649
2706
 
2650
2707
    def disableExtraResults(self):
2671
2728
        graph = repo.get_graph()
2672
2729
        # Query for b'first' and b'null:'.  Because b'null:' is a parent of
2673
2730
        # 'first' it will be a candidate for the stop_keys of subsequent
2674
 
        # requests, and because b'null:' was queried but not returned it will be
2675
 
        # cached as missing.
 
2731
        # requests, and because b'null:' was queried but not returned it will
 
2732
        # be cached as missing.
2676
2733
        self.assertEqual({b'first': (b'null:',)},
2677
 
            graph.get_parent_map([b'first', b'null:']))
 
2734
                         graph.get_parent_map([b'first', b'null:']))
2678
2735
        # Now query for another key.  This request will pass along a recipe of
2679
2736
        # start and stop keys describing the already cached results, and this
2680
2737
        # recipe's revision count must be correct (or else it will trigger an
2694
2751
            builder.start_tree(tree)
2695
2752
            builder.build([])
2696
2753
            builder.finish_tree()
2697
 
            tree.set_parent_ids([b'non-existant'], allow_leftmost_as_ghost=True)
 
2754
            tree.set_parent_ids([b'non-existant'],
 
2755
                                allow_leftmost_as_ghost=True)
2698
2756
            rev_id = tree.commit('')
2699
2757
        tree.lock_read()
2700
2758
        self.addCleanup(tree.unlock)
2725
2783
        self.assertEqual([], client._calls)
2726
2784
        self.assertEqual({r2: (r1,)}, repo.get_parent_map([r2]))
2727
2785
        self.assertEqual({r1: (NULL_REVISION,)},
2728
 
            repo.get_cached_parent_map([r1]))
 
2786
                         repo.get_cached_parent_map([r1]))
2729
2787
        self.assertEqual(
2730
2788
            [('call_with_body_bytes_expecting_body',
2731
 
              b'Repository.get_parent_map', (b'quack/', b'include-missing:', r2),
 
2789
              b'Repository.get_parent_map', (b'quack/',
 
2790
                                             b'include-missing:', r2),
2732
2791
              b'\n\n0')],
2733
2792
            client._calls)
2734
2793
        repo.unlock()
2750
2809
        self.assertEqual({}, graph.get_parent_map([b'rev1']))
2751
2810
        tree.commit('message', rev_id=b'rev1')
2752
2811
        graph = tree.branch.repository.get_graph()
2753
 
        self.assertEqual({b'rev1': (b'null:',)}, graph.get_parent_map([b'rev1']))
 
2812
        self.assertEqual({b'rev1': (b'null:',)},
 
2813
                         graph.get_parent_map([b'rev1']))
2754
2814
 
2755
2815
 
2756
2816
class TestRepositoryGetRevisions(TestRemoteRepository):
2761
2821
        client.add_success_response_with_body(
2762
2822
            b'', b'ok', b'10')
2763
2823
        self.assertRaises(errors.NoSuchRevision, repo.get_revisions,
2764
 
            [b'somerev1', b'anotherrev2'])
 
2824
                          [b'somerev1', b'anotherrev2'])
2765
2825
        self.assertEqual(
2766
 
            [('call_with_body_bytes_expecting_body', b'Repository.iter_revisions',
2767
 
             (b'quack/', ), b"somerev1\nanotherrev2")],
 
2826
            [('call_with_body_bytes_expecting_body',
 
2827
              b'Repository.iter_revisions', (b'quack/', ),
 
2828
              b"somerev1\nanotherrev2")],
2768
2829
            client._calls)
2769
2830
 
2770
2831
    def test_hpss_get_single_revision(self):
2781
2842
        # Split up body into two bits to make sure the zlib compression object
2782
2843
        # gets data fed twice.
2783
2844
        client.add_success_response_with_body(
2784
 
                [body[:10], body[10:]], b'ok', b'10')
 
2845
            [body[:10], body[10:]], b'ok', b'10')
2785
2846
        revs = repo.get_revisions([b'somerev1'])
2786
2847
        self.assertEqual(revs, [somerev1])
2787
2848
        self.assertEqual(
2788
 
            [('call_with_body_bytes_expecting_body', b'Repository.iter_revisions',
2789
 
             (b'quack/', ), b"somerev1")],
 
2849
            [('call_with_body_bytes_expecting_body',
 
2850
              b'Repository.iter_revisions',
 
2851
              (b'quack/', ), b"somerev1")],
2790
2852
            client._calls)
2791
2853
 
2792
2854
 
2819
2881
        result = repo._get_revision_graph(None)
2820
2882
        self.assertEqual(
2821
2883
            [('call_expecting_body', b'Repository.get_revision_graph',
2822
 
             (b'sinhala/', b''))],
 
2884
              (b'sinhala/', b''))],
2823
2885
            client._calls)
2824
2886
        self.assertEqual({r1: (), r2: (r1, )}, result)
2825
2887
 
2838
2900
        result = repo._get_revision_graph(r2)
2839
2901
        self.assertEqual(
2840
2902
            [('call_expecting_body', b'Repository.get_revision_graph',
2841
 
             (b'sinhala/', r2))],
 
2903
              (b'sinhala/', r2))],
2842
2904
            client._calls)
2843
2905
        self.assertEqual({r11: (), r12: (), r2: (r11, r12), }, result)
2844
2906
 
2849
2911
        client.add_error_response(b'nosuchrevision', revid)
2850
2912
        # also check that the right revision is reported in the error
2851
2913
        self.assertRaises(errors.NoSuchRevision,
2852
 
            repo._get_revision_graph, revid)
 
2914
                          repo._get_revision_graph, revid)
2853
2915
        self.assertEqual(
2854
2916
            [('call_expecting_body', b'Repository.get_revision_graph',
2855
 
             (b'sinhala/', revid))],
 
2917
              (b'sinhala/', revid))],
2856
2918
            client._calls)
2857
2919
 
2858
2920
    def test_unexpected_error(self):
2861
2923
        repo, client = self.setup_fake_client_and_repository(transport_path)
2862
2924
        client.add_error_response(b'AnUnexpectedError')
2863
2925
        e = self.assertRaises(errors.UnknownErrorFromSmartServer,
2864
 
            repo._get_revision_graph, revid)
 
2926
                              repo._get_revision_graph, revid)
2865
2927
        self.assertEqual((b'AnUnexpectedError',), e.error_tuple)
2866
2928
 
2867
2929
 
2870
2932
    def test_ok(self):
2871
2933
        repo, client = self.setup_fake_client_and_repository('quack')
2872
2934
        client.add_expected_call(
2873
 
            b'Repository.get_rev_id_for_revno', (b'quack/', 5, (42, b'rev-foo')),
 
2935
            b'Repository.get_rev_id_for_revno', (b'quack/',
 
2936
                                                 5, (42, b'rev-foo')),
2874
2937
            b'success', (b'ok', b'rev-five'))
2875
2938
        result = repo.get_rev_id_for_revno(5, (42, b'rev-foo'))
2876
2939
        self.assertEqual((True, b'rev-five'), result)
2879
2942
    def test_history_incomplete(self):
2880
2943
        repo, client = self.setup_fake_client_and_repository('quack')
2881
2944
        client.add_expected_call(
2882
 
            b'Repository.get_rev_id_for_revno', (b'quack/', 5, (42, b'rev-foo')),
 
2945
            b'Repository.get_rev_id_for_revno', (b'quack/',
 
2946
                                                 5, (42, b'rev-foo')),
2883
2947
            b'success', (b'history-incomplete', 10, b'rev-ten'))
2884
2948
        result = repo.get_rev_id_for_revno(5, (42, b'rev-foo'))
2885
2949
        self.assertEqual((False, (10, b'rev-ten')), result)
2901
2965
        repo.add_fallback_repository(fallback_repo)
2902
2966
        # First the client should ask the primary repo
2903
2967
        client.add_expected_call(
2904
 
            b'Repository.get_rev_id_for_revno', (b'quack/', 1, (42, b'rev-foo')),
 
2968
            b'Repository.get_rev_id_for_revno', (b'quack/',
 
2969
                                                 1, (42, b'rev-foo')),
2905
2970
            b'success', (b'history-incomplete', 2, b'rev-two'))
2906
2971
        # Then it should ask the fallback, using revno/revid from the
2907
2972
        # history-incomplete response as the known revno/revid.
2908
2973
        client.add_expected_call(
2909
 
            b'Repository.get_rev_id_for_revno', (b'fallback/', 1, (2, b'rev-two')),
 
2974
            b'Repository.get_rev_id_for_revno', (
 
2975
                b'fallback/', 1, (2, b'rev-two')),
2910
2976
            b'success', (b'ok', b'rev-one'))
2911
2977
        result = repo.get_rev_id_for_revno(1, (42, b'rev-foo'))
2912
2978
        self.assertEqual((True, b'rev-one'), result)
2917
2983
        # remote repo.  The client translates that response to NoSuchRevision.
2918
2984
        repo, client = self.setup_fake_client_and_repository('quack')
2919
2985
        client.add_expected_call(
2920
 
            b'Repository.get_rev_id_for_revno', (b'quack/', 5, (42, b'rev-foo')),
 
2986
            b'Repository.get_rev_id_for_revno', (b'quack/',
 
2987
                                                 5, (42, b'rev-foo')),
2921
2988
            b'error', (b'nosuchrevision', b'rev-foo'))
2922
2989
        self.assertRaises(
2923
2990
            errors.NoSuchRevision,
2934
3001
        tree.lock_write()
2935
3002
        tree.add('')
2936
3003
        rev1 = tree.commit('First')
2937
 
        rev2 = tree.commit('Second')
 
3004
        tree.commit('Second')
2938
3005
        tree.unlock()
2939
3006
        branch = tree.branch
2940
3007
        self.assertFalse(branch.is_locked())
3098
3165
        # groups. For those, fall back to the "real" repository.
3099
3166
        transport_path = 'quack'
3100
3167
        repo, client = self.setup_fake_client_and_repository(transport_path)
 
3168
 
3101
3169
        def stub_ensure_real():
3102
3170
            client._calls.append(('_ensure_real',))
3103
3171
            repo._real_repository = _StubRealPackRepository(client._calls)
3124
3192
            b'Repository.start_write_group', (b'quack/', b'a token'),
3125
3193
            b'success', (b'ok', [b'token1']))
3126
3194
        client.add_expected_call(
3127
 
            b'Repository.commit_write_group', (b'quack/', b'a token', [b'token1']),
 
3195
            b'Repository.commit_write_group', (b'quack/',
 
3196
                                               b'a token', [b'token1']),
3128
3197
            b'success', (b'ok',))
3129
3198
        repo.lock_write()
3130
3199
        repo.start_write_group()
3140
3209
            b'Repository.start_write_group', (b'quack/', b'a token'),
3141
3210
            b'success', (b'ok', [b'token1']))
3142
3211
        client.add_expected_call(
3143
 
            b'Repository.abort_write_group', (b'quack/', b'a token', [b'token1']),
 
3212
            b'Repository.abort_write_group', (b'quack/',
 
3213
                                              b'a token', [b'token1']),
3144
3214
            b'success', (b'ok',))
3145
3215
        repo.lock_write()
3146
3216
        repo.start_write_group()
3158
3228
            b'Repository.lock_write', (b'quack/', b''),
3159
3229
            b'success', (b'ok', b'a token'))
3160
3230
        client.add_expected_call(
3161
 
            b'Repository.check_write_group', (b'quack/', b'a token', [b'token1']),
 
3231
            b'Repository.check_write_group', (b'quack/',
 
3232
                                              b'a token', [b'token1']),
3162
3233
            b'success', (b'ok',))
3163
3234
        repo.lock_write()
3164
3235
        repo.resume_write_group(['token1'])
3174
3245
        self.disable_verb(verb)
3175
3246
        repo.set_make_working_trees(True)
3176
3247
        call_count = len([call for call in self.hpss_calls if
3177
 
            call.call.method == verb])
 
3248
                          call.call.method == verb])
3178
3249
        self.assertEqual(1, call_count)
3179
3250
 
3180
3251
    def test_current(self):
3238
3309
            b'Repository.iter_files_bytes', (b'quack/', ),
3239
3310
            b'success', (b'ok',), iter([b"ok\x000", b"\n", zlib.compress(b"mydata" * 10)]))
3240
3311
        for (identifier, byte_stream) in repo.iter_files_bytes([(b"somefile",
3241
 
                b"somerev", b"myid")]):
 
3312
                                                                 b"somerev", b"myid")]):
3242
3313
            self.assertEqual(b"myid", identifier)
3243
3314
            self.assertEqual(b"".join(byte_stream), b"mydata" * 10)
3244
3315
 
3247
3318
        repo, client = self.setup_fake_client_and_repository(transport_path)
3248
3319
        client.add_expected_call(
3249
3320
            b'Repository.iter_files_bytes',
3250
 
                (b'quack/', ),
 
3321
            (b'quack/', ),
3251
3322
            b'error', (b'RevisionNotPresent', b'somefile', b'somerev'),
3252
3323
            iter([b"absent\0somefile\0somerev\n"]))
3253
3324
        self.assertRaises(errors.RevisionNotPresent, list,
3254
 
                repo.iter_files_bytes(
3255
 
                [(b"somefile", b"somerev", b"myid")]))
 
3325
                          repo.iter_files_bytes(
 
3326
                              [(b"somefile", b"somerev", b"myid")]))
3256
3327
 
3257
3328
 
3258
3329
class TestRepositoryInsertStreamBase(TestRemoteRepository):
3259
3330
    """Base class for Repository.insert_stream and .insert_stream_1.19
3260
3331
    tests.
3261
3332
    """
3262
 
    
 
3333
 
3263
3334
    def checkInsertEmptyStream(self, repo, client):
3264
3335
        """Insert an empty stream, checking the result.
3265
3336
 
3355
3426
        # Create a fake real repository for insert_stream to fall back on, so
3356
3427
        # that we can directly see the records the RemoteSink passes to the
3357
3428
        # real sink.
 
3429
 
3358
3430
        class FakeRealSink:
3359
3431
            def __init__(self):
3360
3432
                self.records = []
 
3433
 
3361
3434
            def insert_stream(self, stream, src_format, resume_tokens):
3362
3435
                for substream_kind, substream in stream:
3363
3436
                    self.records.append(
3364
3437
                        (substream_kind, [record.key for record in substream]))
3365
3438
                return [b'fake tokens'], [b'fake missing keys']
3366
3439
        fake_real_sink = FakeRealSink()
 
3440
 
3367
3441
        class FakeRealRepository:
3368
3442
            def _get_sink(self):
3369
3443
                return fake_real_sink
 
3444
 
3370
3445
            def is_in_write_group(self):
3371
3446
                return False
 
3447
 
3372
3448
            def refresh_data(self):
3373
3449
                return True
3374
3450
        repo._real_repository = FakeRealRepository()
3401
3477
        # Define a stream using generators so that it isn't rewindable.
3402
3478
        inv = inventory.Inventory(revision_id=b'rev1')
3403
3479
        inv.root.revision = b'rev1'
 
3480
 
3404
3481
        def stream_with_inv_delta():
3405
3482
            yield ('inventories', inventories_substream())
3406
3483
            yield ('inventory-deltas', inventory_delta_substream())
3407
3484
            yield ('texts', [
3408
3485
                versionedfile.FulltextContentFactory(
3409
3486
                    (b'some-rev', b'some-file'), (), None, b'content')])
 
3487
 
3410
3488
        def inventories_substream():
3411
3489
            # An empty inventory fulltext.  This will be streamed normally.
3412
3490
            text = fmt._serializer.write_inventory_to_string(inv)
3413
3491
            yield versionedfile.FulltextContentFactory(
3414
3492
                (b'rev1',), (), None, text)
 
3493
 
3415
3494
        def inventory_delta_substream():
3416
3495
            # An inventory delta.  This can't be streamed via this verb, so it
3417
3496
            # will trigger a fallback to VFS insert_stream.
3498
3577
        transport_path = 'repo'
3499
3578
        expected_calls = [('call_expecting_body', b'Repository.tarball',
3500
3579
                           (b'repo/', b'bz2',),),
3501
 
            ]
 
3580
                          ]
3502
3581
        repo, client = self.setup_fake_client_and_repository(transport_path)
3503
3582
        client.add_success_response_with_body(self.tarball_content, b'ok')
3504
3583
        # Now actually ask for the tarball
3591
3670
        transport_path = 'quack'
3592
3671
        repo, client = self.setup_fake_client_and_repository(transport_path)
3593
3672
        client.add_unknown_method_response(b'PackRepository.autopack')
 
3673
 
3594
3674
        def stub_ensure_real():
3595
3675
            client._calls.append(('_ensure_real',))
3596
3676
            repo._real_repository = _StubRealPackRepository(client._calls)
3693
3773
    def test_norepository(self):
3694
3774
        bzrdir = self.make_controldir('')
3695
3775
        translated_error = self.translateTuple((b'norepository',),
3696
 
            bzrdir=bzrdir)
 
3776
                                               bzrdir=bzrdir)
3697
3777
        expected_error = errors.NoRepositoryPresent(bzrdir)
3698
3778
        self.assertEqual(expected_error, translated_error)
3699
3779
 
3712
3792
    def test_LockFailed(self):
3713
3793
        lock = 'str() of a server lock'
3714
3794
        why = 'str() of why'
3715
 
        translated_error = self.translateTuple((b'LockFailed', lock.encode('ascii'), why.encode('ascii')))
 
3795
        translated_error = self.translateTuple(
 
3796
            (b'LockFailed', lock.encode('ascii'), why.encode('ascii')))
3716
3797
        expected_error = errors.LockFailed(lock, why)
3717
3798
        self.assertEqual(expected_error, translated_error)
3718
3799
 
3719
3800
    def test_TokenMismatch(self):
3720
3801
        token = 'a lock token'
3721
 
        translated_error = self.translateTuple((b'TokenMismatch',), token=token)
 
3802
        translated_error = self.translateTuple(
 
3803
            (b'TokenMismatch',), token=token)
3722
3804
        expected_error = errors.TokenMismatch(token, '(remote token)')
3723
3805
        self.assertEqual(expected_error, translated_error)
3724
3806
 
3744
3826
 
3745
3827
    def test_ReadError(self):
3746
3828
        path = 'a path'
3747
 
        translated_error = self.translateTuple((b'ReadError', path.encode('utf-8')))
 
3829
        translated_error = self.translateTuple(
 
3830
            (b'ReadError', path.encode('utf-8')))
3748
3831
        expected_error = errors.ReadError(path)
3749
3832
        self.assertEqual(expected_error, translated_error)
3750
3833
 
3751
3834
    def test_IncompatibleRepositories(self):
3752
3835
        translated_error = self.translateTuple((b'IncompatibleRepositories',
3753
 
            b"repo1", b"repo2", b"details here"))
 
3836
                                                b"repo1", b"repo2", b"details here"))
3754
3837
        expected_error = errors.IncompatibleRepositories("repo1", "repo2",
3755
 
            "details here")
 
3838
                                                         "details here")
3756
3839
        self.assertEqual(expected_error, translated_error)
3757
3840
 
3758
3841
    def test_GhostRevisionsHaveNoRevno(self):
3759
3842
        translated_error = self.translateTuple((b'GhostRevisionsHaveNoRevno',
3760
 
            b"revid1", b"revid2"))
 
3843
                                                b"revid1", b"revid2"))
3761
3844
        expected_error = errors.GhostRevisionsHaveNoRevno(b"revid1", b"revid2")
3762
3845
        self.assertEqual(expected_error, translated_error)
3763
3846
 
3764
3847
    def test_PermissionDenied_no_args(self):
3765
3848
        path = 'a path'
3766
3849
        translated_error = self.translateTuple((b'PermissionDenied',),
3767
 
            path=path)
 
3850
                                               path=path)
3768
3851
        expected_error = errors.PermissionDenied(path)
3769
3852
        self.assertEqual(expected_error, translated_error)
3770
3853
 
3771
3854
    def test_PermissionDenied_one_arg(self):
3772
3855
        path = 'a path'
3773
 
        translated_error = self.translateTuple((b'PermissionDenied', path.encode('utf-8')))
 
3856
        translated_error = self.translateTuple(
 
3857
            (b'PermissionDenied', path.encode('utf-8')))
3774
3858
        expected_error = errors.PermissionDenied(path)
3775
3859
        self.assertEqual(expected_error, translated_error)
3776
3860
 
3798
3882
    def test_NoSuchFile_context_path(self):
3799
3883
        local_path = "local path"
3800
3884
        translated_error = self.translateTuple((b'ReadError', b"remote path"),
3801
 
            path=local_path)
 
3885
                                               path=local_path)
3802
3886
        expected_error = errors.ReadError(local_path)
3803
3887
        self.assertEqual(expected_error, translated_error)
3804
3888
 
3805
3889
    def test_NoSuchFile_without_context(self):
3806
3890
        remote_path = "remote path"
3807
 
        translated_error = self.translateTuple((b'ReadError', remote_path.encode('utf-8')))
 
3891
        translated_error = self.translateTuple(
 
3892
            (b'ReadError', remote_path.encode('utf-8')))
3808
3893
        expected_error = errors.ReadError(remote_path)
3809
3894
        self.assertEqual(expected_error, translated_error)
3810
3895
 
3816
3901
    def test_MemoryError(self):
3817
3902
        translated_error = self.translateTuple((b'MemoryError',))
3818
3903
        self.assertStartsWith(str(translated_error),
3819
 
            "remote server out of memory")
 
3904
                              "remote server out of memory")
3820
3905
 
3821
3906
    def test_generic_IndexError_no_classname(self):
3822
 
        err = errors.ErrorFromSmartServer((b'error', b"list index out of range"))
 
3907
        err = errors.ErrorFromSmartServer(
 
3908
            (b'error', b"list index out of range"))
3823
3909
        translated_error = self.translateErrorFromSmartServer(err)
3824
3910
        expected_error = errors.UnknownErrorFromSmartServer(err)
3825
3911
        self.assertEqual(expected_error, translated_error)
3859
3945
        # To translate a NoSuchRevision error _translate_error needs a 'branch'
3860
3946
        # in the context dict.  So let's give it an empty context dict instead
3861
3947
        # to exercise its error recovery.
3862
 
        empty_context = {}
3863
3948
        error_tuple = (b'NoSuchRevision', b'revid')
3864
3949
        server_error = errors.ErrorFromSmartServer(error_tuple)
3865
3950
        translated_error = self.translateErrorFromSmartServer(server_error)
3895
3980
        # make a branch stacked on another repository containing an empty
3896
3981
        # revision, then open it over hpss - we should be able to see that
3897
3982
        # revision.
3898
 
        base_transport = self.get_transport()
3899
3983
        base_builder = self.make_branch_builder('base', format='1.9')
3900
3984
        base_builder.start_series()
3901
3985
        base_revid = base_builder.build_snapshot(None,
3902
 
            [('add', ('', None, 'directory', None))],
3903
 
            'message', revision_id=b'rev-id')
 
3986
                                                 [('add', ('', None, 'directory', None))],
 
3987
                                                 'message', revision_id=b'rev-id')
3904
3988
        base_builder.finish_series()
3905
3989
        stacked_branch = self.make_branch('stacked', format='1.9')
3906
3990
        stacked_branch.set_stacked_on_url('../base')
3917
4001
            # be a RemoteRepository
3918
4002
            self.assertLength(1, remote_repo._fallback_repositories)
3919
4003
            self.assertIsInstance(remote_repo._fallback_repositories[0],
3920
 
                RemoteRepository)
 
4004
                                  RemoteRepository)
3921
4005
            # and it has the revision committed to the underlying repository;
3922
4006
            # these have varying implementations so we try several of them
3923
4007
            self.assertTrue(remote_repo.has_revisions([base_revid]))
3924
4008
            self.assertTrue(remote_repo.has_revision(base_revid))
3925
4009
            self.assertEqual(remote_repo.get_revision(base_revid).message,
3926
 
                'message')
 
4010
                             'message')
3927
4011
        finally:
3928
4012
            remote_repo.unlock()
3929
4013
 
3933
4017
        tree1 = self.make_branch_and_tree('tree1', format='1.9')
3934
4018
        tree1.commit('rev1', rev_id=b'rev1')
3935
4019
        tree2 = tree1.branch.controldir.sprout('tree2', stacked=True
3936
 
            ).open_workingtree()
 
4020
                                               ).open_workingtree()
3937
4021
        local_tree = tree2.branch.create_checkout('local')
3938
4022
        local_tree.commit('local changes make me feel good.')
3939
4023
        branch2 = Branch.open(self.get_url('tree2'))
4012
4096
        def make_stacked_stacked():
4013
4097
            _, stacked = self.prepare_stacked_remote_branch()
4014
4098
            tree = stacked.controldir.sprout('tree3', stacked=True
4015
 
                ).open_workingtree()
 
4099
                                             ).open_workingtree()
4016
4100
            local_tree = tree.branch.create_checkout('local-tree3')
4017
4101
            local_tree.commit('more local changes are better')
4018
4102
            branch = Branch.open(self.get_url('tree3'))
4019
4103
            branch.lock_read()
4020
4104
            self.addCleanup(branch.unlock)
4021
4105
            return None, branch
4022
 
        rev_ord, expected_revs = self.get_ordered_revs('1.9', 'unordered',
4023
 
            branch_factory=make_stacked_stacked)
 
4106
        rev_ord, expected_revs = self.get_ordered_revs(
 
4107
            '1.9', 'unordered', branch_factory=make_stacked_stacked)
4024
4108
        self.assertEqual(set(expected_revs), set(rev_ord))
4025
4109
        # Getting unordered results should have made a streaming data request
4026
4110
        # from the server, and one from each backing repo
4055
4139
        # branch pulling content from stacked and trunk.
4056
4140
        self.setup_smart_server_with_call_log()
4057
4141
        trunk = self.make_branch_and_tree('trunk', format="1.9-rich-root")
4058
 
        r1 = trunk.commit('start')
 
4142
        trunk.commit('start')
4059
4143
        stacked_branch = trunk.branch.create_clone_on_transport(
4060
4144
            self.get_transport('stacked'), stacked_on=trunk.branch.base)
4061
4145
        local = self.make_branch('local', format='1.9-rich-root')
4062
4146
        local.repository.fetch(stacked_branch.repository,
4063
 
            stacked_branch.last_revision())
 
4147
                               stacked_branch.last_revision())
4064
4148
 
4065
4149
 
4066
4150
class TestRemoteBranchEffort(tests.TestCaseWithTransport):
4108
4192
        orig_info = request_handlers.get_info(verb_name)
4109
4193
        request_handlers.register(verb_name, verb, override_existing=True)
4110
4194
        self.addCleanup(request_handlers.register, verb_name, orig_verb,
4111
 
                override_existing=True, info=orig_info)
 
4195
                        override_existing=True, info=orig_info)
4112
4196
 
4113
4197
    def test_fetch_everything_backwards_compat(self):
4114
4198
        """Can fetch with EverythingResult even with pre 2.4 servers.
4115
 
        
 
4199
 
4116
4200
        Pre-2.4 do not support 'everything' searches with the
4117
4201
        Repository.get_stream_1.19 verb.
4118
4202
        """
4119
4203
        verb_log = []
 
4204
 
4120
4205
        class OldGetStreamVerb(SmartServerRepositoryGetStream_1_19):
4121
4206
            """A version of the Repository.get_stream_1.19 verb patched to
4122
4207
            reject 'everything' searches the way 2.3 and earlier do.
4123
4208
            """
 
4209
 
4124
4210
            def recreate_search(self, repository, search_bytes,
4125
4211
                                discard_excess=False):
4126
4212
                verb_log.append(search_bytes.split(b'\n', 1)[0])
4128
4214
                    return (None,
4129
4215
                            request.FailedSmartServerResponse((b'BadSearch',)))
4130
4216
                return super(OldGetStreamVerb,
4131
 
                        self).recreate_search(repository, search_bytes,
4132
 
                            discard_excess=discard_excess)
 
4217
                             self).recreate_search(repository, search_bytes,
 
4218
                                                   discard_excess=discard_excess)
4133
4219
        self.override_verb(b'Repository.get_stream_1.19', OldGetStreamVerb)
4134
4220
        local = self.make_branch('local')
4135
4221
        builder = self.make_branch_builder('remote')
4148
4234
 
4149
4235
 
4150
4236
class TestUpdateBoundBranchWithModifiedBoundLocation(
4151
 
    tests.TestCaseWithTransport):
 
4237
        tests.TestCaseWithTransport):
4152
4238
    """Ensure correct handling of bound_location modifications.
4153
4239
 
4154
4240
    This is tested against a smart server as http://pad.lv/786980 was about a
4201
4287
            def __init__(self, urgency):
4202
4288
                self.urgency = urgency
4203
4289
        remote.no_context_error_translators.register(b"OutOfCoffee",
4204
 
            lambda err: OutOfCoffee(err.error_args[0]))
 
4290
                                                     lambda err: OutOfCoffee(err.error_args[0]))
4205
4291
        transport = MemoryTransport()
4206
4292
        client = FakeClient(transport.base)
4207
4293
        client.add_expected_call(
4223
4309
                self.branch = branch
4224
4310
                self.urgency = urgency
4225
4311
        remote.error_translators.register(b"OutOfTea",
4226
 
            lambda err, find, path: OutOfTea(
4227
 
                err.error_args[0].decode('utf-8'),
4228
 
                find("branch")))
 
4312
                                          lambda err, find, path: OutOfTea(
 
4313
                                              err.error_args[0].decode(
 
4314
                                                  'utf-8'),
 
4315
                                              find("branch")))
4229
4316
        transport = MemoryTransport()
4230
4317
        client = FakeClient(transport.base)
4231
4318
        client.add_expected_call(
4287
4374
        repo._format = fmt
4288
4375
        stream = [('inventory-deltas', [
4289
4376
            versionedfile.FulltextContentFactory(b'somerevid', None, None,
4290
 
                self._serialize_inv_delta(b'null:', b'somerevid', []))])]
 
4377
                                                 self._serialize_inv_delta(b'null:', b'somerevid', []))])]
4291
4378
        client.add_expected_call(
4292
 
            b'VersionedFileRepository.get_inventories', (b'quack/', b'unordered'),
 
4379
            b'VersionedFileRepository.get_inventories', (
 
4380
                b'quack/', b'unordered'),
4293
4381
            b'success', (b'ok', ),
4294
4382
            _stream_to_byte_stream(stream, fmt))
4295
4383
        ret = list(repo.iter_inventories([b"somerevid"]))
4307
4395
        transport_path = 'quack'
4308
4396
        repo, client = self.setup_fake_client_and_repository(transport_path)
4309
4397
        client.add_expected_call(
4310
 
            b'VersionedFileRepository.get_inventories', (b'quack/', b'unordered'),
 
4398
            b'VersionedFileRepository.get_inventories', (
 
4399
                b'quack/', b'unordered'),
4311
4400
            b'success', (b'ok', ), iter([]))
4312
4401
        self.assertRaises(errors.NoSuchRevision, list, repo.iter_inventories(
4313
4402
            [b"somerevid"]))
4327
4416
        repo._format = fmt
4328
4417
        stream = [('inventory-deltas', [
4329
4418
            versionedfile.FulltextContentFactory(b'somerevid', None, None,
4330
 
                self._serialize_inv_delta(b'null:', b'somerevid', []))])]
 
4419
                                                 self._serialize_inv_delta(b'null:', b'somerevid', []))])]
4331
4420
        client.add_expected_call(
4332
 
            b'VersionedFileRepository.get_inventories', (b'quack/', b'unordered'),
 
4421
            b'VersionedFileRepository.get_inventories', (
 
4422
                b'quack/', b'unordered'),
4333
4423
            b'success', (b'ok', ),
4334
4424
            _stream_to_byte_stream(stream, fmt))
4335
4425
        f = BytesIO()
4342
4432
            info.size = len(contents)
4343
4433
            tf.addfile(info, BytesIO(contents))
4344
4434
        client.add_expected_call(
4345
 
            b'Repository.revision_archive', (b'quack/', b'somerevid', b'tar', b'foo.tar', b'', b'', None),
 
4435
            b'Repository.revision_archive', (b'quack/',
 
4436
                                             b'somerevid', b'tar', b'foo.tar', b'', b'', None),
4346
4437
            b'success', (b'ok', ),
4347
4438
            f.getvalue())
4348
4439
        tree = repo.revision_tree(b'somerevid')
4349
 
        self.assertEqual(f.getvalue(), b''.join(tree.archive('tar', 'foo.tar')))
 
4440
        self.assertEqual(f.getvalue(), b''.join(
 
4441
            tree.archive('tar', 'foo.tar')))
4350
4442
 
4351
4443
 
4352
4444
class TestRepositoryAnnotate(TestRemoteRepository):
4361
4453
        repo, client = self.setup_fake_client_and_repository(transport_path)
4362
4454
        fmt = controldir.format_registry.get('2a')().repository_format
4363
4455
        repo._format = fmt
4364
 
        stream = [('inventory-deltas', [
4365
 
            versionedfile.FulltextContentFactory(b'somerevid', None, None,
4366
 
                self._serialize_inv_delta(b'null:', b'somerevid', []))])]
 
4456
        stream = [
 
4457
            ('inventory-deltas', [
 
4458
                versionedfile.FulltextContentFactory(
 
4459
                    b'somerevid', None, None,
 
4460
                    self._serialize_inv_delta(b'null:', b'somerevid', []))])]
4367
4461
        client.add_expected_call(
4368
 
            b'VersionedFileRepository.get_inventories', (b'quack/', b'unordered'),
 
4462
            b'VersionedFileRepository.get_inventories', (
 
4463
                b'quack/', b'unordered'),
4369
4464
            b'success', (b'ok', ),
4370
4465
            _stream_to_byte_stream(stream, fmt))
4371
4466
        client.add_expected_call(