Add fake resources generator
In a variety of places we need to have an easy way to have resources populated with fake data. It costs quite a lot of lines of code and can be easily automated. With this change it can be as easy as `_fake = sdk_fakes.generate_fake_resource(Project)`. The code is implemented not to require estabilshed connection to ease use in tests. Change-Id: I47312f4036a0b389cd3689466ab220ba558aa39a
This commit is contained in:
parent
aba2b4179c
commit
d2a166a98e
0
openstack/test/__init__.py
Normal file
0
openstack/test/__init__.py
Normal file
122
openstack/test/fakes.py
Normal file
122
openstack/test/fakes.py
Normal file
@ -0,0 +1,122 @@
|
||||
# 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 inspect
|
||||
from random import choice
|
||||
from random import randint
|
||||
from random import random
|
||||
import uuid
|
||||
|
||||
from openstack import format as _format
|
||||
from openstack import resource
|
||||
|
||||
|
||||
def generate_fake_resource(resource_type, **attrs):
|
||||
"""Generate fake resource
|
||||
|
||||
:param type resource_type: Object class
|
||||
:param dict attrs: Optional attributes to be set on resource
|
||||
|
||||
:return: Instance of `resource_type` class populated with fake
|
||||
values of expected types.
|
||||
"""
|
||||
base_attrs = dict()
|
||||
for name, value in inspect.getmembers(
|
||||
resource_type,
|
||||
predicate=lambda x: isinstance(x, (resource.Body, resource.URI)),
|
||||
):
|
||||
if isinstance(value, resource.Body):
|
||||
target_type = value.type
|
||||
if target_type is None:
|
||||
if (
|
||||
name == "properties"
|
||||
and hasattr(
|
||||
resource_type, "_store_unknown_attrs_as_properties"
|
||||
)
|
||||
and resource_type._store_unknown_attrs_as_properties
|
||||
):
|
||||
# virtual "properties" attr which hosts all unknown attrs
|
||||
# (i.e. Image)
|
||||
base_attrs[name] = dict()
|
||||
else:
|
||||
# Type not defined - string
|
||||
base_attrs[name] = uuid.uuid4().hex
|
||||
elif issubclass(target_type, resource.Resource):
|
||||
# Attribute is of another Resource type
|
||||
base_attrs[name] = generate_fake_resource(target_type)
|
||||
elif issubclass(target_type, list) and value.list_type is not None:
|
||||
# List of ...
|
||||
item_type = value.list_type
|
||||
if issubclass(item_type, resource.Resource):
|
||||
# item is of Resource type
|
||||
base_attrs[name] = generate_fake_resource(item_type)
|
||||
elif issubclass(item_type, dict):
|
||||
base_attrs[name] = dict()
|
||||
elif issubclass(item_type, str):
|
||||
base_attrs[name] = [uuid.uuid4().hex]
|
||||
else:
|
||||
# Everything else
|
||||
msg = "Fake value for %s.%s can not be generated" % (
|
||||
resource_type.__name__,
|
||||
name,
|
||||
)
|
||||
raise NotImplementedError(msg)
|
||||
elif issubclass(target_type, list) and value.list_type is None:
|
||||
# List of str
|
||||
base_attrs[name] = [uuid.uuid4().hex]
|
||||
elif issubclass(target_type, str):
|
||||
# definitely string
|
||||
base_attrs[name] = uuid.uuid4().hex
|
||||
elif issubclass(target_type, int):
|
||||
# int
|
||||
base_attrs[name] = randint(1, 100)
|
||||
elif issubclass(target_type, float):
|
||||
# float
|
||||
base_attrs[name] = random()
|
||||
elif issubclass(target_type, bool) or issubclass(
|
||||
target_type, _format.BoolStr
|
||||
):
|
||||
# bool
|
||||
base_attrs[name] = choice([True, False])
|
||||
elif issubclass(target_type, dict):
|
||||
# some dict - without further details leave it empty
|
||||
base_attrs[name] = dict()
|
||||
else:
|
||||
# Everything else
|
||||
msg = "Fake value for %s.%s can not be generated" % (
|
||||
resource_type.__name__,
|
||||
name,
|
||||
)
|
||||
raise NotImplementedError(msg)
|
||||
if isinstance(value, resource.URI):
|
||||
# For URI we just generate something
|
||||
base_attrs[name] = uuid.uuid4().hex
|
||||
|
||||
base_attrs.update(**attrs)
|
||||
fake = resource_type(**base_attrs)
|
||||
return fake
|
||||
|
||||
|
||||
def generate_fake_resources(resource_type, count=1, attrs=None):
|
||||
"""Generate given number of fake resource entities
|
||||
|
||||
:param type resource_type: Object class
|
||||
:param int count: Number of objects to return
|
||||
:param dict attrs: Attribute values to set into each instance
|
||||
|
||||
:return: Array of `resource_type` class instances populated with fake
|
||||
values of expected types.
|
||||
"""
|
||||
if not attrs:
|
||||
attrs = {}
|
||||
for _ in range(count):
|
||||
yield generate_fake_resource(resource_type, **attrs)
|
73
openstack/tests/unit/test_fakes.py
Normal file
73
openstack/tests/unit/test_fakes.py
Normal file
@ -0,0 +1,73 @@
|
||||
# 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 openstack import format as _format
|
||||
from openstack import resource
|
||||
from openstack.test import fakes
|
||||
from openstack.tests.unit import base
|
||||
|
||||
|
||||
class TestGetFake(base.TestCase):
|
||||
def test_generate_fake_resource_one(self):
|
||||
res = fakes.generate_fake_resource(resource.Resource)
|
||||
self.assertIsInstance(res, resource.Resource)
|
||||
|
||||
def test_generate_fake_resource_list(self):
|
||||
res = list(fakes.generate_fake_resources(resource.Resource, 2))
|
||||
self.assertEqual(2, len(res))
|
||||
self.assertIsInstance(res[0], resource.Resource)
|
||||
|
||||
def test_generate_fake_resource_types(self):
|
||||
class Fake(resource.Resource):
|
||||
a = resource.Body("a", type=str)
|
||||
b = resource.Body("b", type=int)
|
||||
c = resource.Body("c", type=bool)
|
||||
d = resource.Body("d", type=_format.BoolStr)
|
||||
e = resource.Body("e", type=dict)
|
||||
f = resource.URI("path")
|
||||
|
||||
res = fakes.generate_fake_resource(Fake)
|
||||
self.assertIsInstance(res.a, str)
|
||||
self.assertIsInstance(res.b, int)
|
||||
self.assertIsInstance(res.c, bool)
|
||||
self.assertIsInstance(res.d, bool)
|
||||
self.assertIsInstance(res.e, dict)
|
||||
self.assertIsInstance(res.f, str)
|
||||
|
||||
def test_generate_fake_resource_attrs(self):
|
||||
class Fake(resource.Resource):
|
||||
a = resource.Body("a", type=str)
|
||||
b = resource.Body("b", type=str)
|
||||
|
||||
res = fakes.generate_fake_resource(Fake, b="bar")
|
||||
self.assertIsInstance(res.a, str)
|
||||
self.assertIsInstance(res.b, str)
|
||||
self.assertEqual("bar", res.b)
|
||||
|
||||
def test_generate_fake_resource_types_inherit(self):
|
||||
class Fake(resource.Resource):
|
||||
a = resource.Body("a", type=str)
|
||||
|
||||
class FakeInherit(resource.Resource):
|
||||
a = resource.Body("a", type=Fake)
|
||||
|
||||
res = fakes.generate_fake_resource(FakeInherit)
|
||||
self.assertIsInstance(res.a, Fake)
|
||||
self.assertIsInstance(res.a.a, str)
|
||||
|
||||
def test_unknown_attrs_as_props(self):
|
||||
class Fake(resource.Resource):
|
||||
properties = resource.Body("properties")
|
||||
_store_unknown_attrs_as_properties = True
|
||||
|
||||
res = fakes.generate_fake_resource(Fake)
|
||||
self.assertIsInstance(res.properties, dict)
|
@ -0,0 +1,5 @@
|
||||
---
|
||||
features:
|
||||
- |
|
||||
Add fake resource generator to ease unit testing in packages that depend on
|
||||
openstacksdk.
|
Loading…
Reference in New Issue
Block a user