~ubuntu-branches/ubuntu/trusty/cinder/trusty

« back to all changes in this revision

Viewing changes to cinder/tests/api/openstack/test_wsgi.py

  • Committer: Package Import Robot
  • Author(s): Chuck Short
  • Date: 2012-05-22 09:57:46 UTC
  • Revision ID: package-import@ubuntu.com-20120522095746-9lm71yvzltjybk4b
Tags: upstream-2012.2~f1~20120503.2
ImportĀ upstreamĀ versionĀ 2012.2~f1~20120503.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# vim: tabstop=4 shiftwidth=4 softtabstop=4
 
2
 
 
3
import inspect
 
4
import json
 
5
import webob
 
6
 
 
7
from cinder import exception
 
8
from cinder import test
 
9
from cinder import utils
 
10
from cinder.api.openstack import wsgi
 
11
from cinder.tests.api.openstack import fakes
 
12
import cinder.context
 
13
 
 
14
 
 
15
class RequestTest(test.TestCase):
 
16
    def test_content_type_missing(self):
 
17
        request = wsgi.Request.blank('/tests/123', method='POST')
 
18
        request.body = "<body />"
 
19
        self.assertEqual(None, request.get_content_type())
 
20
 
 
21
    def test_content_type_unsupported(self):
 
22
        request = wsgi.Request.blank('/tests/123', method='POST')
 
23
        request.headers["Content-Type"] = "text/html"
 
24
        request.body = "asdf<br />"
 
25
        self.assertRaises(exception.InvalidContentType,
 
26
                          request.get_content_type)
 
27
 
 
28
    def test_content_type_with_charset(self):
 
29
        request = wsgi.Request.blank('/tests/123')
 
30
        request.headers["Content-Type"] = "application/json; charset=UTF-8"
 
31
        result = request.get_content_type()
 
32
        self.assertEqual(result, "application/json")
 
33
 
 
34
    def test_content_type_from_accept(self):
 
35
        for content_type in ('application/xml',
 
36
                             'application/vnd.openstack.volume+xml',
 
37
                             'application/json',
 
38
                             'application/vnd.openstack.volume+json'):
 
39
            request = wsgi.Request.blank('/tests/123')
 
40
            request.headers["Accept"] = content_type
 
41
            result = request.best_match_content_type()
 
42
            self.assertEqual(result, content_type)
 
43
 
 
44
    def test_content_type_from_accept_best(self):
 
45
        request = wsgi.Request.blank('/tests/123')
 
46
        request.headers["Accept"] = "application/xml, application/json"
 
47
        result = request.best_match_content_type()
 
48
        self.assertEqual(result, "application/json")
 
49
 
 
50
        request = wsgi.Request.blank('/tests/123')
 
51
        request.headers["Accept"] = ("application/json; q=0.3, "
 
52
                                     "application/xml; q=0.9")
 
53
        result = request.best_match_content_type()
 
54
        self.assertEqual(result, "application/xml")
 
55
 
 
56
    def test_content_type_from_query_extension(self):
 
57
        request = wsgi.Request.blank('/tests/123.xml')
 
58
        result = request.best_match_content_type()
 
59
        self.assertEqual(result, "application/xml")
 
60
 
 
61
        request = wsgi.Request.blank('/tests/123.json')
 
62
        result = request.best_match_content_type()
 
63
        self.assertEqual(result, "application/json")
 
64
 
 
65
        request = wsgi.Request.blank('/tests/123.invalid')
 
66
        result = request.best_match_content_type()
 
67
        self.assertEqual(result, "application/json")
 
68
 
 
69
    def test_content_type_accept_and_query_extension(self):
 
70
        request = wsgi.Request.blank('/tests/123.xml')
 
71
        request.headers["Accept"] = "application/json"
 
72
        result = request.best_match_content_type()
 
73
        self.assertEqual(result, "application/xml")
 
74
 
 
75
    def test_content_type_accept_default(self):
 
76
        request = wsgi.Request.blank('/tests/123.unsupported')
 
77
        request.headers["Accept"] = "application/unsupported1"
 
78
        result = request.best_match_content_type()
 
79
        self.assertEqual(result, "application/json")
 
80
 
 
81
 
 
82
class ActionDispatcherTest(test.TestCase):
 
83
    def test_dispatch(self):
 
