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:
parent
9199863136
commit
f181ea08b0
@ -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
|
||||
|
||||
|
10
designate/tests/unit/README
Normal file
10
designate/tests/unit/README
Normal 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
|
||||
|
||||
|
||||
|
0
designate/tests/unit/test_objects/__init__.py
Normal file
0
designate/tests/unit/test_objects/__init__.py
Normal 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())
|
@ -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'}])
|
102
designate/tests/unit/test_objects/test_domain.py
Normal file
102
designate/tests/unit/test_objects/test_domain.py
Normal 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()
|
194
designate/tests/unit/test_objects/test_recordset.py
Normal file
194
designate/tests/unit/test_objects/test_recordset.py
Normal 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()
|
Loading…
Reference in New Issue
Block a user