Create unit tests dir, move objects tests there

Coverage of objects/base up to 93%. Ongoing work to fix some tests.

Change-Id: I7366037269762ae76f5b8cc1613fe2bf29f897ec
This commit is contained in:
Federico Ceratto 2015-07-17 10:58:43 +01:00
parent 9199863136
commit f181ea08b0
8 changed files with 465 additions and 21 deletions

View File

@ -264,12 +264,13 @@ class DesignateObject(object):
for field in six.iterkeys(self.FIELDS):
if self.obj_attr_is_set(field):
if isinstance(getattr(self, field), ListObjectMixin):
data[field] = getattr(self, field).to_list()
elif isinstance(getattr(self, field), DesignateObject):
data[field] = getattr(self, field).to_dict()
val = getattr(self, field)
if isinstance(val, ListObjectMixin):
data[field] = val.to_list()
elif isinstance(val, DesignateObject):
data[field] = val.to_dict()
else:
data[field] = getattr(self, field)
data[field] = val
return data

View File

@ -0,0 +1,10 @@
This directory contains pure unit tests.
Examples:
ostestr --regex designate.tests.test_unit
python setup.py testr --coverage -t designate.tests.test_unit

View File

@ -13,9 +13,10 @@
# 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 oslo_log import log as logging
from designate import tests
from oslo_log import log as logging
import oslotest.base
from designate import objects
from designate.objects import adapters
@ -33,7 +34,7 @@ class DesignateTestAdapter(adapters.DesignateAdapter):
}
class DesignateAdapterTest(tests.TestCase):
class DesignateAdapterTest(oslotest.base.BaseTestCase):
def test_get_object_adapter(self):
adapters.DesignateAdapter.get_object_adapter(
'TEST_API', objects.DesignateObject())

View File