84
        serializer = wsgi.ActionDispatcher()
 
85
        serializer.create = lambda x: 'pants'
 
86
        self.assertEqual(serializer.dispatch({}, action='create'), 'pants')
 
87
 
 
88
    def test_dispatch_action_None(self):
 
89
        serializer = wsgi.ActionDispatcher()
 
90
        serializer.create = lambda x: 'pants'
 
91
        serializer.default = lambda x: 'trousers'
 
92
        self.assertEqual(serializer.dispatch({}, action=None), 'trousers')
 
93
 
 
94
    def test_dispatch_default(self):
 
95
        serializer = wsgi.ActionDispatcher()
 
96
        serializer.create = lambda x: 'pants'
 
97
        serializer.default = lambda x: 'trousers'
 
98
        self.assertEqual(serializer.dispatch({}, action='update'), 'trousers')
 
99
 
 
100
 
 
101
class DictSerializerTest(test.TestCase):
 
102
    def test_dispatch_default(self):
 
103
        serializer = wsgi.DictSerializer()
 
104
        self.assertEqual(serializer.serialize({}, 'update'), '')
 
105
 
 
106
 
 
107
class XMLDictSerializerTest(test.TestCase):
 
108
    def test_xml(self):
 
109
        input_dict = dict(servers=dict(a=(2, 3)))
 
110
        expected_xml = '<serversxmlns="asdf"><a>(2,3)</a></servers>'
 
111
        serializer = wsgi.XMLDictSerializer(xmlns="asdf")
 
112
        result = serializer.serialize(input_dict)
 
113
        result = result.replace('\n', '').replace(' ', '')
 
114
        self.assertEqual(result, expected_xml)
 
115
 
 
116
 
 
117
class JSONDictSerializerTest(test.TestCase):
 
118
    def test_json(self):
 
119
        input_dict = dict(servers=dict(a=(2, 3)))
 
120
        expected_json = '{"servers":{"a":[2,3]}}'
 
121
        serializer = wsgi.JSONDictSerializer()
 
122
        result = serializer.serialize(input_dict)
 
123
        result = result.replace('\n', '').replace(' ', '')
 
124
        self.assertEqual(result, expected_json)
 
125
 
 
126
 
 
127
class TextDeserializerTest(test.TestCase):
 
128
    def test_dispatch_default(self):
 
129
        deserializer = wsgi.TextDeserializer()
 
130
        self.assertEqual(deserializer.deserialize({}, 'update'), {})
 
131
 
 
132
 
 
133
class JSONDeserializerTest(test.TestCase):
 
134
    def test_json(self):
 
135
        data = """{"a": {
 
136
                "a1": "1",
 
137
                "a2": "2",
 
138
                "bs": ["1", "2", "3", {"c": {"c1": "1"}}],
 
139
                "d": {"e": "1"},
 
140
                "f": "1"}}"""
 
141
        as_dict = {
 
142
            'body': {
 
143
                'a': {
 
144
                    'a1': '1',
 
145
                    'a2': '2',
 
146
                    'bs': ['1', '2', '3', {'c': {'c1': '1'}}],
 
147
                    'd': {'e': '1'},
 
148
                    'f': '1',
 
149
                },
 
150
            },
 
151
        }
 
152
        deserializer = wsgi.JSONDeserializer()
 
153
        self.assertEqual(deserializer.deserialize(data), as_dict)
 
154
 
 
155
 
 
156
class XMLDeserializerTest(test.TestCase):
 
157
    def test_xml(self):
 
158
        xml = """
 
159
            <a a1="1" a2="2">
 
160
              <bs><b>1</b><b>2</b><b>3</b><b><c c1="1"/></b></bs>
 
161
              <d><e>1</e></d>
 
162
              <f>1</f>
 
163
            </a>
 
164
            """.strip()
 
165
        as_dict = {
 
166
            'body': {
 
167
                'a': {
 
168
                    'a1': '1',
 
169
                    'a2': '2',
 
170
                    'bs': ['1', '2', '3', {'c': {'c1': '1'}}],
 
171
                    'd': {'e': '1'},
 
172
                    'f': '1',
 
173
                },
 
174
            },
 
175
        }
 
176
        metadata = {'plurals': {'bs': 'b', 'ts': 't'}}
 
