Add check for restricted characters
Remove placeholder test Adjust flake8 settings Add new mock requirements to test-requirements.txt Change-Id: I8f58341108710b1bc7431154cda096d6583d1ef3
This commit is contained in:
parent
5377aa6cb0
commit
9607e1aabd
@ -1,21 +0,0 @@
|
||||
# Copyright 2014 Hewlett-Packard
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import unittest
|
||||
|
||||
|
||||
class Test_first(unittest.TestCase):
|
||||
|
||||
def test_first(self):
|
||||
assert 1 == 1
|
86
monasca_api/tests/test_validation.py
Normal file
86
monasca_api/tests/test_validation.py
Normal file
@ -0,0 +1,86 @@
|
||||
# Copyright 2015 Hewlett-Packard
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import monasca_api.v2.common.validation as validation
|
||||
|
||||
import unittest
|
||||
|
||||
invalid_chars = "<>={}(),'\"\\;&"
|
||||
|
||||
|
||||
class TestMetricNameValidation(unittest.TestCase):
|
||||
def test_valid_name(self):
|
||||
metric_name = "this.is_a.valid-name"
|
||||
validation.metric_name(metric_name)
|
||||
self.assertTrue(True)
|
||||
|
||||
def test_nonstring_name(self):
|
||||
metric_name = 123456789
|
||||
self.assertRaises(AssertionError, validation.metric_name, metric_name)
|
||||
|
||||
def test_long_name(self):
|
||||
metric_name = ("abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz"
|
||||
"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz"
|
||||
"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz"
|
||||
"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz")
|
||||
self.assertRaises(AssertionError, validation.metric_name, metric_name)
|
||||
|
||||
def test_invalid_chars(self):
|
||||
for c in invalid_chars:
|
||||
metric_name = "this{}that".format(c)
|
||||
self.assertRaises(AssertionError, validation.metric_name, metric_name)
|
||||
|
||||
|
||||
class TestDimensionValidation(unittest.TestCase):
|
||||
def test_valid_key(self):
|
||||
dim_key = "this.is_a.valid-key"
|
||||
validation.dimension_key(dim_key)
|
||||
self.assertTrue(True)
|
||||
|
||||
def test_nonstring_key(self):
|
||||
dim_key = 123456
|
||||
self.assertRaises(AssertionError, validation.dimension_key, dim_key)
|
||||
|
||||
def test_long_key(self):
|
||||
dim_key = ("abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz"
|
||||
"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz"
|
||||
"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz"
|
||||
"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz")
|
||||
self.assertRaises(AssertionError, validation.dimension_key, dim_key)
|
||||
|
||||
def test_invalid_chars_key(self):
|
||||
for c in invalid_chars:
|
||||
dim_key = "this{}that".format(c)
|
||||
self.assertRaises(AssertionError, validation.dimension_key, dim_key)
|
||||
|
||||
def test_valid_value(self):
|
||||
dim_value = "this.is_a.valid-value"
|
||||
validation.dimension_value(dim_value)
|
||||
self.assertTrue(True)
|
||||
|
||||
def test_nonstring_value(self):
|
||||
dim_value = None
|
||||
self.assertRaises(AssertionError, validation.dimension_value, dim_value)
|
||||
|
||||
def test_long_value(self):
|
||||
dim_value = ("abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz"
|
||||
"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz"
|
||||
"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz"
|
||||
"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz")
|
||||
self.assertRaises(AssertionError, validation.dimension_value, dim_value)
|
||||
|
||||
def test_invalid_chars_value(self):
|
||||
for c in invalid_chars:
|
||||
dim_value = "this{}that".format(c)
|
||||
self.assertRaises(AssertionError, validation.dimension_value, dim_value)
|
36
monasca_api/v2/common/validation.py
Normal file
36
monasca_api/v2/common/validation.py
Normal file
@ -0,0 +1,36 @@
|
||||
# Copyright 2015 Hewlett-Packard
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import re
|
||||
|
||||
invalid_chars = "<>={}(),'\"\\\\;&"
|
||||
restricted_chars = re.compile('[' + invalid_chars + ']')
|
||||
|
||||
|
||||
def metric_name(name):
|
||||
assert isinstance(name, (str, unicode)), "Metric name must be a string"
|
||||
assert len(name) <= 255, "Metric name must be 255 characters or less"
|
||||
assert not restricted_chars.search(name), "Invalid characters in metric name " + name
|
||||
|
||||
|
||||
def dimension_key(dkey):
|
||||
assert isinstance(dkey, (str, unicode)), "Dimension key must be a string"
|
||||
assert len(dkey) <= 255, "Dimension key must be 255 characters or less"
|
||||
assert not restricted_chars.search(dkey), "Invalid characters in dimension name " + dkey
|
||||
|
||||
|
||||
def dimension_value(value):
|
||||
assert isinstance(value, (str, unicode)), "Dimension value must be a string"
|
||||
assert len(value) <= 255, "Dimension value must be 255 characters or less"
|
||||
assert not restricted_chars.search(value), "Invalid characters in dimension value " + value
|
@ -25,7 +25,7 @@ from monasca_api.common.repositories import exceptions
|
||||
import monasca_api.expression_parser.alarm_expr_parser
|
||||
from monasca_api.v2.common.schemas import (
|
||||
alarm_definition_request_body_schema as schema_alarms)
|
||||
from monasca_api.v2.common.schemas import exceptions as schemas_exceptions
|
||||
from monasca_api.v2.common import validation
|
||||
from monasca_api.v2.reference import alarming
|
||||
from monasca_api.v2.reference import helpers
|
||||
from monasca_api.v2.reference import resource
|
||||
@ -316,7 +316,11 @@ class AlarmDefinitions(alarm_definitions_api_v2.AlarmDefinitionsV2API,
|
||||
|
||||
try:
|
||||
schema_alarms.validate(alarm_definition)
|
||||
except schemas_exceptions.ValidationException as ex:
|
||||
if 'match_by' in alarm_definition:
|
||||
for name in alarm_definition['match_by']:
|
||||
validation.dimension_key(name)
|
||||
|
||||
except Exception as ex:
|
||||
LOG.debug(ex)
|
||||
raise falcon.HTTPBadRequest('Bad request', ex.message)
|
||||
|
||||
|
@ -22,6 +22,7 @@ from monasca_api.common.messaging import (
|
||||
exceptions as message_queue_exceptions)
|
||||
from monasca_api.common.messaging.message_formats import (
|
||||
metrics as metrics_message)
|
||||
from monasca_api.v2.common import validation
|
||||
from monasca_api.v2.reference import helpers
|
||||
from monasca_api.v2.reference import resource
|
||||
|
||||
@ -80,16 +81,13 @@ class Metrics(metrics_api_v2.MetricsV2API):
|
||||
raise falcon.HTTPBadRequest('Bad request', ex.message)
|
||||
|
||||
def _validate_single_metric(self, metric):
|
||||
assert isinstance(metric['name'], (str, unicode))
|
||||
assert len(metric['name']) <= 64
|
||||
assert isinstance(metric['timestamp'], (int, float))
|
||||
assert isinstance(metric['value'], (int, long, float, complex))
|
||||
validation.metric_name(metric['name'])
|
||||
assert isinstance(metric['timestamp'], (int, float)), "Timestamp must be a number"
|
||||
assert isinstance(metric['value'], (int, long, float, complex)), "Value must be a number"
|
||||
if "dimensions" in metric:
|
||||
for d in metric['dimensions']:
|
||||
assert isinstance(d, (str, unicode))
|
||||
assert len(d) <= 255
|
||||
assert isinstance(metric['dimensions'][d], (str, unicode))
|
||||
assert len(metric['dimensions'][d]) <= 255
|
||||
for dimension_key in metric['dimensions']:
|
||||
validation.dimension_key(dimension_key)
|
||||
validation.dimension_value(metric['dimensions'][dimension_key])
|
||||
|
||||
def _send_metrics(self, metrics):
|
||||
|
||||
|
@ -8,6 +8,7 @@ flake8==2.1.0
|
||||
pep8<=1.5.6
|
||||
httplib2>=0.7.5
|
||||
mock>=1.0
|
||||
funcsigs
|
||||
mox>=0.5.3
|
||||
nose
|
||||
# Docs Requirements
|
||||
|
9
tox.ini
9
tox.ini
@ -30,6 +30,15 @@ commands = python setup.py build_sphinx
|
||||
commands = {posargs}
|
||||
|
||||
[flake8]
|
||||
max-line-length = 120
|
||||
# TODO: ignored checks should be enabled in the future
|
||||
# H201 no 'except:' at least use 'except Exception:'
|
||||
# H302 import only modules
|
||||
# H305 imports not grouped correctly
|
||||
# H307 like imports should be grouped together
|
||||
# H405 multi line docstring summary not separated with an empty line
|
||||
# H904 Wrap long lines in parentheses instead of a backslash
|
||||
ignore = F821,H201,H302,H305,H307,H405,H904
|
||||
builtins = _
|
||||
exclude=.venv,.git,.tox,dist,doc,./monasca_api/openstack/common,*lib/python*,*egg,tools,build
|
||||
show-source = True
|
||||
|
Loading…
Reference in New Issue
Block a user