Merge "Make `is_valid` more flexible with uuid validation"

This commit is contained in:
Jenkins 2017-02-17 18:06:41 +00:00 committed by Gerrit Code Review
commit e813a4de5a
2 changed files with 83 additions and 8 deletions

View File

@ -12,6 +12,7 @@
# License for the specific language governing permissions and limitations under
# the License.
import hashlib
import re
import uuid
import warnings
@ -33,6 +34,8 @@ if CONF.audit.namespace:
md5_hash = hashlib.md5(CONF.audit.namespace.encode('utf-8'))
AUDIT_NS = uuid.UUID(md5_hash.hexdigest())
VALID_EXCEPTIONS = ['default', 'initiator', 'observer', 'target']
def generate_uuid():
"""Generate a CADF identifier."""
@ -48,15 +51,31 @@ def norm_ns(str_id):
return prefix + str_id
def _check_valid_uuid(value):
"""Checks a value for one or multiple valid uuids joined together."""
if not value:
raise ValueError
value = re.sub('[{}-]|urn:uuid:', '', value)
for val in [value[i:i + 32] for i in range(0, len(value), 32)]:
uuid.UUID(val)
def is_valid(value):
"""Validation to ensure Identifier is correct."""
if value in ['target', 'initiator', 'observer']:
"""Validation to ensure Identifier is correct.
If the Identifier value is a string type but not a valid UUID string,
warn against interoperability issues and return True. This relaxes
the requirement of having strict UUID checking.
"""
if value in VALID_EXCEPTIONS:
return True
try:
uuid.UUID(value)
_check_valid_uuid(value)
except (ValueError, TypeError):
if not isinstance(value, six.string_types) or not value:
return False
warnings.warn('Invalid uuid. To ensure interoperability, identifiers '
'should be a valid uuid.')
warnings.warn(('Invalid uuid: %s. To ensure interoperability, '
'identifiers should be a valid uuid.' % (value)))
return True

View File

@ -38,16 +38,72 @@ from pycadf import timestamp
class TestCADFSpec(base.TestCase):
@mock.patch('pycadf.identifier.warnings.warn')
def test_identifier(self, warning_mock):
# empty string
self.assertFalse(identifier.is_valid(''))
def test_identifier_generated_uuid(self, warning_mock):
# generated uuid
self.assertTrue(identifier.is_valid(identifier.generate_uuid()))
self.assertFalse(warning_mock.called)
@mock.patch('pycadf.identifier.warnings.warn')
def test_identifier_empty_string_is_invalid(self, warning_mock):
# empty string
self.assertFalse(identifier.is_valid(''))
self.assertFalse(warning_mock.called)
@mock.patch('pycadf.identifier.warnings.warn')
def test_identifier_any_string_is_invalid(self, warning_mock):
# any string
self.assertTrue(identifier.is_valid('blah'))
self.assertTrue(warning_mock.called)
@mock.patch('pycadf.identifier.warnings.warn')
def test_identifier_joined_uuids_are_valid(self, warning_mock):
# multiple uuids joined together
long_128_uuids = [
('3adce28e67e44544a5a9d5f1ab54f578a86d310aac3a465e9d'
'd2693a78b45c0e42dce28e67e44544a5a9d5f1ab54f578a86d'
'310aac3a465e9dd2693a78b45c0e'),
('{3adce28e67e44544a5a9d5f1ab54f578a86d310aac3a465e9d'
'd2693a78b45c0e42dce28e67e44544a5a9d5f1ab54f578a86d'
'310aac3a465e9dd2693a78b45c0e}'),
('{12345678-1234-5678-1234-567812345678'
'12345678-1234-5678-1234-567812345678'
'12345678-1234-5678-1234-567812345678'
'12345678-1234-5678-1234-567812345678}'),
('urn:uuid:3adce28e67e44544a5a9d5f1ab54f578a86d310aac3a465e9d'
'd2693a78b45c0e42dce28e67e44544a5a9d5f1ab54f578a86d'
'310aac3a465e9dd2693a78b45c0e')]
for value in long_128_uuids:
self.assertTrue(identifier.is_valid(value))
self.assertFalse(warning_mock.called)
@mock.patch('pycadf.identifier.warnings.warn')
def test_identifier_long_nonjoined_uuid_is_invalid(self, warning_mock):
# long uuid not of size % 32
char_42_id = '3adce28e67e44544a5a9d5f1ab54f578a86d310aac'
self.assertTrue(identifier.is_valid(char_42_id))
self.assertTrue(warning_mock.called)
@mock.patch('pycadf.identifier.warnings.warn')
def test_identifier_specific_exceptions_are_valid(self, warning_mock):
# uuid exceptions
for value in identifier.VALID_EXCEPTIONS:
self.assertTrue(identifier.is_valid(value))
self.assertFalse(warning_mock.called)
@mock.patch('pycadf.identifier.warnings.warn')
def test_identifier_valid_id_extra_chars_is_valid(self, warning_mock):
# valid uuid with additional characters according to:
# https://docs.python.org/2/library/uuid.html
valid_ids = [
'{1234567890abcdef1234567890abcdef}',
'{12345678-1234-5678-1234-567812345678}',
'urn:uuid:12345678-1234-5678-1234-567812345678']
for value in valid_ids:
self.assertTrue(identifier.is_valid(value))
self.assertFalse(warning_mock.called)
def test_endpoint(self):
endp = endpoint.Endpoint(url='http://192.168.0.1',
name='endpoint name',