summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRenuka Apte <renuka.apte@citrix.com>2012-05-29 16:36:54 -0700
committerRenuka Apte <renuka.apte@citrix.com>2012-06-18 13:46:11 -0700
commit02a9a18088b62d1c4c5aaafc44523d3dda6db527 (patch)
treef2b92211065e08fff386f8236513392a3fd54f32
parentba52373f3827117f07b1b871eed3970c83131973 (diff)
downloadnova-02a9a18088b62d1c4c5aaafc44523d3dda6db527.tar.gz
nova-02a9a18088b62d1c4c5aaafc44523d3dda6db527.tar.xz
nova-02a9a18088b62d1c4c5aaafc44523d3dda6db527.zip
SM volume driver: DB changes and tests
Fixes the storage manager db api code in minor ways like checking for duplicates during creation. Adds tests for the storage manager db api. Change-Id: I00f431ed9137b140f46b4e30cb953792d7307d22
-rwxr-xr-xbin/nova-manage2
-rw-r--r--nova/db/api.py11
-rw-r--r--nova/db/sqlalchemy/api.py86
-rw-r--r--nova/test.py9
-rw-r--r--nova/tests/test_db_api.py186
5 files changed, 270 insertions, 24 deletions
diff --git a/bin/nova-manage b/bin/nova-manage
index 5414e4e5e..6bda2ada5 100755
--- a/bin/nova-manage
+++ b/bin/nova-manage
@@ -1367,7 +1367,7 @@ class StorageManagerCommands(object):
sys.exit(2)
try:
- flavors = db.sm_flavor_get(ctxt, flavor_label)
+ flavors = db.sm_flavor_get_by_label(ctxt, flavor_label)
except exception.NotFound as ex:
print "error: %s" % ex
sys.exit(2)
diff --git a/nova/db/api.py b/nova/db/api.py
index 025a5848f..e0d150506 100644
--- a/nova/db/api.py
+++ b/nova/db/api.py
@@ -1784,7 +1784,7 @@ def sm_flavor_create(context, values):
def sm_flavor_update(context, sm_flavor_id, values):
"""Update a SM Flavor entry."""
- return IMPL.sm_flavor_update(context, values)
+ return IMPL.sm_flavor_update(context, sm_flavor_id, values)
def sm_flavor_delete(context, sm_flavor_id):
@@ -1792,9 +1792,9 @@ def sm_flavor_delete(context, sm_flavor_id):
return IMPL.sm_flavor_delete(context, sm_flavor_id)
-def sm_flavor_get(context, sm_flavor):
+def sm_flavor_get(context, sm_flavor_id):
"""Get a specific SM Flavor."""
- return IMPL.sm_flavor_get(context, sm_flavor)
+ return IMPL.sm_flavor_get(context, sm_flavor_id)
def sm_flavor_get_all(context):
@@ -1802,6 +1802,11 @@ def sm_flavor_get_all(context):
return IMPL.sm_flavor_get_all(context)
+def sm_flavor_get_by_label(context, sm_flavor_label):
+ """Get a specific SM Flavor given label."""
+ return IMPL.sm_flavor_get_by_label(context, sm_flavor_label)
+
+
####################
diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py
index 49f77aacc..cff4cd8ab 100644
--- a/nova/db/sqlalchemy/api.py
+++ b/nova/db/sqlalchemy/api.py
@@ -4628,9 +4628,21 @@ def s3_image_create(context, image_uuid):
@require_admin_context
def sm_backend_conf_create(context, values):
- backend_conf = models.SMBackendConf()
- backend_conf.update(values)
- backend_conf.save()
+ session = get_session()
+ with session.begin():
+ config_params = values['config_params']
+ backend_conf = model_query(context, models.SMBackendConf,
+ session=session,
+ read_deleted="yes").\
+ filter_by(config_params=config_params).\
+ first()
+
+ if backend_conf:
+ raise exception.Duplicate(_('Backend exists'))
+ else:
+ backend_conf = models.SMBackendConf()
+ backend_conf.update(values)
+ backend_conf.save(session=session)
return backend_conf
@@ -4681,9 +4693,13 @@ def sm_backend_conf_get(context, sm_backend_id):
@require_admin_context
def sm_backend_conf_get_by_sr(context, sr_uuid):
session = get_session()
- return model_query(context, models.SMBackendConf, read_deleted="yes").\
- filter_by(sr_uuid=sr_uuid).\
- first()
+ result = model_query(context, models.SMBackendConf, read_deleted="yes").\
+ filter_by(sr_uuid=sr_uuid).\
+ first()
+ if not result:
+ raise exception.NotFound(_("No backend config with sr uuid "
+ "%(sr_uuid)s") % locals())
+ return result
@require_admin_context
@@ -4695,42 +4711,61 @@ def sm_backend_conf_get_all(context):
####################
-def _sm_flavor_get_query(context, sm_flavor_label, session=None):
+def _sm_flavor_get_query(context, sm_flavor_id, session=None):
return model_query(context, models.SMFlavors, session=session,
read_deleted="yes").\
- filter_by(label=sm_flavor_label)
+ filter_by(id=sm_flavor_id)
@require_admin_context
def sm_flavor_create(context, values):
- sm_flavor = models.SMFlavors()
- sm_flavor.update(values)
- sm_flavor.save()
+ session = get_session()
+ with session.begin():
+ sm_flavor = model_query(context, models.SMFlavors,
+ session=session,
+ read_deleted="yes").\
+ filter_by(label=values['label']).\
+ first()
+ if not sm_flavor:
+ sm_flavor = models.SMFlavors()
+ sm_flavor.update(values)
+ sm_flavor.save(session=session)
+ else:
+ raise exception.Duplicate(_('Flavor exists'))
return sm_flavor
@require_admin_context
-def sm_flavor_update(context, sm_flavor_label, values):
- sm_flavor = sm_flavor_get(context, sm_flavor_label)
- sm_flavor.update(values)
- sm_flavor.save()
+def sm_flavor_update(context, sm_flavor_id, values):
+ session = get_session()
+ with session.begin():
+ sm_flavor = model_query(context, models.SMFlavors,
+ session=session,
+ read_deleted="yes").\
+ filter_by(id=sm_flavor_id).\
+ first()
+ if not sm_flavor:
+ raise exception.NotFound(
+ _('%(sm_flavor_id) flavor not found') % locals())
+ sm_flavor.update(values)
+ sm_flavor.save(session=session)
return sm_flavor
@require_admin_context
-def sm_flavor_delete(context, sm_flavor_label):
+def sm_flavor_delete(context, sm_flavor_id):
session = get_session()
with session.begin():
- _sm_flavor_get_query(context, sm_flavor_label).delete()
+ _sm_flavor_get_query(context, sm_flavor_id).delete()
@require_admin_context
-def sm_flavor_get(context, sm_flavor_label):
- result = _sm_flavor_get_query(context, sm_flavor_label).first()
+def sm_flavor_get(context, sm_flavor_id):
+ result = _sm_flavor_get_query(context, sm_flavor_id).first()
if not result:
raise exception.NotFound(
- _("No sm_flavor called %(sm_flavor)s") % locals())
+ _("No sm_flavor called %(sm_flavor_id)s") % locals())
return result
@@ -4740,6 +4775,17 @@ def sm_flavor_get_all(context):
return model_query(context, models.SMFlavors, read_deleted="yes").all()
+@require_admin_context
+def sm_flavor_get_by_label(context, sm_flavor_label):
+ result = model_query(context, models.SMFlavors,
+ read_deleted="yes").\
+ filter_by(label=sm_flavor_label).first()
+ if not result:
+ raise exception.NotFound(
+ _("No sm_flavor called %(sm_flavor_label)s") % locals())
+ return result
+
+
###############################
diff --git a/nova/test.py b/nova/test.py
index 8de4ddfca..1839fd1e4 100644
--- a/nova/test.py
+++ b/nova/test.py
@@ -316,3 +316,12 @@ class TestCase(unittest.TestCase):
raise AssertionError(exc_msg)
except Exception:
pass # Any other errors are fine
+
+ def assertIsInstance(self, a, b, *args, **kwargs):
+ """Python < v2.7 compatibility. Assert 'a' is Instance of 'b'"""
+ try:
+ f = super(TestCase, self).assertIsInstance
+ except AttributeError:
+ self.assertTrue(isinstance(a, b), *args, **kwargs)
+ else:
+ f(a, b, *args, **kwargs)
diff --git a/nova/tests/test_db_api.py b/nova/tests/test_db_api.py
index d28acfd72..aaddb08a6 100644
--- a/nova/tests/test_db_api.py
+++ b/nova/tests/test_db_api.py
@@ -878,3 +878,189 @@ class InstanceDestroyConstraints(test.TestCase):
ctx, instance['uuid'], constraint)
instance = db.instance_get_by_uuid(ctx, instance['uuid'])
self.assertFalse(instance['deleted'])
+
+
+def _get_sm_backend_params():
+ config_params = ("name_label=testsmbackend "
+ "server=localhost "
+ "serverpath=/tmp/nfspath")
+ params = dict(flavor_id=1,
+ sr_uuid=None,
+ sr_type='nfs',
+ config_params=config_params)
+ return params
+
+
+def _get_sm_flavor_params():
+ params = dict(label="gold",
+ description="automatic backups")
+ return params
+
+
+class SMVolumeDBApiTestCase(test.TestCase):
+ def setUp(self):
+ super(SMVolumeDBApiTestCase, self).setUp()
+ self.user_id = 'fake'
+ self.project_id = 'fake'
+ self.context = context.RequestContext(self.user_id, self.project_id)
+
+ def test_sm_backend_conf_create(self):
+ params = _get_sm_backend_params()
+ ctxt = context.get_admin_context()
+ beconf = db.sm_backend_conf_create(ctxt,
+ params)
+ self.assertIsInstance(beconf['id'], int)
+
+ def test_sm_backend_conf_create_raise_duplicate(self):
+ params = _get_sm_backend_params()
+ ctxt = context.get_admin_context()
+ beconf = db.sm_backend_conf_create(ctxt,
+ params)
+ self.assertIsInstance(beconf['id'], int)
+ self.assertRaises(exception.Duplicate,
+ db.sm_backend_conf_create,
+ ctxt,
+ params)
+
+ def test_sm_backend_conf_update(self):
+ ctxt = context.get_admin_context()
+ params = _get_sm_backend_params()
+ beconf = db.sm_backend_conf_create(ctxt,
+ params)
+ beconf = db.sm_backend_conf_update(ctxt,
+ beconf['id'],
+ dict(sr_uuid="FA15E-1D"))
+ self.assertEqual(beconf['sr_uuid'], "FA15E-1D")
+
+ def test_sm_backend_conf_update_raise_notfound(self):
+ ctxt = context.get_admin_context()
+ self.assertRaises(exception.NotFound,
+ db.sm_backend_conf_update,
+ ctxt,
+ 7,
+ dict(sr_uuid="FA15E-1D"))
+
+ def test_sm_backend_conf_get(self):
+ ctxt = context.get_admin_context()
+ params = _get_sm_backend_params()
+ beconf = db.sm_backend_conf_create(ctxt,
+ params)
+ val = db.sm_backend_conf_get(ctxt, beconf['id'])
+ self.assertDictMatch(dict(val), dict(beconf))
+
+ def test_sm_backend_conf_get_raise_notfound(self):
+ ctxt = context.get_admin_context()
+ self.assertRaises(exception.NotFound,
+ db.sm_backend_conf_get,
+ ctxt,
+ 7)
+
+ def test_sm_backend_conf_get_by_sr(self):
+ ctxt = context.get_admin_context()
+ params = _get_sm_backend_params()
+ beconf = db.sm_backend_conf_create(ctxt,
+ params)
+ val = db.sm_backend_conf_get_by_sr(ctxt, beconf['sr_uuid'])
+ self.assertDictMatch(dict(val), dict(beconf))
+
+ def test_sm_backend_conf_get_by_sr_raise_notfound(self):
+ ctxt = context.get_admin_context()
+ self.assertRaises(exception.NotFound,
+ db.sm_backend_conf_get_by_sr,
+ ctxt,
+ "FA15E-1D")
+
+ def test_sm_backend_conf_delete(self):
+ ctxt = context.get_admin_context()
+ params = _get_sm_backend_params()
+ beconf = db.sm_backend_conf_create(ctxt,
+ params)
+ db.sm_backend_conf_delete(ctxt, beconf['id'])
+ self.assertRaises(exception.NotFound,
+ db.sm_backend_conf_get,
+ ctxt,
+ beconf['id'])
+
+ def test_sm_backend_conf_delete_nonexisting(self):
+ ctxt = context.get_admin_context()
+ self.assertNotRaises(None, db.sm_backend_conf_delete,
+ ctxt, "FA15E-1D")
+
+ def test_sm_flavor_create(self):
+ ctxt = context.get_admin_context()
+ params = _get_sm_flavor_params()
+ flav = db.sm_flavor_create(ctxt,
+ params)
+ self.assertIsInstance(flav['id'], int)
+
+ def sm_flavor_create_raise_duplicate(self):
+ ctxt = context.get_admin_context()
+ params = _get_sm_flavor_params()
+ flav = db.sm_flavor_create(ctxt,
+ params)
+ self.assertRaises(exception.Duplicate,
+ db.sm_flavor_create,
+ params)
+
+ def test_sm_flavor_update(self):
+ ctxt = context.get_admin_context()
+ params = _get_sm_flavor_params()
+ flav = db.sm_flavor_create(ctxt,
+ params)
+ newparms = dict(description="basic volumes")
+ flav = db.sm_flavor_update(ctxt, flav['id'], newparms)
+ self.assertEqual(flav['description'], "basic volumes")
+
+ def test_sm_flavor_update_raise_notfound(self):
+ ctxt = context.get_admin_context()
+ self.assertRaises(exception.NotFound,
+ db.sm_flavor_update,
+ ctxt,
+ 7,
+ dict(description="fakedesc"))
+
+ def test_sm_flavor_delete(self):
+ ctxt = context.get_admin_context()
+ params = _get_sm_flavor_params()
+ flav = db.sm_flavor_create(ctxt,
+ params)
+ db.sm_flavor_delete(ctxt, flav['id'])
+ self.assertRaises(exception.NotFound,
+ db.sm_flavor_get,
+ ctxt,
+ "gold")
+
+ def test_sm_flavor_delete_nonexisting(self):
+ ctxt = context.get_admin_context()
+ self.assertNotRaises(None, db.sm_flavor_delete,
+ ctxt, 7)
+
+ def test_sm_flavor_get(self):
+ ctxt = context.get_admin_context()
+ params = _get_sm_flavor_params()
+ flav = db.sm_flavor_create(ctxt,
+ params)
+ val = db.sm_flavor_get(ctxt, flav['id'])
+ self.assertDictMatch(dict(val), dict(flav))
+
+ def test_sm_flavor_get_raise_notfound(self):
+ ctxt = context.get_admin_context()
+ self.assertRaises(exception.NotFound,
+ db.sm_flavor_get,
+ ctxt,
+ 7)
+
+ def test_sm_flavor_get_by_label(self):
+ ctxt = context.get_admin_context()
+ params = _get_sm_flavor_params()
+ flav = db.sm_flavor_create(ctxt,
+ params)
+ val = db.sm_flavor_get_by_label(ctxt, flav['label'])
+ self.assertDictMatch(dict(val), dict(flav))
+
+ def test_sm_flavor_get_by_label_raise_notfound(self):
+ ctxt = context.get_admin_context()
+ self.assertRaises(exception.NotFound,
+ db.sm_flavor_get,
+ ctxt,
+ "fake")