Don't fail if database returns "description": None

Change-Id: Ifffb061ef59729a21bb7356db180fe76deb8de4b
This commit is contained in:
Ben Motz
2015-09-25 16:34:56 +01:00
parent 4046be46c6
commit f7fab655dc
2 changed files with 143 additions and 17 deletions

View File

@@ -18,7 +18,9 @@ import json
import falcon.testing
import fixtures
import testtools.matchers as matchers
from monasca_api.v2.reference import alarm_definitions
from monasca_api.v2.reference import alarms
import oslo_config
@@ -27,6 +29,8 @@ import oslotest.base as oslotest
CONF = oslo_config.cfg.CONF
TENANT_ID = u"fedcba9876543210fedcba9876543210"
ALARM_HISTORY = OrderedDict((
# Only present in data returned from InfluxDB:
(u"time", u"2015-01-01T00:00:00.000Z"),
@@ -63,7 +67,7 @@ ALARM_HISTORY = OrderedDict((
u"sub_alarm_state": u"ALARM",
u"current_values": [50.1],
}]),
(u"tenant_id", u"fedcba9876543210fedcba9876543210"),
(u"tenant_id", TENANT_ID),
))
@@ -83,6 +87,10 @@ class MonascaApiConfigFixture(oslo_config.fixture.Config):
'alarms_driver',
'monasca_api.common.repositories.mysql.alarms_repository:AlarmsRepository',
group='repositories')
self.conf.set_override(
'alarm_definitions_driver',
'monasca_api.common.repositories.alarm_definitions_repository:AlarmDefinitionsRepository',
group='repositories')
self.conf.set_override(
'metrics_driver',
'monasca_api.common.repositories.influxdb.metrics_repository:MetricsRepository',
@@ -114,18 +122,49 @@ class InfluxClientAlarmHistoryResponseFixture(fixtures.MockPatch):
}
class TestAlarmsStateHistory(falcon.testing.TestBase, oslotest.BaseTestCase):
class RESTResponseEquals(object):
"""Match if the supplied data contains a single string containing a JSON
object which decodes to match expected_data, excluding the contents of
the 'links' key.
"""
def __init__(self, *args, **kwargs):
super(TestAlarmsStateHistory, self).__init__(*args, **kwargs)
def __init__(self, expected_data):
self.expected_data = expected_data
if u"links" in expected_data:
del expected_data[u"links"]
def __str__(self):
return 'RESTResponseEquals(%s)' % (self.expected,)
def match(self, actual):
if len(actual) != 1:
return matchers.Mismatch("Response contains <> 1 item: %r" % actual)
response_data = json.loads(actual[0])
if u"links" in response_data:
del response_data[u"links"]
return matchers.Equals(self.expected_data).match(response_data)
class AlarmTestBase(falcon.testing.TestBase, oslotest.BaseTestCase):
def setUp(self):
super(AlarmTestBase, self).setUp()
self.useFixture(fixtures.MockPatch(
'monasca_api.common.messaging.kafka_publisher.KafkaPublisher'))
self.CONF = self.useFixture(MonascaApiConfigFixture(CONF)).conf
class TestAlarmsStateHistory(AlarmTestBase):
def setUp(self):
super(TestAlarmsStateHistory, self).setUp()
self.CONF = self.useFixture(MonascaApiConfigFixture(CONF)).conf
self.useFixture(fixtures.MockPatch(
'monasca_api.common.messaging.kafka_publisher.KafkaPublisher'))
self.useFixture(InfluxClientAlarmHistoryResponseFixture(
'monasca_api.common.repositories.influxdb.metrics_repository.client.InfluxDBClient'))
self.useFixture(fixtures.MockPatch(
@@ -136,9 +175,9 @@ class TestAlarmsStateHistory(falcon.testing.TestBase, oslotest.BaseTestCase):
'/v2.0/alarms/{alarm_id}/state-history/', self.alarms_resource)
def test_alarm_state_history(self):
expected_elements = dict(ALARM_HISTORY)
del expected_elements[u"time"]
del expected_elements[u"sub_alarms"][0][u"sub_alarm_expression"][u"metric_definition"]
expected_elements = {u"elements": [dict(ALARM_HISTORY)]}
del expected_elements[u"elements"][0][u"time"]
del expected_elements[u"elements"][0][u"sub_alarms"][0][u"sub_alarm_expression"][u"metric_definition"]
response = self.simulate_request(
u'/v2.0/alarms/%s/state-history/' % ALARM_HISTORY[u"alarm_id"],
@@ -148,9 +187,94 @@ class TestAlarmsStateHistory(falcon.testing.TestBase, oslotest.BaseTestCase):
})
self.assertEqual(self.srmock.status, falcon.HTTP_200)
self.assertThat(response, RESTResponseEquals(expected_elements))
self.assertEqual(len(response), 1)
response_data = json.loads(response[0])
response_elements = response_data["elements"]
self.assertEqual(response_elements, [expected_elements])
class TestAlarmDefinitionList(AlarmTestBase):
def setUp(self):
super(TestAlarmDefinitionList, self).setUp()
self.alarm_def_repo_mock = self.useFixture(fixtures.MockPatch(
'monasca_api.common.repositories.alarm_definitions_repository.AlarmDefinitionsRepository'
)).mock
self.alarm_definition_resource = alarm_definitions.AlarmDefinitions()
self.api.add_route("/v2.0/alarm-definitions/{alarm_definition_id}",
self.alarm_definition_resource)
def test_alarm_definition_specific_alarm(self):
self.alarm_def_repo_mock.return_value.get_alarm_definition.return_value = {
'alarm_actions': None,
'ok_actions': None,
'description': b'Non-ASCII character: \xe2\x98\x83',
'match_by': u'hostname',
'name': u'Test Alarm',
'actions_enabled': 1,
'undetermined_actions': None,
'expression': u'max(test.metric{hostname=host}) gte 1',
'id': u'00000001-0001-0001-0001-000000000001',
'severity': u'LOW'
}
expected_data = {
u'alarm_actions': [],
u'ok_actions': [],
u'description': u'Non-ASCII character: \u2603',
u'match_by': [u'hostname'],
u'name': u'Test Alarm',
u'actions_enabled': True,
u'undetermined_actions': [],
u'expression': u'max(test.metric{hostname=host}) gte 1',
u'id': u'00000001-0001-0001-0001-000000000001',
u'severity': u'LOW',
}
response = self.simulate_request(
'/v2.0/alarm-definitions/%s' % (expected_data[u'id']),
headers={
'X-Roles': 'admin',
'X-Tenant-Id': TENANT_ID,
})
self.assertEqual(self.srmock.status, falcon.HTTP_200)
self.assertThat(response, RESTResponseEquals(expected_data))
def test_alarm_definition_specific_alarm_description_none(self):
self.alarm_def_repo_mock.return_value.get_alarm_definition.return_value = {
'alarm_actions': None,
'ok_actions': None,
'description': None,
'match_by': u'hostname',
'name': u'Test Alarm',
'actions_enabled': 1,
'undetermined_actions': None,
'expression': u'max(test.metric{hostname=host}) gte 1',
'id': u'00000001-0001-0001-0001-000000000001',
'severity': u'LOW'
}
expected_data = {
u'alarm_actions': [],
u'ok_actions': [],
u'description': None,
u'match_by': [u'hostname'],
u'name': u'Test Alarm',
u'actions_enabled': True,
u'undetermined_actions': [],
u'expression': u'max(test.metric{hostname=host}) gte 1',
u'id': u'00000001-0001-0001-0001-000000000001',
u'severity': u'LOW',
}
response = self.simulate_request(
'/v2.0/alarm-definitions/%s' % (expected_data[u'id']),
headers={
'X-Roles': 'admin',
'X-Tenant-Id': TENANT_ID,
})
self.assertEqual(self.srmock.status, falcon.HTTP_200)
self.assertThat(response, RESTResponseEquals(expected_data))

View File

@@ -233,13 +233,15 @@ class AlarmDefinitions(alarm_definitions_api_v2.AlarmDefinitionsV2API,
undetermined_actions_list = get_comma_separated_str_as_list(
alarm_definition_row['undetermined_actions'])
description = (alarm_definition_row['description'].decode('utf8')
if alarm_definition_row['description'] is not None else None)
result = {
u'actions_enabled': alarm_definition_row['actions_enabled'] == 1,
u'alarm_actions': alarm_actions_list,
u'undetermined_actions': undetermined_actions_list,
u'ok_actions': ok_actions_list,
u'description': alarm_definition_row['description'].decode(
'utf8'),
u'description': description,
u'expression': alarm_definition_row['expression'].decode('utf8'),
u'id': alarm_definition_row['id'].decode('utf8'),
u'match_by': match_by,