diff options
| author | vladimir.p <vladimir@zadarastorage.com> | 2011-08-25 16:14:44 +0000 |
|---|---|---|
| committer | Tarmac <> | 2011-08-25 16:14:44 +0000 |
| commit | ae07c417b554d0b26d055a7bd8b3217a59c1966f (patch) | |
| tree | ab696134c806d40ac239e5b2f6f30bfe1a488920 /nova/tests | |
| parent | f136cf119778b4d5d09e607487cf011b9f16dedb (diff) | |
| parent | 3a2cdb0d9dc3e8a4ebf30bb31b37bb6bca84330f (diff) | |
Added:
- volume metadata
- volume types
- volume types extra_specs
Volume create API receives volume types & metadata.
Work in progress on Openstack APIs for volume types & extra_specs.
Diffstat (limited to 'nova/tests')
| -rw-r--r-- | nova/tests/api/openstack/test_extensions.py | 1 | ||||
| -rw-r--r-- | nova/tests/api/openstack/test_volume_types.py | 171 | ||||
| -rw-r--r-- | nova/tests/api/openstack/test_volume_types_extra_specs.py | 181 | ||||
| -rw-r--r-- | nova/tests/integrated/test_volumes.py | 17 | ||||
| -rw-r--r-- | nova/tests/test_volume_types.py | 207 | ||||
| -rw-r--r-- | nova/tests/test_volume_types_extra_specs.py | 132 |
6 files changed, 709 insertions, 0 deletions
diff --git a/nova/tests/api/openstack/test_extensions.py b/nova/tests/api/openstack/test_extensions.py index 9f923852d..c78588d65 100644 --- a/nova/tests/api/openstack/test_extensions.py +++ b/nova/tests/api/openstack/test_extensions.py @@ -97,6 +97,7 @@ class ExtensionControllerTest(test.TestCase): "SecurityGroups", "VirtualInterfaces", "Volumes", + "VolumeTypes", ] self.ext_list.sort() diff --git a/nova/tests/api/openstack/test_volume_types.py b/nova/tests/api/openstack/test_volume_types.py new file mode 100644 index 000000000..192e66854 --- /dev/null +++ b/nova/tests/api/openstack/test_volume_types.py @@ -0,0 +1,171 @@ +# 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 json +import stubout +import webob + +from nova import exception +from nova import context +from nova import test +from nova import log as logging +from nova.volume import volume_types +from nova.tests.api.openstack import fakes + +LOG = logging.getLogger('nova.tests.api.openstack.test_volume_types') + +last_param = {} + + +def stub_volume_type(id): + specs = { + "key1": "value1", + "key2": "value2", + "key3": "value3", + "key4": "value4", + "key5": "value5"} + return dict(id=id, name='vol_type_%s' % str(id), extra_specs=specs) + + +def return_volume_types_get_all_types(context): + return dict(vol_type_1=stub_volume_type(1), + vol_type_2=stub_volume_type(2), + vol_type_3=stub_volume_type(3)) + + +def return_empty_volume_types_get_all_types(context): + return {} + + +def return_volume_types_get_volume_type(context, id): + if id == "777": + raise exception.VolumeTypeNotFound(volume_type_id=id) + return stub_volume_type(int(id)) + + +def return_volume_types_destroy(context, name): + if name == "777": + raise exception.VolumeTypeNotFoundByName(volume_type_name=name) + pass + + +def return_volume_types_create(context, name, specs): + pass + + +def return_volume_types_get_by_name(context, name): + if name == "777": + raise exception.VolumeTypeNotFoundByName(volume_type_name=name) + return stub_volume_type(int(name.split("_")[2])) + + +class VolumeTypesApiTest(test.TestCase): + def setUp(self): + super(VolumeTypesApiTest, self).setUp() + fakes.stub_out_key_pair_funcs(self.stubs) + + def tearDown(self): + self.stubs.UnsetAll() + super(VolumeTypesApiTest, self).tearDown() + + def test_volume_types_index(self): + self.stubs.Set(volume_types, 'get_all_types', + return_volume_types_get_all_types) + req = webob.Request.blank('/v1.1/123/os-volume-types') + res = req.get_response(fakes.wsgi_app()) + self.assertEqual(200, res.status_int) + res_dict = json.loads(res.body) + self.assertEqual('application/json', res.headers['Content-Type']) + + self.assertEqual(3, len(res_dict)) + for name in ['vol_type_1', 'vol_type_2', 'vol_type_3']: + self.assertEqual(name, res_dict[name]['name']) + self.assertEqual('value1', res_dict[name]['extra_specs']['key1']) + + def test_volume_types_index_no_data(self): + self.stubs.Set(volume_types, 'get_all_types', + return_empty_volume_types_get_all_types) + req = webob.Request.blank('/v1.1/123/os-volume-types') + res = req.get_response(fakes.wsgi_app()) + res_dict = json.loads(res.body) + self.assertEqual(200, res.status_int) + self.assertEqual('application/json', res.headers['Content-Type']) + self.assertEqual(0, len(res_dict)) + + def test_volume_types_show(self): + self.stubs.Set(volume_types, 'get_volume_type', + return_volume_types_get_volume_type) + req = webob.Request.blank('/v1.1/123/os-volume-types/1') + res = req.get_response(fakes.wsgi_app()) + self.assertEqual(200, res.status_int) + res_dict = json.loads(res.body) + self.assertEqual('application/json', res.headers['Content-Type']) + self.assertEqual(1, len(res_dict)) + self.assertEqual('vol_type_1', res_dict['volume_type']['name']) + + def test_volume_types_show_not_found(self): + self.stubs.Set(volume_types, 'get_volume_type', + return_volume_types_get_volume_type) + req = webob.Request.blank('/v1.1/123/os-volume-types/777') + res = req.get_response(fakes.wsgi_app()) + self.assertEqual(404, res.status_int) + + def test_volume_types_delete(self): + self.stubs.Set(volume_types, 'get_volume_type', + return_volume_types_get_volume_type) + self.stubs.Set(volume_types, 'destroy', + return_volume_types_destroy) + req = webob.Request.blank('/v1.1/123/os-volume-types/1') + req.method = 'DELETE' + res = req.get_response(fakes.wsgi_app()) + self.assertEqual(200, res.status_int) + + def test_volume_types_delete_not_found(self): + self.stubs.Set(volume_types, 'get_volume_type', + return_volume_types_get_volume_type) + self.stubs.Set(volume_types, 'destroy', + return_volume_types_destroy) + req = webob.Request.blank('/v1.1/123/os-volume-types/777') + req.method = 'DELETE' + res = req.get_response(fakes.wsgi_app()) + self.assertEqual(404, res.status_int) + + def test_create(self): + self.stubs.Set(volume_types, 'create', + return_volume_types_create) + self.stubs.Set(volume_types, 'get_volume_type_by_name', + return_volume_types_get_by_name) + req = webob.Request.blank('/v1.1/123/os-volume-types') + req.method = 'POST' + req.body = '{"volume_type": {"name": "vol_type_1", '\ + '"extra_specs": {"key1": "value1"}}}' + req.headers["content-type"] = "application/json" + res = req.get_response(fakes.wsgi_app()) + self.assertEqual(200, res.status_int) + res_dict = json.loads(res.body) + self.assertEqual('application/json', res.headers['Content-Type']) + self.assertEqual(1, len(res_dict)) + self.assertEqual('vol_type_1', res_dict['volume_type']['name']) + + def test_create_empty_body(self): + self.stubs.Set(volume_types, 'create', + return_volume_types_create) + self.stubs.Set(volume_types, 'get_volume_type_by_name', + return_volume_types_get_by_name) + req = webob.Request.blank('/v1.1/123/os-volume-types') + req.method = 'POST' + req.headers["content-type"] = "application/json" + res = req.get_response(fakes.wsgi_app()) + self.assertEqual(400, res.status_int) diff --git a/nova/tests/api/openstack/test_volume_types_extra_specs.py b/nova/tests/api/openstack/test_volume_types_extra_specs.py new file mode 100644 index 000000000..34bdada22 --- /dev/null +++ b/nova/tests/api/openstack/test_volume_types_extra_specs.py @@ -0,0 +1,181 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright (c) 2011 Zadara Storage Inc. +# Copyright (c) 2011 OpenStack LLC. +# Copyright 2011 University of Southern California +# 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 json +import stubout +import webob +import os.path + + +from nova import test +from nova.api import openstack +from nova.api.openstack import extensions +from nova.tests.api.openstack import fakes +import nova.wsgi + + +def return_create_volume_type_extra_specs(context, volume_type_id, + extra_specs): + return stub_volume_type_extra_specs() + + +def return_volume_type_extra_specs(context, volume_type_id): + return stub_volume_type_extra_specs() + + +def return_empty_volume_type_extra_specs(context, volume_type_id): + return {} + + +def delete_volume_type_extra_specs(context, volume_type_id, key): + pass + + +def stub_volume_type_extra_specs(): + specs = { + "key1": "value1", + "key2": "value2", + "key3": "value3", + "key4": "value4", + "key5": "value5"} + return specs + + +class VolumeTypesExtraSpecsTest(test.TestCase): + + def setUp(self): + super(VolumeTypesExtraSpecsTest, self).setUp() + fakes.stub_out_key_pair_funcs(self.stubs) + self.api_path = '/v1.1/123/os-volume-types/1/extra_specs' + + def test_index(self): + self.stubs.Set(nova.db.api, 'volume_type_extra_specs_get', + return_volume_type_extra_specs) + request = webob.Request.blank(self.api_path) + res = request.get_response(fakes.wsgi_app()) + self.assertEqual(200, res.status_int) + res_dict = json.loads(res.body) + self.assertEqual('application/json', res.headers['Content-Type']) + self.assertEqual('value1', res_dict['extra_specs']['key1']) + + def test_index_no_data(self): + self.stubs.Set(nova.db.api, 'volume_type_extra_specs_get', + return_empty_volume_type_extra_specs) + req = webob.Request.blank(self.api_path) + res = req.get_response(fakes.wsgi_app()) + res_dict = json.loads(res.body) + self.assertEqual(200, res.status_int) + self.assertEqual('application/json', res.headers['Content-Type']) + self.assertEqual(0, len(res_dict['extra_specs'])) + + def test_show(self): + self.stubs.Set(nova.db.api, 'volume_type_extra_specs_get', + return_volume_type_extra_specs) + req = webob.Request.blank(self.api_path + '/key5') + res = req.get_response(fakes.wsgi_app()) + self.assertEqual(200, res.status_int) + res_dict = json.loads(res.body) + self.assertEqual('application/json', res.headers['Content-Type']) + self.assertEqual('value5', res_dict['key5']) + + def test_show_spec_not_found(self): + self.stubs.Set(nova.db.api, 'volume_type_extra_specs_get', + return_empty_volume_type_extra_specs) + req = webob.Request.blank(self.api_path + '/key6') + res = req.get_response(fakes.wsgi_app()) + res_dict = json.loads(res.body) + self.assertEqual(404, res.status_int) + + def test_delete(self): + self.stubs.Set(nova.db.api, 'volume_type_extra_specs_delete', + delete_volume_type_extra_specs) + req = webob.Request.blank(self.api_path + '/key5') + req.method = 'DELETE' + res = req.get_response(fakes.wsgi_app()) + self.assertEqual(200, res.status_int) + + def test_create(self): + self.stubs.Set(nova.db.api, + 'volume_type_extra_specs_update_or_create', + return_create_volume_type_extra_specs) + req = webob.Request.blank(self.api_path) + req.method = 'POST' + req.body = '{"extra_specs": {"key1": "value1"}}' + req.headers["content-type"] = "application/json" + res = req.get_response(fakes.wsgi_app()) + res_dict = json.loads(res.body) + self.assertEqual(200, res.status_int) + self.assertEqual('application/json', res.headers['Content-Type']) + self.assertEqual('value1', res_dict['extra_specs']['key1']) + + def test_create_empty_body(self): + self.stubs.Set(nova.db.api, + 'volume_type_extra_specs_update_or_create', + return_create_volume_type_extra_specs) + req = webob.Request.blank(self.api_path) + req.method = 'POST' + req.headers["content-type"] = "application/json" + res = req.get_response(fakes.wsgi_app()) + self.assertEqual(400, res.status_int) + + def test_update_item(self): + self.stubs.Set(nova.db.api, + 'volume_type_extra_specs_update_or_create', + return_create_volume_type_extra_specs) + req = webob.Request.blank(self.api_path + '/key1') + req.method = 'PUT' + req.body = '{"key1": "value1"}' + req.headers["content-type"] = "application/json" + res = req.get_response(fakes.wsgi_app()) + self.assertEqual(200, res.status_int) + self.assertEqual('application/json', res.headers['Content-Type']) + res_dict = json.loads(res.body) + self.assertEqual('value1', res_dict['key1']) + + def test_update_item_empty_body(self): + self.stubs.Set(nova.db.api, + 'volume_type_extra_specs_update_or_create', + return_create_volume_type_extra_specs) + req = webob.Request.blank(self.api_path + '/key1') + req.method = 'PUT' + req.headers["content-type"] = "application/json" + res = req.get_response(fakes.wsgi_app()) + self.assertEqual(400, res.status_int) + + def test_update_item_too_many_keys(self): + self.stubs.Set(nova.db.api, + 'volume_type_extra_specs_update_or_create', + return_create_volume_type_extra_specs) + req = webob.Request.blank(self.api_path + '/key1') + req.method = 'PUT' + req.body = '{"key1": "value1", "key2": "value2"}' + req.headers["content-type"] = "application/json" + res = req.get_response(fakes.wsgi_app()) + self.assertEqual(400, res.status_int) + + def test_update_item_body_uri_mismatch(self): + self.stubs.Set(nova.db.api, + 'volume_type_extra_specs_update_or_create', + return_create_volume_type_extra_specs) + req = webob.Request.blank(self.api_path + '/bad') + req.method = 'PUT' + req.body = '{"key1": "value1"}' + req.headers["content-type"] = "application/json" + res = req.get_response(fakes.wsgi_app()) + self.assertEqual(400, res.status_int) diff --git a/nova/tests/integrated/test_volumes.py b/nova/tests/integrated/test_volumes.py index d3e936462..d6c5e1ba1 100644 --- a/nova/tests/integrated/test_volumes.py +++ b/nova/tests/integrated/test_volumes.py @@ -285,6 +285,23 @@ class VolumesTest(integrated_helpers._IntegratedTestBase): self.assertEquals(undisco_move['mountpoint'], device) self.assertEquals(undisco_move['instance_id'], server_id) + def test_create_volume_with_metadata(self): + """Creates and deletes a volume.""" + + # Create volume + metadata = {'key1': 'value1', + 'key2': 'value2'} + created_volume = self.api.post_volume( + {'volume': {'size': 1, + 'metadata': metadata}}) + LOG.debug("created_volume: %s" % created_volume) + self.assertTrue(created_volume['id']) + created_volume_id = created_volume['id'] + + # Check it's there and metadata present + found_volume = self.api.get_volume(created_volume_id) + self.assertEqual(created_volume_id, found_volume['id']) + self.assertEqual(metadata, found_volume['metadata']) if __name__ == "__main__": unittest.main() diff --git a/nova/tests/test_volume_types.py b/nova/tests/test_volume_types.py new file mode 100644 index 000000000..1e190805c --- /dev/null +++ b/nova/tests/test_volume_types.py @@ -0,0 +1,207 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright (c) 2011 Zadara Storage Inc. +# Copyright (c) 2011 OpenStack LLC. +# 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. +""" +Unit Tests for volume types code +""" +import time + +from nova import context +from nova import db +from nova import exception +from nova import flags +from nova import log as logging +from nova import test +from nova import utils +from nova.volume import volume_types +from nova.db.sqlalchemy.session import get_session +from nova.db.sqlalchemy import models + +FLAGS = flags.FLAGS +LOG = logging.getLogger('nova.tests.test_volume_types') + + +class VolumeTypeTestCase(test.TestCase): + """Test cases for volume type code""" + def setUp(self): + super(VolumeTypeTestCase, self).setUp() + + self.ctxt = context.get_admin_context() + self.vol_type1_name = str(int(time.time())) + self.vol_type1_specs = dict( + type="physical drive", + drive_type="SAS", + size="300", + rpm="7200", + visible="True") + self.vol_type1 = dict(name=self.vol_type1_name, + extra_specs=self.vol_type1_specs) + + def test_volume_type_create_then_destroy(self): + """Ensure volume types can be created and deleted""" + prev_all_vtypes = volume_types.get_all_types(self.ctxt) + + volume_types.create(self.ctxt, + self.vol_type1_name, + self.vol_type1_specs) + new = volume_types.get_volume_type_by_name(self.ctxt, + self.vol_type1_name) + + LOG.info(_("Given data: %s"), self.vol_type1_specs) + LOG.info(_("Result data: %s"), new) + + for k, v in self.vol_type1_specs.iteritems(): + self.assertEqual(v, new['extra_specs'][k], + 'one of fields doesnt match') + + new_all_vtypes = volume_types.get_all_types(self.ctxt) + self.assertEqual(len(prev_all_vtypes) + 1, + len(new_all_vtypes), + 'drive type was not created') + + volume_types.destroy(self.ctxt, self.vol_type1_name) + new_all_vtypes = volume_types.get_all_types(self.ctxt) + self.assertEqual(prev_all_vtypes, + new_all_vtypes, + 'drive type was not deleted') + + def test_volume_type_create_then_purge(self): + """Ensure volume types can be created and deleted""" + prev_all_vtypes = volume_types.get_all_types(self.ctxt, inactive=1) + + volume_types.create(self.ctxt, + self.vol_type1_name, + self.vol_type1_specs) + new = volume_types.get_volume_type_by_name(self.ctxt, + self.vol_type1_name) + + for k, v in self.vol_type1_specs.iteritems(): + self.assertEqual(v, new['extra_specs'][k], + 'one of fields doesnt match') + + new_all_vtypes = volume_types.get_all_types(self.ctxt, inactive=1) + self.assertEqual(len(prev_all_vtypes) + 1, + len(new_all_vtypes), + 'drive type was not created') + + volume_types.destroy(self.ctxt, self.vol_type1_name) + new_all_vtypes2 = volume_types.get_all_types(self.ctxt, inactive=1) + self.assertEqual(len(new_all_vtypes), + len(new_all_vtypes2), + 'drive type was incorrectly deleted') + + volume_types.purge(self.ctxt, self.vol_type1_name) + new_all_vtypes2 = volume_types.get_all_types(self.ctxt, inactive=1) + self.assertEqual(len(new_all_vtypes) - 1, + len(new_all_vtypes2), + 'drive type was not purged') + + def test_get_all_volume_types(self): + """Ensures that all volume types can be retrieved""" + session = get_session() + total_volume_types = session.query(models.VolumeTypes).\ + count() + vol_types = volume_types.get_all_types(self.ctxt) + self.assertEqual(total_volume_types, len(vol_types)) + + def test_non_existant_inst_type_shouldnt_delete(self): + """Ensures that volume type creation fails with invalid args""" + self.assertRaises(exception.ApiError, + volume_types.destroy, self.ctxt, "sfsfsdfdfs") + + def test_repeated_vol_types_should_raise_api_error(self): + """Ensures that volume duplicates raises ApiError""" + new_name = self.vol_type1_name + "dup" + volume_types.create(self.ctxt, new_name) + volume_types.destroy(self.ctxt, new_name) + self.assertRaises( + exception.ApiError, + volume_types.create, self.ctxt, new_name) + + def test_invalid_volume_types_params(self): + """Ensures that volume type creation fails with invalid args""" + self.assertRaises(exception.InvalidVolumeType, + volume_types.destroy, self.ctxt, None) + self.assertRaises(exception.InvalidVolumeType, + volume_types.purge, self.ctxt, None) + self.assertRaises(exception.InvalidVolumeType, + volume_types.get_volume_type, self.ctxt, None) + self.assertRaises(exception.InvalidVolumeType, + volume_types.get_volume_type_by_name, + self.ctxt, None) + + def test_volume_type_get_by_id_and_name(self): + """Ensure volume types get returns same entry""" + volume_types.create(self.ctxt, + self.vol_type1_name, + self.vol_type1_specs) + new = volume_types.get_volume_type_by_name(self.ctxt, + self.vol_type1_name) + + new2 = volume_types.get_volume_type(self.ctxt, new['id']) + self.assertEqual(new, new2) + + def test_volume_type_search_by_extra_spec(self): + """Ensure volume types get by extra spec returns correct type""" + volume_types.create(self.ctxt, "type1", {"key1": "val1", + "key2": "val2"}) + volume_types.create(self.ctxt, "type2", {"key2": "val2", + "key3": "val3"}) + volume_types.create(self.ctxt, "type3", {"key3": "another_value", + "key4": "val4"}) + + vol_types = volume_types.get_all_types(self.ctxt, + search_opts={'extra_specs': {"key1": "val1"}}) + LOG.info("vol_types: %s" % vol_types) + self.assertEqual(len(vol_types), 1) + self.assertTrue("type1" in vol_types.keys()) + self.assertEqual(vol_types['type1']['extra_specs'], + {"key1": "val1", "key2": "val2"}) + + vol_types = volume_types.get_all_types(self.ctxt, + search_opts={'extra_specs': {"key2": "val2"}}) + LOG.info("vol_types: %s" % vol_types) + self.assertEqual(len(vol_types), 2) + self.assertTrue("type1" in vol_types.keys()) + self.assertTrue("type2" in vol_types.keys()) + + vol_types = volume_types.get_all_types(self.ctxt, + search_opts={'extra_specs': {"key3": "val3"}}) + LOG.info("vol_types: %s" % vol_types) + self.assertEqual(len(vol_types), 1) + self.assertTrue("type2" in vol_types.keys()) + + def test_volume_type_search_by_extra_spec_multiple(self): + """Ensure volume types get by extra spec returns correct type""" + volume_types.create(self.ctxt, "type1", {"key1": "val1", + "key2": "val2", + "key3": "val3"}) + volume_types.create(self.ctxt, "type2", {"key2": "val2", + "key3": "val3"}) + volume_types.create(self.ctxt, "type3", {"key1": "val1", + "key3": "val3", + "key4": "val4"}) + + vol_types = volume_types.get_all_types(self.ctxt, + search_opts={'extra_specs': {"key1": "val1", + "key3": "val3"}}) + LOG.info("vol_types: %s" % vol_types) + self.assertEqual(len(vol_types), 2) + self.assertTrue("type1" in vol_types.keys()) + self.assertTrue("type3" in vol_types.keys()) + self.assertEqual(vol_types['type1']['extra_specs'], + {"key1": "val1", "key2": "val2", "key3": "val3"}) + self.assertEqual(vol_types['type3']['extra_specs'], + {"key1": "val1", "key3": "val3", "key4": "val4"}) diff --git a/nova/tests/test_volume_types_extra_specs.py b/nova/tests/test_volume_types_extra_specs.py new file mode 100644 index 000000000..017b187a1 --- /dev/null +++ b/nova/tests/test_volume_types_extra_specs.py @@ -0,0 +1,132 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright (c) 2011 Zadara Storage Inc. +# Copyright (c) 2011 OpenStack LLC. +# Copyright 2011 University of Southern California +# 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. +""" +Unit Tests for volume types extra specs code +""" + +from nova import context +from nova import db +from nova import test +from nova.db.sqlalchemy.session import get_session +from nova.db.sqlalchemy import models + + +class VolumeTypeExtraSpecsTestCase(test.TestCase): + + def setUp(self): + super(VolumeTypeExtraSpecsTestCase, self).setUp() + self.context = context.get_admin_context() + self.vol_type1 = dict(name="TEST: Regular volume test") + self.vol_type1_specs = dict(vol_extra1="value1", + vol_extra2="value2", + vol_extra3=3) + self.vol_type1['extra_specs'] = self.vol_type1_specs + ref = db.api.volume_type_create(self.context, self.vol_type1) + self.volume_type1_id = ref.id + for k, v in self.vol_type1_specs.iteritems(): + self.vol_type1_specs[k] = str(v) + + self.vol_type2_noextra = dict(name="TEST: Volume type without extra") + ref = db.api.volume_type_create(self.context, self.vol_type2_noextra) + self.vol_type2_id = ref.id + + def tearDown(self): + # Remove the instance type from the database + db.api.volume_type_purge(context.get_admin_context(), + self.vol_type1['name']) + db.api.volume_type_purge(context.get_admin_context(), + self.vol_type2_noextra['name']) + super(VolumeTypeExtraSpecsTestCase, self).tearDown() + + def test_volume_type_specs_get(self): + expected_specs = self.vol_type1_specs.copy() + actual_specs = db.api.volume_type_extra_specs_get( + context.get_admin_context(), + self.volume_type1_id) + self.assertEquals(expected_specs, actual_specs) + + def test_volume_type_extra_specs_delete(self): + expected_specs = self.vol_type1_specs.copy() + del expected_specs['vol_extra2'] + db.api.volume_type_extra_specs_delete(context.get_admin_context(), + self.volume_type1_id, + 'vol_extra2') + actual_specs = db.api.volume_type_extra_specs_get( + context.get_admin_context(), + self.volume_type1_id) + self.assertEquals(expected_specs, actual_specs) + + def test_volume_type_extra_specs_update(self): + expected_specs = self.vol_type1_specs.copy() + expected_specs['vol_extra3'] = "4" + db.api.volume_type_extra_specs_update_or_create( + context.get_admin_context(), + self.volume_type1_id, + dict(vol_extra3=4)) + actual_specs = db.api.volume_type_extra_specs_get( + context.get_admin_context(), + self.volume_type1_id) + self.assertEquals(expected_specs, actual_specs) + + def test_volume_type_extra_specs_create(self): + expected_specs = self.vol_type1_specs.copy() + expected_specs['vol_extra4'] = 'value4' + expected_specs['vol_extra5'] = 'value5' + db.api.volume_type_extra_specs_update_or_create( + context.get_admin_context(), + self.volume_type1_id, + dict(vol_extra4="value4", + vol_extra5="value5")) + actual_specs = db.api.volume_type_extra_specs_get( + context.get_admin_context(), + self.volume_type1_id) + self.assertEquals(expected_specs, actual_specs) + + def test_volume_type_get_with_extra_specs(self): + volume_type = db.api.volume_type_get( + context.get_admin_context(), + self.volume_type1_id) + self.assertEquals(volume_type['extra_specs'], + self.vol_type1_specs) + + volume_type = db.api.volume_type_get( + context.get_admin_context(), + self.vol_type2_id) + self.assertEquals(volume_type['extra_specs'], {}) + + def test_volume_type_get_by_name_with_extra_specs(self): + volume_type = db.api.volume_type_get_by_name( + context.get_admin_context(), + self.vol_type1['name']) + self.assertEquals(volume_type['extra_specs'], + self.vol_type1_specs) + + volume_type = db.api.volume_type_get_by_name( + context.get_admin_context(), + self.vol_type2_noextra['name']) + self.assertEquals(volume_type['extra_specs'], {}) + + def test_volume_type_get_all(self): + expected_specs = self.vol_type1_specs.copy() + + types = db.api.volume_type_get_all(context.get_admin_context()) + + self.assertEquals( + types[self.vol_type1['name']]['extra_specs'], expected_specs) + + self.assertEquals( + types[self.vol_type2_noextra['name']]['extra_specs'], {}) |
