diff --git a/monasca_common/tests/validation/test_metric_validation.py b/monasca_common/tests/validation/test_metric_validation.py index 81e0976e..e5bfbd61 100644 --- a/monasca_common/tests/validation/test_metric_validation.py +++ b/monasca_common/tests/validation/test_metric_validation.py @@ -281,6 +281,21 @@ class TestMetricValidation(base.BaseTestCase): value, metric_validator.validate, metric) + def test_invalid_value_includes_metric(self): + """When it fails, does it include the metric name in the ex?""" + metric = {"name": "test_metric_name", + "dimensions": {"key1": "value1", + "key2": "value2"}, + "timestamp": 1405630174123, + "value": None} + + for value in ('nan', 'inf', '-inf'): + metric['value'] = float(value) + self.assertRaisesRegex( + metric_validator.InvalidValue, + "for metric test_metric_name", + metric_validator.validate, metric) + def test_valid_name_chars(self): for c in valid_name_chars: metric = {"name": 'test{}counter'.format(c), @@ -335,7 +350,7 @@ class TestMetricValidation(base.BaseTestCase): def test_invalid_too_many_value_meta(self): value_meta = {} - for i in six.moves.range(0, 17): + for i in six.moves.range(0, metric_validator.VALUE_META_MAX_NUMBER + 3): value_meta['key{}'.format(i)] = 'value{}'.format(i) metric = {"name": "test_metric_name", "dimensions": {"key1": "value1", @@ -393,8 +408,9 @@ class TestMetricValidation(base.BaseTestCase): "value": 5} self.assertRaisesRegex( metric_validator.InvalidValueMeta, - "Unable to serialize valueMeta into JSON", + "value combinations must be", metric_validator.validate, metric) + # TODO: what would make ujson.dumps fail? def test_invalid_timestamp(self): metric = {'name': 'test_metric_name', diff --git a/monasca_common/validation/metrics.py b/monasca_common/validation/metrics.py index 816f9121..e75bc9b4 100644 --- a/monasca_common/validation/metrics.py +++ b/monasca_common/validation/metrics.py @@ -17,6 +17,7 @@ import math import re import six +import sys import ujson # This is used to ensure that metrics with a timestamp older than @@ -77,12 +78,17 @@ def validate(metrics): def validate_metric(metric): validate_name(metric['name']) - validate_value(metric['value']) - validate_timestamp(metric['timestamp']) - if "dimensions" in metric: - validate_dimensions(metric['dimensions']) - if "value_meta" in metric: - validate_value_meta(metric['value_meta']) + try: + validate_value(metric['value']) + validate_timestamp(metric['timestamp']) + if "dimensions" in metric: + validate_dimensions(metric['dimensions']) + if "value_meta" in metric: + validate_value_meta(metric['value_meta']) + except Exception as ex: + six.reraise(type(ex), + type(ex)(str(ex) + ": for metric %s" % metric['name']), + sys.exc_info()[2]) def validate_value_meta(value_meta): @@ -103,13 +109,13 @@ def validate_value_meta(value_meta): try: value_meta_json = ujson.dumps(value_meta) - if len(value_meta_json) > VALUE_META_VALUE_MAX_LENGTH: - msg = "valueMeta name value combinations must be {0} characters " \ - "or less: valueMeta {1}".format(VALUE_META_VALUE_MAX_LENGTH, - value_meta) - raise InvalidValueMeta(msg) except Exception: raise InvalidValueMeta("Unable to serialize valueMeta into JSON") + if len(value_meta_json) > VALUE_META_VALUE_MAX_LENGTH: + msg = "valueMeta name value combinations must be {0} characters " \ + "or less: valueMeta {1}".format(VALUE_META_VALUE_MAX_LENGTH, + value_meta) + raise InvalidValueMeta(msg) def validate_dimension_key(k):