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
|
|
|
@ -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)
|
|
@ -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
|
import monasca_api.expression_parser.alarm_expr_parser
|
||||||
from monasca_api.v2.common.schemas import (
|
from monasca_api.v2.common.schemas import (
|
||||||
alarm_definition_request_body_schema as schema_alarms)
|
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 alarming
|
||||||
from monasca_api.v2.reference import helpers
|
from monasca_api.v2.reference import helpers
|
||||||
from monasca_api.v2.reference import resource
|
from monasca_api.v2.reference import resource
|
||||||
|
@ -316,7 +316,11 @@ class AlarmDefinitions(alarm_definitions_api_v2.AlarmDefinitionsV2API,
|
||||||
|
|
||||||
try:
|
try:
|
||||||
schema_alarms.validate(alarm_definition)
|
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)
|
LOG.debug(ex)
|
||||||
raise falcon.HTTPBadRequest('Bad request', ex.message)
|
raise falcon.HTTPBadRequest('Bad request', ex.message)
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,7 @@ from monasca_api.common.messaging import (
|
||||||
exceptions as message_queue_exceptions)
|
exceptions as message_queue_exceptions)
|
||||||
from monasca_api.common.messaging.message_formats import (
|
from monasca_api.common.messaging.message_formats import (
|
||||||
metrics as metrics_message)
|
metrics as metrics_message)
|
||||||
|
from monasca_api.v2.common import validation
|
||||||
from monasca_api.v2.reference import helpers
|
from monasca_api.v2.reference import helpers
|
||||||
from monasca_api.v2.reference import resource
|
from monasca_api.v2.reference import resource
|
||||||
|
|
||||||
|
@ -80,16 +81,13 @@ class Metrics(metrics_api_v2.MetricsV2API):
|
||||||
raise falcon.HTTPBadRequest('Bad request', ex.message)
|
raise falcon.HTTPBadRequest('Bad request', ex.message)
|
||||||
|
|
||||||
def _validate_single_metric(self, metric):
|
def _validate_single_metric(self, metric):
|
||||||
assert isinstance(metric['name'], (str, unicode))
|
validation.metric_name(metric['name'])
|
||||||
assert len(metric['name']) <= 64
|
assert isinstance(metric['timestamp'], (int, float)), "Timestamp must be a number"
|
||||||
assert isinstance(metric['timestamp'], (int, float))
|
assert isinstance(metric['value'], (int, long, float, complex)), "Value must be a number"
|
||||||
assert isinstance(metric['value'], (int, long, float, complex))
|
|
||||||
if "dimensions" in metric:
|
if "dimensions" in metric:
|
||||||
for d in metric['dimensions']:
|
for dimension_key in metric['dimensions']:
|
||||||
assert isinstance(d, (str, unicode))
|
validation.dimension_key(dimension_key)
|
||||||
assert len(d) <= 255
|
validation.dimension_value(metric['dimensions'][dimension_key])
|
||||||
assert isinstance(metric['dimensions'][d], (str, unicode))
|
|
||||||
assert len(metric['dimensions'][d]) <= 255
|
|
||||||
|
|
||||||
def _send_metrics(self, metrics):
|
def _send_metrics(self, metrics):
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@ flake8==2.1.0
|
||||||
pep8<=1.5.6
|
pep8<=1.5.6
|
||||||
httplib2>=0.7.5
|
httplib2>=0.7.5
|
||||||
mock>=1.0
|
mock>=1.0
|
||||||
|
funcsigs
|
||||||
mox>=0.5.3
|
mox>=0.5.3
|
||||||
nose
|
nose
|
||||||
# Docs Requirements
|
# Docs Requirements
|
||||||
|
|
9
tox.ini
9
tox.ini
|
@ -30,6 +30,15 @@ commands = python setup.py build_sphinx
|
||||||
commands = {posargs}
|
commands = {posargs}
|
||||||
|
|
||||||
[flake8]
|
[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 = _
|
builtins = _
|
||||||
exclude=.venv,.git,.tox,dist,doc,./monasca_api/openstack/common,*lib/python*,*egg,tools,build
|
exclude=.venv,.git,.tox,dist,doc,./monasca_api/openstack/common,*lib/python*,*egg,tools,build
|
||||||
show-source = True
|
show-source = True
|
||||||
|
|
Loading…
Reference in New Issue