/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
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
4160.2.2 by Andrew Bennetts
Add setup_jail and teardown_jail to SmartServerRequest.
19
import threading
20
3990.3.3 by Andrew Bennetts
Add a test that unexpected request bodies trigger a SmartProtocolError from request implementations.
21
from bzrlib import errors
3990.3.2 by Andrew Bennetts
Fix the do_body NotImplementedError log spam.
22
from bzrlib.smart import request
4160.2.2 by Andrew Bennetts
Add setup_jail and teardown_jail to SmartServerRequest.
23
from bzrlib.tests import TestCase, TestCaseWithMemoryTransport
3990.3.2 by Andrew Bennetts
Fix the do_body NotImplementedError log spam.
24
25
3990.3.3 by Andrew Bennetts
Add a test that unexpected request bodies trigger a SmartProtocolError from request implementations.
26
class NoBodyRequest(request.SmartServerRequest):
27
    """A request that does not implement do_body."""
28
29
    def do(self):
30
        return request.SuccessfulSmartServerResponse(('ok',))
31
32
4144.3.1 by Andrew Bennetts
Add Repository.insert_stream_locked server-side implementation, plus tests for server-side _translate_error.
33
class DoErrorRequest(request.SmartServerRequest):
34
    """A request that raises an error from self.do()."""
35
    
36
    def do(self):
37
        raise errors.NoSuchFile('xyzzy')
38
39
40
class ChunkErrorRequest(request.SmartServerRequest):
41
    """A request that raises an error from self.do_chunk()."""
42
    
43
    def do(self):
44
        """No-op."""
45
        pass
46
47
    def do_chunk(self, bytes):
48
        raise errors.NoSuchFile('xyzzy')
49
50
51
class EndErrorRequest(request.SmartServerRequest):
52
    """A request that raises an error from self.do_end()."""
53
    
54
    def do(self):
55
        """No-op."""
56
        pass
57
58
    def do_chunk(self, bytes):
59
        """No-op."""
60
        pass
61
        
62
    def do_end(self):
63
        raise errors.NoSuchFile('xyzzy')
64
65
4160.2.2 by Andrew Bennetts
Add setup_jail and teardown_jail to SmartServerRequest.
66
class CheckJailRequest(request.SmartServerRequest):
67
68
    def __init__(self, *args):
69
        request.SmartServerRequest.__init__(self, *args)
70
        self.jail_transports_log = []
71
72
    def do(self):
73
        self.jail_transports_log.append(request.jail_info.transports)
74
75
    def do_chunk(self, bytes):
76
        self.jail_transports_log.append(request.jail_info.transports)
77
78
    def do_end(self):
79
        self.jail_transports_log.append(request.jail_info.transports)
80
81
3990.3.2 by Andrew Bennetts
Fix the do_body NotImplementedError log spam.
82
class TestSmartRequest(TestCase):
83
84
    def test_request_class_without_do_body(self):
85
        """If a request has no body data, and the request's implementation does
86
        not override do_body, then no exception is raised.
87
        """
88
        # Create a SmartServerRequestHandler with a SmartServerRequest subclass
89
        # that does not implement do_body.
90
        handler = request.SmartServerRequestHandler(
91
            None, {'foo': NoBodyRequest}, '/')
92
        # Emulate a request with no body (i.e. just args).
93
        handler.args_received(('foo',))
94
        handler.end_received()
3990.3.3 by Andrew Bennetts
Add a test that unexpected request bodies trigger a SmartProtocolError from request implementations.
95
        # Request done, no exception was raised.
96
4160.2.2 by Andrew Bennetts
Add setup_jail and teardown_jail to SmartServerRequest.
97
    def test_only_request_code_is_jailed(self):
98
        transport = 'dummy transport'
99
        handler = request.SmartServerRequestHandler(
100
            transport, {'foo': CheckJailRequest}, '/')
101
        handler.args_received(('foo',))
102
        self.assertEqual(None, request.jail_info.transports)
103
        handler.accept_body('bytes')
104
        self.assertEqual(None, request.jail_info.transports)
105
        handler.end_received()
106
        self.assertEqual(None, request.jail_info.transports)
107
        self.assertEqual(
108
            [[transport]] * 3, handler._command.jail_transports_log)
109
110
4144.3.1 by Andrew Bennetts
Add Repository.insert_stream_locked server-side implementation, plus tests for server-side _translate_error.
111
112
class TestSmartRequestHandlerErrorTranslation(TestCase):
113
    """Tests that SmartServerRequestHandler will translate exceptions raised by
114
    a SmartServerRequest into FailedSmartServerResponses.
115
    """
116
117
    def assertNoResponse(self, handler):
118
        self.assertEqual(None, handler.response)
119
120
    def assertResponseIsTranslatedError(self, handler):
121
        expected_translation = ('NoSuchFile', 'xyzzy')
122
        self.assertEqual(
123
            request.FailedSmartServerResponse(expected_translation),
124
            handler.response)
125
126
    def test_error_translation_from_args_received(self):
127
        handler = request.SmartServerRequestHandler(
128
            None, {'foo': DoErrorRequest}, '/')
129
        handler.args_received(('foo',))
130
        self.assertResponseIsTranslatedError(handler)
131
132
    def test_error_translation_from_chunk_received(self):
133
        handler = request.SmartServerRequestHandler(
134
            None, {'foo': ChunkErrorRequest}, '/')
135
        handler.args_received(('foo',))
136
        self.assertNoResponse(handler)
137
        handler.accept_body('bytes')
138
        self.assertResponseIsTranslatedError(handler)
139
140
    def test_error_translation_from_end_received(self):
141
        handler = request.SmartServerRequestHandler(
142
            None, {'foo': EndErrorRequest}, '/')
143
        handler.args_received(('foo',))
144
        self.assertNoResponse(handler)
145
        handler.end_received()
146
        self.assertResponseIsTranslatedError(handler)
147
148
149
class TestRequestHanderErrorTranslation(TestCase):
150
    """Tests for bzrlib.smart.request._translate_error."""
151
152
    def assertTranslationEqual(self, expected_tuple, error):
153
        self.assertEqual(expected_tuple, request._translate_error(error))
154
155
    def test_NoSuchFile(self):
156
        self.assertTranslationEqual(
157
            ('NoSuchFile', 'path'), errors.NoSuchFile('path'))
158
159
    def test_LockContention(self):
160
        self.assertTranslationEqual(
161
            ('LockContention', 'lock', 'msg'),
162
            errors.LockContention('lock', 'msg'))
163
164
    def test_TokenMismatch(self):
165
        self.assertTranslationEqual(
166
            ('TokenMismatch', 'some-token', 'actual-token'),
167
            errors.TokenMismatch('some-token', 'actual-token'))
168
4160.2.2 by Andrew Bennetts
Add setup_jail and teardown_jail to SmartServerRequest.
169
170
class TestRequestJail(TestCaseWithMemoryTransport):
171
    
172
    def test_jail(self):
173
        transport = self.get_transport('blah')
174
        req = request.SmartServerRequest(transport)
175
        tls = threading.local()
176
        self.assertEqual(None, request.jail_info.transports)
177
        req.setup_jail()
178
        self.assertEqual([transport], request.jail_info.transports)
179
        req.teardown_jail()
180
        self.assertEqual(None, request.jail_info.transports)
181