~bzr-pqm/bzr/bzr.dev

3990.3.2 by Andrew Bennetts
Fix the do_body NotImplementedError log spam.
1
# Copyright (C) 2009 Canonical Ltd
2
#
3
# This program is free software; you can redistribute it and/or modify
4
# it under the terms of the GNU General Public License as published by
5
# the Free Software Foundation; either version 2 of the License, or
6
# (at your option) any later version.
7
#
8
# This program is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
# GNU General Public License for more details.
12
#
13
# You should have received a copy of the GNU General Public License
14
# along with this program; if not, write to the Free Software
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
17
"""Tests for smart server request infrastructure (bzrlib.smart.request)."""
18
3990.3.3 by Andrew Bennetts
Add a test that unexpected request bodies trigger a SmartProtocolError from request implementations.
19
from bzrlib import errors
3990.3.2 by Andrew Bennetts
Fix the do_body NotImplementedError log spam.
20
from bzrlib.smart import request
21
from bzrlib.tests import TestCase
22
23
3990.3.3 by Andrew Bennetts
Add a test that unexpected request bodies trigger a SmartProtocolError from request implementations.
24
class NoBodyRequest(request.SmartServerRequest):
25
    """A request that does not implement do_body."""
26
27
    def do(self):
28
        return request.SuccessfulSmartServerResponse(('ok',))
29
30
4144.3.1 by Andrew Bennetts
Add Repository.insert_stream_locked server-side implementation, plus tests for server-side _translate_error.
31
class DoErrorRequest(request.SmartServerRequest):
32
    """A request that raises an error from self.do()."""
33
    
34
    def do(self):
35
        raise errors.NoSuchFile('xyzzy')
36
37
38
class ChunkErrorRequest(request.SmartServerRequest):
39
    """A request that raises an error from self.do_chunk()."""
40
    
41
    def do(self):
42
        """No-op."""
43
        pass
44
45
    def do_chunk(self, bytes):
46
        raise errors.NoSuchFile('xyzzy')
47
48
49
class EndErrorRequest(request.SmartServerRequest):
50
    """A request that raises an error from self.do_end()."""
51
    
52
    def do(self):
53
        """No-op."""
54
        pass
55
56
    def do_chunk(self, bytes):
57
        """No-op."""
58
        pass
59
        
60
    def do_end(self):
61
        raise errors.NoSuchFile('xyzzy')
62
63
3990.3.2 by Andrew Bennetts
Fix the do_body NotImplementedError log spam.
64
class TestSmartRequest(TestCase):
65
66
    def test_request_class_without_do_body(self):
67
        """If a request has no body data, and the request's implementation does
68
        not override do_body, then no exception is raised.
69
        """
70
        # Create a SmartServerRequestHandler with a SmartServerRequest subclass
71
        # that does not implement do_body.
72
        handler = request.SmartServerRequestHandler(
73
            None, {'foo': NoBodyRequest}, '/')
74
        # Emulate a request with no body (i.e. just args).
75
        handler.args_received(('foo',))
76
        handler.end_received()
3990.3.3 by Andrew Bennetts
Add a test that unexpected request bodies trigger a SmartProtocolError from request implementations.
77
        # Request done, no exception was raised.
78
4144.3.1 by Andrew Bennetts
Add Repository.insert_stream_locked server-side implementation, plus tests for server-side _translate_error.
79
80
class TestSmartRequestHandlerErrorTranslation(TestCase):
81
    """Tests that SmartServerRequestHandler will translate exceptions raised by
82
    a SmartServerRequest into FailedSmartServerResponses.
83
    """
84
85
    def assertNoResponse(self, handler):
86
        self.assertEqual(None, handler.response)
87
88
    def assertResponseIsTranslatedError(self, handler):
89
        expected_translation = ('NoSuchFile', 'xyzzy')
90
        self.assertEqual(
91
            request.FailedSmartServerResponse(expected_translation),
92
            handler.response)
93
94
    def test_error_translation_from_args_received(self):
95
        handler = request.SmartServerRequestHandler(
96
            None, {'foo': DoErrorRequest}, '/')
97
        handler.args_received(('foo',))
98
        self.assertResponseIsTranslatedError(handler)
99
100
    def test_error_translation_from_chunk_received(self):
101
        handler = request.SmartServerRequestHandler(
102
            None, {'foo': ChunkErrorRequest}, '/')
103
        handler.args_received(('foo',))
104
        self.assertNoResponse(handler)
105
        handler.accept_body('bytes')
106
        self.assertResponseIsTranslatedError(handler)
107
108
    def test_error_translation_from_end_received(self):
109
        handler = request.SmartServerRequestHandler(
110
            None, {'foo': EndErrorRequest}, '/')
111
        handler.args_received(('foo',))
112
        self.assertNoResponse(handler)
113
        handler.end_received()
114
        self.assertResponseIsTranslatedError(handler)
115
116
117
class TestRequestHanderErrorTranslation(TestCase):
118
    """Tests for bzrlib.smart.request._translate_error."""
119
120
    def assertTranslationEqual(self, expected_tuple, error):
121
        self.assertEqual(expected_tuple, request._translate_error(error))
122
123
    def test_NoSuchFile(self):
124
        self.assertTranslationEqual(
125
            ('NoSuchFile', 'path'), errors.NoSuchFile('path'))
126
127
    def test_LockContention(self):
128
        self.assertTranslationEqual(
129
            ('LockContention', 'lock', 'msg'),
130
            errors.LockContention('lock', 'msg'))
131
132
    def test_TokenMismatch(self):
133
        self.assertTranslationEqual(
134
            ('TokenMismatch', 'some-token', 'actual-token'),
135
            errors.TokenMismatch('some-token', 'actual-token'))
136