Merge "Add the ability to update type public status"

This commit is contained in:
Jenkins 2015-08-30 09:19:27 +00:00 committed by Gerrit Code Review
commit 0a3f0232d1
7 changed files with 76 additions and 54 deletions
cinder

@ -112,6 +112,7 @@ class VolumeTypesManageController(wsgi.Controller):
vol_type = body['volume_type']
description = vol_type.get('description')
name = vol_type.get('name')
is_public = vol_type.get('is_public')
# Name and description can not be both None.
# If name specified, name can not be empty.
@ -123,6 +124,11 @@ class VolumeTypesManageController(wsgi.Controller):
msg = _("Specify either volume type name and/or description.")
raise webob.exc.HTTPBadRequest(explanation=msg)
if is_public is not None and not utils.is_valid_boolstr(is_public):
msg = _("Invalid value '%s' for is_public. Accepted values: "
"True or False.") % is_public
raise webob.exc.HTTPBadRequest(explanation=msg)
if name:
utils.check_string_length(name, 'Type name',
min_length=1, max_length=255)
@ -132,7 +138,8 @@ class VolumeTypesManageController(wsgi.Controller):
min_length=0, max_length=255)
try:
volume_types.update(context, id, name, description)
volume_types.update(context, id, name, description,
is_public=is_public)
# Get the updated
vol_type = volume_types.get_volume_type(context, id)
req.cache_resource(vol_type, name='types')

@ -22,6 +22,7 @@ class ViewBuilder(common.ViewBuilder):
"""Trim away extraneous volume type attributes."""
trimmed = dict(id=volume_type.get('id'),
name=volume_type.get('name'),
is_public=volume_type.get('is_public'),
extra_specs=volume_type.get('extra_specs'),
description=volume_type.get('description'))
return trimmed if brief else dict(volume_type=trimmed)

@ -2436,6 +2436,10 @@ def volume_type_update(context, volume_type_id, values):
if values['description'] is None:
del values['description']
# No is_public change
if values['is_public'] is None:
del values['is_public']
# No name change
if values['name'] is None:
del values['name']

