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 d963e25906b75a48c75b6e589deb2a53f75d6ee3 Mon Sep 17 00:00:00 2001 From: Christopher MacGown Date: Fri, 22 Jul 2011 20:29:37 -0700 Subject: Config-Drive happiness, minus smoketest --- nova/tests/api/openstack/test_servers.py | 135 ++++++++++++++++++++++++++++++- nova/tests/test_compute.py | 14 ++++ 2 files changed, 146 insertions(+), 3 deletions(-) (limited to 'nova/tests') diff --git a/nova/tests/api/openstack/test_servers.py b/nova/tests/api/openstack/test_servers.py index 3fc38b73c..6a1eb8c87 100644 --- a/nova/tests/api/openstack/test_servers.py +++ b/nova/tests/api/openstack/test_servers.py @@ -775,11 +775,14 @@ class ServersTest(test.TestCase): self.assertEqual(res.status_int, 400) self.assertTrue(res.body.find('marker param') > -1) - def _setup_for_create_instance(self): + def _setup_for_create_instance(self, instance_db_stub=None): """Shared implementation for tests below that create instance""" def instance_create(context, inst): - return {'id': 1, 'display_name': 'server_test', - 'uuid': FAKE_UUID} + if instance_db_stub: + return instance_db_stub + else: + return {'id': 1, 'display_name': 'server_test', + 'uuid': FAKE_UUID,} def server_update(context, id, params): return instance_create(context, id) @@ -997,6 +1000,132 @@ class ServersTest(test.TestCase): self.assertEqual(flavor_ref, server['flavorRef']) self.assertEqual(image_href, server['imageRef']) + def test_create_instance_with_config_drive_v1_1(self): + db_stub = {'id': 100, 'display_name': 'config_drive_test', + 'uuid': FAKE_UUID, 'config_drive': True} + self._setup_for_create_instance(instance_db_stub=db_stub) + + image_href = 'http://localhost/v1.1/images/2' + flavor_ref = 'http://localhost/v1.1/flavors/3' + body = { + 'server': { + 'name': 'config_drive_test', + 'imageRef': image_href, + 'flavorRef': flavor_ref, + 'metadata': { + 'hello': 'world', + 'open': 'stack', + }, + 'personality': {}, + 'config_drive': True, + }, + } + + req = webob.Request.blank('/v1.1/servers') + req.method = 'POST' + req.body = json.dumps(body) + req.headers["content-type"] = "application/json" + + res = req.get_response(fakes.wsgi_app()) + self.assertEqual(res.status_int, 200) + server = json.loads(res.body)['server'] + self.assertEqual(100, server['id']) + self.assertTrue(server['config_drive']) + + def test_create_instance_with_config_drive_as_id_v1_1(self): + db_stub = {'id': 100, 'display_name': 'config_drive_test', + 'uuid': FAKE_UUID, 'config_drive': 2} + self._setup_for_create_instance(instance_db_stub=db_stub) + + image_href = 'http://localhost/v1.1/images/2' + flavor_ref = 'http://localhost/v1.1/flavors/3' + body = { + 'server': { + 'name': 'config_drive_test', + 'imageRef': image_href, + 'flavorRef': flavor_ref, + 'metadata': { + 'hello': 'world', + 'open': 'stack', + }, + 'personality': {}, + 'config_drive': 2, + }, + } + + req = webob.Request.blank('/v1.1/servers') + req.method = 'POST' + req.body = json.dumps(body) + req.headers["content-type"] = "application/json" + + res = req.get_response(fakes.wsgi_app()) + self.assertEqual(res.status_int, 200) + server = json.loads(res.body)['server'] + self.assertEqual(100, server['id']) + self.assertTrue(server['config_drive']) + self.assertEqual(2, server['config_drive']) + + def test_create_instance_with_bad_config_drive_v1_1(self): + db_stub = {'id': 100, 'display_name': 'config_drive_test', + 'uuid': FAKE_UUID, 'config_drive': 'asdf'} + self._setup_for_create_instance(instance_db_stub=db_stub) + + image_href = 'http://localhost/v1.1/images/2' + flavor_ref = 'http://localhost/v1.1/flavors/3' + body = { + 'server': { + 'name': 'config_drive_test', + 'imageRef': image_href, + 'flavorRef': flavor_ref, + 'metadata': { + 'hello': 'world', + 'open': 'stack', + }, + 'personality': {}, + 'config_drive': 'asdf', + }, + } + + req = webob.Request.blank('/v1.1/servers') + req.method = 'POST' + req.body = json.dumps(body) + req.headers["content-type"] = "application/json" + + res = req.get_response(fakes.wsgi_app()) + self.assertEqual(res.status_int, 400) + + def test_create_instance_without_config_drive_v1_1(self): + db_stub = {'id': 100, 'display_name': 'config_drive_test', + 'uuid': FAKE_UUID, 'config_drive': None} + self._setup_for_create_instance(instance_db_stub=db_stub) + + image_href = 'http://localhost/v1.1/images/2' + flavor_ref = 'http://localhost/v1.1/flavors/3' + body = { + 'server': { + 'name': 'config_drive_test', + 'imageRef': image_href, + 'flavorRef': flavor_ref, + 'metadata': { + 'hello': 'world', + 'open': 'stack', + }, + 'personality': {}, + 'config_drive': True, + }, + } + + req = webob.Request.blank('/v1.1/servers') + req.method = 'POST' + req.body = json.dumps(body) + req.headers["content-type"] = "application/json" + + res = req.get_response(fakes.wsgi_app()) + self.assertEqual(res.status_int, 200) + server = json.loads(res.body)['server'] + self.assertEqual(100, server['id']) + self.assertFalse(server['config_drive']) + def test_create_instance_v1_1_bad_href(self): self._setup_for_create_instance() diff --git a/nova/tests/test_compute.py b/nova/tests/test_compute.py index 5d59b628a..bc681706d 100644 --- a/nova/tests/test_compute.py +++ b/nova/tests/test_compute.py @@ -162,6 +162,20 @@ class ComputeTestCase(test.TestCase): db.security_group_destroy(self.context, group['id']) db.instance_destroy(self.context, ref[0]['id']) + def test_create_instance_associates_config_drive(self): + """Make sure create associates a config drive.""" + + instance_id = self._create_instance(params={'config_drive': True,}) + + try: + self.compute.run_instance(self.context, instance_id) + instances = db.instance_get_all(context.get_admin_context()) + instance = instances[0] + + self.assertTrue(instance.config_drive) + finally: + db.instance_destroy(self.context, instance_id) + def test_default_hostname_generator(self): cases = [(None, 'server_1'), ('Hello, Server!', 'hello_server'), ('<}\x1fh\x10e\x08l\x02l\x05o\x12!{>', 'hello')] -- 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 f11581221a3739c25e5f7b77b96f3dc8d332af5c Mon Sep 17 00:00:00 2001 From: Tim Simpson Date: Tue, 16 Aug 2011 08:55:17 -0500 Subject: Added list_notifier, a driver for the notifer api which calls a list of other drivers. --- nova/tests/notifier/__init__.py | 16 ++++++ nova/tests/notifier/test_list_notifier.py | 85 +++++++++++++++++++++++++++++++ 2 files changed, 101 insertions(+) create mode 100644 nova/tests/notifier/__init__.py create mode 100644 nova/tests/notifier/test_list_notifier.py (limited to 'nova/tests') diff --git a/nova/tests/notifier/__init__.py b/nova/tests/notifier/__init__.py new file mode 100644 index 000000000..bd862c46a --- /dev/null +++ b/nova/tests/notifier/__init__.py @@ -0,0 +1,16 @@ +# 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. + +from nova.tests import * diff --git a/nova/tests/notifier/test_list_notifier.py b/nova/tests/notifier/test_list_notifier.py new file mode 100644 index 000000000..65c2ecd90 --- /dev/null +++ b/nova/tests/notifier/test_list_notifier.py @@ -0,0 +1,85 @@ +# 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 context +from nova import flags +from nova import log as logging +from nova import rpc +import nova.notifier.api +from nova.notifier.api import notify +from nova.notifier import log_notifier +from nova.notifier import no_op_notifier +from nova.notifier import list_notifier +from nova.notifier import rabbit_notifier +from nova import test + + +class NotifierListTestCase(test.TestCase): + """Test case for notifications""" + def setUp(self): + super(NotifierListTestCase, self).setUp() + list_notifier._reset_drivers() + self.stubs = stubout.StubOutForTesting() + + def tearDown(self): + self.stubs.UnsetAll() + list_notifier._reset_drivers() + super(NotifierListTestCase, self).tearDown() + + def test_send_notifications_successfully(self): + self.flags(notification_driver='nova.notifier.list_notifier', + list_notifier_drivers=['nova.notifier.no_op_notifier', + 'nova.notifier.no_op_notifier']) + self.notify_count = 0 + + def mock_notify(cls, *args): + self.notify_count += 1 + + self.stubs.Set(nova.notifier.no_op_notifier, 'notify', + mock_notify) + + notify('publisher_id', 'event_type', + nova.notifier.api.WARN, dict(a=3)) + self.assertEqual(self.notify_count, 2) + + def test_send_notifications_with_errors(self): + self.exception_count = 0 + def mock_exception(cls, *args): + self.exception_count += 1 + + self.notify_count = 0 + def mock_notify(cls, *args): + self.notify_count += 1 + + def mock_notify2(cls, *args): + raise RuntimeError("Bad notifier.") + + self.flags(notification_driver='nova.notifier.list_notifier', + list_notifier_drivers=['nova.notifier.no_op_notifier', + 'nova.notifier.log_notifier']) + + list_notifier_log = logging.getLogger('nova.notifier.list_notifier') + list_notifier_log.exception + self.stubs.Set(list_notifier_log, "exception", mock_exception) + self.stubs.Set(nova.notifier.no_op_notifier, 'notify', mock_notify) + self.stubs.Set(nova.notifier.log_notifier, 'notify', mock_notify2) + + notify('publisher_id', 'event_type', nova.notifier.api.WARN, dict(a=3)) + + self.assertEqual(self.notify_count, 1) + self.assertEqual(self.exception_count, 1) -- cgit From 9ad17dec99608b3738d662d91c49964b3f207d02 Mon Sep 17 00:00:00 2001 From: Hisaharu Ishii Date: Wed, 17 Aug 2011 09:57:15 -0700 Subject: Add NetworkCommandsTestCase into unit test of nova-manage --- nova/tests/test_nova_manage.py | 73 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) (limited to 'nova/tests') diff --git a/nova/tests/test_nova_manage.py b/nova/tests/test_nova_manage.py index 9c6563f14..69e73367f 100644 --- a/nova/tests/test_nova_manage.py +++ b/nova/tests/test_nova_manage.py @@ -15,6 +15,7 @@ # License for the specific language governing permissions and limitations # under the License. +import gettext import os import sys @@ -24,16 +25,20 @@ TOPDIR = os.path.normpath(os.path.join( os.pardir)) NOVA_MANAGE_PATH = os.path.join(TOPDIR, 'bin', 'nova-manage') +gettext.install('nova', unicode=1) + sys.dont_write_bytecode = True import imp nova_manage = imp.load_source('nova_manage.py', NOVA_MANAGE_PATH) sys.dont_write_bytecode = False import netaddr +import StringIO from nova import context from nova import db from nova import flags from nova import test +from nova import exception FLAGS = flags.FLAGS @@ -80,3 +85,71 @@ class FixedIpCommandsTestCase(test.TestCase): address = db.fixed_ip_get_by_address(context.get_admin_context(), '10.0.0.100') self.assertEqual(address['reserved'], False) + +class NetworkCommandsTestCase(test.TestCase): + def setUp(self): +# print 'piyo' + super(NetworkCommandsTestCase, self).setUp() + self.commands = nova_manage.NetworkCommands() + self.context = context.get_admin_context() + nets = db.network_get_all(self.context) + for net in nets: + db.network_delete_safe(self.context, net['id']) + + def tearDown(self): + super(NetworkCommandsTestCase, self).tearDown() + + def test_create(self): + self.commands.create( + label = 'Test', + fixed_range_v4 = '10.2.0.0/24', + fixed_range_v6 = 'fd00:2::/64', + num_networks = 1, + network_size = 256, + vlan_start = 200, + bridge_interface = 'eth0', + ) + net = db.network_get_by_cidr(self.context, '10.2.0.0/24') + self.assertEqual(net['label'], 'Test') + self.assertEqual(net['cidr'], '10.2.0.0/24') + self.assertEqual(net['netmask'], '255.255.255.0') + self.assertEqual(net['cidr_v6'], 'fd00:2::/64') + self.assertEqual(net['bridge_interface'], 'eth0') + self.assertEqual(net['vlan'], 200) + + def test_list(self): + format = "%-18s\t%-15s\t%-15s\t%-15s\t%-15s\t%-15s\t%-15s" + head = format % ( + _('IPv4'), + _('IPv6'), + _('start address'), + _('DNS1'), + _('DNS2'), + _('VlanID'), + _('project')) + body = format % ( + '10.2.0.0/24', + 'fd00:2::/64', + '10.2.0.3', + 'None', + 'None', + '200', + 'None',) + self.test_create() + output = StringIO.StringIO() + sys.stdout = output + self.commands.list() + sys.stdout = sys.__stdout__ + result = output.getvalue() + answer = '%s\n%s\n' % (head, body) + self.assertEqual(result, answer) + + def test_delete(self): + self.test_create() + self.commands.delete(fixed_range = '10.2.0.0/24') + net_exist = True + try: + net = db.network_get_by_cidr(self.context, '10.2.0.0/24') + except exception.NetworkNotFoundForCidr, e: + net_exist = False + self.assertEqual(net_exist, False) -- 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 41819d8d048b889f2e7f5e4ee0ff2873bfdef904 Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya Date: Wed, 17 Aug 2011 20:22:30 -0700 Subject: fix integration tests --- nova/tests/integrated/integrated_helpers.py | 109 ++++------------------------ nova/tests/integrated/test_login.py | 33 --------- nova/tests/integrated/test_servers.py | 2 +- 3 files changed, 14 insertions(+), 130 deletions(-) (limited to 'nova/tests') diff --git a/nova/tests/integrated/integrated_helpers.py b/nova/tests/integrated/integrated_helpers.py index fb2f88502..343190427 100644 --- a/nova/tests/integrated/integrated_helpers.py +++ b/nova/tests/integrated/integrated_helpers.py @@ -22,10 +22,8 @@ Provides common functionality for integrated unit tests import random import string -from nova import exception from nova import service from nova import test # For the flags -from nova.auth import manager import nova.image.glance from nova.log import logging from nova.tests.integrated.api import client @@ -58,90 +56,6 @@ def generate_new_element(items, prefix, numeric=False): LOG.debug("Random collision on %s" % candidate) -class TestUser(object): - def __init__(self, name, secret, auth_url): - self.name = name - self.secret = secret - self.auth_url = auth_url - - if not auth_url: - raise exception.Error("auth_url is required") - self.openstack_api = client.TestOpenStackClient(self.name, - self.secret, - self.auth_url) - - def get_unused_server_name(self): - servers = self.openstack_api.get_servers() - server_names = [server['name'] for server in servers] - return generate_new_element(server_names, 'server') - - def get_invalid_image(self): - images = self.openstack_api.get_images() - image_ids = [image['id'] for image in images] - return generate_new_element(image_ids, '', numeric=True) - - def get_valid_image(self, create=False): - images = self.openstack_api.get_images() - if create and not images: - # TODO(justinsb): No way currently to create an image through API - #created_image = self.openstack_api.post_image(image) - #images.append(created_image) - raise exception.Error("No way to create an image through API") - - if images: - return images[0] - return None - - -class IntegratedUnitTestContext(object): - def __init__(self, auth_url): - self.auth_manager = manager.AuthManager() - - self.auth_url = auth_url - self.project_name = None - - self.test_user = None - - self.setup() - - def setup(self): - self._create_test_user() - - def _create_test_user(self): - self.test_user = self._create_unittest_user() - - # No way to currently pass this through the OpenStack API - self.project_name = 'openstack' - self._configure_project(self.project_name, self.test_user) - - def cleanup(self): - self.test_user = None - - def _create_unittest_user(self): - users = self.auth_manager.get_users() - user_names = [user.name for user in users] - auth_name = generate_new_element(user_names, 'unittest_user_') - auth_key = generate_random_alphanumeric(16) - - # Right now there's a bug where auth_name and auth_key are reversed - # bug732907 - auth_key = auth_name - - self.auth_manager.create_user(auth_name, auth_name, auth_key, False) - return TestUser(auth_name, auth_key, self.auth_url) - - def _configure_project(self, project_name, user): - projects = self.auth_manager.get_projects() - project_names = [project.name for project in projects] - if not project_name in project_names: - project = self.auth_manager.create_project(project_name, - user.name, - description=None, - member_users=None) - else: - self.auth_manager.add_to_project(user.name, project_name) - - class _IntegratedTestBase(test.TestCase): def setUp(self): super(_IntegratedTestBase, self).setUp() @@ -163,10 +77,7 @@ class _IntegratedTestBase(test.TestCase): self._start_api_service() - self.context = IntegratedUnitTestContext(self.auth_url) - - self.user = self.context.test_user - self.api = self.user.openstack_api + self.api = client.TestOpenStackClient('fake', 'fake', self.auth_url) def _start_api_service(self): osapi = service.WSGIService("osapi") @@ -174,10 +85,6 @@ class _IntegratedTestBase(test.TestCase): self.auth_url = 'http://%s:%s/v1.1' % (osapi.host, osapi.port) LOG.warn(self.auth_url) - def tearDown(self): - self.context.cleanup() - super(_IntegratedTestBase, self).tearDown() - def _get_flags(self): """An opportunity to setup flags, before the services are started.""" f = {} @@ -190,10 +97,20 @@ class _IntegratedTestBase(test.TestCase): f['fake_network'] = True return f + def get_unused_server_name(self): + servers = self.api.get_servers() + server_names = [server['name'] for server in servers] + return generate_new_element(server_names, 'server') + + def get_invalid_image(self): + images = self.api.get_images() + image_ids = [image['id'] for image in images] + return generate_new_element(image_ids, '', numeric=True) + def _build_minimal_create_server_request(self): server = {} - image = self.user.get_valid_image(create=True) + image = self.api.get_images()[0] LOG.debug("Image: %s" % image) if 'imageRef' in image: @@ -211,7 +128,7 @@ class _IntegratedTestBase(test.TestCase): server['flavorRef'] = 'http://fake.server/%s' % flavor['id'] # Set a valid server name - server_name = self.user.get_unused_server_name() + server_name = self.get_unused_server_name() server['name'] = server_name return server diff --git a/nova/tests/integrated/test_login.py b/nova/tests/integrated/test_login.py index 06359a52f..3a863d0f9 100644 --- a/nova/tests/integrated/test_login.py +++ b/nova/tests/integrated/test_login.py @@ -15,11 +15,9 @@ # License for the specific language governing permissions and limitations # under the License. -import unittest from nova.log import logging from nova.tests.integrated import integrated_helpers -from nova.tests.integrated.api import client LOG = logging.getLogger('nova.tests.integrated') @@ -31,34 +29,3 @@ class LoginTest(integrated_helpers._IntegratedTestBase): flavors = self.api.get_flavors() for flavor in flavors: LOG.debug(_("flavor: %s") % flavor) - - def test_bad_login_password(self): - """Test that I get a 401 with a bad username.""" - bad_credentials_api = client.TestOpenStackClient(self.user.name, - "notso_password", - self.user.auth_url) - - self.assertRaises(client.OpenStackApiAuthenticationException, - bad_credentials_api.get_flavors) - - def test_bad_login_username(self): - """Test that I get a 401 with a bad password.""" - bad_credentials_api = client.TestOpenStackClient("notso_username", - self.user.secret, - self.user.auth_url) - - self.assertRaises(client.OpenStackApiAuthenticationException, - bad_credentials_api.get_flavors) - - def test_bad_login_both_bad(self): - """Test that I get a 401 with both bad username and bad password.""" - bad_credentials_api = client.TestOpenStackClient("notso_username", - "notso_password", - self.user.auth_url) - - self.assertRaises(client.OpenStackApiAuthenticationException, - bad_credentials_api.get_flavors) - - -if __name__ == "__main__": - unittest.main() diff --git a/nova/tests/integrated/test_servers.py b/nova/tests/integrated/test_servers.py index 725f6d529..c2f800689 100644 --- a/nova/tests/integrated/test_servers.py +++ b/nova/tests/integrated/test_servers.py @@ -51,7 +51,7 @@ class ServersTest(integrated_helpers._IntegratedTestBase): self.api.post_server, post) # With an invalid imageRef, this throws 500. - server['imageRef'] = self.user.get_invalid_image() + server['imageRef'] = self.get_invalid_image() # TODO(justinsb): Check whatever the spec says should be thrown here self.assertRaises(client.OpenStackApiException, self.api.post_server, post) -- cgit From a1ceed43d6ab871d3dea721b855bd7eabec48433 Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya Date: Wed, 17 Aug 2011 20:24:52 -0700 Subject: clean up fake auth from server actions test --- nova/tests/api/openstack/test_server_actions.py | 8 -------- 1 file changed, 8 deletions(-) (limited to 'nova/tests') diff --git a/nova/tests/api/openstack/test_server_actions.py b/nova/tests/api/openstack/test_server_actions.py index 687a19390..3b419dec5 100644 --- a/nova/tests/api/openstack/test_server_actions.py +++ b/nova/tests/api/openstack/test_server_actions.py @@ -1,17 +1,13 @@ import base64 import json -import unittest -from xml.dom import minidom import stubout import webob from nova import context -from nova import db from nova import utils from nova import flags from nova.api.openstack import create_instance_helper -from nova.compute import instance_types from nova.compute import power_state import nova.db.api from nova import test @@ -103,8 +99,6 @@ class ServerActionsTest(test.TestCase): super(ServerActionsTest, self).setUp() self.flags(verbose=True) self.stubs = stubout.StubOutForTesting() - fakes.FakeAuthManager.reset_fake_data() - fakes.FakeAuthDatabase.data = {} fakes.stub_out_auth(self.stubs) self.stubs.Set(nova.db.api, 'instance_get', return_server_by_id) self.stubs.Set(nova.db.api, 'instance_update', instance_update) @@ -468,8 +462,6 @@ class ServerActionsTestV11(test.TestCase): self.maxDiff = None super(ServerActionsTestV11, self).setUp() self.stubs = stubout.StubOutForTesting() - fakes.FakeAuthManager.reset_fake_data() - fakes.FakeAuthDatabase.data = {} fakes.stub_out_auth(self.stubs) self.stubs.Set(nova.db.api, 'instance_get', return_server_by_id) self.stubs.Set(nova.db.api, 'instance_update', instance_update) -- cgit From b703b33cdd48c2409205504ef09cc91d287862bf Mon Sep 17 00:00:00 2001 From: "vladimir.p" Date: Thu, 18 Aug 2011 14:40:05 -0700 Subject: added unittests for volume_extra_data --- nova/tests/test_volume_types_extra_specs.py | 131 ++++++++++++++++++++++++++++ 1 file changed, 131 insertions(+) create mode 100644 nova/tests/test_volume_types_extra_specs.py (limited to 'nova/tests') diff --git a/nova/tests/test_volume_types_extra_specs.py b/nova/tests/test_volume_types_extra_specs.py new file mode 100644 index 000000000..c48ed789e --- /dev/null +++ b/nova/tests/test_volume_types_extra_specs.py @@ -0,0 +1,131 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright (c) 2011 Zadara Storage Inc. +# Copyright (c) 2011 OpenStack LLC. +# Copyright 2011 University of Southern California +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +""" +Unit Tests for volume types extra specs code +""" + +from nova import context +from nova import db +from nova import test +from nova.db.sqlalchemy.session import get_session +from nova.db.sqlalchemy import models + + +class VolumeTypeExtraSpecsTestCase(test.TestCase): + + def setUp(self): + super(VolumeTypeExtraSpecsTestCase, self).setUp() + self.context = context.get_admin_context() + self.vol_type1 = dict(name="TEST: Regular volume test") + self.vol_type1_specs = dict(vol_extra1="value1", + vol_extra2="value2", + vol_extra3=3) + self.vol_type1['extra_specs'] = self.vol_type1_specs + ref = db.api.volume_type_create(self.context, self.vol_type1) + self.volume_type1_id = ref.id + + self.vol_type2_noextra = dict(name="TEST: Volume type without extra") + ref = db.api.volume_type_create(self.context, self.vol_type2_noextra) + self.vol_type2_id = ref.id + + + def tearDown(self): + # Remove the instance type from the database + db.api.volume_type_purge(context.get_admin_context(), + self.vol_type1['name']) + db.api.volume_type_purge(context.get_admin_context(), + self.vol_type2_noextra['name']) + super(VolumeTypeExtraSpecsTestCase, self).tearDown() + + def test_volume_type_specs_get(self): + expected_specs = self.vol_type1_specs.copy() + actual_specs = db.api.volume_type_extra_specs_get( + context.get_admin_context(), + self.volume_type1_id) + self.assertEquals(expected_specs, actual_specs) + + def test_volume_type_extra_specs_delete(self): + expected_specs = self.vol_type1_specs.copy() + del expected_specs['vol_extra2'] + db.api.volume_type_extra_specs_delete(context.get_admin_context(), + self.volume_type1_id, + 'vol_extra2') + actual_specs = db.api.volume_type_extra_specs_get( + context.get_admin_context(), + self.volume_type1_id) + self.assertEquals(expected_specs, actual_specs) + + def test_volume_type_extra_specs_update(self): + expected_specs = self.vol_type1_specs.copy() + expected_specs['vol_extra3'] = 4 + db.api.volume_type_extra_specs_update_or_create( + context.get_admin_context(), + self.volume_type1_id, + dict(vol_extra3=4)) + actual_specs = db.api.volume_type_extra_specs_get( + context.get_admin_context(), + self.volume_type1_id) + self.assertEquals(expected_specs, actual_specs) + + def test_volume_type_extra_specs_create(self): + expected_specs = self.vol_type1_specs.copy() + expected_specs['vol_extra4'] = 'value4' + expected_specs['vol_extra5'] = 'value5' + db.api.volume_type_extra_specs_update_or_create( + context.get_admin_context(), + self.volume_type1_id, + dict(vol_extra4="value4", + vol_extra5=5)) + actual_specs = db.api.volume_type_extra_specs_get( + context.get_admin_context(), + self.volume_type1_id) + self.assertEquals(expected_specs, actual_specs) + + def test_volume_type_get_with_extra_specs(self): + volume_type = db.api.volume_type_get( + context.get_admin_context(), + self.volume_type1_id) + self.assertEquals(volume_type['extra_specs'], + self.vol_type1_specs) + + volume_type = db.api.volume_type_get( + context.get_admin_context(), + self.vol_type2_id) + self.assertEquals(volume_type['extra_specs'], {}) + + def test_volume_type_get_by_name_with_extra_specs(self): + volume_type = db.api.volume_type_get_by_name( + context.get_admin_context(), + self.vol_type1['name']) + self.assertEquals(volume_type['extra_specs'], + self.vol_type1_specs) + + volume_type = db.api.volume_type_get_by_name( + context.get_admin_context(), + self.vol_type2_noextra['name']) + self.assertEquals(volume_type['extra_specs'], {}) + + def test_volume_type_get_all(self): + expected_specs = self.vol_type1_specs.copy() + + types = db.api.volume_type_get_all(context.get_admin_context()) + + self.assertEquals( + types[self.vol_type1['name']]['extra_specs'], expected_specs) + + self.assertEquals( + types[self.vol_type2_noextra['name']]['extra_specs'], {}) -- cgit From ef3f02fb37d49ccf6099e012bc27b87d7859a306 Mon Sep 17 00:00:00 2001 From: "vladimir.p" Date: Thu, 18 Aug 2011 15:42:30 -0700 Subject: added volume metadata. Fixed test_volume_types_extra_specs --- nova/tests/test_volume_types_extra_specs.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'nova/tests') diff --git a/nova/tests/test_volume_types_extra_specs.py b/nova/tests/test_volume_types_extra_specs.py index c48ed789e..8d2aa2df3 100644 --- a/nova/tests/test_volume_types_extra_specs.py +++ b/nova/tests/test_volume_types_extra_specs.py @@ -37,6 +37,8 @@ class VolumeTypeExtraSpecsTestCase(test.TestCase): self.vol_type1['extra_specs'] = self.vol_type1_specs ref = db.api.volume_type_create(self.context, self.vol_type1) self.volume_type1_id = ref.id + for k, v in self.vol_type1_specs.iteritems(): + self.vol_type1_specs[k] = str(v) self.vol_type2_noextra = dict(name="TEST: Volume type without extra") ref = db.api.volume_type_create(self.context, self.vol_type2_noextra) @@ -71,7 +73,7 @@ class VolumeTypeExtraSpecsTestCase(test.TestCase): def test_volume_type_extra_specs_update(self): expected_specs = self.vol_type1_specs.copy() - expected_specs['vol_extra3'] = 4 + expected_specs['vol_extra3'] = "4" db.api.volume_type_extra_specs_update_or_create( context.get_admin_context(), self.volume_type1_id, @@ -89,7 +91,7 @@ class VolumeTypeExtraSpecsTestCase(test.TestCase): context.get_admin_context(), self.volume_type1_id, dict(vol_extra4="value4", - vol_extra5=5)) + vol_extra5="value5")) actual_specs = db.api.volume_type_extra_specs_get( context.get_admin_context(), self.volume_type1_id) -- cgit From c4fc9f0737ec9f8d5c950b850fed9930a68164f4 Mon Sep 17 00:00:00 2001 From: Christopher MacGown Date: Fri, 19 Aug 2011 08:44:14 -0700 Subject: Add copyright notices --- nova/tests/api/openstack/test_servers.py | 1 + nova/tests/test_compute.py | 1 + 2 files changed, 2 insertions(+) (limited to 'nova/tests') diff --git a/nova/tests/api/openstack/test_servers.py b/nova/tests/api/openstack/test_servers.py index 7d8b222cc..0a46c3fd1 100644 --- a/nova/tests/api/openstack/test_servers.py +++ b/nova/tests/api/openstack/test_servers.py @@ -1,6 +1,7 @@ # vim: tabstop=4 shiftwidth=4 softtabstop=4 # Copyright 2010-2011 OpenStack LLC. +# Copyright 2011 Piston Cloud Computing, Inc. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may diff --git a/nova/tests/test_compute.py b/nova/tests/test_compute.py index 227b42fd7..8d1b95f74 100644 --- a/nova/tests/test_compute.py +++ b/nova/tests/test_compute.py @@ -2,6 +2,7 @@ # Copyright 2010 United States Government as represented by the # Administrator of the National Aeronautics and Space Administration. +# Copyright 2011 Piston Cloud Computing, Inc. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may -- cgit From b3d3f735a7402c49b8db0e19c9b1f8521187378b Mon Sep 17 00:00:00 2001 From: Hisaharu Ishii Date: Fri, 19 Aug 2011 09:32:39 -0700 Subject: Fix unit test for the change of 'nova-manage network list' format --- nova/tests/test_nova_manage.py | 42 +++++++++++++++++++++++------------------- 1 file changed, 23 insertions(+), 19 deletions(-) (limited to 'nova/tests') diff --git a/nova/tests/test_nova_manage.py b/nova/tests/test_nova_manage.py index 69e73367f..e4914e0b1 100644 --- a/nova/tests/test_nova_manage.py +++ b/nova/tests/test_nova_manage.py @@ -103,7 +103,7 @@ class NetworkCommandsTestCase(test.TestCase): self.commands.create( label = 'Test', fixed_range_v4 = '10.2.0.0/24', - fixed_range_v6 = 'fd00:2::/64', + fixed_range_v6 = 'fd00:2::/120', num_networks = 1, network_size = 256, vlan_start = 200, @@ -113,34 +113,38 @@ class NetworkCommandsTestCase(test.TestCase): self.assertEqual(net['label'], 'Test') self.assertEqual(net['cidr'], '10.2.0.0/24') self.assertEqual(net['netmask'], '255.255.255.0') - self.assertEqual(net['cidr_v6'], 'fd00:2::/64') + self.assertEqual(net['cidr_v6'], 'fd00:2::/120') self.assertEqual(net['bridge_interface'], 'eth0') self.assertEqual(net['vlan'], 200) def test_list(self): - format = "%-18s\t%-15s\t%-15s\t%-15s\t%-15s\t%-15s\t%-15s" - head = format % ( - _('IPv4'), - _('IPv6'), - _('start address'), - _('DNS1'), - _('DNS2'), - _('VlanID'), - _('project')) - body = format % ( - '10.2.0.0/24', - 'fd00:2::/64', - '10.2.0.3', - 'None', - 'None', - '200', - 'None',) self.test_create() + net = db.network_get_by_cidr(self.context, '10.2.0.0/24') output = StringIO.StringIO() sys.stdout = output self.commands.list() sys.stdout = sys.__stdout__ result = output.getvalue() + _fmt = "%-5s\t%-18s\t%-15s\t%-15s\t%-15s\t%-15s\t%-15s\t%-15s\t%-15s" + head = _fmt % (_('id'), + _('IPv4'), + _('IPv6'), + _('start address'), + _('DNS1'), + _('DNS2'), + _('VlanID'), + _('project'), + _("uuid")) + body = _fmt % ( + net['id'], + '10.2.0.0/24', + 'fd00:2::/120', + '10.2.0.3', + 'None', + 'None', + '200', + 'None', + net['uuid'],) answer = '%s\n%s\n' % (head, body) self.assertEqual(result, answer) -- cgit From 37508da788c5b2c2eadb36ef61d58836d93a3365 Mon Sep 17 00:00:00 2001 From: Ken Pepple Date: Sat, 20 Aug 2011 12:41:38 -0700 Subject: improve test coverage for instance types / flavors --- nova/tests/test_instance_types.py | 66 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 65 insertions(+), 1 deletion(-) (limited to 'nova/tests') diff --git a/nova/tests/test_instance_types.py b/nova/tests/test_instance_types.py index ef271518c..989c6f32f 100644 --- a/nova/tests/test_instance_types.py +++ b/nova/tests/test_instance_types.py @@ -47,6 +47,29 @@ class InstanceTypeTestCase(test.TestCase): self.id = max_id["id"] + 1 self.name = str(int(time.time())) + def _nonexistant_flavor_name(self): + """return an instance type name not in the DB""" + nonexistant_flavor = "sdfsfsdf" + flavors = instance_types.get_all_types() + while flavors.has_key(nonexistant_flavor): + nonexistant_flavor = nonexistant_flavor.join("z") + else: + return nonexistant_flavor + + def _nonexistant_flavor_id(self): + """return an instance type ID not in the DB""" + nonexistant_flavor = 2700 + flavor_ids = [ value["id"] for key, value in\ + instance_types.get_all_types().iteritems() ] + while nonexistant_flavor in flavor_ids: + nonexistant_flavor += 1 + else: + return nonexistant_flavor + + def _existing_flavor(self): + """return first instance type name""" + return instance_types.get_all_types().keys()[0] + def test_instance_type_create_then_delete(self): """Ensure instance types can be created""" starting_inst_list = instance_types.get_all_types() @@ -87,7 +110,8 @@ class InstanceTypeTestCase(test.TestCase): def test_non_existant_inst_type_shouldnt_delete(self): """Ensures that instance type creation fails with invalid args""" self.assertRaises(exception.ApiError, - instance_types.destroy, "sfsfsdfdfs") + instance_types.destroy, + self._nonexistant_flavor_name()) def test_repeated_inst_types_should_raise_api_error(self): """Ensures that instance duplicates raises ApiError""" @@ -97,3 +121,43 @@ class InstanceTypeTestCase(test.TestCase): self.assertRaises( exception.ApiError, instance_types.create, new_name, 256, 1, 120, self.flavorid) + + def test_will_not_destroy_with_no_name(self): + """Ensure destroy sad path of no name raises error""" + self.assertRaises(exception.ApiError, + instance_types.destroy, + self._nonexistant_flavor_name()) + + def test_will_not_purge_without_name(self): + """Ensure purge without a name raises error""" + self.assertRaises(exception.InvalidInstanceType, + instance_types.purge, None) + + def test_will_not_purge_with_wrong_name(self): + """Ensure purge without correct name raises error""" + self.assertRaises(exception.ApiError, + instance_types.purge, + self._nonexistant_flavor_name()) + + def test_will_not_get_bad_default_instance_type(self): + """ensures error raised on bad default instance type""" + FLAGS.default_instance_type = self._nonexistant_flavor_name() + self.assertRaises(exception.InstanceTypeNotFoundByName, + instance_types.get_default_instance_type) + + def test_will_not_get_instance_type_by_name_with_no_name(self): + """Ensure get by name returns default flavor with no name""" + self.assertEqual(instance_types.get_default_instance_type(), + instance_types.get_instance_type_by_name(None)) + + def test_will_not_get_instance_type_with_bad_name(self): + """Ensure get by name returns default flavor with bad name""" + self.assertRaises(exception.InstanceTypeNotFound, + instance_types.get_instance_type, + self._nonexistant_flavor_name()) + + def test_will_not_get_flavor_by_bad_flavor_id(self): + """Ensure get by flavor raises error with wrong flavorid""" + self.assertRaises(exception.InstanceTypeNotFound, + instance_types.get_instance_type_by_name, + self._nonexistant_flavor_id()) -- cgit From 65b30ad73338fa481d1ab9155153b8265fbe8f90 Mon Sep 17 00:00:00 2001 From: Ken Pepple Date: Sat, 20 Aug 2011 12:43:50 -0700 Subject: pep8 --- nova/tests/test_instance_types.py | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'nova/tests') diff --git a/nova/tests/test_instance_types.py b/nova/tests/test_instance_types.py index 989c6f32f..556ba91a9 100644 --- a/nova/tests/test_instance_types.py +++ b/nova/tests/test_instance_types.py @@ -51,20 +51,20 @@ class InstanceTypeTestCase(test.TestCase): """return an instance type name not in the DB""" nonexistant_flavor = "sdfsfsdf" flavors = instance_types.get_all_types() - while flavors.has_key(nonexistant_flavor): - nonexistant_flavor = nonexistant_flavor.join("z") + while nonexistant_flavor in flavors: + nonexistant_flavor = nonexistant_flavor.join("z") else: - return nonexistant_flavor + return nonexistant_flavor def _nonexistant_flavor_id(self): """return an instance type ID not in the DB""" nonexistant_flavor = 2700 - flavor_ids = [ value["id"] for key, value in\ - instance_types.get_all_types().iteritems() ] + flavor_ids = [value["id"] for key, value in\ + instance_types.get_all_types().iteritems()] while nonexistant_flavor in flavor_ids: - nonexistant_flavor += 1 + nonexistant_flavor += 1 else: - return nonexistant_flavor + return nonexistant_flavor def _existing_flavor(self): """return first instance type name""" @@ -127,12 +127,12 @@ class InstanceTypeTestCase(test.TestCase): self.assertRaises(exception.ApiError, instance_types.destroy, self._nonexistant_flavor_name()) - + def test_will_not_purge_without_name(self): """Ensure purge without a name raises error""" self.assertRaises(exception.InvalidInstanceType, instance_types.purge, None) - + def test_will_not_purge_with_wrong_name(self): """Ensure purge without correct name raises error""" self.assertRaises(exception.ApiError, @@ -149,7 +149,7 @@ class InstanceTypeTestCase(test.TestCase): """Ensure get by name returns default flavor with no name""" self.assertEqual(instance_types.get_default_instance_type(), instance_types.get_instance_type_by_name(None)) - + def test_will_not_get_instance_type_with_bad_name(self): """Ensure get by name returns default flavor with bad name""" self.assertRaises(exception.InstanceTypeNotFound, -- cgit From f4cd3a72fa2a3630ccab2c0224777c3eff05380e Mon Sep 17 00:00:00 2001 From: Ken Pepple Date: Sat, 20 Aug 2011 14:55:41 -0700 Subject: added rainy day test for ipv6 tests. fixed ipv6.to_global to trap correct exception. --- nova/tests/test_ipv6.py | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'nova/tests') diff --git a/nova/tests/test_ipv6.py b/nova/tests/test_ipv6.py index d123df6f1..12d64f776 100644 --- a/nova/tests/test_ipv6.py +++ b/nova/tests/test_ipv6.py @@ -23,6 +23,7 @@ from nova import test LOG = logging.getLogger('nova.tests.test_ipv6') import sys +import netaddr class IPv6RFC2462TestCase(test.TestCase): @@ -40,6 +41,11 @@ class IPv6RFC2462TestCase(test.TestCase): mac = ipv6.to_mac('2001:db8::216:3eff:fe33:4455') self.assertEquals(mac, '00:16:3e:33:44:55') + def test_to_global_with_bad_mac(self): + bad_mac = '02:16:3e:33:44:5Z' + self.assertRaises(TypeError, ipv6.to_global, + '2001:db8::', bad_mac, 'test') + class IPv6AccountIdentiferTestCase(test.TestCase): """Unit tests for IPv6 account_identifier backend operations.""" -- cgit From bad921b5efa7b11a91d1df32b3d17fdb95852589 Mon Sep 17 00:00:00 2001 From: Ken Pepple Date: Sat, 20 Aug 2011 15:07:37 -0700 Subject: removed leftover netaddr import --- nova/tests/test_ipv6.py | 1 - 1 file changed, 1 deletion(-) (limited to 'nova/tests') diff --git a/nova/tests/test_ipv6.py b/nova/tests/test_ipv6.py index 12d64f776..891d52358 100644 --- a/nova/tests/test_ipv6.py +++ b/nova/tests/test_ipv6.py @@ -23,7 +23,6 @@ from nova import test LOG = logging.getLogger('nova.tests.test_ipv6') import sys -import netaddr class IPv6RFC2462TestCase(test.TestCase): -- cgit From 43e2ca531f0fdea5173b7f237627fc3543caf13b Mon Sep 17 00:00:00 2001 From: Ken Pepple Date: Sat, 20 Aug 2011 15:30:59 -0700 Subject: lp:828610 --- nova/tests/test_ipv6.py | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'nova/tests') diff --git a/nova/tests/test_ipv6.py b/nova/tests/test_ipv6.py index d123df6f1..6afc7e3f9 100644 --- a/nova/tests/test_ipv6.py +++ b/nova/tests/test_ipv6.py @@ -55,3 +55,8 @@ class IPv6AccountIdentiferTestCase(test.TestCase): def test_to_mac(self): mac = ipv6.to_mac('2001:db8::a94a:8fe5:ff33:4455') self.assertEquals(mac, '02:16:3e:33:44:55') + + def test_to_global_with_bad_mac(self): + bad_mac = '02:16:3e:33:44:5X' + self.assertRaises(TypeError, ipv6.to_global, + '2001:db8::', bad_mac, 'test') -- cgit From 3bbecbbb8c857079f75bea6fc6610bce9942de34 Mon Sep 17 00:00:00 2001 From: Ken Pepple Date: Sat, 20 Aug 2011 18:20:55 -0700 Subject: added unit tests for versions.py --- nova/tests/test_versions.py | 58 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 nova/tests/test_versions.py (limited to 'nova/tests') diff --git a/nova/tests/test_versions.py b/nova/tests/test_versions.py new file mode 100644 index 000000000..9578eda6d --- /dev/null +++ b/nova/tests/test_versions.py @@ -0,0 +1,58 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright 2011 Ken Pepple +# +# 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. + + +from nova import exception +from nova import test +from nova import utils +from nova import version + + +class VersionTestCase(test.TestCase): + def setUp(self): + """setup test with unchanging values""" + super(VersionTestCase, self).setUp() + self.version = version + self.version.FINAL = False + self.version.NOVA_VERSION = ['2012', '10'] + self.version.YEAR, self.version.COUNT = self.version.NOVA_VERSION + self.version.version_info = {'branch_nick': u'LOCALBRANCH', + 'revision_id': 'LOCALREVISION', + 'revno': 0} + + def test_version_string_is_good(self): + """Ensure version string works""" + self.assertEqual("2012.10-dev", self.version.version_string()) + + def test_canonical_version_string_is_good(self): + """Ensure canonical version works""" + self.assertEqual("2012.10", self.version.canonical_version_string()) + + def test_final_version_strings_are_identical(self): + """Ensure final version strings match""" + self.version.FINAL = True + self.assertEqual(self.version.canonical_version_string(), + self.version.version_string()) + + def test_vcs_version_string_is_good(self): + """""" + self.assertEqual("LOCALBRANCH:LOCALREVISION", + self.version.vcs_version_string()) + + def test_version_string_with_vcs_is_good(self): + """""" + self.assertEqual("2012.10-LOCALBRANCH:LOCALREVISION", + self.version.version_string_with_vcs()) -- cgit From f2981d8463779fa1fca52c840d91b47845719340 Mon Sep 17 00:00:00 2001 From: Ken Pepple Date: Sat, 20 Aug 2011 18:28:30 -0700 Subject: comment strings --- nova/tests/test_versions.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'nova/tests') diff --git a/nova/tests/test_versions.py b/nova/tests/test_versions.py index 9578eda6d..4621b042b 100644 --- a/nova/tests/test_versions.py +++ b/nova/tests/test_versions.py @@ -22,6 +22,7 @@ from nova import version class VersionTestCase(test.TestCase): + """Test cases for Versions code""" def setUp(self): """setup test with unchanging values""" super(VersionTestCase, self).setUp() @@ -42,17 +43,19 @@ class VersionTestCase(test.TestCase): self.assertEqual("2012.10", self.version.canonical_version_string()) def test_final_version_strings_are_identical(self): - """Ensure final version strings match""" + """Ensure final version strings match only at release""" + self.assertNotEqual(self.version.canonical_version_string(), + self.version.version_string()) self.version.FINAL = True self.assertEqual(self.version.canonical_version_string(), self.version.version_string()) def test_vcs_version_string_is_good(self): - """""" + """Ensure uninstalled code generates local """ self.assertEqual("LOCALBRANCH:LOCALREVISION", self.version.vcs_version_string()) def test_version_string_with_vcs_is_good(self): - """""" + """Ensure uninstalled code get version string""" self.assertEqual("2012.10-LOCALBRANCH:LOCALREVISION", self.version.version_string_with_vcs()) -- cgit From 0fdbea56baaef08575b98e8a553ceac9876e4962 Mon Sep 17 00:00:00 2001 From: Ken Pepple Date: Sun, 21 Aug 2011 17:52:14 -0700 Subject: added exception catch and test for bad prefix --- nova/tests/test_ipv6.py | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'nova/tests') diff --git a/nova/tests/test_ipv6.py b/nova/tests/test_ipv6.py index 891d52358..6e72b7330 100644 --- a/nova/tests/test_ipv6.py +++ b/nova/tests/test_ipv6.py @@ -45,6 +45,13 @@ class IPv6RFC2462TestCase(test.TestCase): self.assertRaises(TypeError, ipv6.to_global, '2001:db8::', bad_mac, 'test') + def test_to_global_with_bad_prefix(self): + bad_prefix = '82' + self.assertRaises(TypeError, ipv6.to_global, + bad_prefix, + '2001:db8::216:3eff:fe33:4455', + 'test') + class IPv6AccountIdentiferTestCase(test.TestCase): """Unit tests for IPv6 account_identifier backend operations.""" -- cgit From 326cfda8cc50f5db083e9df381d3109e0302605d Mon Sep 17 00:00:00 2001 From: Ken Pepple Date: Sun, 21 Aug 2011 17:55:54 -0700 Subject: added exception catch for bad prefix and matching test --- nova/tests/test_ipv6.py | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'nova/tests') diff --git a/nova/tests/test_ipv6.py b/nova/tests/test_ipv6.py index 6afc7e3f9..f9c2517a7 100644 --- a/nova/tests/test_ipv6.py +++ b/nova/tests/test_ipv6.py @@ -60,3 +60,10 @@ class IPv6AccountIdentiferTestCase(test.TestCase): bad_mac = '02:16:3e:33:44:5X' self.assertRaises(TypeError, ipv6.to_global, '2001:db8::', bad_mac, 'test') + + def test_to_global_with_bad_prefix(self): + bad_prefix = '78' + self.assertRaises(TypeError, ipv6.to_global, + bad_prefix, + '2001:db8::a94a:8fe5:ff33:4455', + 'test') -- cgit From b5bf5fbb77e95b44f3254a111374ddba73016c4d Mon Sep 17 00:00:00 2001 From: Ken Pepple Date: Sun, 21 Aug 2011 18:01:34 -0700 Subject: added exception catch and test for bad project_id --- nova/tests/test_ipv6.py | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'nova/tests') diff --git a/nova/tests/test_ipv6.py b/nova/tests/test_ipv6.py index f9c2517a7..5c333b17e 100644 --- a/nova/tests/test_ipv6.py +++ b/nova/tests/test_ipv6.py @@ -67,3 +67,10 @@ class IPv6AccountIdentiferTestCase(test.TestCase): bad_prefix, '2001:db8::a94a:8fe5:ff33:4455', 'test') + + def test_to_global_with_bad_project(self): + bad_project = 'non-existent-project-name' + self.assertRaises(TypeError, ipv6.to_global, + '2001:db8::', + '2001:db8::a94a:8fe5:ff33:4455', + bad_project) -- cgit From d4b09b85ad20bd0b83bc48d7bd1e0c6754b2649b Mon Sep 17 00:00:00 2001 From: Ken Pepple Date: Sun, 21 Aug 2011 18:07:07 -0700 Subject: added test for bad project_id ... although it may not be used --- nova/tests/test_ipv6.py | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'nova/tests') diff --git a/nova/tests/test_ipv6.py b/nova/tests/test_ipv6.py index 6e72b7330..f151b9840 100644 --- a/nova/tests/test_ipv6.py +++ b/nova/tests/test_ipv6.py @@ -52,6 +52,13 @@ class IPv6RFC2462TestCase(test.TestCase): '2001:db8::216:3eff:fe33:4455', 'test') + def test_to_global_with_bad_project(self): + bad_project = 'non-existent-project-name' + self.assertRaises(TypeError, ipv6.to_global, + '2001:db8::', + '2001:db8::a94a:8fe5:ff33:4455', + bad_project) + class IPv6AccountIdentiferTestCase(test.TestCase): """Unit tests for IPv6 account_identifier backend operations.""" -- cgit From 34e310eff24b96bcc27df176bfecbd02ac863e7c Mon Sep 17 00:00:00 2001 From: Brian Waldon Date: Sun, 21 Aug 2011 22:59:46 -0400 Subject: fixing bug lp:830817 --- nova/tests/api/openstack/test_servers.py | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'nova/tests') diff --git a/nova/tests/api/openstack/test_servers.py b/nova/tests/api/openstack/test_servers.py index 437620854..8167c4ace 100644 --- a/nova/tests/api/openstack/test_servers.py +++ b/nova/tests/api/openstack/test_servers.py @@ -752,6 +752,27 @@ class ServersTest(test.TestCase): (ip,) = private_node.getElementsByTagName('ip') self.assertEquals(ip.getAttribute('addr'), private) + # NOTE(bcwaldon): lp830817 + def test_get_server_by_id_malformed_networks_v1_1(self): + ifaces = [ + { + 'network': None, + 'fixed_ips': [ + {'address': '192.168.0.3'}, + {'address': '192.168.0.4'}, + ], + }, + ] + new_return_server = return_server_with_attributes(interfaces=ifaces) + self.stubs.Set(nova.db.api, 'instance_get', new_return_server) + + req = webob.Request.blank('/v1.1/servers/1') + res = req.get_response(fakes.wsgi_app()) + self.assertEqual(res.status_int, 200) + res_dict = json.loads(res.body) + self.assertEqual(res_dict['server']['id'], 1) + self.assertEqual(res_dict['server']['name'], 'server1') + def test_get_server_by_id_with_addresses_v1_1(self): self.flags(use_ipv6=True) interfaces = [ -- cgit From 9508bb599c15035f7afbdc80fe70d539e8598edf Mon Sep 17 00:00:00 2001 From: Hisaharu Ishii Date: Mon, 22 Aug 2011 08:59:35 -0700 Subject: Add 'nova-manage network modify' command. --- nova/tests/test_nova_manage.py | 50 ++++++++++++++++++++++++++++++++---------- 1 file changed, 39 insertions(+), 11 deletions(-) (limited to 'nova/tests') diff --git a/nova/tests/test_nova_manage.py b/nova/tests/test_nova_manage.py index e4914e0b1..4c828da16 100644 --- a/nova/tests/test_nova_manage.py +++ b/nova/tests/test_nova_manage.py @@ -39,8 +39,10 @@ from nova import db from nova import flags from nova import test from nova import exception +from nova import log as logging FLAGS = flags.FLAGS +LOG = logging.getLogger('nova.tests.nova_manage') class FixedIpCommandsTestCase(test.TestCase): @@ -88,7 +90,6 @@ class FixedIpCommandsTestCase(test.TestCase): class NetworkCommandsTestCase(test.TestCase): def setUp(self): -# print 'piyo' super(NetworkCommandsTestCase, self).setUp() self.commands = nova_manage.NetworkCommands() self.context = context.get_admin_context() @@ -100,22 +101,29 @@ class NetworkCommandsTestCase(test.TestCase): super(NetworkCommandsTestCase, self).tearDown() def test_create(self): + FLAGS.network_manager='nova.network.manager.VlanManager' self.commands.create( - label = 'Test', - fixed_range_v4 = '10.2.0.0/24', - fixed_range_v6 = 'fd00:2::/120', - num_networks = 1, - network_size = 256, - vlan_start = 200, - bridge_interface = 'eth0', - ) + label='Test', + fixed_range_v4='10.2.0.0/24', + num_networks=1, + network_size=256, + multi_host='F', + vlan_start=200, + vpn_start=2000, + fixed_range_v6='fd00:2::/120', + gateway_v6='fd00:2::22', + bridge_interface='eth0') net = db.network_get_by_cidr(self.context, '10.2.0.0/24') self.assertEqual(net['label'], 'Test') self.assertEqual(net['cidr'], '10.2.0.0/24') self.assertEqual(net['netmask'], '255.255.255.0') + self.assertEqual(net['multi_host'], False) + self.assertEqual(net['vlan'], 200) + self.assertEqual(net['bridge'], 'br200') + self.assertEqual(net['vpn_public_port'], 2000) self.assertEqual(net['cidr_v6'], 'fd00:2::/120') + self.assertEqual(net['gateway_v6'], 'fd00:2::22') self.assertEqual(net['bridge_interface'], 'eth0') - self.assertEqual(net['vlan'], 200) def test_list(self): self.test_create() @@ -150,10 +158,30 @@ class NetworkCommandsTestCase(test.TestCase): def test_delete(self): self.test_create() - self.commands.delete(fixed_range = '10.2.0.0/24') + self.commands.delete(fixed_range='10.2.0.0/24') net_exist = True try: net = db.network_get_by_cidr(self.context, '10.2.0.0/24') except exception.NetworkNotFoundForCidr, e: net_exist = False self.assertEqual(net_exist, False) + + def test_modify(self): + self.test_create() + net = db.network_get_by_cidr(self.context, '10.2.0.0/24') + db.network_disassociate(self.context, net['id']) + net = db.network_get_by_cidr(self.context, '10.2.0.0/24') + self.assertEqual(net['project_id'], None) + self.assertEqual(net['host'], None) + self.commands.modify('10.2.0.0/24', project='test_project', host='test_host') + net = db.network_get_by_cidr(self.context, '10.2.0.0/24') + self.assertEqual(net['project_id'], 'test_project') + self.assertEqual(net['host'], 'test_host') + self.commands.modify('10.2.0.0/24') + net = db.network_get_by_cidr(self.context, '10.2.0.0/24') + self.assertEqual(net['project_id'], 'test_project') + self.assertEqual(net['host'], 'test_host') + self.commands.modify('10.2.0.0/24', project='None', host='None') + net = db.network_get_by_cidr(self.context, '10.2.0.0/24') + self.assertEqual(net['project_id'], None) + self.assertEqual(net['host'], None) -- cgit From f05da72e28fac1bfc7f208ce57d4462a53f290f2 Mon Sep 17 00:00:00 2001 From: Hisaharu Ishii Date: Mon, 22 Aug 2011 11:50:44 -0700 Subject: Fix pep8 --- nova/tests/test_nova_manage.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'nova/tests') diff --git a/nova/tests/test_nova_manage.py b/nova/tests/test_nova_manage.py index 4c828da16..d6edc8ba9 100644 --- a/nova/tests/test_nova_manage.py +++ b/nova/tests/test_nova_manage.py @@ -88,6 +88,7 @@ class FixedIpCommandsTestCase(test.TestCase): '10.0.0.100') self.assertEqual(address['reserved'], False) + class NetworkCommandsTestCase(test.TestCase): def setUp(self): super(NetworkCommandsTestCase, self).setUp() @@ -101,7 +102,7 @@ class NetworkCommandsTestCase(test.TestCase): super(NetworkCommandsTestCase, self).tearDown() def test_create(self): - FLAGS.network_manager='nova.network.manager.VlanManager' + FLAGS.network_manager = 'nova.network.manager.VlanManager' self.commands.create( label='Test', fixed_range_v4='10.2.0.0/24', @@ -173,7 +174,8 @@ class NetworkCommandsTestCase(test.TestCase): net = db.network_get_by_cidr(self.context, '10.2.0.0/24') self.assertEqual(net['project_id'], None) self.assertEqual(net['host'], None) - self.commands.modify('10.2.0.0/24', project='test_project', host='test_host') + self.commands.modify('10.2.0.0/24', project='test_project', + host='test_host') net = db.network_get_by_cidr(self.context, '10.2.0.0/24') self.assertEqual(net['project_id'], 'test_project') self.assertEqual(net['host'], 'test_host') -- cgit From e36ebf31699546e48d27754ac1e26b3704399ab0 Mon Sep 17 00:00:00 2001 From: Tim Simpson Date: Mon, 22 Aug 2011 14:06:59 -0500 Subject: Added ability to detect import errors in list_notifier if one or more drivers could not be loaded. --- nova/tests/notifier/test_list_notifier.py | 52 +++++++++++++++---------------- 1 file changed, 26 insertions(+), 26 deletions(-) (limited to 'nova/tests') diff --git a/nova/tests/notifier/test_list_notifier.py b/nova/tests/notifier/test_list_notifier.py index 65c2ecd90..ca8b3e0a7 100644 --- a/nova/tests/notifier/test_list_notifier.py +++ b/nova/tests/notifier/test_list_notifier.py @@ -31,10 +31,26 @@ from nova import test class NotifierListTestCase(test.TestCase): """Test case for notifications""" + def setUp(self): super(NotifierListTestCase, self).setUp() list_notifier._reset_drivers() self.stubs = stubout.StubOutForTesting() + # Mock log to add one to exception_count when log.exception is called + def mock_exception(cls, *args): + self.exception_count += 1 + self.exception_count = 0 + list_notifier_log = logging.getLogger('nova.notifier.list_notifier') + self.stubs.Set(list_notifier_log, "exception", mock_exception) + # Mock no_op notifier to add one to notify_count when called. + def mock_notify(cls, *args): + self.notify_count += 1 + self.notify_count = 0 + self.stubs.Set(nova.notifier.no_op_notifier, 'notify', mock_notify) + # Mock log_notifier to raise RuntimeError when called. + def mock_notify2(cls, *args): + raise RuntimeError("Bad notifier.") + self.stubs.Set(nova.notifier.log_notifier, 'notify', mock_notify2) def tearDown(self): self.stubs.UnsetAll() @@ -45,41 +61,25 @@ class NotifierListTestCase(test.TestCase): self.flags(notification_driver='nova.notifier.list_notifier', list_notifier_drivers=['nova.notifier.no_op_notifier', 'nova.notifier.no_op_notifier']) - self.notify_count = 0 - - def mock_notify(cls, *args): - self.notify_count += 1 - - self.stubs.Set(nova.notifier.no_op_notifier, 'notify', - mock_notify) - notify('publisher_id', 'event_type', nova.notifier.api.WARN, dict(a=3)) self.assertEqual(self.notify_count, 2) + self.assertEqual(self.exception_count, 0) def test_send_notifications_with_errors(self): - self.exception_count = 0 - def mock_exception(cls, *args): - self.exception_count += 1 - - self.notify_count = 0 - def mock_notify(cls, *args): - self.notify_count += 1 - - def mock_notify2(cls, *args): - raise RuntimeError("Bad notifier.") self.flags(notification_driver='nova.notifier.list_notifier', list_notifier_drivers=['nova.notifier.no_op_notifier', 'nova.notifier.log_notifier']) - - list_notifier_log = logging.getLogger('nova.notifier.list_notifier') - list_notifier_log.exception - self.stubs.Set(list_notifier_log, "exception", mock_exception) - self.stubs.Set(nova.notifier.no_op_notifier, 'notify', mock_notify) - self.stubs.Set(nova.notifier.log_notifier, 'notify', mock_notify2) - notify('publisher_id', 'event_type', nova.notifier.api.WARN, dict(a=3)) - self.assertEqual(self.notify_count, 1) self.assertEqual(self.exception_count, 1) + + def test_when_driver_fails_to_import(self): + self.flags(notification_driver='nova.notifier.list_notifier', + list_notifier_drivers=['nova.notifier.no_op_notifier', + 'nova.notifier.logo_notifier', + 'fdsjgsdfhjkhgsfkj']) + notify('publisher_id', 'event_type', nova.notifier.api.WARN, dict(a=3)) + self.assertEqual(self.exception_count, 2) + self.assertEqual(self.notify_count, 1) -- cgit From 25ee794d803fa522d31177dc16d8c535d9b8daab Mon Sep 17 00:00:00 2001 From: Soren Hansen Date: Mon, 22 Aug 2011 21:52:49 +0200 Subject: Add a generic set of tests for hypervisor drivers. --- nova/tests/test_virt_drivers.py | 483 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 483 insertions(+) create mode 100644 nova/tests/test_virt_drivers.py (limited to 'nova/tests') diff --git a/nova/tests/test_virt_drivers.py b/nova/tests/test_virt_drivers.py new file mode 100644 index 000000000..2c91c0664 --- /dev/null +++ b/nova/tests/test_virt_drivers.py @@ -0,0 +1,483 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 +# +# Copyright 2010 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. + +import base64 +import netaddr +import sys +import traceback + +from nova import exception +from nova import flags +from nova import image +from nova import log as logging +from nova import test +from nova.tests import utils as test_utils + +libvirt = None +FLAGS = flags.FLAGS + +LOG = logging.getLogger('nova.tests.test_virt_drivers') + +def catch_notimplementederror(f): + """Decorator to simplify catching drivers raising NotImplementedError + + If a particular call makes a driver raise NotImplementedError, we + log it so that we can extract this information afterwards to + automatically generate a hypervisor/feature support matrix.""" + def wrapped_func(self, *args, **kwargs): + try: + return f(self, *args, **kwargs) + except NotImplementedError: + frame = traceback.extract_tb(sys.exc_info()[2])[-1] + LOG.error('%(driver)s does not implement %(method)s' % { + 'driver': type(self.connection), + 'method': frame[2]}) + + wrapped_func.__name__ = f.__name__ + wrapped_func.__doc__ = f.__doc__ + return wrapped_func + +class _VirtDriverTestCase(test.TestCase): + def setUp(self): + super(_VirtDriverTestCase, self).setUp() + self.connection = self.driver_module.get_connection('') + self.ctxt = test_utils.get_test_admin_context() + self.image_service = image.get_default_image_service() + + @catch_notimplementederror + def test_init_host(self): + self.connection.init_host('myhostname') + + @catch_notimplementederror + def test_list_instances(self): + self.connection.list_instances() + + @catch_notimplementederror + def test_list_instances_detail(self): + self.connection.list_instances_detail() + + @catch_notimplementederror + def test_spawn(self): + instance_ref = test_utils.get_test_instance() + network_info = test_utils.get_test_network_info() + self.connection.spawn(self.ctxt, instance_ref, network_info) + + domains = self.connection.list_instances() + self.assertIn(instance_ref['name'], domains) + + domains_details = self.connection.list_instances_detail() + self.assertIn(instance_ref['name'], [i.name for i in domains_details]) + + @catch_notimplementederror + def test_snapshot_not_running(self): + instance_ref = test_utils.get_test_instance() + img_ref = self.image_service.create(self.ctxt, {'name': 'snap-1'}) + self.assertRaises(exception.InstanceNotRunning, + self.connection.snapshot, + self.ctxt, instance_ref, img_ref['id']) + + @catch_notimplementederror + def test_snapshot_running(self): + instance_ref = test_utils.get_test_instance() + network_info = test_utils.get_test_network_info() + img_ref = self.image_service.create(self.ctxt, {'name': 'snap-1'}) + self.connection.spawn(self.ctxt, instance_ref, network_info) + self.connection.snapshot(self.ctxt, instance_ref, img_ref['id']) + + @catch_notimplementederror + def test_reboot(self): + instance_ref = test_utils.get_test_instance() + network_info = test_utils.get_test_network_info() + self.connection.spawn(self.ctxt, instance_ref, network_info) + self.connection.reboot(instance_ref, network_info) + + @catch_notimplementederror + def test_get_host_ip_addr(self): + host_ip = self.connection.get_host_ip_addr() + + # Will raise an exception if it's not a valid IP at all + ip = netaddr.IPAddress(host_ip) + + # For now, assume IPv4. + self.assertEquals(ip.version, 4) + + @catch_notimplementederror + def test_resize_running(self): + instance_ref = test_utils.get_test_instance() + network_info = test_utils.get_test_network_info() + self.connection.spawn(self.ctxt, instance_ref, network_info) + self.connection.resize(instance_ref, 7) + + @catch_notimplementederror + def test_set_admin_password(self): + instance_ref = test_utils.get_test_instance() + network_info = test_utils.get_test_network_info() + self.connection.spawn(self.ctxt, instance_ref, network_info) + self.connection.set_admin_password(instance_ref, 'p4ssw0rd') + + @catch_notimplementederror + def test_inject_file(self): + instance_ref = test_utils.get_test_instance() + network_info = test_utils.get_test_network_info() + self.connection.spawn(self.ctxt, instance_ref, network_info) + self.connection.inject_file(instance_ref, + base64.b64encode('/testfile'), + base64.b64encode('testcontents')) + + @catch_notimplementederror + def test_agent_update(self): + instance_ref = test_utils.get_test_instance() + network_info = test_utils.get_test_network_info() + self.connection.spawn(self.ctxt, instance_ref, network_info) + self.connection.agent_update(instance_ref, 'http://www.openstack.org/', + 'd41d8cd98f00b204e9800998ecf8427e') + + @catch_notimplementederror + def test_rescue(self): + instance_ref = test_utils.get_test_instance() + network_info = test_utils.get_test_network_info() + self.connection.spawn(self.ctxt, instance_ref, network_info) + self.connection.rescue(self.ctxt, instance_ref, + lambda x:None, network_info) + + @catch_notimplementederror + def test_unrescue_unrescued_instance(self): + instance_ref = test_utils.get_test_instance() + network_info = test_utils.get_test_network_info() + self.connection.spawn(self.ctxt, instance_ref, network_info) + self.connection.unrescue(instance_ref, lambda x:None, network_info) + + @catch_notimplementederror + def test_unrescue_rescued_instance(self): + instance_ref = test_utils.get_test_instance() + network_info = test_utils.get_test_network_info() + self.connection.spawn(self.ctxt, instance_ref, network_info) + self.connection.rescue(self.ctxt, instance_ref, + lambda x:None, network_info) + self.connection.unrescue(instance_ref, lambda x:None, network_info) + + @catch_notimplementederror + def test_poll_rescued_instances(self): + self.connection.poll_rescued_instances(10) + + @catch_notimplementederror + def test_migrate_disk_and_power_off(self): + instance_ref = test_utils.get_test_instance() + network_info = test_utils.get_test_network_info() + self.connection.spawn(self.ctxt, instance_ref, network_info) + self.connection.migrate_disk_and_power_off(instance_ref, 'dest_host') + + @catch_notimplementederror + def test_pause(self): + instance_ref = test_utils.get_test_instance() + network_info = test_utils.get_test_network_info() + self.connection.spawn(self.ctxt, instance_ref, network_info) + self.connection.pause(instance_ref, None) + + @catch_notimplementederror + def test_unpause_unpaused_instance(self): + instance_ref = test_utils.get_test_instance() + network_info = test_utils.get_test_network_info() + self.connection.spawn(self.ctxt, instance_ref, network_info) + self.connection.unpause(instance_ref, None) + + @catch_notimplementederror + def test_unpause_paused_instance(self): + instance_ref = test_utils.get_test_instance() + network_info = test_utils.get_test_network_info() + self.connection.spawn(self.ctxt, instance_ref, network_info) + self.connection.pause(instance_ref, None) + self.connection.unpause(instance_ref, None) + + @catch_notimplementederror + def test_suspend(self): + instance_ref = test_utils.get_test_instance() + network_info = test_utils.get_test_network_info() + self.connection.spawn(self.ctxt, instance_ref, network_info) + self.connection.suspend(instance_ref, None) + + @catch_notimplementederror + def test_resume_unsuspended_instance(self): + instance_ref = test_utils.get_test_instance() + network_info = test_utils.get_test_network_info() + self.connection.spawn(self.ctxt, instance_ref, network_info) + self.connection.resume(instance_ref, None) + + @catch_notimplementederror + def test_resume_suspended_instance(self): + instance_ref = test_utils.get_test_instance() + network_info = test_utils.get_test_network_info() + self.connection.spawn(self.ctxt, instance_ref, network_info) + self.connection.suspend(instance_ref, None) + self.connection.resume(instance_ref, None) + + @catch_notimplementederror + def test_destroy_instance_nonexistant(self): + fake_instance = { 'id': 42, 'name': 'I just made this up!' } + network_info = test_utils.get_test_network_info() + self.connection.destroy(fake_instance, network_info) + + @catch_notimplementederror + def test_destroy_instance(self): + instance_ref = test_utils.get_test_instance() + network_info = test_utils.get_test_network_info() + self.connection.spawn(self.ctxt, instance_ref, network_info) + self.assertIn(instance_ref['name'], + self.connection.list_instances()) + self.connection.destroy(instance_ref, network_info) + self.assertNotIn(instance_ref['name'], + self.connection.list_instances()) + + @catch_notimplementederror + def test_attach_detach_volume(self): + network_info = test_utils.get_test_network_info() + instance_ref = test_utils.get_test_instance() + self.connection.spawn(self.ctxt, instance_ref, network_info) + self.connection.attach_volume(instance_ref['name'], + '/dev/null', '/mnt/nova/something') + self.connection.detach_volume(instance_ref['name'], + '/mnt/nova/something') + + @catch_notimplementederror + def test_get_info(self): + network_info = test_utils.get_test_network_info() + instance_ref = test_utils.get_test_instance() + self.connection.spawn(self.ctxt, instance_ref, network_info) + info = self.connection.get_info(instance_ref['name']) + self.assertIn('state', info) + self.assertIn('max_mem', info) + self.assertIn('mem', info) + self.assertIn('num_cpu', info) + self.assertIn('cpu_time', info) + + @catch_notimplementederror + def test_get_info_for_unknown_instance(self): + self.assertRaises(exception.NotFound, + self.connection.get_info, 'I just made this name up') + + @catch_notimplementederror + def test_get_diagnostics(self): + network_info = test_utils.get_test_network_info() + instance_ref = test_utils.get_test_instance() + self.connection.spawn(self.ctxt, instance_ref, network_info) + self.connection.get_diagnostics(instance_ref['name']) + + @catch_notimplementederror + def test_list_disks(self): + network_info = test_utils.get_test_network_info() + instance_ref = test_utils.get_test_instance() + self.connection.spawn(self.ctxt, instance_ref, network_info) + self.connection.list_disks(instance_ref['name']) + + @catch_notimplementederror + def test_list_interfaces(self): + network_info = test_utils.get_test_network_info() + instance_ref = test_utils.get_test_instance() + self.connection.spawn(self.ctxt, instance_ref, network_info) + self.connection.list_interfaces(instance_ref['name']) + + @catch_notimplementederror + def test_block_stats(self): + network_info = test_utils.get_test_network_info() + instance_ref = test_utils.get_test_instance() + self.connection.spawn(self.ctxt, instance_ref, network_info) + stats = self.connection.block_stats(instance_ref['name'], 'someid') + self.assertEquals(len(stats), 5) + + @catch_notimplementederror + def test_interface_stats(self): + network_info = test_utils.get_test_network_info() + instance_ref = test_utils.get_test_instance() + self.connection.spawn(self.ctxt, instance_ref, network_info) + stats = self.connection.interface_stats(instance_ref['name'], 'someid') + self.assertEquals(len(stats), 8) + + @catch_notimplementederror + def test_get_console_output(self): + network_info = test_utils.get_test_network_info() + instance_ref = test_utils.get_test_instance() + self.connection.spawn(self.ctxt, instance_ref, network_info) + console_output = self.connection.get_console_output(instance_ref) + self.assertTrue(isinstance(console_output, basestring)) + + @catch_notimplementederror + def test_get_ajax_console(self): + network_info = test_utils.get_test_network_info() + instance_ref = test_utils.get_test_instance() + self.connection.spawn(self.ctxt, instance_ref, network_info) + ajax_console = self.connection.get_ajax_console(instance_ref) + self.assertIn('token', ajax_console) + self.assertIn('host', ajax_console) + self.assertIn('port', ajax_console) + + @catch_notimplementederror + def test_get_vnc_console(self): + network_info = test_utils.get_test_network_info() + instance_ref = test_utils.get_test_instance() + self.connection.spawn(self.ctxt, instance_ref, network_info) + vnc_console = self.connection.get_vnc_console(instance_ref) + self.assertIn('token', vnc_console) + self.assertIn('host', vnc_console) + self.assertIn('port', vnc_console) + + @catch_notimplementederror + def test_get_console_pool_info(self): + network_info = test_utils.get_test_network_info() + instance_ref = test_utils.get_test_instance() + self.connection.spawn(self.ctxt, instance_ref, network_info) + console_pool = self.connection.get_console_pool_info(instance_ref) + self.assertIn('address', console_pool) + self.assertIn('username', console_pool) + self.assertIn('password', console_pool) + + @catch_notimplementederror + def test_refresh_security_group_rules(self): + network_info = test_utils.get_test_network_info() + instance_ref = test_utils.get_test_instance() + # FIXME: Create security group and add the instance to it + self.connection.spawn(self.ctxt, instance_ref, network_info) + self.connection.refresh_security_group_rules(1) + + @catch_notimplementederror + def test_refresh_security_group_members(self): + network_info = test_utils.get_test_network_info() + instance_ref = test_utils.get_test_instance() + # FIXME: Create security group and add the instance to it + self.connection.spawn(self.ctxt, instance_ref, network_info) + self.connection.refresh_security_group_members(1) + + @catch_notimplementederror + def test_refresh_provider_fw_rules(self): + network_info = test_utils.get_test_network_info() + instance_ref = test_utils.get_test_instance() + self.connection.spawn(self.ctxt, instance_ref, network_info) + self.connection.refresh_provider_fw_rules() + + @catch_notimplementederror + def test_update_available_resource(self): + self.compute = self.start_service('compute', host='dummy') + self.connection.update_available_resource(self.ctxt, 'dummy') + + @catch_notimplementederror + def test_compare_cpu(self): + cpu_info = '''{ "topology": { + "sockets": 1, + "cores": 2, + "threads": 1 }, + "features": [ + "xtpr", + "tm2", + "est", + "vmx", + "ds_cpl", + "monitor", + "pbe", + "tm", + "ht", + "ss", + "acpi", + "ds", + "vme"], + "arch": "x86_64", + "model": "Penryn", + "vendor": "Intel" }''' + + self.connection.compare_cpu(cpu_info) + + @catch_notimplementederror + def test_ensure_filtering_for_instance(self): + instance_ref = test_utils.get_test_instance() + network_info = test_utils.get_test_network_info() + self.connection.ensure_filtering_rules_for_instance(instance_ref, + network_info) + + @catch_notimplementederror + def test_unfilter_instance(self): + instance_ref = test_utils.get_test_instance() + network_info = test_utils.get_test_network_info() + self.connection.unfilter_instance(instance_ref, network_info) + + + @catch_notimplementederror + def test_live_migration(self): + network_info = test_utils.get_test_network_info() + instance_ref = test_utils.get_test_instance() + self.connection.spawn(self.ctxt, instance_ref, network_info) + self.connection.live_migration(self.ctxt, instance_ref, 'otherhost', + None, None) + + @catch_notimplementederror + def _check_host_status_fields(self, host_status): + self.assertIn('host_name-description', host_status) + self.assertIn('host_hostname', host_status) + self.assertIn('host_memory_total', host_status) + self.assertIn('host_memory_overhead', host_status) + self.assertIn('host_memory_free', host_status) + self.assertIn('host_memory_free_computed', host_status) + self.assertIn('host_other_config', host_status) + self.assertIn('host_ip_address', host_status) + self.assertIn('host_cpu_info', host_status) + self.assertIn('disk_available', host_status) + self.assertIn('disk_total', host_status) + self.assertIn('disk_used', host_status) + self.assertIn('host_uuid', host_status) + self.assertIn('host_name_label', host_status) + + @catch_notimplementederror + def test_update_host_status(self): + host_status = self.connection.update_host_status() + self._check_host_status_fields(host_status) + + @catch_notimplementederror + def test_get_host_stats(self): + host_status = self.connection.get_host_stats() + self._check_host_status_fields(host_status) + + @catch_notimplementederror + def test_set_host_enabled(self): + self.connection.set_host_enabled('Am I a useless argument?', True) + + @catch_notimplementederror + def test_host_power_action_reboot(self): + self.connection.host_power_action('Am I a useless argument?', 'reboot') + + @catch_notimplementederror + def test_host_power_action_shutdown(self): + self.connection.host_power_action('Am I a useless argument?', 'shutdown') + + @catch_notimplementederror + def test_host_power_action_startup(self): + self.connection.host_power_action('Am I a useless argument?', 'startup') + +class AbstractDriverTestCase(_VirtDriverTestCase): + def setUp(self): + import nova.virt.driver + self.driver_module = nova.virt.driver + def get_driver_connection(_): + return nova.virt.driver.ComputeDriver() + self.driver_module.get_connection = get_driver_connection + super(AbstractDriverTestCase, self).setUp() + +class FakeConnectionTestCase(_VirtDriverTestCase): + def setUp(self): + import nova.virt.fake + self.driver_module = nova.virt.fake + super(FakeConnectionTestCase, self).setUp() + +# Before long, we'll add the real hypervisor drivers here as well +# with whatever instrumentation they need to work independently of +# their hypervisor. This way, we can verify that they all act the +# same. -- cgit From 51344d7be195f9342d24d461f4c07fa1c9141da4 Mon Sep 17 00:00:00 2001 From: Tim Simpson Date: Mon, 22 Aug 2011 15:21:31 -0500 Subject: Changed list_notifier to call sys.exit if a notification driver could not be found. --- nova/tests/notifier/test_list_notifier.py | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'nova/tests') diff --git a/nova/tests/notifier/test_list_notifier.py b/nova/tests/notifier/test_list_notifier.py index ca8b3e0a7..bab1a0ab8 100644 --- a/nova/tests/notifier/test_list_notifier.py +++ b/nova/tests/notifier/test_list_notifier.py @@ -14,18 +14,15 @@ # under the License. import stubout +import sys import nova -from nova import context -from nova import flags from nova import log as logging -from nova import rpc import nova.notifier.api from nova.notifier.api import notify from nova.notifier import log_notifier from nova.notifier import no_op_notifier from nova.notifier import list_notifier -from nova.notifier import rabbit_notifier from nova import test @@ -51,6 +48,11 @@ class NotifierListTestCase(test.TestCase): def mock_notify2(cls, *args): raise RuntimeError("Bad notifier.") self.stubs.Set(nova.notifier.log_notifier, 'notify', mock_notify2) + # mock sys.exit so we don't actually kill the program during our tests. + self.sys_exit_code = 0 + def mock_sys_exit(code): + self.sys_exit_code += code + self.stubs.Set(sys, 'exit', mock_sys_exit) def tearDown(self): self.stubs.UnsetAll() @@ -65,6 +67,7 @@ class NotifierListTestCase(test.TestCase): nova.notifier.api.WARN, dict(a=3)) self.assertEqual(self.notify_count, 2) self.assertEqual(self.exception_count, 0) + self.assertEqual(self.sys_exit_code, 0) def test_send_notifications_with_errors(self): @@ -74,6 +77,7 @@ class NotifierListTestCase(test.TestCase): notify('publisher_id', 'event_type', nova.notifier.api.WARN, dict(a=3)) self.assertEqual(self.notify_count, 1) self.assertEqual(self.exception_count, 1) + self.assertEqual(self.sys_exit_code, 0) def test_when_driver_fails_to_import(self): self.flags(notification_driver='nova.notifier.list_notifier', @@ -81,5 +85,6 @@ class NotifierListTestCase(test.TestCase): 'nova.notifier.logo_notifier', 'fdsjgsdfhjkhgsfkj']) notify('publisher_id', 'event_type', nova.notifier.api.WARN, dict(a=3)) - self.assertEqual(self.exception_count, 2) + self.assertEqual(self.exception_count, 0) self.assertEqual(self.notify_count, 1) + self.assertEqual(self.sys_exit_code, 2) -- cgit From 5a288485215a13f3892ae17a46b9644ed84fc089 Mon Sep 17 00:00:00 2001 From: Nachi Ueno Date: Mon, 22 Aug 2011 14:24:37 -0700 Subject: Added Test Code, doc string, and fixed pip-requiresw --- nova/tests/test_notifier.py | 22 ++++++++++++++++++++++ nova/tests/test_utils.py | 44 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+) (limited to 'nova/tests') diff --git a/nova/tests/test_notifier.py b/nova/tests/test_notifier.py index 64b799a2c..ab5dfb692 100644 --- a/nova/tests/test_notifier.py +++ b/nova/tests/test_notifier.py @@ -134,3 +134,25 @@ class NotifierTestCase(test.TestCase): self.assertEqual(msg['event_type'], 'error_notification') self.assertEqual(msg['priority'], 'ERROR') self.assertEqual(msg['payload']['error'], 'foo') + + def test_send_notification_by_decorator(self): + self.notify_called = False + + def example_api(arg1, arg2): + return arg1 + arg2 + + example_api =\ + nova.notifier.api.notify_decorator( + 'example_api', + example_api) + + def mock_notify(cls, *args): + self.notify_called = True + + self.stubs.Set(nova.notifier.no_op_notifier, 'notify', + mock_notify) + + class Mock(object): + pass + self.assertEqual(3, example_api(1, 2)) + self.assertEqual(self.notify_called, True) diff --git a/nova/tests/test_utils.py b/nova/tests/test_utils.py index ec5098a37..317ec46d0 100644 --- a/nova/tests/test_utils.py +++ b/nova/tests/test_utils.py @@ -18,6 +18,7 @@ import datetime import os import tempfile +import nova from nova import exception from nova import test from nova import utils @@ -384,3 +385,46 @@ class ToPrimitiveTestCase(test.TestCase): def test_typeerror(self): x = bytearray # Class, not instance self.assertEquals(utils.to_primitive(x), u"") + + +class MonkeyPatchTestCase(test.TestCase): + """Unit test for utils.monkey_patch().""" + def setUp(self): + super(MonkeyPatchTestCase, self).setUp() + self.flags( + monkey_patch=True, + monkey_patch_modules=['nova.tests.example.example_a' + ':' + + 'nova.tests.example.example_decorator']) + + def test_monkey_patch(self): + utils.monkey_patch() + nova.tests.example.CALLED_FUNCTION = [] + from nova.tests.example import example_a, example_b + + self.assertEqual('Example function', example_a.example_function_a()) + exampleA = example_a.ExampleClassA() + exampleA.example_method() + ret_a = exampleA.example_method_add(3, 5) + self.assertEqual(ret_a, 8) + + self.assertEqual('Example function', example_b.example_function_b()) + exampleB = example_b.ExampleClassB() + exampleB.example_method() + ret_b = exampleB.example_method_add(3, 5) + + self.assertEqual(ret_b, 8) + package_a = 'nova.tests.example.example_a.' + self.assertTrue(package_a + 'example_function_a' + in nova.tests.example.CALLED_FUNCTION) + + self.assertTrue(package_a + 'ExampleClassA.example_method' + in nova.tests.example.CALLED_FUNCTION) + self.assertTrue(package_a + 'ExampleClassA.example_method_add' + in nova.tests.example.CALLED_FUNCTION) + package_b = 'nova.tests.example.example_b.' + self.assertFalse(package_b + 'example_function_b' + in nova.tests.example.CALLED_FUNCTION) + self.assertFalse(package_b + 'ExampleClassB.example_method' + in nova.tests.example.CALLED_FUNCTION) + self.assertFalse(package_b + 'ExampleClassB.example_method_add' + in nova.tests.example.CALLED_FUNCTION) -- cgit From 150098011db8ca6c534c4a281df388bd42301eea Mon Sep 17 00:00:00 2001 From: Soren Hansen Date: Mon, 22 Aug 2011 23:26:12 +0200 Subject: Update a few doc strings. Address a few pep8 issues. Add nova.tests.utils which provides a couple of handy methods for testing stuff. --- nova/tests/test_test_utils.py | 41 +++++++++++++++++++++++++ nova/tests/test_virt_drivers.py | 26 ++++++++++------ nova/tests/utils.py | 68 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 125 insertions(+), 10 deletions(-) create mode 100644 nova/tests/test_test_utils.py create mode 100644 nova/tests/utils.py (limited to 'nova/tests') diff --git a/nova/tests/test_test_utils.py b/nova/tests/test_test_utils.py new file mode 100644 index 000000000..237339758 --- /dev/null +++ b/nova/tests/test_test_utils.py @@ -0,0 +1,41 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 +# +# Copyright 2010 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. + +from nova import db +from nova import test +from nova.tests import utils as test_utils + + +class TestUtilsTestCase(test.TestCase): + def test_get_test_admin_context(self): + """get_test_admin_context's return value behaves like admin context""" + ctxt = test_utils.get_test_admin_context() + + # TODO(soren): This should verify the full interface context + # objects expose. + self.assertTrue(ctxt.is_admin) + + def test_get_test_instance(self): + """get_test_instance's return value looks like an instance_ref""" + instance_ref = test_utils.get_test_instance() + ctxt = test_utils.get_test_admin_context() + db.instance_get(ctxt, instance_ref['id']) + + def _test_get_test_network_info(self): + """Does the return value match a real network_info structure""" + # The challenge here is to define what exactly such a structure + # must look like. + pass diff --git a/nova/tests/test_virt_drivers.py b/nova/tests/test_virt_drivers.py index 2c91c0664..480247c91 100644 --- a/nova/tests/test_virt_drivers.py +++ b/nova/tests/test_virt_drivers.py @@ -31,6 +31,7 @@ FLAGS = flags.FLAGS LOG = logging.getLogger('nova.tests.test_virt_drivers') + def catch_notimplementederror(f): """Decorator to simplify catching drivers raising NotImplementedError @@ -50,6 +51,7 @@ def catch_notimplementederror(f): wrapped_func.__doc__ = f.__doc__ return wrapped_func + class _VirtDriverTestCase(test.TestCase): def setUp(self): super(_VirtDriverTestCase, self).setUp() @@ -151,14 +153,14 @@ class _VirtDriverTestCase(test.TestCase): network_info = test_utils.get_test_network_info() self.connection.spawn(self.ctxt, instance_ref, network_info) self.connection.rescue(self.ctxt, instance_ref, - lambda x:None, network_info) + lambda x: None, network_info) @catch_notimplementederror def test_unrescue_unrescued_instance(self): instance_ref = test_utils.get_test_instance() network_info = test_utils.get_test_network_info() self.connection.spawn(self.ctxt, instance_ref, network_info) - self.connection.unrescue(instance_ref, lambda x:None, network_info) + self.connection.unrescue(instance_ref, lambda x: None, network_info) @catch_notimplementederror def test_unrescue_rescued_instance(self): @@ -166,8 +168,8 @@ class _VirtDriverTestCase(test.TestCase): network_info = test_utils.get_test_network_info() self.connection.spawn(self.ctxt, instance_ref, network_info) self.connection.rescue(self.ctxt, instance_ref, - lambda x:None, network_info) - self.connection.unrescue(instance_ref, lambda x:None, network_info) + lambda x: None, network_info) + self.connection.unrescue(instance_ref, lambda x: None, network_info) @catch_notimplementederror def test_poll_rescued_instances(self): @@ -226,7 +228,7 @@ class _VirtDriverTestCase(test.TestCase): @catch_notimplementederror def test_destroy_instance_nonexistant(self): - fake_instance = { 'id': 42, 'name': 'I just made this up!' } + fake_instance = {'id': 42, 'name': 'I just made this up!'} network_info = test_utils.get_test_network_info() self.connection.destroy(fake_instance, network_info) @@ -410,7 +412,6 @@ class _VirtDriverTestCase(test.TestCase): network_info = test_utils.get_test_network_info() self.connection.unfilter_instance(instance_ref, network_info) - @catch_notimplementederror def test_live_migration(self): network_info = test_utils.get_test_network_info() @@ -448,29 +449,34 @@ class _VirtDriverTestCase(test.TestCase): @catch_notimplementederror def test_set_host_enabled(self): - self.connection.set_host_enabled('Am I a useless argument?', True) + self.connection.set_host_enabled('a useless argument?', True) @catch_notimplementederror def test_host_power_action_reboot(self): - self.connection.host_power_action('Am I a useless argument?', 'reboot') + self.connection.host_power_action('a useless argument?', 'reboot') @catch_notimplementederror def test_host_power_action_shutdown(self): - self.connection.host_power_action('Am I a useless argument?', 'shutdown') + self.connection.host_power_action('a useless argument?', 'shutdown') @catch_notimplementederror def test_host_power_action_startup(self): - self.connection.host_power_action('Am I a useless argument?', 'startup') + self.connection.host_power_action('a useless argument?', 'startup') + class AbstractDriverTestCase(_VirtDriverTestCase): def setUp(self): import nova.virt.driver + self.driver_module = nova.virt.driver + def get_driver_connection(_): return nova.virt.driver.ComputeDriver() + self.driver_module.get_connection = get_driver_connection super(AbstractDriverTestCase, self).setUp() + class FakeConnectionTestCase(_VirtDriverTestCase): def setUp(self): import nova.virt.fake diff --git a/nova/tests/utils.py b/nova/tests/utils.py new file mode 100644 index 000000000..e0cacadb4 --- /dev/null +++ b/nova/tests/utils.py @@ -0,0 +1,68 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 +# +# Copyright 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 +# + +import nova.context +import nova.db +import nova.flags + +FLAGS = nova.flags.FLAGS + + +def get_test_admin_context(): + return nova.context.get_admin_context() + + +def get_test_instance(context=None): + if not context: + context = get_test_admin_context() + + test_instance = {'memory_kb': '1024000', + 'basepath': '/some/path', + 'bridge_name': 'br100', + 'vcpus': 2, + 'project_id': 'fake', + 'bridge': 'br101', + 'image_ref': '1', + 'instance_type_id': '5'} # m1.small + + instance_ref = nova.db.instance_create(context, test_instance) + return instance_ref + + +def get_test_network_info(count=1): + ipv6 = FLAGS.use_ipv6 + fake = 'fake' + fake_ip = '0.0.0.0/0' + fake_ip_2 = '0.0.0.1/0' + fake_ip_3 = '0.0.0.1/0' + fake_vlan = 100 + fake_bridge_interface = 'eth0' + network = {'bridge': fake, + 'cidr': fake_ip, + 'cidr_v6': fake_ip, + 'vlan': fake_vlan, + 'bridge_interface': fake_bridge_interface, + 'injected': False} + mapping = {'mac': fake, + 'dhcp_server': fake, + 'gateway': fake, + 'gateway6': fake, + 'ips': [{'ip': fake_ip}, {'ip': fake_ip}]} + if ipv6: + mapping['ip6s'] = [{'ip': fake_ip}, + {'ip': fake_ip_2}, + {'ip': fake_ip_3}] + return [(network, mapping) for x in xrange(0, count)] -- cgit From 0d0c8dfbf29b47aa13e18dd8861bad6ccb10cf12 Mon Sep 17 00:00:00 2001 From: Hisaharu Ishii Date: Mon, 22 Aug 2011 16:46:29 -0700 Subject: Change parameters of 'nova-manage network modify'. Move common test codes into private method. --- nova/tests/test_nova_manage.py | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) (limited to 'nova/tests') diff --git a/nova/tests/test_nova_manage.py b/nova/tests/test_nova_manage.py index d6edc8ba9..91130de67 100644 --- a/nova/tests/test_nova_manage.py +++ b/nova/tests/test_nova_manage.py @@ -36,10 +36,10 @@ import netaddr import StringIO from nova import context from nova import db -from nova import flags -from nova import test from nova import exception +from nova import flags from nova import log as logging +from nova import test FLAGS = flags.FLAGS LOG = logging.getLogger('nova.tests.nova_manage') @@ -101,7 +101,7 @@ class NetworkCommandsTestCase(test.TestCase): def tearDown(self): super(NetworkCommandsTestCase, self).tearDown() - def test_create(self): + def _create_network(self): FLAGS.network_manager = 'nova.network.manager.VlanManager' self.commands.create( label='Test', @@ -114,7 +114,10 @@ class NetworkCommandsTestCase(test.TestCase): fixed_range_v6='fd00:2::/120', gateway_v6='fd00:2::22', bridge_interface='eth0') - net = db.network_get_by_cidr(self.context, '10.2.0.0/24') + return db.network_get_by_cidr(self.context, '10.2.0.0/24') + + def test_create(self): + net = self._create_network() self.assertEqual(net['label'], 'Test') self.assertEqual(net['cidr'], '10.2.0.0/24') self.assertEqual(net['netmask'], '255.255.255.0') @@ -127,8 +130,7 @@ class NetworkCommandsTestCase(test.TestCase): self.assertEqual(net['bridge_interface'], 'eth0') def test_list(self): - self.test_create() - net = db.network_get_by_cidr(self.context, '10.2.0.0/24') + net = self._create_network() output = StringIO.StringIO() sys.stdout = output self.commands.list() @@ -158,7 +160,7 @@ class NetworkCommandsTestCase(test.TestCase): self.assertEqual(result, answer) def test_delete(self): - self.test_create() + net = self._create_network() self.commands.delete(fixed_range='10.2.0.0/24') net_exist = True try: @@ -168,8 +170,7 @@ class NetworkCommandsTestCase(test.TestCase): self.assertEqual(net_exist, False) def test_modify(self): - self.test_create() - net = db.network_get_by_cidr(self.context, '10.2.0.0/24') + net = self._create_network() db.network_disassociate(self.context, net['id']) net = db.network_get_by_cidr(self.context, '10.2.0.0/24') self.assertEqual(net['project_id'], None) @@ -183,7 +184,7 @@ class NetworkCommandsTestCase(test.TestCase): net = db.network_get_by_cidr(self.context, '10.2.0.0/24') self.assertEqual(net['project_id'], 'test_project') self.assertEqual(net['host'], 'test_host') - self.commands.modify('10.2.0.0/24', project='None', host='None') + self.commands.modify('10.2.0.0/24', dis_project=True, dis_host=True) net = db.network_get_by_cidr(self.context, '10.2.0.0/24') self.assertEqual(net['project_id'], None) self.assertEqual(net['host'], None) -- cgit From 7f1adb50cfab91a553f2d129b9b2eef1e5b2145b Mon Sep 17 00:00:00 2001 From: Christopher MacGown Date: Mon, 22 Aug 2011 22:17:51 -0700 Subject: Moved migration and fixed tests from upstream --- nova/tests/api/openstack/test_servers.py | 28 ++++++++++++++++------------ nova/tests/test_compute.py | 2 +- 2 files changed, 17 insertions(+), 13 deletions(-) (limited to 'nova/tests') diff --git a/nova/tests/api/openstack/test_servers.py b/nova/tests/api/openstack/test_servers.py index f854a500c..aec2ad947 100644 --- a/nova/tests/api/openstack/test_servers.py +++ b/nova/tests/api/openstack/test_servers.py @@ -1776,8 +1776,8 @@ class ServersTest(test.TestCase): self.config_drive = True self._setup_for_create_instance() - image_href = 'http://localhost/v1.1/images/2' - flavor_ref = 'http://localhost/v1.1/flavors/3' + image_href = 'http://localhost/v1.1/123/images/2' + flavor_ref = 'http://localhost/v1.1/123/flavors/3' body = { 'server': { 'name': 'config_drive_test', @@ -1792,12 +1792,13 @@ class ServersTest(test.TestCase): }, } - req = webob.Request.blank('/v1.1/servers') + req = webob.Request.blank('/v1.1/123/servers') req.method = 'POST' req.body = json.dumps(body) req.headers["content-type"] = "application/json" res = req.get_response(fakes.wsgi_app()) + print res self.assertEqual(res.status_int, 202) server = json.loads(res.body)['server'] self.assertEqual(1, server['id']) @@ -1807,8 +1808,8 @@ class ServersTest(test.TestCase): self.config_drive = 2 self._setup_for_create_instance() - image_href = 'http://localhost/v1.1/images/2' - flavor_ref = 'http://localhost/v1.1/flavors/3' + image_href = 'http://localhost/v1.1/123/images/2' + flavor_ref = 'http://localhost/v1.1/123/flavors/3' body = { 'server': { 'name': 'config_drive_test', @@ -1823,7 +1824,7 @@ class ServersTest(test.TestCase): }, } - req = webob.Request.blank('/v1.1/servers') + req = webob.Request.blank('/v1.1/123/servers') req.method = 'POST' req.body = json.dumps(body) req.headers["content-type"] = "application/json" @@ -1840,8 +1841,8 @@ class ServersTest(test.TestCase): self.config_drive = "asdf" self._setup_for_create_instance() - image_href = 'http://localhost/v1.1/images/2' - flavor_ref = 'http://localhost/v1.1/flavors/3' + image_href = 'http://localhost/v1.1/123/images/2' + flavor_ref = 'http://localhost/v1.1/123/flavors/3' body = { 'server': { 'name': 'config_drive_test', @@ -1856,7 +1857,7 @@ class ServersTest(test.TestCase): }, } - req = webob.Request.blank('/v1.1/servers') + req = webob.Request.blank('/v1.1/123/servers') req.method = 'POST' req.body = json.dumps(body) req.headers["content-type"] = "application/json" @@ -1867,8 +1868,8 @@ class ServersTest(test.TestCase): def test_create_instance_without_config_drive_v1_1(self): self._setup_for_create_instance() - image_href = 'http://localhost/v1.1/images/2' - flavor_ref = 'http://localhost/v1.1/flavors/3' + image_href = 'http://localhost/v1.1/123/images/2' + flavor_ref = 'http://localhost/v1.1/123/flavors/3' body = { 'server': { 'name': 'config_drive_test', @@ -1883,7 +1884,7 @@ class ServersTest(test.TestCase): }, } - req = webob.Request.blank('/v1.1/servers') + req = webob.Request.blank('/v1.1/123/servers') req.method = 'POST' req.body = json.dumps(body) req.headers["content-type"] = "application/json" @@ -3588,6 +3589,7 @@ class ServersViewBuilderV11Test(test.TestCase): "id": 1, "uuid": self.instance['uuid'], "name": "test_server", + "config_drive": None, "links": [ { "rel": "self", @@ -3747,6 +3749,7 @@ class ServersViewBuilderV11Test(test.TestCase): }, "addresses": {}, "metadata": {}, + "config_drive": None, "accessIPv4": "1.2.3.4", "accessIPv6": "", "links": [ @@ -3801,6 +3804,7 @@ class ServersViewBuilderV11Test(test.TestCase): }, "addresses": {}, "metadata": {}, + "config_drive": None, "accessIPv4": "", "accessIPv6": "fead::1234", "links": [ diff --git a/nova/tests/test_compute.py b/nova/tests/test_compute.py index b75e25dda..0523d73b6 100644 --- a/nova/tests/test_compute.py +++ b/nova/tests/test_compute.py @@ -163,7 +163,7 @@ class ComputeTestCase(test.TestCase): def test_create_instance_associates_config_drive(self): """Make sure create associates a config drive.""" - instance_id = self._create_instance(params={'config_drive': True,}) + instance_id = self._create_instance(params={'config_drive': True, }) try: self.compute.run_instance(self.context, instance_id) -- cgit From 5ae44219fd82d843cc5e715c318d9e80ab20b1a2 Mon Sep 17 00:00:00 2001 From: Nachi Ueno Date: Tue, 23 Aug 2011 08:07:25 -0700 Subject: Fixed typo and docstring and example class name --- nova/tests/example/__init__.py | 34 ---------------------------- nova/tests/example/example_a.py | 32 -------------------------- nova/tests/example/example_b.py | 32 -------------------------- nova/tests/monkey_patch_example/__init__.py | 34 ++++++++++++++++++++++++++++ nova/tests/monkey_patch_example/example_a.py | 32 ++++++++++++++++++++++++++ nova/tests/monkey_patch_example/example_b.py | 32 ++++++++++++++++++++++++++ nova/tests/test_utils.py | 25 ++++++++++---------- 7 files changed, 111 insertions(+), 110 deletions(-) delete mode 100644 nova/tests/example/__init__.py delete mode 100644 nova/tests/example/example_a.py delete mode 100644 nova/tests/example/example_b.py create mode 100644 nova/tests/monkey_patch_example/__init__.py create mode 100644 nova/tests/monkey_patch_example/example_a.py create mode 100644 nova/tests/monkey_patch_example/example_b.py (limited to 'nova/tests') diff --git a/nova/tests/example/__init__.py b/nova/tests/example/__init__.py deleted file mode 100644 index 1cfdf8a7e..000000000 --- a/nova/tests/example/__init__.py +++ /dev/null @@ -1,34 +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. -"""Example Module for testing utils.monkey_patch() -""" - - -CALLED_FUNCTION = [] - - -def example_decorator(name, function): - """ decorator for notify which is used from utils.monkey_patch() - Parameters: - - name - name of the function - function - object of the function - - - """ - def wrapped_func(*args, **kwarg): - CALLED_FUNCTION.append(name) - return function(*args, **kwarg) - return wrapped_func diff --git a/nova/tests/example/example_a.py b/nova/tests/example/example_a.py deleted file mode 100644 index 91bf048e4..000000000 --- a/nova/tests/example/example_a.py +++ /dev/null @@ -1,32 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2010 United States Government as represented by the -# Administrator of the National Aeronautics and Space Administration. -# 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. - -"""Example Module A for testing utils.monkey_patch() -""" - - -def example_function_a(): - return 'Example function' - - -class ExampleClassA(): - def example_method(self): - return 'Example method' - - def example_method_add(self, arg1, arg2): - return arg1 + arg2 diff --git a/nova/tests/example/example_b.py b/nova/tests/example/example_b.py deleted file mode 100644 index edd267c4f..000000000 --- a/nova/tests/example/example_b.py +++ /dev/null @@ -1,32 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2010 United States Government as represented by the -# Administrator of the National Aeronautics and Space Administration. -# 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. - -"""Example Module B for testing utils.monkey_patch() -""" - - -def example_function_b(): - return 'Example function' - - -class ExampleClassB(): - def example_method(self): - return 'Example method' - - def example_method_add(self, arg1, arg2): - return arg1 + arg2 diff --git a/nova/tests/monkey_patch_example/__init__.py b/nova/tests/monkey_patch_example/__init__.py new file mode 100644 index 000000000..1cfdf8a7e --- /dev/null +++ b/nova/tests/monkey_patch_example/__init__.py @@ -0,0 +1,34 @@ +# 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. +"""Example Module for testing utils.monkey_patch() +""" + + +CALLED_FUNCTION = [] + + +def example_decorator(name, function): + """ decorator for notify which is used from utils.monkey_patch() + Parameters: + + name - name of the function + function - object of the function + + + """ + def wrapped_func(*args, **kwarg): + CALLED_FUNCTION.append(name) + return function(*args, **kwarg) + return wrapped_func diff --git a/nova/tests/monkey_patch_example/example_a.py b/nova/tests/monkey_patch_example/example_a.py new file mode 100644 index 000000000..91bf048e4 --- /dev/null +++ b/nova/tests/monkey_patch_example/example_a.py @@ -0,0 +1,32 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright 2010 United States Government as represented by the +# Administrator of the National Aeronautics and Space Administration. +# 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. + +"""Example Module A for testing utils.monkey_patch() +""" + + +def example_function_a(): + return 'Example function' + + +class ExampleClassA(): + def example_method(self): + return 'Example method' + + def example_method_add(self, arg1, arg2): + return arg1 + arg2 diff --git a/nova/tests/monkey_patch_example/example_b.py b/nova/tests/monkey_patch_example/example_b.py new file mode 100644 index 000000000..edd267c4f --- /dev/null +++ b/nova/tests/monkey_patch_example/example_b.py @@ -0,0 +1,32 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright 2010 United States Government as represented by the +# Administrator of the National Aeronautics and Space Administration. +# 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. + +"""Example Module B for testing utils.monkey_patch() +""" + + +def example_function_b(): + return 'Example function' + + +class ExampleClassB(): + def example_method(self): + return 'Example method' + + def example_method_add(self, arg1, arg2): + return arg1 + arg2 diff --git a/nova/tests/test_utils.py b/nova/tests/test_utils.py index f80ffb179..1ba794a1a 100644 --- a/nova/tests/test_utils.py +++ b/nova/tests/test_utils.py @@ -401,15 +401,16 @@ class MonkeyPatchTestCase(test.TestCase): """Unit test for utils.monkey_patch().""" def setUp(self): super(MonkeyPatchTestCase, self).setUp() + self.example_package = 'nova.tests.monkey_patch_example.' self.flags( monkey_patch=True, - monkey_patch_modules=['nova.tests.example.example_a' + ':' - + 'nova.tests.example.example_decorator']) + monkey_patch_modules=[self.example_package + 'example_a' + ':' + + self.example_package + 'example_decorator']) def test_monkey_patch(self): utils.monkey_patch() - nova.tests.example.CALLED_FUNCTION = [] - from nova.tests.example import example_a, example_b + nova.tests.monkey_patch_example.CALLED_FUNCTION = [] + from nova.tests.monkey_patch_example import example_a, example_b self.assertEqual('Example function', example_a.example_function_a()) exampleA = example_a.ExampleClassA() @@ -423,18 +424,18 @@ class MonkeyPatchTestCase(test.TestCase): ret_b = exampleB.example_method_add(3, 5) self.assertEqual(ret_b, 8) - package_a = 'nova.tests.example.example_a.' + package_a = self.example_package + 'example_a.' self.assertTrue(package_a + 'example_function_a' - in nova.tests.example.CALLED_FUNCTION) + in nova.tests.monkey_patch_example.CALLED_FUNCTION) self.assertTrue(package_a + 'ExampleClassA.example_method' - in nova.tests.example.CALLED_FUNCTION) + in nova.tests.monkey_patch_example.CALLED_FUNCTION) self.assertTrue(package_a + 'ExampleClassA.example_method_add' - in nova.tests.example.CALLED_FUNCTION) - package_b = 'nova.tests.example.example_b.' + in nova.tests.monkey_patch_example.CALLED_FUNCTION) + package_b = self.example_package + 'example_b.' self.assertFalse(package_b + 'example_function_b' - in nova.tests.example.CALLED_FUNCTION) + in nova.tests.monkey_patch_example.CALLED_FUNCTION) self.assertFalse(package_b + 'ExampleClassB.example_method' - in nova.tests.example.CALLED_FUNCTION) + in nova.tests.monkey_patch_example.CALLED_FUNCTION) self.assertFalse(package_b + 'ExampleClassB.example_method_add' - in nova.tests.example.CALLED_FUNCTION) + in nova.tests.monkey_patch_example.CALLED_FUNCTION) -- cgit From 76f02277a3677d40a13a8b05a12f9d83053808c3 Mon Sep 17 00:00:00 2001 From: Nachi Ueno Date: Tue, 23 Aug 2011 09:46:49 -0700 Subject: Fixed some docstring Added default publisher_id flagw --- nova/tests/monkey_patch_example/__init__.py | 13 ++++++------- nova/tests/monkey_patch_example/example_a.py | 7 ++----- nova/tests/monkey_patch_example/example_b.py | 6 ++---- nova/tests/test_notifier.py | 3 +-- 4 files changed, 11 insertions(+), 18 deletions(-) (limited to 'nova/tests') diff --git a/nova/tests/monkey_patch_example/__init__.py b/nova/tests/monkey_patch_example/__init__.py index 1cfdf8a7e..25cf9ccfe 100644 --- a/nova/tests/monkey_patch_example/__init__.py +++ b/nova/tests/monkey_patch_example/__init__.py @@ -1,3 +1,5 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + # Copyright 2011 OpenStack LLC. # All Rights Reserved. # @@ -12,8 +14,7 @@ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. -"""Example Module for testing utils.monkey_patch() -""" +"""Example Module for testing utils.monkey_patch().""" CALLED_FUNCTION = [] @@ -21,12 +22,10 @@ CALLED_FUNCTION = [] def example_decorator(name, function): """ decorator for notify which is used from utils.monkey_patch() - Parameters: - - name - name of the function - function - object of the function - + :param name: name of the function + :param function: - object of the function + :returns: function -- decorated function """ def wrapped_func(*args, **kwarg): CALLED_FUNCTION.append(name) diff --git a/nova/tests/monkey_patch_example/example_a.py b/nova/tests/monkey_patch_example/example_a.py index 91bf048e4..21e79bcb0 100644 --- a/nova/tests/monkey_patch_example/example_a.py +++ b/nova/tests/monkey_patch_example/example_a.py @@ -1,7 +1,6 @@ # vim: tabstop=4 shiftwidth=4 softtabstop=4 -# Copyright 2010 United States Government as represented by the -# Administrator of the National Aeronautics and Space Administration. +# Copyright 2011 OpenStack LLC. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may @@ -15,9 +14,7 @@ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. - -"""Example Module A for testing utils.monkey_patch() -""" +"""Example Module A for testing utils.monkey_patch().""" def example_function_a(): diff --git a/nova/tests/monkey_patch_example/example_b.py b/nova/tests/monkey_patch_example/example_b.py index edd267c4f..9d8f6d339 100644 --- a/nova/tests/monkey_patch_example/example_b.py +++ b/nova/tests/monkey_patch_example/example_b.py @@ -1,7 +1,6 @@ # vim: tabstop=4 shiftwidth=4 softtabstop=4 -# Copyright 2010 United States Government as represented by the -# Administrator of the National Aeronautics and Space Administration. +# Copyright 2011 OpenStack LLC. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may @@ -16,8 +15,7 @@ # License for the specific language governing permissions and limitations # under the License. -"""Example Module B for testing utils.monkey_patch() -""" +"""Example Module B for testing utils.monkey_patch().""" def example_function_b(): diff --git a/nova/tests/test_notifier.py b/nova/tests/test_notifier.py index ab5dfb692..7de3a4a99 100644 --- a/nova/tests/test_notifier.py +++ b/nova/tests/test_notifier.py @@ -141,8 +141,7 @@ class NotifierTestCase(test.TestCase): def example_api(arg1, arg2): return arg1 + arg2 - example_api =\ - nova.notifier.api.notify_decorator( + example_api = nova.notifier.api.notify_decorator( 'example_api', example_api) -- cgit From 295bcc8ef70d767bf1539defe1a79a67bdf555ff Mon Sep 17 00:00:00 2001 From: Brian Waldon Date: Tue, 23 Aug 2011 13:44:39 -0400 Subject: updating tests --- nova/tests/api/openstack/test_servers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'nova/tests') diff --git a/nova/tests/api/openstack/test_servers.py b/nova/tests/api/openstack/test_servers.py index cec6eecc0..e5c1f2c34 100644 --- a/nova/tests/api/openstack/test_servers.py +++ b/nova/tests/api/openstack/test_servers.py @@ -785,7 +785,7 @@ class ServersTest(test.TestCase): new_return_server = return_server_with_attributes(interfaces=ifaces) self.stubs.Set(nova.db.api, 'instance_get', new_return_server) - req = webob.Request.blank('/v1.1/servers/1') + req = webob.Request.blank('/v1.1/fake/servers/1') res = req.get_response(fakes.wsgi_app()) self.assertEqual(res.status_int, 200) res_dict = json.loads(res.body) -- cgit From b75f90e0d83e50b6699a8e6efc60cc97a00c0678 Mon Sep 17 00:00:00 2001 From: Tim Simpson Date: Tue, 23 Aug 2011 13:12:54 -0500 Subject: Switched list_notifier to log an exception each time notify is called, for each notification driver that failed to import. --- nova/tests/notifier/test_list_notifier.py | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) (limited to 'nova/tests') diff --git a/nova/tests/notifier/test_list_notifier.py b/nova/tests/notifier/test_list_notifier.py index bab1a0ab8..ad2b039c5 100644 --- a/nova/tests/notifier/test_list_notifier.py +++ b/nova/tests/notifier/test_list_notifier.py @@ -48,11 +48,6 @@ class NotifierListTestCase(test.TestCase): def mock_notify2(cls, *args): raise RuntimeError("Bad notifier.") self.stubs.Set(nova.notifier.log_notifier, 'notify', mock_notify2) - # mock sys.exit so we don't actually kill the program during our tests. - self.sys_exit_code = 0 - def mock_sys_exit(code): - self.sys_exit_code += code - self.stubs.Set(sys, 'exit', mock_sys_exit) def tearDown(self): self.stubs.UnsetAll() @@ -67,7 +62,6 @@ class NotifierListTestCase(test.TestCase): nova.notifier.api.WARN, dict(a=3)) self.assertEqual(self.notify_count, 2) self.assertEqual(self.exception_count, 0) - self.assertEqual(self.sys_exit_code, 0) def test_send_notifications_with_errors(self): @@ -77,7 +71,6 @@ class NotifierListTestCase(test.TestCase): notify('publisher_id', 'event_type', nova.notifier.api.WARN, dict(a=3)) self.assertEqual(self.notify_count, 1) self.assertEqual(self.exception_count, 1) - self.assertEqual(self.sys_exit_code, 0) def test_when_driver_fails_to_import(self): self.flags(notification_driver='nova.notifier.list_notifier', @@ -85,6 +78,5 @@ class NotifierListTestCase(test.TestCase): 'nova.notifier.logo_notifier', 'fdsjgsdfhjkhgsfkj']) notify('publisher_id', 'event_type', nova.notifier.api.WARN, dict(a=3)) - self.assertEqual(self.exception_count, 0) + self.assertEqual(self.exception_count, 2) self.assertEqual(self.notify_count, 1) - self.assertEqual(self.sys_exit_code, 2) -- cgit From 8c30e3e4b1847e6f44790fc4b614fe56de84cbfb Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya Date: Tue, 23 Aug 2011 13:44:21 -0700 Subject: Forgot to set the flag for the test --- nova/tests/test_auth.py | 1 + 1 file changed, 1 insertion(+) (limited to 'nova/tests') diff --git a/nova/tests/test_auth.py b/nova/tests/test_auth.py index 4561eb7f2..1b3166af7 100644 --- a/nova/tests/test_auth.py +++ b/nova/tests/test_auth.py @@ -147,6 +147,7 @@ class _AuthManagerBaseTestCase(test.TestCase): '/services/Cloud')) def test_can_get_credentials(self): + self.flags(use_deprecated_auth=True) st = {'access': 'access', 'secret': 'secret'} with user_and_project_generator(self.manager, user_state=st) as (u, p): credentials = self.manager.get_environment_rc(u, p) -- cgit From cbf8b3b36dde763164fcfd06e1d3c5732f57311d Mon Sep 17 00:00:00 2001 From: Tim Simpson Date: Tue, 23 Aug 2011 15:50:39 -0500 Subject: Fixed some pep8 and pylint issues. --- nova/tests/notifier/test_list_notifier.py | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'nova/tests') diff --git a/nova/tests/notifier/test_list_notifier.py b/nova/tests/notifier/test_list_notifier.py index ad2b039c5..b77720759 100644 --- a/nova/tests/notifier/test_list_notifier.py +++ b/nova/tests/notifier/test_list_notifier.py @@ -34,19 +34,25 @@ class NotifierListTestCase(test.TestCase): list_notifier._reset_drivers() self.stubs = stubout.StubOutForTesting() # Mock log to add one to exception_count when log.exception is called + def mock_exception(cls, *args): self.exception_count += 1 + self.exception_count = 0 list_notifier_log = logging.getLogger('nova.notifier.list_notifier') self.stubs.Set(list_notifier_log, "exception", mock_exception) # Mock no_op notifier to add one to notify_count when called. + def mock_notify(cls, *args): self.notify_count += 1 + self.notify_count = 0 self.stubs.Set(nova.notifier.no_op_notifier, 'notify', mock_notify) # Mock log_notifier to raise RuntimeError when called. + def mock_notify2(cls, *args): raise RuntimeError("Bad notifier.") + self.stubs.Set(nova.notifier.log_notifier, 'notify', mock_notify2) def tearDown(self): -- cgit From 8cd7dcca1ccac0347289d633ebd10567d6cba4c7 Mon Sep 17 00:00:00 2001 From: Hisaharu Ishii Date: Tue, 23 Aug 2011 15:06:24 -0700 Subject: Stub out the DB in unit test. Fix 'nova-manage network modify' to use db.network_update() --- nova/tests/test_nova_manage.py | 162 +++++++++++++++++++++++++++-------------- 1 file changed, 107 insertions(+), 55 deletions(-) (limited to 'nova/tests') diff --git a/nova/tests/test_nova_manage.py b/nova/tests/test_nova_manage.py index 6b34a90f9..03ee1140d 100644 --- a/nova/tests/test_nova_manage.py +++ b/nova/tests/test_nova_manage.py @@ -75,17 +75,59 @@ class FixedIpCommandsTestCase(test.TestCase): class NetworkCommandsTestCase(test.TestCase): def setUp(self): super(NetworkCommandsTestCase, self).setUp() + self.stubs = stubout.StubOutForTesting() self.commands = nova_manage.NetworkCommands() self.context = context.get_admin_context() - nets = db.network_get_all(self.context) - for net in nets: - db.network_delete_safe(self.context, net['id']) + self.net = {'id': 0, + 'label': 'fake', + 'injected': False, + 'cidr': '192.168.0.0/24', + 'cidr_v6': 'dead:beef::/64', + 'multi_host': False, + 'gateway_v6': 'dead:beef::1', + 'netmask_v6': '64', + 'netmask': '255.255.255.0', + 'bridge': 'fa0', + 'bridge_interface': 'fake_fa0', + 'gateway': '192.168.0.1', + 'broadcast': '192.168.0.255', + 'dns1': '8.8.8.8', + 'dns2': '8.8.4.4', + 'vlan': 200, + 'vpn_public_address': '10.0.0.2', + 'vpn_public_port': '2222', + 'vpn_private_address': '192.168.0.2', + 'dhcp_start': '192.168.0.3', + 'project_id': 'fake_project', + 'host': 'fake_host', + 'uuid': 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa'} + def tearDown(self): super(NetworkCommandsTestCase, self).tearDown() + self.stubs.UnsetAll() + + def test_create(self): - def _create_network(self): + def fake_create_networks(obj, context, **kwargs): + self.assertTrue(context.to_dict()['is_admin']) + self.assertEqual(kwargs['label'], 'Test') + self.assertEqual(kwargs['cidr'], '10.2.0.0/24') + self.assertEqual(kwargs['multi_host'], False) + self.assertEqual(kwargs['num_networks'], 1) + self.assertEqual(kwargs['network_size'], 256) + self.assertEqual(kwargs['vlan_start'], 200) + self.assertEqual(kwargs['vpn_start'], 2000) + self.assertEqual(kwargs['cidr_v6'], 'fd00:2::/120') + self.assertEqual(kwargs['gateway_v6'], 'fd00:2::22') + self.assertEqual(kwargs['bridge'], 'br200') + self.assertEqual(kwargs['bridge_interface'], 'eth0') + self.assertEqual(kwargs['dns1'], '8.8.8.8') + self.assertEqual(kwargs['dns2'], '8.8.4.4') FLAGS.network_manager = 'nova.network.manager.VlanManager' + from nova.network import manager as net_manager + self.stubs.Set(net_manager.VlanManager, 'create_networks', + fake_create_networks) self.commands.create( label='Test', fixed_range_v4='10.2.0.0/24', @@ -96,24 +138,16 @@ class NetworkCommandsTestCase(test.TestCase): vpn_start=2000, fixed_range_v6='fd00:2::/120', gateway_v6='fd00:2::22', - bridge_interface='eth0') - return db.network_get_by_cidr(self.context, '10.2.0.0/24') - - def test_create(self): - net = self._create_network() - self.assertEqual(net['label'], 'Test') - self.assertEqual(net['cidr'], '10.2.0.0/24') - self.assertEqual(net['netmask'], '255.255.255.0') - self.assertEqual(net['multi_host'], False) - self.assertEqual(net['vlan'], 200) - self.assertEqual(net['bridge'], 'br200') - self.assertEqual(net['vpn_public_port'], 2000) - self.assertEqual(net['cidr_v6'], 'fd00:2::/120') - self.assertEqual(net['gateway_v6'], 'fd00:2::22') - self.assertEqual(net['bridge_interface'], 'eth0') + bridge='br200', + bridge_interface='eth0', + dns1='8.8.8.8', + dns2='8.8.4.4') def test_list(self): - net = self._create_network() + + def fake_network_get_all(context): + return [db_fakes.FakeModel(self.net)] + self.stubs.Set(db, 'network_get_all', fake_network_get_all) output = StringIO.StringIO() sys.stdout = output self.commands.list() @@ -129,45 +163,63 @@ class NetworkCommandsTestCase(test.TestCase): _('VlanID'), _('project'), _("uuid")) - body = _fmt % ( - net['id'], - '10.2.0.0/24', - 'fd00:2::/120', - '10.2.0.3', - 'None', - 'None', - '200', - 'None', - net['uuid'],) + body = _fmt % (self.net['id'], + self.net['cidr'], + self.net['cidr_v6'], + self.net['dhcp_start'], + self.net['dns1'], + self.net['dns2'], + self.net['vlan'], + self.net['project_id'], + self.net['uuid']) answer = '%s\n%s\n' % (head, body) self.assertEqual(result, answer) def test_delete(self): - net = self._create_network() - self.commands.delete(fixed_range='10.2.0.0/24') - net_exist = True - try: - net = db.network_get_by_cidr(self.context, '10.2.0.0/24') - except exception.NetworkNotFoundForCidr, e: - net_exist = False - self.assertEqual(net_exist, False) + net_dis = self.net + net_dis['project_id'] = None + net_dis['host'] = None + + def fake_network_get_by_cidr(context, cidr): + self.assertTrue(context.to_dict()['is_admin']) + self.assertEqual(cidr, net_dis['cidr']) + return db_fakes.FakeModel(net_dis) + self.stubs.Set(db, 'network_get_by_cidr', fake_network_get_by_cidr) + + def fake_network_delete_safe(context, network_id): + self.assertTrue(context.to_dict()['is_admin']) + self.assertEqual(network_id, net_dis['id']) + self.stubs.Set(db, 'network_delete_safe', fake_network_delete_safe) + self.commands.delete(fixed_range=net_dis['cidr']) def test_modify(self): - net = self._create_network() - db.network_disassociate(self.context, net['id']) - net = db.network_get_by_cidr(self.context, '10.2.0.0/24') - self.assertEqual(net['project_id'], None) - self.assertEqual(net['host'], None) - self.commands.modify('10.2.0.0/24', project='test_project', + + def fake_network_get_by_cidr(context, cidr): + self.assertTrue(context.to_dict()['is_admin']) + self.assertEqual(cidr, self.net['cidr']) + return db_fakes.FakeModel(self.net) + self.stubs.Set(db, 'network_get_by_cidr', fake_network_get_by_cidr) + + def fake_network_update(context, network_id, values): + self.assertTrue(context.to_dict()['is_admin']) + self.assertEqual(network_id, self.net['id']) + self.assertEqual(values, {'project_id': 'test_project', + 'host': 'test_host'}) + self.stubs.Set(db, 'network_update', fake_network_update) + self.commands.modify(self.net['cidr'], project='test_project', host='test_host') - net = db.network_get_by_cidr(self.context, '10.2.0.0/24') - self.assertEqual(net['project_id'], 'test_project') - self.assertEqual(net['host'], 'test_host') - self.commands.modify('10.2.0.0/24') - net = db.network_get_by_cidr(self.context, '10.2.0.0/24') - self.assertEqual(net['project_id'], 'test_project') - self.assertEqual(net['host'], 'test_host') - self.commands.modify('10.2.0.0/24', dis_project=True, dis_host=True) - net = db.network_get_by_cidr(self.context, '10.2.0.0/24') - self.assertEqual(net['project_id'], None) - self.assertEqual(net['host'], None) + + def fake_network_update(context, network_id, values): + self.assertTrue(context.to_dict()['is_admin']) + self.assertEqual(network_id, self.net['id']) + self.assertEqual(values, {}) + self.stubs.Set(db, 'network_update', fake_network_update) + self.commands.modify(self.net['cidr']) + + def fake_network_update(context, network_id, values): + self.assertTrue(context.to_dict()['is_admin']) + self.assertEqual(network_id, self.net['id']) + self.assertEqual(values, {'project_id': None, + 'host': None}) + self.stubs.Set(db, 'network_update', fake_network_update) + self.commands.modify(self.net['cidr'], dis_project=True, dis_host=True) -- cgit From ddc7d9470674a4d7300d15e5c6fa54b784b6a36f Mon Sep 17 00:00:00 2001 From: "vladimir.p" Date: Tue, 23 Aug 2011 15:18:50 -0700 Subject: added volume_types APIs --- nova/tests/test_volume_types.py | 156 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 156 insertions(+) create mode 100644 nova/tests/test_volume_types.py (limited to 'nova/tests') diff --git a/nova/tests/test_volume_types.py b/nova/tests/test_volume_types.py new file mode 100644 index 000000000..3d906a5fd --- /dev/null +++ b/nova/tests/test_volume_types.py @@ -0,0 +1,156 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright (c) 2011 Zadara Storage Inc. +# Copyright (c) 2011 OpenStack LLC. +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +""" +Unit Tests for volume types code +""" +import time + +from nova import context +from nova import db +from nova import exception +from nova import flags +from nova import log as logging +from nova import test +from nova import utils +from nova.volume import volume_types +from nova.db.sqlalchemy.session import get_session +from nova.db.sqlalchemy import models + +FLAGS = flags.FLAGS +LOG = logging.getLogger('nova.tests.test_volume_types') + + +class VolumeTypeTestCase(test.TestCase): + """Test cases for volume type code""" + def setUp(self): + super(VolumeTypeTestCase, self).setUp() + + self.ctxt = context.get_admin_context() + self.vol_type1_name = str(int(time.time())) + self.vol_type1_specs = dict( + type="physical drive", + drive_type="SAS", + size="300", + rpm="7200", + visible="True") + self.vol_type1 = dict(name=self.vol_type1_name, + extra_specs=self.vol_type1_specs) + + def test_volume_type_create_then_destroy(self): + """Ensure volume types can be created and deleted""" + prev_all_vtypes = volume_types.get_all_types(self.ctxt) + + volume_types.create(self.ctxt, + self.vol_type1_name, + self.vol_type1_specs) + new = volume_types.get_volume_type_by_name(self.ctxt, + self.vol_type1_name) + + LOG.info(_("Given data: %s"), self.vol_type1_specs) + LOG.info(_("Result data: %s"), new) + + for k, v in self.vol_type1_specs.iteritems(): + self.assertEqual(v, new['extra_specs'][k], + 'one of fields doesnt match') + + new_all_vtypes = volume_types.get_all_types(self.ctxt) + self.assertEqual(len(prev_all_vtypes) + 1, + len(new_all_vtypes), + 'drive type was not created') + + volume_types.destroy(self.ctxt, self.vol_type1_name) + new_all_vtypes = volume_types.get_all_types(self.ctxt) + self.assertEqual(prev_all_vtypes, + new_all_vtypes, + 'drive type was not deleted') + + def test_volume_type_create_then_purge(self): + """Ensure volume types can be created and deleted""" + prev_all_vtypes = volume_types.get_all_types(self.ctxt, inactive=1) + + volume_types.create(self.ctxt, + self.vol_type1_name, + self.vol_type1_specs) + new = volume_types.get_volume_type_by_name(self.ctxt, + self.vol_type1_name) + + for k, v in self.vol_type1_specs.iteritems(): + self.assertEqual(v, new['extra_specs'][k], + 'one of fields doesnt match') + + new_all_vtypes = volume_types.get_all_types(self.ctxt, inactive=1) + self.assertEqual(len(prev_all_vtypes) + 1, + len(new_all_vtypes), + 'drive type was not created') + + volume_types.destroy(self.ctxt, self.vol_type1_name) + new_all_vtypes2 = volume_types.get_all_types(self.ctxt, inactive=1) + self.assertEqual(len(new_all_vtypes), + len(new_all_vtypes2), + 'drive type was incorrectly deleted') + + volume_types.purge(self.ctxt, self.vol_type1_name) + new_all_vtypes2 = volume_types.get_all_types(self.ctxt, inactive=1) + self.assertEqual(len(new_all_vtypes) - 1, + len(new_all_vtypes2), + 'drive type was not purged') + + def test_get_all_volume_types(self): + """Ensures that all volume types can be retrieved""" + session = get_session() + total_volume_types = session.query(models.VolumeTypes).\ + count() + vol_types = volume_types.get_all_types(self.ctxt) + self.assertEqual(total_volume_types, len(vol_types)) + + def test_non_existant_inst_type_shouldnt_delete(self): + """Ensures that volume type creation fails with invalid args""" + self.assertRaises(exception.ApiError, + volume_types.destroy, self.ctxt, "sfsfsdfdfs") + + def test_repeated_vol_types_should_raise_api_error(self): + """Ensures that volume duplicates raises ApiError""" + new_name = self.vol_type1_name + "dup" + volume_types.create(self.ctxt, new_name) + volume_types.destroy(self.ctxt, new_name) + self.assertRaises( + exception.ApiError, + volume_types.create, self.ctxt, new_name) + + def test_invalid_volume_types_params(self): + """Ensures that volume type creation fails with invalid args""" + self.assertRaises(exception.InvalidVolumeType, + volume_types.destroy, self.ctxt, None) + self.assertRaises(exception.InvalidVolumeType, + volume_types.purge, self.ctxt, None) + self.assertRaises(exception.InvalidVolumeType, + volume_types.get_volume_type, self.ctxt, None) + self.assertRaises(exception.InvalidVolumeType, + volume_types.get_volume_type_by_name, + self.ctxt, None) + + def test_volume_type_get_by_id_and_name(self): + """Ensure volume types get returns same entry""" + volume_types.create(self.ctxt, + self.vol_type1_name, + self.vol_type1_specs) + new = volume_types.get_volume_type_by_name(self.ctxt, + self.vol_type1_name) + + new2 = volume_types.get_volume_type(self.ctxt, new['id']) + self.assertEqual(new, new2) + + -- cgit From 9fbdfa5061dc17e43fc8a5200415e0dffc55b911 Mon Sep 17 00:00:00 2001 From: Hisaharu Ishii Date: Tue, 23 Aug 2011 15:40:28 -0700 Subject: Fix pep8 --- nova/tests/test_nova_manage.py | 1 - 1 file changed, 1 deletion(-) (limited to 'nova/tests') diff --git a/nova/tests/test_nova_manage.py b/nova/tests/test_nova_manage.py index 097d2dbf5..ca4f4c894 100644 --- a/nova/tests/test_nova_manage.py +++ b/nova/tests/test_nova_manage.py @@ -112,7 +112,6 @@ class NetworkCommandsTestCase(test.TestCase): 'host': 'fake_host', 'uuid': 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa'} - def tearDown(self): super(NetworkCommandsTestCase, self).tearDown() self.stubs.UnsetAll() -- cgit From 309a264db6c952081f2e85db21efc719596240a6 Mon Sep 17 00:00:00 2001 From: Brian Waldon Date: Tue, 23 Aug 2011 20:59:24 -0400 Subject: updating tests --- nova/tests/api/openstack/test_server_actions.py | 122 +++++++++++++++++------- 1 file changed, 87 insertions(+), 35 deletions(-) (limited to 'nova/tests') diff --git a/nova/tests/api/openstack/test_server_actions.py b/nova/tests/api/openstack/test_server_actions.py index bdd6824e7..769de4b34 100644 --- a/nova/tests/api/openstack/test_server_actions.py +++ b/nova/tests/api/openstack/test_server_actions.py @@ -1,4 +1,5 @@ import base64 +import datetime import json import stubout @@ -8,8 +9,11 @@ from nova import context from nova import utils from nova import flags from nova.api.openstack import create_instance_helper +from nova.compute import instance_types from nova.compute import power_state import nova.db.api +from nova.db.sqlalchemy.models import Instance +from nova.db.sqlalchemy.models import InstanceMetadata from nova import test from nova.tests.api.openstack import common from nova.tests.api.openstack import fakes @@ -19,61 +23,58 @@ FLAGS = flags.FLAGS def return_server_by_id(context, id): - return _get_instance() + return stub_instance(id) def instance_update(context, instance_id, kwargs): - return _get_instance() + return stub_instance(instance_id) -def return_server_with_power_state(power_state): +def return_server_with_attributes(**kwargs): def _return_server(context, id): - instance = _get_instance() - instance['state'] = power_state - return instance + return stub_instance(id, **kwargs) return _return_server +def return_server_with_power_state(power_state): + return return_server_with_attributes(power_state=power_state) + + def return_server_with_uuid_and_power_state(power_state): - def _return_server(context, id): - return return_server_with_power_state(power_state) - return _return_server + return return_server_with_power_state(power_state) -class MockSetAdminPassword(object): - def __init__(self): - self.instance_id = None - self.password = None +def stub_instance(id, power_state=0, metadata=None, + image_ref="10", flavor_id="1", name=None): - def __call__(self, context, instance_id, password): - self.instance_id = instance_id - self.password = password + if metadata is not None: + metadata_items = [{'key': k, 'value': v} for k, v in metadata.items()] + else: + metadata_items = [{'key': 'seq', 'value':id}] + inst_type = instance_types.get_instance_type_by_flavor_id(int(flavor_id)) -def _get_instance(): instance = { - "id": 1, - "created_at": "2010-10-10 12:00:00", - "updated_at": "2010-11-11 11:00:00", + "id": int(id), + "created_at": datetime.datetime(2010, 10, 10, 12, 0, 0), + "updated_at": datetime.datetime(2010, 11, 11, 11, 0, 0), "admin_pass": "", - "user_id": "", - "project_id": "", - "image_ref": "5", + "user_id": "fake", + "project_id": "fake", + "image_ref": image_ref, "kernel_id": "", "ramdisk_id": "", "launch_index": 0, "key_name": "", "key_data": "", - "state": 0, + "state": power_state, "state_description": "", "memory_mb": 0, "vcpus": 0, "local_gb": 0, "hostname": "", "host": "", - "instance_type": { - "flavorid": 1, - }, + "instance_type": dict(inst_type), "user_data": "", "reservation_id": "", "mac_address": "", @@ -81,17 +82,32 @@ def _get_instance(): "launched_at": utils.utcnow(), "terminated_at": utils.utcnow(), "availability_zone": "", - "display_name": "test_server", + "display_name": name or "server%s" % id, "display_description": "", "locked": False, - "metadata": [], - #"address": , - #"floating_ips": [{"address":ip} for ip in public_addresses]} - "uuid": "deadbeef-feed-edee-beef-d0ea7beefedd"} + "metadata": metadata_items, + "access_ip_v4": "", + "access_ip_v6": "", + "uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa", + "virtual_interfaces": []} + + instance["fixed_ips"] = { + "address": '192.168.0.1', + "floating_ips": []} return instance +class MockSetAdminPassword(object): + def __init__(self): + self.instance_id = None + self.password = None + + def __call__(self, context, instance_id, password): + self.instance_id = instance_id + self.password = password + + class ServerActionsTest(test.TestCase): def setUp(self): @@ -598,6 +614,9 @@ class ServerActionsTestV11(test.TestCase): self.assertEqual(res.status_int, 400) def test_server_rebuild_accepted_minimum(self): + new_return_server = return_server_with_attributes(image_ref='2') + self.stubs.Set(nova.db.api, 'instance_get', new_return_server) + body = { "rebuild": { "imageRef": "http://localhost/images/2", @@ -611,6 +630,9 @@ class ServerActionsTestV11(test.TestCase): res = req.get_response(fakes.wsgi_app()) self.assertEqual(res.status_int, 202) + body = json.loads(res.body) + self.assertEqual(body['server']['image']['id'], '2') + self.assertEqual(len(body['server']['adminPass']), 16) def test_server_rebuild_rejected_when_building(self): body = { @@ -634,12 +656,15 @@ class ServerActionsTestV11(test.TestCase): self.assertEqual(res.status_int, 409) def test_server_rebuild_accepted_with_metadata(self): + metadata = {'new': 'metadata'} + + new_return_server = return_server_with_attributes(metadata=metadata) + self.stubs.Set(nova.db.api, 'instance_get', new_return_server) + body = { "rebuild": { "imageRef": "http://localhost/images/2", - "metadata": { - "new": "metadata", - }, + "metadata": metadata, }, } @@ -649,7 +674,10 @@ class ServerActionsTestV11(test.TestCase): req.body = json.dumps(body) res = req.get_response(fakes.wsgi_app()) + print res.body self.assertEqual(res.status_int, 202) + body = json.loads(res.body) + self.assertEqual(body['server']['metadata'], metadata) def test_server_rebuild_accepted_with_bad_metadata(self): body = { @@ -719,6 +747,30 @@ class ServerActionsTestV11(test.TestCase): res = req.get_response(fakes.wsgi_app()) self.assertEqual(res.status_int, 202) + body = json.loads(res.body) + self.assertTrue('personality' not in body['server']) + + def test_server_rebuild_admin_pass(self): + new_return_server = return_server_with_attributes(image_ref='2') + self.stubs.Set(nova.db.api, 'instance_get', new_return_server) + + body = { + "rebuild": { + "imageRef": "http://localhost/images/2", + "adminPass": "asdf", + }, + } + + req = webob.Request.blank('/v1.1/fake/servers/1/action') + req.method = 'POST' + req.content_type = 'application/json' + req.body = json.dumps(body) + + res = req.get_response(fakes.wsgi_app()) + self.assertEqual(res.status_int, 202) + body = json.loads(res.body) + self.assertEqual(body['server']['image']['id'], '2') + self.assertEqual(body['server']['adminPass'], 'asdf') def test_resize_server(self): -- cgit From 29940dd27f3a40a4ad54bc2f7a4cea5ac2226b83 Mon Sep 17 00:00:00 2001 From: "vladimir.p" Date: Tue, 23 Aug 2011 20:22:27 -0700 Subject: added volume metadata APIs (OS & volume layers), search volume by metadata & other --- nova/tests/integrated/test_volumes.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'nova/tests') diff --git a/nova/tests/integrated/test_volumes.py b/nova/tests/integrated/test_volumes.py index d3e936462..86165944f 100644 --- a/nova/tests/integrated/test_volumes.py +++ b/nova/tests/integrated/test_volumes.py @@ -285,6 +285,22 @@ class VolumesTest(integrated_helpers._IntegratedTestBase): self.assertEquals(undisco_move['mountpoint'], device) self.assertEquals(undisco_move['instance_id'], server_id) + def test_create_volume_with_metadata(self): + """Creates and deletes a volume.""" + + # Create volume + metadata = {'key1': 'value1', + 'key2': 'value2'} + created_volume = self.api.post_volume({'volume': {'size': 1, + 'metadata': metadata}}) + LOG.debug("created_volume: %s" % created_volume) + self.assertTrue(created_volume['id']) + created_volume_id = created_volume['id'] + + # Check it's there and metadata present + found_volume = self.api.get_volume(created_volume_id) + self.assertEqual(created_volume_id, found_volume['id']) + self.assertEqual(metadata, found_volume['metadata']) if __name__ == "__main__": unittest.main() -- cgit From 8b6f6145a4a99f8b60e77cb8758ffcc2c0591ebd Mon Sep 17 00:00:00 2001 From: Brian Waldon Date: Tue, 23 Aug 2011 23:27:36 -0400 Subject: removing print statement --- nova/tests/api/openstack/test_server_actions.py | 1 - 1 file changed, 1 deletion(-) (limited to 'nova/tests') diff --git a/nova/tests/api/openstack/test_server_actions.py b/nova/tests/api/openstack/test_server_actions.py index 769de4b34..aeb132e87 100644 --- a/nova/tests/api/openstack/test_server_actions.py +++ b/nova/tests/api/openstack/test_server_actions.py @@ -674,7 +674,6 @@ class ServerActionsTestV11(test.TestCase): req.body = json.dumps(body) res = req.get_response(fakes.wsgi_app()) - print res.body self.assertEqual(res.status_int, 202) body = json.loads(res.body) self.assertEqual(body['server']['metadata'], metadata) -- cgit From 8191cd38b2030a9d8816bcc21bd0cbc0119a7d91 Mon Sep 17 00:00:00 2001 From: Thierry Carrez Date: Wed, 24 Aug 2011 14:42:30 +0200 Subject: Thou shalt not use underscores in hostnames --- nova/tests/test_compute.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'nova/tests') diff --git a/nova/tests/test_compute.py b/nova/tests/test_compute.py index 0523d73b6..6659b81eb 100644 --- a/nova/tests/test_compute.py +++ b/nova/tests/test_compute.py @@ -175,8 +175,9 @@ class ComputeTestCase(test.TestCase): db.instance_destroy(self.context, instance_id) def test_default_hostname_generator(self): - cases = [(None, 'server_1'), ('Hello, Server!', 'hello_server'), - ('<}\x1fh\x10e\x08l\x02l\x05o\x12!{>', 'hello')] + cases = [(None, 'server-1'), ('Hello, Server!', 'hello-server'), + ('<}\x1fh\x10e\x08l\x02l\x05o\x12!{>', 'hello'), + ('hello_server', 'hello-server')] for display_name, hostname in cases: ref = self.compute_api.create(self.context, instance_types.get_default_instance_type(), None, -- cgit From bc235682305c3eb70eb80f1dddc15d86359a9ca3 Mon Sep 17 00:00:00 2001 From: Brian Waldon Date: Wed, 24 Aug 2011 09:38:43 -0400 Subject: pep8 --- nova/tests/api/openstack/test_server_actions.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'nova/tests') diff --git a/nova/tests/api/openstack/test_server_actions.py b/nova/tests/api/openstack/test_server_actions.py index aeb132e87..926420407 100644 --- a/nova/tests/api/openstack/test_server_actions.py +++ b/nova/tests/api/openstack/test_server_actions.py @@ -48,9 +48,9 @@ def stub_instance(id, power_state=0, metadata=None, image_ref="10", flavor_id="1", name=None): if metadata is not None: - metadata_items = [{'key': k, 'value': v} for k, v in metadata.items()] + metadata_items = [{'key':k, 'value':v} for k, v in metadata.items()] else: - metadata_items = [{'key': 'seq', 'value':id}] + metadata_items = [{'key':'seq', 'value':id}] inst_type = instance_types.get_instance_type_by_flavor_id(int(flavor_id)) -- cgit From e5e95e1bfb6b1569b7e30a7066a0cd9c6ebff2c7 Mon Sep 17 00:00:00 2001 From: Brian Waldon Date: Wed, 24 Aug 2011 10:06:20 -0400 Subject: removing extraneous imports --- nova/tests/api/openstack/test_server_actions.py | 2 -- 1 file changed, 2 deletions(-) (limited to 'nova/tests') diff --git a/nova/tests/api/openstack/test_server_actions.py b/nova/tests/api/openstack/test_server_actions.py index 926420407..057277887 100644 --- a/nova/tests/api/openstack/test_server_actions.py +++ b/nova/tests/api/openstack/test_server_actions.py @@ -12,8 +12,6 @@ from nova.api.openstack import create_instance_helper from nova.compute import instance_types from nova.compute import power_state import nova.db.api -from nova.db.sqlalchemy.models import Instance -from nova.db.sqlalchemy.models import InstanceMetadata from nova import test from nova.tests.api.openstack import common from nova.tests.api.openstack import fakes -- cgit From 3d4d3d7f422c7327346b5731ad3c620f279411f2 Mon Sep 17 00:00:00 2001 From: Brian Waldon Date: Wed, 24 Aug 2011 10:37:59 -0400 Subject: adding xml serialization and handling instance not found --- nova/tests/api/openstack/test_server_actions.py | 20 ++++ nova/tests/api/openstack/test_servers.py | 135 ++++++++++++++++++++++++ 2 files changed, 155 insertions(+) (limited to 'nova/tests') diff --git a/nova/tests/api/openstack/test_server_actions.py b/nova/tests/api/openstack/test_server_actions.py index 057277887..9a664f44d 100644 --- a/nova/tests/api/openstack/test_server_actions.py +++ b/nova/tests/api/openstack/test_server_actions.py @@ -7,6 +7,7 @@ import webob from nova import context from nova import utils +from nova import exception from nova import flags from nova.api.openstack import create_instance_helper from nova.compute import instance_types @@ -769,6 +770,25 @@ class ServerActionsTestV11(test.TestCase): self.assertEqual(body['server']['image']['id'], '2') self.assertEqual(body['server']['adminPass'], 'asdf') + def test_server_rebuild_server_not_found(self): + def server_not_found(self, instance_id): + raise exception.InstanceNotFound(instance_id=instance_id) + self.stubs.Set(nova.db.api, 'instance_get', server_not_found) + + body = { + "rebuild": { + "imageRef": "http://localhost/images/2", + }, + } + + req = webob.Request.blank('/v1.1/fake/servers/1/action') + req.method = 'POST' + req.content_type = 'application/json' + req.body = json.dumps(body) + + res = req.get_response(fakes.wsgi_app()) + self.assertEqual(res.status_int, 404) + def test_resize_server(self): req = webob.Request.blank('/v1.1/fake/servers/1/action') diff --git a/nova/tests/api/openstack/test_servers.py b/nova/tests/api/openstack/test_servers.py index aec2ad947..e533fb190 100644 --- a/nova/tests/api/openstack/test_servers.py +++ b/nova/tests/api/openstack/test_servers.py @@ -4541,3 +4541,138 @@ class ServerXMLSerializationTest(test.TestCase): str(ip['version'])) self.assertEqual(str(ip_elem.get('addr')), str(ip['addr'])) + + def test_action(self): + serializer = servers.ServerXMLSerializer() + + fixture = { + "server": { + "id": 1, + "uuid": FAKE_UUID, + 'created': self.TIMESTAMP, + 'updated': self.TIMESTAMP, + "progress": 0, + "name": "test_server", + "status": "BUILD", + "accessIPv4": "1.2.3.4", + "accessIPv6": "fead::1234", + "hostId": "e4d909c290d0fb1ca068ffaddf22cbd0", + "adminPass": "test_password", + "image": { + "id": "5", + "links": [ + { + "rel": "bookmark", + "href": self.IMAGE_BOOKMARK, + }, + ], + }, + "flavor": { + "id": "1", + "links": [ + { + "rel": "bookmark", + "href": self.FLAVOR_BOOKMARK, + }, + ], + }, + "addresses": { + "network_one": [ + { + "version": 4, + "addr": "67.23.10.138", + }, + { + "version": 6, + "addr": "::babe:67.23.10.138", + }, + ], + "network_two": [ + { + "version": 4, + "addr": "67.23.10.139", + }, + { + "version": 6, + "addr": "::babe:67.23.10.139", + }, + ], + }, + "metadata": { + "Open": "Stack", + "Number": "1", + }, + 'links': [ + { + 'href': self.SERVER_HREF, + 'rel': 'self', + }, + { + 'href': self.SERVER_BOOKMARK, + 'rel': 'bookmark', + }, + ], + } + } + + output = serializer.serialize(fixture, 'action') + root = etree.XML(output) + xmlutil.validate_schema(root, 'server') + + expected_server_href = self.SERVER_HREF + expected_server_bookmark = self.SERVER_BOOKMARK + expected_image_bookmark = self.IMAGE_BOOKMARK + expected_flavor_bookmark = self.FLAVOR_BOOKMARK + expected_now = self.TIMESTAMP + expected_uuid = FAKE_UUID + server_dict = fixture['server'] + + for key in ['name', 'id', 'uuid', 'created', 'accessIPv4', + 'updated', 'progress', 'status', 'hostId', + 'accessIPv6', 'adminPass']: + self.assertEqual(root.get(key), str(server_dict[key])) + + link_nodes = root.findall('{0}link'.format(ATOMNS)) + self.assertEqual(len(link_nodes), 2) + for i, link in enumerate(server_dict['links']): + for key, value in link.items(): + self.assertEqual(link_nodes[i].get(key), value) + + metadata_root = root.find('{0}metadata'.format(NS)) + metadata_elems = metadata_root.findall('{0}meta'.format(NS)) + self.assertEqual(len(metadata_elems), 2) + for i, metadata_elem in enumerate(metadata_elems): + (meta_key, meta_value) = server_dict['metadata'].items()[i] + self.assertEqual(str(metadata_elem.get('key')), str(meta_key)) + self.assertEqual(str(metadata_elem.text).strip(), str(meta_value)) + + image_root = root.find('{0}image'.format(NS)) + self.assertEqual(image_root.get('id'), server_dict['image']['id']) + link_nodes = image_root.findall('{0}link'.format(ATOMNS)) + self.assertEqual(len(link_nodes), 1) + for i, link in enumerate(server_dict['image']['links']): + for key, value in link.items(): + self.assertEqual(link_nodes[i].get(key), value) + + flavor_root = root.find('{0}flavor'.format(NS)) + self.assertEqual(flavor_root.get('id'), server_dict['flavor']['id']) + link_nodes = flavor_root.findall('{0}link'.format(ATOMNS)) + self.assertEqual(len(link_nodes), 1) + for i, link in enumerate(server_dict['flavor']['links']): + for key, value in link.items(): + self.assertEqual(link_nodes[i].get(key), value) + + addresses_root = root.find('{0}addresses'.format(NS)) + addresses_dict = server_dict['addresses'] + network_elems = addresses_root.findall('{0}network'.format(NS)) + self.assertEqual(len(network_elems), 2) + for i, network_elem in enumerate(network_elems): + network = addresses_dict.items()[i] + self.assertEqual(str(network_elem.get('id')), str(network[0])) + ip_elems = network_elem.findall('{0}ip'.format(NS)) + for z, ip_elem in enumerate(ip_elems): + ip = network[1][z] + self.assertEqual(str(ip_elem.get('version')), + str(ip['version'])) + self.assertEqual(str(ip_elem.get('addr')), + str(ip['addr'])) -- cgit From 998f40594841094291c7472dd608b6a2ba689e4d Mon Sep 17 00:00:00 2001 From: Brian Waldon Date: Wed, 24 Aug 2011 11:11:20 -0400 Subject: dict formatting --- nova/tests/api/openstack/test_server_actions.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'nova/tests') diff --git a/nova/tests/api/openstack/test_server_actions.py b/nova/tests/api/openstack/test_server_actions.py index 9a664f44d..3dfdeb79c 100644 --- a/nova/tests/api/openstack/test_server_actions.py +++ b/nova/tests/api/openstack/test_server_actions.py @@ -88,11 +88,13 @@ def stub_instance(id, power_state=0, metadata=None, "access_ip_v4": "", "access_ip_v6": "", "uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa", - "virtual_interfaces": []} + "virtual_interfaces": [], + } instance["fixed_ips"] = { "address": '192.168.0.1', - "floating_ips": []} + "floating_ips": [], + } return instance -- cgit From 390f35f8e7736bfbd650c9e3f522274e92adb005 Mon Sep 17 00:00:00 2001 From: Hisaharu Ishii Date: Wed, 24 Aug 2011 09:11:57 -0700 Subject: Fix flag override in unit test --- nova/tests/test_nova_manage.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'nova/tests') diff --git a/nova/tests/test_nova_manage.py b/nova/tests/test_nova_manage.py index ca4f4c894..ce731222c 100644 --- a/nova/tests/test_nova_manage.py +++ b/nova/tests/test_nova_manage.py @@ -133,7 +133,7 @@ class NetworkCommandsTestCase(test.TestCase): self.assertEqual(kwargs['bridge_interface'], 'eth0') self.assertEqual(kwargs['dns1'], '8.8.8.8') self.assertEqual(kwargs['dns2'], '8.8.4.4') - FLAGS.network_manager = 'nova.network.manager.VlanManager' + self.flags(network_manager='nova.network.manager.VlanManager') from nova.network import manager as net_manager self.stubs.Set(net_manager.VlanManager, 'create_networks', fake_create_networks) -- cgit From 8ad9373648dea11783545ad88429def4691a2925 Mon Sep 17 00:00:00 2001 From: "vladimir.p" Date: Wed, 24 Aug 2011 09:18:53 -0700 Subject: pep8 compliant --- nova/tests/integrated/test_volumes.py | 5 +++-- nova/tests/test_volume_types.py | 2 -- nova/tests/test_volume_types_extra_specs.py | 1 - 3 files changed, 3 insertions(+), 5 deletions(-) (limited to 'nova/tests') diff --git a/nova/tests/integrated/test_volumes.py b/nova/tests/integrated/test_volumes.py index 86165944f..d6c5e1ba1 100644 --- a/nova/tests/integrated/test_volumes.py +++ b/nova/tests/integrated/test_volumes.py @@ -291,8 +291,9 @@ class VolumesTest(integrated_helpers._IntegratedTestBase): # Create volume metadata = {'key1': 'value1', 'key2': 'value2'} - created_volume = self.api.post_volume({'volume': {'size': 1, - 'metadata': metadata}}) + created_volume = self.api.post_volume( + {'volume': {'size': 1, + 'metadata': metadata}}) LOG.debug("created_volume: %s" % created_volume) self.assertTrue(created_volume['id']) created_volume_id = created_volume['id'] diff --git a/nova/tests/test_volume_types.py b/nova/tests/test_volume_types.py index 3d906a5fd..a20c18b18 100644 --- a/nova/tests/test_volume_types.py +++ b/nova/tests/test_volume_types.py @@ -152,5 +152,3 @@ class VolumeTypeTestCase(test.TestCase): new2 = volume_types.get_volume_type(self.ctxt, new['id']) self.assertEqual(new, new2) - - diff --git a/nova/tests/test_volume_types_extra_specs.py b/nova/tests/test_volume_types_extra_specs.py index 8d2aa2df3..017b187a1 100644 --- a/nova/tests/test_volume_types_extra_specs.py +++ b/nova/tests/test_volume_types_extra_specs.py @@ -44,7 +44,6 @@ class VolumeTypeExtraSpecsTestCase(test.TestCase): ref = db.api.volume_type_create(self.context, self.vol_type2_noextra) self.vol_type2_id = ref.id - def tearDown(self): # Remove the instance type from the database db.api.volume_type_purge(context.get_admin_context(), -- cgit From 207ce4f19655e70d14f3a67a45ba6acf8f12380d Mon Sep 17 00:00:00 2001 From: "vladimir.p" Date: Wed, 24 Aug 2011 10:16:20 -0700 Subject: added volume type search by extra_spec --- nova/tests/test_volume_types.py | 55 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) (limited to 'nova/tests') diff --git a/nova/tests/test_volume_types.py b/nova/tests/test_volume_types.py index a20c18b18..1b4c9396c 100644 --- a/nova/tests/test_volume_types.py +++ b/nova/tests/test_volume_types.py @@ -152,3 +152,58 @@ class VolumeTypeTestCase(test.TestCase): new2 = volume_types.get_volume_type(self.ctxt, new['id']) self.assertEqual(new, new2) + + def test_volume_type_search_by_extra_spec(self): + """Ensure volume types get by extra spec returns correct type""" + volume_types.create(self.ctxt, "type1", {"key1": "val1", + "key2": "val2"}) + volume_types.create(self.ctxt, "type2", {"key2": "val2", + "key3": "val3"}) + volume_types.create(self.ctxt, "type3", {"key3": "another_value", + "key4": "val4"}) + + vol_types = volume_types.get_all_types(self.ctxt, + search_opts={'extra_specs': {"key1": "val1"}}) + LOG.info("vol_types: %s" % vol_types) + self.assertEqual(len(vol_types), 1) + self.assertTrue("type1" in vol_types.keys()) + self.assertEqual(vol_types['type1']['extra_specs'], + {"key1": "val1", "key2": "val2"}) + + vol_types = volume_types.get_all_types(self.ctxt, + search_opts={'extra_specs': {"key2": "val2"}}) + LOG.info("vol_types: %s" % vol_types) + self.assertEqual(len(vol_types), 2) + self.assertTrue("type1" in vol_types.keys()) + self.assertTrue("type2" in vol_types.keys()) + + + vol_types = volume_types.get_all_types(self.ctxt, + search_opts={'extra_specs': {"key3": "val3"}}) + LOG.info("vol_types: %s" % vol_types) + self.assertEqual(len(vol_types), 1) + self.assertTrue("type2" in vol_types.keys()) + + + def test_volume_type_search_by_extra_spec_multiple(self): + """Ensure volume types get by extra spec returns correct type""" + volume_types.create(self.ctxt, "type1", {"key1": "val1", + "key2": "val2", + "key3": "val3"}) + volume_types.create(self.ctxt, "type2", {"key2": "val2", + "key3": "val3"}) + volume_types.create(self.ctxt, "type3", {"key1": "val1", + "key3": "val3", + "key4": "val4"}) + + vol_types = volume_types.get_all_types(self.ctxt, + search_opts={'extra_specs': {"key1": "val1", + "key3": "val3"}}) + LOG.info("vol_types: %s" % vol_types) + self.assertEqual(len(vol_types), 2) + self.assertTrue("type1" in vol_types.keys()) + self.assertTrue("type3" in vol_types.keys()) + self.assertEqual(vol_types['type1']['extra_specs'], + {"key1": "val1", "key2": "val2", "key3": "val3"}) + self.assertEqual(vol_types['type3']['extra_specs'], + {"key1": "val1", "key3": "val3", "key4": "val4"}) -- cgit From 5ab769daf354033f5044c88d4f899d56effd998e Mon Sep 17 00:00:00 2001 From: Hisaharu Ishii Date: Wed, 24 Aug 2011 10:47:11 -0700 Subject: split test_modify() into specific unit tests --- nova/tests/test_nova_manage.py | 88 ++++++++++++++++++++---------------------- 1 file changed, 42 insertions(+), 46 deletions(-) (limited to 'nova/tests') diff --git a/nova/tests/test_nova_manage.py b/nova/tests/test_nova_manage.py index ce731222c..c83d773f2 100644 --- a/nova/tests/test_nova_manage.py +++ b/nova/tests/test_nova_manage.py @@ -34,18 +34,15 @@ sys.dont_write_bytecode = False import mox import stubout -import netaddr import StringIO 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.tests.db import fakes as db_fakes FLAGS = flags.FLAGS -LOG = logging.getLogger('nova.tests.nova_manage') class FixedIpCommandsTestCase(test.TestCase): @@ -112,6 +109,18 @@ class NetworkCommandsTestCase(test.TestCase): 'host': 'fake_host', 'uuid': 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa'} + def fake_network_get_by_cidr(context, cidr): + self.assertTrue(context.to_dict()['is_admin']) + self.assertEqual(cidr, self.fake_net['cidr']) + return db_fakes.FakeModel(self.fake_net) + + def fake_network_update(context, network_id, values): + self.assertTrue(context.to_dict()['is_admin']) + self.assertEqual(network_id, self.fake_net['id']) + self.assertEqual(values, self.fake_update_value) + self.fake_network_get_by_cidr = fake_network_get_by_cidr + self.fake_network_update = fake_network_update + def tearDown(self): super(NetworkCommandsTestCase, self).tearDown() self.stubs.UnsetAll() @@ -185,50 +194,37 @@ class NetworkCommandsTestCase(test.TestCase): self.assertEqual(result, answer) def test_delete(self): - net_dis = self.net - net_dis['project_id'] = None - net_dis['host'] = None - - def fake_network_get_by_cidr(context, cidr): - self.assertTrue(context.to_dict()['is_admin']) - self.assertEqual(cidr, net_dis['cidr']) - return db_fakes.FakeModel(net_dis) - self.stubs.Set(db, 'network_get_by_cidr', fake_network_get_by_cidr) + self.fake_net = self.net + self.fake_net['project_id'] = None + self.fake_net['host'] = None + self.stubs.Set(db, 'network_get_by_cidr', + self.fake_network_get_by_cidr) def fake_network_delete_safe(context, network_id): self.assertTrue(context.to_dict()['is_admin']) - self.assertEqual(network_id, net_dis['id']) + self.assertEqual(network_id, self.fake_net['id']) self.stubs.Set(db, 'network_delete_safe', fake_network_delete_safe) - self.commands.delete(fixed_range=net_dis['cidr']) - - def test_modify(self): - - def fake_network_get_by_cidr(context, cidr): - self.assertTrue(context.to_dict()['is_admin']) - self.assertEqual(cidr, self.net['cidr']) - return db_fakes.FakeModel(self.net) - self.stubs.Set(db, 'network_get_by_cidr', fake_network_get_by_cidr) - - def fake_network_update(context, network_id, values): - self.assertTrue(context.to_dict()['is_admin']) - self.assertEqual(network_id, self.net['id']) - self.assertEqual(values, {'project_id': 'test_project', - 'host': 'test_host'}) - self.stubs.Set(db, 'network_update', fake_network_update) - self.commands.modify(self.net['cidr'], project='test_project', - host='test_host') - - def fake_network_update(context, network_id, values): - self.assertTrue(context.to_dict()['is_admin']) - self.assertEqual(network_id, self.net['id']) - self.assertEqual(values, {}) - self.stubs.Set(db, 'network_update', fake_network_update) - self.commands.modify(self.net['cidr']) - - def fake_network_update(context, network_id, values): - self.assertTrue(context.to_dict()['is_admin']) - self.assertEqual(network_id, self.net['id']) - self.assertEqual(values, {'project_id': None, - 'host': None}) - self.stubs.Set(db, 'network_update', fake_network_update) - self.commands.modify(self.net['cidr'], dis_project=True, dis_host=True) + self.commands.delete(fixed_range=self.fake_net['cidr']) + + def _test_modify_base(self, update_value, project, host, dis_project=None, + dis_host=None): + self.fake_net = self.net + self.fake_update_value = update_value + self.stubs.Set(db, 'network_get_by_cidr', + self.fake_network_get_by_cidr) + self.stubs.Set(db, 'network_update', self.fake_network_update) + self.commands.modify(self.fake_net['cidr'], project=project, host=host, + dis_project=dis_project, dis_host=dis_host) + + def test_modify_associate(self): + self._test_modify_base(update_value={'project_id': 'test_project', + 'host': 'test_host'}, + project='test_project', host='test_host') + + def test_modify_unchanged(self): + self._test_modify_base(update_value={}, project=None, host=None) + + def test_modify_disassociate(self): + self._test_modify_base(update_value={'project_id': None, 'host': None}, + project=None, host=None, dis_project=True, + dis_host=True) -- cgit From e51c73a2d953103d4245cb8d456cad590be73ff5 Mon Sep 17 00:00:00 2001 From: Hisaharu Ishii Date: Wed, 24 Aug 2011 11:10:05 -0700 Subject: Removed unused imports --- nova/tests/test_nova_manage.py | 6 ------ 1 file changed, 6 deletions(-) (limited to 'nova/tests') diff --git a/nova/tests/test_nova_manage.py b/nova/tests/test_nova_manage.py index c83d773f2..70efbf651 100644 --- a/nova/tests/test_nova_manage.py +++ b/nova/tests/test_nova_manage.py @@ -15,7 +15,6 @@ # License for the specific language governing permissions and limitations # under the License. -import gettext import os import sys @@ -25,8 +24,6 @@ TOPDIR = os.path.normpath(os.path.join( os.pardir)) NOVA_MANAGE_PATH = os.path.join(TOPDIR, 'bin', 'nova-manage') -gettext.install('nova', unicode=1) - sys.dont_write_bytecode = True import imp nova_manage = imp.load_source('nova_manage.py', NOVA_MANAGE_PATH) @@ -38,12 +35,9 @@ import StringIO from nova import context from nova import db from nova import exception -from nova import flags from nova import test from nova.tests.db import fakes as db_fakes -FLAGS = flags.FLAGS - class FixedIpCommandsTestCase(test.TestCase): def setUp(self): -- cgit From 156f2fb68981bde1a24233e2648d11890a98e34a Mon Sep 17 00:00:00 2001 From: Hisaharu Ishii Date: Wed, 24 Aug 2011 13:10:56 -0700 Subject: Add names to placeholders of formatting --- nova/tests/test_nova_manage.py | 40 +++++++++++++++++++++------------------- 1 file changed, 21 insertions(+), 19 deletions(-) (limited to 'nova/tests') diff --git a/nova/tests/test_nova_manage.py b/nova/tests/test_nova_manage.py index 70efbf651..520bfbea1 100644 --- a/nova/tests/test_nova_manage.py +++ b/nova/tests/test_nova_manage.py @@ -165,25 +165,27 @@ class NetworkCommandsTestCase(test.TestCase): self.commands.list() sys.stdout = sys.__stdout__ result = output.getvalue() - _fmt = "%-5s\t%-18s\t%-15s\t%-15s\t%-15s\t%-15s\t%-15s\t%-15s\t%-15s" - head = _fmt % (_('id'), - _('IPv4'), - _('IPv6'), - _('start address'), - _('DNS1'), - _('DNS2'), - _('VlanID'), - _('project'), - _("uuid")) - body = _fmt % (self.net['id'], - self.net['cidr'], - self.net['cidr_v6'], - self.net['dhcp_start'], - self.net['dns1'], - self.net['dns2'], - self.net['vlan'], - self.net['project_id'], - self.net['uuid']) + _fmt = "%(id)-5s\t%(cidr)-18s\t%(cidr_v6)-15s\t%(dhcp_start)-15s\t" +\ + "%(dns1)-15s\t%(dns2)-15s\t%(vlan)-15s\t%(project_id)-15s\t" +\ + "%(uuid)-15s" + head = _fmt % {'id': _('id'), + 'cidr': _('IPv4'), + 'cidr_v6': _('IPv6'), + 'dhcp_start': _('start address'), + 'dns1': _('DNS1'), + 'dns2': _('DNS2'), + 'vlan': _('VlanID'), + 'project_id': _('project'), + 'uuid': _("uuid")} + body = _fmt % {'id': self.net['id'], + 'cidr': self.net['cidr'], + 'cidr_v6': self.net['cidr_v6'], + 'dhcp_start': self.net['dhcp_start'], + 'dns1': self.net['dns1'], + 'dns2': self.net['dns2'], + 'vlan': self.net['vlan'], + 'project_id': self.net['project_id'], + 'uuid': self.net['uuid']} answer = '%s\n%s\n' % (head, body) self.assertEqual(result, answer) -- cgit From 576dd4a0dce66c7949a1f66a6979d9e1d11916bf Mon Sep 17 00:00:00 2001 From: "vladimir.p" Date: Wed, 24 Aug 2011 14:07:17 -0700 Subject: added Openstack APIs for volume types & extradata --- nova/tests/api/openstack/test_volume_types.py | 171 +++++++++++++++++++ .../api/openstack/test_volume_types_extra_specs.py | 181 +++++++++++++++++++++ 2 files changed, 352 insertions(+) create mode 100644 nova/tests/api/openstack/test_volume_types.py create mode 100644 nova/tests/api/openstack/test_volume_types_extra_specs.py (limited to 'nova/tests') diff --git a/nova/tests/api/openstack/test_volume_types.py b/nova/tests/api/openstack/test_volume_types.py new file mode 100644 index 000000000..192e66854 --- /dev/null +++ b/nova/tests/api/openstack/test_volume_types.py @@ -0,0 +1,171 @@ +# Copyright 2011 OpenStack LLC. +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +import json +import stubout +import webob + +from nova import exception +from nova import context +from nova import test +from nova import log as logging +from nova.volume import volume_types +from nova.tests.api.openstack import fakes + +LOG = logging.getLogger('nova.tests.api.openstack.test_volume_types') + +last_param = {} + + +def stub_volume_type(id): + specs = { + "key1": "value1", + "key2": "value2", + "key3": "value3", + "key4": "value4", + "key5": "value5"} + return dict(id=id, name='vol_type_%s' % str(id), extra_specs=specs) + + +def return_volume_types_get_all_types(context): + return dict(vol_type_1=stub_volume_type(1), + vol_type_2=stub_volume_type(2), + vol_type_3=stub_volume_type(3)) + + +def return_empty_volume_types_get_all_types(context): + return {} + + +def return_volume_types_get_volume_type(context, id): + if id == "777": + raise exception.VolumeTypeNotFound(volume_type_id=id) + return stub_volume_type(int(id)) + + +def return_volume_types_destroy(context, name): + if name == "777": + raise exception.VolumeTypeNotFoundByName(volume_type_name=name) + pass + + +def return_volume_types_create(context, name, specs): + pass + + +def return_volume_types_get_by_name(context, name): + if name == "777": + raise exception.VolumeTypeNotFoundByName(volume_type_name=name) + return stub_volume_type(int(name.split("_")[2])) + + +class VolumeTypesApiTest(test.TestCase): + def setUp(self): + super(VolumeTypesApiTest, self).setUp() + fakes.stub_out_key_pair_funcs(self.stubs) + + def tearDown(self): + self.stubs.UnsetAll() + super(VolumeTypesApiTest, self).tearDown() + + def test_volume_types_index(self): + self.stubs.Set(volume_types, 'get_all_types', + return_volume_types_get_all_types) + req = webob.Request.blank('/v1.1/123/os-volume-types') + res = req.get_response(fakes.wsgi_app()) + self.assertEqual(200, res.status_int) + res_dict = json.loads(res.body) + self.assertEqual('application/json', res.headers['Content-Type']) + + self.assertEqual(3, len(res_dict)) + for name in ['vol_type_1', 'vol_type_2', 'vol_type_3']: + self.assertEqual(name, res_dict[name]['name']) + self.assertEqual('value1', res_dict[name]['extra_specs']['key1']) + + def test_volume_types_index_no_data(self): + self.stubs.Set(volume_types, 'get_all_types', + return_empty_volume_types_get_all_types) + req = webob.Request.blank('/v1.1/123/os-volume-types') + res = req.get_response(fakes.wsgi_app()) + res_dict = json.loads(res.body) + self.assertEqual(200, res.status_int) + self.assertEqual('application/json', res.headers['Content-Type']) + self.assertEqual(0, len(res_dict)) + + def test_volume_types_show(self): + self.stubs.Set(volume_types, 'get_volume_type', + return_volume_types_get_volume_type) + req = webob.Request.blank('/v1.1/123/os-volume-types/1') + res = req.get_response(fakes.wsgi_app()) + self.assertEqual(200, res.status_int) + res_dict = json.loads(res.body) + self.assertEqual('application/json', res.headers['Content-Type']) + self.assertEqual(1, len(res_dict)) + self.assertEqual('vol_type_1', res_dict['volume_type']['name']) + + def test_volume_types_show_not_found(self): + self.stubs.Set(volume_types, 'get_volume_type', + return_volume_types_get_volume_type) + req = webob.Request.blank('/v1.1/123/os-volume-types/777') + res = req.get_response(fakes.wsgi_app()) + self.assertEqual(404, res.status_int) + + def test_volume_types_delete(self): + self.stubs.Set(volume_types, 'get_volume_type', + return_volume_types_get_volume_type) + self.stubs.Set(volume_types, 'destroy', + return_volume_types_destroy) + req = webob.Request.blank('/v1.1/123/os-volume-types/1') + req.method = 'DELETE' + res = req.get_response(fakes.wsgi_app()) + self.assertEqual(200, res.status_int) + + def test_volume_types_delete_not_found(self): + self.stubs.Set(volume_types, 'get_volume_type', + return_volume_types_get_volume_type) + self.stubs.Set(volume_types, 'destroy', + return_volume_types_destroy) + req = webob.Request.blank('/v1.1/123/os-volume-types/777') + req.method = 'DELETE' + res = req.get_response(fakes.wsgi_app()) + self.assertEqual(404, res.status_int) + + def test_create(self): + self.stubs.Set(volume_types, 'create', + return_volume_types_create) + self.stubs.Set(volume_types, 'get_volume_type_by_name', + return_volume_types_get_by_name) + req = webob.Request.blank('/v1.1/123/os-volume-types') + req.method = 'POST' + req.body = '{"volume_type": {"name": "vol_type_1", '\ + '"extra_specs": {"key1": "value1"}}}' + req.headers["content-type"] = "application/json" + res = req.get_response(fakes.wsgi_app()) + self.assertEqual(200, res.status_int) + res_dict = json.loads(res.body) + self.assertEqual('application/json', res.headers['Content-Type']) + self.assertEqual(1, len(res_dict)) + self.assertEqual('vol_type_1', res_dict['volume_type']['name']) + + def test_create_empty_body(self): + self.stubs.Set(volume_types, 'create', + return_volume_types_create) + self.stubs.Set(volume_types, 'get_volume_type_by_name', + return_volume_types_get_by_name) + req = webob.Request.blank('/v1.1/123/os-volume-types') + req.method = 'POST' + req.headers["content-type"] = "application/json" + res = req.get_response(fakes.wsgi_app()) + self.assertEqual(400, res.status_int) diff --git a/nova/tests/api/openstack/test_volume_types_extra_specs.py b/nova/tests/api/openstack/test_volume_types_extra_specs.py new file mode 100644 index 000000000..34bdada22 --- /dev/null +++ b/nova/tests/api/openstack/test_volume_types_extra_specs.py @@ -0,0 +1,181 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright (c) 2011 Zadara Storage Inc. +# Copyright (c) 2011 OpenStack LLC. +# Copyright 2011 University of Southern California +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +import json +import stubout +import webob +import os.path + + +from nova import test +from nova.api import openstack +from nova.api.openstack import extensions +from nova.tests.api.openstack import fakes +import nova.wsgi + + +def return_create_volume_type_extra_specs(context, volume_type_id, + extra_specs): + return stub_volume_type_extra_specs() + + +def return_volume_type_extra_specs(context, volume_type_id): + return stub_volume_type_extra_specs() + + +def return_empty_volume_type_extra_specs(context, volume_type_id): + return {} + + +def delete_volume_type_extra_specs(context, volume_type_id, key): + pass + + +def stub_volume_type_extra_specs(): + specs = { + "key1": "value1", + "key2": "value2", + "key3": "value3", + "key4": "value4", + "key5": "value5"} + return specs + + +class VolumeTypesExtraSpecsTest(test.TestCase): + + def setUp(self): + super(VolumeTypesExtraSpecsTest, self).setUp() + fakes.stub_out_key_pair_funcs(self.stubs) + self.api_path = '/v1.1/123/os-volume-types/1/extra_specs' + + def test_index(self): + self.stubs.Set(nova.db.api, 'volume_type_extra_specs_get', + return_volume_type_extra_specs) + request = webob.Request.blank(self.api_path) + res = request.get_response(fakes.wsgi_app()) + self.assertEqual(200, res.status_int) + res_dict = json.loads(res.body) + self.assertEqual('application/json', res.headers['Content-Type']) + self.assertEqual('value1', res_dict['extra_specs']['key1']) + + def test_index_no_data(self): + self.stubs.Set(nova.db.api, 'volume_type_extra_specs_get', + return_empty_volume_type_extra_specs) + req = webob.Request.blank(self.api_path) + res = req.get_response(fakes.wsgi_app()) + res_dict = json.loads(res.body) + self.assertEqual(200, res.status_int) + self.assertEqual('application/json', res.headers['Content-Type']) + self.assertEqual(0, len(res_dict['extra_specs'])) + + def test_show(self): + self.stubs.Set(nova.db.api, 'volume_type_extra_specs_get', + return_volume_type_extra_specs) + req = webob.Request.blank(self.api_path + '/key5') + res = req.get_response(fakes.wsgi_app()) + self.assertEqual(200, res.status_int) + res_dict = json.loads(res.body) + self.assertEqual('application/json', res.headers['Content-Type']) + self.assertEqual('value5', res_dict['key5']) + + def test_show_spec_not_found(self): + self.stubs.Set(nova.db.api, 'volume_type_extra_specs_get', + return_empty_volume_type_extra_specs) + req = webob.Request.blank(self.api_path + '/key6') + res = req.get_response(fakes.wsgi_app()) + res_dict = json.loads(res.body) + self.assertEqual(404, res.status_int) + + def test_delete(self): + self.stubs.Set(nova.db.api, 'volume_type_extra_specs_delete', + delete_volume_type_extra_specs) + req = webob.Request.blank(self.api_path + '/key5') + req.method = 'DELETE' + res = req.get_response(fakes.wsgi_app()) + self.assertEqual(200, res.status_int) + + def test_create(self): + self.stubs.Set(nova.db.api, + 'volume_type_extra_specs_update_or_create', + return_create_volume_type_extra_specs) + req = webob.Request.blank(self.api_path) + req.method = 'POST' + req.body = '{"extra_specs": {"key1": "value1"}}' + req.headers["content-type"] = "application/json" + res = req.get_response(fakes.wsgi_app()) + res_dict = json.loads(res.body) + self.assertEqual(200, res.status_int) + self.assertEqual('application/json', res.headers['Content-Type']) + self.assertEqual('value1', res_dict['extra_specs']['key1']) + + def test_create_empty_body(self): + self.stubs.Set(nova.db.api, + 'volume_type_extra_specs_update_or_create', + return_create_volume_type_extra_specs) + req = webob.Request.blank(self.api_path) + req.method = 'POST' + req.headers["content-type"] = "application/json" + res = req.get_response(fakes.wsgi_app()) + self.assertEqual(400, res.status_int) + + def test_update_item(self): + self.stubs.Set(nova.db.api, + 'volume_type_extra_specs_update_or_create', + return_create_volume_type_extra_specs) + req = webob.Request.blank(self.api_path + '/key1') + req.method = 'PUT' + req.body = '{"key1": "value1"}' + req.headers["content-type"] = "application/json" + res = req.get_response(fakes.wsgi_app()) + self.assertEqual(200, res.status_int) + self.assertEqual('application/json', res.headers['Content-Type']) + res_dict = json.loads(res.body) + self.assertEqual('value1', res_dict['key1']) + + def test_update_item_empty_body(self): + self.stubs.Set(nova.db.api, + 'volume_type_extra_specs_update_or_create', + return_create_volume_type_extra_specs) + req = webob.Request.blank(self.api_path + '/key1') + req.method = 'PUT' + req.headers["content-type"] = "application/json" + res = req.get_response(fakes.wsgi_app()) + self.assertEqual(400, res.status_int) + + def test_update_item_too_many_keys(self): + self.stubs.Set(nova.db.api, + 'volume_type_extra_specs_update_or_create', + return_create_volume_type_extra_specs) + req = webob.Request.blank(self.api_path + '/key1') + req.method = 'PUT' + req.body = '{"key1": "value1", "key2": "value2"}' + req.headers["content-type"] = "application/json" + res = req.get_response(fakes.wsgi_app()) + self.assertEqual(400, res.status_int) + + def test_update_item_body_uri_mismatch(self): + self.stubs.Set(nova.db.api, + 'volume_type_extra_specs_update_or_create', + return_create_volume_type_extra_specs) + req = webob.Request.blank(self.api_path + '/bad') + req.method = 'PUT' + req.body = '{"key1": "value1"}' + req.headers["content-type"] = "application/json" + res = req.get_response(fakes.wsgi_app()) + self.assertEqual(400, res.status_int) -- cgit From 96f85f94f23c9eeac3f43e122d2992b6d0938827 Mon Sep 17 00:00:00 2001 From: "vladimir.p" Date: Wed, 24 Aug 2011 14:30:40 -0700 Subject: forgot to add new extension to test_extensions --- nova/tests/api/openstack/test_extensions.py | 1 + 1 file changed, 1 insertion(+) (limited to 'nova/tests') diff --git a/nova/tests/api/openstack/test_extensions.py b/nova/tests/api/openstack/test_extensions.py index 9f923852d..c78588d65 100644 --- a/nova/tests/api/openstack/test_extensions.py +++ b/nova/tests/api/openstack/test_extensions.py @@ -97,6 +97,7 @@ class ExtensionControllerTest(test.TestCase): "SecurityGroups", "VirtualInterfaces", "Volumes", + "VolumeTypes", ] self.ext_list.sort() -- cgit From e30d2c372cc36d7e9a6cf3af5016834b499a7b42 Mon Sep 17 00:00:00 2001 From: Ken Pepple Date: Wed, 24 Aug 2011 15:18:17 -0700 Subject: fixing inappropriate rubyism in test code --- nova/tests/test_instance_types.py | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) (limited to 'nova/tests') diff --git a/nova/tests/test_instance_types.py b/nova/tests/test_instance_types.py index 556ba91a9..409a22fb6 100644 --- a/nova/tests/test_instance_types.py +++ b/nova/tests/test_instance_types.py @@ -47,24 +47,24 @@ class InstanceTypeTestCase(test.TestCase): self.id = max_id["id"] + 1 self.name = str(int(time.time())) - def _nonexistant_flavor_name(self): + def _nonexistent_flavor_name(self): """return an instance type name not in the DB""" - nonexistant_flavor = "sdfsfsdf" + nonexistent_flavor = "sdfsfsdf" flavors = instance_types.get_all_types() - while nonexistant_flavor in flavors: - nonexistant_flavor = nonexistant_flavor.join("z") + while nonexistent_flavor in flavors: + nonexistent_flavor += "z" else: - return nonexistant_flavor + return nonexistent_flavor - def _nonexistant_flavor_id(self): + def _nonexistent_flavor_id(self): """return an instance type ID not in the DB""" - nonexistant_flavor = 2700 + nonexistent_flavor = 2700 flavor_ids = [value["id"] for key, value in\ instance_types.get_all_types().iteritems()] - while nonexistant_flavor in flavor_ids: - nonexistant_flavor += 1 + while nonexistent_flavor in flavor_ids: + nonexistent_flavor += 1 else: - return nonexistant_flavor + return nonexistent_flavor def _existing_flavor(self): """return first instance type name""" @@ -111,7 +111,7 @@ class InstanceTypeTestCase(test.TestCase): """Ensures that instance type creation fails with invalid args""" self.assertRaises(exception.ApiError, instance_types.destroy, - self._nonexistant_flavor_name()) + self._nonexistent_flavor_name()) def test_repeated_inst_types_should_raise_api_error(self): """Ensures that instance duplicates raises ApiError""" @@ -126,7 +126,7 @@ class InstanceTypeTestCase(test.TestCase): """Ensure destroy sad path of no name raises error""" self.assertRaises(exception.ApiError, instance_types.destroy, - self._nonexistant_flavor_name()) + self._nonexistent_flavor_name()) def test_will_not_purge_without_name(self): """Ensure purge without a name raises error""" @@ -137,11 +137,11 @@ class InstanceTypeTestCase(test.TestCase): """Ensure purge without correct name raises error""" self.assertRaises(exception.ApiError, instance_types.purge, - self._nonexistant_flavor_name()) + self._nonexistent_flavor_name()) def test_will_not_get_bad_default_instance_type(self): """ensures error raised on bad default instance type""" - FLAGS.default_instance_type = self._nonexistant_flavor_name() + FLAGS.default_instance_type = self._nonexistent_flavor_name() self.assertRaises(exception.InstanceTypeNotFoundByName, instance_types.get_default_instance_type) @@ -154,10 +154,10 @@ class InstanceTypeTestCase(test.TestCase): """Ensure get by name returns default flavor with bad name""" self.assertRaises(exception.InstanceTypeNotFound, instance_types.get_instance_type, - self._nonexistant_flavor_name()) + self._nonexistent_flavor_name()) def test_will_not_get_flavor_by_bad_flavor_id(self): """Ensure get by flavor raises error with wrong flavorid""" self.assertRaises(exception.InstanceTypeNotFound, instance_types.get_instance_type_by_name, - self._nonexistant_flavor_id()) + self._nonexistent_flavor_id()) -- 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 dde9fdc6665e2562ec490fe43f46dcf945c59220 Mon Sep 17 00:00:00 2001 From: Ken Pepple Date: Wed, 24 Aug 2011 16:03:32 -0700 Subject: removes french spellings to satisfy american developers --- nova/tests/test_instance_types.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'nova/tests') diff --git a/nova/tests/test_instance_types.py b/nova/tests/test_instance_types.py index 409a22fb6..09f532239 100644 --- a/nova/tests/test_instance_types.py +++ b/nova/tests/test_instance_types.py @@ -107,7 +107,7 @@ class InstanceTypeTestCase(test.TestCase): exception.InvalidInput, instance_types.create, self.name, 256, 1, "aa", self.flavorid) - def test_non_existant_inst_type_shouldnt_delete(self): + def test_non_existent_inst_type_shouldnt_delete(self): """Ensures that instance type creation fails with invalid args""" self.assertRaises(exception.ApiError, instance_types.destroy, -- 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 5dc7956eed749c33b6cfaaaf122e829feec62ea9 Mon Sep 17 00:00:00 2001 From: Dan Prince Date: Fri, 26 Aug 2011 09:54:53 -0400 Subject: Update compute API and manager so that the image_ref is set before spawning the rebuilt instance. Fixes issue where rebuild didn't actually change the image_id. --- nova/tests/integrated/test_servers.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'nova/tests') diff --git a/nova/tests/integrated/test_servers.py b/nova/tests/integrated/test_servers.py index c2f800689..b9382038a 100644 --- a/nova/tests/integrated/test_servers.py +++ b/nova/tests/integrated/test_servers.py @@ -193,7 +193,7 @@ class ServersTest(integrated_helpers._IntegratedTestBase): # rebuild the server with metadata post = {} post['rebuild'] = { - "imageRef": "https://localhost/v1.1/32278/images/2", + "imageRef": "https://localhost/v1.1/32278/images/3", "name": "blah", } @@ -205,6 +205,7 @@ class ServersTest(integrated_helpers._IntegratedTestBase): self.assertEqual(created_server_id, found_server['id']) self.assertEqual({}, found_server.get('metadata')) self.assertEqual('blah', found_server.get('name')) + self.assertEqual('3', found_server.get('image')['id']) # Cleanup self._delete_server(created_server_id) -- 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