~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_smart_request.py

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2009-03-18 02:14:31 UTC
  • mfrom: (4158.2.1 integration)
  • Revision ID: pqm@pqm.ubuntu.com-20090318021431-md1n8o3542wwsvai
(mbp) merge back 1.13final to trunk

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2009, 2010 Canonical Ltd
 
1
# Copyright (C) 2009 Canonical Ltd
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
12
12
#
13
13
# You should have received a copy of the GNU General Public License
14
14
# along with this program; if not, write to the Free Software
15
 
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
16
 
17
17
"""Tests for smart server request infrastructure (bzrlib.smart.request)."""
18
18
 
19
 
import threading
20
 
 
21
 
from bzrlib import (
22
 
    errors,
23
 
    transport,
24
 
    )
25
 
from bzrlib.bzrdir import BzrDir
 
19
from bzrlib import errors
26
20
from bzrlib.smart import request
27
 
from bzrlib.tests import TestCase, TestCaseWithMemoryTransport
 
21
from bzrlib.tests import TestCase
28
22
 
29
23
 
30
24
class NoBodyRequest(request.SmartServerRequest):
36
30
 
37
31
class DoErrorRequest(request.SmartServerRequest):
38
32
    """A request that raises an error from self.do()."""
39
 
 
 
33
    
40
34
    def do(self):
41
35
        raise errors.NoSuchFile('xyzzy')
42
36
 
67
61
        raise errors.NoSuchFile('xyzzy')
68
62
 
69
63
 
70
 
class CheckJailRequest(request.SmartServerRequest):
71
 
 
72
 
    def __init__(self, *args):
73
 
        request.SmartServerRequest.__init__(self, *args)
74
 
        self.jail_transports_log = []
75
 
 
76
 
    def do(self):
77
 
        self.jail_transports_log.append(request.jail_info.transports)
78
 
 
79
 
    def do_chunk(self, bytes):
80
 
        self.jail_transports_log.append(request.jail_info.transports)
81
 
 
82
 
    def do_end(self):
83
 
        self.jail_transports_log.append(request.jail_info.transports)
84
 
 
85
 
 
86
64
class TestSmartRequest(TestCase):
87
65
 
88
66
    def test_request_class_without_do_body(self):
98
76
        handler.end_received()
99
77
        # Request done, no exception was raised.
100
78
 
101
 
    def test_only_request_code_is_jailed(self):
102
 
        transport = 'dummy transport'
103
 
        handler = request.SmartServerRequestHandler(
104
 
            transport, {'foo': CheckJailRequest}, '/')
105
 
        handler.args_received(('foo',))
106
 
        self.assertEqual(None, request.jail_info.transports)
107
 
        handler.accept_body('bytes')
108
 
        self.assertEqual(None, request.jail_info.transports)
109
 
        handler.end_received()
110
 
        self.assertEqual(None, request.jail_info.transports)
111
 
        self.assertEqual(
112
 
            [[transport]] * 3, handler._command.jail_transports_log)
113
 
 
114
 
 
115
79
 
116
80
class TestSmartRequestHandlerErrorTranslation(TestCase):
117
81
    """Tests that SmartServerRequestHandler will translate exceptions raised by
161
125
            ('NoSuchFile', 'path'), errors.NoSuchFile('path'))
162
126
 
163
127
    def test_LockContention(self):
164
 
        # For now, LockContentions are always transmitted with no details.
165
 
        # Eventually they should include a relpath or url or something else to
166
 
        # identify which lock is busy.
167
128
        self.assertTranslationEqual(
168
 
            ('LockContention',), errors.LockContention('lock', 'msg'))
 
129
            ('LockContention', 'lock', 'msg'),
 
130
            errors.LockContention('lock', 'msg'))
169
131
 
170
132
    def test_TokenMismatch(self):
171
133
        self.assertTranslationEqual(
172
134
            ('TokenMismatch', 'some-token', 'actual-token'),
173
135
            errors.TokenMismatch('some-token', 'actual-token'))
174
136
 
175
 
 
176
 
class TestRequestJail(TestCaseWithMemoryTransport):
177
 
 
178
 
    def test_jail(self):
179
 
        transport = self.get_transport('blah')
180
 
        req = request.SmartServerRequest(transport)
181
 
        self.assertEqual(None, request.jail_info.transports)
182
 
        req.setup_jail()
183
 
        self.assertEqual([transport], request.jail_info.transports)
184
 
        req.teardown_jail()
185
 
        self.assertEqual(None, request.jail_info.transports)
186
 
 
187
 
 
188
 
class TestJailHook(TestCaseWithMemoryTransport):
189
 
 
190
 
    def setUp(self):
191
 
        super(TestJailHook, self).setUp()
192
 
        def clear_jail_info():
193
 
            request.jail_info.transports = None
194
 
        self.addCleanup(clear_jail_info)
195
 
 
196
 
    def test_jail_hook(self):
197
 
        request.jail_info.transports = None
198
 
        _pre_open_hook = request._pre_open_hook
199
 
        # Any transport is fine if jail_info.transports is None
200
 
        t = self.get_transport('foo')
201
 
        _pre_open_hook(t)
202
 
        # A transport in jail_info.transports is allowed
203
 
        request.jail_info.transports = [t]
204
 
        _pre_open_hook(t)
205
 
        # A child of a transport in jail_info is allowed
206
 
        _pre_open_hook(t.clone('child'))
207
 
        # A parent is not allowed
208
 
        self.assertRaises(errors.JailBreak, _pre_open_hook, t.clone('..'))
209
 
        # A completely unrelated transport is not allowed
210
 
        self.assertRaises(errors.JailBreak, _pre_open_hook,
211
 
                          transport.get_transport('http://host/'))
212
 
 
213
 
    def test_open_bzrdir_in_non_main_thread(self):
214
 
        """Opening a bzrdir in a non-main thread should work ok.
215
 
        
216
 
        This makes sure that the globally-installed
217
 
        bzrlib.smart.request._pre_open_hook, which uses a threading.local(),
218
 
        works in a newly created thread.
219
 
        """
220
 
        bzrdir = self.make_bzrdir('.')
221
 
        transport = bzrdir.root_transport
222
 
        thread_result = []
223
 
        def t():
224
 
            BzrDir.open_from_transport(transport)
225
 
            thread_result.append('ok')
226
 
        thread = threading.Thread(target=t)
227
 
        thread.start()
228
 
        thread.join()
229
 
        self.assertEqual(['ok'], thread_result)
230