~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_smart.py

  • Committer: John Arbash Meinel
  • Date: 2007-07-05 19:39:28 UTC
  • mto: This revision was merged to the branch mainline in revision 2614.
  • Revision ID: john@arbash-meinel.com-20070705193928-xtm8nh4ucc8qosdn
Add direct tests of how we handle incomplete/'broken' lines

Show diffs side-by-side

added added

removed removed

Lines of Context:
14
14
# along with this program; if not, write to the Free Software
15
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
16
 
17
 
"""Tests for the smart wire/domain protocol.
18
 
 
19
 
This module contains tests for the domain-level smart requests and responses,
20
 
such as the 'Branch.lock_write' request. Many of these use specific disk
21
 
formats to exercise calls that only make sense for formats with specific
22
 
properties.
23
 
 
24
 
Tests for low-level protocol encoding are found in test_smart_transport.
25
 
"""
 
17
"""Tests for the smart wire/domain protococl."""
26
18
 
27
19
from StringIO import StringIO
28
20
import tempfile
29
21
import tarfile
30
22
 
31
 
from bzrlib import bzrdir, errors, pack, smart, tests
32
 
from bzrlib.smart.request import (
33
 
    FailedSmartServerResponse,
34
 
    SmartServerResponse,
35
 
    SuccessfulSmartServerResponse,
36
 
    )
 
23
from bzrlib import bzrdir, errors, smart, tests
 
24
from bzrlib.smart.request import SmartServerResponse
37
25
import bzrlib.smart.bzrdir
38
26
import bzrlib.smart.branch
39
27
import bzrlib.smart.repository
40
 
from bzrlib.util import bencode
41
28
 
42
29
 
43
30
class TestCaseWithSmartMedium(tests.TestCaseWithTransport):
384
371
    def test_lock_write_on_unlocked_branch(self):
385
372
        backing = self.get_transport()
386
373
        request = smart.branch.SmartServerBranchRequestLockWrite(backing)
387
 
        branch = self.make_branch('.', format='knit')
 
374
        branch = self.make_branch('.')
388
375
        repository = branch.repository
389
376
        response = request.execute(backing.local_abspath(''))
390
377
        branch_nonce = branch.control_files._lock.peek().get('nonce')
411
398
    def test_lock_write_with_tokens_on_locked_branch(self):
412
399
        backing = self.get_transport()
413
400
        request = smart.branch.SmartServerBranchRequestLockWrite(backing)
414
 
        branch = self.make_branch('.', format='knit')
 
401
        branch = self.make_branch('.')
415
402
        branch_token = branch.lock_write()
416
403
        repo_token = branch.repository.lock_write()
417
404
        branch.repository.unlock()
426
413
    def test_lock_write_with_mismatched_tokens_on_locked_branch(self):
427
414
        backing = self.get_transport()
428
415
        request = smart.branch.SmartServerBranchRequestLockWrite(backing)
429
 
        branch = self.make_branch('.', format='knit')
 
416
        branch = self.make_branch('.')
430
417
        branch_token = branch.lock_write()
431
418
        repo_token = branch.repository.lock_write()
432
419
        branch.repository.unlock()
441
428
    def test_lock_write_on_locked_repo(self):
442
429
        backing = self.get_transport()
443
430
        request = smart.branch.SmartServerBranchRequestLockWrite(backing)
444
 
        branch = self.make_branch('.', format='knit')
 
431
        branch = self.make_branch('.')
445
432
        branch.repository.lock_write()
446
433
        branch.repository.leave_lock_in_place()
447
434
        branch.repository.unlock()
454
441
        request = smart.branch.SmartServerBranchRequestLockWrite(backing)
455
442
        branch = self.make_branch('.')
456
443
        response = request.execute('')
457
 
        error_name, lock_str, why_str = response.args
458
 
        self.assertFalse(response.is_successful())
459
 
        self.assertEqual('LockFailed', error_name)
 
444
        self.assertEqual(
 
445
            SmartServerResponse(('UnlockableTransport',)), response)
460
446
 
461
447
 
462
448
class TestSmartServerBranchRequestUnlock(tests.TestCaseWithTransport):
468
454
    def test_unlock_on_locked_branch_and_repo(self):
469
455
        backing = self.get_transport()
470
456
        request = smart.branch.SmartServerBranchRequestUnlock(backing)
471
 
        branch = self.make_branch('.', format='knit')
 
457
        branch = self.make_branch('.')
472
458
        # Lock the branch
473
459
        branch_token = branch.lock_write()
474
460
        repo_token = branch.repository.lock_write()
491
477
    def test_unlock_on_unlocked_branch_unlocked_repo(self):
492
478
        backing = self.get_transport()
493
479
        request = smart.branch.SmartServerBranchRequestUnlock(backing)