177
        deserializer = wsgi.XMLDeserializer(metadata=metadata)
 
178
        self.assertEqual(deserializer.deserialize(xml), as_dict)
 
179
 
 
180
    def test_xml_empty(self):
 
181
        xml = """<a></a>"""
 
182
        as_dict = {"body": {"a": {}}}
 
183
        deserializer = wsgi.XMLDeserializer()
 
184
        self.assertEqual(deserializer.deserialize(xml), as_dict)
 
185
 
 
186
 
 
187
class ResourceTest(test.TestCase):
 
188
    def test_resource_call(self):
 
189
        class Controller(object):
 
190
            def index(self, req):
 
191
                return 'off'
 
192
 
 
193
        req = webob.Request.blank('/tests')
 
194
        app = fakes.TestRouter(Controller())
 
195
        response = req.get_response(app)
 
196
        self.assertEqual(response.body, 'off')
 
197
        self.assertEqual(response.status_int, 200)
 
198
 
 
199
    def test_resource_not_authorized(self):
 
200
        class Controller(object):
 
201
            def index(self, req):
 
202
                raise exception.NotAuthorized()
 
203
 
 
204
        req = webob.Request.blank('/tests')
 
205
        app = fakes.TestRouter(Controller())
 
206
        response = req.get_response(app)
 
207
        self.assertEqual(response.status_int, 403)
 
208
 
 
209
    def test_dispatch(self):
 
210
        class Controller(object):
 
211
            def index(self, req, pants=None):
 
212
                return pants
 
213
 
 
214
        controller = Controller()
 
215
        resource = wsgi.Resource(controller)
 
216
        method, extensions = resource.get_method(None, 'index', None, '')
 
217
        actual = resource.dispatch(method, None, {'pants': 'off'})
 
218
        expected = 'off'
 
219
        self.assertEqual(actual, expected)
 
220
 
 
221
    def test_get_method_unknown_controller_action(self):
 
222
        class Controller(object):
 
223
            def index(self, req, pants=None):
 
224
                return pants
 
225
 
 
226
        controller = Controller()
 
227
        resource = wsgi.Resource(controller)
 
228
        self.assertRaises(AttributeError, resource.get_method,
 
229
                          None, 'create', None, '')
 
230
 
 
231
    def test_get_method_action_json(self):
 
232
        class Controller(wsgi.Controller):
 
233
            @wsgi.action('fooAction')
 
234
            def _action_foo(self, req, id, body):
 
235
                return body
 
236
 
 
237
        controller = Controller()
 
238
        resource = wsgi.Resource(controller)
 
239
        method, extensions = resource.get_method(None, 'action',
 
240
                                                 'application/json',
 
241
                                                 '{"fooAction": true}')
 
242
        self.assertEqual(controller._action_foo, method)
 
243
 
 
244
    def test_get_method_action_xml(self):
 
245
        class Controller(wsgi.Controller):
 
246
            @wsgi.action('fooAction')
 
247
            def _action_foo(self, req, id, body):
 
248
                return body
 
249
 
 
250
        controller = Controller()
 
251
        resource = wsgi.Resource(controller)
 
252
        method, extensions = resource.get_method(None, 'action',
 
253
                                                 'application/xml',
 
254
                                                 '<fooAction>true</fooAction>')
 
255
        self.assertEqual(controller._action_foo, method)
 
256
 
 
257
    def test_get_method_action_bad_body(self):
 
258
        class Controller(wsgi.Controller):
 
259
            @wsgi.action('fooAction')
 
260
            def _action_foo(self, req, id, body):
 
261
                return body
 
262
 
 
263
        controller = Controller()
 
264
        resource = wsgi.Resource(controller)
 
265
        self.assertRaises(exception.MalformedRequestBody, resource.get_method,
 
266
                          None, 'action', 'application/json', '{}')
 
267
 
 
268
    def test_get_method_unknown_controller_action(self):
 
269
        class Controller(wsgi.Controller):
 
270
            @wsgi.action('fooAction')
 
271
            def _action_foo(self, req, id, body):
 
272
                return body
 
273
 
 
274
        controller = Controller()
 
275
        resource = wsgi.Resource(controller)
 
276
        self.assertRaises(KeyError, resource.get_method,
 
277
                          None, 'action', 'application/json',
 
278
                          '{"barAction": true}')
 
