some cosmetic changes. Prior to merge proposal
This commit is contained in:
parent
10006a7717
commit
fb755ae05b
185
nova/tests/test_vsa.py
Normal file
185
nova/tests/test_vsa.py
Normal file
@ -0,0 +1,185 @@
|
|||||||
|
# Copyright 2011 OpenStack LLC.
|
||||||
|
# All Rights Reserved.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
# a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
|
||||||
|
import stubout
|
||||||
|
import base64
|
||||||
|
|
||||||
|
from xml.etree import ElementTree
|
||||||
|
from xml.etree.ElementTree import Element, SubElement
|
||||||
|
|
||||||
|
from nova import exception
|
||||||
|
from nova import flags
|
||||||
|
from nova import vsa
|
||||||
|
from nova import db
|
||||||
|
from nova import context
|
||||||
|
from nova import test
|
||||||
|
from nova import log as logging
|
||||||
|
import nova.image.fake
|
||||||
|
|
||||||
|
FLAGS = flags.FLAGS
|
||||||
|
LOG = logging.getLogger('nova.tests.vsa')
|
||||||
|
|
||||||
|
|
||||||
|
def fake_drive_type_get_by_name(context, name):
|
||||||
|
drive_type = {
|
||||||
|
'id': 1,
|
||||||
|
'name': name,
|
||||||
|
'type': name.split('_')[0],
|
||||||
|
'size_gb': int(name.split('_')[1]),
|
||||||
|
'rpm': name.split('_')[2],
|
||||||
|
'capabilities': '',
|
||||||
|
'visible': True}
|
||||||
|
return drive_type
|
||||||
|
|
||||||
|
|
||||||
|
class VsaTestCase(test.TestCase):
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
super(VsaTestCase, self).setUp()
|
||||||
|
self.stubs = stubout.StubOutForTesting()
|
||||||
|
self.vsa_api = vsa.API()
|
||||||
|
|
||||||
|
self.context_non_admin = context.RequestContext(None, None)
|
||||||
|
self.context = context.get_admin_context()
|
||||||
|
|
||||||
|
def fake_show_by_name(meh, context, name):
|
||||||
|
if name == 'wrong_image_name':
|
||||||
|
LOG.debug(_("Test: Emulate wrong VSA name. Raise"))
|
||||||
|
raise exception.ImageNotFound
|
||||||
|
return {'id': 1, 'properties': {'kernel_id': 1, 'ramdisk_id': 1}}
|
||||||
|
|
||||||
|
self.stubs.Set(nova.image.fake._FakeImageService, 'show_by_name',
|
||||||
|
fake_show_by_name)
|
||||||
|
|
||||||
|
def tearDown(self):
|
||||||
|
self.stubs.UnsetAll()
|
||||||
|
super(VsaTestCase, self).tearDown()
|
||||||
|
|
||||||
|
def test_vsa_create_delete_defaults(self):
|
||||||
|
param = {'display_name': 'VSA name test'}
|
||||||
|
vsa_ref = self.vsa_api.create(self.context, **param)
|
||||||
|
self.assertEqual(vsa_ref['display_name'], param['display_name'])
|
||||||
|
self.vsa_api.delete(self.context, vsa_ref['id'])
|
||||||
|
|
||||||
|
def test_vsa_create_delete_check_in_db(self):
|
||||||
|
vsa_list1 = self.vsa_api.get_all(self.context)
|
||||||
|
vsa_ref = self.vsa_api.create(self.context)
|
||||||
|
vsa_list2 = self.vsa_api.get_all(self.context)
|
||||||
|
self.assertEqual(len(vsa_list2), len(vsa_list1) + 1)
|
||||||
|
|
||||||
|
self.vsa_api.delete(self.context, vsa_ref['id'])
|
||||||
|
vsa_list3 = self.vsa_api.get_all(self.context)
|
||||||
|
self.assertEqual(len(vsa_list3), len(vsa_list2) - 1)
|
||||||
|
|
||||||
|
def test_vsa_create_delete_high_vc_count(self):
|
||||||
|
param = {'vc_count': FLAGS.max_vcs_in_vsa + 1}
|
||||||
|
vsa_ref = self.vsa_api.create(self.context, **param)
|
||||||
|
self.assertEqual(vsa_ref['vc_count'], FLAGS.max_vcs_in_vsa)
|
||||||
|
self.vsa_api.delete(self.context, vsa_ref['id'])
|
||||||
|
|
||||||
|
def test_vsa_create_wrong_image_name(self):
|
||||||
|
param = {'image_name': 'wrong_image_name'}
|
||||||
|
self.assertRaises(exception.ApiError,
|
||||||
|
self.vsa_api.create, self.context, **param)
|
||||||
|
|
||||||
|
def test_vsa_create_db_error(self):
|
||||||
|
|
||||||
|
def fake_vsa_create(context, options):
|
||||||
|
LOG.debug(_("Test: Emulate DB error. Raise"))
|
||||||
|
raise exception.Error
|
||||||
|
|
||||||
|
self.stubs.Set(nova.db.api, 'vsa_create', fake_vsa_create)
|
||||||
|
self.assertRaises(exception.ApiError,
|
||||||
|
self.vsa_api.create, self.context)
|
||||||
|
|
||||||
|
def test_vsa_create_wrong_storage_params(self):
|
||||||
|
vsa_list1 = self.vsa_api.get_all(self.context)
|
||||||
|
param = {'storage': [{'stub': 1}]}
|
||||||
|
self.assertRaises(exception.ApiError,
|
||||||
|
self.vsa_api.create, self.context, **param)
|
||||||
|
vsa_list2 = self.vsa_api.get_all(self.context)
|
||||||
|
self.assertEqual(len(vsa_list2), len(vsa_list1) + 1)
|
||||||
|
|
||||||
|
param = {'storage': [{'drive_name': 'wrong name'}]}
|
||||||
|
self.assertRaises(exception.ApiError,
|
||||||
|
self.vsa_api.create, self.context, **param)
|
||||||
|
|
||||||
|
def test_vsa_create_with_storage(self, multi_vol_creation=True):
|
||||||
|
"""Test creation of VSA with BE storage"""
|
||||||
|
|
||||||
|
FLAGS.vsa_multi_vol_creation = multi_vol_creation
|
||||||
|
|
||||||
|
self.stubs.Set(nova.vsa.drive_types, 'get_by_name',
|
||||||
|
fake_drive_type_get_by_name)
|
||||||
|
|
||||||
|
param = {'storage': [{'drive_name': 'SATA_500_7200',
|
||||||
|
'num_drives': 3}]}
|
||||||
|
vsa_ref = self.vsa_api.create(self.context, **param)
|
||||||
|
self.assertEqual(vsa_ref['vol_count'], 3)
|
||||||
|
self.vsa_api.delete(self.context, vsa_ref['id'])
|
||||||
|
|
||||||
|
param = {'storage': [{'drive_name': 'SATA_500_7200',
|
||||||
|
'num_drives': 3}],
|
||||||
|
'shared': True}
|
||||||
|
vsa_ref = self.vsa_api.create(self.context, **param)
|
||||||
|
self.assertEqual(vsa_ref['vol_count'], 15)
|
||||||
|
self.vsa_api.delete(self.context, vsa_ref['id'])
|
||||||
|
|
||||||
|
def test_vsa_create_with_storage_single_volumes(self):
|
||||||
|
self.test_vsa_create_with_storage(multi_vol_creation=False)
|
||||||
|
|
||||||
|
def test_vsa_update(self):
|
||||||
|
vsa_ref = self.vsa_api.create(self.context)
|
||||||
|
|
||||||
|
param = {'vc_count': FLAGS.max_vcs_in_vsa + 1}
|
||||||
|
vsa_ref = self.vsa_api.update(self.context, vsa_ref['id'], **param)
|
||||||
|
self.assertEqual(vsa_ref['vc_count'], FLAGS.max_vcs_in_vsa)
|
||||||
|
|
||||||
|
param = {'vc_count': 2}
|
||||||
|
vsa_ref = self.vsa_api.update(self.context, vsa_ref['id'], **param)
|
||||||
|
self.assertEqual(vsa_ref['vc_count'], 2)
|
||||||
|
|
||||||
|
self.vsa_api.delete(self.context, vsa_ref['id'])
|
||||||
|
|
||||||
|
def test_vsa_generate_user_data(self):
|
||||||
|
self.stubs.Set(nova.vsa.drive_types, 'get_by_name',
|
||||||
|
fake_drive_type_get_by_name)
|
||||||
|
|
||||||
|
FLAGS.vsa_multi_vol_creation = False
|
||||||
|
param = {'display_name': 'VSA name test',
|
||||||
|
'display_description': 'VSA desc test',
|
||||||
|
'vc_count': 2,
|
||||||
|
'storage': [{'drive_name': 'SATA_500_7200',
|
||||||
|
'num_drives': 3}]}
|
||||||
|
vsa_ref = self.vsa_api.create(self.context, **param)
|
||||||
|
volumes = db.volume_get_all_assigned_to_vsa(self.context,
|
||||||
|
vsa_ref['id'])
|
||||||
|
|
||||||
|
user_data = self.vsa_api.generate_user_data(self.context,
|
||||||
|
vsa_ref,
|
||||||
|
volumes)
|
||||||
|
user_data = base64.b64decode(user_data)
|
||||||
|
|
||||||
|
LOG.debug(_("Test: user_data = %s"), user_data)
|
||||||
|
|
||||||
|
elem = ElementTree.fromstring(user_data)
|
||||||
|
self.assertEqual(elem.findtext('name'),
|
||||||
|
param['display_name'])
|
||||||
|
self.assertEqual(elem.findtext('description'),
|
||||||
|
param['display_description'])
|
||||||
|
self.assertEqual(elem.findtext('vc_count'),
|
||||||
|
str(param['vc_count']))
|
||||||
|
|
||||||
|
self.vsa_api.delete(self.context, vsa_ref['id'])
|
@ -74,15 +74,15 @@ class API(base.Base):
|
|||||||
num_disks = node.get('num_drives', 1)
|
num_disks = node.get('num_drives', 1)
|
||||||
|
|
||||||
if name is None:
|
if name is None:
|
||||||
raise exception.ApiError(_("No drive_name param found in %s"),
|
raise exception.ApiError(_("No drive_name param found in %s")
|
||||||
node)
|
% node)
|
||||||
|
|
||||||
# find DB record for this disk
|
# find DB record for this disk
|
||||||
try:
|
try:
|
||||||
drive_ref = drive_types.get_by_name(context, name)
|
drive_ref = drive_types.get_by_name(context, name)
|
||||||
except exception.NotFound:
|
except exception.NotFound:
|
||||||
raise exception.ApiError(_("Invalid drive type name %s"),
|
raise exception.ApiError(_("Invalid drive type name %s")
|
||||||
name)
|
% name)
|
||||||
|
|
||||||
# if size field present - override disk size specified in DB
|
# if size field present - override disk size specified in DB
|
||||||
size = node.get('size', drive_ref['size_gb'])
|
size = node.get('size', drive_ref['size_gb'])
|
||||||
@ -149,8 +149,8 @@ class API(base.Base):
|
|||||||
vc_image = image_service.show_by_name(context, image_name)
|
vc_image = image_service.show_by_name(context, image_name)
|
||||||
vc_image_href = vc_image['id']
|
vc_image_href = vc_image['id']
|
||||||
except exception.ImageNotFound:
|
except exception.ImageNotFound:
|
||||||
raise exception.ApiError(_("Failed to find configured image %s"),
|
raise exception.ApiError(_("Failed to find configured image %s")
|
||||||
image_name)
|
% image_name)
|
||||||
|
|
||||||
options = {
|
options = {
|
||||||
'display_name': display_name,
|
'display_name': display_name,
|
||||||
@ -258,34 +258,42 @@ class API(base.Base):
|
|||||||
"""
|
"""
|
||||||
LOG.info(_("VSA ID %(vsa_id)d: Update VSA call"), locals())
|
LOG.info(_("VSA ID %(vsa_id)d: Update VSA call"), locals())
|
||||||
|
|
||||||
|
updatable_fields = ['status', 'vc_count', 'vol_count',
|
||||||
|
'display_name', 'display_description']
|
||||||
|
changes = {}
|
||||||
|
for field in updatable_fields:
|
||||||
|
if field in kwargs:
|
||||||
|
changes[field] = kwargs[field]
|
||||||
|
|
||||||
vc_count = kwargs.get('vc_count', None)
|
vc_count = kwargs.get('vc_count', None)
|
||||||
if vc_count is not None:
|
if vc_count is not None:
|
||||||
# VP-TODO: This request may want to update number of VCs
|
# VP-TODO: This request may want to update number of VCs
|
||||||
# Get number of current VCs and add/delete VCs appropriately
|
# Get number of current VCs and add/delete VCs appropriately
|
||||||
vsa = self.get(context, vsa_id)
|
vsa = self.get(context, vsa_id)
|
||||||
vc_count = int(vc_count)
|
vc_count = int(vc_count)
|
||||||
|
if vc_count > FLAGS.max_vcs_in_vsa:
|
||||||
|
LOG.warning(_("Requested number of VCs (%d) is too high."\
|
||||||
|
" Setting to default"), vc_count)
|
||||||
|
vc_count = FLAGS.max_vcs_in_vsa
|
||||||
|
|
||||||
if vsa['vc_count'] != vc_count:
|
if vsa['vc_count'] != vc_count:
|
||||||
self.update_num_vcs(context, vsa, vc_count)
|
self.update_num_vcs(context, vsa, vc_count)
|
||||||
|
changes['vc_count'] = vc_count
|
||||||
|
|
||||||
return self.db.vsa_update(context, vsa_id, kwargs)
|
return self.db.vsa_update(context, vsa_id, changes)
|
||||||
|
|
||||||
def update_num_vcs(self, context, vsa, vc_count):
|
def update_num_vcs(self, context, vsa, vc_count):
|
||||||
if vc_count > FLAGS.max_vcs_in_vsa:
|
|
||||||
LOG.warning(_("Requested number of VCs (%d) is too high."\
|
|
||||||
" Setting to default"), vc_count)
|
|
||||||
vc_count = FLAGS.max_vcs_in_vsa
|
|
||||||
|
|
||||||
vsa_name = vsa['name']
|
vsa_name = vsa['name']
|
||||||
old_vc_count = vsa['vc_count']
|
old_vc_count = int(vsa['vc_count'])
|
||||||
if vc_count > old_vc_count:
|
if vc_count > old_vc_count:
|
||||||
add_cnt = vc_count - old_vc_count
|
add_cnt = vc_count - old_vc_count
|
||||||
LOG.debug(_("Adding %(add_cnt)d VCs to VSA %(vsa_name)s."),
|
LOG.debug(_("Adding %(add_cnt)s VCs to VSA %(vsa_name)s."),
|
||||||
locals())
|
locals())
|
||||||
# VP-TODO: actual code for adding new VCs
|
# VP-TODO: actual code for adding new VCs
|
||||||
|
|
||||||
elif vc_count < old_vc_count:
|
elif vc_count < old_vc_count:
|
||||||
del_cnt = old_vc_count - vc_count
|
del_cnt = old_vc_count - vc_count
|
||||||
LOG.debug(_("Deleting %(add_cnt)d VCs from VSA %(vsa_name)s."),
|
LOG.debug(_("Deleting %(del_cnt)s VCs from VSA %(vsa_name)s."),
|
||||||
locals())
|
locals())
|
||||||
# VP-TODO: actual code for deleting extra VCs
|
# VP-TODO: actual code for deleting extra VCs
|
||||||
|
|
||||||
@ -372,9 +380,11 @@ class API(base.Base):
|
|||||||
e_vsa_detail = SubElement(e_vsa, "vc_count")
|
e_vsa_detail = SubElement(e_vsa, "vc_count")
|
||||||
e_vsa_detail.text = str(vsa['vc_count'])
|
e_vsa_detail.text = str(vsa['vc_count'])
|
||||||
e_vsa_detail = SubElement(e_vsa, "auth_user")
|
e_vsa_detail = SubElement(e_vsa, "auth_user")
|
||||||
e_vsa_detail.text = str(context.user.name)
|
if context.user is not None:
|
||||||
|
e_vsa_detail.text = str(context.user.name)
|
||||||
e_vsa_detail = SubElement(e_vsa, "auth_access_key")
|
e_vsa_detail = SubElement(e_vsa, "auth_access_key")
|
||||||
e_vsa_detail.text = str(context.user.access)
|
if context.user is not None:
|
||||||
|
e_vsa_detail.text = str(context.user.access)
|
||||||
|
|
||||||
e_volumes = SubElement(e_vsa, "volumes")
|
e_volumes = SubElement(e_vsa, "volumes")
|
||||||
for volume in volumes:
|
for volume in volumes:
|
||||||
|
Loading…
Reference in New Issue
Block a user