Bugfix: Forbid colon in dimension name

Monasca-Agent http_check plugin creates
dimensions which contain multiple colon:
url:http://192.168.10.4:5601

This bugfix makes it possible to query for
metrics with such dimensions. Until now an
exception was thrown.

Closes-Bug: 1668937
Change-Id: I39ed6fba99491630f6a7e0c67743b807e3529461
(cherry picked from commit dcd65110df)
This commit is contained in:
Kamil Choroba 2017-03-01 14:50:29 +01:00
parent ad298fea5b
commit 4f4927cd85
3 changed files with 52 additions and 8 deletions

View File

@ -17,7 +17,6 @@ import unittest
from mock import Mock
from monasca_api.v2.common.exceptions import HTTPUnprocessableEntityError
import monasca_api.v2.reference.helpers as helpers
@ -92,12 +91,23 @@ class TestGetQueryDimension(unittest.TestCase):
result = helpers.get_query_dimensions(req)
self.assertEqual(result, {"Dimension_multi_value": "one|two|three"})
def test_malformed_dimension_extra_colons(self):
def test_dimension_with_multi_colons(self):
req = Mock()
req.query_string = ("foo=bar&dimensions=Dimension:Value1:Value2")
req.query_string = ("foo=bar&dimensions=url:http://192.168.10.4:5601,"
"hostname:monasca,component:kibana,service:monitoring")
self.assertRaises(
HTTPUnprocessableEntityError, helpers.get_query_dimensions, req)
result = helpers.get_query_dimensions(req)
self.assertEqual(result, {"url": "http://192.168.10.4:5601",
"hostname": "monasca",
"component": "kibana",
"service": "monitoring"})
def test_empty_dimension(self):
req = Mock()
req.query_string = ("foo=bar&dimensions=")
result = helpers.get_query_dimensions(req)
self.assertEqual(result, {})
class TestGetOldQueryParams(unittest.TestCase):

View File

@ -164,13 +164,11 @@ def get_query_dimensions(req, param_key='dimensions'):
raise Exception("Error parsing dimensions, unknown format")
for dimension in dimensions_str_array:
dimension_name_value = dimension.split(':')
dimension_name_value = dimension.split(':', 1)
if len(dimension_name_value) == 2:
dimensions[dimension_name_value[0]] = dimension_name_value[1]
elif len(dimension_name_value) == 1:
dimensions[dimension_name_value[0]] = ""
else:
raise Exception('Dimensions are malformed')
return dimensions
except Exception as ex:
LOG.debug(ex)

View File

@ -216,6 +216,42 @@ class TestMetrics(base.BaseMonascaTest):
"metrics = 0"
self.fail(error_msg)
@test.attr(type='gate')
def test_create_metric_with_colon_in_dimension_value(self):
name = data_utils.rand_name('name')
key = 'url'
value = 'http://localhost:8070/v2.0'
timestamp = int(round(time.time() * 1000))
time_iso = helpers.timestamp_to_iso(timestamp)
end_timestamp = int(round((time.time() + 3600 * 24) * 1000))
end_time_iso = helpers.timestamp_to_iso(end_timestamp)
metric = helpers.create_metric(name=name,
dimensions={key: value})
resp, response_body = self.monasca_client.create_metrics(metric)
self.assertEqual(204, resp.status)
query_param = '?name=' + name + '&start_time=' + time_iso + \
'&end_time=' + end_time_iso + \
'&dimensions=' + key + ':' + value
for i in xrange(constants.MAX_RETRIES):
resp, response_body = self.monasca_client. \
list_measurements(query_param)
self.assertEqual(200, resp.status)
elements = response_body['elements']
for element in elements:
if str(element['name']) == name:
self._verify_list_measurements_element(element, key, value)
measurement = element['measurements'][0]
self._verify_list_measurements_measurement(
measurement, metric, None, None)
return
time.sleep(constants.RETRY_WAIT_SECS)
if i == constants.MAX_RETRIES - 1:
error_msg = "Failed test_create_metric: " \
"timeout on waiting for metrics: at least " \
"one metric is needed. Current number of " \
"metrics = 0"
self.fail(error_msg)
@test.attr(type='gate')
@test.attr(type=['negative'])
def test_create_metric_with_no_timestamp(self):