@ -36,9 +36,10 @@ def stub_volume_type(id):
extra_specs=specs)
def stub_volume_type_updated(id):
def stub_volume_type_updated(id, is_public=True):
return dict(id=id,
name='vol_type_%s_%s' % (six.text_type(id), six.text_type(id)),
is_public=is_public,
description='vol_type_desc_%s_%s' % (
six.text_type(id), six.text_type(id)))
@ -84,14 +85,6 @@ def return_volume_types_create_duplicate_type(context,
raise exception.VolumeTypeExists(id=name)
def return_volume_types_update(context, id, name, description):
pass
def return_volume_types_update_fail(context, id, name, description):
raise exception.VolumeTypeUpdateFailed(id=id)
def stub_volume_type_updated_name_only(id):
return dict(id=id,
name='vol_type_%s_%s' % (six.text_type(id), six.text_type(id)),
@ -104,11 +97,7 @@ def stub_volume_type_updated_name_after_delete(id):
description='vol_type_desc_%s' % six.text_type(id))
def return_volume_types_update_exist(context, id, name, description):
raise exception.VolumeTypeExists(id=id, name=name)
def return_volume_types_get_volume_type_updated(context, id):
def return_volume_types_get_volume_type_updated(id, is_public=True):
if id == "777":
raise exception.VolumeTypeNotFound(volume_type_id=id)
if id == '888':
@ -119,7 +108,7 @@ def return_volume_types_get_volume_type_updated(context, id):
return stub_volume_type_updated_name_after_delete(int(id))
# anything else
return stub_volume_type_updated(int(id))
return stub_volume_type_updated(int(id), is_public=is_public)
def return_volume_types_get_by_name(context, name):
@ -273,14 +262,15 @@ class VolumeTypesManageApiTest(test.TestCase):
body = {'volume_type': 'string'}
self._create_volume_type_bad_body(body=body)
def test_update(self):
self.stubs.Set(volume_types, 'update',
return_volume_types_update)
self.stubs.Set(volume_types, 'get_volume_type',
return_volume_types_get_volume_type_updated)
@mock.patch('cinder.volume.volume_types.update')
@mock.patch('cinder.volume.volume_types.get_volume_type')
def test_update(self, mock_get, mock_update):
mock_get.return_value = return_volume_types_get_volume_type_updated(
'1', is_public=False)
body = {"volume_type": {"name": "vol_type_1_1",
"description": "vol_type_desc_1_1"}}
"description": "vol_type_desc_1_1",
"is_public": False}}
req = fakes.HTTPRequest.blank('/v2/fake/types/1')
req.method = 'PUT'
@ -289,7 +279,8 @@ class VolumeTypesManageApiTest(test.TestCase):
self.assertEqual(1, len(self.notifier.notifications))
self._check_test_results(res_dict,
{'expected_desc': 'vol_type_desc_1_1',
'expected_name': 'vol_type_1_1'})
'expected_name': 'vol_type_1_1',
'is_public': False})
@mock.patch('cinder.volume.volume_types.update')
@mock.patch('cinder.volume.volume_types.get_volume_type')
@ -325,11 +316,11 @@ class VolumeTypesManageApiTest(test.TestCase):
self.assertRaises(exception.InvalidInput,
self.controller._update, req, '1', body)
def test_update_non_exist(self):
self.stubs.Set(volume_types, 'update',
return_volume_types_update)
self.stubs.Set(volume_types, 'get_volume_type',
return_volume_types_get_volume_type)
@mock.patch('cinder.volume.volume_types.get_volume_type')
@mock.patch('cinder.volume.volume_types.update')
def test_update_non_exist(self, mock_update, mock_get_volume_type):
mock_get_volume_type.side_effect = exception.VolumeTypeNotFound(
volume_type_id=777)
body = {"volume_type": {"name": "vol_type_1_1",
"description": "vol_type_desc_1_1"}}
@ -341,11 +332,11 @@ class VolumeTypesManageApiTest(test.TestCase):
self.controller._update, req, '777', body)
self.assertEqual(1, len(self.notifier.notifications))
def test_update_db_fail(self):
self.stubs.Set(volume_types, 'update',
return_volume_types_update_fail)
self.stubs.Set(volume_types, 'get_volume_type',
return_volume_types_get_volume_type)
@mock.patch('cinder.volume.volume_types.get_volume_type')
@mock.patch('cinder.volume.volume_types.update')
def test_update_db_fail(self, mock_update, mock_get_volume_type):
mock_update.side_effect = exception.VolumeTypeUpdateFailed(id='1')
mock_get_volume_type.return_value = stub_volume_type(1)
body = {"volume_type": {"name": "vol_type_1_1",
"description": "vol_type_desc_1_1"}}
@ -374,11 +365,11 @@ class VolumeTypesManageApiTest(test.TestCase):
self.assertRaises(webob.exc.HTTPBadRequest,
self.controller._update, req, '1', body)
def test_update_only_name(self):
self.stubs.Set(volume_types, 'update',
return_volume_types_update)
self.stubs.Set(volume_types, 'get_volume_type',
return_volume_types_get_volume_type_updated)
@mock.patch('cinder.volume.volume_types.update')
@mock.patch('cinder.volume.volume_types.get_volume_type')
def test_update_only_name(self, mock_get, mock_update):
mock_get.return_value = return_volume_types_get_volume_type_updated(
'999')
body = {"volume_type": {"name": "vol_type_999_999"}}
req = fakes.HTTPRequest.blank('/v2/fake/types/999')
@ -391,11 +382,11 @@ class VolumeTypesManageApiTest(test.TestCase):
{'expected_name': 'vol_type_999_999',
'expected_desc': 'vol_type_desc_999'})
def test_update_only_description(self):
self.stubs.Set(volume_types, 'update',
return_volume_types_update)
self.stubs.Set(volume_types, 'get_volume_type',
return_volume_types_get_volume_type_updated)
@mock.patch('cinder.volume.volume_types.update')
@mock.patch('cinder.volume.volume_types.get_volume_type')
def test_update_only_description(self, mock_get, mock_update):
mock_get.return_value = return_volume_types_get_volume_type_updated(
'888')
body = {"volume_type": {"description": "vol_type_desc_888_888"}}
req = fakes.HTTPRequest.blank('/v2/fake/types/888')
@ -408,11 +399,23 @@ class VolumeTypesManageApiTest(test.TestCase):
{'expected_name': 'vol_type_888',
'expected_desc': 'vol_type_desc_888_888'})
def test_rename_existing_name(self):
self.stubs.Set(volume_types, 'update',
return_volume_types_update_exist)
self.stubs.Set(volume_types, 'get_volume_type',
return_volume_types_get_volume_type_updated)
def test_update_invalid_is_public(self):
body = {"volume_type": {"name": "test",
"description": "something",
"is_public": "fake"}}
req = fakes.HTTPRequest.blank('/v2/fake/types/1')
req.method = 'PUT'
self.assertRaises(webob.exc.HTTPBadRequest,
self.controller._update, req, '1', body)
@mock.patch('cinder.volume.volume_types.update')
@mock.patch('cinder.volume.volume_types.get_volume_type')
def test_rename_existing_name(self, mock_get, mock_update):
mock_update.side_effect = exception.VolumeTypeExists(
id="666", name="vol_type_666")
mock_get.return_value = return_volume_types_get_volume_type_updated(
'666')
# first attempt fail
body = {"volume_type": {"name": "vol_type_666"}}
req = fakes.HTTPRequest.blank('/v2/fake/types/666')
@ -434,10 +437,7 @@ class VolumeTypesManageApiTest(test.TestCase):
self.assertEqual(1, len(self.notifier.notifications))
# update again
self.stubs.Set(volume_types, 'update',
return_volume_types_update)
self.stubs.Set(volume_types, 'get_volume_type',
return_volume_types_get_volume_type_updated)
mock_update.side_effect = mock.MagicMock()
body = {"volume_type": {"name": "vol_type_666_666"}}
req = fakes.HTTPRequest.blank('/v2/fake/types/666')
req.method = 'PUT'
@ -457,3 +457,6 @@ class VolumeTypesManageApiTest(test.TestCase):
if expected_results.get('expected_name'):
self.assertEqual(expected_results['expected_name'],
results['volume_type']['name'])
if expected_results.get('is_public') is not None:
self.assertEqual(expected_results['is_public'],
results['volume_type']['is_public'])

