~ubuntu-branches/ubuntu/raring/nova/raring

« back to all changes in this revision

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

  • Committer: Package Import Robot
  • Author(s): Chuck Short, Adam Gandelman, Chuck Short
  • Date: 2012-11-23 09:04:58 UTC
  • mfrom: (1.1.66)
  • Revision ID: package-import@ubuntu.com-20121123090458-91565o7aev1i1h71
Tags: 2013.1~g1-0ubuntu1
[ Adam Gandelman ]
* debian/control: Ensure novaclient is upgraded with nova,
  require python-keystoneclient >= 1:2.9.0. (LP: #1073289)
* debian/patches/{ubuntu/*, rbd-security.patch}: Dropped, applied
  upstream.
* debian/control: Add python-testtools to Build-Depends.

[ Chuck Short ]
* New upstream version.
* Refreshed debian/patches/avoid_setuptools_git_dependency.patch.
* debian/rules: FTBFS if missing binaries.
* debian/nova-scheudler.install: Add missing rabbit-queues and
  nova-rpc-zmq-receiver.
* Remove nova-volume since it doesnt exist anymore, transition to cinder-*.
* debian/rules: install apport hook in the right place.
* debian/patches/ubuntu-show-tests.patch: Display test failures.
* debian/control: Add depends on genisoimage
* debian/control: Suggest guestmount.
* debian/control: Suggest websockify. (LP: #1076442)
* debian/nova.conf: Disable nova-volume service.
* debian/control: Depend on xen-system-* rather than the hypervisor.
* debian/control, debian/mans/nova-conductor.8, debian/nova-conductor.init,
  debian/nova-conductor.install, debian/nova-conductor.logrotate
  debian/nova-conductor.manpages, debian/nova-conductor.postrm
  debian/nova-conductor.upstart.in: Add nova-conductor service.
* debian/control: Add python-fixtures as a build deps.

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