279
 
 
280
    def test_get_method_action_method(self):
 
281
        class Controller():
 
282
            def action(self, req, pants=None):
 
283
                return pants
 
284
 
 
285
        controller = Controller()
 
286
        resource = wsgi.Resource(controller)
 
287
        method, extensions = resource.get_method(None, 'action',
 
288
                                                 'application/xml',
 
289
                                                 '<fooAction>true</fooAction')
 
290
        self.assertEqual(controller.action, method)
 
291
 
 
292
    def test_get_action_args(self):
 
293
        class Controller(object):
 
294
            def index(self, req, pants=None):
 
295
                return pants
 
296
 
 
297
        controller = Controller()
 
298
        resource = wsgi.Resource(controller)
 
299
 
 
300
        env = {
 
301
            'wsgiorg.routing_args': [None, {
 
302
                'controller': None,
 
303
                'format': None,
 
304
                'action': 'update',
 
305
                'id': 12,
 
306
            }],
 
307
        }
 
308
 
 
309
        expected = {'action': 'update', 'id': 12}
 
310
 
 
311
        self.assertEqual(resource.get_action_args(env), expected)
 
312
 
 
313
    def test_get_body_bad_content(self):
 
314
        class Controller(object):
 
315
            def index(self, req, pants=None):
 
316
                return pants
 
317
 
 
318
        controller = Controller()
 
319
        resource = wsgi.Resource(controller)
 
320
 
 
321
        request = wsgi.Request.blank('/', method='POST')
 
322
        request.headers['Content-Type'] = 'application/none'
 
323
        request.body = 'foo'
 
324
 
 
325
        content_type, body = resource.get_body(request)
 
326
        self.assertEqual(content_type, None)
 
327
        self.assertEqual(body, '')
 
328
 
 
329
    def test_get_body_no_content_type(self):
 
330
        class Controller(object):
 
331
            def index(self, req, pants=None):
 
332
                return pants
 
333
 
 
334
        controller = Controller()
 
335
        resource = wsgi.Resource(controller)
 
336
 
 
337
        request = wsgi.Request.blank('/', method='POST')
 
338
        request.body = 'foo'
 
339
 
 
340
        content_type, body = resource.get_body(request)
 
341
        self.assertEqual(content_type, None)
 
342
        self.assertEqual(body, '')
 
343
 
 
344
    def test_get_body_no_content_body(self):
 
345
        class Controller(object):
 
346
            def index(self, req, pants=None):
 
347
                return pants
 
348
 
 
349
        controller = Controller()
 
350
        resource = wsgi.Resource(controller)
 
351
 
 
352
        request = wsgi.Request.blank('/', method='POST')
 
353
        request.headers['Content-Type'] = 'application/json'
 
354
        request.body = ''
 
355
 
 
356
        content_type, body = resource.get_body(request)
 
357
        self.assertEqual(content_type, None)
 
358
        self.assertEqual(body, '')
 
359
 
 
360
    def test_get_body(self):
 
361
        class Controller(object):
 
362
            def index(self, req, pants=None):
 
363
                return pants
 
364
 
 
365
        controller = Controller()
 
366
        resource = wsgi.Resource(controller)
 
367
 
 
368
        request = wsgi.Request.blank('/', method='POST')
 
369
        request.headers['Content-Type'] = 'application/json'
 
370
        request.body = 'foo'
 
371
 
 
372
        content_type, body = resource.get_body(request)
 
373
        self.assertEqual(content_type, 'application/json')
 
374
        self.assertEqual(body, 'foo')
 
375
 
 
376
    def test_deserialize_badtype(self):
 
377
        class Controller(object):
 
378
            def index(self, req, pants=None):
 
379
                return pants
 
380
 
 
381
        controller = Controller()
 
382
        resource = wsgi.Resource(controller)
 
383
        self.assertRaises(exception.InvalidContentType,
 
384
                          resource.deserialize,
 
385
                          controller.index, 'application/none', 'foo')
 
386
 
 
387
    def test_deserialize_default(self):
 
388
        class JSONDeserializer(object):
 
389
            def deserialize(self, body):
 
390
                return 'json'
 
391
 
 
392
        class XMLDeserializer(object):
 
393
            def deserialize(self, body):
 
394
                return 'xml'
 
395
 
 
396
        class Controller(object):
 