494
 
        branch = self.make_branch('.', format='knit')
 
480
        branch = self.make_branch('.')
495
481
        response = request.execute(
496
482
            backing.local_abspath(''), 'branch token', 'repo token')
497
483
        self.assertEqual(
500
486
    def test_unlock_on_unlocked_branch_locked_repo(self):
501
487
        backing = self.get_transport()
502
488
        request = smart.branch.SmartServerBranchRequestUnlock(backing)
503
 
        branch = self.make_branch('.', format='knit')
 
489
        branch = self.make_branch('.')
504
490
        # Lock the repository.
505
491
        repo_token = branch.repository.lock_write()
506
492
        branch.repository.leave_lock_in_place()
696
682
    def test_lock_write_on_unlocked_repo(self):
697
683
        backing = self.get_transport()
698
684
        request = smart.repository.SmartServerRepositoryLockWrite(backing)
699
 
        repository = self.make_repository('.', format='knit')
 
685
        repository = self.make_repository('.')
700
686
        response = request.execute(backing.local_abspath(''))
701
687
        nonce = repository.control_files._lock.peek().get('nonce')
702
688
        self.assertEqual(SmartServerResponse(('ok', nonce)), response)
708
694
    def test_lock_write_on_locked_repo(self):
709
695
        backing = self.get_transport()
710
696
        request = smart.repository.SmartServerRepositoryLockWrite(backing)
711
 
        repository = self.make_repository('.', format='knit')
 
697
        repository = self.make_repository('.')
712
698
        repository.lock_write()
713
699
        repository.leave_lock_in_place()
714
700
        repository.unlock()
719
705
    def test_lock_write_on_readonly_transport(self):
720
706
        backing = self.get_readonly_transport()
721
707
        request = smart.repository.SmartServerRepositoryLockWrite(backing)
722
 
        repository = self.make_repository('.', format='knit')
 
708
        repository = self.make_repository('.')
723
709
        response = request.execute('')
724
 
        self.assertFalse(response.is_successful())
725
 
        self.assertEqual('LockFailed', response.args[0])
 
710
        self.assertEqual(
 
711
            SmartServerResponse(('UnlockableTransport',)), response)
726
712
 
727
713
 
728
714
class TestSmartServerRepositoryUnlock(tests.TestCaseWithTransport):
734
720
    def test_unlock_on_locked_repo(self):
735
721
        backing = self.get_transport()
736
722
        request = smart.repository.SmartServerRepositoryUnlock(backing)
737
 
        repository = self.make_repository('.', format='knit')
 
723
        repository = self.make_repository('.')
738
724
        token = repository.lock_write()
739
725
        repository.leave_lock_in_place()
740
726
        repository.unlock()
750
736
    def test_unlock_on_unlocked_repo(self):
751
737
        backing = self.get_transport()
752
738
        request = smart.repository.SmartServerRepositoryUnlock(backing)
753
 
        repository = self.make_repository('.', format='knit')
 
739
        repository = self.make_repository('.')
754
740
        response = request.execute(backing.local_abspath(''), 'some token')
755
741
        self.assertEqual(
756
742
            SmartServerResponse(('TokenMismatch',)), response)
780
766
            "extraneous file present in tar file")
781
767
 
782
768
 
783
 
class TestSmartServerRepositoryStreamKnitData(tests.TestCaseWithTransport):
784
 
 
785
 
    def test_fetch_revisions(self):
786
 
        backing = self.get_transport()
787
 
        request = smart.repository.SmartServerRepositoryStreamKnitDataForRevisions(backing)
788
 
        tree = self.make_branch_and_memory_tree('.')
789
 
        tree.lock_write()
790
 
        tree.add('')
791
 
        rev_id1_utf8 = u'\xc8'.encode('utf-8')
792
 
        rev_id2_utf8 = u'\xc9'.encode('utf-8')
793
 
        r1 = tree.commit('1st commit', rev_id=rev_id1_utf8)
794
 
        r1 = tree.commit('2nd commit', rev_id=rev_id2_utf8)
795
 
        tree.unlock()
796
 
 
797
 
        response = request.execute(backing.local_abspath(''), rev_id2_utf8)
798
 
        self.assertEqual(('ok',), response.args)
799
 
        from cStringIO import StringIO
800
 
        unpacker = pack.ContainerReader(StringIO(response.body))
801
 
        names = []
802
 
        for [name], read_bytes in unpacker.iter_records():
803
 
            names.append(name)
804
 
            bytes = read_bytes(None)
805
 
            # The bytes should be a valid bencoded string.
806
 
            bencode.bdecode(bytes)
807
 
            # XXX: assert that the bencoded knit records have the right
808
 
            # contents?
809
 
        
810
 
    def test_no_such_revision_error(self):
