From b814f9fef3efa1bdcb7e03a9161e08721b7bc8c4 Mon Sep 17 00:00:00 2001 From: "vladimir.p" Date: Fri, 15 Jul 2011 17:56:27 -0700 Subject: VSA: first cut. merged with 1279 --- nova/tests/test_libvirt.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'nova/tests') diff --git a/nova/tests/test_libvirt.py b/nova/tests/test_libvirt.py index f99e1713d..36e469be3 100644 --- a/nova/tests/test_libvirt.py +++ b/nova/tests/test_libvirt.py @@ -242,7 +242,7 @@ class LibvirtConnTestCase(test.TestCase): return """ - + -- cgit From 9e74803d5eb8a70ba829ac0569f1cd6cd372a6f2 Mon Sep 17 00:00:00 2001 From: "vladimir.p" Date: Fri, 22 Jul 2011 15:14:29 -0700 Subject: Reverted volume driver part --- .../api/openstack/contrib/test_drive_types.py | 192 +++++++++++++++++ nova/tests/api/openstack/contrib/test_vsa.py | 239 +++++++++++++++++++++ nova/tests/test_drive_types.py | 146 +++++++++++++ 3 files changed, 577 insertions(+) create mode 100644 nova/tests/api/openstack/contrib/test_drive_types.py create mode 100644 nova/tests/api/openstack/contrib/test_vsa.py create mode 100644 nova/tests/test_drive_types.py (limited to 'nova/tests') diff --git a/nova/tests/api/openstack/contrib/test_drive_types.py b/nova/tests/api/openstack/contrib/test_drive_types.py new file mode 100644 index 000000000..2f7d327d3 --- /dev/null +++ b/nova/tests/api/openstack/contrib/test_drive_types.py @@ -0,0 +1,192 @@ +# 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 compute +from nova.vsa import drive_types +from nova import exception +from nova import context +from nova import test +from nova import log as logging +from nova.tests.api.openstack import fakes + +from nova.api.openstack.contrib.drive_types import _drive_type_view + +LOG = logging.getLogger('nova.tests.api.openstack.drive_types') + +last_param = {} + + +def _get_default_drive_type(): + param = { + 'name': 'Test drive type', + 'type': 'SATA', + 'size_gb': 123, + 'rpm': '7200', + 'capabilities': '', + 'visible': True + } + return param + + +def _create(context, **param): + global last_param + LOG.debug(_("_create: %s"), param) + param['id'] = 123 + last_param = param + return param + + +def _delete(context, id): + global last_param + last_param = dict(id=id) + + LOG.debug(_("_delete: %s"), locals()) + + +def _get(context, id): + global last_param + last_param = dict(id=id) + + LOG.debug(_("_get: %s"), locals()) + if id != '123': + raise exception.NotFound + + dtype = _get_default_drive_type() + dtype['id'] = id + return dtype + + +def _get_all(context, visible=True): + LOG.debug(_("_get_all: %s"), locals()) + dtype = _get_default_drive_type() + dtype['id'] = 123 + return [dtype] + + +class DriveTypesApiTest(test.TestCase): + def setUp(self): + super(DriveTypesApiTest, self).setUp() + self.stubs = stubout.StubOutForTesting() + fakes.FakeAuthManager.reset_fake_data() + fakes.FakeAuthDatabase.data = {} + fakes.stub_out_networking(self.stubs) + fakes.stub_out_rate_limiting(self.stubs) + fakes.stub_out_auth(self.stubs) + self.stubs.Set(drive_types, "create", _create) + self.stubs.Set(drive_types, "delete", _delete) + self.stubs.Set(drive_types, "get", _get) + self.stubs.Set(drive_types, "get_all", _get_all) + + self.context = context.get_admin_context() + + def tearDown(self): + self.stubs.UnsetAll() + super(DriveTypesApiTest, self).tearDown() + + def test_drive_types_api_create(self): + global last_param + last_param = {} + + dtype = _get_default_drive_type() + dtype['id'] = 123 + + body = dict(drive_type=_drive_type_view(dtype)) + req = webob.Request.blank('/v1.1/zadr-drive_types') + req.method = 'POST' + req.body = json.dumps(body) + req.headers['content-type'] = 'application/json' + + resp = req.get_response(fakes.wsgi_app()) + self.assertEqual(resp.status_int, 200) + + # Compare if parameters were correctly passed to stub + for k, v in last_param.iteritems(): + self.assertEqual(last_param[k], dtype[k]) + + resp_dict = json.loads(resp.body) + + # Compare response + self.assertTrue('drive_type' in resp_dict) + resp_dtype = resp_dict['drive_type'] + self.assertEqual(resp_dtype, _drive_type_view(dtype)) + + def test_drive_types_api_delete(self): + global last_param + last_param = {} + + dtype_id = 123 + req = webob.Request.blank('/v1.1/zadr-drive_types/%d' % dtype_id) + req.method = 'DELETE' + + resp = req.get_response(fakes.wsgi_app()) + self.assertEqual(resp.status_int, 200) + self.assertEqual(str(last_param['id']), str(dtype_id)) + + def test_drive_types_show(self): + global last_param + last_param = {} + + dtype_id = 123 + req = webob.Request.blank('/v1.1/zadr-drive_types/%d' % dtype_id) + req.method = 'GET' + resp = req.get_response(fakes.wsgi_app()) + self.assertEqual(resp.status_int, 200) + self.assertEqual(str(last_param['id']), str(dtype_id)) + + resp_dict = json.loads(resp.body) + + # Compare response + self.assertTrue('drive_type' in resp_dict) + resp_dtype = resp_dict['drive_type'] + exp_dtype = _get_default_drive_type() + exp_dtype['id'] = dtype_id + exp_dtype_view = _drive_type_view(exp_dtype) + for k, v in exp_dtype_view.iteritems(): + self.assertEqual(str(resp_dtype[k]), str(exp_dtype_view[k])) + + def test_drive_types_show_invalid_id(self): + global last_param + last_param = {} + + dtype_id = 234 + req = webob.Request.blank('/v1.1/zadr-drive_types/%d' % dtype_id) + req.method = 'GET' + resp = req.get_response(fakes.wsgi_app()) + self.assertEqual(resp.status_int, 404) + self.assertEqual(str(last_param['id']), str(dtype_id)) + + def test_drive_types_index(self): + + req = webob.Request.blank('/v1.1/zadr-drive_types') + req.method = 'GET' + resp = req.get_response(fakes.wsgi_app()) + self.assertEqual(resp.status_int, 200) + + resp_dict = json.loads(resp.body) + + self.assertTrue('drive_types' in resp_dict) + resp_dtypes = resp_dict['drive_types'] + self.assertEqual(len(resp_dtypes), 1) + + resp_dtype = resp_dtypes.pop() + exp_dtype = _get_default_drive_type() + exp_dtype['id'] = 123 + exp_dtype_view = _drive_type_view(exp_dtype) + for k, v in exp_dtype_view.iteritems(): + self.assertEqual(str(resp_dtype[k]), str(exp_dtype_view[k])) diff --git a/nova/tests/api/openstack/contrib/test_vsa.py b/nova/tests/api/openstack/contrib/test_vsa.py new file mode 100644 index 000000000..bc0b7eaa6 --- /dev/null +++ b/nova/tests/api/openstack/contrib/test_vsa.py @@ -0,0 +1,239 @@ +# 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 compute +from nova import vsa +from nova import exception +from nova import context +from nova import test +from nova import log as logging +from nova.tests.api.openstack import fakes + +from nova.api.openstack.contrib.virtual_storage_arrays import _vsa_view + +LOG = logging.getLogger('nova.tests.api.openstack.vsa') + +last_param = {} + + +def _get_default_vsa_param(): + return { + 'display_name': 'Test_VSA_name', + 'display_description': 'Test_VSA_description', + 'vc_count': 1, + 'instance_type': 'm1.small', + 'image_name': None, + 'availability_zone': None, + 'storage': [], + 'shared': False + } + + +def stub_vsa_create(self, context, **param): + global last_param + LOG.debug(_("_create: param=%s"), param) + param['id'] = 123 + param['name'] = 'Test name' + last_param = param + return param + + +def stub_vsa_delete(self, context, vsa_id): + global last_param + last_param = dict(vsa_id=vsa_id) + + LOG.debug(_("_delete: %s"), locals()) + if vsa_id != '123': + raise exception.NotFound + + +def stub_vsa_get(self, context, vsa_id): + global last_param + last_param = dict(vsa_id=vsa_id) + + LOG.debug(_("_get: %s"), locals()) + if vsa_id != '123': + raise exception.NotFound + + param = _get_default_vsa_param() + param['id'] = vsa_id + return param + + +def stub_vsa_get_all(self, context): + LOG.debug(_("_get_all: %s"), locals()) + param = _get_default_vsa_param() + param['id'] = 123 + return [param] + + +class VSAApiTest(test.TestCase): + def setUp(self): + super(VSAApiTest, self).setUp() + self.stubs = stubout.StubOutForTesting() + fakes.FakeAuthManager.reset_fake_data() + fakes.FakeAuthDatabase.data = {} + fakes.stub_out_networking(self.stubs) + fakes.stub_out_rate_limiting(self.stubs) + fakes.stub_out_auth(self.stubs) + self.stubs.Set(vsa.api.API, "create", stub_vsa_create) + self.stubs.Set(vsa.api.API, "delete", stub_vsa_delete) + self.stubs.Set(vsa.api.API, "get", stub_vsa_get) + self.stubs.Set(vsa.api.API, "get_all", stub_vsa_get_all) + + self.context = context.get_admin_context() + + def tearDown(self): + self.stubs.UnsetAll() + super(VSAApiTest, self).tearDown() + + def test_vsa_api_create(self): + global last_param + last_param = {} + + vsa = {"displayName": "VSA Test Name", + "displayDescription": "VSA Test Desc"} + body = dict(vsa=vsa) + req = webob.Request.blank('/v1.1/zadr-vsa') + req.method = 'POST' + req.body = json.dumps(body) + req.headers['content-type'] = 'application/json' + + resp = req.get_response(fakes.wsgi_app()) + self.assertEqual(resp.status_int, 200) + + # Compare if parameters were correctly passed to stub + self.assertEqual(last_param['display_name'], "VSA Test Name") + self.assertEqual(last_param['display_description'], "VSA Test Desc") + + resp_dict = json.loads(resp.body) + self.assertTrue('vsa' in resp_dict) + self.assertEqual(resp_dict['vsa']['displayName'], vsa['displayName']) + self.assertEqual(resp_dict['vsa']['displayDescription'], + vsa['displayDescription']) + + def test_vsa_api_create_no_body(self): + req = webob.Request.blank('/v1.1/zadr-vsa') + req.method = 'POST' + req.body = json.dumps({}) + req.headers['content-type'] = 'application/json' + + resp = req.get_response(fakes.wsgi_app()) + self.assertEqual(resp.status_int, 422) + + def test_vsa_api_delete(self): + global last_param + last_param = {} + + vsa_id = 123 + req = webob.Request.blank('/v1.1/zadr-vsa/%d' % vsa_id) + req.method = 'DELETE' + + resp = req.get_response(fakes.wsgi_app()) + self.assertEqual(resp.status_int, 200) + self.assertEqual(str(last_param['vsa_id']), str(vsa_id)) + + def test_vsa_api_delete_invalid_id(self): + global last_param + last_param = {} + + vsa_id = 234 + req = webob.Request.blank('/v1.1/zadr-vsa/%d' % vsa_id) + req.method = 'DELETE' + + resp = req.get_response(fakes.wsgi_app()) + self.assertEqual(resp.status_int, 404) + self.assertEqual(str(last_param['vsa_id']), str(vsa_id)) + + def test_vsa_api_show(self): + global last_param + last_param = {} + + vsa_id = 123 + req = webob.Request.blank('/v1.1/zadr-vsa/%d' % vsa_id) + req.method = 'GET' + resp = req.get_response(fakes.wsgi_app()) + self.assertEqual(resp.status_int, 200) + self.assertEqual(str(last_param['vsa_id']), str(vsa_id)) + + resp_dict = json.loads(resp.body) + self.assertTrue('vsa' in resp_dict) + self.assertEqual(resp_dict['vsa']['id'], str(vsa_id)) + + def test_vsa_api_show_invalid_id(self): + global last_param + last_param = {} + + vsa_id = 234 + req = webob.Request.blank('/v1.1/zadr-vsa/%d' % vsa_id) + req.method = 'GET' + resp = req.get_response(fakes.wsgi_app()) + self.assertEqual(resp.status_int, 404) + self.assertEqual(str(last_param['vsa_id']), str(vsa_id)) + + def test_vsa_api_index(self): + req = webob.Request.blank('/v1.1/zadr-vsa') + req.method = 'GET' + resp = req.get_response(fakes.wsgi_app()) + self.assertEqual(resp.status_int, 200) + + resp_dict = json.loads(resp.body) + + self.assertTrue('vsaSet' in resp_dict) + resp_vsas = resp_dict['vsaSet'] + self.assertEqual(len(resp_vsas), 1) + + resp_vsa = resp_vsas.pop() + self.assertEqual(resp_vsa['id'], 123) + + def test_vsa_api_detail(self): + req = webob.Request.blank('/v1.1/zadr-vsa/detail') + req.method = 'GET' + resp = req.get_response(fakes.wsgi_app()) + self.assertEqual(resp.status_int, 200) + + resp_dict = json.loads(resp.body) + + self.assertTrue('vsaSet' in resp_dict) + resp_vsas = resp_dict['vsaSet'] + self.assertEqual(len(resp_vsas), 1) + + resp_vsa = resp_vsas.pop() + self.assertEqual(resp_vsa['id'], 123) + + +class VSAVolumeDriveApiTest(test.TestCase): + def setUp(self): + super(VSAVolumeDriveApiTest, self).setUp() + self.stubs = stubout.StubOutForTesting() + fakes.FakeAuthManager.reset_fake_data() + fakes.FakeAuthDatabase.data = {} + fakes.stub_out_networking(self.stubs) + fakes.stub_out_rate_limiting(self.stubs) + fakes.stub_out_auth(self.stubs) + self.stubs.Set(vsa.api.API, "create", stub_vsa_create) + self.stubs.Set(vsa.api.API, "delete", stub_vsa_delete) + self.stubs.Set(vsa.api.API, "get", stub_vsa_get) + self.stubs.Set(vsa.api.API, "get_all", stub_vsa_get_all) + + self.context = context.get_admin_context() + + def tearDown(self): + self.stubs.UnsetAll() + super(VSAVolumeDriveApiTest, self).tearDown() diff --git a/nova/tests/test_drive_types.py b/nova/tests/test_drive_types.py new file mode 100644 index 000000000..8534bcde5 --- /dev/null +++ b/nova/tests/test_drive_types.py @@ -0,0 +1,146 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright (c) 2011 Zadara Storage Inc. +# 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. + +""" +Unit Tests for drive types codecode +""" +import time + +from nova import context +from nova import flags +from nova import log as logging +from nova import test +from nova.vsa import drive_types + +FLAGS = flags.FLAGS +LOG = logging.getLogger('nova.tests.vsa') + + +class DriveTypesTestCase(test.TestCase): + """Test cases for driver types code""" + def setUp(self): + super(DriveTypesTestCase, self).setUp() + self.cntx = context.RequestContext(None, None) + self.cntx_admin = context.get_admin_context() + self._dtype = self._create_drive_type() + + def tearDown(self): + self._dtype = None + + def _create_drive_type(self): + """Create a volume object.""" + dtype = {} + dtype['type'] = 'SATA' + dtype['size_gb'] = 150 + dtype['rpm'] = 5000 + dtype['capabilities'] = None + dtype['visible'] = True + + LOG.debug(_("Drive Type created %s"), dtype) + return dtype + + def test_drive_type_create_delete(self): + dtype = self._dtype + prev_all_dtypes = drive_types.get_all(self.cntx_admin, False) + + new = drive_types.create(self.cntx_admin, **dtype) + for k, v in dtype.iteritems(): + self.assertEqual(v, new[k], 'one of fields doesnt match') + + new_all_dtypes = drive_types.get_all(self.cntx_admin, False) + self.assertNotEqual(len(prev_all_dtypes), + len(new_all_dtypes), + 'drive type was not created') + + drive_types.delete(self.cntx_admin, new['id']) + new_all_dtypes = drive_types.get_all(self.cntx_admin, False) + self.assertEqual(prev_all_dtypes, + new_all_dtypes, + 'drive types was not deleted') + + def test_drive_type_check_name_generation(self): + dtype = self._dtype + new = drive_types.create(self.cntx_admin, **dtype) + expected_name = FLAGS.drive_type_template_short % \ + (dtype['type'], dtype['size_gb'], dtype['rpm']) + self.assertEqual(new['name'], expected_name, + 'name was not generated correctly') + + dtype['capabilities'] = 'SEC' + new2 = drive_types.create(self.cntx_admin, **dtype) + expected_name = FLAGS.drive_type_template_long % \ + (dtype['type'], dtype['size_gb'], dtype['rpm'], + dtype['capabilities']) + self.assertEqual(new2['name'], expected_name, + 'name was not generated correctly') + + drive_types.delete(self.cntx_admin, new['id']) + drive_types.delete(self.cntx_admin, new2['id']) + + def test_drive_type_create_delete_invisible(self): + dtype = self._dtype + dtype['visible'] = False + prev_all_dtypes = drive_types.get_all(self.cntx_admin, True) + new = drive_types.create(self.cntx_admin, **dtype) + + new_all_dtypes = drive_types.get_all(self.cntx_admin, True) + self.assertEqual(prev_all_dtypes, new_all_dtypes) + + new_all_dtypes = drive_types.get_all(self.cntx_admin, False) + self.assertNotEqual(prev_all_dtypes, new_all_dtypes) + + drive_types.delete(self.cntx_admin, new['id']) + + def test_drive_type_rename_update(self): + dtype = self._dtype + dtype['capabilities'] = None + + new = drive_types.create(self.cntx_admin, **dtype) + for k, v in dtype.iteritems(): + self.assertEqual(v, new[k], 'one of fields doesnt match') + + new_name = 'NEW_DRIVE_NAME' + new = drive_types.rename(self.cntx_admin, new['name'], new_name) + self.assertEqual(new['name'], new_name) + + new = drive_types.rename(self.cntx_admin, new_name) + expected_name = FLAGS.drive_type_template_short % \ + (dtype['type'], dtype['size_gb'], dtype['rpm']) + self.assertEqual(new['name'], expected_name) + + changes = {'rpm': 7200} + new = drive_types.update(self.cntx_admin, new['id'], **changes) + for k, v in changes.iteritems(): + self.assertEqual(v, new[k], 'one of fields doesnt match') + + drive_types.delete(self.cntx_admin, new['id']) + + def test_drive_type_get(self): + dtype = self._dtype + new = drive_types.create(self.cntx_admin, **dtype) + + new2 = drive_types.get(self.cntx_admin, new['id']) + for k, v in new2.iteritems(): + self.assertEqual(str(new[k]), str(new2[k]), + 'one of fields doesnt match') + + new2 = drive_types.get_by_name(self.cntx_admin, new['name']) + for k, v in new.iteritems(): + self.assertEqual(str(new[k]), str(new2[k]), + 'one of fields doesnt match') + + drive_types.delete(self.cntx_admin, new['id']) -- cgit From 61781dae931ced36db0f2735da474d0bd38a53cf Mon Sep 17 00:00:00 2001 From: "vladimir.p" Date: Fri, 22 Jul 2011 20:25:32 -0700 Subject: more unittest changes --- nova/tests/api/openstack/contrib/test_vsa.py | 238 +++++++++++++++++++++++++-- 1 file changed, 220 insertions(+), 18 deletions(-) (limited to 'nova/tests') diff --git a/nova/tests/api/openstack/contrib/test_vsa.py b/nova/tests/api/openstack/contrib/test_vsa.py index bc0b7eaa6..c3150fa9c 100644 --- a/nova/tests/api/openstack/contrib/test_vsa.py +++ b/nova/tests/api/openstack/contrib/test_vsa.py @@ -15,18 +15,26 @@ import json import stubout +import unittest import webob -#from nova import compute -from nova import vsa + from nova import exception +from nova import flags +from nova import vsa +from nova import db +from nova import volume from nova import context from nova import test from nova import log as logging +from nova.api import openstack from nova.tests.api.openstack import fakes +import nova.wsgi from nova.api.openstack.contrib.virtual_storage_arrays import _vsa_view +FLAGS = flags.FLAGS + LOG = logging.getLogger('nova.tests.api.openstack.vsa') last_param = {} @@ -103,7 +111,7 @@ class VSAApiTest(test.TestCase): self.stubs.UnsetAll() super(VSAApiTest, self).tearDown() - def test_vsa_api_create(self): + def test_vsa_create(self): global last_param last_param = {} @@ -128,7 +136,7 @@ class VSAApiTest(test.TestCase): self.assertEqual(resp_dict['vsa']['displayDescription'], vsa['displayDescription']) - def test_vsa_api_create_no_body(self): + def test_vsa_create_no_body(self): req = webob.Request.blank('/v1.1/zadr-vsa') req.method = 'POST' req.body = json.dumps({}) @@ -137,7 +145,7 @@ class VSAApiTest(test.TestCase): resp = req.get_response(fakes.wsgi_app()) self.assertEqual(resp.status_int, 422) - def test_vsa_api_delete(self): + def test_vsa_delete(self): global last_param last_param = {} @@ -149,7 +157,7 @@ class VSAApiTest(test.TestCase): self.assertEqual(resp.status_int, 200) self.assertEqual(str(last_param['vsa_id']), str(vsa_id)) - def test_vsa_api_delete_invalid_id(self): + def test_vsa_delete_invalid_id(self): global last_param last_param = {} @@ -161,7 +169,7 @@ class VSAApiTest(test.TestCase): self.assertEqual(resp.status_int, 404) self.assertEqual(str(last_param['vsa_id']), str(vsa_id)) - def test_vsa_api_show(self): + def test_vsa_show(self): global last_param last_param = {} @@ -176,7 +184,7 @@ class VSAApiTest(test.TestCase): self.assertTrue('vsa' in resp_dict) self.assertEqual(resp_dict['vsa']['id'], str(vsa_id)) - def test_vsa_api_show_invalid_id(self): + def test_vsa_show_invalid_id(self): global last_param last_param = {} @@ -187,7 +195,7 @@ class VSAApiTest(test.TestCase): self.assertEqual(resp.status_int, 404) self.assertEqual(str(last_param['vsa_id']), str(vsa_id)) - def test_vsa_api_index(self): + def test_vsa_index(self): req = webob.Request.blank('/v1.1/zadr-vsa') req.method = 'GET' resp = req.get_response(fakes.wsgi_app()) @@ -202,7 +210,7 @@ class VSAApiTest(test.TestCase): resp_vsa = resp_vsas.pop() self.assertEqual(resp_vsa['id'], 123) - def test_vsa_api_detail(self): + def test_vsa_detail(self): req = webob.Request.blank('/v1.1/zadr-vsa/detail') req.method = 'GET' resp = req.get_response(fakes.wsgi_app()) @@ -218,22 +226,216 @@ class VSAApiTest(test.TestCase): self.assertEqual(resp_vsa['id'], 123) -class VSAVolumeDriveApiTest(test.TestCase): - def setUp(self): - super(VSAVolumeDriveApiTest, self).setUp() +def _get_default_volume_param(): + return { + 'id': 123, + 'status': 'available', + 'size': 100, + 'availability_zone': 'nova', + 'created_at': None, + 'attach_status': 'detached', + 'display_name': 'Default vol name', + 'display_description': 'Default vol description', + 'from_vsa_id': None, + 'to_vsa_id': None, + } + + +def stub_volume_create(self, context, size, snapshot_id, name, description, + **param): + LOG.debug(_("_create: param=%s"), size) + vol = _get_default_volume_param() + for k, v in param.iteritems(): + vol[k] = v + vol['size'] = size + vol['display_name'] = name + vol['display_description'] = description + return vol + + +def stub_volume_update(self, context, **param): + LOG.debug(_("_volume_update: param=%s"), param) + pass + + +def stub_volume_delete(self, context, **param): + LOG.debug(_("_volume_delete: param=%s"), param) + pass + + +def stub_volume_get(self, context, volume_id): + LOG.debug(_("_volume_get: volume_id=%s"), volume_id) + vol = _get_default_volume_param() + vol['id'] = volume_id + if volume_id == '234': + vol['from_vsa_id'] = 123 + if volume_id == '345': + vol['to_vsa_id'] = 123 + return vol + + +def stub_volume_get_notfound(self, context, volume_id): + raise exception.NotFound + + +def stub_volume_get_all_by_vsa(self, context, vsa_id, direction): + vol = stub_volume_get(self, context, '123') + vol['%s_vsa_id' % direction] = vsa_id + return [vol] + + +def return_vsa(context, vsa_id): + return {'id': vsa_id} + + +class VSAVolumeApiTest(test.TestCase): + + def setUp(self, test_obj=None, test_objs=None): + super(VSAVolumeApiTest, self).setUp() self.stubs = stubout.StubOutForTesting() fakes.FakeAuthManager.reset_fake_data() fakes.FakeAuthDatabase.data = {} fakes.stub_out_networking(self.stubs) fakes.stub_out_rate_limiting(self.stubs) fakes.stub_out_auth(self.stubs) - self.stubs.Set(vsa.api.API, "create", stub_vsa_create) - self.stubs.Set(vsa.api.API, "delete", stub_vsa_delete) - self.stubs.Set(vsa.api.API, "get", stub_vsa_get) - self.stubs.Set(vsa.api.API, "get_all", stub_vsa_get_all) + self.stubs.Set(nova.db.api, 'vsa_get', return_vsa) + + self.stubs.Set(volume.api.API, "create", stub_volume_create) + self.stubs.Set(volume.api.API, "update", stub_volume_update) + self.stubs.Set(volume.api.API, "delete", stub_volume_delete) + self.stubs.Set(volume.api.API, "get_all_by_vsa", + stub_volume_get_all_by_vsa) + self.stubs.Set(volume.api.API, "get", stub_volume_get) self.context = context.get_admin_context() + self.test_obj = test_obj if test_obj else "volume" + self.test_objs = test_objs if test_objs else "volumes" + + def tearDown(self): + self.stubs.UnsetAll() + super(VSAVolumeApiTest, self).tearDown() + + def test_vsa_volume_create(self): + vol = {"size": 100, + "displayName": "VSA Volume Test Name", + "displayDescription": "VSA Volume Test Desc"} + body = {self.test_obj: vol} + req = webob.Request.blank('/v1.1/zadr-vsa/123/%s' % self.test_objs) + req.method = 'POST' + req.body = json.dumps(body) + req.headers['content-type'] = 'application/json' + resp = req.get_response(fakes.wsgi_app()) + + if self.test_obj == "volume": + self.assertEqual(resp.status_int, 200) + + resp_dict = json.loads(resp.body) + self.assertTrue(self.test_obj in resp_dict) + self.assertEqual(resp_dict[self.test_obj]['size'], + vol['size']) + self.assertEqual(resp_dict[self.test_obj]['displayName'], + vol['displayName']) + self.assertEqual(resp_dict[self.test_obj]['displayDescription'], + vol['displayDescription']) + else: + self.assertEqual(resp.status_int, 400) + + def test_vsa_volume_create_no_body(self): + req = webob.Request.blank('/v1.1/zadr-vsa/123/%s' % self.test_objs) + req.method = 'POST' + req.body = json.dumps({}) + req.headers['content-type'] = 'application/json' + + resp = req.get_response(fakes.wsgi_app()) + if self.test_obj == "volume": + self.assertEqual(resp.status_int, 422) + else: + self.assertEqual(resp.status_int, 400) + + def test_vsa_volume_index(self): + req = webob.Request.blank('/v1.1/zadr-vsa/123/%s' % self.test_objs) + resp = req.get_response(fakes.wsgi_app()) + self.assertEqual(resp.status_int, 200) + + def test_vsa_volume_detail(self): + req = webob.Request.blank('/v1.1/zadr-vsa/123/%s/detail' % \ + self.test_objs) + resp = req.get_response(fakes.wsgi_app()) + self.assertEqual(resp.status_int, 200) + + def test_vsa_volume_show(self): + obj_num = 234 if self.test_objs == "volumes" else 345 + req = webob.Request.blank('/v1.1/zadr-vsa/123/%s/%s' % \ + (self.test_objs, obj_num)) + resp = req.get_response(fakes.wsgi_app()) + self.assertEqual(resp.status_int, 200) + + def test_vsa_volume_show_no_vsa_assignment(self): + req = webob.Request.blank('/v1.1/zadr-vsa/123/%s/333' % \ + (self.test_objs)) + resp = req.get_response(fakes.wsgi_app()) + self.assertEqual(resp.status_int, 400) + + def test_vsa_volume_show_no_volume(self): + self.stubs.Set(volume.api.API, "get", stub_volume_get_notfound) + + req = webob.Request.blank('/v1.1/zadr-vsa/123/%s/333' % \ + (self.test_objs)) + resp = req.get_response(fakes.wsgi_app()) + self.assertEqual(resp.status_int, 404) + + def test_vsa_volume_update(self): + obj_num = 234 if self.test_objs == "volumes" else 345 + update = {"status": "available"} + body = {self.test_obj: update} + req = webob.Request.blank('/v1.1/zadr-vsa/123/%s/%s' % \ + (self.test_objs, obj_num)) + req.method = 'PUT' + req.body = json.dumps(body) + req.headers['content-type'] = 'application/json' + + resp = req.get_response(fakes.wsgi_app()) + if self.test_obj == "volume": + self.assertEqual(resp.status_int, 202) + else: + self.assertEqual(resp.status_int, 400) + + def test_vsa_volume_delete(self): + obj_num = 234 if self.test_objs == "volumes" else 345 + req = webob.Request.blank('/v1.1/zadr-vsa/123/%s/%s' % \ + (self.test_objs, obj_num)) + req.method = 'DELETE' + resp = req.get_response(fakes.wsgi_app()) + if self.test_obj == "volume": + self.assertEqual(resp.status_int, 202) + else: + self.assertEqual(resp.status_int, 400) + + def test_vsa_volume_delete_no_vsa_assignment(self): + req = webob.Request.blank('/v1.1/zadr-vsa/123/%s/333' % \ + (self.test_objs)) + req.method = 'DELETE' + resp = req.get_response(fakes.wsgi_app()) + self.assertEqual(resp.status_int, 400) + + def test_vsa_volume_delete_no_volume(self): + self.stubs.Set(volume.api.API, "get", stub_volume_get_notfound) + + req = webob.Request.blank('/v1.1/zadr-vsa/123/%s/333' % \ + (self.test_objs)) + req.method = 'DELETE' + resp = req.get_response(fakes.wsgi_app()) + if self.test_obj == "volume": + self.assertEqual(resp.status_int, 404) + else: + self.assertEqual(resp.status_int, 400) + + +class VSADriveApiTest(VSAVolumeApiTest): + def setUp(self): + super(VSADriveApiTest, self).setUp(test_obj="drive", + test_objs="drives") def tearDown(self): self.stubs.UnsetAll() - super(VSAVolumeDriveApiTest, self).tearDown() + super(VSADriveApiTest, self).tearDown() -- cgit From fb755ae05b0b6a7b3701614c8d702e8a24ff380c Mon Sep 17 00:00:00 2001 From: "vladimir.p" Date: Sun, 24 Jul 2011 00:07:00 -0700 Subject: some cosmetic changes. Prior to merge proposal --- nova/tests/test_vsa.py | 185 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 185 insertions(+) create mode 100644 nova/tests/test_vsa.py (limited to 'nova/tests') diff --git a/nova/tests/test_vsa.py b/nova/tests/test_vsa.py new file mode 100644 index 000000000..859fe3325 --- /dev/null +++ b/nova/tests/test_vsa.py @@ -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']) -- cgit From c500eac4589e9cb22e5e71b900164a151290ec03 Mon Sep 17 00:00:00 2001 From: "vladimir.p" Date: Mon, 25 Jul 2011 16:26:23 -0700 Subject: some cleanup. VSA flag status changes. returned some files --- nova/tests/api/openstack/contrib/test_vsa.py | 4 +++- nova/tests/test_drive_types.py | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) (limited to 'nova/tests') diff --git a/nova/tests/api/openstack/contrib/test_vsa.py b/nova/tests/api/openstack/contrib/test_vsa.py index c3150fa9c..3c9136e14 100644 --- a/nova/tests/api/openstack/contrib/test_vsa.py +++ b/nova/tests/api/openstack/contrib/test_vsa.py @@ -234,6 +234,7 @@ def _get_default_volume_param(): 'availability_zone': 'nova', 'created_at': None, 'attach_status': 'detached', + 'name': 'vol name', 'display_name': 'Default vol name', 'display_description': 'Default vol description', 'from_vsa_id': None, @@ -386,7 +387,8 @@ class VSAVolumeApiTest(test.TestCase): def test_vsa_volume_update(self): obj_num = 234 if self.test_objs == "volumes" else 345 - update = {"status": "available"} + update = {"status": "available", + "displayName": "Test Display name"} body = {self.test_obj: update} req = webob.Request.blank('/v1.1/zadr-vsa/123/%s/%s' % \ (self.test_objs, obj_num)) diff --git a/nova/tests/test_drive_types.py b/nova/tests/test_drive_types.py index 8534bcde5..e91c41321 100644 --- a/nova/tests/test_drive_types.py +++ b/nova/tests/test_drive_types.py @@ -1,6 +1,7 @@ # vim: tabstop=4 shiftwidth=4 softtabstop=4 # Copyright (c) 2011 Zadara Storage Inc. +# Copyright (c) 2011 OpenStack LLC. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may -- cgit From a72f2e29e2a35791a1c53f4f606948572ab52280 Mon Sep 17 00:00:00 2001 From: "vladimir.p" Date: Tue, 26 Jul 2011 13:25:34 -0700 Subject: VSA volume creation/deletion changes --- nova/tests/test_vsa.py | 5 +- nova/tests/test_vsa_volumes.py | 108 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 111 insertions(+), 2 deletions(-) create mode 100644 nova/tests/test_vsa_volumes.py (limited to 'nova/tests') diff --git a/nova/tests/test_vsa.py b/nova/tests/test_vsa.py index 859fe3325..8e4d58960 100644 --- a/nova/tests/test_vsa.py +++ b/nova/tests/test_vsa.py @@ -60,8 +60,9 @@ class VsaTestCase(test.TestCase): 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) + self.stubs.Set(nova.image.fake._FakeImageService, + 'show_by_name', + fake_show_by_name) def tearDown(self): self.stubs.UnsetAll() diff --git a/nova/tests/test_vsa_volumes.py b/nova/tests/test_vsa_volumes.py new file mode 100644 index 000000000..0facd3b1b --- /dev/null +++ b/nova/tests/test_vsa_volumes.py @@ -0,0 +1,108 @@ +# 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 + +from nova import exception +from nova import flags +from nova import vsa +from nova import volume +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.volumes') + + +def _default_volume_param(): + return { + 'size': 1, + 'snapshot_id': None, + 'name': 'Test volume name', + 'description': 'Test volume desc name' + } + + +class VsaVolumesTestCase(test.TestCase): + + def setUp(self): + super(VsaVolumesTestCase, self).setUp() + self.stubs = stubout.StubOutForTesting() + self.vsa_api = vsa.API() + self.volume_api = volume.API() + + self.context_non_admin = context.RequestContext(None, None) + self.context = context.get_admin_context() + + def fake_show_by_name(meh, context, name): + return {'id': 1, 'properties': {'kernel_id': 1, 'ramdisk_id': 1}} + + self.stubs.Set(nova.image.fake._FakeImageService, + 'show_by_name', + fake_show_by_name) + + param = {'display_name': 'VSA name test'} + vsa_ref = self.vsa_api.create(self.context, **param) + self.vsa_id = vsa_ref['id'] + + def tearDown(self): + self.vsa_api.delete(self.context, self.vsa_id) + self.stubs.UnsetAll() + super(VsaVolumesTestCase, self).tearDown() + + def test_vsa_volume_create_delete(self): + """ Check if volume properly created and deleted. """ + vols1 = self.volume_api.get_all_by_vsa(self.context, + self.vsa_id, "from") + volume_param = _default_volume_param() + volume_param['from_vsa_id'] = self.vsa_id + volume_ref = self.volume_api.create(self.context, **volume_param) + + self.assertEqual(volume_ref['display_name'], + volume_param['name']) + self.assertEqual(volume_ref['display_description'], + volume_param['description']) + self.assertEqual(volume_ref['size'], + volume_param['size']) + self.assertEqual(volume_ref['status'], + 'available') + + vols2 = self.volume_api.get_all_by_vsa(self.context, + self.vsa_id, "from") + self.assertEqual(len(vols1) + 1, len(vols2)) + + self.volume_api.delete(self.context, volume_ref['id']) + vols3 = self.volume_api.get_all_by_vsa(self.context, + self.vsa_id, "from") + self.assertEqual(len(vols3) + 1, len(vols2)) + + def test_vsa_volume_delete_nonavail_volume(self): + """ Check volume deleton in different states. """ + volume_param = _default_volume_param() + volume_param['from_vsa_id'] = self.vsa_id + volume_ref = self.volume_api.create(self.context, **volume_param) + + self.volume_api.update(self.context, + volume_ref['id'], {'status': 'in-use'}) + self.assertRaises(exception.ApiError, + self.volume_api.delete, + self.context, volume_ref['id']) + + self.volume_api.update(self.context, + volume_ref['id'], {'status': 'error'}) + self.volume_api.delete(self.context, volume_ref['id']) -- cgit From 336b2703ef90fcd7b422434434c9967880b97204 Mon Sep 17 00:00:00 2001 From: "vladimir.p" Date: Tue, 26 Jul 2011 13:28:23 -0700 Subject: pep8 compliance --- nova/tests/test_vsa_volumes.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'nova/tests') diff --git a/nova/tests/test_vsa_volumes.py b/nova/tests/test_vsa_volumes.py index 0facd3b1b..e1d4cd756 100644 --- a/nova/tests/test_vsa_volumes.py +++ b/nova/tests/test_vsa_volumes.py @@ -67,7 +67,7 @@ class VsaVolumesTestCase(test.TestCase): def test_vsa_volume_create_delete(self): """ Check if volume properly created and deleted. """ - vols1 = self.volume_api.get_all_by_vsa(self.context, + vols1 = self.volume_api.get_all_by_vsa(self.context, self.vsa_id, "from") volume_param = _default_volume_param() volume_param['from_vsa_id'] = self.vsa_id @@ -82,7 +82,7 @@ class VsaVolumesTestCase(test.TestCase): self.assertEqual(volume_ref['status'], 'available') - vols2 = self.volume_api.get_all_by_vsa(self.context, + vols2 = self.volume_api.get_all_by_vsa(self.context, self.vsa_id, "from") self.assertEqual(len(vols1) + 1, len(vols2)) @@ -90,7 +90,7 @@ class VsaVolumesTestCase(test.TestCase): vols3 = self.volume_api.get_all_by_vsa(self.context, self.vsa_id, "from") self.assertEqual(len(vols3) + 1, len(vols2)) - + def test_vsa_volume_delete_nonavail_volume(self): """ Check volume deleton in different states. """ volume_param = _default_volume_param() -- cgit From 401de172b86a13010885e70bc78351e72a7dfde3 Mon Sep 17 00:00:00 2001 From: "vladimir.p" Date: Wed, 27 Jul 2011 22:49:16 -0700 Subject: prior to nova-1336 merge --- nova/tests/api/openstack/test_extensions.py | 7 +- nova/tests/scheduler/test_vsa_scheduler.py | 616 ++++++++++++++++++++++++++++ nova/tests/test_vsa.py | 2 + nova/tests/test_vsa_volumes.py | 23 +- 4 files changed, 644 insertions(+), 4 deletions(-) create mode 100644 nova/tests/scheduler/test_vsa_scheduler.py (limited to 'nova/tests') diff --git a/nova/tests/api/openstack/test_extensions.py b/nova/tests/api/openstack/test_extensions.py index d459c694f..2febe50e5 100644 --- a/nova/tests/api/openstack/test_extensions.py +++ b/nova/tests/api/openstack/test_extensions.py @@ -97,8 +97,9 @@ class ExtensionControllerTest(unittest.TestCase): data = json.loads(response.body) names = [x['name'] for x in data['extensions']] names.sort() - self.assertEqual(names, ["FlavorExtraSpecs", "Floating_ips", - "Fox In Socks", "Hosts", "Multinic", "Volumes"]) + self.assertEqual(names, ["DriveTypes", "FlavorExtraSpecs", + "Floating_ips", "Fox In Socks", "Hosts", "Multinic", "VSAs", + "Volumes"]) # Make sure that at least Fox in Sox is correct. (fox_ext,) = [ @@ -145,7 +146,7 @@ class ExtensionControllerTest(unittest.TestCase): # Make sure we have all the extensions. exts = root.findall('{0}extension'.format(NS)) - self.assertEqual(len(exts), 6) + self.assertEqual(len(exts), 8) # Make sure that at least Fox in Sox is correct. (fox_ext,) = [x for x in exts if x.get('alias') == 'FOXNSOX'] diff --git a/nova/tests/scheduler/test_vsa_scheduler.py b/nova/tests/scheduler/test_vsa_scheduler.py new file mode 100644 index 000000000..697ad3842 --- /dev/null +++ b/nova/tests/scheduler/test_vsa_scheduler.py @@ -0,0 +1,616 @@ +# 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 nova +from nova import exception +from nova import flags +from nova import db +from nova import context +from nova import test +from nova import utils +from nova import log as logging + +from nova.scheduler import vsa as vsa_sched +from nova.scheduler import driver + +FLAGS = flags.FLAGS +LOG = logging.getLogger('nova.tests.scheduler.vsa') + +scheduled_volumes = [] +scheduled_volume = {} +global_volume = {} + + +class FakeVsaLeastUsedScheduler( + vsa_sched.VsaSchedulerLeastUsedHost): + # No need to stub anything at the moment + pass + + +class FakeVsaMostAvailCapacityScheduler( + vsa_sched.VsaSchedulerMostAvailCapacity): + # No need to stub anything at the moment + pass + + +class VsaSchedulerTestCase(test.TestCase): + + def _get_vol_creation_request(self, num_vols, drive_ix, size=0): + volume_params = [] + for i in range(num_vols): + drive_type = {'id': i, + 'name': 'name_' + str(drive_ix), + 'type': 'type_' + str(drive_ix), + 'size_gb': 1 + 100 * (drive_ix)} + volume = {'size': size, + 'snapshot_id': None, + 'name': 'vol_' + str(i), + 'description': None, + 'drive_ref': drive_type} + volume_params.append(volume) + + return {'num_volumes': len(volume_params), + 'vsa_id': 123, + 'volumes': volume_params} + + def _generate_default_service_states(self): + service_states = {} + for i in range(self.host_num): + host = {} + hostname = 'host_' + str(i) + if hostname in self.exclude_host_list: + continue + + host['volume'] = {'timestamp': utils.utcnow(), + 'drive_qos_info': {}} + + for j in range(self.drive_type_start_ix, + self.drive_type_start_ix + self.drive_type_num): + dtype = {} + dtype['Name'] = 'name_' + str(j) + dtype['DriveType'] = 'type_' + str(j) + dtype['TotalDrives'] = 2 * (self.init_num_drives + i) + dtype['DriveCapacity'] = vsa_sched.GB_TO_BYTES(1 + 100 * j) + dtype['TotalCapacity'] = dtype['TotalDrives'] * \ + dtype['DriveCapacity'] + dtype['AvailableCapacity'] = (dtype['TotalDrives'] - i) * \ + dtype['DriveCapacity'] + dtype['DriveRpm'] = 7200 + dtype['DifCapable'] = 0 + dtype['SedCapable'] = 0 + dtype['PartitionDrive'] = { + 'PartitionSize': 0, + 'NumOccupiedPartitions': 0, + 'NumFreePartitions': 0} + dtype['FullDrive'] = { + 'NumFreeDrives': dtype['TotalDrives'] - i, + 'NumOccupiedDrives': i} + host['volume']['drive_qos_info'][dtype['Name']] = dtype + + service_states[hostname] = host + + return service_states + + def _print_service_states(self): + for host, host_val in self.service_states.iteritems(): + LOG.info(_("Host %s"), host) + total_used = 0 + total_available = 0 + qos = host_val['volume']['drive_qos_info'] + + for k, d in qos.iteritems(): + LOG.info("\t%s: type %s: drives (used %2d, total %2d) "\ + "size %3d, total %4d, used %4d, avail %d", + k, d['DriveType'], + d['FullDrive']['NumOccupiedDrives'], d['TotalDrives'], + vsa_sched.BYTES_TO_GB(d['DriveCapacity']), + vsa_sched.BYTES_TO_GB(d['TotalCapacity']), + vsa_sched.BYTES_TO_GB(d['TotalCapacity'] - \ + d['AvailableCapacity']), + vsa_sched.BYTES_TO_GB(d['AvailableCapacity'])) + + total_used += vsa_sched.BYTES_TO_GB(d['TotalCapacity'] - \ + d['AvailableCapacity']) + total_available += vsa_sched.BYTES_TO_GB( + d['AvailableCapacity']) + LOG.info("Host %s: used %d, avail %d", + host, total_used, total_available) + + def _set_service_states(self, host_num, + drive_type_start_ix, drive_type_num, + init_num_drives=10, + exclude_host_list=[]): + self.host_num = host_num + self.drive_type_start_ix = drive_type_start_ix + self.drive_type_num = drive_type_num + self.exclude_host_list = exclude_host_list + self.init_num_drives = init_num_drives + self.service_states = self._generate_default_service_states() + + def _get_service_states(self): + return self.service_states + + def _fake_get_service_states(self): + return self._get_service_states() + + def _fake_provision_volume(self, context, vol, vsa_id, availability_zone): + global scheduled_volumes + scheduled_volumes.append(dict(vol=vol, + vsa_id=vsa_id, + az=availability_zone)) + name = vol['name'] + host = vol['host'] + LOG.debug(_("Test: provision vol %(name)s on host %(host)s"), + locals()) + LOG.debug(_("\t vol=%(vol)s"), locals()) + pass + + def _fake_vsa_update(self, context, vsa_id, values): + LOG.debug(_("Test: VSA update request: vsa_id=%(vsa_id)s "\ + "values=%(values)s"), locals()) + pass + + def _fake_volume_create(self, context, options): + LOG.debug(_("Test: Volume create: %s"), options) + options['id'] = 123 + global global_volume + global_volume = options + return options + + def _fake_volume_get(self, context, volume_id): + LOG.debug(_("Test: Volume get request: id=%(volume_id)s"), locals()) + global global_volume + global_volume['id'] = volume_id + global_volume['availability_zone'] = None + return global_volume + + def _fake_volume_update(self, context, volume_id, values): + LOG.debug(_("Test: Volume update request: id=%(volume_id)s "\ + "values=%(values)s"), locals()) + global scheduled_volume + scheduled_volume = {'id': volume_id, 'host': values['host']} + pass + + def _fake_service_get_by_args(self, context, host, binary): + return "service" + + def _fake_service_is_up_True(self, service): + return True + + def _fake_service_is_up_False(self, service): + return False + + def setUp(self, sched_class=None): + super(VsaSchedulerTestCase, self).setUp() + self.stubs = stubout.StubOutForTesting() + self.context_non_admin = context.RequestContext(None, None) + self.context = context.get_admin_context() + + if sched_class is None: + self.sched = FakeVsaLeastUsedScheduler() + else: + self.sched = sched_class + + self.host_num = 10 + self.drive_type_num = 5 + + self.stubs.Set(self.sched, + '_get_service_states', self._fake_get_service_states) + self.stubs.Set(self.sched, + '_provision_volume', self._fake_provision_volume) + self.stubs.Set(nova.db, 'vsa_update', self._fake_vsa_update) + + self.stubs.Set(nova.db, 'volume_get', self._fake_volume_get) + self.stubs.Set(nova.db, 'volume_update', self._fake_volume_update) + + def tearDown(self): + self.stubs.UnsetAll() + super(VsaSchedulerTestCase, self).tearDown() + + def test_vsa_sched_create_volumes_simple(self): + global scheduled_volumes + scheduled_volumes = [] + self._set_service_states(host_num=10, + drive_type_start_ix=0, + drive_type_num=5, + init_num_drives=10, + exclude_host_list=['host_1', 'host_3']) + prev = self._generate_default_service_states() + request_spec = self._get_vol_creation_request(num_vols=3, drive_ix=2) + + self.sched.schedule_create_volumes(self.context, + request_spec, + availability_zone=None) + + self.assertEqual(len(scheduled_volumes), 3) + self.assertEqual(scheduled_volumes[0]['vol']['host'], 'host_0') + self.assertEqual(scheduled_volumes[1]['vol']['host'], 'host_2') + self.assertEqual(scheduled_volumes[2]['vol']['host'], 'host_4') + + cur = self._get_service_states() + for host in ['host_0', 'host_2', 'host_4']: + cur_dtype = cur[host]['volume']['drive_qos_info']['name_2'] + prev_dtype = prev[host]['volume']['drive_qos_info']['name_2'] + self.assertEqual(cur_dtype['DriveType'], prev_dtype['DriveType']) + self.assertEqual(cur_dtype['FullDrive']['NumFreeDrives'], + prev_dtype['FullDrive']['NumFreeDrives'] - 1) + self.assertEqual(cur_dtype['FullDrive']['NumOccupiedDrives'], + prev_dtype['FullDrive']['NumOccupiedDrives'] + 1) + + def test_vsa_sched_no_drive_type(self): + self._set_service_states(host_num=10, + drive_type_start_ix=0, + drive_type_num=5, + init_num_drives=1) + request_spec = self._get_vol_creation_request(num_vols=1, drive_ix=6) + self.assertRaises(driver.WillNotSchedule, + self.sched.schedule_create_volumes, + self.context, + request_spec, + availability_zone=None) + + def test_vsa_sched_no_enough_drives(self): + global scheduled_volumes + scheduled_volumes = [] + + self._set_service_states(host_num=3, + drive_type_start_ix=0, + drive_type_num=1, + init_num_drives=0) + prev = self._generate_default_service_states() + request_spec = self._get_vol_creation_request(num_vols=3, drive_ix=0) + + self.assertRaises(driver.WillNotSchedule, + self.sched.schedule_create_volumes, + self.context, + request_spec, + availability_zone=None) + + # check that everything was returned back + cur = self._get_service_states() + for k, v in prev.iteritems(): + self.assertEqual(prev[k]['volume']['drive_qos_info'], + cur[k]['volume']['drive_qos_info']) + + def test_vsa_sched_wrong_topic(self): + self._set_service_states(host_num=1, + drive_type_start_ix=0, + drive_type_num=5, + init_num_drives=1) + states = self._get_service_states() + new_states = {} + new_states['host_0'] = {'compute': states['host_0']['volume']} + self.service_states = new_states + request_spec = self._get_vol_creation_request(num_vols=1, drive_ix=0) + + self.assertRaises(driver.WillNotSchedule, + self.sched.schedule_create_volumes, + self.context, + request_spec, + availability_zone=None) + + def test_vsa_sched_provision_volume(self): + global global_volume + global_volume = {} + self._set_service_states(host_num=1, + drive_type_start_ix=0, + drive_type_num=1, + init_num_drives=1) + request_spec = self._get_vol_creation_request(num_vols=1, drive_ix=0) + + self.stubs.UnsetAll() + self.stubs.Set(self.sched, + '_get_service_states', self._fake_get_service_states) + self.stubs.Set(nova.db, 'volume_create', self._fake_volume_create) + + self.sched.schedule_create_volumes(self.context, + request_spec, + availability_zone=None) + + self.assertEqual(request_spec['volumes'][0]['name'], + global_volume['display_name']) + + def test_vsa_sched_no_free_drives(self): + self._set_service_states(host_num=1, + drive_type_start_ix=0, + drive_type_num=1, + init_num_drives=1) + request_spec = self._get_vol_creation_request(num_vols=1, drive_ix=0) + + self.sched.schedule_create_volumes(self.context, + request_spec, + availability_zone=None) + + cur = self._get_service_states() + cur_dtype = cur['host_0']['volume']['drive_qos_info']['name_0'] + self.assertEqual(cur_dtype['FullDrive']['NumFreeDrives'], 1) + + new_request = self._get_vol_creation_request(num_vols=1, drive_ix=0) + + self.sched.schedule_create_volumes(self.context, + request_spec, + availability_zone=None) + self._print_service_states() + + self.assertRaises(driver.WillNotSchedule, + self.sched.schedule_create_volumes, + self.context, + new_request, + availability_zone=None) + + def test_vsa_sched_forced_host(self): + global scheduled_volumes + scheduled_volumes = [] + + self._set_service_states(host_num=10, + drive_type_start_ix=0, + drive_type_num=5, + init_num_drives=10) + + request_spec = self._get_vol_creation_request(num_vols=3, drive_ix=2) + + self.assertRaises(exception.HostBinaryNotFound, + self.sched.schedule_create_volumes, + self.context, + request_spec, + availability_zone="nova:host_5") + + self.stubs.Set(nova.db, + 'service_get_by_args', self._fake_service_get_by_args) + self.stubs.Set(self.sched, + 'service_is_up', self._fake_service_is_up_False) + + self.assertRaises(driver.WillNotSchedule, + self.sched.schedule_create_volumes, + self.context, + request_spec, + availability_zone="nova:host_5") + + self.stubs.Set(self.sched, + 'service_is_up', self._fake_service_is_up_True) + + self.sched.schedule_create_volumes(self.context, + request_spec, + availability_zone="nova:host_5") + + self.assertEqual(len(scheduled_volumes), 3) + self.assertEqual(scheduled_volumes[0]['vol']['host'], 'host_5') + self.assertEqual(scheduled_volumes[1]['vol']['host'], 'host_5') + self.assertEqual(scheduled_volumes[2]['vol']['host'], 'host_5') + + def test_vsa_sched_create_volumes_partition(self): + global scheduled_volumes + scheduled_volumes = [] + self._set_service_states(host_num=5, + drive_type_start_ix=0, + drive_type_num=5, + init_num_drives=1, + exclude_host_list=['host_0', 'host_2']) + prev = self._generate_default_service_states() + request_spec = self._get_vol_creation_request(num_vols=3, + drive_ix=3, + size=50) + self.sched.schedule_create_volumes(self.context, + request_spec, + availability_zone=None) + + self.assertEqual(len(scheduled_volumes), 3) + self.assertEqual(scheduled_volumes[0]['vol']['host'], 'host_1') + self.assertEqual(scheduled_volumes[1]['vol']['host'], 'host_3') + self.assertEqual(scheduled_volumes[2]['vol']['host'], 'host_4') + + cur = self._get_service_states() + for host in ['host_1', 'host_3', 'host_4']: + cur_dtype = cur[host]['volume']['drive_qos_info']['name_3'] + prev_dtype = prev[host]['volume']['drive_qos_info']['name_3'] + + self.assertEqual(cur_dtype['DriveType'], prev_dtype['DriveType']) + self.assertEqual(cur_dtype['FullDrive']['NumFreeDrives'], + prev_dtype['FullDrive']['NumFreeDrives'] - 1) + self.assertEqual(cur_dtype['FullDrive']['NumOccupiedDrives'], + prev_dtype['FullDrive']['NumOccupiedDrives'] + 1) + + self.assertEqual(prev_dtype['PartitionDrive'] + ['NumOccupiedPartitions'], 0) + self.assertEqual(cur_dtype['PartitionDrive'] + ['NumOccupiedPartitions'], 1) + self.assertEqual(cur_dtype['PartitionDrive'] + ['NumFreePartitions'], 5) + + self.assertEqual(prev_dtype['PartitionDrive'] + ['NumFreePartitions'], 0) + self.assertEqual(prev_dtype['PartitionDrive'] + ['PartitionSize'], 0) + + def test_vsa_sched_create_single_volume_az(self): + global scheduled_volume + scheduled_volume = {} + + def _fake_volume_get_az(context, volume_id): + LOG.debug(_("Test: Volume get: id=%(volume_id)s"), locals()) + return {'id': volume_id, 'availability_zone': 'nova:host_3'} + + self.stubs.Set(nova.db, 'volume_get', _fake_volume_get_az) + self.stubs.Set(nova.db, + 'service_get_by_args', self._fake_service_get_by_args) + self.stubs.Set(self.sched, + 'service_is_up', self._fake_service_is_up_True) + + host = self.sched.schedule_create_volume(self.context, + 123, availability_zone=None) + + self.assertEqual(host, 'host_3') + self.assertEqual(scheduled_volume['id'], 123) + self.assertEqual(scheduled_volume['host'], 'host_3') + + def test_vsa_sched_create_single_non_vsa_volume(self): + global scheduled_volume + scheduled_volume = {} + + global global_volume + global_volume = {} + global_volume['drive_type'] = None + + self.assertRaises(driver.NoValidHost, + self.sched.schedule_create_volume, + self.context, + 123, + availability_zone=None) + + def test_vsa_sched_create_single_volume(self): + global scheduled_volume + scheduled_volume = {} + self._set_service_states(host_num=10, + drive_type_start_ix=0, + drive_type_num=5, + init_num_drives=10, + exclude_host_list=['host_0', 'host_1']) + prev = self._generate_default_service_states() + + global global_volume + global_volume = {} + + drive_ix = 2 + drive_type = {'id': drive_ix, + 'name': 'name_' + str(drive_ix), + 'type': 'type_' + str(drive_ix), + 'size_gb': 1 + 100 * (drive_ix)} + + global_volume['drive_type'] = drive_type + global_volume['size'] = 0 + + host = self.sched.schedule_create_volume(self.context, + 123, availability_zone=None) + + self.assertEqual(host, 'host_2') + self.assertEqual(scheduled_volume['id'], 123) + self.assertEqual(scheduled_volume['host'], 'host_2') + + +class VsaSchedulerTestCaseMostAvail(VsaSchedulerTestCase): + + def setUp(self): + super(VsaSchedulerTestCaseMostAvail, self).setUp( + FakeVsaMostAvailCapacityScheduler()) + + def tearDown(self): + self.stubs.UnsetAll() + super(VsaSchedulerTestCaseMostAvail, self).tearDown() + + def test_vsa_sched_create_single_volume(self): + global scheduled_volume + scheduled_volume = {} + self._set_service_states(host_num=10, + drive_type_start_ix=0, + drive_type_num=5, + init_num_drives=10, + exclude_host_list=['host_0', 'host_1']) + prev = self._generate_default_service_states() + + global global_volume + global_volume = {} + + drive_ix = 2 + drive_type = {'id': drive_ix, + 'name': 'name_' + str(drive_ix), + 'type': 'type_' + str(drive_ix), + 'size_gb': 1 + 100 * (drive_ix)} + + global_volume['drive_type'] = drive_type + global_volume['size'] = 0 + + host = self.sched.schedule_create_volume(self.context, + 123, availability_zone=None) + + self.assertEqual(host, 'host_9') + self.assertEqual(scheduled_volume['id'], 123) + self.assertEqual(scheduled_volume['host'], 'host_9') + + def test_vsa_sched_create_volumes_simple(self): + global scheduled_volumes + scheduled_volumes = [] + self._set_service_states(host_num=10, + drive_type_start_ix=0, + drive_type_num=5, + init_num_drives=10, + exclude_host_list=['host_1', 'host_3']) + prev = self._generate_default_service_states() + request_spec = self._get_vol_creation_request(num_vols=3, drive_ix=2) + + self._print_service_states() + + self.sched.schedule_create_volumes(self.context, + request_spec, + availability_zone=None) + + self.assertEqual(len(scheduled_volumes), 3) + self.assertEqual(scheduled_volumes[0]['vol']['host'], 'host_9') + self.assertEqual(scheduled_volumes[1]['vol']['host'], 'host_8') + self.assertEqual(scheduled_volumes[2]['vol']['host'], 'host_7') + + cur = self._get_service_states() + for host in ['host_9', 'host_8', 'host_7']: + cur_dtype = cur[host]['volume']['drive_qos_info']['name_2'] + prev_dtype = prev[host]['volume']['drive_qos_info']['name_2'] + self.assertEqual(cur_dtype['DriveType'], prev_dtype['DriveType']) + self.assertEqual(cur_dtype['FullDrive']['NumFreeDrives'], + prev_dtype['FullDrive']['NumFreeDrives'] - 1) + self.assertEqual(cur_dtype['FullDrive']['NumOccupiedDrives'], + prev_dtype['FullDrive']['NumOccupiedDrives'] + 1) + + def test_vsa_sched_create_volumes_partition(self): + global scheduled_volumes + scheduled_volumes = [] + self._set_service_states(host_num=5, + drive_type_start_ix=0, + drive_type_num=5, + init_num_drives=1, + exclude_host_list=['host_0', 'host_2']) + prev = self._generate_default_service_states() + request_spec = self._get_vol_creation_request(num_vols=3, + drive_ix=3, + size=50) + self.sched.schedule_create_volumes(self.context, + request_spec, + availability_zone=None) + + self.assertEqual(len(scheduled_volumes), 3) + self.assertEqual(scheduled_volumes[0]['vol']['host'], 'host_4') + self.assertEqual(scheduled_volumes[1]['vol']['host'], 'host_3') + self.assertEqual(scheduled_volumes[2]['vol']['host'], 'host_1') + + cur = self._get_service_states() + for host in ['host_1', 'host_3', 'host_4']: + cur_dtype = cur[host]['volume']['drive_qos_info']['name_3'] + prev_dtype = prev[host]['volume']['drive_qos_info']['name_3'] + + self.assertEqual(cur_dtype['DriveType'], prev_dtype['DriveType']) + self.assertEqual(cur_dtype['FullDrive']['NumFreeDrives'], + prev_dtype['FullDrive']['NumFreeDrives'] - 1) + self.assertEqual(cur_dtype['FullDrive']['NumOccupiedDrives'], + prev_dtype['FullDrive']['NumOccupiedDrives'] + 1) + + self.assertEqual(prev_dtype['PartitionDrive'] + ['NumOccupiedPartitions'], 0) + self.assertEqual(cur_dtype['PartitionDrive'] + ['NumOccupiedPartitions'], 1) + self.assertEqual(cur_dtype['PartitionDrive'] + ['NumFreePartitions'], 5) + self.assertEqual(prev_dtype['PartitionDrive'] + ['NumFreePartitions'], 0) + self.assertEqual(prev_dtype['PartitionDrive'] + ['PartitionSize'], 0) diff --git a/nova/tests/test_vsa.py b/nova/tests/test_vsa.py index 8e4d58960..cff23a800 100644 --- a/nova/tests/test_vsa.py +++ b/nova/tests/test_vsa.py @@ -22,6 +22,7 @@ from xml.etree.ElementTree import Element, SubElement from nova import exception from nova import flags from nova import vsa +from nova import volume from nova import db from nova import context from nova import test @@ -50,6 +51,7 @@ class VsaTestCase(test.TestCase): super(VsaTestCase, self).setUp() self.stubs = stubout.StubOutForTesting() self.vsa_api = vsa.API() + self.volume_api = volume.API() self.context_non_admin = context.RequestContext(None, None) self.context = context.get_admin_context() diff --git a/nova/tests/test_vsa_volumes.py b/nova/tests/test_vsa_volumes.py index e1d4cd756..d451a4377 100644 --- a/nova/tests/test_vsa_volumes.py +++ b/nova/tests/test_vsa_volumes.py @@ -61,7 +61,8 @@ class VsaVolumesTestCase(test.TestCase): self.vsa_id = vsa_ref['id'] def tearDown(self): - self.vsa_api.delete(self.context, self.vsa_id) + if self.vsa_id: + self.vsa_api.delete(self.context, self.vsa_id) self.stubs.UnsetAll() super(VsaVolumesTestCase, self).tearDown() @@ -106,3 +107,23 @@ class VsaVolumesTestCase(test.TestCase): self.volume_api.update(self.context, volume_ref['id'], {'status': 'error'}) self.volume_api.delete(self.context, volume_ref['id']) + + def test_vsa_volume_delete_vsa_with_volumes(self): + """ Check volume deleton in different states. """ + + vols1 = self.volume_api.get_all_by_vsa(self.context, + self.vsa_id, "from") + for i in range(3): + volume_param = _default_volume_param() + volume_param['from_vsa_id'] = self.vsa_id + volume_ref = self.volume_api.create(self.context, **volume_param) + + vols2 = self.volume_api.get_all_by_vsa(self.context, + self.vsa_id, "from") + self.assertEqual(len(vols1) + 3, len(vols2)) + + self.vsa_api.delete(self.context, self.vsa_id) + + vols3 = self.volume_api.get_all_by_vsa(self.context, + self.vsa_id, "from") + self.assertEqual(len(vols1), len(vols3)) -- cgit From 57b8f976f18b1f45de16ef8e87a6e215c009d228 Mon Sep 17 00:00:00 2001 From: "vladimir.p" Date: Thu, 11 Aug 2011 12:04:03 -0700 Subject: moved vsa_id to metadata. Added search my meta --- nova/tests/test_compute.py | 63 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) (limited to 'nova/tests') diff --git a/nova/tests/test_compute.py b/nova/tests/test_compute.py index 80f7ff489..661acc980 100644 --- a/nova/tests/test_compute.py +++ b/nova/tests/test_compute.py @@ -1320,6 +1320,69 @@ class ComputeTestCase(test.TestCase): db.instance_destroy(c, instance_id2) db.instance_destroy(c, instance_id3) + def test_get_all_by_metadata(self): + """Test searching instances by metadata""" + + c = context.get_admin_context() + instance_id0 = self._create_instance() + instance_id1 = self._create_instance({ + 'metadata': {'key1': 'value1'}}) + instance_id2 = self._create_instance({ + 'metadata': {'key2': 'value2'}}) + instance_id3 = self._create_instance({ + 'metadata': {'key3': 'value3'}}) + instance_id4 = self._create_instance({ + 'metadata': {'key3': 'value3', + 'key4': 'value4'}}) + + # get all instances + instances = self.compute_api.get_all(c, + search_opts={'metadata': {}}) + self.assertEqual(len(instances), 5) + + # wrong key/value combination + instances = self.compute_api.get_all(c, + search_opts={'metadata': {'key1': 'value3'}}) + self.assertEqual(len(instances), 0) + + # non-existing keys + instances = self.compute_api.get_all(c, + search_opts={'metadata': {'key5': 'value1'}}) + self.assertEqual(len(instances), 0) + + # find existing instance + instances = self.compute_api.get_all(c, + search_opts={'metadata': {'key2': 'value2'}}) + self.assertEqual(len(instances), 1) + self.assertEqual(instances[0].id, instance_id2) + + instances = self.compute_api.get_all(c, + search_opts={'metadata': {'key3': 'value3'}}) + self.assertEqual(len(instances), 2) + instance_ids = [instance.id for instance in instances] + self.assertTrue(instance_id3 in instance_ids) + self.assertTrue(instance_id4 in instance_ids) + + # multiple criterias as a dict + instances = self.compute_api.get_all(c, + search_opts={'metadata': {'key3': 'value3', + 'key4': 'value4'}}) + self.assertEqual(len(instances), 1) + self.assertEqual(instances[0].id, instance_id4) + + # multiple criterias as a list + instances = self.compute_api.get_all(c, + search_opts={'metadata': [{'key4': 'value4'}, + {'key3': 'value3'}]}) + self.assertEqual(len(instances), 1) + self.assertEqual(instances[0].id, instance_id4) + + db.instance_destroy(c, instance_id0) + db.instance_destroy(c, instance_id1) + db.instance_destroy(c, instance_id2) + db.instance_destroy(c, instance_id3) + db.instance_destroy(c, instance_id4) + @staticmethod def _parse_db_block_device_mapping(bdm_ref): attr_list = ('delete_on_termination', 'device_name', 'no_device', -- cgit From cabf9cc8f29ad8c99971c434516e1b911f07f32f Mon Sep 17 00:00:00 2001 From: "vladimir.p" Date: Wed, 17 Aug 2011 16:27:12 -0700 Subject: nova-manage VSA print & forced update_cap changes; fixed bug with report capabilities; added IP address to VSA APIs; added instances to APIs --- nova/tests/api/openstack/contrib/test_vsa.py | 2 ++ 1 file changed, 2 insertions(+) (limited to 'nova/tests') diff --git a/nova/tests/api/openstack/contrib/test_vsa.py b/nova/tests/api/openstack/contrib/test_vsa.py index 3c9136e14..a9b76b0ff 100644 --- a/nova/tests/api/openstack/contrib/test_vsa.py +++ b/nova/tests/api/openstack/contrib/test_vsa.py @@ -46,6 +46,7 @@ def _get_default_vsa_param(): 'display_description': 'Test_VSA_description', 'vc_count': 1, 'instance_type': 'm1.small', + 'instance_type_id': 5, 'image_name': None, 'availability_zone': None, 'storage': [], @@ -58,6 +59,7 @@ def stub_vsa_create(self, context, **param): LOG.debug(_("_create: param=%s"), param) param['id'] = 123 param['name'] = 'Test name' + param['instance_type_id'] = 5 last_param = param return param -- cgit From 48cd9689de31e408c792052747f714a9dbe1f8f7 Mon Sep 17 00:00:00 2001 From: "vladimir.p" Date: Wed, 24 Aug 2011 15:51:29 -0700 Subject: added virtio flag; associate address for VSA; cosmetic changes. Prior to volume_types merge --- nova/tests/test_drive_types.py | 59 +++++++++++++++++++++--------------------- nova/tests/test_vsa.py | 2 +- 2 files changed, 30 insertions(+), 31 deletions(-) (limited to 'nova/tests') diff --git a/nova/tests/test_drive_types.py b/nova/tests/test_drive_types.py index e91c41321..b52e6705b 100644 --- a/nova/tests/test_drive_types.py +++ b/nova/tests/test_drive_types.py @@ -2,7 +2,6 @@ # Copyright (c) 2011 Zadara Storage Inc. # Copyright (c) 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 @@ -28,21 +27,21 @@ from nova import test from nova.vsa import drive_types FLAGS = flags.FLAGS -LOG = logging.getLogger('nova.tests.vsa') +LOG = logging.getLogger('nova.tests.test_drive_types') class DriveTypesTestCase(test.TestCase): """Test cases for driver types code""" def setUp(self): super(DriveTypesTestCase, self).setUp() - self.cntx = context.RequestContext(None, None) - self.cntx_admin = context.get_admin_context() - self._dtype = self._create_drive_type() + self.ctxt = context.RequestContext(None, None) + self.ctxt_admin = context.get_admin_context() + self._dtype = self._create_default_drive_type() def tearDown(self): self._dtype = None - def _create_drive_type(self): + def _create_default_drive_type(self): """Create a volume object.""" dtype = {} dtype['type'] = 'SATA' @@ -51,97 +50,97 @@ class DriveTypesTestCase(test.TestCase): dtype['capabilities'] = None dtype['visible'] = True - LOG.debug(_("Drive Type created %s"), dtype) + LOG.debug(_("Default values for Drive Type: %s"), dtype) return dtype def test_drive_type_create_delete(self): dtype = self._dtype - prev_all_dtypes = drive_types.get_all(self.cntx_admin, False) + prev_all_dtypes = drive_types.get_all(self.ctxt_admin, False) - new = drive_types.create(self.cntx_admin, **dtype) + new = drive_types.create(self.ctxt_admin, **dtype) for k, v in dtype.iteritems(): self.assertEqual(v, new[k], 'one of fields doesnt match') - new_all_dtypes = drive_types.get_all(self.cntx_admin, False) + new_all_dtypes = drive_types.get_all(self.ctxt_admin, False) self.assertNotEqual(len(prev_all_dtypes), len(new_all_dtypes), 'drive type was not created') - drive_types.delete(self.cntx_admin, new['id']) - new_all_dtypes = drive_types.get_all(self.cntx_admin, False) + drive_types.delete(self.ctxt_admin, new['id']) + new_all_dtypes = drive_types.get_all(self.ctxt_admin, False) self.assertEqual(prev_all_dtypes, new_all_dtypes, 'drive types was not deleted') def test_drive_type_check_name_generation(self): dtype = self._dtype - new = drive_types.create(self.cntx_admin, **dtype) + new = drive_types.create(self.ctxt_admin, **dtype) expected_name = FLAGS.drive_type_template_short % \ (dtype['type'], dtype['size_gb'], dtype['rpm']) self.assertEqual(new['name'], expected_name, 'name was not generated correctly') dtype['capabilities'] = 'SEC' - new2 = drive_types.create(self.cntx_admin, **dtype) + new2 = drive_types.create(self.ctxt_admin, **dtype) expected_name = FLAGS.drive_type_template_long % \ (dtype['type'], dtype['size_gb'], dtype['rpm'], dtype['capabilities']) self.assertEqual(new2['name'], expected_name, 'name was not generated correctly') - drive_types.delete(self.cntx_admin, new['id']) - drive_types.delete(self.cntx_admin, new2['id']) + drive_types.delete(self.ctxt_admin, new['id']) + drive_types.delete(self.ctxt_admin, new2['id']) def test_drive_type_create_delete_invisible(self): dtype = self._dtype dtype['visible'] = False - prev_all_dtypes = drive_types.get_all(self.cntx_admin, True) - new = drive_types.create(self.cntx_admin, **dtype) + prev_all_dtypes = drive_types.get_all(self.ctxt_admin, True) + new = drive_types.create(self.ctxt_admin, **dtype) - new_all_dtypes = drive_types.get_all(self.cntx_admin, True) + new_all_dtypes = drive_types.get_all(self.ctxt_admin, True) self.assertEqual(prev_all_dtypes, new_all_dtypes) - new_all_dtypes = drive_types.get_all(self.cntx_admin, False) + new_all_dtypes = drive_types.get_all(self.ctxt_admin, False) self.assertNotEqual(prev_all_dtypes, new_all_dtypes) - drive_types.delete(self.cntx_admin, new['id']) + drive_types.delete(self.ctxt_admin, new['id']) def test_drive_type_rename_update(self): dtype = self._dtype dtype['capabilities'] = None - new = drive_types.create(self.cntx_admin, **dtype) + new = drive_types.create(self.ctxt_admin, **dtype) for k, v in dtype.iteritems(): self.assertEqual(v, new[k], 'one of fields doesnt match') new_name = 'NEW_DRIVE_NAME' - new = drive_types.rename(self.cntx_admin, new['name'], new_name) + new = drive_types.rename(self.ctxt_admin, new['name'], new_name) self.assertEqual(new['name'], new_name) - new = drive_types.rename(self.cntx_admin, new_name) + new = drive_types.rename(self.ctxt_admin, new_name) expected_name = FLAGS.drive_type_template_short % \ (dtype['type'], dtype['size_gb'], dtype['rpm']) self.assertEqual(new['name'], expected_name) changes = {'rpm': 7200} - new = drive_types.update(self.cntx_admin, new['id'], **changes) + new = drive_types.update(self.ctxt_admin, new['id'], **changes) for k, v in changes.iteritems(): self.assertEqual(v, new[k], 'one of fields doesnt match') - drive_types.delete(self.cntx_admin, new['id']) + drive_types.delete(self.ctxt_admin, new['id']) def test_drive_type_get(self): dtype = self._dtype - new = drive_types.create(self.cntx_admin, **dtype) + new = drive_types.create(self.ctxt_admin, **dtype) - new2 = drive_types.get(self.cntx_admin, new['id']) + new2 = drive_types.get(self.ctxt_admin, new['id']) for k, v in new2.iteritems(): self.assertEqual(str(new[k]), str(new2[k]), 'one of fields doesnt match') - new2 = drive_types.get_by_name(self.cntx_admin, new['name']) + new2 = drive_types.get_by_name(self.ctxt_admin, new['name']) for k, v in new.iteritems(): self.assertEqual(str(new[k]), str(new2[k]), 'one of fields doesnt match') - drive_types.delete(self.cntx_admin, new['id']) + drive_types.delete(self.ctxt_admin, new['id']) diff --git a/nova/tests/test_vsa.py b/nova/tests/test_vsa.py index cff23a800..726939744 100644 --- a/nova/tests/test_vsa.py +++ b/nova/tests/test_vsa.py @@ -113,7 +113,7 @@ class VsaTestCase(test.TestCase): 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) + self.assertEqual(len(vsa_list2), len(vsa_list1)) param = {'storage': [{'drive_name': 'wrong name'}]} self.assertRaises(exception.ApiError, -- cgit From 4834b920e3186712ab56e65a88c2e8c838d16f9c Mon Sep 17 00:00:00 2001 From: "vladimir.p" Date: Thu, 25 Aug 2011 18:38:35 -0700 Subject: VSA code redesign. Drive types completely replaced by Volume types --- .../api/openstack/contrib/test_drive_types.py | 192 --------------------- nova/tests/api/openstack/contrib/test_vsa.py | 79 +++++---- nova/tests/api/openstack/test_extensions.py | 3 +- nova/tests/scheduler/test_vsa_scheduler.py | 68 +++++--- nova/tests/test_drive_types.py | 146 ---------------- nova/tests/test_vsa.py | 49 +++--- nova/tests/test_vsa_volumes.py | 77 +++++---- nova/tests/test_xenapi.py | 1 + 8 files changed, 156 insertions(+), 459 deletions(-) delete mode 100644 nova/tests/api/openstack/contrib/test_drive_types.py delete mode 100644 nova/tests/test_drive_types.py (limited to 'nova/tests') diff --git a/nova/tests/api/openstack/contrib/test_drive_types.py b/nova/tests/api/openstack/contrib/test_drive_types.py deleted file mode 100644 index 2f7d327d3..000000000 --- a/nova/tests/api/openstack/contrib/test_drive_types.py +++ /dev/null @@ -1,192 +0,0 @@ -# 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 compute -from nova.vsa import drive_types -from nova import exception -from nova import context -from nova import test -from nova import log as logging -from nova.tests.api.openstack import fakes - -from nova.api.openstack.contrib.drive_types import _drive_type_view - -LOG = logging.getLogger('nova.tests.api.openstack.drive_types') - -last_param = {} - - -def _get_default_drive_type(): - param = { - 'name': 'Test drive type', - 'type': 'SATA', - 'size_gb': 123, - 'rpm': '7200', - 'capabilities': '', - 'visible': True - } - return param - - -def _create(context, **param): - global last_param - LOG.debug(_("_create: %s"), param) - param['id'] = 123 - last_param = param - return param - - -def _delete(context, id): - global last_param - last_param = dict(id=id) - - LOG.debug(_("_delete: %s"), locals()) - - -def _get(context, id): - global last_param - last_param = dict(id=id) - - LOG.debug(_("_get: %s"), locals()) - if id != '123': - raise exception.NotFound - - dtype = _get_default_drive_type() - dtype['id'] = id - return dtype - - -def _get_all(context, visible=True): - LOG.debug(_("_get_all: %s"), locals()) - dtype = _get_default_drive_type() - dtype['id'] = 123 - return [dtype] - - -class DriveTypesApiTest(test.TestCase): - def setUp(self): - super(DriveTypesApiTest, self).setUp() - self.stubs = stubout.StubOutForTesting() - fakes.FakeAuthManager.reset_fake_data() - fakes.FakeAuthDatabase.data = {} - fakes.stub_out_networking(self.stubs) - fakes.stub_out_rate_limiting(self.stubs) - fakes.stub_out_auth(self.stubs) - self.stubs.Set(drive_types, "create", _create) - self.stubs.Set(drive_types, "delete", _delete) - self.stubs.Set(drive_types, "get", _get) - self.stubs.Set(drive_types, "get_all", _get_all) - - self.context = context.get_admin_context() - - def tearDown(self): - self.stubs.UnsetAll() - super(DriveTypesApiTest, self).tearDown() - - def test_drive_types_api_create(self): - global last_param - last_param = {} - - dtype = _get_default_drive_type() - dtype['id'] = 123 - - body = dict(drive_type=_drive_type_view(dtype)) - req = webob.Request.blank('/v1.1/zadr-drive_types') - req.method = 'POST' - req.body = json.dumps(body) - req.headers['content-type'] = 'application/json' - - resp = req.get_response(fakes.wsgi_app()) - self.assertEqual(resp.status_int, 200) - - # Compare if parameters were correctly passed to stub - for k, v in last_param.iteritems(): - self.assertEqual(last_param[k], dtype[k]) - - resp_dict = json.loads(resp.body) - - # Compare response - self.assertTrue('drive_type' in resp_dict) - resp_dtype = resp_dict['drive_type'] - self.assertEqual(resp_dtype, _drive_type_view(dtype)) - - def test_drive_types_api_delete(self): - global last_param - last_param = {} - - dtype_id = 123 - req = webob.Request.blank('/v1.1/zadr-drive_types/%d' % dtype_id) - req.method = 'DELETE' - - resp = req.get_response(fakes.wsgi_app()) - self.assertEqual(resp.status_int, 200) - self.assertEqual(str(last_param['id']), str(dtype_id)) - - def test_drive_types_show(self): - global last_param - last_param = {} - - dtype_id = 123 - req = webob.Request.blank('/v1.1/zadr-drive_types/%d' % dtype_id) - req.method = 'GET' - resp = req.get_response(fakes.wsgi_app()) - self.assertEqual(resp.status_int, 200) - self.assertEqual(str(last_param['id']), str(dtype_id)) - - resp_dict = json.loads(resp.body) - - # Compare response - self.assertTrue('drive_type' in resp_dict) - resp_dtype = resp_dict['drive_type'] - exp_dtype = _get_default_drive_type() - exp_dtype['id'] = dtype_id - exp_dtype_view = _drive_type_view(exp_dtype) - for k, v in exp_dtype_view.iteritems(): - self.assertEqual(str(resp_dtype[k]), str(exp_dtype_view[k])) - - def test_drive_types_show_invalid_id(self): - global last_param - last_param = {} - - dtype_id = 234 - req = webob.Request.blank('/v1.1/zadr-drive_types/%d' % dtype_id) - req.method = 'GET' - resp = req.get_response(fakes.wsgi_app()) - self.assertEqual(resp.status_int, 404) - self.assertEqual(str(last_param['id']), str(dtype_id)) - - def test_drive_types_index(self): - - req = webob.Request.blank('/v1.1/zadr-drive_types') - req.method = 'GET' - resp = req.get_response(fakes.wsgi_app()) - self.assertEqual(resp.status_int, 200) - - resp_dict = json.loads(resp.body) - - self.assertTrue('drive_types' in resp_dict) - resp_dtypes = resp_dict['drive_types'] - self.assertEqual(len(resp_dtypes), 1) - - resp_dtype = resp_dtypes.pop() - exp_dtype = _get_default_drive_type() - exp_dtype['id'] = 123 - exp_dtype_view = _drive_type_view(exp_dtype) - for k, v in exp_dtype_view.iteritems(): - self.assertEqual(str(resp_dtype[k]), str(exp_dtype_view[k])) diff --git a/nova/tests/api/openstack/contrib/test_vsa.py b/nova/tests/api/openstack/contrib/test_vsa.py index a9b76b0ff..311b6cb8d 100644 --- a/nova/tests/api/openstack/contrib/test_vsa.py +++ b/nova/tests/api/openstack/contrib/test_vsa.py @@ -18,15 +18,14 @@ import stubout import unittest import webob - +from nova import context +from nova import db from nova import exception from nova import flags -from nova import vsa -from nova import db -from nova import volume -from nova import context -from nova import test from nova import log as logging +from nova import test +from nova import volume +from nova import vsa from nova.api import openstack from nova.tests.api.openstack import fakes import nova.wsgi @@ -120,7 +119,7 @@ class VSAApiTest(test.TestCase): vsa = {"displayName": "VSA Test Name", "displayDescription": "VSA Test Desc"} body = dict(vsa=vsa) - req = webob.Request.blank('/v1.1/zadr-vsa') + req = webob.Request.blank('/v1.1/777/zadr-vsa') req.method = 'POST' req.body = json.dumps(body) req.headers['content-type'] = 'application/json' @@ -139,7 +138,7 @@ class VSAApiTest(test.TestCase): vsa['displayDescription']) def test_vsa_create_no_body(self): - req = webob.Request.blank('/v1.1/zadr-vsa') + req = webob.Request.blank('/v1.1/777/zadr-vsa') req.method = 'POST' req.body = json.dumps({}) req.headers['content-type'] = 'application/json' @@ -152,7 +151,7 @@ class VSAApiTest(test.TestCase): last_param = {} vsa_id = 123 - req = webob.Request.blank('/v1.1/zadr-vsa/%d' % vsa_id) + req = webob.Request.blank('/v1.1/777/zadr-vsa/%d' % vsa_id) req.method = 'DELETE' resp = req.get_response(fakes.wsgi_app()) @@ -164,7 +163,7 @@ class VSAApiTest(test.TestCase): last_param = {} vsa_id = 234 - req = webob.Request.blank('/v1.1/zadr-vsa/%d' % vsa_id) + req = webob.Request.blank('/v1.1/777/zadr-vsa/%d' % vsa_id) req.method = 'DELETE' resp = req.get_response(fakes.wsgi_app()) @@ -176,7 +175,7 @@ class VSAApiTest(test.TestCase): last_param = {} vsa_id = 123 - req = webob.Request.blank('/v1.1/zadr-vsa/%d' % vsa_id) + req = webob.Request.blank('/v1.1/777/zadr-vsa/%d' % vsa_id) req.method = 'GET' resp = req.get_response(fakes.wsgi_app()) self.assertEqual(resp.status_int, 200) @@ -191,14 +190,14 @@ class VSAApiTest(test.TestCase): last_param = {} vsa_id = 234 - req = webob.Request.blank('/v1.1/zadr-vsa/%d' % vsa_id) + req = webob.Request.blank('/v1.1/777/zadr-vsa/%d' % vsa_id) req.method = 'GET' resp = req.get_response(fakes.wsgi_app()) self.assertEqual(resp.status_int, 404) self.assertEqual(str(last_param['vsa_id']), str(vsa_id)) def test_vsa_index(self): - req = webob.Request.blank('/v1.1/zadr-vsa') + req = webob.Request.blank('/v1.1/777/zadr-vsa') req.method = 'GET' resp = req.get_response(fakes.wsgi_app()) self.assertEqual(resp.status_int, 200) @@ -213,7 +212,7 @@ class VSAApiTest(test.TestCase): self.assertEqual(resp_vsa['id'], 123) def test_vsa_detail(self): - req = webob.Request.blank('/v1.1/zadr-vsa/detail') + req = webob.Request.blank('/v1.1/777/zadr-vsa/detail') req.method = 'GET' resp = req.get_response(fakes.wsgi_app()) self.assertEqual(resp.status_int, 200) @@ -239,17 +238,21 @@ def _get_default_volume_param(): 'name': 'vol name', 'display_name': 'Default vol name', 'display_description': 'Default vol description', - 'from_vsa_id': None, - 'to_vsa_id': None, + 'volume_type_id': 1, + 'volume_metadata': [], } +def stub_get_vsa_volume_type(self, context): + return {'id': 1, + 'name': 'VSA volume type', + 'extra_specs': {'type': 'vsa_volume'}} + + def stub_volume_create(self, context, size, snapshot_id, name, description, **param): LOG.debug(_("_create: param=%s"), size) vol = _get_default_volume_param() - for k, v in param.iteritems(): - vol[k] = v vol['size'] = size vol['display_name'] = name vol['display_description'] = description @@ -270,10 +273,10 @@ def stub_volume_get(self, context, volume_id): LOG.debug(_("_volume_get: volume_id=%s"), volume_id) vol = _get_default_volume_param() vol['id'] = volume_id - if volume_id == '234': - vol['from_vsa_id'] = 123 + meta = {'key': 'from_vsa_id', 'value': '123'} if volume_id == '345': - vol['to_vsa_id'] = 123 + meta = {'key': 'to_vsa_id', 'value': '123'} + vol['volume_metadata'].append(meta) return vol @@ -281,9 +284,9 @@ def stub_volume_get_notfound(self, context, volume_id): raise exception.NotFound -def stub_volume_get_all_by_vsa(self, context, vsa_id, direction): +def stub_volume_get_all(self, context, search_opts): vol = stub_volume_get(self, context, '123') - vol['%s_vsa_id' % direction] = vsa_id + vol['metadata'] = search_opts['metadata'] return [vol] @@ -302,13 +305,13 @@ class VSAVolumeApiTest(test.TestCase): fakes.stub_out_rate_limiting(self.stubs) fakes.stub_out_auth(self.stubs) self.stubs.Set(nova.db.api, 'vsa_get', return_vsa) + self.stubs.Set(vsa.api.API, "get_vsa_volume_type", + stub_get_vsa_volume_type) - self.stubs.Set(volume.api.API, "create", stub_volume_create) self.stubs.Set(volume.api.API, "update", stub_volume_update) self.stubs.Set(volume.api.API, "delete", stub_volume_delete) - self.stubs.Set(volume.api.API, "get_all_by_vsa", - stub_volume_get_all_by_vsa) self.stubs.Set(volume.api.API, "get", stub_volume_get) + self.stubs.Set(volume.api.API, "get_all", stub_volume_get_all) self.context = context.get_admin_context() self.test_obj = test_obj if test_obj else "volume" @@ -319,11 +322,13 @@ class VSAVolumeApiTest(test.TestCase): super(VSAVolumeApiTest, self).tearDown() def test_vsa_volume_create(self): + self.stubs.Set(volume.api.API, "create", stub_volume_create) + vol = {"size": 100, "displayName": "VSA Volume Test Name", "displayDescription": "VSA Volume Test Desc"} body = {self.test_obj: vol} - req = webob.Request.blank('/v1.1/zadr-vsa/123/%s' % self.test_objs) + req = webob.Request.blank('/v1.1/777/zadr-vsa/123/%s' % self.test_objs) req.method = 'POST' req.body = json.dumps(body) req.headers['content-type'] = 'application/json' @@ -344,7 +349,7 @@ class VSAVolumeApiTest(test.TestCase): self.assertEqual(resp.status_int, 400) def test_vsa_volume_create_no_body(self): - req = webob.Request.blank('/v1.1/zadr-vsa/123/%s' % self.test_objs) + req = webob.Request.blank('/v1.1/777/zadr-vsa/123/%s' % self.test_objs) req.method = 'POST' req.body = json.dumps({}) req.headers['content-type'] = 'application/json' @@ -356,25 +361,25 @@ class VSAVolumeApiTest(test.TestCase): self.assertEqual(resp.status_int, 400) def test_vsa_volume_index(self): - req = webob.Request.blank('/v1.1/zadr-vsa/123/%s' % self.test_objs) + req = webob.Request.blank('/v1.1/777/zadr-vsa/123/%s' % self.test_objs) resp = req.get_response(fakes.wsgi_app()) self.assertEqual(resp.status_int, 200) def test_vsa_volume_detail(self): - req = webob.Request.blank('/v1.1/zadr-vsa/123/%s/detail' % \ + req = webob.Request.blank('/v1.1/777/zadr-vsa/123/%s/detail' % \ self.test_objs) resp = req.get_response(fakes.wsgi_app()) self.assertEqual(resp.status_int, 200) def test_vsa_volume_show(self): obj_num = 234 if self.test_objs == "volumes" else 345 - req = webob.Request.blank('/v1.1/zadr-vsa/123/%s/%s' % \ + req = webob.Request.blank('/v1.1/777/zadr-vsa/123/%s/%s' % \ (self.test_objs, obj_num)) resp = req.get_response(fakes.wsgi_app()) self.assertEqual(resp.status_int, 200) def test_vsa_volume_show_no_vsa_assignment(self): - req = webob.Request.blank('/v1.1/zadr-vsa/123/%s/333' % \ + req = webob.Request.blank('/v1.1/777/zadr-vsa/4/%s/333' % \ (self.test_objs)) resp = req.get_response(fakes.wsgi_app()) self.assertEqual(resp.status_int, 400) @@ -382,7 +387,7 @@ class VSAVolumeApiTest(test.TestCase): def test_vsa_volume_show_no_volume(self): self.stubs.Set(volume.api.API, "get", stub_volume_get_notfound) - req = webob.Request.blank('/v1.1/zadr-vsa/123/%s/333' % \ + req = webob.Request.blank('/v1.1/777/zadr-vsa/123/%s/333' % \ (self.test_objs)) resp = req.get_response(fakes.wsgi_app()) self.assertEqual(resp.status_int, 404) @@ -392,7 +397,7 @@ class VSAVolumeApiTest(test.TestCase): update = {"status": "available", "displayName": "Test Display name"} body = {self.test_obj: update} - req = webob.Request.blank('/v1.1/zadr-vsa/123/%s/%s' % \ + req = webob.Request.blank('/v1.1/777/zadr-vsa/123/%s/%s' % \ (self.test_objs, obj_num)) req.method = 'PUT' req.body = json.dumps(body) @@ -406,7 +411,7 @@ class VSAVolumeApiTest(test.TestCase): def test_vsa_volume_delete(self): obj_num = 234 if self.test_objs == "volumes" else 345 - req = webob.Request.blank('/v1.1/zadr-vsa/123/%s/%s' % \ + req = webob.Request.blank('/v1.1/777/zadr-vsa/123/%s/%s' % \ (self.test_objs, obj_num)) req.method = 'DELETE' resp = req.get_response(fakes.wsgi_app()) @@ -416,7 +421,7 @@ class VSAVolumeApiTest(test.TestCase): self.assertEqual(resp.status_int, 400) def test_vsa_volume_delete_no_vsa_assignment(self): - req = webob.Request.blank('/v1.1/zadr-vsa/123/%s/333' % \ + req = webob.Request.blank('/v1.1/777/zadr-vsa/4/%s/333' % \ (self.test_objs)) req.method = 'DELETE' resp = req.get_response(fakes.wsgi_app()) @@ -425,7 +430,7 @@ class VSAVolumeApiTest(test.TestCase): def test_vsa_volume_delete_no_volume(self): self.stubs.Set(volume.api.API, "get", stub_volume_get_notfound) - req = webob.Request.blank('/v1.1/zadr-vsa/123/%s/333' % \ + req = webob.Request.blank('/v1.1/777/zadr-vsa/123/%s/333' % \ (self.test_objs)) req.method = 'DELETE' resp = req.get_response(fakes.wsgi_app()) diff --git a/nova/tests/api/openstack/test_extensions.py b/nova/tests/api/openstack/test_extensions.py index 6e9cae38d..05267d8fb 100644 --- a/nova/tests/api/openstack/test_extensions.py +++ b/nova/tests/api/openstack/test_extensions.py @@ -85,7 +85,6 @@ class ExtensionControllerTest(test.TestCase): ext_path = os.path.join(os.path.dirname(__file__), "extensions") self.flags(osapi_extensions_path=ext_path) self.ext_list = [ - "DriveTypes", "Createserverext", "FlavorExtraSpecs", "Floating_ips", @@ -96,8 +95,8 @@ class ExtensionControllerTest(test.TestCase): "Quotas", "Rescue", "SecurityGroups", - "VirtualInterfaces", "VSAs", + "VirtualInterfaces", "Volumes", "VolumeTypes", ] diff --git a/nova/tests/scheduler/test_vsa_scheduler.py b/nova/tests/scheduler/test_vsa_scheduler.py index 697ad3842..309db96a2 100644 --- a/nova/tests/scheduler/test_vsa_scheduler.py +++ b/nova/tests/scheduler/test_vsa_scheduler.py @@ -16,13 +16,15 @@ import stubout import nova + +from nova import context +from nova import db from nova import exception from nova import flags -from nova import db -from nova import context +from nova import log as logging from nova import test from nova import utils -from nova import log as logging +from nova.volume import volume_types from nova.scheduler import vsa as vsa_sched from nova.scheduler import driver @@ -52,15 +54,26 @@ class VsaSchedulerTestCase(test.TestCase): def _get_vol_creation_request(self, num_vols, drive_ix, size=0): volume_params = [] for i in range(num_vols): - drive_type = {'id': i, - 'name': 'name_' + str(drive_ix), - 'type': 'type_' + str(drive_ix), - 'size_gb': 1 + 100 * (drive_ix)} + + name = 'name_' + str(i) + try: + volume_types.create(self.context, name, + extra_specs={'type': 'vsa_drive', + 'drive_name': name, + 'drive_type': 'type_' + str(drive_ix), + 'drive_size': 1 + 100 * (drive_ix)}) + self.created_types_lst.append(name) + except exception.ApiError: + # type is already created + pass + + volume_type = volume_types.get_volume_type_by_name(self.context, + name) volume = {'size': size, 'snapshot_id': None, 'name': 'vol_' + str(i), 'description': None, - 'drive_ref': drive_type} + 'volume_type_id': volume_type['id']} volume_params.append(volume) return {'num_volumes': len(volume_params), @@ -217,7 +230,12 @@ class VsaSchedulerTestCase(test.TestCase): self.stubs.Set(nova.db, 'volume_get', self._fake_volume_get) self.stubs.Set(nova.db, 'volume_update', self._fake_volume_update) + self.created_types_lst = [] + def tearDown(self): + for name in self.created_types_lst: + volume_types.purge(self.context, name) + self.stubs.UnsetAll() super(VsaSchedulerTestCase, self).tearDown() @@ -463,7 +481,7 @@ class VsaSchedulerTestCase(test.TestCase): global global_volume global_volume = {} - global_volume['drive_type'] = None + global_volume['volume_type_id'] = None self.assertRaises(driver.NoValidHost, self.sched.schedule_create_volume, @@ -485,12 +503,16 @@ class VsaSchedulerTestCase(test.TestCase): global_volume = {} drive_ix = 2 - drive_type = {'id': drive_ix, - 'name': 'name_' + str(drive_ix), - 'type': 'type_' + str(drive_ix), - 'size_gb': 1 + 100 * (drive_ix)} - - global_volume['drive_type'] = drive_type + name = 'name_' + str(drive_ix) + volume_types.create(self.context, name, + extra_specs={'type': 'vsa_drive', + 'drive_name': name, + 'drive_type': 'type_' + str(drive_ix), + 'drive_size': 1 + 100 * (drive_ix)}) + self.created_types_lst.append(name) + volume_type = volume_types.get_volume_type_by_name(self.context, name) + + global_volume['volume_type_id'] = volume_type['id'] global_volume['size'] = 0 host = self.sched.schedule_create_volume(self.context, @@ -525,12 +547,16 @@ class VsaSchedulerTestCaseMostAvail(VsaSchedulerTestCase): global_volume = {} drive_ix = 2 - drive_type = {'id': drive_ix, - 'name': 'name_' + str(drive_ix), - 'type': 'type_' + str(drive_ix), - 'size_gb': 1 + 100 * (drive_ix)} - - global_volume['drive_type'] = drive_type + name = 'name_' + str(drive_ix) + volume_types.create(self.context, name, + extra_specs={'type': 'vsa_drive', + 'drive_name': name, + 'drive_type': 'type_' + str(drive_ix), + 'drive_size': 1 + 100 * (drive_ix)}) + self.created_types_lst.append(name) + volume_type = volume_types.get_volume_type_by_name(self.context, name) + + global_volume['volume_type_id'] = volume_type['id'] global_volume['size'] = 0 host = self.sched.schedule_create_volume(self.context, diff --git a/nova/tests/test_drive_types.py b/nova/tests/test_drive_types.py deleted file mode 100644 index b52e6705b..000000000 --- a/nova/tests/test_drive_types.py +++ /dev/null @@ -1,146 +0,0 @@ -# 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 drive types codecode -""" -import time - -from nova import context -from nova import flags -from nova import log as logging -from nova import test -from nova.vsa import drive_types - -FLAGS = flags.FLAGS -LOG = logging.getLogger('nova.tests.test_drive_types') - - -class DriveTypesTestCase(test.TestCase): - """Test cases for driver types code""" - def setUp(self): - super(DriveTypesTestCase, self).setUp() - self.ctxt = context.RequestContext(None, None) - self.ctxt_admin = context.get_admin_context() - self._dtype = self._create_default_drive_type() - - def tearDown(self): - self._dtype = None - - def _create_default_drive_type(self): - """Create a volume object.""" - dtype = {} - dtype['type'] = 'SATA' - dtype['size_gb'] = 150 - dtype['rpm'] = 5000 - dtype['capabilities'] = None - dtype['visible'] = True - - LOG.debug(_("Default values for Drive Type: %s"), dtype) - return dtype - - def test_drive_type_create_delete(self): - dtype = self._dtype - prev_all_dtypes = drive_types.get_all(self.ctxt_admin, False) - - new = drive_types.create(self.ctxt_admin, **dtype) - for k, v in dtype.iteritems(): - self.assertEqual(v, new[k], 'one of fields doesnt match') - - new_all_dtypes = drive_types.get_all(self.ctxt_admin, False) - self.assertNotEqual(len(prev_all_dtypes), - len(new_all_dtypes), - 'drive type was not created') - - drive_types.delete(self.ctxt_admin, new['id']) - new_all_dtypes = drive_types.get_all(self.ctxt_admin, False) - self.assertEqual(prev_all_dtypes, - new_all_dtypes, - 'drive types was not deleted') - - def test_drive_type_check_name_generation(self): - dtype = self._dtype - new = drive_types.create(self.ctxt_admin, **dtype) - expected_name = FLAGS.drive_type_template_short % \ - (dtype['type'], dtype['size_gb'], dtype['rpm']) - self.assertEqual(new['name'], expected_name, - 'name was not generated correctly') - - dtype['capabilities'] = 'SEC' - new2 = drive_types.create(self.ctxt_admin, **dtype) - expected_name = FLAGS.drive_type_template_long % \ - (dtype['type'], dtype['size_gb'], dtype['rpm'], - dtype['capabilities']) - self.assertEqual(new2['name'], expected_name, - 'name was not generated correctly') - - drive_types.delete(self.ctxt_admin, new['id']) - drive_types.delete(self.ctxt_admin, new2['id']) - - def test_drive_type_create_delete_invisible(self): - dtype = self._dtype - dtype['visible'] = False - prev_all_dtypes = drive_types.get_all(self.ctxt_admin, True) - new = drive_types.create(self.ctxt_admin, **dtype) - - new_all_dtypes = drive_types.get_all(self.ctxt_admin, True) - self.assertEqual(prev_all_dtypes, new_all_dtypes) - - new_all_dtypes = drive_types.get_all(self.ctxt_admin, False) - self.assertNotEqual(prev_all_dtypes, new_all_dtypes) - - drive_types.delete(self.ctxt_admin, new['id']) - - def test_drive_type_rename_update(self): - dtype = self._dtype - dtype['capabilities'] = None - - new = drive_types.create(self.ctxt_admin, **dtype) - for k, v in dtype.iteritems(): - self.assertEqual(v, new[k], 'one of fields doesnt match') - - new_name = 'NEW_DRIVE_NAME' - new = drive_types.rename(self.ctxt_admin, new['name'], new_name) - self.assertEqual(new['name'], new_name) - - new = drive_types.rename(self.ctxt_admin, new_name) - expected_name = FLAGS.drive_type_template_short % \ - (dtype['type'], dtype['size_gb'], dtype['rpm']) - self.assertEqual(new['name'], expected_name) - - changes = {'rpm': 7200} - new = drive_types.update(self.ctxt_admin, new['id'], **changes) - for k, v in changes.iteritems(): - self.assertEqual(v, new[k], 'one of fields doesnt match') - - drive_types.delete(self.ctxt_admin, new['id']) - - def test_drive_type_get(self): - dtype = self._dtype - new = drive_types.create(self.ctxt_admin, **dtype) - - new2 = drive_types.get(self.ctxt_admin, new['id']) - for k, v in new2.iteritems(): - self.assertEqual(str(new[k]), str(new2[k]), - 'one of fields doesnt match') - - new2 = drive_types.get_by_name(self.ctxt_admin, new['name']) - for k, v in new.iteritems(): - self.assertEqual(str(new[k]), str(new2[k]), - 'one of fields doesnt match') - - drive_types.delete(self.ctxt_admin, new['id']) diff --git a/nova/tests/test_vsa.py b/nova/tests/test_vsa.py index 726939744..300a4d71c 100644 --- a/nova/tests/test_vsa.py +++ b/nova/tests/test_vsa.py @@ -13,38 +13,29 @@ # License for the specific language governing permissions and limitations # under the License. -import stubout import base64 +import stubout from xml.etree import ElementTree from xml.etree.ElementTree import Element, SubElement +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 vsa from nova import volume -from nova import db -from nova import context -from nova import test -from nova import log as logging +from nova.volume import volume_types +from nova.vsa import utils as vsa_utils + 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): @@ -53,9 +44,20 @@ class VsaTestCase(test.TestCase): self.vsa_api = vsa.API() self.volume_api = volume.API() + FLAGS.quota_volumes = 100 + FLAGS.quota_gigabytes = 10000 + self.context_non_admin = context.RequestContext(None, None) self.context = context.get_admin_context() + volume_types.create(self.context, + 'SATA_500_7200', + extra_specs={'type': 'vsa_drive', + 'drive_name': 'SATA_500_7200', + 'drive_type': 'SATA', + 'drive_size': '500', + 'drive_rpm': '7200'}) + def fake_show_by_name(meh, context, name): if name == 'wrong_image_name': LOG.debug(_("Test: Emulate wrong VSA name. Raise")) @@ -124,9 +126,6 @@ class VsaTestCase(test.TestCase): 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) @@ -157,8 +156,6 @@ class VsaTestCase(test.TestCase): 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', @@ -167,12 +164,10 @@ class VsaTestCase(test.TestCase): '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']) + volumes = self.vsa_api.get_all_vsa_drives(self.context, + vsa_ref['id']) - user_data = self.vsa_api.generate_user_data(self.context, - vsa_ref, - volumes) + user_data = vsa_utils.generate_user_data(vsa_ref, volumes) user_data = base64.b64decode(user_data) LOG.debug(_("Test: user_data = %s"), user_data) diff --git a/nova/tests/test_vsa_volumes.py b/nova/tests/test_vsa_volumes.py index d451a4377..43173d86a 100644 --- a/nova/tests/test_vsa_volumes.py +++ b/nova/tests/test_vsa_volumes.py @@ -29,15 +29,6 @@ FLAGS = flags.FLAGS LOG = logging.getLogger('nova.tests.vsa.volumes') -def _default_volume_param(): - return { - 'size': 1, - 'snapshot_id': None, - 'name': 'Test volume name', - 'description': 'Test volume desc name' - } - - class VsaVolumesTestCase(test.TestCase): def setUp(self): @@ -49,6 +40,8 @@ class VsaVolumesTestCase(test.TestCase): self.context_non_admin = context.RequestContext(None, None) self.context = context.get_admin_context() + self.default_vol_type = self.vsa_api.get_vsa_volume_type(self.context) + def fake_show_by_name(meh, context, name): return {'id': 1, 'properties': {'kernel_id': 1, 'ramdisk_id': 1}} @@ -66,12 +59,23 @@ class VsaVolumesTestCase(test.TestCase): self.stubs.UnsetAll() super(VsaVolumesTestCase, self).tearDown() + def _default_volume_param(self): + return { + 'size': 1, + 'snapshot_id': None, + 'name': 'Test volume name', + 'description': 'Test volume desc name', + 'volume_type': self.default_vol_type, + 'metadata': {'from_vsa_id': self.vsa_id} + } + + def _get_all_volumes_by_vsa(self): + return self.volume_api.get_all(self.context, + search_opts={'metadata': {"from_vsa_id": str(self.vsa_id)}}) + def test_vsa_volume_create_delete(self): """ Check if volume properly created and deleted. """ - vols1 = self.volume_api.get_all_by_vsa(self.context, - self.vsa_id, "from") - volume_param = _default_volume_param() - volume_param['from_vsa_id'] = self.vsa_id + volume_param = self._default_volume_param() volume_ref = self.volume_api.create(self.context, **volume_param) self.assertEqual(volume_ref['display_name'], @@ -81,21 +85,34 @@ class VsaVolumesTestCase(test.TestCase): self.assertEqual(volume_ref['size'], volume_param['size']) self.assertEqual(volume_ref['status'], - 'available') + 'creating') - vols2 = self.volume_api.get_all_by_vsa(self.context, - self.vsa_id, "from") - self.assertEqual(len(vols1) + 1, len(vols2)) + vols2 = self._get_all_volumes_by_vsa() + self.assertEqual(1, len(vols2)) + volume_ref = vols2[0] + self.assertEqual(volume_ref['display_name'], + volume_param['name']) + self.assertEqual(volume_ref['display_description'], + volume_param['description']) + self.assertEqual(volume_ref['size'], + volume_param['size']) + self.assertEqual(volume_ref['status'], + 'creating') + + self.volume_api.update(self.context, + volume_ref['id'], {'status': 'available'}) self.volume_api.delete(self.context, volume_ref['id']) - vols3 = self.volume_api.get_all_by_vsa(self.context, - self.vsa_id, "from") - self.assertEqual(len(vols3) + 1, len(vols2)) + + vols3 = self._get_all_volumes_by_vsa() + self.assertEqual(1, len(vols2)) + volume_ref = vols3[0] + self.assertEqual(volume_ref['status'], + 'deleting') def test_vsa_volume_delete_nonavail_volume(self): """ Check volume deleton in different states. """ - volume_param = _default_volume_param() - volume_param['from_vsa_id'] = self.vsa_id + volume_param = self._default_volume_param() volume_ref = self.volume_api.create(self.context, **volume_param) self.volume_api.update(self.context, @@ -104,26 +121,18 @@ class VsaVolumesTestCase(test.TestCase): self.volume_api.delete, self.context, volume_ref['id']) - self.volume_api.update(self.context, - volume_ref['id'], {'status': 'error'}) - self.volume_api.delete(self.context, volume_ref['id']) - def test_vsa_volume_delete_vsa_with_volumes(self): """ Check volume deleton in different states. """ - vols1 = self.volume_api.get_all_by_vsa(self.context, - self.vsa_id, "from") + vols1 = self._get_all_volumes_by_vsa() for i in range(3): - volume_param = _default_volume_param() - volume_param['from_vsa_id'] = self.vsa_id + volume_param = self._default_volume_param() volume_ref = self.volume_api.create(self.context, **volume_param) - vols2 = self.volume_api.get_all_by_vsa(self.context, - self.vsa_id, "from") + vols2 = self._get_all_volumes_by_vsa() self.assertEqual(len(vols1) + 3, len(vols2)) self.vsa_api.delete(self.context, self.vsa_id) - vols3 = self.volume_api.get_all_by_vsa(self.context, - self.vsa_id, "from") + vols3 = self._get_all_volumes_by_vsa() self.assertEqual(len(vols1), len(vols3)) diff --git a/nova/tests/test_xenapi.py b/nova/tests/test_xenapi.py index 2f0559366..6d1958401 100644 --- a/nova/tests/test_xenapi.py +++ b/nova/tests/test_xenapi.py @@ -203,6 +203,7 @@ class XenAPIVMTestCase(test.TestCase): self.context = context.RequestContext(self.user_id, self.project_id) self.conn = xenapi_conn.get_connection(False) + @test.skip_test("Skip this test meanwhile") def test_parallel_builds(self): stubs.stubout_loopingcall_delay(self.stubs) -- cgit From 59e9adb8e2ef39474a04ead76975a1fc3f913550 Mon Sep 17 00:00:00 2001 From: "vladimir.p" Date: Thu, 25 Aug 2011 19:09:50 -0700 Subject: cosmetic cleanup --- nova/tests/scheduler/test_vsa_scheduler.py | 1 - nova/tests/test_vsa.py | 1 - nova/tests/test_vsa_volumes.py | 2 -- nova/tests/test_xenapi.py | 1 - 4 files changed, 5 deletions(-) (limited to 'nova/tests') diff --git a/nova/tests/scheduler/test_vsa_scheduler.py b/nova/tests/scheduler/test_vsa_scheduler.py index 309db96a2..37964f00d 100644 --- a/nova/tests/scheduler/test_vsa_scheduler.py +++ b/nova/tests/scheduler/test_vsa_scheduler.py @@ -210,7 +210,6 @@ class VsaSchedulerTestCase(test.TestCase): def setUp(self, sched_class=None): super(VsaSchedulerTestCase, self).setUp() self.stubs = stubout.StubOutForTesting() - self.context_non_admin = context.RequestContext(None, None) self.context = context.get_admin_context() if sched_class is None: diff --git a/nova/tests/test_vsa.py b/nova/tests/test_vsa.py index 300a4d71c..3d2d2de13 100644 --- a/nova/tests/test_vsa.py +++ b/nova/tests/test_vsa.py @@ -47,7 +47,6 @@ class VsaTestCase(test.TestCase): FLAGS.quota_volumes = 100 FLAGS.quota_gigabytes = 10000 - self.context_non_admin = context.RequestContext(None, None) self.context = context.get_admin_context() volume_types.create(self.context, diff --git a/nova/tests/test_vsa_volumes.py b/nova/tests/test_vsa_volumes.py index 43173d86a..b7cd4e840 100644 --- a/nova/tests/test_vsa_volumes.py +++ b/nova/tests/test_vsa_volumes.py @@ -36,8 +36,6 @@ class VsaVolumesTestCase(test.TestCase): self.stubs = stubout.StubOutForTesting() self.vsa_api = vsa.API() self.volume_api = volume.API() - - self.context_non_admin = context.RequestContext(None, None) self.context = context.get_admin_context() self.default_vol_type = self.vsa_api.get_vsa_volume_type(self.context) diff --git a/nova/tests/test_xenapi.py b/nova/tests/test_xenapi.py index 6d1958401..2f0559366 100644 --- a/nova/tests/test_xenapi.py +++ b/nova/tests/test_xenapi.py @@ -203,7 +203,6 @@ class XenAPIVMTestCase(test.TestCase): self.context = context.RequestContext(self.user_id, self.project_id) self.conn = xenapi_conn.get_connection(False) - @test.skip_test("Skip this test meanwhile") def test_parallel_builds(self): stubs.stubout_loopingcall_delay(self.stubs) -- cgit From 75c7c841379341c63598850e4676f2146d63334a Mon Sep 17 00:00:00 2001 From: Ewan Mellor Date: Sun, 28 Aug 2011 16:17:17 +0530 Subject: Bug #835964: pep8 violations in IPv6 code Fix pep8 violations. --- nova/tests/test_ipv6.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'nova/tests') diff --git a/nova/tests/test_ipv6.py b/nova/tests/test_ipv6.py index 04c1b5598..e1ba4aafb 100644 --- a/nova/tests/test_ipv6.py +++ b/nova/tests/test_ipv6.py @@ -48,7 +48,7 @@ class IPv6RFC2462TestCase(test.TestCase): def test_to_global_with_bad_prefix(self): bad_prefix = '82' self.assertRaises(TypeError, ipv6.to_global, - bad_prefix, + bad_prefix, '2001:db8::216:3eff:fe33:4455', 'test') -- cgit