397
            @wsgi.deserializers(xml=XMLDeserializer)
 
398
            def index(self, req, pants=None):
 
399
                return pants
 
400
 
 
401
        controller = Controller()
 
402
        resource = wsgi.Resource(controller, json=JSONDeserializer)
 
403
 
 
404
        obj = resource.deserialize(controller.index, 'application/json', 'foo')
 
405
        self.assertEqual(obj, 'json')
 
406
 
 
407
    def test_deserialize_decorator(self):
 
408
        class JSONDeserializer(object):
 
409
            def deserialize(self, body):
 
410
                return 'json'
 
411
 
 
412
        class XMLDeserializer(object):
 
413
            def deserialize(self, body):
 
414
                return 'xml'
 
415
 
 
416
        class Controller(object):
 
417
            @wsgi.deserializers(xml=XMLDeserializer)
 
418
            def index(self, req, pants=None):
 
419
                return pants
 
420
 
 
421
        controller = Controller()
 
422
        resource = wsgi.Resource(controller, json=JSONDeserializer)
 
423
 
 
424
        obj = resource.deserialize(controller.index, 'application/xml', 'foo')
 
425
        self.assertEqual(obj, 'xml')
 
426
 
 
427
    def test_register_actions(self):
 
428
        class Controller(object):
 
429
            def index(self, req, pants=None):
 
430
                return pants
 
431
 
 
432
        class ControllerExtended(wsgi.Controller):
 
433
            @wsgi.action('fooAction')
 
434
            def _action_foo(self, req, id, body):
 
435
                return body
 
436
 
 
437
            @wsgi.action('barAction')
 
438
            def _action_bar(self, req, id, body):
 
439
                return body
 
440
 
 
441
        controller = Controller()
 
442
        resource = wsgi.Resource(controller)
 
443
        self.assertEqual({}, resource.wsgi_actions)
 
444
 
 
445
        extended = ControllerExtended()
 
446
        resource.register_actions(extended)
 
447
        self.assertEqual({
 
448
                'fooAction': extended._action_foo,
 
449
                'barAction': extended._action_bar,
 
450
                }, resource.wsgi_actions)
 
451
 
 
452
    def test_register_extensions(self):
 
453
        class Controller(object):
 
454
            def index(self, req, pants=None):
 
455
                return pants
 
456
 
 
457
        class ControllerExtended(wsgi.Controller):
 
458
            @wsgi.extends
 
459
            def index(self, req, resp_obj, pants=None):
 
460
                return None
 
461
 
 
462
            @wsgi.extends(action='fooAction')
 
463
            def _action_foo(self, req, resp, id, body):
 
464
                return None
 
465
 
 
466
        controller = Controller()
 
467
        resource = wsgi.Resource(controller)
 
468
        self.assertEqual({}, resource.wsgi_extensions)
 
469
        self.assertEqual({}, resource.wsgi_action_extensions)
 
470
 
 
471
        extended = ControllerExtended()
 
472
        resource.register_extensions(extended)
 
473
        self.assertEqual({'index': [extended.index]}, resource.wsgi_extensions)
 
474
        self.assertEqual({'fooAction': [extended._action_foo]},
 
475
                         resource.wsgi_action_extensions)
 
476
 
 
477
    def test_get_method_extensions(self):
 
478
        class Controller(object):
 
479
            def index(self, req, pants=None):
 
480
                return pants
 
481
 
 
482
        class ControllerExtended(wsgi.Controller):
 
483
            @wsgi.extends
 
484
            def index(self, req, resp_obj, pants=None):
 
485
                return None
 
486
 
 
487
        controller = Controller()
 
488
        extended = ControllerExtended()
 
489
        resource = wsgi.Resource(controller)
 
490
        resource.register_extensions(extended)
 
491
        method, extensions = resource.get_method(None, 'index', None, '')
 
492
        self.assertEqual(method, controller.index)
 
493
        self.assertEqual(extensions, [extended.index])
 
494
 
 
495
    def test_get_method_action_extensions(self):
 
496
        class Controller(wsgi.Controller):
 
497
            def index(self, req, pants=None):
 
498
                return pants
 
499
 
 
500
            @wsgi.action('fooAction')
 
501
            def _action_foo(self, req, id, body):
 
502
                return body
 