@ -13,16 +13,19 @@
# 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 copy
from operator import attrgetter
import copy
import unittest
import testtools
from oslo_log import log as logging
from testtools import ExpectedException as raises # with raises(...): ...
import mock
import oslotest.base
import testtools
from designate import tests
from designate import objects
from designate import exceptions
from designate import objects
LOG = logging.getLogger(__name__)
@ -69,7 +72,7 @@ class TestValidatableObject(objects.DesignateObject):
}
class DesignateObjectTest(tests.TestCase):
class DesignateObjectTest(oslotest.base.BaseTestCase):
def test_obj_cls_from_name(self):
cls = objects.DesignateObject.obj_cls_from_name('TestObject')
self.assertEqual(TestObject, cls)
@ -183,6 +186,40 @@ class DesignateObjectTest(tests.TestCase):
# other for the nested field
self.assertEqual(set(['id', 'nested_list']), obj.obj_what_changed())
def test_from_list(self):
with raises(NotImplementedError):
TestObject.from_list([])
def test_get_schema(self):
obj = TestValidatableObject()
obj.id = 'ffded5c4-e4f6-4e02-a175-48e13c5c12a0'
obj.validate()
self.assertTrue(hasattr(obj, '_obj_validator'))
expected = {
'description': 'Designate TestValidatableObject Object',
'title': 'TestValidatableObject', 'required': ['id'],
'additionalProperties': False,
'$schema': 'http://json-schema.org/draft-04/hyper-schema',
'type': 'object',
'properties': {
'id': {
'type': 'string', 'format': 'uuid'
}
}
}
schema = obj._obj_validator.schema
self.assertEqual(schema, expected)
with raises(AttributeError): # bug
schema = obj.obj_get_schema()
@unittest.expectedFailure # bug
def test__schema_ref_resolver(self):
from designate.objects.base import _schema_ref_resolver
_schema_ref_resolver(
'obj://TestValidatableObject#/subpathA/subpathB')
def test_init_invalid(self):
with testtools.ExpectedException(TypeError):
TestObject(extra_field='Fail')
@ -190,17 +227,17 @@ class DesignateObjectTest(tests.TestCase):
def test_hasattr(self):
obj = TestObject()
# Suceess Cases
# Success Cases
self.assertTrue(hasattr(obj, 'id'),
"Should have id attribute")
"Should have id attribute")
self.assertTrue(hasattr(obj, 'name'),
"Should have name attribute")
"Should have name attribute")
# Failure Cases
self.assertFalse(hasattr(obj, 'email'),
"Should not have email attribute")
"Should not have email attribute")
self.assertFalse(hasattr(obj, 'names'),
"Should not have names attribute")
"Should not have names attribute")
def test_setattr(self):
obj = TestObject()
@ -308,6 +345,17 @@ class DesignateObjectTest(tests.TestCase):
self.assertEqual(expected, dict_)
def test_update(self):
obj = TestObject(id='MyID', name='test')
obj.update({'id': 'new_id', 'name': 'new_name'})
self.assertEqual(obj.id, 'new_id')
self.assertEqual(obj.name, 'new_name')
def test_update_unexpected_attribute(self):
obj = TestObject(id='MyID', name='test')
with raises(AttributeError):
obj.update({'id': 'new_id', 'new_key': 3})
def test_is_valid(self):
obj = TestValidatableObject(id='MyID')
@ -505,6 +553,11 @@ class DesignateObjectTest(tests.TestCase):
# Ensure they do not evaluate to equal
self.assertNotEqual(obj_one, obj_two)
def test_eq_false(self):
obj = TestObject(id="My ID", name="My Name")
self.assertFalse(obj == tuple())
self.assertNotEqual(obj, tuple())
def test_ne(self):
# Create two equal objects
obj_one = TestObject(id="My ID", name="My Name")
@ -520,7 +573,7 @@ class DesignateObjectTest(tests.TestCase):
self.assertTrue(obj_one != obj_two)
class DictObjectMixinTest(tests.TestCase):
class DictObjectMixinTest(oslotest.base.BaseTestCase):
def test_cast_to_dict(self):
# Create an object
obj = TestObjectDict()
@ -534,8 +587,53 @@ class DictObjectMixinTest(tests.TestCase):
self.assertEqual(expected, dict(obj))
def test_gititem(self):
obj = TestObjectDict(name=1)
self.assertEqual(obj['name'], 1)
class ListObjectMixinTest(tests.TestCase):
def test_setitem(self):
obj = TestObjectDict()
obj['name'] = 1
self.assertEqual(obj.name, 1)
def test_contains(self):
obj = TestObjectDict(name=1)
self.assertTrue('name' in obj)
def test_get(self):
obj = TestObjectDict(name=1)
v = obj.get('name')
self.assertEqual(v, 1)
def test_get_missing(self):
obj = TestObjectDict(name=1)
self.assertFalse(obj.obj_attr_is_set('foo'))
with raises(AttributeError):
obj.get('foo')
def test_get_default(self):
obj = TestObjectDict(name='n')
v = obj.get('name', default='default')
self.assertEqual(v, 'n')
def test_get_default_with_patch(self):
obj = TestObjectDict(name='v')
fname = 'designate.objects.base.DesignateObject.obj_attr_is_set'
with mock.patch(fname) as attr_is_set:
attr_is_set.return_value = False
v = obj.get('name', default='default')
self.assertEqual(v, 'default')
def test_iteritems(self):
obj = TestObjectDict(name=None, id=1)
items = tuple(obj.items())
self.assertEqual(
sorted(items),
[('id', 1), ('name', None)]
)
class ListObjectMixinTest(oslotest.base.BaseTestCase):
def test_from_primitive(self):
primitive = {
'designate_object.name': 'TestObjectList',
@ -732,6 +830,16 @@ class ListObjectMixinTest(tests.TestCase):
self.assertEqual(obj.objects, [obj_one, obj_two, obj_three])
def test_remove(self):
# Create a few objects
obj_one = TestObject(id="One")
obj_two = TestObject(id="Two")
# Create a ListObject
obj = TestObjectList(objects=[obj_one, obj_two])
obj.remove(obj_one)
self.assertEqual(obj.objects, [obj_two])
def test_index(self):
# Create a few objects
obj_one = TestObject(id="One")
@ -764,3 +872,31 @@ class ListObjectMixinTest(tests.TestCase):
obj.sort(key=attrgetter('id'))
self.assertEqual(obj.objects, [obj_one, obj_two, obj_three])
def test_to_dict(self):
# Create a ListObject containing a DesignateObject
obj_one = objects.DesignateObject()
obj = TestObjectList(objects=obj_one)
dict_ = obj.to_dict()
expected = {'objects': {}}
self.assertEqual(dict_, expected)
def test_to_dict_list_mixin(self):
# Create a ListObject containing an ObjectList
obj = TestObjectList(objects=TestObjectList())
dict_ = obj.to_dict()
expected = {'objects': []}
self.assertEqual(dict_, expected)
def test_to_list(self):
# Create a few objects
obj_one = TestObject(id="One")
obj_three = TestObject(id="Three")
# Create a ListObject
obj = TestObjectList(objects=[obj_one, obj_three])
li = obj.to_list()
self .assertEqual(li, [{'id': 'One'}, {'id': 'Three'}])

View File

@ -0,0 +1,102 @@
# Copyright 2015 Hewlett-Packard Development Company, L.P.
#
# Author: Federico Ceratto <federico.ceratto@hp.com>
#
# 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 unittest
from oslo_log import log as logging
from testtools import ExpectedException as raises # with raises(...): ...
import mock
import oslotest.base
from designate import exceptions
from designate import objects
LOG = logging.getLogger(__name__)
def create_test_domain():
return objects.Domain(
name='www.example.org.',
email='foo@example.com',
)
class DomainTest(oslotest.base.BaseTestCase):
def test_init(self):
domain = create_test_domain()
self.assertEqual(domain.name, 'www.example.org.')
def test_masters_none(self):
domain = objects.Domain()
self.assertEqual(domain.masters, None)
def test_masters(self):
domain = objects.Domain(
attributes=objects.DomainAttributeList.from_list([
objects.DomainAttribute(key='master', value='1.0.0.0')
])
)
self.assertEqual(domain.masters, ['1.0.0.0'])
def test_masters_2(self):
domain = objects.Domain(
attributes=objects.DomainAttributeList.from_list([
objects.DomainAttribute(key='master', value='1.0.0.0'),
objects.DomainAttribute(key='master', value='2.0.0.0')
])
)
self.assertEqual(len(domain.masters), 2)
def test_set_masters_none(self):
domain = create_test_domain()
domain.set_masters(('1.0.0.0', '2.0.0.0'))
self.assertEqual(len(domain.attributes), 2)
def test_get_master_by_ip(self):
domain = objects.Domain(
attributes=objects.DomainAttributeList.from_list([
objects.DomainAttribute(key='master', value='1.0.0.0'),
objects.DomainAttribute(key='master', value='2.0.0.0')
])
)
def mock_split(v):
assert ':' not in v
return v, ''
with mock.patch('designate.objects.domain.utils.split_host_port',
side_effect=mock_split):
m = domain.get_master_by_ip('2.0.0.0')
self.assertEqual(m, '2.0.0.0')
@unittest.expectedFailure # bug: domain.masters is not iterable
def test_get_master_by_ip_none(self):
domain = objects.Domain()
m = domain.get_master_by_ip('2.0.0.0')
self.assertEqual(m, False)
def test_validate(self):
domain = create_test_domain()
domain.validate()
def test_validate_invalid_secondary(self):
domain = objects.Domain(
type='SECONDARY',
)
with raises(exceptions.InvalidObject):
domain.validate()

View File

@ -0,0 +1,194 @@
# Copyright 2015 Hewlett-Packard Development Company, L.P.
#
# Author: Federico Ceratto <federico.ceratto@hp.com>
#
# 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 itertools
import unittest
from oslo_log import log as logging
from testtools import ExpectedException as raises # with raises(...): ...
import mock
import oslotest.base
from designate import exceptions
from designate import objects
LOG = logging.getLogger(__name__)
def debug(*a, **kw):
for v in a:
LOG.debug(repr(v))
for k in sorted(kw):
LOG.debug("%s: %s", k, repr(kw[k]))
class TestRecordSet(objects.RecordSet):
FIELDS = {
'id': {},
'name': {},
'records': {
'relation': True,
'relation_cls': 'RecordList',
},
}
def create_test_recordset():
rs = objects.RecordSet(
name='www.example.org.',
type='A',
records=objects.RecordList(objects=[
objects.Record(data='192.0.2.1'),
objects.Record(data='192.0.2.2'),
])
)
return rs
class RecordSetTest(oslotest.base.BaseTestCase):
def test_init(self):
rs = create_test_recordset()
self.assertEqual(rs.name, 'www.example.org.')
self.assertEqual(rs.type, 'A')
def test_not_managed(self):
rs = create_test_recordset()
self.assertFalse(rs.managed)
def test_managed(self):
rs = objects.RecordSet(
name='www.example.org.',
type='A',
records=objects.RecordList(objects=[
objects.Record(data='192.0.2.1', managed=True),
objects.Record(data='192.0.2.2'),
])
)
self.assertTrue(rs.managed)
def test_action(self):
action = 'CREATE'
rs = objects.RecordSet(
name='www.example.org.',
type='A',
records=objects.RecordList(objects=[
objects.Record(data='192.0.2.1', action=action),
])
)
self.assertEqual(rs.action, action)
def test_action_create(self):
rs = objects.RecordSet(
name='www.example.org.', type='A',
records=objects.RecordList(objects=[
objects.Record(data='192.0.2.1', action='CREATE'),
])
)
self.assertEqual(rs.action, 'CREATE')
def test_action_create_plus_update(self):
rs = objects.RecordSet(
name='www.example.org.', type='A',
records=objects.RecordList(objects=[
objects.Record(data='192.0.2.1', action='CREATE'),
objects.Record(data='192.0.2.2', action='UPDATE'),
])
)
self.assertEqual(rs.action, 'UPDATE')
def test_action_delete_plus_update(self):
rs = objects.RecordSet(
name='www.example.org.', type='A',
records=objects.RecordList(objects=[
objects.Record(data='192.0.2.1', action='DELETE'),
objects.Record(data='192.0.2.2', action='UPDATE'),
])
)
self.assertEqual(rs.action, 'UPDATE')
def test_action_delete_only(self):
rs = objects.RecordSet(
name='www.example.org.', type='A',
records=objects.RecordList(objects=[
objects.Record(data='192.0.2.1', action='DELETE'),
objects.Record(data='192.0.2.2', action='DELETE'),
])
)
self.assertEqual(rs.action, 'DELETE')
@unittest.expectedFailure # bug
def test_status_error(self):
statuses = ('ERROR', 'PENDING', 'ACTIVE')
failed = False
for s1, s2, s3 in itertools.permutations(statuses):
rs = objects.RecordSet(
name='www.example.org.', type='A',
records=objects.RecordList(objects=[
objects.Record(data='192.0.2.1', status=s1),
objects.Record(data='192.0.2.2', status=s2),
objects.Record(data='192.0.2.3', status=s3),
])
)
if rs.status != 'ERROR':
failed = True
print("test_status_error failed for %s %s %s: %s" % (
s1, s2, s3, rs.status))
self.assertFalse(failed)
def test_status_pending(self):
rs = objects.RecordSet(
name='www.example.org.', type='A',
records=objects.RecordList(objects=[
objects.Record(data='192.0.2.2', status='PENDING'),
objects.Record(data='192.0.2.3', status='ACTIVE'),
])
)
self.assertEqual(rs.status, 'PENDING')
def test_status_pending2(self):
rs = objects.RecordSet(
name='www.example.org.', type='A',
records=objects.RecordList(objects=[
objects.Record(data='192.0.2.3', status='ACTIVE'),
objects.Record(data='192.0.2.2', status='PENDING'),
])
)
self.assertEqual(rs.status, 'PENDING')
def test_status_active(self):
rs = objects.RecordSet(
name='www.example.org.', type='A',
records=objects.RecordList(objects=[
objects.Record(data='192.0.2.3', status='ACTIVE'),
])
)
self.assertEqual(rs.status, 'ACTIVE')
def test_validate(self):
rs = create_test_recordset()
rs.validate()
def test_validate_handle_exception(self):
rs = create_test_recordset()
with mock.patch('designate.objects.DesignateObject.obj_cls_from_name') \
as patched:
patched.side_effect = KeyError
with raises(exceptions.InvalidObject):
# TODO(Federico): check the attributes of the exception
rs.validate()