811
 
        backing = self.get_transport()
812
 
        request = smart.repository.SmartServerRepositoryStreamKnitDataForRevisions(backing)
813
 
        repo = self.make_repository('.')
814
 
        rev_id1_utf8 = u'\xc8'.encode('utf-8')
815
 
        response = request.execute(backing.local_abspath(''), rev_id1_utf8)
816
 
        self.assertEqual(
817
 
            SmartServerResponse(('NoSuchRevision', rev_id1_utf8)),
818
 
            response)
819
 
 
820
 
 
821
 
class TestSmartServerRepositoryStreamRevisionsChunked(tests.TestCaseWithTransport):
822
 
 
823
 
    def test_fetch_revisions(self):
824
 
        backing = self.get_transport()
825
 
        request = smart.repository.SmartServerRepositoryStreamRevisionsChunked(
826
 
            backing)
827
 
        tree = self.make_branch_and_memory_tree('.')
828
 
        tree.lock_write()
829
 
        tree.add('')
830
 
        rev_id1_utf8 = u'\xc8'.encode('utf-8')
831
 
        rev_id2_utf8 = u'\xc9'.encode('utf-8')
832
 
        r1 = tree.commit('1st commit', rev_id=rev_id1_utf8)
833
 
        r1 = tree.commit('2nd commit', rev_id=rev_id2_utf8)
834
 
        tree.unlock()
835
 
 
836
 
        response = request.execute(backing.local_abspath(''), rev_id2_utf8)
837
 
        self.assertEqual(('ok',), response.args)
838
 
        from cStringIO import StringIO
839
 
        parser = pack.ContainerPushParser()
840
 
        names = []
841
 
        for stream_bytes in response.body_stream:
842
 
            parser.accept_bytes(stream_bytes)
843
 
            for [name], record_bytes in parser.read_pending_records():
844
 
                names.append(name)
845
 
                # The bytes should be a valid bencoded string.
846
 
                bencode.bdecode(record_bytes)
847
 
                # XXX: assert that the bencoded knit records have the right
848
 
                # contents?
849
 
        
850
 
    def test_no_such_revision_error(self):
851
 
        backing = self.get_transport()
852
 
        request = smart.repository.SmartServerRepositoryStreamRevisionsChunked(
853
 
            backing)
854
 
        repo = self.make_repository('.')
855
 
        rev_id1_utf8 = u'\xc8'.encode('utf-8')
856
 
        response = request.execute(backing.local_abspath(''), rev_id1_utf8)
857
 
        # There's no error initially.
858
 
        self.assertTrue(response.is_successful())
859
 
        self.assertEqual(('ok',), response.args)
860
 
        # We only get an error while streaming the body.
861
 
        body = list(response.body_stream)
862
 
        last_chunk = body[-1]
863
 
        self.assertIsInstance(last_chunk, FailedSmartServerResponse)
864
 
        self.assertEqual(
865
 
            last_chunk,
866
 
            FailedSmartServerResponse(('NoSuchRevision', rev_id1_utf8)))
867
 
 
868
 
 
869
769
class TestSmartServerIsReadonly(tests.TestCaseWithTransport):
870
770
 
871
771
    def test_is_readonly_no(self):
919
819
            smart.request.request_handlers.get('Repository.gather_stats'),
920
820
            smart.repository.SmartServerRepositoryGatherStats)
921
821
        self.assertEqual(
922
 
            smart.request.request_handlers.get(
923
 
                'Repository.get_revision_graph'),
 
822
            smart.request.request_handlers.get('Repository.get_revision_graph'),
924
823
            smart.repository.SmartServerRepositoryGetRevisionGraph)
925
824
        self.assertEqual(
926
825
            smart.request.request_handlers.get('Repository.has_revision'),
932
831
            smart.request.request_handlers.get('Repository.lock_write'),
933
832
            smart.repository.SmartServerRepositoryLockWrite)
934
833
        self.assertEqual(
935
 
            smart.request.request_handlers.get(
936
 
                'Repository.chunked_stream_knit_data_for_revisions'),
937
 
            smart.repository.SmartServerRepositoryStreamKnitDataForRevisions)
 
834
            smart.request.request_handlers.get('Repository.unlock'),
 
835
            smart.repository.SmartServerRepositoryUnlock)
938
836
        self.assertEqual(
939
837
            smart.request.request_handlers.get('Repository.tarball'),
940
838
            smart.repository.SmartServerRepositoryTarball)
941
839
        self.assertEqual(
942
 
            smart.request.request_handlers.get('Repository.unlock'),
943
 
            smart.repository.SmartServerRepositoryUnlock)
944
 
        self.assertEqual(
945
840
            smart.request.request_handlers.get('Transport.is_readonly'),
946
841
            smart.request.SmartServerIsReadonly)