Changes block_device_mapping extension into v2.1

This patch changes v3 block_device_mapping API to v2.1 and make
unittest share between v2 and v2.1

The differences between v2 and v3 are described on the wiki page
https://wiki.openstack.org/wiki/NovaAPIv2tov3.

Partially implements blueprint v2-on-v3-api

Change-Id: I935b336523241a32dbd2bb8b154ce72afefd3aa9
This commit is contained in:
He Jie Xu
2014-08-19 12:43:59 +08:00
parent 62a8e4e47d
commit e2fd04e281
4 changed files with 49 additions and 126 deletions
@@ -22,7 +22,7 @@ from nova import block_device
from nova import exception
ALIAS = "os-block-device-mapping"
ATTRIBUTE_NAME = "%s:block_device_mapping" % ALIAS
ATTRIBUTE_NAME = "block_device_mapping_v2"
class BlockDeviceMapping(extensions.V3APIExtensionBase):
@@ -545,7 +545,8 @@ class ServersController(wsgi.Controller):
exception.SecurityGroupNotFound,
exception.PortRequiresFixedIP,
exception.NetworkRequiresSubnet,
exception.NetworkNotFound) as error:
exception.NetworkNotFound,
exception.InvalidBDMVolumeNotBootable) as error:
raise exc.HTTPBadRequest(explanation=error.format_message())
except (exception.PortInUse,
exception.NetworkAmbiguous,
@@ -18,9 +18,11 @@ import mox
from oslo.config import cfg
from webob import exc
from nova.api.openstack.compute import extensions
from nova.api.openstack.compute import plugins
from nova.api.openstack.compute.plugins.v3 import block_device_mapping
from nova.api.openstack.compute.plugins.v3 import servers
from nova.api.openstack.compute.plugins.v3 import servers as servers_v3
from nova.api.openstack.compute import servers as servers_v2
from nova import block_device
from nova.compute import api as compute_api
from nova import exception
@@ -33,19 +35,20 @@ from nova.tests import matchers
CONF = cfg.CONF
class BlockDeviceMappingTest(test.TestCase):
def setUp(self):
super(BlockDeviceMappingTest, self).setUp()
class BlockDeviceMappingTestV21(test.TestCase):
def _setup_controller(self):
ext_info = plugins.LoadedExtensionInfo()
self.controller = servers.ServersController(extension_info=ext_info)
self.controller = servers_v3.ServersController(extension_info=ext_info)
CONF.set_override('extensions_blacklist', 'os-block-device-mapping',
'osapi_v3')
self.no_volumes_controller = servers.ServersController(
extension_info=ext_info)
self.no_bdm_v2_controller = servers_v3.ServersController(
extension_info=ext_info)
CONF.set_override('extensions_blacklist', '', 'osapi_v3')
def setUp(self):
super(BlockDeviceMappingTestV21, self).setUp()
self._setup_controller()
fake.stub_out_image_service(self.stubs)
self.bdm = [{
@@ -57,7 +60,7 @@ class BlockDeviceMappingTest(test.TestCase):
'delete_on_termination': False,
}]
def _test_create(self, params, no_image=False, override_controller=None):
def _get_servers_body(self, no_image=False):
body = {
'server': {
'min_count': 2,
@@ -70,10 +73,12 @@ class BlockDeviceMappingTest(test.TestCase):
},
},
}
if no_image:
del body['server']['imageRef']
return body
def _test_create(self, params, no_image=False, override_controller=None):
body = self._get_servers_body(no_image)
body['server'].update(params)
req = fakes.HTTPRequestV3.blank('/servers')
@@ -100,7 +105,7 @@ class BlockDeviceMappingTest(test.TestCase):
params = {block_device_mapping.ATTRIBUTE_NAME: bdm}
self._test_create(params,
override_controller=self.no_volumes_controller)
override_controller=self.no_bdm_v2_controller)
def test_create_instance_with_volumes_enabled_no_image(self):
"""Test that the create will fail if there is no image
@@ -281,14 +286,35 @@ class BlockDeviceMappingTest(test.TestCase):
@mock.patch('nova.compute.api.API._get_bdm_image_metadata')
def test_create_instance_non_bootable_volume_fails(self, fake_bdm_meta):
bdm = [{
'id': 1,
'bootable': False,
'volume_id': '1',
'status': 'active',
'device_name': 'vda',
}]
params = {'block_device_mapping': bdm}
params = {block_device_mapping.ATTRIBUTE_NAME: self.bdm}
fake_bdm_meta.side_effect = exception.InvalidBDMVolumeNotBootable(id=1)
self.assertRaises(exc.HTTPBadRequest, self._test_create, params,
no_image=True)
class BlockDeviceMappingTestV2(BlockDeviceMappingTestV21):
def _setup_controller(self):
self.ext_mgr = extensions.ExtensionManager()
self.ext_mgr.extensions = {'os-volumes': 'fake',
'os-block-device-mapping-v2-boot': 'fake'}
self.controller = servers_v2.Controller(self.ext_mgr)
self.ext_mgr_bdm_v2 = extensions.ExtensionManager()
self.ext_mgr_bdm_v2.extensions = {'os-volumes': 'fake'}
self.no_bdm_v2_controller = servers_v2.Controller(
self.ext_mgr_bdm_v2)
def test_create_instance_with_block_device_mapping_disabled(self):
bdm = [{'device_name': 'foo'}]
old_create = compute_api.API.create
def create(*args, **kwargs):
self.assertIsNone(kwargs['block_device_mapping'], None)
return old_create(*args, **kwargs)
self.stubs.Set(compute_api.API, 'create', create)
params = {block_device_mapping.ATTRIBUTE_NAME: bdm}
self._test_create(params,
override_controller=self.no_bdm_v2_controller)
@@ -35,7 +35,6 @@ from nova.api.openstack.compute import servers
from nova.api.openstack.compute import views
from nova.api.openstack import extensions
from nova.api.openstack import xmlutil
from nova import block_device
from nova.compute import api as compute_api
from nova.compute import flavors
from nova.compute import task_states
@@ -2680,41 +2679,6 @@ class ServersControllerCreateTest(test.TestCase):
self.mox.ReplayAll()
self._test_create_extra(params, no_image=True)
def test_create_instance_with_bdm_v2_enabled_and_bdms_no_image(self):
self.ext_mgr.extensions = {
'os-volumes': 'fake',
'os-block-device-mapping-v2-boot': 'fake'}
bdm_v2 = [{
'no_device': None,
'source_type': 'volume',
'destination_type': 'volume',
'uuid': self.volume_id,
'device_name': 'vda',
'delete_on_termination': False,
}]
params = {'block_device_mapping_v2': bdm_v2}
old_create = compute_api.API.create
def create(*args, **kwargs):
self.assertThat(block_device.BlockDeviceDict(bdm_v2[0]),
matchers.DictMatches(
kwargs['block_device_mapping'][0]))
self.assertNotIn('imageRef', kwargs)
return old_create(*args, **kwargs)
self.mox.StubOutWithMock(compute_api.API, '_validate_bdm')
self.mox.StubOutWithMock(compute_api.API, '_get_bdm_image_metadata')
compute_api.API._validate_bdm(
mox.IgnoreArg(), mox.IgnoreArg(),
mox.IgnoreArg(), mox.IgnoreArg()).AndReturn(True)
compute_api.API._get_bdm_image_metadata(
mox.IgnoreArg(), mox.IgnoreArg(), False).AndReturn({})
self.mox.ReplayAll()
self.stubs.Set(compute_api.API, 'create', create)
self._test_create_extra(params, no_image=True)
def test_create_instance_with_volumes_disabled(self):
bdm = [{'device_name': 'foo'}]
params = {'block_device_mapping': bdm}
@@ -2817,7 +2781,7 @@ class ServersControllerCreateTest(test.TestCase):
def test_create_instance_bdm_api_validation_fails(self):
self.ext_mgr.extensions = {'os-volumes': 'fake',
'os-block-device-mapping-v2-boot': 'fake'}
'os-block-devic-emapping-v2-boot': 'fake'}
bdm = {'delete_on_termination': 1,
'device_name': 'vda',
'source_type': 'volume',
@@ -2893,33 +2857,6 @@ class ServersControllerCreateTest(test.TestCase):
self.stubs.Set(compute_api.API, '_validate_bdm', _validate_bdm)
self._test_create_extra(params)
def test_create_instance_bdm_v2(self):
self.ext_mgr.extensions = {'os-volumes': 'fake',
'os-block-device-mapping-v2-boot': 'fake'}
bdm_v2 = [{'source_type': 'volume',
'device_name': 'fake_dev',
'uuid': 'fake_vol'}]
bdm_v2_expected = [{'source_type': 'volume',
'device_name': 'fake_dev',
'volume_id': 'fake_vol'}]
params = {'block_device_mapping_v2': bdm_v2}
old_create = compute_api.API.create
def create(*args, **kwargs):
self.assertFalse(kwargs['legacy_bdm'])
for expected, received in zip(bdm_v2_expected,
kwargs['block_device_mapping']):
self.assertThat(block_device.BlockDeviceDict(expected),
matchers.DictMatches(received))
return old_create(*args, **kwargs)
def _validate_bdm(*args, **kwargs):
pass
self.stubs.Set(compute_api.API, 'create', create)
self.stubs.Set(compute_api.API, '_validate_bdm', _validate_bdm)
self._test_create_extra(params)
def test_create_instance_decide_format_legacy(self):
self.ext_mgr.extensions = {'os-volumes': 'fake',
'os-block-device-mapping-v2-boot': 'fake'}
@@ -2947,32 +2884,6 @@ class ServersControllerCreateTest(test.TestCase):
params = {'block_device_mapping': bdm}
self._test_create_extra(params)
def test_create_instance_decide_format_new(self):
self.ext_mgr.extensions = {'os-volumes': 'fake',
'os-block-device-mapping-v2-boot': 'fake'}
bdm_v2 = [{'source_type': 'volume',
'device_name': 'fake_dev',
'uuid': 'fake_vol'}]
old_create = compute_api.API.create
expected_legacy_flag = False
def create(*args, **kwargs):
self.assertEqual(kwargs['legacy_bdm'], expected_legacy_flag)
return old_create(*args, **kwargs)
def _validate_bdm(*args, **kwargs):
pass
self.stubs.Set(compute_api.API, 'create', create)
self.stubs.Set(compute_api.API, '_validate_bdm',
_validate_bdm)
params = {'block_device_mapping_v2': bdm_v2}
self._test_create_extra(params)
def test_create_instance_both_bdm_formats(self):
self.ext_mgr.extensions = {'os-volumes': 'fake',
'os-block-device-mapping-v2-boot': 'fake'}
@@ -2985,21 +2896,6 @@ class ServersControllerCreateTest(test.TestCase):
self.assertRaises(webob.exc.HTTPBadRequest,
self._test_create_extra, params)
def test_create_instance_bdm_v2_validation_error(self):
self.ext_mgr.extensions = {'os-volumes': 'fake',
'os-block-device-mapping-v2-boot': 'fake'}
bdm_v2 = [{'device_name': 'bogus device'}]
params = {'block_device_mapping_v2': bdm_v2}
def _validate(*args, **kwargs):
raise exception.InvalidBDMFormat()
self.stubs.Set(block_device.BlockDeviceDict,
'_validate', _validate)
self.assertRaises(webob.exc.HTTPBadRequest,
self._test_create_extra, params)
def test_create_instance_with_user_data_enabled(self):
self.ext_mgr.extensions = {'os-user-data': 'fake'}
user_data = 'fake'