503
 
 
504
        class ControllerExtended(wsgi.Controller):
 
505
            @wsgi.extends(action='fooAction')
 
506
            def _action_foo(self, req, resp_obj, id, body):
 
507
                return None
 
508
 
 
509
        controller = Controller()
 
510
        extended = ControllerExtended()
 
511
        resource = wsgi.Resource(controller)
 
512
        resource.register_extensions(extended)
 
513
        method, extensions = resource.get_method(None, 'action',
 
514
                                                 'application/json',
 
515
                                                 '{"fooAction": true}')
 
516
        self.assertEqual(method, controller._action_foo)
 
517
        self.assertEqual(extensions, [extended._action_foo])
 
518
 
 
519
    def test_get_method_action_whitelist_extensions(self):
 
520
        class Controller(wsgi.Controller):
 
521
            def index(self, req, pants=None):
 
522
                return pants
 
523
 
 
524
        class ControllerExtended(wsgi.Controller):
 
525
            @wsgi.action('create')
 
526
            def _create(self, req, body):
 
527
                pass
 
528
 
 
529
            @wsgi.action('delete')
 
530
            def _delete(self, req, id):
 
531
                pass
 
532
 
 
533
        controller = Controller()
 
534
        extended = ControllerExtended()
 
535
        resource = wsgi.Resource(controller)
 
536
        resource.register_actions(extended)
 
537
 
 
538
        method, extensions = resource.get_method(None, 'create',
 
539
                                                 'application/json',
 
540
                                                 '{"create": true}')
 
541
        self.assertEqual(method, extended._create)
 
542
        self.assertEqual(extensions, [])
 
543
 
 
544
        method, extensions = resource.get_method(None, 'delete', None, None)
 
545
        self.assertEqual(method, extended._delete)
 
546
        self.assertEqual(extensions, [])
 
547
 
 
548
    def test_pre_process_extensions_regular(self):
 
549
        class Controller(object):
 
550
            def index(self, req, pants=None):
 
551
                return pants
 
552
 
 
553
        controller = Controller()
 
554
        resource = wsgi.Resource(controller)
 
555
 
 
556
        called = []
 
557
 
 
558
        def extension1(req, resp_obj):
 
559
            called.append(1)
 
560
            return None
 
561
 
 
562
        def extension2(req, resp_obj):
 
563
            called.append(2)
 
564
            return None
 
565
 
 
566
        extensions = [extension1, extension2]
 
567
        response, post = resource.pre_process_extensions(extensions, None, {})
 
568
        self.assertEqual(called, [])
 
569
        self.assertEqual(response, None)
 
570
        self.assertEqual(list(post), [extension2, extension1])
 
571
 
 
572
    def test_pre_process_extensions_generator(self):
 
573
        class Controller(object):
 
574
            def index(self, req, pants=None):
 
575
                return pants
 
576
 
 
577
        controller = Controller()
 
578
        resource = wsgi.Resource(controller)
 
579
 
 
580
        called = []
 
581
 
 
582
        def extension1(req):
 
583
            called.append('pre1')
 
584
            resp_obj = yield
 
585
            called.append('post1')
 
586
 
 
587
        def extension2(req):
 
588
            called.append('pre2')
 
589
            resp_obj = yield
 
590
            called.append('post2')
 
591
 
 
592
        extensions = [extension1, extension2]
 
593
        response, post = resource.pre_process_extensions(extensions, None, {})
 
594
        post = list(post)
 
595
        self.assertEqual(called, ['pre1', 'pre2'])
 
596
        self.assertEqual(response, None)
 
597
        self.assertEqual(len(post), 2)
 
598
        self.assertTrue(inspect.isgenerator(post[0]))
 
599
        self.assertTrue(inspect.isgenerator(post[1]))
 
600
 
 
601
        for gen in post:
 
602
            try:
 
603
                gen.send(None)
 
604
            except StopIteration:
 
605
                continue
 
606
 
 
607
        self.assertEqual(called, ['pre1', 'pre2', 'post2', 'post1'])
 
608
 
 
609
    def test_pre_process_extensions_generator_response(self):
 
610
        class Controller(object):
 
611
            def index(self, req, pants=None):
 
612
                return pants
 
613
 
 
614
        controller = Controller()
 
615
        resource = wsgi.Resource(controller)
 
