From c911b3858bda240514c85bca0422cf39a7b7e88e Mon Sep 17 00:00:00 2001 From: Zhong Luyao Date: Fri, 17 Mar 2017 14:52:59 +0800 Subject: [PATCH] Add instance_fault testcases add unit testcases 1.db testcases 2.objects testcases Change-Id: I4cd8ce8ecb2cf2977599906e763a2742fd59f9c6 --- mogan/objects/instance_fault.py | 1 - mogan/tests/unit/db/base.py | 49 ++++++++++++ mogan/tests/unit/db/test_instance_faults.py | 77 +++++++++++++++++++ mogan/tests/unit/db/utils.py | 27 +++++++ .../tests/unit/objects/test_instance_fault.py | 65 ++++++++++++++++ mogan/tests/unit/objects/utils.py | 25 ++++++ 6 files changed, 243 insertions(+), 1 deletion(-) create mode 100644 mogan/tests/unit/db/test_instance_faults.py create mode 100644 mogan/tests/unit/objects/test_instance_fault.py diff --git a/mogan/objects/instance_fault.py b/mogan/objects/instance_fault.py index 3227a022..23a0f4ef 100644 --- a/mogan/objects/instance_fault.py +++ b/mogan/objects/instance_fault.py @@ -65,7 +65,6 @@ class InstanceFault(base.MoganObject, object_base.VersionedObjectDictCompat): 'code': self.code, 'message': self.message, 'detail': self.detail, - 'created_at': self.created_at, } db_fault = self.dbapi.instance_fault_create(self._context, values) self._from_db_object(self._context, self, db_fault) diff --git a/mogan/tests/unit/db/base.py b/mogan/tests/unit/db/base.py index d546276d..0b38270c 100644 --- a/mogan/tests/unit/db/base.py +++ b/mogan/tests/unit/db/base.py @@ -74,3 +74,52 @@ class DbTestCase(base.TestCase): _DB_CACHE = Database(engine, migration, sql_connection=CONF.database.connection) self.useFixture(_DB_CACHE) + + def _dict_from_object(self, obj, ignored_keys): + if ignored_keys is None: + ignored_keys = [] + + return {k: v for k, v in obj.items() + if k not in ignored_keys} + + def _assertDickeysEqual(self, obj1_dic, obj2_dic, msg=None): + obj1_keys = set(obj1_dic.keys()) + obj2_keys = set(obj2_dic.keys()) + + difference1 = obj1_keys.difference(obj2_keys) + difference2 = obj2_keys.difference(obj1_keys) + + if not (difference1 or difference2): + return + + lines = [] + if difference1: + lines.append('Keys in the first obj but not the second:') + for item in difference1: + lines.append(repr(item)) + if difference2: + lines.append('Keys in the second obj but not the first:') + for item in difference2: + lines.append(repr(item)) + standardMsg = '\n'.join(lines) + self.fail(self._formatMessage(msg, standardMsg)) + + def _assertEqualObjects(self, obj1, obj2, ignored_keys=None): + obj1 = self._dict_from_object(obj1, ignored_keys) + obj2 = self._dict_from_object(obj2, ignored_keys) + + self._assertDickeysEqual(obj1, obj2) + self.assertDictEqual(obj1, obj2) + + def _assertEqualListsOfObjects(self, objs1, objs2, ignored_keys=None): + obj_to_dict = lambda o: self._dict_from_object(o, ignored_keys) + sort_key = lambda d: [d[k] for k in sorted(d)] + conv_and_sort = lambda obj: sorted(map(obj_to_dict, obj), key=sort_key) + self.assertListEqual(conv_and_sort(objs1), conv_and_sort(objs2)) + + def _assertEqualOrderedListOfObjects(self, objs1, objs2, + ignored_keys=None): + conv = lambda objs:\ + [self._dict_from_object(obj, ignored_keys) for obj in objs] + + self.assertListEqual(conv(objs1), conv(objs2)) diff --git a/mogan/tests/unit/db/test_instance_faults.py b/mogan/tests/unit/db/test_instance_faults.py new file mode 100644 index 00000000..0123a6fc --- /dev/null +++ b/mogan/tests/unit/db/test_instance_faults.py @@ -0,0 +1,77 @@ +# Copyright 2017 Intel +# 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. + +"""Tests for manipulating Instance Faults via the DB API""" + +from oslo_utils import uuidutils + +from mogan.tests.unit.db import base +from mogan.tests.unit.db import utils + + +class DbInstanceFaultTestCase(base.DbTestCase): + def setUp(self): + super(DbInstanceFaultTestCase, self).setUp() + self.ctxt = {} + + def test_create_instance_fault(self): + uuid = uuidutils.generate_uuid() + # Ensure no faults registered for this instance + faults = self.dbapi.instance_fault_get_by_instance_uuids(self.ctxt, + [uuid]) + self.assertEqual(0, len(faults[uuid])) + + # Create a fault + fault_values = utils.get_test_instance_fault(instance_uuid=uuid) + fault = utils.create_test_instance_fault(self.ctxt, instance_uuid=uuid) + + ignored_keys = ['created_at', 'updated_at', 'id'] + self._assertEqualObjects(fault_values, fault, ignored_keys) + + # Retrieve the fault to ensure it was successfully added + faults = self.dbapi.instance_fault_get_by_instance_uuids(self.ctxt, + [uuid]) + self.assertEqual(1, len(faults[uuid])) + self._assertEqualObjects(fault, faults[uuid][0]) + + def test_get_instance_fault_by_instance(self): + """Ensure we can retrieve faults for instance.""" + uuids = [uuidutils.generate_uuid(), uuidutils.generate_uuid()] + fault_codes = [404, 500] + expected = {} + + # Create faults + for uuid in uuids: + utils.create_test_instance(self.ctxt, instance_uuid=uuid) + + expected[uuid] = [] + for code in fault_codes: + fault = utils.create_test_instance_fault(self.ctxt, + instance_uuid=uuid, + code=code) + # We expect the faults to be returned ordered by created_at in + # descending order, so insert the newly created fault at the + # front of our list. + expected[uuid].insert(0, fault) + + # Ensure faults are saved + faults = self.dbapi.instance_fault_get_by_instance_uuids(self.ctxt, + uuids) + ignored_keys = ['created_at', 'updated_at', 'id'] + self.assertEqual(len(expected), len(faults)) + for uuid in uuids: + self._assertEqualOrderedListOfObjects(expected[uuid], + faults[uuid], + ignored_keys) diff --git a/mogan/tests/unit/db/utils.py b/mogan/tests/unit/db/utils.py index 9f529639..3515e525 100644 --- a/mogan/tests/unit/db/utils.py +++ b/mogan/tests/unit/db/utils.py @@ -149,6 +149,33 @@ def create_test_instance_type(context={}, **kw): return dbapi.instance_type_create(context, instance_type) +def get_test_instance_fault(**kw): + return { + 'instance_uuid': kw.get('instance_uuid'), + 'code': kw.get('code', 404), + 'message': kw.get('message', 'message'), + 'detail': kw.get('detail', 'detail'), + 'created_at': kw.get('create_at', None), + 'updated_at': kw.get('update_at', None) + } + + +def create_test_instance_fault(context={}, **kw): + """Create test instance fault entry in DB and return the DB object. + + Function to be used to create test Instance Fault objects in the database. + + :param context: The request context, for access checks. + :param kw: kwargs with overriding values for instance fault's attributes. + :returns: Test Instance Fault DB object. + + """ + instance_fault = get_test_instance_fault(**kw) + dbapi = db_api.get_instance() + + return dbapi.instance_fault_create(context, instance_fault) + + def get_test_quota(**kw): return { 'id': kw.get('id', 123), diff --git a/mogan/tests/unit/objects/test_instance_fault.py b/mogan/tests/unit/objects/test_instance_fault.py new file mode 100644 index 00000000..1b1162b1 --- /dev/null +++ b/mogan/tests/unit/objects/test_instance_fault.py @@ -0,0 +1,65 @@ +# Copyright 2017 Intel +# 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 mock +from oslo_context import context +from oslo_utils import uuidutils + +from mogan import objects +from mogan.tests.unit.db import base +from mogan.tests.unit.objects import utils as obj_utils + + +class TestInstanceFaultObject(base.DbTestCase): + + def setUp(self): + super(TestInstanceFaultObject, self).setUp() + self.ctxt = context.get_admin_context() + + def test_create(self): + with mock.patch.object(self.dbapi, 'instance_fault_create', + autospec=True) as mock_fault_create: + uuid = uuidutils.generate_uuid() + fake_fault = obj_utils.get_test_instance_fault(instance_uuid=uuid) + mock_fault_create.return_value = fake_fault + instance_fault = objects.InstanceFault(self.ctxt) + instance_fault.instance_uuid = uuid + instance_fault.code = 456 + instance_fault.message = 'foo' + instance_fault.detail = 'you screwed up' + instance_fault.create() + self.assertEqual(123456, instance_fault.id) + mock_fault_create.assert_called_once_with( + self.ctxt, + {'instance_uuid': uuid, + 'code': 456, + 'message': 'foo', + 'detail': 'you screwed up'}) + + def test_get_latest_for_instance(self): + with mock.patch.object(self.dbapi, + 'instance_fault_get_by_instance_uuids', + autospec=True) as mock_fault_get: + uuid = uuidutils.generate_uuid() + fake_faults = obj_utils.get_test_instance_faults( + instance_uuid=uuid) + mock_fault_get.return_value = fake_faults + instance_fault = objects.InstanceFault.get_latest_for_instance( + self.ctxt, 'fake-uuid') + for key in fake_faults['fake-uuid'][0]: + self.assertEqual(fake_faults['fake-uuid'][0][key], + instance_fault[key]) + mock_fault_get.assert_called_once_with(self.ctxt, ['fake-uuid']) diff --git a/mogan/tests/unit/objects/utils.py b/mogan/tests/unit/objects/utils.py index 3a1af859..477d316f 100644 --- a/mogan/tests/unit/objects/utils.py +++ b/mogan/tests/unit/objects/utils.py @@ -69,6 +69,31 @@ def create_test_instance(ctxt, **kw): return instance +def get_test_instance_fault(**kw): + return { + 'id': kw.get('id', 123456), + 'instance_uuid': kw.get('instance_uuid'), + 'code': kw.get('code', 404), + 'message': kw.get('message', 'message'), + 'detail': kw.get('detail', 'detail'), + 'created_at': kw.get('create_at', None), + 'updated_at': kw.get('update_at', None) + } + + +def get_test_instance_faults(**kw): + return { + 'fake-uuid': [ + {'id': 1, 'instance_uuid': kw.get('instance_uuid'), 'code': 123, + 'message': 'msg1', 'detail': 'detail', 'created_at': None, + 'updated_at': None}, + {'id': 2, 'instance_uuid': kw.get('instance_uuid'), 'code': 456, + 'message': 'msg2', 'detail': 'detail', 'created_at': None, + 'updated_at': None}, + ] + } + + def get_test_compute_node(ctxt, **kw): """Return a ComputeNode object with appropriate attributes.