From dd5f5716c9a32634caa2a44d362cd77461ba873d Mon Sep 17 00:00:00 2001 From: Hong Hui Xiao Date: Thu, 17 Dec 2015 03:26:56 -0500 Subject: [PATCH] Remove duplicated code in attribute.py The _validate_XXX_list functions in [1] are mostly duplicated, this patch will use one function to validate list of items and remove others. [1] neutron/api/v2/attributes.py Change-Id: I86905018914becb64451941f0ecb06be30f2c740 Closes-Bug: #1527113 --- neutron/api/v2/attributes.py | 71 ++++++-------------- neutron/tests/unit/api/v2/test_attributes.py | 55 +++++++-------- 2 files changed, 46 insertions(+), 80 deletions(-) diff --git a/neutron/api/v2/attributes.py b/neutron/api/v2/attributes.py index 00a827e92..e3a6a0591 100644 --- a/neutron/api/v2/attributes.py +++ b/neutron/api/v2/attributes.py @@ -15,6 +15,7 @@ import re +import functools import netaddr from oslo_log import log as logging from oslo_utils import uuidutils @@ -77,6 +78,21 @@ def is_attr_set(attribute): return not (attribute is None or attribute is ATTR_NOT_SPECIFIED) +def _validate_list_of_items(item_validator, data, *args, **kwargs): + if not isinstance(data, list): + msg = _("'%s' is not a list") % data + return msg + + if len(set(data)) != len(data): + msg = _("Duplicate items in the list: '%s'") % ', '.join(data) + return msg + + for item in data: + msg = item_validator(item, *args, **kwargs) + if msg: + return msg + + def _validate_values(data, valid_values=None): if data not in valid_values: msg = (_("'%(data)s' is not in %(valid_values)s") % @@ -118,19 +134,8 @@ def _validate_string(data, max_len=None): return msg -def validate_list_of_unique_strings(data, max_string_len=None): - if not isinstance(data, list): - msg = _("'%s' is not a list") % data - return msg - - if len(set(data)) != len(data): - msg = _("Duplicate items in the list: '%s'") % ', '.join(data) - return msg - - for item in data: - msg = _validate_string(item, max_string_len) - if msg: - return msg +validate_list_of_unique_strings = functools.partial(_validate_list_of_items, + _validate_string) def _validate_boolean(data, valid_values=None): @@ -347,23 +352,6 @@ def _validate_subnet(data, valid_values=None): return msg -def _validate_subnet_list(data, valid_values=None): - if not isinstance(data, list): - msg = _("'%s' is not a list") % data - LOG.debug(msg) - return msg - - if len(set(data)) != len(data): - msg = _("Duplicate items in the list: '%s'") % ', '.join(data) - LOG.debug(msg) - return msg - - for item in data: - msg = _validate_subnet(item) - if msg: - return msg - - def _validate_subnet_or_none(data, valid_values=None): if data is not None: return _validate_subnet(data, valid_values) @@ -408,23 +396,6 @@ def _validate_uuid_or_none(data, valid_values=None): return _validate_uuid(data) -def _validate_uuid_list(data, valid_values=None): - if not isinstance(data, list): - msg = _("'%s' is not a list") % data - LOG.debug(msg) - return msg - - for item in data: - msg = _validate_uuid(item) - if msg: - return msg - - if len(set(data)) != len(data): - msg = _("Duplicate items in the list: '%s'") % ', '.join(data) - LOG.debug(msg) - return msg - - def _validate_dict_item(key, key_validator, data): # Find conversion function, if any, and apply it conv_func = key_validator.get('convert_to') @@ -640,13 +611,15 @@ validators = {'type:dict': _validate_dict, 'type:not_empty_string_or_none': _validate_not_empty_string_or_none, 'type:subnet': _validate_subnet, - 'type:subnet_list': _validate_subnet_list, + 'type:subnet_list': functools.partial(_validate_list_of_items, + _validate_subnet), 'type:subnet_or_none': _validate_subnet_or_none, 'type:subnetpool_id': _validate_subnetpool_id, 'type:subnetpool_id_or_none': _validate_subnetpool_id_or_none, 'type:uuid': _validate_uuid, 'type:uuid_or_none': _validate_uuid_or_none, - 'type:uuid_list': _validate_uuid_list, + 'type:uuid_list': functools.partial(_validate_list_of_items, + _validate_uuid), 'type:values': _validate_values, 'type:boolean': _validate_boolean, 'type:list_of_unique_strings': validate_list_of_unique_strings} diff --git a/neutron/tests/unit/api/v2/test_attributes.py b/neutron/tests/unit/api/v2/test_attributes.py index 4401566f6..96ac017c4 100644 --- a/neutron/tests/unit/api/v2/test_attributes.py +++ b/neutron/tests/unit/api/v2/test_attributes.py @@ -610,54 +610,47 @@ class TestAttributes(base.BaseTestCase): allow_none=True) def test_validate_uuid(self): - msg = attributes._validate_uuid('garbage') - self.assertEqual("'garbage' is not a valid UUID", msg) + invalid_uuids = [None, + 123, + '123', + 't5069610-744b-42a7-8bd8-ceac1a229cd4', + 'e5069610-744bb-42a7-8bd8-ceac1a229cd4'] + for uuid in invalid_uuids: + msg = attributes._validate_uuid(uuid) + error = "'%s' is not a valid UUID" % uuid + self.assertEqual(error, msg) msg = attributes._validate_uuid('00000000-ffff-ffff-ffff-000000000000') self.assertIsNone(msg) - def test_validate_uuid_list(self): + def test__validate_list_of_items(self): # check not a list - uuids = [None, + items = [None, 123, 'e5069610-744b-42a7-8bd8-ceac1a229cd4', '12345678123456781234567812345678', {'uuid': 'e5069610-744b-42a7-8bd8-ceac1a229cd4'}] - for uuid in uuids: - msg = attributes._validate_uuid_list(uuid) - error = "'%s' is not a list" % uuid - self.assertEqual(error, msg) - - # check invalid uuid in a list - invalid_uuid_lists = [[None], - [123], - [123, 'e5069610-744b-42a7-8bd8-ceac1a229cd4'], - ['123', '12345678123456781234567812345678'], - ['t5069610-744b-42a7-8bd8-ceac1a229cd4'], - ['e5069610-744b-42a7-8bd8-ceac1a229cd44'], - ['e50696100-744b-42a7-8bd8-ceac1a229cd4'], - ['e5069610-744bb-42a7-8bd8-ceac1a229cd4']] - for uuid_list in invalid_uuid_lists: - msg = attributes._validate_uuid_list(uuid_list) - error = "'%s' is not a valid UUID" % uuid_list[0] + for item in items: + msg = attributes._validate_list_of_items(mock.Mock(), item) + error = "'%s' is not a list" % item self.assertEqual(error, msg) # check duplicate items in a list - duplicate_uuids = ['e5069610-744b-42a7-8bd8-ceac1a229cd4', + duplicate_items = ['e5069610-744b-42a7-8bd8-ceac1a229cd4', 'f3eeab00-8367-4524-b662-55e64d4cacb5', 'e5069610-744b-42a7-8bd8-ceac1a229cd4'] - msg = attributes._validate_uuid_list(duplicate_uuids) + msg = attributes._validate_list_of_items(mock.Mock(), duplicate_items) error = ("Duplicate items in the list: " - "'%s'" % ', '.join(duplicate_uuids)) + "'%s'" % ', '.join(duplicate_items)) self.assertEqual(error, msg) - # check valid uuid lists - valid_uuid_lists = [['e5069610-744b-42a7-8bd8-ceac1a229cd4'], - ['f3eeab00-8367-4524-b662-55e64d4cacb5'], - ['e5069610-744b-42a7-8bd8-ceac1a229cd4', - 'f3eeab00-8367-4524-b662-55e64d4cacb5']] - for uuid_list in valid_uuid_lists: - msg = attributes._validate_uuid_list(uuid_list) + # check valid lists + valid_lists = [[], + [1, 2, 3], + ['a', 'b', 'c']] + for list_obj in valid_lists: + msg = attributes._validate_list_of_items( + mock.Mock(return_value=None), list_obj) self.assertIsNone(msg) def test_validate_dict_type(self): -- 2.45.2