616
 
 
617
        called = []
 
618
 
 
619
        def extension1(req):
 
620
            called.append('pre1')
 
621
            yield 'foo'
 
622
 
 
623
        def extension2(req):
 
624
            called.append('pre2')
 
625
 
 
626
        extensions = [extension1, extension2]
 
627
        response, post = resource.pre_process_extensions(extensions, None, {})
 
628
        self.assertEqual(called, ['pre1'])
 
629
        self.assertEqual(response, 'foo')
 
630
        self.assertEqual(post, [])
 
631
 
 
632
    def test_post_process_extensions_regular(self):
 
633
        class Controller(object):
 
634
            def index(self, req, pants=None):
 
635
                return pants
 
636
 
 
637
        controller = Controller()
 
638
        resource = wsgi.Resource(controller)
 
639
 
 
640
        called = []
 
641
 
 
642
        def extension1(req, resp_obj):
 
643
            called.append(1)
 
644
            return None
 
645
 
 
646
        def extension2(req, resp_obj):
 
647
            called.append(2)
 
648
            return None
 
649
 
 
650
        response = resource.post_process_extensions([extension2, extension1],
 
651
                                                    None, None, {})
 
652
        self.assertEqual(called, [2, 1])
 
653
        self.assertEqual(response, None)
 
654
 
 
655
    def test_post_process_extensions_regular_response(self):
 
656
        class Controller(object):
 
657
            def index(self, req, pants=None):
 
658
                return pants
 
659
 
 
660
        controller = Controller()
 
661
        resource = wsgi.Resource(controller)
 
662
 
 
663
        called = []
 
664
 
 
665
        def extension1(req, resp_obj):
 
666
            called.append(1)
 
667
            return None
 
668
 
 
669
        def extension2(req, resp_obj):
 
670
            called.append(2)
 
671
            return 'foo'
 
672
 
 
673
        response = resource.post_process_extensions([extension2, extension1],
 
674
                                                    None, None, {})
 
675
        self.assertEqual(called, [2])
 
676
        self.assertEqual(response, 'foo')
 
677
 
 
678
    def test_post_process_extensions_generator(self):
 
679
        class Controller(object):
 
680
            def index(self, req, pants=None):
 
681
                return pants
 
682
 
 
683
        controller = Controller()
 
684
        resource = wsgi.Resource(controller)
 
685
 
 
686
        called = []
 
687
 
 
688
        def extension1(req):
 
689
            resp_obj = yield
 
690
            called.append(1)
 
691
 
 
692
        def extension2(req):
 
693
            resp_obj = yield
 
694
            called.append(2)
 
695
 
 
696
        ext1 = extension1(None)
 
697
        ext1.next()
 
698
        ext2 = extension2(None)
 
699
        ext2.next()
 
700
 
 
701
        response = resource.post_process_extensions([ext2, ext1],
 
702
                                                    None, None, {})
 
703
 
 
704
        self.assertEqual(called, [2, 1])
 
705
        self.assertEqual(response, None)
 
706
 
 
707
    def test_post_process_extensions_generator_response(self):
 
708
        class Controller(object):
 
709
            def index(self, req, pants=None):
 
710
                return pants
 
711
 
 
712
        controller = Controller()
 
713
        resource = wsgi.Resource(controller)
 
714
 
 
715
        called = []
 
716
 
 
717
        def extension1(req):
 
718
            resp_obj = yield
 
719
            called.append(1)
 
720
 
 
721
        def extension2(req):
 
722
            resp_obj = yield
 
723
            called.append(2)
 
724
            yield 'foo'
 
725
 
 
726
        ext1 = extension1(None)
 
727
        ext1.next()
 
728
        ext2 = extension2(None)
 
729
        ext2.next()
 
730
 
 
731
        response = resource.post_process_extensions([ext2, ext1],
 
732
                                                    None, None, {})
 
733
 
 
734
        self.assertEqual(called, [2])
 
735
        self.assertEqual(response, 'foo')
 
736
 
 
737
 
 
738
class ResponseObjectTest(test.TestCase):
 
739
    def test_default_code(self):
 
740
        robj = wsgi.ResponseObject({})
 
741
        self.assertEqual(robj.code, 200)
 
742
 
 
743
    def test_modified_code(self):
 
744
        robj = wsgi.ResponseObject({})
 
