~zulcss/cinder/cinder-ca-g2

« back to all changes in this revision

Viewing changes to cinder/tests/api/openstack/volume/test_volumes.py

  • Committer: Package Import Robot
  • Author(s): Chuck Short
  • Date: 2012-10-09 08:26:21 UTC
  • mfrom: (3.1.10 quantal)
  • Revision ID: package-import@ubuntu.com-20121009082621-stc86vcuyzyrp7ow
Tags: 2012.2-0ubuntu2
* debian/cinder_tgt.conf: Add missing configuration file. (LP: #1064366) 
* debian/README.Debian: Added note about migration from nova-volume
  to cinder-volume.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright 2013 Josh Durgin
 
2
# All Rights Reserved.
 
3
#
 
4
#    Licensed under the Apache License, Version 2.0 (the "License"); you may
 
5
#    not use this file except in compliance with the License. You may obtain
 
6
#    a copy of the License at
 
7
#
 
8
#         http://www.apache.org/licenses/LICENSE-2.0
 
9
#
 
10
#    Unless required by applicable law or agreed to in writing, software
 
11
#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 
12
#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 
13
#    License for the specific language governing permissions and limitations
 
14
#    under the License.
 
15
 
 
16
import datetime
 
17
 
 
18
from lxml import etree
 
19
import webob
 
20
 
 
21
from cinder.api.openstack.volume import volumes
 
22
from cinder import db
 
23
from cinder.api.openstack.volume import extensions
 
24
from cinder import exception
 
25
from cinder import flags
 
26
from cinder import test
 
27
from cinder.tests.api.openstack import fakes
 
28
from cinder.tests.image import fake as fake_image
 
29
from cinder.volume import api as volume_api
 
30
 
 
31
 
 
32
FLAGS = flags.FLAGS
 
33
NS = '{http://docs.openstack.org/volume/api/v1}'
 
34
 
 
35
TEST_SNAPSHOT_UUID = '00000000-0000-0000-0000-000000000001'
 
36
 
 
37
 
 
38
def stub_snapshot_get(self, context, snapshot_id):
 
39
    if snapshot_id != TEST_SNAPSHOT_UUID:
 
40
        raise exception.NotFound
 
41
 
 
42
    return {
 
43
            'id': snapshot_id,
 
44
            'volume_id': 12,
 
45
            'status': 'available',
 
46
            'volume_size': 100,
 
47
            'created_at': None,
 
48
            'display_name': 'Default name',
 
49
            'display_description': 'Default description',
 
50
            }
 
51
 
 
52
 
 
53
class VolumeApiTest(test.TestCase):
 
54
    def setUp(self):
 
55
        super(VolumeApiTest, self).setUp()
 
56
        self.ext_mgr = extensions.ExtensionManager()
 
57
        self.ext_mgr.extensions = {}
 
58
        fake_image.stub_out_image_service(self.stubs)
 
59
        self.controller = volumes.VolumeController(self.ext_mgr)
 
60
 
 
61
        self.stubs.Set(db, 'volume_get_all', fakes.stub_volume_get_all)
 
62
        self.stubs.Set(db, 'volume_get_all_by_project',
 
63
                       fakes.stub_volume_get_all_by_project)
 
64
        self.stubs.Set(volume_api.API, 'get', fakes.stub_volume_get)
 
65
        self.stubs.Set(volume_api.API, 'delete', fakes.stub_volume_delete)
 
66
 
 
67
    def test_volume_create(self):
 
68
        self.stubs.Set(volume_api.API, "create", fakes.stub_volume_create)
 
69
 
 
70
        vol = {"size": 100,
 
71
               "display_name": "Volume Test Name",
 
72
               "display_description": "Volume Test Desc",
 
73
               "availability_zone": "zone1:host1"}
 
74
        body = {"volume": vol}
 
75
        req = fakes.HTTPRequest.blank('/v1/volumes')
 
76
        res_dict = self.controller.create(req, body)
 
77
        expected = {'volume': {'status': 'fakestatus',
 
78
                               'display_description': 'Volume Test Desc',
 
79
                               'availability_zone': 'zone1:host1',
 
80
                               'display_name': 'Volume Test Name',
 
81
                               'attachments': [{'device': '/',
 
82
                                                'server_id': 'fakeuuid',
 
83
                                                'id': '1',
 
84
                                                'volume_id': '1'}],
 
85
                               'volume_type': 'vol_type_name',
 
86
                               'snapshot_id': None,
 
87
                               'metadata': {},
 
88
                               'id': '1',
 
89
                               'created_at': datetime.datetime(1, 1, 1,
 
90
                                                              1, 1, 1),
 
91
                               'size': 100}}
 
92
        self.assertEqual(res_dict, expected)
 
93
 
 
94
    def test_volume_creation_fails_with_bad_size(self):
 
95
        vol = {"size": '',
 
96
               "display_name": "Volume Test Name",
 
97
               "display_description": "Volume Test Desc",
 
98
               "availability_zone": "zone1:host1"}
 
99
        body = {"volume": vol}
 
100
        req = fakes.HTTPRequest.blank('/v1/volumes')
 
101
        self.assertRaises(exception.InvalidInput,
 
102
                          self.controller.create,
 
103
                          req,
 
104
                          body)
 
105
 
 
106
    def test_volume_create_with_image_id(self):
 
107
        self.stubs.Set(volume_api.API, "create", fakes.stub_volume_create)
 
108
        self.ext_mgr.extensions = {'os-image-create': 'fake'}
 
109
        vol = {"size": '1',
 
110
               "display_name": "Volume Test Name",
 
111
               "display_description": "Volume Test Desc",
 
112
               "availability_zone": "nova",
 
113
               "imageRef": 'c905cedb-7281-47e4-8a62-f26bc5fc4c77'}
 
114
        expected = {'volume': {'status': 'fakestatus',
 
115
                           'display_description': 'Volume Test Desc',
 
116
                           'availability_zone': 'nova',
 
117
                           'display_name': 'Volume Test Name',
 
118
                           'attachments': [{'device': '/',
 
119
                                            'server_id': 'fakeuuid',
 
120
                                            'id': '1',
 
121
                                            'volume_id': '1'}],
 
122
                            'volume_type': 'vol_type_name',
 
123
                            'image_id': 'c905cedb-7281-47e4-8a62-f26bc5fc4c77',
 
124
                            'snapshot_id': None,
 
125
                            'metadata': {},
 
126
                            'id': '1',
 
127
                            'created_at': datetime.datetime(1, 1, 1, 1, 1, 1),
 
128
                            'size': '1'}
 
129
                    }
 
130
        body = {"volume": vol}
 
131
        req = fakes.HTTPRequest.blank('/v1/volumes')
 
132
        res_dict = self.controller.create(req, body)
 
133
        self.assertEqual(res_dict, expected)
 
134
 
 
135
    def test_volume_create_with_image_id_and_snapshot_id(self):
 
136
        self.stubs.Set(volume_api.API, "create", fakes.stub_volume_create)
 
137
        self.stubs.Set(volume_api.API, "get_snapshot", stub_snapshot_get)
 
138
        self.ext_mgr.extensions = {'os-image-create': 'fake'}
 
139
        vol = {"size": '1',
 
140
                "display_name": "Volume Test Name",
 
141
                "display_description": "Volume Test Desc",
 
142
                "availability_zone": "cinder",
 
143
                "imageRef": 'c905cedb-7281-47e4-8a62-f26bc5fc4c77',
 
144
                "snapshot_id": TEST_SNAPSHOT_UUID}
 
145
        body = {"volume": vol}
 
146
        req = fakes.HTTPRequest.blank('/v1/volumes')
 
147
        self.assertRaises(webob.exc.HTTPBadRequest,
 
148
                          self.controller.create,
 
149
                          req,
 
150
                          body)
 
151
 
 
152
    def test_volume_create_with_image_id_is_integer(self):
 
153
        self.stubs.Set(volume_api.API, "create", fakes.stub_volume_create)
 
154
        self.ext_mgr.extensions = {'os-image-create': 'fake'}
 
155
        vol = {"size": '1',
 
156
                "display_name": "Volume Test Name",
 
157
                "display_description": "Volume Test Desc",
 
158
                "availability_zone": "cinder",
 
159
                "imageRef": 1234}
 
160
        body = {"volume": vol}
 
161
        req = fakes.HTTPRequest.blank('/v1/volumes')
 
162
        self.assertRaises(webob.exc.HTTPBadRequest,
 
163
                          self.controller.create,
 
164
                          req,
 
165
                          body)
 
166
 
 
167
    def test_volume_create_with_image_id_not_uuid_format(self):
 
168
        self.stubs.Set(volume_api.API, "create", fakes.stub_volume_create)
 
169
        self.ext_mgr.extensions = {'os-image-create': 'fake'}
 
170
        vol = {"size": '1',
 
171
                "display_name": "Volume Test Name",
 
172
                "display_description": "Volume Test Desc",
 
173
                "availability_zone": "cinder",
 
174
                "imageRef": '12345'}
 
175
        body = {"volume": vol}
 
176
        req = fakes.HTTPRequest.blank('/v1/volumes')
 
177
        self.assertRaises(webob.exc.HTTPBadRequest,
 
178
                          self.controller.create,
 
179
                          req,
 
180
                          body)
 
181
 
 
182
    def test_volume_list(self):
 
183
        self.stubs.Set(volume_api.API, 'get_all',
 
184
                       fakes.stub_volume_get_all_by_project)
 
185
 
 
186
        req = fakes.HTTPRequest.blank('/v1/volumes')
 
187
        res_dict = self.controller.index(req)
 
188
        expected = {'volumes': [{'status': 'fakestatus',
 
189
                                 'display_description': 'displaydesc',
 
190
                                 'availability_zone': 'fakeaz',
 
191
                                 'display_name': 'displayname',
 
192
                                 'attachments': [{'device': '/',
 
193
                                                  'server_id': 'fakeuuid',
 
194
                                                  'id': '1',
 
195
                                                  'volume_id': '1'}],
 
196
                                 'volume_type': 'vol_type_name',
 
197
                                 'snapshot_id': None,
 
198
                                 'metadata': {},
 
199
                                 'id': '1',
 
200
                                 'created_at': datetime.datetime(1, 1, 1,
 
201
                                                                1, 1, 1),
 
202
                                 'size': 1}]}
 
203
        self.assertEqual(res_dict, expected)
 
204
 
 
205
    def test_volume_list_detail(self):
 
206
        self.stubs.Set(volume_api.API, 'get_all',
 
207
                       fakes.stub_volume_get_all_by_project)
 
208
        req = fakes.HTTPRequest.blank('/v1/volumes/detail')
 
209
        res_dict = self.controller.index(req)
 
210
        expected = {'volumes': [{'status': 'fakestatus',
 
211
                                 'display_description': 'displaydesc',
 
212
                                 'availability_zone': 'fakeaz',
 
213
                                 'display_name': 'displayname',
 
214
                                 'attachments': [{'device': '/',
 
215
                                                  'server_id': 'fakeuuid',
 
216
                                                  'id': '1',
 
217
                                                  'volume_id': '1'}],
 
218
                                 'volume_type': 'vol_type_name',
 
219
                                 'snapshot_id': None,
 
220
                                 'metadata': {},
 
221
                                 'id': '1',
 
222
                                 'created_at': datetime.datetime(1, 1, 1,
 
223
                                                                1, 1, 1),
 
224
                                 'size': 1}]}
 
225
        self.assertEqual(res_dict, expected)
 
226
 
 
227
    def test_volume_list_by_name(self):
 
228
        def stub_volume_get_all_by_project(context, project_id):
 
229
            return [
 
230
                fakes.stub_volume(1, display_name='vol1'),
 
231
                fakes.stub_volume(2, display_name='vol2'),
 
232
                fakes.stub_volume(3, display_name='vol3'),
 
233
            ]
 
234
        self.stubs.Set(db, 'volume_get_all_by_project',
 
235
                       stub_volume_get_all_by_project)
 
236
 
 
237
        # no display_name filter
 
238
        req = fakes.HTTPRequest.blank('/v1/volumes')
 
239
        resp = self.controller.index(req)
 
240
        self.assertEqual(len(resp['volumes']), 3)
 
241
        # filter on display_name
 
242
        req = fakes.HTTPRequest.blank('/v1/volumes?display_name=vol2')
 
243
        resp = self.controller.index(req)
 
244
        self.assertEqual(len(resp['volumes']), 1)
 
245
        self.assertEqual(resp['volumes'][0]['display_name'], 'vol2')
 
246
        # filter no match
 
247
        req = fakes.HTTPRequest.blank('/v1/volumes?display_name=vol4')
 
248
        resp = self.controller.index(req)
 
249
        self.assertEqual(len(resp['volumes']), 0)
 
250
 
 
251
    def test_volume_list_by_status(self):
 
252
        def stub_volume_get_all_by_project(context, project_id):
 
253
            return [
 
254
                fakes.stub_volume(1, display_name='vol1', status='available'),
 
255
                fakes.stub_volume(2, display_name='vol2', status='available'),
 
256
                fakes.stub_volume(3, display_name='vol3', status='in-use'),
 
257
            ]
 
258
        self.stubs.Set(db, 'volume_get_all_by_project',
 
259
                       stub_volume_get_all_by_project)
 
260
        # no status filter
 
261
        req = fakes.HTTPRequest.blank('/v1/volumes')
 
262
        resp = self.controller.index(req)
 
263
        self.assertEqual(len(resp['volumes']), 3)
 
264
        # single match
 
265
        req = fakes.HTTPRequest.blank('/v1/volumes?status=in-use')
 
266
        resp = self.controller.index(req)
 
267
        self.assertEqual(len(resp['volumes']), 1)
 
268
        self.assertEqual(resp['volumes'][0]['status'], 'in-use')
 
269
        # multiple match
 
270
        req = fakes.HTTPRequest.blank('/v1/volumes?status=available')
 
271
        resp = self.controller.index(req)
 
272
        self.assertEqual(len(resp['volumes']), 2)
 
273
        for volume in resp['volumes']:
 
274
            self.assertEqual(volume['status'], 'available')
 
275
        # multiple filters
 
276
        req = fakes.HTTPRequest.blank('/v1/volumes?status=available&'
 
277
                                      'display_name=vol1')
 
278
        resp = self.controller.index(req)
 
279
        self.assertEqual(len(resp['volumes']), 1)
 
280
        self.assertEqual(resp['volumes'][0]['display_name'], 'vol1')
 
281
        self.assertEqual(resp['volumes'][0]['status'], 'available')
 
282
        # no match
 
283
        req = fakes.HTTPRequest.blank('/v1/volumes?status=in-use&'
 
284
                                      'display_name=vol1')
 
285
        resp = self.controller.index(req)
 
286
        self.assertEqual(len(resp['volumes']), 0)
 
287
 
 
288
    def test_volume_show(self):
 
289
        req = fakes.HTTPRequest.blank('/v1/volumes/1')
 
290
        res_dict = self.controller.show(req, '1')
 
291
        expected = {'volume': {'status': 'fakestatus',
 
292
                               'display_description': 'displaydesc',
 
293
                               'availability_zone': 'fakeaz',
 
294
                               'display_name': 'displayname',
 
295
                               'attachments': [{'device': '/',
 
296
                                                'server_id': 'fakeuuid',
 
297
                                                'id': '1',
 
298
                                                'volume_id': '1'}],
 
299
                               'volume_type': 'vol_type_name',
 
300
                               'snapshot_id': None,
 
301
                               'metadata': {},
 
302
                               'id': '1',
 
303
                               'created_at': datetime.datetime(1, 1, 1,
 
304
                                                              1, 1, 1),
 
305
                               'size': 1}}
 
306
        self.assertEqual(res_dict, expected)
 
307
 
 
308
    def test_volume_show_no_attachments(self):
 
309
        def stub_volume_get(self, context, volume_id):
 
310
            return fakes.stub_volume(volume_id, attach_status='detached')
 
311
 
 
312
        self.stubs.Set(volume_api.API, 'get', stub_volume_get)
 
313
 
 
314
        req = fakes.HTTPRequest.blank('/v1/volumes/1')
 
315
        res_dict = self.controller.show(req, '1')
 
316
        expected = {'volume': {'status': 'fakestatus',
 
317
                               'display_description': 'displaydesc',
 
318
                               'availability_zone': 'fakeaz',
 
319
                               'display_name': 'displayname',
 
320
                               'attachments': [],
 
321
                               'volume_type': 'vol_type_name',
 
322
                               'snapshot_id': None,
 
323
                               'metadata': {},
 
324
                               'id': '1',
 
325
                               'created_at': datetime.datetime(1, 1, 1,
 
326
                                                              1, 1, 1),
 
327
                               'size': 1}}
 
328
        self.assertEqual(res_dict, expected)
 
329
 
 
330
    def test_volume_show_no_volume(self):
 
331
        self.stubs.Set(volume_api.API, "get", fakes.stub_volume_get_notfound)
 
332
 
 
333
        req = fakes.HTTPRequest.blank('/v1/volumes/1')
 
334
        self.assertRaises(webob.exc.HTTPNotFound,
 
335
                          self.controller.show,
 
336
                          req,
 
337
                          1)
 
338
 
 
339
    def test_volume_delete(self):
 
340
        req = fakes.HTTPRequest.blank('/v1/volumes/1')
 
341
        resp = self.controller.delete(req, 1)
 
342
        self.assertEqual(resp.status_int, 202)
 
343
 
 
344
    def test_volume_delete_no_volume(self):
 
345
        self.stubs.Set(volume_api.API, "get", fakes.stub_volume_get_notfound)
 
346
 
 
347
        req = fakes.HTTPRequest.blank('/v1/volumes/1')
 
348
        self.assertRaises(webob.exc.HTTPNotFound,
 
349
                          self.controller.delete,
 
350
                          req,
 
351
                          1)
 
352
 
 
353
    def test_admin_list_volumes_limited_to_project(self):
 
354
        req = fakes.HTTPRequest.blank('/v1/fake/volumes',
 
355
                                      use_admin_context=True)
 
356
        res = self.controller.index(req)
 
357
 
 
358
        self.assertTrue('volumes' in res)
 
359
        self.assertEqual(1, len(res['volumes']))
 
360
 
 
361
    def test_admin_list_volumes_all_tenants(self):
 
362
        req = fakes.HTTPRequest.blank('/v1/fake/volumes?all_tenants=1',
 
363
                                      use_admin_context=True)
 
364
        res = self.controller.index(req)
 
365
        self.assertTrue('volumes' in res)
 
366
        self.assertEqual(3, len(res['volumes']))
 
367
 
 
368
    def test_all_tenants_non_admin_gets_all_tenants(self):
 
369
        req = fakes.HTTPRequest.blank('/v1/fake/volumes?all_tenants=1')
 
370
        res = self.controller.index(req)
 
371
        self.assertTrue('volumes' in res)
 
372
        self.assertEqual(1, len(res['volumes']))
 
373
 
 
374
    def test_non_admin_get_by_project(self):
 
375
        req = fakes.HTTPRequest.blank('/v1/fake/volumes')
 
376
        res = self.controller.index(req)
 
377
        self.assertTrue('volumes' in res)
 
378
        self.assertEqual(1, len(res['volumes']))
 
379
 
 
380
 
 
381
class VolumeSerializerTest(test.TestCase):
 
382
    def _verify_volume_attachment(self, attach, tree):
 
383
        for attr in ('id', 'volume_id', 'server_id', 'device'):
 
384
            self.assertEqual(str(attach[attr]), tree.get(attr))
 
385
 
 
386
    def _verify_volume(self, vol, tree):
 
387
        self.assertEqual(tree.tag, NS + 'volume')
 
388
 
 
389
        for attr in ('id', 'status', 'size', 'availability_zone', 'created_at',
 
390
                     'display_name', 'display_description', 'volume_type',
 
391
                     'snapshot_id'):
 
392
            self.assertEqual(str(vol[attr]), tree.get(attr))
 
393
 
 
394
        for child in tree:
 
395
            print child.tag
 
396
            self.assertTrue(child.tag in (NS + 'attachments', NS + 'metadata'))
 
397
            if child.tag == 'attachments':
 
398
                self.assertEqual(1, len(child))
 
399
                self.assertEqual('attachment', child[0].tag)
 
400
                self._verify_volume_attachment(vol['attachments'][0], child[0])
 
401
            elif child.tag == 'metadata':
 
402
                not_seen = set(vol['metadata'].keys())
 
403
                for gr_child in child:
 
404
                    self.assertTrue(gr_child.get("key") in not_seen)
 
405
                    self.assertEqual(str(vol['metadata'][gr_child.get("key")]),
 
406
                                     gr_child.text)
 
407
                    not_seen.remove(gr_child.get('key'))
 
408
                self.assertEqual(0, len(not_seen))
 
409
 
 
410
    def test_volume_show_create_serializer(self):
 
411
        serializer = volumes.VolumeTemplate()
 
412
        raw_volume = dict(
 
413
            id='vol_id',
 
414
            status='vol_status',
 
415
            size=1024,
 
416
            availability_zone='vol_availability',
 
417
            created_at=datetime.datetime.now(),
 
418
            attachments=[dict(
 
419
                    id='vol_id',
 
420
                    volume_id='vol_id',
 
421
                    server_id='instance_uuid',
 
422
                    device='/foo')],
 
423
            display_name='vol_name',
 
424
            display_description='vol_desc',
 
425
            volume_type='vol_type',
 
426
            snapshot_id='snap_id',
 
427
            metadata=dict(
 
428
                foo='bar',
 
429
                baz='quux',
 
430
                ),
 
431
            )
 
432
        text = serializer.serialize(dict(volume=raw_volume))
 
433
 
 
434
        print text
 
435
        tree = etree.fromstring(text)
 
436
 
 
437
        self._verify_volume(raw_volume, tree)
 
438
 
 
439
    def test_volume_index_detail_serializer(self):
 
440
        serializer = volumes.VolumesTemplate()
 
441
        raw_volumes = [dict(
 
442
                id='vol1_id',
 
443
                status='vol1_status',
 
444
                size=1024,
 
445
                availability_zone='vol1_availability',
 
446
                created_at=datetime.datetime.now(),
 
447
                attachments=[dict(
 
448
                        id='vol1_id',
 
449
                        volume_id='vol1_id',
 
450
                        server_id='instance_uuid',
 
451
                        device='/foo1')],
 
452
                display_name='vol1_name',
 
453
                display_description='vol1_desc',
 
454
                volume_type='vol1_type',
 
455
                snapshot_id='snap1_id',
 
456
                metadata=dict(
 
457
                    foo='vol1_foo',
 
458
                    bar='vol1_bar',
 
459
                    ),
 
460
                ),
 
461
                       dict(
 
462
                id='vol2_id',
 
463
                status='vol2_status',
 
464
                size=1024,
 
465
                availability_zone='vol2_availability',
 
466
                created_at=datetime.datetime.now(),
 
467
                attachments=[dict(
 
468
                        id='vol2_id',
 
469
                        volume_id='vol2_id',
 
470
                        server_id='instance_uuid',
 
471
                        device='/foo2')],
 
472
                display_name='vol2_name',
 
473
                display_description='vol2_desc',
 
474
                volume_type='vol2_type',
 
475
                snapshot_id='snap2_id',
 
476
                metadata=dict(
 
477
                    foo='vol2_foo',
 
478
                    bar='vol2_bar',
 
479
                    ),
 
480
                )]
 
481
        text = serializer.serialize(dict(volumes=raw_volumes))
 
482
 
 
483
        print text
 
484
        tree = etree.fromstring(text)
 
485
 
 
486
        self.assertEqual(NS + 'volumes', tree.tag)
 
487
        self.assertEqual(len(raw_volumes), len(tree))
 
488
        for idx, child in enumerate(tree):
 
489
            self._verify_volume(raw_volumes[idx], child)
 
490
 
 
491
 
 
492
class TestVolumeCreateRequestXMLDeserializer(test.TestCase):
 
493
 
 
494
    def setUp(self):
 
495
        super(TestVolumeCreateRequestXMLDeserializer, self).setUp()
 
496
        self.deserializer = volumes.CreateDeserializer()
 
497
 
 
498
    def test_minimal_volume(self):
 
499
        self_request = """
 
500
<volume xmlns="http://docs.openstack.org/compute/api/v1.1"
 
501
        size="1"></volume>"""
 
502
        request = self.deserializer.deserialize(self_request)
 
503
        expected = {
 
504
            "volume": {
 
505
                    "size": "1",
 
506
            },
 
507
        }
 
508
        self.assertEquals(request['body'], expected)
 
509
 
 
510
    def test_display_name(self):
 
511
        self_request = """
 
512
<volume xmlns="http://docs.openstack.org/compute/api/v1.1"
 
513
        size="1"
 
514
        display_name="Volume-xml"></volume>"""
 
515
        request = self.deserializer.deserialize(self_request)
 
516
        expected = {
 
517
            "volume": {
 
518
                "size": "1",
 
519
                "display_name": "Volume-xml",
 
520
            },
 
521
        }
 
522
        self.assertEquals(request['body'], expected)
 
523
 
 
524
    def test_display_description(self):
 
525
        self_request = """
 
526
<volume xmlns="http://docs.openstack.org/compute/api/v1.1"
 
527
        size="1"
 
528
        display_name="Volume-xml"
 
529
        display_description="description"></volume>"""
 
530
        request = self.deserializer.deserialize(self_request)
 
531
        expected = {
 
532
            "volume": {
 
533
                "size": "1",
 
534
                "display_name": "Volume-xml",
 
535
                "display_description": "description",
 
536
            },
 
537
        }
 
538
        self.assertEquals(request['body'], expected)
 
539
 
 
540
    def test_volume_type(self):
 
541
        self_request = """
 
542
<volume xmlns="http://docs.openstack.org/compute/api/v1.1"
 
543
        size="1"
 
544
        display_name="Volume-xml"
 
545
        display_description="description"
 
546
        volume_type="289da7f8-6440-407c-9fb4-7db01ec49164"></volume>"""
 
547
        request = self.deserializer.deserialize(self_request)
 
548
        expected = {
 
549
            "volume": {
 
550
                "display_name": "Volume-xml",
 
551
                "size": "1",
 
552
                "display_name": "Volume-xml",
 
553
                "display_description": "description",
 
554
                "volume_type": "289da7f8-6440-407c-9fb4-7db01ec49164",
 
555
            },
 
556
        }
 
557
        self.assertEquals(request['body'], expected)
 
558
 
 
559
    def test_availability_zone(self):
 
560
        self_request = """
 
561
<volume xmlns="http://docs.openstack.org/compute/api/v1.1"
 
562
        size="1"
 
563
        display_name="Volume-xml"
 
564
        display_description="description"
 
565
        volume_type="289da7f8-6440-407c-9fb4-7db01ec49164"
 
566
        availability_zone="us-east1"></volume>"""
 
567
        request = self.deserializer.deserialize(self_request)
 
568
        expected = {
 
569
            "volume": {
 
570
                "size": "1",
 
571
                "display_name": "Volume-xml",
 
572
                "display_description": "description",
 
573
                "volume_type": "289da7f8-6440-407c-9fb4-7db01ec49164",
 
574
                "availability_zone": "us-east1",
 
575
            },
 
576
        }
 
577
        self.assertEquals(request['body'], expected)
 
578
 
 
579
    def test_metadata(self):
 
580
        self_request = """
 
581
<volume xmlns="http://docs.openstack.org/compute/api/v1.1"
 
582
        display_name="Volume-xml"
 
583
        size="1">
 
584
        <metadata><meta key="Type">work</meta></metadata></volume>"""
 
585
        request = self.deserializer.deserialize(self_request)
 
586
        expected = {
 
587
            "volume": {
 
588
                "display_name": "Volume-xml",
 
589
                "size": "1",
 
590
                "metadata": {
 
591
                    "Type": "work",
 
592
                },
 
593
            },
 
594
        }
 
595
        self.assertEquals(request['body'], expected)
 
596
 
 
597
    def test_full_volume(self):
 
598
        self_request = """
 
599
<volume xmlns="http://docs.openstack.org/compute/api/v1.1"
 
600
        size="1"
 
601
        display_name="Volume-xml"
 
602
        display_description="description"
 
603
        volume_type="289da7f8-6440-407c-9fb4-7db01ec49164"
 
604
        availability_zone="us-east1">
 
605
        <metadata><meta key="Type">work</meta></metadata></volume>"""
 
606
        request = self.deserializer.deserialize(self_request)
 
607
        expected = {
 
608
            "volume": {
 
609
                "size": "1",
 
610
                "display_name": "Volume-xml",
 
611
                "display_description": "description",
 
612
                "volume_type": "289da7f8-6440-407c-9fb4-7db01ec49164",
 
613
                "availability_zone": "us-east1",
 
614
                "metadata": {
 
615
                    "Type": "work",
 
616
                },
 
617
            },
 
618
        }
 
619
        self.assertEquals(request['body'], expected)
 
620
 
 
621
 
 
622
class VolumesUnprocessableEntityTestCase(test.TestCase):
 
623
 
 
624
    """
 
625
    Tests of places we throw 422 Unprocessable Entity from
 
626
    """
 
627
 
 
628
    def setUp(self):
 
629
        super(VolumesUnprocessableEntityTestCase, self).setUp()
 
630
        self.ext_mgr = extensions.ExtensionManager()
 
631
        self.ext_mgr.extensions = {}
 
632
        self.controller = volumes.VolumeController(self.ext_mgr)
 
633
 
 
634
    def _unprocessable_volume_create(self, body):
 
635
        req = fakes.HTTPRequest.blank('/v2/fake/volumes')
 
636
        req.method = 'POST'
 
637
 
 
638
        self.assertRaises(webob.exc.HTTPUnprocessableEntity,
 
639
                          self.controller.create, req, body)
 
640
 
 
641
    def test_create_no_body(self):
 
642
        self._unprocessable_volume_create(body=None)
 
643
 
 
644
    def test_create_missing_volume(self):
 
645
        body = {'foo': {'a': 'b'}}
 
646
        self._unprocessable_volume_create(body=body)
 
647
 
 
648
    def test_create_malformed_entity(self):
 
649
        body = {'volume': 'string'}
 
650
        self._unprocessable_volume_create(body=body)