diff options
author | Renuka Apte <renuka.apte@citrix.com> | 2012-05-29 16:36:54 -0700 |
---|---|---|
committer | Renuka Apte <renuka.apte@citrix.com> | 2012-06-18 13:46:11 -0700 |
commit | 02a9a18088b62d1c4c5aaafc44523d3dda6db527 (patch) | |
tree | f2b92211065e08fff386f8236513392a3fd54f32 | |
parent | ba52373f3827117f07b1b871eed3970c83131973 (diff) | |
download | nova-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-x | bin/nova-manage | 2 | ||||
-rw-r--r-- | nova/db/api.py | 11 | ||||
-rw-r--r-- | nova/db/sqlalchemy/api.py | 86 | ||||
-rw-r--r-- | nova/test.py | 9 | ||||
-rw-r--r-- | nova/tests/test_db_api.py | 186 |
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") |