745
        robj._default_code = 202
 
746
        self.assertEqual(robj.code, 202)
 
747
 
 
748
    def test_override_default_code(self):
 
749
        robj = wsgi.ResponseObject({}, code=404)
 
750
        self.assertEqual(robj.code, 404)
 
751
 
 
752
    def test_override_modified_code(self):
 
753
        robj = wsgi.ResponseObject({}, code=404)
 
754
        robj._default_code = 202
 
755
        self.assertEqual(robj.code, 404)
 
756
 
 
757
    def test_set_header(self):
 
758
        robj = wsgi.ResponseObject({})
 
759
        robj['Header'] = 'foo'
 
760
        self.assertEqual(robj.headers, {'header': 'foo'})
 
761
 
 
762
    def test_get_header(self):
 
763
        robj = wsgi.ResponseObject({})
 
764
        robj['Header'] = 'foo'
 
765
        self.assertEqual(robj['hEADER'], 'foo')
 
766
 
 
767
    def test_del_header(self):
 
768
        robj = wsgi.ResponseObject({})
 
769
        robj['Header'] = 'foo'
 
770
        del robj['hEADER']
 
771
        self.assertFalse('header' in robj.headers)
 
772
 
 
773
    def test_header_isolation(self):
 
774
        robj = wsgi.ResponseObject({})
 
775
        robj['Header'] = 'foo'
 
776
        hdrs = robj.headers
 
777
        hdrs['hEADER'] = 'bar'
 
778
        self.assertEqual(robj['hEADER'], 'foo')
 
779
 
 
780
    def test_default_serializers(self):
 
781
        robj = wsgi.ResponseObject({})
 
782
        self.assertEqual(robj.serializers, {})
 
783
 
 
784
    def test_bind_serializers(self):
 
785
        robj = wsgi.ResponseObject({}, json='foo')
 
786
        robj._bind_method_serializers(dict(xml='bar', json='baz'))
 
787
        self.assertEqual(robj.serializers, dict(xml='bar', json='foo'))
 
788
 
 
789
    def test_get_serializer(self):
 
790
        robj = wsgi.ResponseObject({}, json='json', xml='xml', atom='atom')
 
791
        for content_type, mtype in wsgi._MEDIA_TYPE_MAP.items():
 
792
            _mtype, serializer = robj.get_serializer(content_type)
 
793
            self.assertEqual(serializer, mtype)
 
794
 
 
795
    def test_get_serializer_defaults(self):
 
796
        robj = wsgi.ResponseObject({})
 
797
        default_serializers = dict(json='json', xml='xml', atom='atom')
 
798
        for content_type, mtype in wsgi._MEDIA_TYPE_MAP.items():
 
799
            self.assertRaises(exception.InvalidContentType,
 
800
                              robj.get_serializer, content_type)
 
801
            _mtype, serializer = robj.get_serializer(content_type,
 
802
                                                     default_serializers)
 
803
            self.assertEqual(serializer, mtype)
 
804
 
 
805
    def test_serialize(self):
 
806
        class JSONSerializer(object):
 
807
            def serialize(self, obj):
 
808
                return 'json'
 
809
 
 
810
        class XMLSerializer(object):
 
811
            def serialize(self, obj):
 
812
                return 'xml'
 
813
 
 
814
        class AtomSerializer(object):
 
815
            def serialize(self, obj):
 
816
                return 'atom'
 
817
 
 
818
        robj = wsgi.ResponseObject({}, code=202,
 
819
                                   json=JSONSerializer,
 
820
                                   xml=XMLSerializer,
 
821
                                   atom=AtomSerializer)
 
822
        robj['X-header1'] = 'header1'
 
823
        robj['X-header2'] = 'header2'
 
824
 
 
825
        for content_type, mtype in wsgi._MEDIA_TYPE_MAP.items():
 
826
            request = wsgi.Request.blank('/tests/123')
 
827
            response = robj.serialize(request, content_type)
 
828
 
 
829
            self.assertEqual(response.headers['Content-Type'], content_type)
 
830
            self.assertEqual(response.headers['X-header1'], 'header1')
 
831
            self.assertEqual(response.headers['X-header2'], 'header2')
 
832
            self.assertEqual(response.status_int, 202)
 
833
            self.assertEqual(response.body, mtype)