From 79e62516afdb924677f18ba8fa83e1120c429e58 Mon Sep 17 00:00:00 2001 From: Ihar Hrachyshka Date: Tue, 29 Nov 2016 00:20:44 +0000 Subject: [PATCH] tests: introduce update_obj_fields method in base objects test class This method can be used by subclasses to inject specific values into randomly generated values for objects, for example, when we need to link those automatic test objects to other objects through foreign keys. Change-Id: Ic32ebf5ef055b25e4c765a9bf71ca4657d3b3d70 Partially-Implements: blueprint adopt-oslo-versioned-objects-for-db --- .../extensions/test_allowedaddresspairs.py | 5 +-- .../port/extensions/test_extra_dhcp_opt.py | 5 +-- neutron/tests/unit/objects/test_base.py | 37 +++++++++++++++- neutron/tests/unit/objects/test_floatingip.py | 8 +--- neutron/tests/unit/objects/test_network.py | 23 +++------- neutron/tests/unit/objects/test_ports.py | 43 ++++++------------- .../unit/objects/test_provisioning_blocks.py | 6 +-- neutron/tests/unit/objects/test_router.py | 19 ++++---- .../tests/unit/objects/test_securitygroup.py | 10 ++--- neutron/tests/unit/objects/test_subnet.py | 19 +++----- neutron/tests/unit/objects/test_subnetpool.py | 5 +-- 11 files changed, 79 insertions(+), 101 deletions(-) diff --git a/neutron/tests/unit/objects/port/extensions/test_allowedaddresspairs.py b/neutron/tests/unit/objects/port/extensions/test_allowedaddresspairs.py index 50b62127ba2..d62f6f423a0 100644 --- a/neutron/tests/unit/objects/port/extensions/test_allowedaddresspairs.py +++ b/neutron/tests/unit/objects/port/extensions/test_allowedaddresspairs.py @@ -10,8 +10,6 @@ # License for the specific language governing permissions and limitations # under the License. -import itertools - from neutron import context from neutron.objects.port.extensions import allowedaddresspairs from neutron.tests.unit.objects import test_base as obj_test_base @@ -34,5 +32,4 @@ class AllowedAddrPairsDbObjTestCase(obj_test_base.BaseDbObjectTestCase, self.context = context.get_admin_context() self._create_test_network() self._create_test_port(self._network) - for obj in itertools.chain(self.db_objs, self.obj_fields, self.objs): - obj['port_id'] = self._port['id'] + self.update_obj_fields({'port_id': self._port['id']}) diff --git a/neutron/tests/unit/objects/port/extensions/test_extra_dhcp_opt.py b/neutron/tests/unit/objects/port/extensions/test_extra_dhcp_opt.py index d89152251f9..28bcf6e7061 100644 --- a/neutron/tests/unit/objects/port/extensions/test_extra_dhcp_opt.py +++ b/neutron/tests/unit/objects/port/extensions/test_extra_dhcp_opt.py @@ -10,8 +10,6 @@ # License for the specific language governing permissions and limitations # under the License. -import itertools - from neutron.objects.port.extensions import extra_dhcp_opt from neutron.tests.unit.objects import test_base as obj_test_base from neutron.tests.unit import testlib_api @@ -31,5 +29,4 @@ class ExtraDhcpOptDbObjectTestCase(obj_test_base.BaseDbObjectTestCase, super(ExtraDhcpOptDbObjectTestCase, self).setUp() self._create_test_network() self._create_test_port(self._network) - for obj in itertools.chain(self.db_objs, self.obj_fields, self.objs): - obj['port_id'] = self._port['id'] + self.update_obj_fields({'port_id': self._port['id']}) diff --git a/neutron/tests/unit/objects/test_base.py b/neutron/tests/unit/objects/test_base.py index 3dd07d05447..3d6999d73ed 100644 --- a/neutron/tests/unit/objects/test_base.py +++ b/neutron/tests/unit/objects/test_base.py @@ -479,7 +479,7 @@ class _BaseObjectTestCase(object): valid_field = [f for f in self._test_class.fields if f not in self._test_class.synthetic_fields][0] self.valid_field_filter = {valid_field: - self.obj_fields[0][valid_field]} + self.obj_fields[-1][valid_field]} self.obj_registry = self.useFixture( fixture.VersionedObjectRegistryFixture()) self.obj_registry.register(FakeSmallNeutronObject) @@ -502,6 +502,41 @@ class _BaseObjectTestCase(object): fields[field] = get_value(generator, ip_version) return obj_cls.modify_fields_to_db(fields) + def update_obj_fields(self, values_dict, + db_objs=None, obj_fields=None, objs=None): + '''Update values for test objects with specific values. + + The default behaviour is using random values for all fields of test + objects. Sometimes it's not practical, for example, when some fields, + often those referencing other objects, require non-random values (None + or UUIDs of valid objects). If that's the case, a test subclass may + call the method to override some field values for test objects. + + Receives a single ``values_dict`` dict argument where keys are names of + test class fields, and values are either actual values for the keys, or + callables that will be used to generate different values for each test + object. + + Note: if a value is a dict itself, the method will recursively update + corresponding embedded objects. + ''' + for k, v in values_dict.items(): + for db_obj, fields, obj in zip( + db_objs or self.db_objs, + obj_fields or self.obj_fields, + objs or self.objs): + val = v() if callable(v) else v + db_obj_key = obj.fields_need_translation.get(k, k) + if isinstance(val, collections.Mapping): + self.update_obj_fields( + val, db_obj[db_obj_key], fields[k], obj[k]) + else: + db_obj[db_obj_key] = val + fields[k] = val + obj[k] = val + if k in self.valid_field_filter: + self.valid_field_filter[k] = val + @classmethod def generate_object_keys(cls, obj_cls, field_names=None): if field_names is None: diff --git a/neutron/tests/unit/objects/test_floatingip.py b/neutron/tests/unit/objects/test_floatingip.py index 6ee4b9085b5..2bccf06bf31 100644 --- a/neutron/tests/unit/objects/test_floatingip.py +++ b/neutron/tests/unit/objects/test_floatingip.py @@ -31,9 +31,5 @@ class FloatingIPDNSDbObjectTestcase(obj_test_base.BaseDbObjectTestCase, def setUp(self): super(FloatingIPDNSDbObjectTestcase, self).setUp() - for db_obj, obj_field, obj in zip(self.db_objs, - self.obj_fields, self.objs): - fip = self._create_test_fip() - db_obj['floatingip_id'] = fip['id'] - obj_field['floatingip_id'] = fip['id'] - obj['floatingip_id'] = fip['id'] + self.update_obj_fields( + {'floatingip_id': lambda: self._create_test_fip().id}) diff --git a/neutron/tests/unit/objects/test_network.py b/neutron/tests/unit/objects/test_network.py index 14ea7af813a..fbc9c5a97fe 100644 --- a/neutron/tests/unit/objects/test_network.py +++ b/neutron/tests/unit/objects/test_network.py @@ -10,8 +10,6 @@ # License for the specific language governing permissions and limitations # under the License. -import itertools - from neutron.objects import base as obj_base from neutron.objects import network from neutron.objects.qos import policy @@ -30,12 +28,7 @@ class NetworkPortSecurityDbObjTestCase(obj_test_base.BaseDbObjectTestCase, def setUp(self): super(NetworkPortSecurityDbObjTestCase, self).setUp() - for db_obj, obj_field, obj in zip( - self.db_objs, self.obj_fields, self.objs): - network = self._create_network() - db_obj['network_id'] = network.id - obj_field['id'] = network.id - obj['id'] = network['id'] + self.update_obj_fields({'id': lambda: self._create_network().id}) class NetworkSegmentIfaceObjTestCase(obj_test_base.BaseObjectIfaceTestCase): @@ -59,8 +52,7 @@ class NetworkSegmentDbObjTestCase(obj_test_base.BaseDbObjectTestCase, def setUp(self): super(NetworkSegmentDbObjTestCase, self).setUp() network = self._create_network() - for obj in itertools.chain(self.db_objs, self.obj_fields, self.objs): - obj['network_id'] = network.id + self.update_obj_fields({'network_id': network.id}) class NetworkObjectIfaceTestCase(obj_test_base.BaseObjectIfaceTestCase): @@ -171,8 +163,7 @@ class SegmentHostMappingDbObjectTestCase(obj_test_base.BaseDbObjectTestCase, super(SegmentHostMappingDbObjectTestCase, self).setUp() self._create_test_network() self._create_test_segment(network=self._network) - for obj in itertools.chain(self.db_objs, self.obj_fields, self.objs): - obj['segment_id'] = self._segment['id'] + self.update_obj_fields({'segment_id': self._segment['id']}) class NetworkDNSDomainIfaceObjectTestcase( @@ -188,9 +179,5 @@ class NetworkDNSDomainDbObjectTestcase(obj_test_base.BaseDbObjectTestCase, def setUp(self): super(NetworkDNSDomainDbObjectTestcase, self).setUp() - for db_obj, obj_field, obj in zip(self.db_objs, - self.obj_fields, self.objs): - network = self._create_network() - db_obj['network_id'] = network['id'] - obj_field['network_id'] = network['id'] - obj['network_id'] = network['id'] + self.update_obj_fields( + {'network_id': lambda: self._create_network().id}) diff --git a/neutron/tests/unit/objects/test_ports.py b/neutron/tests/unit/objects/test_ports.py index d418ac69b24..cf556e34ec6 100644 --- a/neutron/tests/unit/objects/test_ports.py +++ b/neutron/tests/unit/objects/test_ports.py @@ -10,8 +10,6 @@ # License for the specific language governing permissions and limitations # under the License. -import itertools - from oslo_utils import uuidutils import testscenarios @@ -31,12 +29,8 @@ class BasePortBindingDbObjectTestCase(obj_test_base._BaseObjectTestCase, def setUp(self): super(BasePortBindingDbObjectTestCase, self).setUp() self._create_test_network() - for db_obj, fields, obj in zip( - self.db_objs, self.obj_fields, self.objs): - port = self._create_port(network_id=self._network['id']) - db_obj['port_id'] = port.id - fields['port_id'] = port.id - obj.port_id = port.id + getter = lambda: self._create_port(network_id=self._network['id']).id + self.update_obj_fields({'port_id': getter}) class PortBindingIfaceObjTestCase(obj_test_base.BaseObjectIfaceTestCase): @@ -77,12 +71,8 @@ class PortBindingVifDetailsTestCase(testscenarios.WithScenarios, def setUp(self): super(PortBindingVifDetailsTestCase, self).setUp() self._create_test_network() - for db_obj, fields, obj in zip( - self.db_objs, self.obj_fields, self.objs): - port = self._create_port(network_id=self._network['id']) - db_obj['port_id'] = port.id - fields['port_id'] = port.id - obj.port_id = port.id + getter = lambda: self._create_port(network_id=self._network['id']).id + self.update_obj_fields({'port_id': getter}) def _create_port(self, **port_attrs): attrs = {'project_id': uuidutils.generate_uuid(), @@ -165,10 +155,9 @@ class IPAllocationDbObjectTestCase(obj_test_base.BaseDbObjectTestCase, self._create_test_network() self._create_test_subnet(self._network) self._create_test_port(self._network) - for obj in itertools.chain(self.db_objs, self.obj_fields, self.objs): - obj['port_id'] = self._port.id - obj['network_id'] = self._network.id - obj['subnet_id'] = self._subnet.id + self.update_obj_fields({'port_id': self._port.id, + 'network_id': self._network.id, + 'subnet_id': self._subnet.id}) class PortDNSIfaceObjTestCase(obj_test_base.BaseObjectIfaceTestCase): @@ -184,12 +173,8 @@ class PortDNSDbObjectTestCase(obj_test_base.BaseDbObjectTestCase, def setUp(self): super(PortDNSDbObjectTestCase, self).setUp() self._create_test_network() - for db_obj, fields, obj in zip( - self.db_objs, self.obj_fields, self.objs): - port_ = self._create_port(network_id=self._network['id']) - db_obj['port_id'] = port_.id - fields['port_id'] = port_.id - obj.port_id = port_.id + getter = lambda: self._create_port(network_id=self._network['id']).id + self.update_obj_fields({'port_id': getter}) class PortBindingLevelIfaceObjTestCase( @@ -239,12 +224,10 @@ class PortDbObjectTestCase(obj_test_base.BaseDbObjectTestCase, super(PortDbObjectTestCase, self).setUp() self._create_test_network() self._create_test_subnet(self._network) - for obj in itertools.chain(self.db_objs, self.obj_fields, self.objs): - obj['network_id'] = self._network['id'] - for obj in self.db_objs: - for ipalloc in obj['fixed_ips']: - ipalloc['subnet_id'] = self._subnet.id - ipalloc['network_id'] = self._network['id'] + self.update_obj_fields( + {'network_id': self._network.id, + 'fixed_ips': {'subnet_id': self._subnet.id, + 'network_id': self._network['id']}}) def test_security_group_ids(self): sg1 = self._create_test_security_group() diff --git a/neutron/tests/unit/objects/test_provisioning_blocks.py b/neutron/tests/unit/objects/test_provisioning_blocks.py index 979085d6f26..03d08220587 100644 --- a/neutron/tests/unit/objects/test_provisioning_blocks.py +++ b/neutron/tests/unit/objects/test_provisioning_blocks.py @@ -10,8 +10,6 @@ # License for the specific language governing permissions and limitations # under the License. -import itertools - from neutron.objects import provisioning_blocks from neutron.tests.unit.objects import test_base as obj_test_base from neutron.tests.unit import testlib_api @@ -31,5 +29,5 @@ class ProvisioningBlockDbObjectTestCase(obj_test_base.BaseDbObjectTestCase, def setUp(self): super(ProvisioningBlockDbObjectTestCase, self).setUp() self._create_test_standard_attribute() - for obj in itertools.chain(self.db_objs, self.obj_fields, self.objs): - obj['standard_attr_id'] = self._standard_attribute['id'] + self.update_obj_fields( + {'standard_attr_id': self._standard_attribute['id']}) diff --git a/neutron/tests/unit/objects/test_router.py b/neutron/tests/unit/objects/test_router.py index b743ee60d43..d72f262323a 100644 --- a/neutron/tests/unit/objects/test_router.py +++ b/neutron/tests/unit/objects/test_router.py @@ -31,12 +31,12 @@ class RouterRouteDbObjectTestCase(obj_test_base.BaseDbObjectTestCase, def setUp(self): super(RouterRouteDbObjectTestCase, self).setUp() - for db_obj, obj_field, obj in zip( - self.db_objs, self.obj_fields, self.objs): + + def getter(): self._create_test_router() - db_obj['router_id'] = self._router['id'] - obj_field['router_id'] = self._router['id'] - obj['router_id'] = self._router['id'] + return self._router['id'] + + self.update_obj_fields({'router_id': getter}) class RouterExtraAttrsIfaceObjTestCase(obj_test_base. @@ -51,9 +51,8 @@ class RouterExtraAttrsDbObjTestCase(obj_test_base.BaseDbObjectTestCase, def setUp(self): super(RouterExtraAttrsDbObjTestCase, self).setUp() - for db_obj, obj_field, obj in zip( - self.db_objs, self.obj_fields, self.objs): + def getter(): self._create_test_router() - db_obj['router_id'] = self._router['id'] - obj_field['router_id'] = self._router['id'] - obj['router_id'] = self._router['id'] + return self._router['id'] + + self.update_obj_fields({'router_id': getter}) diff --git a/neutron/tests/unit/objects/test_securitygroup.py b/neutron/tests/unit/objects/test_securitygroup.py index 3df141126b5..97e1462ca0a 100644 --- a/neutron/tests/unit/objects/test_securitygroup.py +++ b/neutron/tests/unit/objects/test_securitygroup.py @@ -10,8 +10,6 @@ # License for the specific language governing permissions and limitations # under the License. -import itertools - from neutron.objects import securitygroup from neutron.tests.unit.objects import test_base from neutron.tests.unit import testlib_api @@ -117,8 +115,7 @@ class DefaultSecurityGroupDbObjTestCase(test_base.BaseDbObjectTestCase, sg_db_obj) self.sg_obj = securitygroup.SecurityGroup(self.context, **sg_fields) self.sg_obj.create() - for obj in itertools.chain(self.db_objs, self.obj_fields, self.objs): - obj['security_group_id'] = self.sg_obj['id'] + self.update_obj_fields({'security_group_id': self.sg_obj['id']}) class SecurityGroupRuleIfaceObjTestCase(test_base.BaseObjectIfaceTestCase): @@ -138,6 +135,5 @@ class SecurityGroupRuleDbObjTestCase(test_base.BaseDbObjectTestCase, sg_db_obj) self.sg_obj = securitygroup.SecurityGroup(self.context, **sg_fields) self.sg_obj.create() - for obj in itertools.chain(self.db_objs, self.obj_fields, self.objs): - obj['security_group_id'] = self.sg_obj['id'] - obj['remote_group_id'] = self.sg_obj['id'] + self.update_obj_fields({'security_group_id': self.sg_obj['id'], + 'remote_group_id': self.sg_obj['id']}) diff --git a/neutron/tests/unit/objects/test_subnet.py b/neutron/tests/unit/objects/test_subnet.py index 7171f06e335..d37c35ffb6a 100644 --- a/neutron/tests/unit/objects/test_subnet.py +++ b/neutron/tests/unit/objects/test_subnet.py @@ -10,8 +10,6 @@ # License for the specific language governing permissions and limitations # under the License. -import itertools - from oslo_utils import uuidutils from neutron import context @@ -38,8 +36,7 @@ class IPAllocationPoolDbObjectTestCase(obj_test_base.BaseDbObjectTestCase, super(IPAllocationPoolDbObjectTestCase, self).setUp() self._create_test_network() self._create_test_subnet(self._network) - for obj in itertools.chain(self.db_objs, self.obj_fields, self.objs): - obj['subnet_id'] = self._subnet['id'] + self.update_obj_fields({'subnet_id': self._subnet['id']}) class DNSNameServerObjectIfaceTestCase(obj_test_base.BaseObjectIfaceTestCase): @@ -61,8 +58,7 @@ class DNSNameServerDbObjectTestCase(obj_test_base.BaseDbObjectTestCase, super(DNSNameServerDbObjectTestCase, self).setUp() self._create_test_network() self._create_test_subnet(self._network) - for obj in itertools.chain(self.db_objs, self.obj_fields, self.objs): - obj['subnet_id'] = self._subnet['id'] + self.update_obj_fields({'subnet_id': self._subnet['id']}) def _create_dnsnameservers(self): for obj in self.obj_fields: @@ -106,8 +102,7 @@ class RouteDbObjectTestCase(obj_test_base.BaseDbObjectTestCase, super(RouteDbObjectTestCase, self).setUp() self._create_test_network() self._create_test_subnet(self._network) - for obj in itertools.chain(self.db_objs, self.obj_fields, self.objs): - obj['subnet_id'] = self._subnet['id'] + self.update_obj_fields({'subnet_id': self._subnet['id']}) class SubnetServiceTypeObjectIfaceTestCase( @@ -125,8 +120,7 @@ class SubnetServiceTypeDbObjectTestCase(obj_test_base.BaseDbObjectTestCase, super(SubnetServiceTypeDbObjectTestCase, self).setUp() self._create_test_network() self._create_test_subnet(self._network) - for obj in itertools.chain(self.db_objs, self.obj_fields, self.objs): - obj['subnet_id'] = self._subnet['id'] + self.update_obj_fields({'subnet_id': self._subnet['id']}) class SubnetObjectIfaceTestCase(obj_test_base.BaseObjectIfaceTestCase): @@ -148,9 +142,8 @@ class SubnetDbObjectTestCase(obj_test_base.BaseDbObjectTestCase, super(SubnetDbObjectTestCase, self).setUp() self._create_test_network() self._create_test_segment(self._network) - for obj in itertools.chain(self.db_objs, self.obj_fields, self.objs): - obj['network_id'] = self._network['id'] - obj['segment_id'] = self._segment['id'] + self.update_obj_fields({'network_id': self._network['id'], + 'segment_id': self._segment['id']}) def test_get_dns_nameservers_in_order(self): obj = self._make_object(self.obj_fields[0]) diff --git a/neutron/tests/unit/objects/test_subnetpool.py b/neutron/tests/unit/objects/test_subnetpool.py index 3bf8036e4d3..9913d296463 100644 --- a/neutron/tests/unit/objects/test_subnetpool.py +++ b/neutron/tests/unit/objects/test_subnetpool.py @@ -13,8 +13,6 @@ # License for the specific language governing permissions and limitations # under the License. -import itertools - from oslo_utils import uuidutils from neutron.objects import subnetpool @@ -87,5 +85,4 @@ class SubnetPoolPrefixDbObjectTestCase( def setUp(self): super(SubnetPoolPrefixDbObjectTestCase, self).setUp() self._create_test_subnetpool() - for obj in itertools.chain(self.db_objs, self.obj_fields, self.objs): - obj['subnetpool_id'] = self._pool.id + self.update_obj_fields({'subnetpool_id': self._pool.id})