Adding invalid_property attr to support test code
Moving all base class calls to first line Adding invalid_property to InvalidObject exception and invalid_field to UnsupportedField exception. Modified test code to check these attributes instead of checking the exception message string. Also updating NewOrderValidator and VerificationValidator per bug #1246871 Change-Id: I0776d4a33652ec28c713037c2ef49e35c9b39e54 Implements: blueprint validation-improve-err-msgs
This commit is contained in:
parent
9dc1c17058
commit
e51ca90944
@ -40,6 +40,7 @@ class BarbicanException(Exception):
|
||||
message = _("An unknown exception occurred")
|
||||
|
||||
def __init__(self, message=None, *args, **kwargs):
|
||||
super(BarbicanException, self).__init__(message)
|
||||
if not message:
|
||||
message = self.message
|
||||
try:
|
||||
@ -51,8 +52,6 @@ class BarbicanException(Exception):
|
||||
# at least get the core message out if something happened
|
||||
pass
|
||||
|
||||
super(BarbicanException, self).__init__(message)
|
||||
|
||||
|
||||
class MissingArgumentError(BarbicanException):
|
||||
message = _("Missing required argument.")
|
||||
@ -180,9 +179,9 @@ class LimitExceeded(BarbicanException):
|
||||
"breached.\n\nThe response body:\n%(body)s")
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(LimitExceeded, self).__init__(*args, **kwargs)
|
||||
self.retry_after = (int(kwargs['retry']) if kwargs.get('retry')
|
||||
else None)
|
||||
super(LimitExceeded, self).__init__(*args, **kwargs)
|
||||
|
||||
|
||||
class ServiceUnavailable(BarbicanException):
|
||||
@ -191,9 +190,9 @@ class ServiceUnavailable(BarbicanException):
|
||||
"outage.")
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(ServiceUnavailable, self).__init__(*args, **kwargs)
|
||||
self.retry_after = (int(kwargs['retry']) if kwargs.get('retry')
|
||||
else None)
|
||||
super(ServiceUnavailable, self).__init__(*args, **kwargs)
|
||||
|
||||
|
||||
class ServerError(BarbicanException):
|
||||
@ -275,11 +274,19 @@ class InvalidObject(BarbicanException):
|
||||
message = _("Provided object does not match schema "
|
||||
"'%(schema)s': %(reason)s")
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(InvalidObject, self).__init__(*args, **kwargs)
|
||||
self.invalid_property = kwargs.get('property')
|
||||
|
||||
|
||||
class UnsupportedField(BarbicanException):
|
||||
message = _("No support for value set on field '%(field)s' on "
|
||||
"schema '%(schema)s': %(reason)s")
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(UnsupportedField, self).__init__(*args, **kwargs)
|
||||
self.invalid_field = kwargs.get('field')
|
||||
|
||||
|
||||
class UnsupportedHeaderFeature(BarbicanException):
|
||||
message = _("Provided header feature is unsupported: %(feature)s")
|
||||
|
@ -29,6 +29,12 @@ def secret_too_big(data):
|
||||
return len(data.encode('utf-8')) > CONF.max_allowed_secret_in_bytes
|
||||
|
||||
|
||||
def get_invalid_property(validation_error):
|
||||
# we are interested in the second item which is the failed propertyName.
|
||||
if validation_error.schema_path and len(validation_error.schema_path) > 1:
|
||||
return validation_error.schema_path[1]
|
||||
|
||||
|
||||
class ValidatorBase(object):
|
||||
"""Base class for validators."""
|
||||
|
||||
@ -94,7 +100,9 @@ class NewSecretValidator(ValidatorBase):
|
||||
try:
|
||||
schema.validate(json_data, self.schema)
|
||||
except schema.ValidationError as e:
|
||||
raise exception.InvalidObject(schema=schema_name, reason=e.message)
|
||||
raise exception.InvalidObject(schema=schema_name,
|
||||
reason=e.message,
|
||||
property=get_invalid_property(e))
|
||||
|
||||
# Validate/normalize 'name'.
|
||||
name = json_data.get('name', '').strip()
|
||||
@ -110,7 +118,8 @@ class NewSecretValidator(ValidatorBase):
|
||||
if expiration <= utcnow:
|
||||
raise exception.InvalidObject(schema=schema_name,
|
||||
reason=_("'expiration' is "
|
||||
"before current time"))
|
||||
"before current time"),
|
||||
property="expiration")
|
||||
json_data['expiration'] = expiration
|
||||
|
||||
# Validate/convert 'payload' if provided.
|
||||
@ -120,7 +129,8 @@ class NewSecretValidator(ValidatorBase):
|
||||
raise exception.InvalidObject(
|
||||
schema=schema_name,
|
||||
reason=_("If 'payload' is supplied, 'payload_content_type'"
|
||||
" must also be supplied.")
|
||||
" must also be supplied."),
|
||||
property="payload_content_type"
|
||||
)
|
||||
|
||||
content_encoding = json_data.get('payload_content_encoding')
|
||||
@ -130,7 +140,8 @@ class NewSecretValidator(ValidatorBase):
|
||||
schema=schema_name,
|
||||
reason=_("payload_content_encoding must be specified "
|
||||
"when payload_content_type is application/"
|
||||
"octet-stream.")
|
||||
"octet-stream."),
|
||||
property="payload_content_encoding"
|
||||
)
|
||||
|
||||
if content_type.startswith('text/plain') and \
|
||||
@ -138,7 +149,8 @@ class NewSecretValidator(ValidatorBase):
|
||||
raise exception.InvalidObject(
|
||||
schema=schema_name,
|
||||
reason=_("payload_content_encoding must not be specified "
|
||||
"when payload_content_type is text/plain")
|
||||
"when payload_content_type is text/plain"),
|
||||
property="payload_content_encoding"
|
||||
)
|
||||
|
||||
payload = json_data['payload']
|
||||
@ -150,7 +162,8 @@ class NewSecretValidator(ValidatorBase):
|
||||
raise exception.InvalidObject(schema=schema_name,
|
||||
reason=_("If 'payload' "
|
||||
"specified, must be "
|
||||
"non empty"))
|
||||
"non empty"),
|
||||
property="payload")
|
||||
|
||||
json_data['payload'] = payload
|
||||
|
||||
@ -168,7 +181,8 @@ class NewSecretValidator(ValidatorBase):
|
||||
LOG.exception("Problem parsing expiration date")
|
||||
raise exception.InvalidObject(schema=schema_name,
|
||||
reason=_("Invalid date "
|
||||
"for 'expiration'"))
|
||||
"for 'expiration'"),
|
||||
property="expiration")
|
||||
|
||||
return expiration
|
||||
|
||||
@ -191,13 +205,15 @@ class NewOrderValidator(ValidatorBase):
|
||||
try:
|
||||
schema.validate(json_data, self.schema)
|
||||
except schema.ValidationError as e:
|
||||
raise exception.InvalidObject(schema=schema_name, reason=str(e))
|
||||
raise exception.InvalidObject(schema=schema_name, reason=e.message,
|
||||
property=get_invalid_property(e))
|
||||
|
||||
secret = json_data.get('secret')
|
||||
if secret is None:
|
||||
raise exception.InvalidObject(schema=schema_name,
|
||||
reason=_("'secret' attributes "
|
||||
"are required"))
|
||||
"are required"),
|
||||
property="secret")
|
||||
|
||||
# If secret group is provided, validate it now.
|
||||
self.secret_validator.validate(secret, parent_schema=self.name)
|
||||
@ -205,7 +221,8 @@ class NewOrderValidator(ValidatorBase):
|
||||
raise exception.InvalidObject(schema=schema_name,
|
||||
reason=_("'payload' not "
|
||||
"allowed for secret "
|
||||
"generation"))
|
||||
"generation"),
|
||||
property="secret")
|
||||
|
||||
# Validation secret generation related fields.
|
||||
# TODO: Invoke the crypto plugin for this purpose
|
||||
@ -279,6 +296,7 @@ class VerificationValidator(ValidatorBase):
|
||||
try:
|
||||
schema.validate(json_data, self.schema)
|
||||
except schema.ValidationError as e:
|
||||
raise exception.InvalidObject(schema=schema_name, reason=str(e))
|
||||
raise exception.InvalidObject(schema=schema_name, reason=e.message,
|
||||
property=get_invalid_property(e))
|
||||
|
||||
return json_data
|
||||
|
@ -123,29 +123,34 @@ class WhenTestingSecretValidator(unittest.TestCase):
|
||||
def test_should_fail_numeric_name(self):
|
||||
self.secret_req['name'] = 123
|
||||
|
||||
with self.assertRaises(excep.InvalidObject):
|
||||
with self.assertRaises(excep.InvalidObject) as e:
|
||||
self.validator.validate(self.secret_req)
|
||||
|
||||
self.assertEqual('name', e.exception.invalid_property)
|
||||
|
||||
def test_should_fail_negative_bit_length(self):
|
||||
self.secret_req['bit_length'] = -23
|
||||
|
||||
with self.assertRaises(excep.InvalidObject):
|
||||
with self.assertRaises(excep.InvalidObject) as e:
|
||||
self.validator.validate(self.secret_req)
|
||||
|
||||
self.assertEqual('bit_length', e.exception.invalid_property)
|
||||
|
||||
def test_should_fail_non_integer_bit_length(self):
|
||||
self.secret_req['bit_length'] = "23"
|
||||
|
||||
with self.assertRaises(excep.InvalidObject):
|
||||
with self.assertRaises(excep.InvalidObject) as e:
|
||||
self.validator.validate(self.secret_req)
|
||||
|
||||
self.assertEqual('bit_length', e.exception.invalid_property)
|
||||
|
||||
def test_validation_should_fail_with_empty_payload(self):
|
||||
self.secret_req['payload'] = ' '
|
||||
|
||||
with self.assertRaises(excep.InvalidObject) as e:
|
||||
self.validator.validate(self.secret_req)
|
||||
|
||||
exception = e.exception
|
||||
self.assertTrue('payload' in str(exception))
|
||||
self.assertEqual('payload', e.exception.invalid_property)
|
||||
|
||||
def test_should_fail_already_expired(self):
|
||||
self.secret_req['expiration'] = '2004-02-28T19:14:44.180394'
|
||||
@ -153,8 +158,7 @@ class WhenTestingSecretValidator(unittest.TestCase):
|
||||
with self.assertRaises(excep.InvalidObject) as e:
|
||||
self.validator.validate(self.secret_req)
|
||||
|
||||
exception = e.exception
|
||||
self.assertTrue('expiration' in str(exception))
|
||||
self.assertEqual('expiration', e.exception.invalid_property)
|
||||
|
||||
def test_should_fail_expiration_nonsense(self):
|
||||
self.secret_req['expiration'] = 'nonsense'
|
||||
@ -162,8 +166,7 @@ class WhenTestingSecretValidator(unittest.TestCase):
|
||||
with self.assertRaises(excep.InvalidObject) as e:
|
||||
self.validator.validate(self.secret_req)
|
||||
|
||||
exception = e.exception
|
||||
self.assertTrue('expiration' in str(exception))
|
||||
self.assertEqual('expiration', e.exception.invalid_property)
|
||||
|
||||
def test_should_fail_all_nulls(self):
|
||||
self.secret_req = {'name': None,
|
||||
@ -264,45 +267,48 @@ class WhenTestingOrderValidator(unittest.TestCase):
|
||||
def test_should_fail_numeric_name(self):
|
||||
self.secret_req['name'] = 123
|
||||
|
||||
with self.assertRaises(excep.InvalidObject):
|
||||
with self.assertRaises(excep.InvalidObject) as e:
|
||||
self.validator.validate(self.order_req)
|
||||
|
||||
self.assertEqual('name', e.exception.invalid_property)
|
||||
|
||||
def test_should_fail_bad_mode(self):
|
||||
self.secret_req['mode'] = 'badmode'
|
||||
|
||||
with self.assertRaises(excep.UnsupportedField) as e:
|
||||
self.validator.validate(self.order_req)
|
||||
|
||||
exception = e.exception
|
||||
self.assertTrue('mode' in str(exception))
|
||||
self.assertEqual('mode', e.exception.invalid_field)
|
||||
|
||||
def test_should_fail_negative_bit_length(self):
|
||||
self.secret_req['bit_length'] = -23
|
||||
|
||||
with self.assertRaises(excep.InvalidObject):
|
||||
with self.assertRaises(excep.InvalidObject) as e:
|
||||
self.validator.validate(self.order_req)
|
||||
|
||||
self.assertEqual('bit_length', e.exception.invalid_property)
|
||||
|
||||
def test_should_fail_non_integer_bit_length(self):
|
||||
self.secret_req['bit_length'] = "23"
|
||||
|
||||
with self.assertRaises(excep.InvalidObject):
|
||||
with self.assertRaises(excep.InvalidObject) as e:
|
||||
self.validator.validate(self.order_req)
|
||||
|
||||
self.assertEqual('bit_length', e.exception.invalid_property)
|
||||
|
||||
def test_should_fail_non_multiple_eight_bit_length(self):
|
||||
self.secret_req['bit_length'] = 129
|
||||
|
||||
with self.assertRaises(excep.UnsupportedField) as e:
|
||||
self.validator.validate(self.order_req)
|
||||
|
||||
exception = e.exception
|
||||
self.assertTrue('bit_length' in str(exception))
|
||||
self.assertEqual('bit_length', e.exception.invalid_field)
|
||||
|
||||
def test_should_fail_secret_not_order_schema_provided(self):
|
||||
with self.assertRaises(excep.InvalidObject) as e:
|
||||
self.validator.validate(self.secret_req)
|
||||
|
||||
exception = e.exception
|
||||
self.assertTrue('secret' in str(exception))
|
||||
self.assertEqual('secret', e.exception.invalid_property)
|
||||
|
||||
def test_should_fail_payload_provided(self):
|
||||
self.secret_req['payload'] = ' '
|
||||
@ -310,8 +316,7 @@ class WhenTestingOrderValidator(unittest.TestCase):
|
||||
with self.assertRaises(excep.InvalidObject) as e:
|
||||
self.validator.validate(self.order_req)
|
||||
|
||||
exception = e.exception
|
||||
self.assertTrue('payload' in str(exception))
|
||||
self.assertTrue('payload' in e.exception.invalid_property)
|
||||
|
||||
def test_should_fail_already_expired(self):
|
||||
self.secret_req['expiration'] = '2004-02-28T19:14:44.180394'
|
||||
@ -319,8 +324,7 @@ class WhenTestingOrderValidator(unittest.TestCase):
|
||||
with self.assertRaises(excep.InvalidObject) as e:
|
||||
self.validator.validate(self.order_req)
|
||||
|
||||
exception = e.exception
|
||||
self.assertTrue('expiration' in str(exception))
|
||||
self.assertEqual('expiration', e.exception.invalid_property)
|
||||
|
||||
def test_should_fail_expiration_nonsense(self):
|
||||
self.secret_req['expiration'] = 'nonsense'
|
||||
@ -328,8 +332,7 @@ class WhenTestingOrderValidator(unittest.TestCase):
|
||||
with self.assertRaises(excep.InvalidObject) as e:
|
||||
self.validator.validate(self.order_req)
|
||||
|
||||
exception = e.exception
|
||||
self.assertTrue('expiration' in str(exception))
|
||||
self.assertEqual('expiration', e.exception.invalid_property)
|
||||
|
||||
def test_should_fail_all_nulls(self):
|
||||
self.secret_req = {'name': None,
|
||||
@ -369,8 +372,7 @@ class WhenTestingOrderValidator(unittest.TestCase):
|
||||
with self.assertRaises(excep.UnsupportedField) as e:
|
||||
self.validator.validate(self.order_req)
|
||||
|
||||
exception = e.exception
|
||||
self.assertTrue('mode' in str(exception))
|
||||
self.assertEqual('mode', e.exception.invalid_field)
|
||||
|
||||
def test_should_fail_empty_algorithm(self):
|
||||
del self.secret_req['algorithm']
|
||||
@ -378,8 +380,7 @@ class WhenTestingOrderValidator(unittest.TestCase):
|
||||
with self.assertRaises(excep.UnsupportedField) as e:
|
||||
self.validator.validate(self.order_req)
|
||||
|
||||
exception = e.exception
|
||||
self.assertTrue('algorithm' in str(exception))
|
||||
self.assertEqual('algorithm', e.exception.invalid_field)
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
Loading…
x
Reference in New Issue
Block a user