@ -128,6 +128,7 @@ class VolumeTypesApiTest(test.TestCase):
expected_volume_type = dict(name='new_type',
extra_specs={},
description=None,
is_public=None,
id=42)
self.assertDictMatch(output['volume_type'], expected_volume_type)
@ -154,6 +155,7 @@ class VolumeTypesApiTest(test.TestCase):
expected_volume_type = dict(name='new_type',
extra_specs={},
id=42 + i,
is_public=None,
description=None)
self.assertDictMatch(output['volume_types'][i],
expected_volume_type)

@ -153,6 +153,7 @@ class VolumeTypesApiTest(test.TestCase):
raw_volume_type = dict(
name='new_type',
description='new_type_desc',
is_public=True,
deleted=False,
created_at=now,
updated_at=now,
@ -168,6 +169,7 @@ class VolumeTypesApiTest(test.TestCase):
expected_volume_type = dict(
name='new_type',
description='new_type_desc',
is_public=True,
extra_specs={},
id=42,
)
@ -183,6 +185,7 @@ class VolumeTypesApiTest(test.TestCase):
dict(
name='new_type',
description='new_type_desc',
is_public=True,
deleted=False,
created_at=now,
updated_at=now,
@ -200,6 +203,7 @@ class VolumeTypesApiTest(test.TestCase):
expected_volume_type = dict(
name='new_type',
description='new_type_desc',
is_public=True,
extra_specs={},
id=42 + i
)

@ -57,7 +57,7 @@ def create(context,
return type_ref
def update(context, id, name, description):
def update(context, id, name, description, is_public=None):
"""Update volume type by id."""
if id is None:
msg = _("id cannot be None")
@ -66,7 +66,8 @@ def update(context, id, name, description):
type_updated = db.volume_type_update(context,
id,
dict(name=name,
description=description))
description=description,
is_public=is_public))
except db_exc.DBError:
LOG.exception(_LE('DB error:'))
raise exception.VolumeTypeUpdateFailed(id=id)