Merge "Remove newline characters and change StandardError to Exception"
This commit is contained in:
commit
793d2450b6
@ -151,5 +151,5 @@ class CollectDPlugin(object):
|
||||
collectd.register_notification(callback, **kwargs)
|
||||
|
||||
|
||||
class PluginError(StandardError):
|
||||
class PluginError(Exception):
|
||||
pass
|
||||
|
@ -1,15 +1,15 @@
|
||||
# Copyright 2016 - ZTE
|
||||
#
|
||||
# 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.
|
||||
|
||||
__author__ = 'stack'
|
||||
# Copyright 2016 - ZTE
|
||||
#
|
||||
# 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.
|
||||
|
||||
__author__ = 'stack'
|
||||
|
@ -1,115 +1,115 @@
|
||||
# Copyright 2016 - ZTE, Nokia
|
||||
#
|
||||
# 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.
|
||||
|
||||
from vitrage.common.constants import DatasourceAction
|
||||
from vitrage.common.constants import DatasourceProperties as DSProps
|
||||
from vitrage.common.constants import EdgeLabel
|
||||
from vitrage.common.constants import EntityCategory
|
||||
from vitrage.common.constants import GraphAction
|
||||
from vitrage.common.constants import VertexProperties as VProps
|
||||
from vitrage.datasources.alarm_properties import AlarmProperties as AlarmProps
|
||||
from vitrage.datasources.aodh.properties import AodhProperties as AodhProps
|
||||
from vitrage.datasources.aodh.properties import AodhState
|
||||
from vitrage.datasources.nova.instance import NOVA_INSTANCE_DATASOURCE
|
||||
from vitrage.datasources.transformer_base import TransformerBase
|
||||
from vitrage.graph.driver.elements import Vertex
|
||||
from vitrage.tests import base
|
||||
|
||||
|
||||
class AodhTransformerBaseTest(base.BaseTest):
|
||||
|
||||
def _validate_aodh_vertex_props(self, vertex, event):
|
||||
|
||||
self.assertEqual(EntityCategory.ALARM, vertex[VProps.VITRAGE_CATEGORY])
|
||||
self.assertEqual(event[DSProps.ENTITY_TYPE],
|
||||
vertex[VProps.VITRAGE_TYPE])
|
||||
self.assertEqual(event[AodhProps.NAME], vertex[VProps.NAME])
|
||||
self.assertEqual(event[AodhProps.SEVERITY], vertex[VProps.SEVERITY])
|
||||
self.assertEqual(event[AodhProps.DESCRIPTION],
|
||||
vertex[AodhProps.DESCRIPTION])
|
||||
self.assertEqual(event[AodhProps.ENABLED], vertex[AodhProps.ENABLED])
|
||||
self.assertEqual(event[AodhProps.PROJECT_ID],
|
||||
vertex[VProps.PROJECT_ID])
|
||||
self.assertEqual(event[AodhProps.REPEAT_ACTIONS],
|
||||
vertex[AodhProps.REPEAT_ACTIONS])
|
||||
self.assertEqual(event[AodhProps.TYPE], vertex['alarm_type'])
|
||||
if event[AodhProps.TYPE] == AodhProps.EVENT:
|
||||
self.assertEqual(event[AodhProps.EVENT_TYPE],
|
||||
vertex[AodhProps.EVENT_TYPE])
|
||||
elif event[AodhProps.TYPE] == AodhProps.THRESHOLD:
|
||||
self.assertEqual(event[AodhProps.STATE_TIMESTAMP],
|
||||
vertex[AodhProps.STATE_TIMESTAMP])
|
||||
self.assertEqual(event[DSProps.SAMPLE_DATE],
|
||||
vertex[VProps.VITRAGE_SAMPLE_TIMESTAMP])
|
||||
|
||||
event_status = event[AodhProps.STATE]
|
||||
if event_status == AodhState.OK:
|
||||
self.assertEqual(AlarmProps.INACTIVE_STATE,
|
||||
vertex[VProps.STATE])
|
||||
else:
|
||||
self.assertEqual(AlarmProps.ACTIVE_STATE,
|
||||
vertex[VProps.STATE])
|
||||
self.assertFalse(vertex[VProps.VITRAGE_IS_PLACEHOLDER])
|
||||
self.assertFalse(vertex[VProps.VITRAGE_IS_DELETED])
|
||||
|
||||
def _validate_action(self, alarm, wrapper):
|
||||
if DSProps.EVENT_TYPE in alarm \
|
||||
and alarm[DSProps.EVENT_TYPE] in GraphAction.__dict__.values():
|
||||
self.assertEqual(alarm[DSProps.EVENT_TYPE], wrapper.action)
|
||||
return
|
||||
|
||||
ds_action = alarm[DSProps.DATASOURCE_ACTION]
|
||||
if ds_action in (DatasourceAction.SNAPSHOT, DatasourceAction.UPDATE):
|
||||
self.assertEqual(GraphAction.UPDATE_ENTITY, wrapper.action)
|
||||
else:
|
||||
self.assertEqual(GraphAction.CREATE_ENTITY, wrapper.action)
|
||||
|
||||
def _validate_neighbors(self, neighbors, alarm_id, event):
|
||||
resource_counter = 0
|
||||
|
||||
for neighbor in neighbors:
|
||||
resource_id = event[AodhProps.RESOURCE_ID]
|
||||
self._validate_instance_neighbor(neighbor,
|
||||
resource_id,
|
||||
alarm_id)
|
||||
resource_counter += 1
|
||||
|
||||
self.assertEqual(1,
|
||||
resource_counter,
|
||||
'Alarm can be belonged to only one resource')
|
||||
|
||||
def _validate_instance_neighbor(self,
|
||||
alarm_neighbor,
|
||||
resource_id,
|
||||
alarm_vertex_id):
|
||||
# validate neighbor vertex
|
||||
self.assertEqual(EntityCategory.RESOURCE,
|
||||
alarm_neighbor.vertex[VProps.VITRAGE_CATEGORY])
|
||||
self.assertEqual(NOVA_INSTANCE_DATASOURCE,
|
||||
alarm_neighbor.vertex[VProps.VITRAGE_TYPE])
|
||||
self.assertEqual(resource_id, alarm_neighbor.vertex[VProps.ID])
|
||||
self.assertFalse(alarm_neighbor.vertex[VProps.VITRAGE_IS_PLACEHOLDER])
|
||||
self.assertFalse(alarm_neighbor.vertex[VProps.VITRAGE_IS_DELETED])
|
||||
|
||||
# Validate neighbor edge
|
||||
edge = alarm_neighbor.edge
|
||||
self.assertEqual(edge.target_id, alarm_neighbor.vertex.vertex_id)
|
||||
self.assertEqual(edge.source_id, alarm_vertex_id)
|
||||
self.assertEqual(edge.label, EdgeLabel.ON)
|
||||
|
||||
def _convert_dist_to_vertex(self, neighbor):
|
||||
ver_id = neighbor[VProps.VITRAGE_CATEGORY] + \
|
||||
TransformerBase.KEY_SEPARATOR + neighbor[VProps.VITRAGE_TYPE] + \
|
||||
TransformerBase.KEY_SEPARATOR + neighbor[VProps.ID]
|
||||
return Vertex(vertex_id=ver_id, properties=neighbor)
|
||||
# Copyright 2016 - ZTE, Nokia
|
||||
#
|
||||
# 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.
|
||||
|
||||
from vitrage.common.constants import DatasourceAction
|
||||
from vitrage.common.constants import DatasourceProperties as DSProps
|
||||
from vitrage.common.constants import EdgeLabel
|
||||
from vitrage.common.constants import EntityCategory
|
||||
from vitrage.common.constants import GraphAction
|
||||
from vitrage.common.constants import VertexProperties as VProps
|
||||
from vitrage.datasources.alarm_properties import AlarmProperties as AlarmProps
|
||||
from vitrage.datasources.aodh.properties import AodhProperties as AodhProps
|
||||
from vitrage.datasources.aodh.properties import AodhState
|
||||
from vitrage.datasources.nova.instance import NOVA_INSTANCE_DATASOURCE
|
||||
from vitrage.datasources.transformer_base import TransformerBase
|
||||
from vitrage.graph.driver.elements import Vertex
|
||||
from vitrage.tests import base
|
||||
|
||||
|
||||
class AodhTransformerBaseTest(base.BaseTest):
|
||||
|
||||
def _validate_aodh_vertex_props(self, vertex, event):
|
||||
|
||||
self.assertEqual(EntityCategory.ALARM, vertex[VProps.VITRAGE_CATEGORY])
|
||||
self.assertEqual(event[DSProps.ENTITY_TYPE],
|
||||
vertex[VProps.VITRAGE_TYPE])
|
||||
self.assertEqual(event[AodhProps.NAME], vertex[VProps.NAME])
|
||||
self.assertEqual(event[AodhProps.SEVERITY], vertex[VProps.SEVERITY])
|
||||
self.assertEqual(event[AodhProps.DESCRIPTION],
|
||||
vertex[AodhProps.DESCRIPTION])
|
||||
self.assertEqual(event[AodhProps.ENABLED], vertex[AodhProps.ENABLED])
|
||||
self.assertEqual(event[AodhProps.PROJECT_ID],
|
||||
vertex[VProps.PROJECT_ID])
|
||||
self.assertEqual(event[AodhProps.REPEAT_ACTIONS],
|
||||
vertex[AodhProps.REPEAT_ACTIONS])
|
||||
self.assertEqual(event[AodhProps.TYPE], vertex['alarm_type'])
|
||||
if event[AodhProps.TYPE] == AodhProps.EVENT:
|
||||
self.assertEqual(event[AodhProps.EVENT_TYPE],
|
||||
vertex[AodhProps.EVENT_TYPE])
|
||||
elif event[AodhProps.TYPE] == AodhProps.THRESHOLD:
|
||||
self.assertEqual(event[AodhProps.STATE_TIMESTAMP],
|
||||
vertex[AodhProps.STATE_TIMESTAMP])
|
||||
self.assertEqual(event[DSProps.SAMPLE_DATE],
|
||||
vertex[VProps.VITRAGE_SAMPLE_TIMESTAMP])
|
||||
|
||||
event_status = event[AodhProps.STATE]
|
||||
if event_status == AodhState.OK:
|
||||
self.assertEqual(AlarmProps.INACTIVE_STATE,
|
||||
vertex[VProps.STATE])
|
||||
else:
|
||||
self.assertEqual(AlarmProps.ACTIVE_STATE,
|
||||
vertex[VProps.STATE])
|
||||
self.assertFalse(vertex[VProps.VITRAGE_IS_PLACEHOLDER])
|
||||
self.assertFalse(vertex[VProps.VITRAGE_IS_DELETED])
|
||||
|
||||
def _validate_action(self, alarm, wrapper):
|
||||
if DSProps.EVENT_TYPE in alarm \
|
||||
and alarm[DSProps.EVENT_TYPE] in GraphAction.__dict__.values():
|
||||
self.assertEqual(alarm[DSProps.EVENT_TYPE], wrapper.action)
|
||||
return
|
||||
|
||||
ds_action = alarm[DSProps.DATASOURCE_ACTION]
|
||||
if ds_action in (DatasourceAction.SNAPSHOT, DatasourceAction.UPDATE):
|
||||
self.assertEqual(GraphAction.UPDATE_ENTITY, wrapper.action)
|
||||
else:
|
||||
self.assertEqual(GraphAction.CREATE_ENTITY, wrapper.action)
|
||||
|
||||
def _validate_neighbors(self, neighbors, alarm_id, event):
|
||||
resource_counter = 0
|
||||
|
||||
for neighbor in neighbors:
|
||||
resource_id = event[AodhProps.RESOURCE_ID]
|
||||
self._validate_instance_neighbor(neighbor,
|
||||
resource_id,
|
||||
alarm_id)
|
||||
resource_counter += 1
|
||||
|
||||
self.assertEqual(1,
|
||||
resource_counter,
|
||||
'Alarm can be belonged to only one resource')
|
||||
|
||||
def _validate_instance_neighbor(self,
|
||||
alarm_neighbor,
|
||||
resource_id,
|
||||
alarm_vertex_id):
|
||||
# validate neighbor vertex
|
||||
self.assertEqual(EntityCategory.RESOURCE,
|
||||
alarm_neighbor.vertex[VProps.VITRAGE_CATEGORY])
|
||||
self.assertEqual(NOVA_INSTANCE_DATASOURCE,
|
||||
alarm_neighbor.vertex[VProps.VITRAGE_TYPE])
|
||||
self.assertEqual(resource_id, alarm_neighbor.vertex[VProps.ID])
|
||||
self.assertFalse(alarm_neighbor.vertex[VProps.VITRAGE_IS_PLACEHOLDER])
|
||||
self.assertFalse(alarm_neighbor.vertex[VProps.VITRAGE_IS_DELETED])
|
||||
|
||||
# Validate neighbor edge
|
||||
edge = alarm_neighbor.edge
|
||||
self.assertEqual(edge.target_id, alarm_neighbor.vertex.vertex_id)
|
||||
self.assertEqual(edge.source_id, alarm_vertex_id)
|
||||
self.assertEqual(edge.label, EdgeLabel.ON)
|
||||
|
||||
def _convert_dist_to_vertex(self, neighbor):
|
||||
ver_id = neighbor[VProps.VITRAGE_CATEGORY] + \
|
||||
TransformerBase.KEY_SEPARATOR + neighbor[VProps.VITRAGE_TYPE] + \
|
||||
TransformerBase.KEY_SEPARATOR + neighbor[VProps.ID]
|
||||
return Vertex(vertex_id=ver_id, properties=neighbor)
|
||||
|
@ -1,27 +1,27 @@
|
||||
# Copyright 2016 - Nokia
|
||||
#
|
||||
# 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.
|
||||
|
||||
from vitrage.datasources.aodh.driver import AodhDriver
|
||||
|
||||
|
||||
class MockAodhDriver(AodhDriver):
|
||||
"""A aodh driver for tests.
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, conf):
|
||||
super(MockAodhDriver, self).__init__(conf)
|
||||
|
||||
def _cache_all_alarms(self):
|
||||
pass
|
||||
# Copyright 2016 - Nokia
|
||||
#
|
||||
# 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.
|
||||
|
||||
from vitrage.datasources.aodh.driver import AodhDriver
|
||||
|
||||
|
||||
class MockAodhDriver(AodhDriver):
|
||||
"""A aodh driver for tests.
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, conf):
|
||||
super(MockAodhDriver, self).__init__(conf)
|
||||
|
||||
def _cache_all_alarms(self):
|
||||
pass
|
||||
|
@ -1,376 +1,376 @@
|
||||
# Copyright 2016 - ZTE, Nokia
|
||||
#
|
||||
# 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.
|
||||
|
||||
from oslo_config import cfg
|
||||
|
||||
from vitrage.common.constants import DatasourceOpts as DSOpts
|
||||
from vitrage.common.constants import DatasourceProperties as DSProps
|
||||
from vitrage.common.constants import UpdateMethod
|
||||
from vitrage.datasources.aodh import AODH_DATASOURCE
|
||||
from vitrage.datasources.aodh.properties import AodhEventType
|
||||
from vitrage.datasources.aodh.properties import AodhProperties as AodhProps
|
||||
from vitrage.tests import base
|
||||
from vitrage.tests.mocks import mock_driver
|
||||
from vitrage.tests.unit.datasources.aodh.mock_driver import MockAodhDriver
|
||||
|
||||
|
||||
class AodhDriverTest(base.BaseTest):
|
||||
|
||||
OPTS = [
|
||||
cfg.StrOpt(DSOpts.UPDATE_METHOD,
|
||||
default=UpdateMethod.PUSH),
|
||||
]
|
||||
|
||||
# noinspection PyPep8Naming
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
cls.conf = cfg.ConfigOpts()
|
||||
cls.conf.register_opts(cls.OPTS, group=AODH_DATASOURCE)
|
||||
|
||||
def test_event_alarm_notifications(self):
|
||||
|
||||
aodh_driver = MockAodhDriver(self.conf)
|
||||
|
||||
# 1. alarm creation with 'ok' state
|
||||
# prepare data
|
||||
detail_data = {"type": "creation",
|
||||
AodhProps.DETAIL: self._create_alarm_data_type_event()}
|
||||
generators = \
|
||||
mock_driver.simple_aodh_alarm_notification_generators(
|
||||
alarm_num=1,
|
||||
update_events=1,
|
||||
update_vals=detail_data)
|
||||
alarm = mock_driver.generate_sequential_events_list(generators)[0]
|
||||
alarm_info = alarm.copy()
|
||||
|
||||
# action
|
||||
entity = aodh_driver.enrich_event(alarm, AodhEventType.CREATION)
|
||||
|
||||
# Test assertions
|
||||
# alarm with status OK should not be handled
|
||||
self.assertIsNone(entity)
|
||||
|
||||
# 2.alarm state transition from 'ok' to 'alarm'
|
||||
detail_data = {"type": "state transition",
|
||||
AodhProps.DETAIL: {AodhProps.STATE: "alarm"}}
|
||||
alarm.update(detail_data)
|
||||
entity = aodh_driver.enrich_event(alarm,
|
||||
AodhEventType.STATE_TRANSITION)
|
||||
|
||||
# Test assertions
|
||||
# alarm state change: ok->alarm, need to be added
|
||||
self.assertIsNotNone(entity)
|
||||
self._validate_aodh_entity_comm_props(entity, alarm_info)
|
||||
self.assertEqual(entity[AodhProps.STATE],
|
||||
alarm[AodhProps.DETAIL][AodhProps.STATE])
|
||||
self.assertEqual(entity[AodhProps.SEVERITY],
|
||||
alarm[AodhProps.SEVERITY])
|
||||
self.assertEqual(entity[DSProps.EVENT_TYPE],
|
||||
AodhEventType.STATE_TRANSITION)
|
||||
|
||||
# 3. delete alarm which is 'alarm' state
|
||||
# prepare data
|
||||
detail_data = {"type": "deletion"}
|
||||
alarm.update(detail_data)
|
||||
|
||||
# action
|
||||
entity = aodh_driver.enrich_event(alarm, AodhEventType.DELETION)
|
||||
|
||||
# Test assertions
|
||||
self.assertIsNotNone(entity)
|
||||
self._validate_aodh_entity_comm_props(entity, alarm_info)
|
||||
self.assertEqual(entity[DSProps.EVENT_TYPE],
|
||||
AodhEventType.DELETION)
|
||||
|
||||
# 4. alarm creation with 'alarm' state
|
||||
# prepare data
|
||||
detail_data = {"type": "creation",
|
||||
AodhProps.DETAIL:
|
||||
self._create_alarm_data_type_event(state="alarm")}
|
||||
generators = \
|
||||
mock_driver.simple_aodh_alarm_notification_generators(
|
||||
alarm_num=1,
|
||||
update_events=1,
|
||||
update_vals=detail_data)
|
||||
alarm = mock_driver.generate_sequential_events_list(generators)[0]
|
||||
alarm_info = alarm.copy()
|
||||
|
||||
# action
|
||||
entity = aodh_driver.enrich_event(alarm, AodhEventType.CREATION)
|
||||
|
||||
# Test assertions
|
||||
# alarm with status 'alarm' need to be added
|
||||
self.assertIsNotNone(entity)
|
||||
self._validate_aodh_entity_comm_props(entity, alarm_info)
|
||||
self.assertEqual(entity[AodhProps.STATE],
|
||||
alarm[AodhProps.DETAIL][AodhProps.STATE])
|
||||
self.assertEqual(entity[AodhProps.SEVERITY],
|
||||
alarm[AodhProps.SEVERITY])
|
||||
self.assertIsNone(entity[AodhProps.RESOURCE_ID])
|
||||
self.assertEqual("*", entity[AodhProps.EVENT_TYPE])
|
||||
self.assertEqual(entity[DSProps.EVENT_TYPE],
|
||||
AodhEventType.CREATION)
|
||||
|
||||
# 5. alarm rule change
|
||||
# prepare data
|
||||
detail_data = {"type": "rule change",
|
||||
AodhProps.DETAIL: {
|
||||
"severity": "critical",
|
||||
AodhProps.RULE:
|
||||
{"query": [{"field": "traits.resource_id",
|
||||
"type": "",
|
||||
"value": "1",
|
||||
"op": "eq"}],
|
||||
"event_type": "instance.update"}}}
|
||||
alarm.update(detail_data)
|
||||
|
||||
# action
|
||||
entity = aodh_driver.enrich_event(alarm,
|
||||
AodhEventType.RULE_CHANGE)
|
||||
|
||||
# Test assertions
|
||||
# alarm rule change: need to be update
|
||||
self.assertIsNotNone(entity)
|
||||
self._validate_aodh_entity_comm_props(entity, alarm_info)
|
||||
self.assertEqual(entity[AodhProps.SEVERITY],
|
||||
alarm[AodhProps.DETAIL][AodhProps.SEVERITY])
|
||||
self.assertEqual(
|
||||
entity[AodhProps.EVENT_TYPE],
|
||||
alarm[AodhProps.DETAIL][AodhProps.RULE][AodhProps.EVENT_TYPE])
|
||||
self.assertEqual("1", entity[AodhProps.RESOURCE_ID])
|
||||
self.assertEqual(entity[DSProps.EVENT_TYPE],
|
||||
AodhEventType.RULE_CHANGE)
|
||||
|
||||
# 6. alarm state change from 'alarm' to 'ok'
|
||||
# prepare data
|
||||
detail_data = {"type": "state transition",
|
||||
AodhProps.DETAIL: {AodhProps.STATE: "ok"}}
|
||||
alarm.update(detail_data)
|
||||
|
||||
# action
|
||||
entity = aodh_driver.enrich_event(alarm,
|
||||
AodhEventType.STATE_TRANSITION)
|
||||
|
||||
# Test assertions
|
||||
# alarm state change: alarm->OK, need to be deleted
|
||||
self.assertIsNotNone(entity)
|
||||
self._validate_aodh_entity_comm_props(entity, alarm_info)
|
||||
self.assertEqual(entity[DSProps.EVENT_TYPE],
|
||||
AodhEventType.STATE_TRANSITION)
|
||||
|
||||
# 7. delete alarm which is 'ok' state
|
||||
# prepare data
|
||||
detail_data = {"type": "deletion"}
|
||||
alarm.update(detail_data)
|
||||
|
||||
# action
|
||||
entity = aodh_driver.enrich_event(alarm, AodhEventType.DELETION)
|
||||
|
||||
# Test assertions
|
||||
self.assertIsNone(entity)
|
||||
|
||||
def test_gnocchi_threshold_alarm_notifications(self):
|
||||
aodh_driver = MockAodhDriver(self.conf)
|
||||
|
||||
# 1. alarm creation with 'ok' state
|
||||
# prepare data
|
||||
detail_data = {"type": "gnocchi_resources_threshold",
|
||||
AodhProps.DETAIL: self._create_alarm_data_gnocchi()}
|
||||
generators = \
|
||||
mock_driver.simple_aodh_alarm_notification_generators(
|
||||
alarm_num=1,
|
||||
update_events=1,
|
||||
update_vals=detail_data)
|
||||
alarm = mock_driver.generate_sequential_events_list(generators)[0]
|
||||
alarm_info = alarm.copy()
|
||||
|
||||
# action
|
||||
entity = aodh_driver.enrich_event(alarm, AodhEventType.CREATION)
|
||||
|
||||
# Test assertions
|
||||
# alarm with status OK should not be handled
|
||||
self.assertIsNone(entity)
|
||||
|
||||
# 2.alarm state transition from 'ok' to 'alarm'
|
||||
detail_data = {"type": "state transition",
|
||||
AodhProps.DETAIL: {AodhProps.STATE: "alarm"}}
|
||||
alarm.update(detail_data)
|
||||
entity = aodh_driver.enrich_event(alarm,
|
||||
AodhEventType.STATE_TRANSITION)
|
||||
|
||||
# Test assertions
|
||||
# alarm state change: ok->alarm, need to be added
|
||||
self.assertIsNotNone(entity)
|
||||
self._validate_aodh_entity_comm_props(entity, alarm_info)
|
||||
self.assertEqual(entity[AodhProps.STATE],
|
||||
alarm[AodhProps.DETAIL][AodhProps.STATE])
|
||||
self.assertEqual(entity[AodhProps.SEVERITY],
|
||||
alarm[AodhProps.SEVERITY])
|
||||
|
||||
# 3. delete alarm which is 'alarm' state
|
||||
# prepare data
|
||||
detail_data = {"type": "deletion"}
|
||||
alarm.update(detail_data)
|
||||
|
||||
# action
|
||||
entity = aodh_driver.enrich_event(alarm, AodhEventType.DELETION)
|
||||
|
||||
# Test assertions
|
||||
self.assertIsNotNone(entity)
|
||||
self._validate_aodh_entity_comm_props(entity, alarm_info)
|
||||
self.assertEqual(entity[DSProps.EVENT_TYPE],
|
||||
AodhEventType.DELETION)
|
||||
|
||||
# 4. alarm creation with 'alarm' state
|
||||
# prepare data
|
||||
detail_data = {"type": "gnocchi_resources_threshold",
|
||||
AodhProps.DETAIL:
|
||||
self._create_alarm_data_gnocchi(state="alarm")}
|
||||
generators = \
|
||||
mock_driver.simple_aodh_alarm_notification_generators(
|
||||
alarm_num=1,
|
||||
update_events=1,
|
||||
update_vals=detail_data)
|
||||
alarm = mock_driver.generate_sequential_events_list(generators)[0]
|
||||
alarm_info = alarm.copy()
|
||||
|
||||
# action
|
||||
entity = aodh_driver.enrich_event(alarm, AodhEventType.CREATION)
|
||||
|
||||
# Test assertions
|
||||
# alarm with status 'alarm' need to be added
|
||||
self.assertIsNotNone(entity)
|
||||
self._validate_aodh_entity_comm_props(entity, alarm_info)
|
||||
self.assertEqual(entity[AodhProps.STATE],
|
||||
alarm[AodhProps.DETAIL][AodhProps.STATE])
|
||||
self.assertEqual(entity[AodhProps.SEVERITY],
|
||||
alarm[AodhProps.SEVERITY])
|
||||
self.assertEqual(entity[DSProps.EVENT_TYPE],
|
||||
AodhEventType.CREATION)
|
||||
|
||||
# 5. alarm rule change
|
||||
# prepare data
|
||||
detail_data = {"type": "rule change",
|
||||
AodhProps.DETAIL: {
|
||||
"severity": "critical",
|
||||
AodhProps.RULE:
|
||||
{"granularity": "300",
|
||||
"threshold": "0.0123",
|
||||
"comparison_operator": "eq"}}}
|
||||
alarm.update(detail_data)
|
||||
|
||||
# action
|
||||
entity = aodh_driver.enrich_event(alarm,
|
||||
AodhEventType.RULE_CHANGE)
|
||||
|
||||
# Test assertions
|
||||
# alarm rule change: need to be update
|
||||
self.assertIsNotNone(entity)
|
||||
self._validate_aodh_entity_comm_props(entity, alarm_info)
|
||||
self.assertEqual(entity[AodhProps.SEVERITY],
|
||||
alarm[AodhProps.DETAIL][AodhProps.SEVERITY])
|
||||
self.assertEqual(entity[DSProps.EVENT_TYPE],
|
||||
AodhEventType.RULE_CHANGE)
|
||||
|
||||
# 6. alarm state change from 'alarm' to 'ok'
|
||||
# prepare data
|
||||
detail_data = {"type": "state transition",
|
||||
AodhProps.DETAIL: {AodhProps.STATE: "ok"}}
|
||||
alarm.update(detail_data)
|
||||
|
||||
# action
|
||||
entity = aodh_driver.enrich_event(alarm,
|
||||
AodhEventType.STATE_TRANSITION)
|
||||
|
||||
# Test assertions
|
||||
# alarm state change: alarm->OK, need to be deleted
|
||||
self.assertIsNotNone(entity)
|
||||
self._validate_aodh_entity_comm_props(entity, alarm_info)
|
||||
self.assertEqual(entity[DSProps.EVENT_TYPE],
|
||||
AodhEventType.STATE_TRANSITION)
|
||||
|
||||
# 7. delete alarm which is 'ok' state
|
||||
# prepare data
|
||||
detail_data = {"type": "deletion"}
|
||||
alarm.update(detail_data)
|
||||
|
||||
# action
|
||||
entity = aodh_driver.enrich_event(alarm, AodhEventType.DELETION)
|
||||
|
||||
# Test assertions
|
||||
self.assertIsNone(entity)
|
||||
|
||||
def _create_alarm_data_gnocchi(self,
|
||||
state="ok",
|
||||
type="gnocchi_resources_threshold",
|
||||
rule=None):
|
||||
|
||||
if rule is None:
|
||||
rule = {"granularity": "300",
|
||||
"threshold": "0.001",
|
||||
"comparison_operator": "gt",
|
||||
"resource_type": "instance"
|
||||
}
|
||||
return {AodhProps.DESCRIPTION: "test",
|
||||
AodhProps.TIMESTAMP: "2016-11-09T01:39:13.839584",
|
||||
AodhProps.ENABLED: True,
|
||||
AodhProps.STATE_TIMESTAMP: "2016-11-09T01:39:13.839584",
|
||||
AodhProps.ALARM_ID: "7e5c3754-e2eb-4782-ae00-7da5ded8568b",
|
||||
AodhProps.REPEAT_ACTIONS: False,
|
||||
AodhProps.PROJECT_ID: "c365d18fcc03493187016ae743f0cc4d",
|
||||
AodhProps.NAME: "test",
|
||||
AodhProps.SEVERITY: "low",
|
||||
AodhProps.RESOURCE_ID: "88cd2d1d-8af4-4d00-9b5e-f82f8c8b0f8d",
|
||||
AodhProps.TYPE: type,
|
||||
AodhProps.STATE: state,
|
||||
AodhProps.RULE: rule}
|
||||
|
||||
def _create_alarm_data_type_event(self,
|
||||
state="ok",
|
||||
type="event",
|
||||
rule=None):
|
||||
|
||||
if rule is None:
|
||||
rule = {"query": [], "event_type": "*"}
|
||||
return {AodhProps.DESCRIPTION: "test",
|
||||
AodhProps.TIMESTAMP: "2016-11-09T01:39:13.839584",
|
||||
AodhProps.ENABLED: True,
|
||||
AodhProps.STATE_TIMESTAMP: "2016-11-09T01:39:13.839584",
|
||||
AodhProps.ALARM_ID: "7e5c3754-e2eb-4782-ae00-7da5ded8568b",
|
||||
AodhProps.REPEAT_ACTIONS: False,
|
||||
AodhProps.PROJECT_ID: "c365d18fcc03493187016ae743f0cc4d",
|
||||
AodhProps.NAME: "test",
|
||||
AodhProps.SEVERITY: "low",
|
||||
AodhProps.TYPE: type,
|
||||
AodhProps.STATE: state,
|
||||
AodhProps.RULE: rule}
|
||||
|
||||
def _validate_aodh_entity_comm_props(self, entity, alarm):
|
||||
|
||||
self.assertEqual(entity[AodhProps.ALARM_ID],
|
||||
alarm[AodhProps.ALARM_ID])
|
||||
self.assertEqual(entity[AodhProps.PROJECT_ID],
|
||||
alarm[AodhProps.PROJECT_ID])
|
||||
self.assertEqual(entity[AodhProps.TIMESTAMP],
|
||||
alarm[AodhProps.TIMESTAMP])
|
||||
self.assertEqual(entity[AodhProps.DESCRIPTION],
|
||||
alarm[AodhProps.DETAIL][AodhProps.DESCRIPTION])
|
||||
self.assertEqual(entity[AodhProps.ENABLED],
|
||||
alarm[AodhProps.DETAIL][AodhProps.ENABLED])
|
||||
self.assertEqual(entity[AodhProps.NAME],
|
||||
alarm[AodhProps.DETAIL][AodhProps.NAME])
|
||||
self.assertEqual(entity[AodhProps.REPEAT_ACTIONS],
|
||||
alarm[AodhProps.DETAIL][AodhProps.REPEAT_ACTIONS])
|
||||
self.assertEqual(entity[AodhProps.TYPE],
|
||||
alarm[AodhProps.DETAIL][AodhProps.TYPE])
|
||||
# Copyright 2016 - ZTE, Nokia
|
||||
#
|
||||
# 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.
|
||||
|
||||
from oslo_config import cfg
|
||||
|
||||
from vitrage.common.constants import DatasourceOpts as DSOpts
|
||||
from vitrage.common.constants import DatasourceProperties as DSProps
|
||||
from vitrage.common.constants import UpdateMethod
|
||||
from vitrage.datasources.aodh import AODH_DATASOURCE
|
||||
from vitrage.datasources.aodh.properties import AodhEventType
|
||||
from vitrage.datasources.aodh.properties import AodhProperties as AodhProps
|
||||
from vitrage.tests import base
|
||||
from vitrage.tests.mocks import mock_driver
|
||||
from vitrage.tests.unit.datasources.aodh.mock_driver import MockAodhDriver
|
||||
|
||||
|
||||
class AodhDriverTest(base.BaseTest):
|
||||
|
||||
OPTS = [
|
||||
cfg.StrOpt(DSOpts.UPDATE_METHOD,
|
||||
default=UpdateMethod.PUSH),
|
||||
]
|
||||
|
||||
# noinspection PyPep8Naming
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
cls.conf = cfg.ConfigOpts()
|
||||
cls.conf.register_opts(cls.OPTS, group=AODH_DATASOURCE)
|
||||
|
||||
def test_event_alarm_notifications(self):
|
||||
|
||||
aodh_driver = MockAodhDriver(self.conf)
|
||||
|
||||
# 1. alarm creation with 'ok' state
|
||||
# prepare data
|
||||
detail_data = {"type": "creation",
|
||||
AodhProps.DETAIL: self._create_alarm_data_type_event()}
|
||||
generators = \
|
||||
mock_driver.simple_aodh_alarm_notification_generators(
|
||||
alarm_num=1,
|
||||
update_events=1,
|
||||
update_vals=detail_data)
|
||||
alarm = mock_driver.generate_sequential_events_list(generators)[0]
|
||||
alarm_info = alarm.copy()
|
||||
|
||||
# action
|
||||
entity = aodh_driver.enrich_event(alarm, AodhEventType.CREATION)
|
||||
|
||||
# Test assertions
|
||||
# alarm with status OK should not be handled
|
||||
self.assertIsNone(entity)
|
||||
|
||||
# 2.alarm state transition from 'ok' to 'alarm'
|
||||
detail_data = {"type": "state transition",
|
||||
AodhProps.DETAIL: {AodhProps.STATE: "alarm"}}
|
||||
alarm.update(detail_data)
|
||||
entity = aodh_driver.enrich_event(alarm,
|
||||
AodhEventType.STATE_TRANSITION)
|
||||
|
||||
# Test assertions
|
||||
# alarm state change: ok->alarm, need to be added
|
||||
self.assertIsNotNone(entity)
|
||||
self._validate_aodh_entity_comm_props(entity, alarm_info)
|
||||
self.assertEqual(entity[AodhProps.STATE],
|
||||
alarm[AodhProps.DETAIL][AodhProps.STATE])
|
||||
self.assertEqual(entity[AodhProps.SEVERITY],
|
||||
alarm[AodhProps.SEVERITY])
|
||||
self.assertEqual(entity[DSProps.EVENT_TYPE],
|
||||
AodhEventType.STATE_TRANSITION)
|
||||
|
||||
# 3. delete alarm which is 'alarm' state
|
||||
# prepare data
|
||||
detail_data = {"type": "deletion"}
|
||||
alarm.update(detail_data)
|
||||
|
||||
# action
|
||||
entity = aodh_driver.enrich_event(alarm, AodhEventType.DELETION)
|
||||
|
||||
# Test assertions
|
||||
self.assertIsNotNone(entity)
|
||||
self._validate_aodh_entity_comm_props(entity, alarm_info)
|
||||
self.assertEqual(entity[DSProps.EVENT_TYPE],
|
||||
AodhEventType.DELETION)
|
||||
|
||||
# 4. alarm creation with 'alarm' state
|
||||
# prepare data
|
||||
detail_data = {"type": "creation",
|
||||
AodhProps.DETAIL:
|
||||
self._create_alarm_data_type_event(state="alarm")}
|
||||
generators = \
|
||||
mock_driver.simple_aodh_alarm_notification_generators(
|
||||
alarm_num=1,
|
||||
update_events=1,
|
||||
update_vals=detail_data)
|
||||
alarm = mock_driver.generate_sequential_events_list(generators)[0]
|
||||
alarm_info = alarm.copy()
|
||||
|
||||
# action
|
||||
entity = aodh_driver.enrich_event(alarm, AodhEventType.CREATION)
|
||||
|
||||
# Test assertions
|
||||
# alarm with status 'alarm' need to be added
|
||||
self.assertIsNotNone(entity)
|
||||
self._validate_aodh_entity_comm_props(entity, alarm_info)
|
||||
self.assertEqual(entity[AodhProps.STATE],
|
||||
alarm[AodhProps.DETAIL][AodhProps.STATE])
|
||||
self.assertEqual(entity[AodhProps.SEVERITY],
|
||||
alarm[AodhProps.SEVERITY])
|
||||
self.assertIsNone(entity[AodhProps.RESOURCE_ID])
|
||||
self.assertEqual("*", entity[AodhProps.EVENT_TYPE])
|
||||
self.assertEqual(entity[DSProps.EVENT_TYPE],
|
||||
AodhEventType.CREATION)
|
||||
|
||||
# 5. alarm rule change
|
||||
# prepare data
|
||||
detail_data = {"type": "rule change",
|
||||
AodhProps.DETAIL: {
|
||||
"severity": "critical",
|
||||
AodhProps.RULE:
|
||||
{"query": [{"field": "traits.resource_id",
|
||||
"type": "",
|
||||
"value": "1",
|
||||
"op": "eq"}],
|
||||
"event_type": "instance.update"}}}
|
||||
alarm.update(detail_data)
|
||||
|
||||
# action
|
||||
entity = aodh_driver.enrich_event(alarm,
|
||||
AodhEventType.RULE_CHANGE)
|
||||
|
||||
# Test assertions
|
||||
# alarm rule change: need to be update
|
||||
self.assertIsNotNone(entity)
|
||||
self._validate_aodh_entity_comm_props(entity, alarm_info)
|
||||
self.assertEqual(entity[AodhProps.SEVERITY],
|
||||
alarm[AodhProps.DETAIL][AodhProps.SEVERITY])
|
||||
self.assertEqual(
|
||||
entity[AodhProps.EVENT_TYPE],
|
||||
alarm[AodhProps.DETAIL][AodhProps.RULE][AodhProps.EVENT_TYPE])
|
||||
self.assertEqual("1", entity[AodhProps.RESOURCE_ID])
|
||||
self.assertEqual(entity[DSProps.EVENT_TYPE],
|
||||
AodhEventType.RULE_CHANGE)
|
||||
|
||||
# 6. alarm state change from 'alarm' to 'ok'
|
||||
# prepare data
|
||||
detail_data = {"type": "state transition",
|
||||
AodhProps.DETAIL: {AodhProps.STATE: "ok"}}
|
||||
alarm.update(detail_data)
|
||||
|
||||
# action
|
||||
entity = aodh_driver.enrich_event(alarm,
|
||||
AodhEventType.STATE_TRANSITION)
|
||||
|
||||
# Test assertions
|
||||
# alarm state change: alarm->OK, need to be deleted
|
||||
self.assertIsNotNone(entity)
|
||||
self._validate_aodh_entity_comm_props(entity, alarm_info)
|
||||
self.assertEqual(entity[DSProps.EVENT_TYPE],
|
||||
AodhEventType.STATE_TRANSITION)
|
||||
|
||||
# 7. delete alarm which is 'ok' state
|
||||
# prepare data
|
||||
detail_data = {"type": "deletion"}
|
||||
alarm.update(detail_data)
|
||||
|
||||
# action
|
||||
entity = aodh_driver.enrich_event(alarm, AodhEventType.DELETION)
|
||||
|
||||
# Test assertions
|
||||
self.assertIsNone(entity)
|
||||
|
||||
def test_gnocchi_threshold_alarm_notifications(self):
|
||||
aodh_driver = MockAodhDriver(self.conf)
|
||||
|
||||
# 1. alarm creation with 'ok' state
|
||||
# prepare data
|
||||
detail_data = {"type": "gnocchi_resources_threshold",
|
||||
AodhProps.DETAIL: self._create_alarm_data_gnocchi()}
|
||||
generators = \
|
||||
mock_driver.simple_aodh_alarm_notification_generators(
|
||||
alarm_num=1,
|
||||
update_events=1,
|
||||
update_vals=detail_data)
|
||||
alarm = mock_driver.generate_sequential_events_list(generators)[0]
|
||||
alarm_info = alarm.copy()
|
||||
|
||||
# action
|
||||
entity = aodh_driver.enrich_event(alarm, AodhEventType.CREATION)
|
||||
|
||||
# Test assertions
|
||||
# alarm with status OK should not be handled
|
||||
self.assertIsNone(entity)
|
||||
|
||||
# 2.alarm state transition from 'ok' to 'alarm'
|
||||
detail_data = {"type": "state transition",
|
||||
AodhProps.DETAIL: {AodhProps.STATE: "alarm"}}
|
||||
alarm.update(detail_data)
|
||||
entity = aodh_driver.enrich_event(alarm,
|
||||
AodhEventType.STATE_TRANSITION)
|
||||
|
||||
# Test assertions
|
||||
# alarm state change: ok->alarm, need to be added
|
||||
self.assertIsNotNone(entity)
|
||||
self._validate_aodh_entity_comm_props(entity, alarm_info)
|
||||
self.assertEqual(entity[AodhProps.STATE],
|
||||
alarm[AodhProps.DETAIL][AodhProps.STATE])
|
||||
self.assertEqual(entity[AodhProps.SEVERITY],
|
||||
alarm[AodhProps.SEVERITY])
|
||||
|
||||
# 3. delete alarm which is 'alarm' state
|
||||
# prepare data
|
||||
detail_data = {"type": "deletion"}
|
||||
alarm.update(detail_data)
|
||||
|
||||
# action
|
||||
entity = aodh_driver.enrich_event(alarm, AodhEventType.DELETION)
|
||||
|
||||
# Test assertions
|
||||
self.assertIsNotNone(entity)
|
||||
self._validate_aodh_entity_comm_props(entity, alarm_info)
|
||||
self.assertEqual(entity[DSProps.EVENT_TYPE],
|
||||
AodhEventType.DELETION)
|
||||
|
||||
# 4. alarm creation with 'alarm' state
|
||||
# prepare data
|
||||
detail_data = {"type": "gnocchi_resources_threshold",
|
||||
AodhProps.DETAIL:
|
||||
self._create_alarm_data_gnocchi(state="alarm")}
|
||||
generators = \
|
||||
mock_driver.simple_aodh_alarm_notification_generators(
|
||||
alarm_num=1,
|
||||
update_events=1,
|
||||
update_vals=detail_data)
|
||||
alarm = mock_driver.generate_sequential_events_list(generators)[0]
|
||||
alarm_info = alarm.copy()
|
||||
|
||||
# action
|
||||
entity = aodh_driver.enrich_event(alarm, AodhEventType.CREATION)
|
||||
|
||||
# Test assertions
|
||||
# alarm with status 'alarm' need to be added
|
||||
self.assertIsNotNone(entity)
|
||||
self._validate_aodh_entity_comm_props(entity, alarm_info)
|
||||
self.assertEqual(entity[AodhProps.STATE],
|
||||
alarm[AodhProps.DETAIL][AodhProps.STATE])
|
||||
self.assertEqual(entity[AodhProps.SEVERITY],
|
||||
alarm[AodhProps.SEVERITY])
|
||||
self.assertEqual(entity[DSProps.EVENT_TYPE],
|
||||
AodhEventType.CREATION)
|
||||
|
||||
# 5. alarm rule change
|
||||
# prepare data
|
||||
detail_data = {"type": "rule change",
|
||||
AodhProps.DETAIL: {
|
||||
"severity": "critical",
|
||||
AodhProps.RULE:
|
||||
{"granularity": "300",
|
||||
"threshold": "0.0123",
|
||||
"comparison_operator": "eq"}}}
|
||||
alarm.update(detail_data)
|
||||
|
||||
# action
|
||||
entity = aodh_driver.enrich_event(alarm,
|
||||
AodhEventType.RULE_CHANGE)
|
||||
|
||||
# Test assertions
|
||||
# alarm rule change: need to be update
|
||||
self.assertIsNotNone(entity)
|
||||
self._validate_aodh_entity_comm_props(entity, alarm_info)
|
||||
self.assertEqual(entity[AodhProps.SEVERITY],
|
||||
alarm[AodhProps.DETAIL][AodhProps.SEVERITY])
|
||||
self.assertEqual(entity[DSProps.EVENT_TYPE],
|
||||
AodhEventType.RULE_CHANGE)
|
||||
|
||||
# 6. alarm state change from 'alarm' to 'ok'
|
||||
# prepare data
|
||||
detail_data = {"type": "state transition",
|
||||
AodhProps.DETAIL: {AodhProps.STATE: "ok"}}
|
||||
alarm.update(detail_data)
|
||||
|
||||
# action
|
||||
entity = aodh_driver.enrich_event(alarm,
|
||||
AodhEventType.STATE_TRANSITION)
|
||||
|
||||
# Test assertions
|
||||
# alarm state change: alarm->OK, need to be deleted
|
||||
self.assertIsNotNone(entity)
|
||||
self._validate_aodh_entity_comm_props(entity, alarm_info)
|
||||
self.assertEqual(entity[DSProps.EVENT_TYPE],
|
||||
AodhEventType.STATE_TRANSITION)
|
||||
|
||||
# 7. delete alarm which is 'ok' state
|
||||
# prepare data
|
||||
detail_data = {"type": "deletion"}
|
||||
alarm.update(detail_data)
|
||||
|
||||
# action
|
||||
entity = aodh_driver.enrich_event(alarm, AodhEventType.DELETION)
|
||||
|
||||
# Test assertions
|
||||
self.assertIsNone(entity)
|
||||
|
||||
def _create_alarm_data_gnocchi(self,
|
||||
state="ok",
|
||||
type="gnocchi_resources_threshold",
|
||||
rule=None):
|
||||
|
||||
if rule is None:
|
||||
rule = {"granularity": "300",
|
||||
"threshold": "0.001",
|
||||
"comparison_operator": "gt",
|
||||
"resource_type": "instance"
|
||||
}
|
||||
return {AodhProps.DESCRIPTION: "test",
|
||||
AodhProps.TIMESTAMP: "2016-11-09T01:39:13.839584",
|
||||
AodhProps.ENABLED: True,
|
||||
AodhProps.STATE_TIMESTAMP: "2016-11-09T01:39:13.839584",
|
||||
AodhProps.ALARM_ID: "7e5c3754-e2eb-4782-ae00-7da5ded8568b",
|
||||
AodhProps.REPEAT_ACTIONS: False,
|
||||
AodhProps.PROJECT_ID: "c365d18fcc03493187016ae743f0cc4d",
|
||||
AodhProps.NAME: "test",
|
||||
AodhProps.SEVERITY: "low",
|
||||
AodhProps.RESOURCE_ID: "88cd2d1d-8af4-4d00-9b5e-f82f8c8b0f8d",
|
||||
AodhProps.TYPE: type,
|
||||
AodhProps.STATE: state,
|
||||
AodhProps.RULE: rule}
|
||||
|
||||
def _create_alarm_data_type_event(self,
|
||||
state="ok",
|
||||
type="event",
|
||||
rule=None):
|
||||
|
||||
if rule is None:
|
||||
rule = {"query": [], "event_type": "*"}
|
||||
return {AodhProps.DESCRIPTION: "test",
|
||||
AodhProps.TIMESTAMP: "2016-11-09T01:39:13.839584",
|
||||
AodhProps.ENABLED: True,
|
||||
AodhProps.STATE_TIMESTAMP: "2016-11-09T01:39:13.839584",
|
||||
AodhProps.ALARM_ID: "7e5c3754-e2eb-4782-ae00-7da5ded8568b",
|
||||
AodhProps.REPEAT_ACTIONS: False,
|
||||
AodhProps.PROJECT_ID: "c365d18fcc03493187016ae743f0cc4d",
|
||||
AodhProps.NAME: "test",
|
||||
AodhProps.SEVERITY: "low",
|
||||
AodhProps.TYPE: type,
|
||||
AodhProps.STATE: state,
|
||||
AodhProps.RULE: rule}
|
||||
|
||||
def _validate_aodh_entity_comm_props(self, entity, alarm):
|
||||
|
||||
self.assertEqual(entity[AodhProps.ALARM_ID],
|
||||
alarm[AodhProps.ALARM_ID])
|
||||
self.assertEqual(entity[AodhProps.PROJECT_ID],
|
||||
alarm[AodhProps.PROJECT_ID])
|
||||
self.assertEqual(entity[AodhProps.TIMESTAMP],
|
||||
alarm[AodhProps.TIMESTAMP])
|
||||
self.assertEqual(entity[AodhProps.DESCRIPTION],
|
||||
alarm[AodhProps.DETAIL][AodhProps.DESCRIPTION])
|
||||
self.assertEqual(entity[AodhProps.ENABLED],
|
||||
alarm[AodhProps.DETAIL][AodhProps.ENABLED])
|
||||
self.assertEqual(entity[AodhProps.NAME],
|
||||
alarm[AodhProps.DETAIL][AodhProps.NAME])
|
||||
self.assertEqual(entity[AodhProps.REPEAT_ACTIONS],
|
||||
alarm[AodhProps.DETAIL][AodhProps.REPEAT_ACTIONS])
|
||||
self.assertEqual(entity[AodhProps.TYPE],
|
||||
alarm[AodhProps.DETAIL][AodhProps.TYPE])
|
||||
|
@ -1,158 +1,158 @@
|
||||
# Copyright 2016 - ZTE, Nokia
|
||||
#
|
||||
# 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.
|
||||
|
||||
from oslo_config import cfg
|
||||
from oslo_log import log as logging
|
||||
|
||||
from vitrage.common.constants import DatasourceOpts as DSOpts
|
||||
from vitrage.common.constants import DatasourceProperties as DSProps
|
||||
from vitrage.common.constants import EntityCategory
|
||||
from vitrage.common.constants import UpdateMethod
|
||||
from vitrage.datasources.aodh import AODH_DATASOURCE
|
||||
from vitrage.datasources.aodh.properties import AodhProperties as AodhProps
|
||||
from vitrage.datasources.aodh.transformer import AodhTransformer
|
||||
from vitrage.datasources.transformer_base import TransformerBase
|
||||
from vitrage.tests.mocks import mock_transformer as mock_sync
|
||||
from vitrage.tests.unit.datasources.aodh.aodh_transformer_base_test import \
|
||||
AodhTransformerBaseTest
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class TestAodhAlarmTransformer(AodhTransformerBaseTest):
|
||||
|
||||
OPTS = [
|
||||
cfg.StrOpt(DSOpts.UPDATE_METHOD,
|
||||
default=UpdateMethod.PULL),
|
||||
]
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
cls.transformers = {}
|
||||
cls.conf = cfg.ConfigOpts()
|
||||
cls.conf.register_opts(cls.OPTS, group=AODH_DATASOURCE)
|
||||
cls.transformers[AODH_DATASOURCE] = \
|
||||
AodhTransformer(cls.transformers, cls.conf)
|
||||
|
||||
def test_key_values_with_vitrage_alarm(self):
|
||||
LOG.debug('Aodh transformer test: get key values(vitrage_alarm)')
|
||||
|
||||
# Test setup
|
||||
entity = {AodhProps.VITRAGE_ID: 'test',
|
||||
DSProps.ENTITY_TYPE: AODH_DATASOURCE,
|
||||
AodhProps.ALARM_ID: '12345'}
|
||||
transformer = self.transformers[AODH_DATASOURCE]
|
||||
|
||||
# Test action
|
||||
observed_key_fields = transformer._create_entity_key(entity)
|
||||
|
||||
# Test assertions
|
||||
self.assertEqual('test', observed_key_fields)
|
||||
|
||||
def test_key_values(self):
|
||||
LOG.debug('Aodh transformer test: get key values(aodh alarm)')
|
||||
|
||||
# Test setup
|
||||
entity = {DSProps.ENTITY_TYPE: AODH_DATASOURCE,
|
||||
AodhProps.ALARM_ID: '12345'}
|
||||
transformer = self.transformers[AODH_DATASOURCE]
|
||||
|
||||
# Test action
|
||||
entity_key_fields = transformer._create_entity_key(entity).split(":")
|
||||
|
||||
# Test assertions
|
||||
self.assertEqual(EntityCategory.ALARM, entity_key_fields[0])
|
||||
self.assertEqual(AODH_DATASOURCE, entity_key_fields[1])
|
||||
self.assertEqual(entity[AodhProps.ALARM_ID], entity_key_fields[2])
|
||||
|
||||
def test_snapshot_transform(self):
|
||||
LOG.debug('Aodh alarm transformer test: transform entity event '
|
||||
'snapshot')
|
||||
|
||||
# Test setup
|
||||
spec_list = mock_sync.simple_aodh_alarm_generators(alarm_num=3,
|
||||
snapshot_events=3)
|
||||
static_events = mock_sync.generate_random_events_list(spec_list)
|
||||
|
||||
for event in static_events:
|
||||
# convert neighbor from dict to vertex object
|
||||
neighbors = event[TransformerBase.QUERY_RESULT]
|
||||
vertices = []
|
||||
for neighbor in neighbors:
|
||||
neighbor_vertex = self._convert_dist_to_vertex(neighbor)
|
||||
vertices.append(self.transformers[AODH_DATASOURCE].
|
||||
update_uuid_in_vertex(neighbor_vertex))
|
||||
event[TransformerBase.QUERY_RESULT] = vertices
|
||||
|
||||
# Test action
|
||||
wrapper = self.transformers[AODH_DATASOURCE].transform(event)
|
||||
|
||||
# Test assertions
|
||||
vertex = wrapper.vertex
|
||||
self._validate_aodh_vertex_props(vertex, event)
|
||||
|
||||
neighbors = wrapper.neighbors
|
||||
self.assertEqual(1, len(neighbors))
|
||||
self._validate_neighbors(neighbors, vertex.vertex_id, event)
|
||||
|
||||
self._validate_action(event, wrapper)
|
||||
|
||||
|
||||
class TestAodhAlarmPushTransformer(AodhTransformerBaseTest):
|
||||
|
||||
OPTS = [
|
||||
cfg.StrOpt(DSOpts.UPDATE_METHOD,
|
||||
default=UpdateMethod.PUSH),
|
||||
]
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
cls.transformers = {}
|
||||
cls.conf = cfg.ConfigOpts()
|
||||
cls.conf.register_opts(cls.OPTS, group=AODH_DATASOURCE)
|
||||
cls.transformers[AODH_DATASOURCE] = \
|
||||
AodhTransformer(cls.transformers, cls.conf)
|
||||
|
||||
def test_update_transform(self):
|
||||
LOG.debug('Aodh update alarm transformer test:'
|
||||
'transform entity event update')
|
||||
|
||||
# Test setup
|
||||
spec_list = \
|
||||
mock_sync.simple_aodh_update_alarm_generators(alarm_num=5,
|
||||
update_events=5)
|
||||
static_events = mock_sync.generate_random_events_list(spec_list)
|
||||
|
||||
for event in static_events:
|
||||
# convert neighbor from dict to vertex object
|
||||
neighbors = event[TransformerBase.QUERY_RESULT]
|
||||
vertices = []
|
||||
for neighbor in neighbors:
|
||||
neighbor_vertex = self._convert_dist_to_vertex(neighbor)
|
||||
vertices.append(self.transformers[AODH_DATASOURCE].
|
||||
update_uuid_in_vertex(neighbor_vertex))
|
||||
event[TransformerBase.QUERY_RESULT] = vertices
|
||||
|
||||
# Test action
|
||||
wrapper = self.transformers[AODH_DATASOURCE].transform(event)
|
||||
|
||||
# Test assertions
|
||||
vertex = wrapper.vertex
|
||||
self._validate_aodh_vertex_props(vertex, event)
|
||||
|
||||
neighbors = wrapper.neighbors
|
||||
self.assertEqual(1, len(neighbors))
|
||||
self._validate_neighbors(neighbors, vertex.vertex_id, event)
|
||||
|
||||
self._validate_action(event, wrapper)
|
||||
# Copyright 2016 - ZTE, Nokia
|
||||
#
|
||||
# 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.
|
||||
|
||||
from oslo_config import cfg
|
||||
from oslo_log import log as logging
|
||||
|
||||
from vitrage.common.constants import DatasourceOpts as DSOpts
|
||||
from vitrage.common.constants import DatasourceProperties as DSProps
|
||||
from vitrage.common.constants import EntityCategory
|
||||
from vitrage.common.constants import UpdateMethod
|
||||
from vitrage.datasources.aodh import AODH_DATASOURCE
|
||||
from vitrage.datasources.aodh.properties import AodhProperties as AodhProps
|
||||
from vitrage.datasources.aodh.transformer import AodhTransformer
|
||||
from vitrage.datasources.transformer_base import TransformerBase
|
||||
from vitrage.tests.mocks import mock_transformer as mock_sync
|
||||
from vitrage.tests.unit.datasources.aodh.aodh_transformer_base_test import \
|
||||
AodhTransformerBaseTest
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class TestAodhAlarmTransformer(AodhTransformerBaseTest):
|
||||
|
||||
OPTS = [
|
||||
cfg.StrOpt(DSOpts.UPDATE_METHOD,
|
||||
default=UpdateMethod.PULL),
|
||||
]
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
cls.transformers = {}
|
||||
cls.conf = cfg.ConfigOpts()
|
||||
cls.conf.register_opts(cls.OPTS, group=AODH_DATASOURCE)
|
||||
cls.transformers[AODH_DATASOURCE] = \
|
||||
AodhTransformer(cls.transformers, cls.conf)
|
||||
|
||||
def test_key_values_with_vitrage_alarm(self):
|
||||
LOG.debug('Aodh transformer test: get key values(vitrage_alarm)')
|
||||
|
||||
# Test setup
|
||||
entity = {AodhProps.VITRAGE_ID: 'test',
|
||||
DSProps.ENTITY_TYPE: AODH_DATASOURCE,
|
||||
AodhProps.ALARM_ID: '12345'}
|
||||
transformer = self.transformers[AODH_DATASOURCE]
|
||||
|
||||
# Test action
|
||||
observed_key_fields = transformer._create_entity_key(entity)
|
||||
|
||||
# Test assertions
|
||||
self.assertEqual('test', observed_key_fields)
|
||||
|
||||
def test_key_values(self):
|
||||
LOG.debug('Aodh transformer test: get key values(aodh alarm)')
|
||||
|
||||
# Test setup
|
||||
entity = {DSProps.ENTITY_TYPE: AODH_DATASOURCE,
|
||||
AodhProps.ALARM_ID: '12345'}
|
||||
transformer = self.transformers[AODH_DATASOURCE]
|
||||
|
||||
# Test action
|
||||
entity_key_fields = transformer._create_entity_key(entity).split(":")
|
||||
|
||||
# Test assertions
|
||||
self.assertEqual(EntityCategory.ALARM, entity_key_fields[0])
|
||||
self.assertEqual(AODH_DATASOURCE, entity_key_fields[1])
|
||||
self.assertEqual(entity[AodhProps.ALARM_ID], entity_key_fields[2])
|
||||
|
||||
def test_snapshot_transform(self):
|
||||
LOG.debug('Aodh alarm transformer test: transform entity event '
|
||||
'snapshot')
|
||||
|
||||
# Test setup
|
||||
spec_list = mock_sync.simple_aodh_alarm_generators(alarm_num=3,
|
||||
snapshot_events=3)
|
||||
static_events = mock_sync.generate_random_events_list(spec_list)
|
||||
|
||||
for event in static_events:
|
||||
# convert neighbor from dict to vertex object
|
||||
neighbors = event[TransformerBase.QUERY_RESULT]
|
||||
vertices = []
|
||||
for neighbor in neighbors:
|
||||
neighbor_vertex = self._convert_dist_to_vertex(neighbor)
|
||||
vertices.append(self.transformers[AODH_DATASOURCE].
|
||||
update_uuid_in_vertex(neighbor_vertex))
|
||||
event[TransformerBase.QUERY_RESULT] = vertices
|
||||
|
||||
# Test action
|
||||
wrapper = self.transformers[AODH_DATASOURCE].transform(event)
|
||||
|
||||
# Test assertions
|
||||
vertex = wrapper.vertex
|
||||
self._validate_aodh_vertex_props(vertex, event)
|
||||
|
||||
neighbors = wrapper.neighbors
|
||||
self.assertEqual(1, len(neighbors))
|
||||
self._validate_neighbors(neighbors, vertex.vertex_id, event)
|
||||
|
||||
self._validate_action(event, wrapper)
|
||||
|
||||
|
||||
class TestAodhAlarmPushTransformer(AodhTransformerBaseTest):
|
||||
|
||||
OPTS = [
|
||||
cfg.StrOpt(DSOpts.UPDATE_METHOD,
|
||||
default=UpdateMethod.PUSH),
|
||||
]
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
cls.transformers = {}
|
||||
cls.conf = cfg.ConfigOpts()
|
||||
cls.conf.register_opts(cls.OPTS, group=AODH_DATASOURCE)
|
||||
cls.transformers[AODH_DATASOURCE] = \
|
||||
AodhTransformer(cls.transformers, cls.conf)
|
||||
|
||||
def test_update_transform(self):
|
||||
LOG.debug('Aodh update alarm transformer test:'
|
||||
'transform entity event update')
|
||||
|
||||
# Test setup
|
||||
spec_list = \
|
||||
mock_sync.simple_aodh_update_alarm_generators(alarm_num=5,
|
||||
update_events=5)
|
||||
static_events = mock_sync.generate_random_events_list(spec_list)
|
||||
|
||||
for event in static_events:
|
||||
# convert neighbor from dict to vertex object
|
||||
neighbors = event[TransformerBase.QUERY_RESULT]
|
||||
vertices = []
|
||||
for neighbor in neighbors:
|
||||
neighbor_vertex = self._convert_dist_to_vertex(neighbor)
|
||||
vertices.append(self.transformers[AODH_DATASOURCE].
|
||||
update_uuid_in_vertex(neighbor_vertex))
|
||||
event[TransformerBase.QUERY_RESULT] = vertices
|
||||
|
||||
# Test action
|
||||
wrapper = self.transformers[AODH_DATASOURCE].transform(event)
|
||||
|
||||
# Test assertions
|
||||
vertex = wrapper.vertex
|
||||
self._validate_aodh_vertex_props(vertex, event)
|
||||
|
||||
neighbors = wrapper.neighbors
|
||||
self.assertEqual(1, len(neighbors))
|
||||
self._validate_neighbors(neighbors, vertex.vertex_id, event)
|
||||
|
||||
self._validate_action(event, wrapper)
|
||||
|
@ -1,15 +1,15 @@
|
||||
# Copyright 2017 - ZTE
|
||||
#
|
||||
# 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.
|
||||
|
||||
__author__ = 'stack'
|
||||
# Copyright 2017 - ZTE
|
||||
#
|
||||
# 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.
|
||||
|
||||
__author__ = 'stack'
|
||||
|
@ -1,119 +1,119 @@
|
||||
# Copyright 2017 - ZTE, Nokia
|
||||
#
|
||||
# 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.
|
||||
|
||||
from vitrage.common.constants import DatasourceAction
|
||||
from vitrage.common.constants import DatasourceProperties as DSProps
|
||||
from vitrage.common.constants import EdgeLabel
|
||||
from vitrage.common.constants import EntityCategory
|
||||
from vitrage.common.constants import GraphAction
|
||||
from vitrage.common.constants import VertexProperties as VProps
|
||||
from vitrage.datasources.alarm_properties import AlarmProperties as AlarmProps
|
||||
from vitrage.datasources.ceilometer.properties \
|
||||
import CeilometerProperties as CeilProps
|
||||
from vitrage.datasources.ceilometer.properties import CeilometerState
|
||||
from vitrage.datasources.nova.instance import NOVA_INSTANCE_DATASOURCE
|
||||
from vitrage.datasources.transformer_base import TransformerBase
|
||||
from vitrage.graph.driver.elements import Vertex
|
||||
from vitrage.tests import base
|
||||
|
||||
|
||||
class CeilometerTransformerBaseTest(base.BaseTest):
|
||||
|
||||
def _validate_aodh_vertex_props(self, vertex, event):
|
||||
|
||||
self.assertEqual(EntityCategory.ALARM,
|
||||
vertex[VProps.VITRAGE_CATEGORY])
|
||||
self.assertEqual(event[DSProps.ENTITY_TYPE],
|
||||
vertex[VProps.VITRAGE_TYPE])
|
||||
self.assertEqual(event[CeilProps.NAME], vertex[VProps.NAME])
|
||||
self.assertEqual(event[CeilProps.SEVERITY],
|
||||
vertex[VProps.SEVERITY])
|
||||
self.assertEqual(event[CeilProps.DESCRIPTION],
|
||||
vertex[CeilProps.DESCRIPTION])
|
||||
self.assertEqual(event[CeilProps.ENABLED],
|
||||
vertex[CeilProps.ENABLED])
|
||||
self.assertEqual(event[CeilProps.PROJECT_ID],
|
||||
vertex[VProps.PROJECT_ID])
|
||||
self.assertEqual(event[CeilProps.REPEAT_ACTIONS],
|
||||
vertex[CeilProps.REPEAT_ACTIONS])
|
||||
self.assertEqual(event[CeilProps.TYPE], vertex['alarm_type'])
|
||||
if event[CeilProps.TYPE] == CeilProps.EVENT:
|
||||
self.assertEqual(event[CeilProps.EVENT_TYPE],
|
||||
vertex[CeilProps.EVENT_TYPE])
|
||||
elif event[CeilProps.TYPE] == CeilProps.THRESHOLD:
|
||||
self.assertEqual(event[CeilProps.STATE_TIMESTAMP],
|
||||
vertex[CeilProps.STATE_TIMESTAMP])
|
||||
self.assertEqual(event[DSProps.SAMPLE_DATE],
|
||||
vertex[VProps.VITRAGE_SAMPLE_TIMESTAMP])
|
||||
|
||||
event_status = event[CeilProps.STATE]
|
||||
if event_status == CeilometerState.OK:
|
||||
self.assertEqual(AlarmProps.INACTIVE_STATE,
|
||||
vertex[VProps.STATE])
|
||||
else:
|
||||
self.assertEqual(AlarmProps.ACTIVE_STATE,
|
||||
vertex[VProps.STATE])
|
||||
self.assertFalse(vertex[VProps.VITRAGE_IS_PLACEHOLDER])
|
||||
self.assertFalse(vertex[VProps.VITRAGE_IS_DELETED])
|
||||
|
||||
def _validate_action(self, alarm, wrapper):
|
||||
if DSProps.EVENT_TYPE in alarm \
|
||||
and alarm[DSProps.EVENT_TYPE] in GraphAction.__dict__.values():
|
||||
self.assertEqual(alarm[DSProps.EVENT_TYPE], wrapper.action)
|
||||
return
|
||||
|
||||
ds_action = alarm[DSProps.DATASOURCE_ACTION]
|
||||
if ds_action in (DatasourceAction.SNAPSHOT, DatasourceAction.UPDATE):
|
||||
self.assertEqual(GraphAction.UPDATE_ENTITY, wrapper.action)
|
||||
else:
|
||||
self.assertEqual(GraphAction.CREATE_ENTITY, wrapper.action)
|
||||
|
||||
def _validate_neighbors(self, neighbors, alarm_id, event):
|
||||
resource_counter = 0
|
||||
|
||||
for neighbor in neighbors:
|
||||
resource_id = event[CeilProps.RESOURCE_ID]
|
||||
self._validate_instance_neighbor(neighbor,
|
||||
resource_id,
|
||||
alarm_id)
|
||||
resource_counter += 1
|
||||
|
||||
self.assertEqual(1,
|
||||
resource_counter,
|
||||
'Alarm can be belonged to only one resource')
|
||||
|
||||
def _validate_instance_neighbor(self,
|
||||
alarm_neighbor,
|
||||
resource_id,
|
||||
alarm_vertex_id):
|
||||
# validate neighbor vertex
|
||||
self.assertEqual(EntityCategory.RESOURCE,
|
||||
alarm_neighbor.vertex[VProps.VITRAGE_CATEGORY])
|
||||
self.assertEqual(NOVA_INSTANCE_DATASOURCE,
|
||||
alarm_neighbor.vertex[VProps.VITRAGE_TYPE])
|
||||
self.assertEqual(resource_id, alarm_neighbor.vertex[VProps.ID])
|
||||
self.assertFalse(alarm_neighbor.vertex[VProps.VITRAGE_IS_PLACEHOLDER])
|
||||
self.assertFalse(alarm_neighbor.vertex[VProps.VITRAGE_IS_DELETED])
|
||||
|
||||
# Validate neighbor edge
|
||||
edge = alarm_neighbor.edge
|
||||
self.assertEqual(edge.target_id, alarm_neighbor.vertex.vertex_id)
|
||||
self.assertEqual(edge.source_id, alarm_vertex_id)
|
||||
self.assertEqual(edge.label, EdgeLabel.ON)
|
||||
|
||||
def _convert_dist_to_vertex(self, neighbor):
|
||||
ver_id = neighbor[VProps.VITRAGE_CATEGORY] + \
|
||||
TransformerBase.KEY_SEPARATOR + neighbor[VProps.VITRAGE_TYPE] + \
|
||||
TransformerBase.KEY_SEPARATOR + neighbor[VProps.ID]
|
||||
return Vertex(vertex_id=ver_id, properties=neighbor)
|
||||
# Copyright 2017 - ZTE, Nokia
|
||||
#
|
||||
# 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.
|
||||
|
||||
from vitrage.common.constants import DatasourceAction
|
||||
from vitrage.common.constants import DatasourceProperties as DSProps
|
||||
from vitrage.common.constants import EdgeLabel
|
||||
from vitrage.common.constants import EntityCategory
|
||||
from vitrage.common.constants import GraphAction
|
||||
from vitrage.common.constants import VertexProperties as VProps
|
||||
from vitrage.datasources.alarm_properties import AlarmProperties as AlarmProps
|
||||
from vitrage.datasources.ceilometer.properties \
|
||||
import CeilometerProperties as CeilProps
|
||||
from vitrage.datasources.ceilometer.properties import CeilometerState
|
||||
from vitrage.datasources.nova.instance import NOVA_INSTANCE_DATASOURCE
|
||||
from vitrage.datasources.transformer_base import TransformerBase
|
||||
from vitrage.graph.driver.elements import Vertex
|
||||
from vitrage.tests import base
|
||||
|
||||
|
||||
class CeilometerTransformerBaseTest(base.BaseTest):
|
||||
|
||||
def _validate_aodh_vertex_props(self, vertex, event):
|
||||
|
||||
self.assertEqual(EntityCategory.ALARM,
|
||||
vertex[VProps.VITRAGE_CATEGORY])
|
||||
self.assertEqual(event[DSProps.ENTITY_TYPE],
|
||||
vertex[VProps.VITRAGE_TYPE])
|
||||
self.assertEqual(event[CeilProps.NAME], vertex[VProps.NAME])
|
||||
self.assertEqual(event[CeilProps.SEVERITY],
|
||||
vertex[VProps.SEVERITY])
|
||||
self.assertEqual(event[CeilProps.DESCRIPTION],
|
||||
vertex[CeilProps.DESCRIPTION])
|
||||
self.assertEqual(event[CeilProps.ENABLED],
|
||||
vertex[CeilProps.ENABLED])
|
||||
self.assertEqual(event[CeilProps.PROJECT_ID],
|
||||
vertex[VProps.PROJECT_ID])
|
||||
self.assertEqual(event[CeilProps.REPEAT_ACTIONS],
|
||||
vertex[CeilProps.REPEAT_ACTIONS])
|
||||
self.assertEqual(event[CeilProps.TYPE], vertex['alarm_type'])
|
||||
if event[CeilProps.TYPE] == CeilProps.EVENT:
|
||||
self.assertEqual(event[CeilProps.EVENT_TYPE],
|
||||
vertex[CeilProps.EVENT_TYPE])
|
||||
elif event[CeilProps.TYPE] == CeilProps.THRESHOLD:
|
||||
self.assertEqual(event[CeilProps.STATE_TIMESTAMP],
|
||||
vertex[CeilProps.STATE_TIMESTAMP])
|
||||
self.assertEqual(event[DSProps.SAMPLE_DATE],
|
||||
vertex[VProps.VITRAGE_SAMPLE_TIMESTAMP])
|
||||
|
||||
event_status = event[CeilProps.STATE]
|
||||
if event_status == CeilometerState.OK:
|
||||
self.assertEqual(AlarmProps.INACTIVE_STATE,
|
||||
vertex[VProps.STATE])
|
||||
else:
|
||||
self.assertEqual(AlarmProps.ACTIVE_STATE,
|
||||
vertex[VProps.STATE])
|
||||
self.assertFalse(vertex[VProps.VITRAGE_IS_PLACEHOLDER])
|
||||
self.assertFalse(vertex[VProps.VITRAGE_IS_DELETED])
|
||||
|
||||
def _validate_action(self, alarm, wrapper):
|
||||
if DSProps.EVENT_TYPE in alarm \
|
||||
and alarm[DSProps.EVENT_TYPE] in GraphAction.__dict__.values():
|
||||
self.assertEqual(alarm[DSProps.EVENT_TYPE], wrapper.action)
|
||||
return
|
||||
|
||||
ds_action = alarm[DSProps.DATASOURCE_ACTION]
|
||||
if ds_action in (DatasourceAction.SNAPSHOT, DatasourceAction.UPDATE):
|
||||
self.assertEqual(GraphAction.UPDATE_ENTITY, wrapper.action)
|
||||
else:
|
||||
self.assertEqual(GraphAction.CREATE_ENTITY, wrapper.action)
|
||||
|
||||
def _validate_neighbors(self, neighbors, alarm_id, event):
|
||||
resource_counter = 0
|
||||
|
||||
for neighbor in neighbors:
|
||||
resource_id = event[CeilProps.RESOURCE_ID]
|
||||
self._validate_instance_neighbor(neighbor,
|
||||
resource_id,
|
||||
alarm_id)
|
||||
resource_counter += 1
|
||||
|
||||
self.assertEqual(1,
|
||||
resource_counter,
|
||||
'Alarm can be belonged to only one resource')
|
||||
|
||||
def _validate_instance_neighbor(self,
|
||||
alarm_neighbor,
|
||||
resource_id,
|
||||
alarm_vertex_id):
|
||||
# validate neighbor vertex
|
||||
self.assertEqual(EntityCategory.RESOURCE,
|
||||
alarm_neighbor.vertex[VProps.VITRAGE_CATEGORY])
|
||||
self.assertEqual(NOVA_INSTANCE_DATASOURCE,
|
||||
alarm_neighbor.vertex[VProps.VITRAGE_TYPE])
|
||||
self.assertEqual(resource_id, alarm_neighbor.vertex[VProps.ID])
|
||||
self.assertFalse(alarm_neighbor.vertex[VProps.VITRAGE_IS_PLACEHOLDER])
|
||||
self.assertFalse(alarm_neighbor.vertex[VProps.VITRAGE_IS_DELETED])
|
||||
|
||||
# Validate neighbor edge
|
||||
edge = alarm_neighbor.edge
|
||||
self.assertEqual(edge.target_id, alarm_neighbor.vertex.vertex_id)
|
||||
self.assertEqual(edge.source_id, alarm_vertex_id)
|
||||
self.assertEqual(edge.label, EdgeLabel.ON)
|
||||
|
||||
def _convert_dist_to_vertex(self, neighbor):
|
||||
ver_id = neighbor[VProps.VITRAGE_CATEGORY] + \
|
||||
TransformerBase.KEY_SEPARATOR + neighbor[VProps.VITRAGE_TYPE] + \
|
||||
TransformerBase.KEY_SEPARATOR + neighbor[VProps.ID]
|
||||
return Vertex(vertex_id=ver_id, properties=neighbor)
|
||||
|
@ -1,27 +1,27 @@
|
||||
# Copyright 2017 - Nokia
|
||||
#
|
||||
# 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.
|
||||
|
||||
from vitrage.datasources.ceilometer.driver import CeilometerDriver
|
||||
|
||||
|
||||
class MockCeilometerDriver(CeilometerDriver):
|
||||
"""A aodh driver for tests.
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, conf):
|
||||
super(MockCeilometerDriver, self).__init__(conf)
|
||||
|
||||
def _cache_all_alarms(self):
|
||||
pass
|
||||
# Copyright 2017 - Nokia
|
||||
#
|
||||
# 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.
|
||||
|
||||
from vitrage.datasources.ceilometer.driver import CeilometerDriver
|
||||
|
||||
|
||||
class MockCeilometerDriver(CeilometerDriver):
|
||||
"""A aodh driver for tests.
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, conf):
|
||||
super(MockCeilometerDriver, self).__init__(conf)
|
||||
|
||||
def _cache_all_alarms(self):
|
||||
pass
|
||||
|
@ -1,389 +1,389 @@
|
||||
# Copyright 2017 - ZTE, Nokia
|
||||
#
|
||||
# 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.
|
||||
|
||||
from oslo_config import cfg
|
||||
|
||||
from vitrage.common.constants import DatasourceOpts as DSOpts
|
||||
from vitrage.common.constants import DatasourceProperties as DSProps
|
||||
from vitrage.common.constants import UpdateMethod
|
||||
from vitrage.datasources.ceilometer import CEILOMETER_DATASOURCE
|
||||
from vitrage.datasources.ceilometer.properties import CeilometerEventType
|
||||
from vitrage.datasources.ceilometer.properties \
|
||||
import CeilometerProperties as CeilProps
|
||||
from vitrage.tests import base
|
||||
from vitrage.tests.mocks import mock_driver
|
||||
from vitrage.tests.unit.datasources.ceilometer.mock_driver \
|
||||
import MockCeilometerDriver
|
||||
|
||||
|
||||
class CeilometerDriverTest(base.BaseTest):
|
||||
|
||||
OPTS = [
|
||||
cfg.StrOpt(DSOpts.UPDATE_METHOD,
|
||||
default=UpdateMethod.PUSH),
|
||||
]
|
||||
|
||||
# noinspection PyPep8Naming
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
cls.conf = cfg.ConfigOpts()
|
||||
cls.conf.register_opts(cls.OPTS, group=CEILOMETER_DATASOURCE)
|
||||
|
||||
def test_event_alarm_notifications(self):
|
||||
|
||||
aodh_driver = MockCeilometerDriver(self.conf)
|
||||
|
||||
# 1. alarm creation with 'ok' state
|
||||
# prepare data
|
||||
detail_data = {"type": "creation",
|
||||
CeilProps.DETAIL: self._create_alarm_data_type_event(),
|
||||
}
|
||||
generators = \
|
||||
mock_driver.simple_aodh_alarm_notification_generators(
|
||||
alarm_num=1,
|
||||
update_events=1,
|
||||
update_vals=detail_data)
|
||||
alarm = mock_driver.generate_sequential_events_list(generators)[0]
|
||||
alarm_info = alarm.copy()
|
||||
|
||||
# action
|
||||
entity = aodh_driver.enrich_event(alarm, CeilometerEventType.CREATION)
|
||||
|
||||
# Test assertions
|
||||
# alarm with status OK should not be handled
|
||||
self.assertIsNone(entity)
|
||||
|
||||
# 2.alarm state transition from 'ok' to 'alarm'
|
||||
detail_data = {"type": "state transition",
|
||||
CeilProps.DETAIL: {CeilProps.STATE: "alarm"}}
|
||||
alarm.update(detail_data)
|
||||
entity = aodh_driver.enrich_event(alarm,
|
||||
CeilometerEventType.STATE_TRANSITION)
|
||||
|
||||
# Test assertions
|
||||
# alarm state change: ok->alarm, need to be added
|
||||
self.assertIsNotNone(entity)
|
||||
self._validate_aodh_entity_comm_props(entity, alarm_info)
|
||||
self.assertEqual(entity[CeilProps.STATE],
|
||||
alarm[CeilProps.DETAIL][CeilProps.STATE])
|
||||
self.assertEqual(entity[CeilProps.SEVERITY],
|
||||
alarm[CeilProps.SEVERITY])
|
||||
self.assertEqual(entity[DSProps.EVENT_TYPE],
|
||||
CeilometerEventType.STATE_TRANSITION)
|
||||
|
||||
# 3. delete alarm which is 'alarm' state
|
||||
# prepare data
|
||||
detail_data = {"type": "deletion"}
|
||||
alarm.update(detail_data)
|
||||
|
||||
# action
|
||||
entity = aodh_driver.enrich_event(
|
||||
alarm, CeilometerEventType.DELETION)
|
||||
|
||||
# Test assertions
|
||||
self.assertIsNotNone(entity)
|
||||
self._validate_aodh_entity_comm_props(entity, alarm_info)
|
||||
self.assertEqual(entity[DSProps.EVENT_TYPE],
|
||||
CeilometerEventType.DELETION)
|
||||
|
||||
# 4. alarm creation with 'alarm' state
|
||||
# prepare data
|
||||
detail_data = {"type": "creation",
|
||||
CeilProps.DETAIL:
|
||||
self._create_alarm_data_type_event(state="alarm")}
|
||||
generators = \
|
||||
mock_driver.simple_aodh_alarm_notification_generators(
|
||||
alarm_num=1,
|
||||
update_events=1,
|
||||
update_vals=detail_data)
|
||||
alarm = mock_driver.generate_sequential_events_list(generators)[0]
|
||||
alarm_info = alarm.copy()
|
||||
|
||||
# action
|
||||
entity = aodh_driver.enrich_event(
|
||||
alarm, CeilometerEventType.CREATION)
|
||||
|
||||
# Test assertions
|
||||
# alarm with status 'alarm' need to be added
|
||||
self.assertIsNotNone(entity)
|
||||
self._validate_aodh_entity_comm_props(entity, alarm_info)
|
||||
self.assertEqual(entity[CeilProps.STATE],
|
||||
alarm[CeilProps.DETAIL][CeilProps.STATE])
|
||||
self.assertEqual(entity[CeilProps.SEVERITY],
|
||||
alarm[CeilProps.SEVERITY])
|
||||
self.assertIsNone(entity[CeilProps.RESOURCE_ID])
|
||||
self.assertEqual("*", entity[CeilProps.EVENT_TYPE])
|
||||
self.assertEqual(entity[DSProps.EVENT_TYPE],
|
||||
CeilometerEventType.CREATION)
|
||||
|
||||
# 5. alarm rule change
|
||||
# prepare data
|
||||
detail_data = {"type": "rule change",
|
||||
CeilProps.DETAIL: {
|
||||
"severity": "critical",
|
||||
CeilProps.RULE:
|
||||
{"query": [{"field": "traits.resource_id",
|
||||
"type": "",
|
||||
"value": "1",
|
||||
"op": "eq"}],
|
||||
"event_type": "instance.update"}}}
|
||||
alarm.update(detail_data)
|
||||
|
||||
# action
|
||||
entity = aodh_driver.enrich_event(
|
||||
alarm, CeilometerEventType.RULE_CHANGE)
|
||||
|
||||
# Test assertions
|
||||
# alarm rule change: need to be update
|
||||
self.assertIsNotNone(entity)
|
||||
self._validate_aodh_entity_comm_props(entity, alarm_info)
|
||||
self.assertEqual(entity[CeilProps.SEVERITY],
|
||||
alarm[CeilProps.DETAIL][CeilProps.SEVERITY])
|
||||
self.assertEqual(
|
||||
entity[CeilProps.EVENT_TYPE],
|
||||
alarm[CeilProps.DETAIL][CeilProps.RULE][CeilProps.EVENT_TYPE])
|
||||
self.assertEqual("1", entity[CeilProps.RESOURCE_ID])
|
||||
self.assertEqual(entity[DSProps.EVENT_TYPE],
|
||||
CeilometerEventType.RULE_CHANGE)
|
||||
|
||||
# 6. alarm state change from 'alarm' to 'ok'
|
||||
# prepare data
|
||||
detail_data = {"type": "state transition",
|
||||
CeilProps.DETAIL: {CeilProps.STATE: "ok"}}
|
||||
alarm.update(detail_data)
|
||||
|
||||
# action
|
||||
entity = aodh_driver.enrich_event(
|
||||
alarm, CeilometerEventType.STATE_TRANSITION)
|
||||
|
||||
# Test assertions
|
||||
# alarm state change: alarm->OK, need to be deleted
|
||||
self.assertIsNotNone(entity)
|
||||
self._validate_aodh_entity_comm_props(entity, alarm_info)
|
||||
self.assertEqual(entity[DSProps.EVENT_TYPE],
|
||||
CeilometerEventType.STATE_TRANSITION)
|
||||
|
||||
# 7. delete alarm which is 'ok' state
|
||||
# prepare data
|
||||
detail_data = {"type": "deletion"}
|
||||
alarm.update(detail_data)
|
||||
|
||||
# action
|
||||
entity = aodh_driver.enrich_event(
|
||||
alarm, CeilometerEventType.DELETION)
|
||||
|
||||
# Test assertions
|
||||
self.assertIsNone(entity)
|
||||
|
||||
def test_gnocchi_threshold_alarm_notifications(self):
|
||||
aodh_driver = MockCeilometerDriver(self.conf)
|
||||
|
||||
# 1. alarm creation with 'ok' state
|
||||
# prepare data
|
||||
detail_data = {"type": "gnocchi_resources_threshold",
|
||||
CeilProps.DETAIL: self._create_alarm_data_gnocchi()}
|
||||
generators = \
|
||||
mock_driver.simple_aodh_alarm_notification_generators(
|
||||
alarm_num=1,
|
||||
update_events=1,
|
||||
update_vals=detail_data)
|
||||
alarm = mock_driver.generate_sequential_events_list(generators)[0]
|
||||
alarm_info = alarm.copy()
|
||||
|
||||
# action
|
||||
entity = aodh_driver.enrich_event(
|
||||
alarm, CeilometerEventType.CREATION)
|
||||
|
||||
# Test assertions
|
||||
# alarm with status OK should not be handled
|
||||
self.assertIsNone(entity)
|
||||
|
||||
# 2.alarm state transition from 'ok' to 'alarm'
|
||||
detail_data = {"type": "state transition",
|
||||
CeilProps.DETAIL: {CeilProps.STATE: "alarm"}}
|
||||
alarm.update(detail_data)
|
||||
entity = aodh_driver.enrich_event(
|
||||
alarm, CeilometerEventType.STATE_TRANSITION)
|
||||
|
||||
# Test assertions
|
||||
# alarm state change: ok->alarm, need to be added
|
||||
self.assertIsNotNone(entity)
|
||||
self._validate_aodh_entity_comm_props(entity, alarm_info)
|
||||
self.assertEqual(entity[CeilProps.STATE],
|
||||
alarm[CeilProps.DETAIL][CeilProps.STATE])
|
||||
self.assertEqual(entity[CeilProps.SEVERITY],
|
||||
alarm[CeilProps.SEVERITY])
|
||||
|
||||
# 3. delete alarm which is 'alarm' state
|
||||
# prepare data
|
||||
detail_data = {"type": "deletion"}
|
||||
alarm.update(detail_data)
|
||||
|
||||
# action
|
||||
entity = aodh_driver.enrich_event(
|
||||
alarm, CeilometerEventType.DELETION)
|
||||
|
||||
# Test assertions
|
||||
self.assertIsNotNone(entity)
|
||||
self._validate_aodh_entity_comm_props(entity, alarm_info)
|
||||
self.assertEqual(entity[DSProps.EVENT_TYPE],
|
||||
CeilometerEventType.DELETION)
|
||||
|
||||
# 4. alarm creation with 'alarm' state
|
||||
# prepare data
|
||||
detail_data = {"type": "gnocchi_resources_threshold",
|
||||
CeilProps.DETAIL:
|
||||
self._create_alarm_data_gnocchi(state="alarm")}
|
||||
generators = \
|
||||
mock_driver.simple_aodh_alarm_notification_generators(
|
||||
alarm_num=1,
|
||||
update_events=1,
|
||||
update_vals=detail_data)
|
||||
alarm = mock_driver.generate_sequential_events_list(generators)[0]
|
||||
alarm_info = alarm.copy()
|
||||
|
||||
# action
|
||||
entity = aodh_driver.enrich_event(
|
||||
alarm, CeilometerEventType.CREATION)
|
||||
|
||||
# Test assertions
|
||||
# alarm with status 'alarm' need to be added
|
||||
self.assertIsNotNone(entity)
|
||||
self._validate_aodh_entity_comm_props(entity, alarm_info)
|
||||
self.assertEqual(entity[CeilProps.STATE],
|
||||
alarm[CeilProps.DETAIL][CeilProps.STATE])
|
||||
self.assertEqual(entity[CeilProps.SEVERITY],
|
||||
alarm[CeilProps.SEVERITY])
|
||||
self.assertEqual(entity[DSProps.EVENT_TYPE],
|
||||
CeilometerEventType.CREATION)
|
||||
|
||||
# 5. alarm rule change
|
||||
# prepare data
|
||||
detail_data = {"type": "rule change",
|
||||
CeilProps.DETAIL: {
|
||||
"severity": "critical",
|
||||
CeilProps.RULE:
|
||||
{"granularity": "300",
|
||||
"threshold": "0.0123",
|
||||
"comparison_operator": "eq"}}}
|
||||
alarm.update(detail_data)
|
||||
|
||||
# action
|
||||
entity = aodh_driver.enrich_event(
|
||||
alarm, CeilometerEventType.RULE_CHANGE)
|
||||
|
||||
# Test assertions
|
||||
# alarm rule change: need to be update
|
||||
self.assertIsNotNone(entity)
|
||||
self._validate_aodh_entity_comm_props(entity, alarm_info)
|
||||
self.assertEqual(entity[CeilProps.SEVERITY],
|
||||
alarm[CeilProps.DETAIL][CeilProps.SEVERITY])
|
||||
self.assertEqual(entity[DSProps.EVENT_TYPE],
|
||||
CeilometerEventType.RULE_CHANGE)
|
||||
|
||||
# 6. alarm state change from 'alarm' to 'ok'
|
||||
# prepare data
|
||||
detail_data = {"type": "state transition",
|
||||
CeilProps.DETAIL: {CeilProps.STATE: "ok"}}
|
||||
alarm.update(detail_data)
|
||||
|
||||
# action
|
||||
entity = aodh_driver.enrich_event(
|
||||
alarm,
|
||||
CeilometerEventType.STATE_TRANSITION)
|
||||
|
||||
# Test assertions
|
||||
# alarm state change: alarm->OK, need to be deleted
|
||||
self.assertIsNotNone(entity)
|
||||
self._validate_aodh_entity_comm_props(entity, alarm_info)
|
||||
self.assertEqual(entity[DSProps.EVENT_TYPE],
|
||||
CeilometerEventType.STATE_TRANSITION)
|
||||
|
||||
# 7. delete alarm which is 'ok' state
|
||||
# prepare data
|
||||
detail_data = {"type": "deletion"}
|
||||
alarm.update(detail_data)
|
||||
|
||||
# action
|
||||
entity = aodh_driver.enrich_event(
|
||||
alarm, CeilometerEventType.DELETION)
|
||||
|
||||
# Test assertions
|
||||
self.assertIsNone(entity)
|
||||
|
||||
def _create_alarm_data_gnocchi(self,
|
||||
state="ok",
|
||||
type="gnocchi_resources_threshold",
|
||||
rule=None):
|
||||
|
||||
if rule is None:
|
||||
rule = {"granularity": "300",
|
||||
"threshold": "0.001",
|
||||
"comparison_operator": "gt",
|
||||
"resource_type": "instance"
|
||||
}
|
||||
return {CeilProps.DESCRIPTION: "test",
|
||||
CeilProps.TIMESTAMP: "2016-11-09T01:39:13.839584",
|
||||
CeilProps.ENABLED: True,
|
||||
CeilProps.STATE_TIMESTAMP: "2016-11-09T01:39:13.839584",
|
||||
CeilProps.ALARM_ID: "7e5c3754-e2eb-4782-ae00-7da5ded8568b",
|
||||
CeilProps.REPEAT_ACTIONS: False,
|
||||
CeilProps.PROJECT_ID: "c365d18fcc03493187016ae743f0cc4d",
|
||||
CeilProps.NAME: "test",
|
||||
CeilProps.SEVERITY: "low",
|
||||
CeilProps.RESOURCE_ID: "88cd2d1d-8af4-4d00-9b5e-f82f8c8b0f8d",
|
||||
CeilProps.TYPE: type,
|
||||
CeilProps.STATE: state,
|
||||
CeilProps.RULE: rule,
|
||||
CeilProps.STATE_REASON: 'for test'}
|
||||
|
||||
def _create_alarm_data_type_event(self,
|
||||
state="ok",
|
||||
type="event",
|
||||
rule=None):
|
||||
|
||||
if rule is None:
|
||||
rule = {"query": [], "event_type": "*"}
|
||||
return {CeilProps.DESCRIPTION: "test",
|
||||
CeilProps.TIMESTAMP: "2016-11-09T01:39:13.839584",
|
||||
CeilProps.ENABLED: True,
|
||||
CeilProps.STATE_TIMESTAMP: "2016-11-09T01:39:13.839584",
|
||||
CeilProps.ALARM_ID: "7e5c3754-e2eb-4782-ae00-7da5ded8568b",
|
||||
CeilProps.REPEAT_ACTIONS: False,
|
||||
CeilProps.PROJECT_ID: "c365d18fcc03493187016ae743f0cc4d",
|
||||
CeilProps.NAME: "test",
|
||||
CeilProps.SEVERITY: "low",
|
||||
CeilProps.TYPE: type,
|
||||
CeilProps.STATE: state,
|
||||
CeilProps.RULE: rule,
|
||||
CeilProps.STATE_REASON: 'for test'}
|
||||
|
||||
def _validate_aodh_entity_comm_props(self, entity, alarm):
|
||||
|
||||
self.assertEqual(entity[CeilProps.ALARM_ID],
|
||||
alarm[CeilProps.ALARM_ID])
|
||||
self.assertEqual(entity[CeilProps.PROJECT_ID],
|
||||
alarm[CeilProps.PROJECT_ID])
|
||||
self.assertEqual(entity[CeilProps.TIMESTAMP],
|
||||
alarm[CeilProps.TIMESTAMP])
|
||||
self.assertEqual(entity[CeilProps.DESCRIPTION],
|
||||
alarm[CeilProps.DETAIL][CeilProps.DESCRIPTION])
|
||||
self.assertEqual(entity[CeilProps.ENABLED],
|
||||
alarm[CeilProps.DETAIL][CeilProps.ENABLED])
|
||||
self.assertEqual(entity[CeilProps.NAME],
|
||||
alarm[CeilProps.DETAIL][CeilProps.NAME])
|
||||
self.assertEqual(entity[CeilProps.REPEAT_ACTIONS],
|
||||
alarm[CeilProps.DETAIL][CeilProps.REPEAT_ACTIONS])
|
||||
self.assertEqual(entity[CeilProps.TYPE],
|
||||
alarm[CeilProps.DETAIL][CeilProps.TYPE])
|
||||
# Copyright 2017 - ZTE, Nokia
|
||||
#
|
||||
# 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.
|
||||
|
||||
from oslo_config import cfg
|
||||
|
||||
from vitrage.common.constants import DatasourceOpts as DSOpts
|
||||
from vitrage.common.constants import DatasourceProperties as DSProps
|
||||
from vitrage.common.constants import UpdateMethod
|
||||
from vitrage.datasources.ceilometer import CEILOMETER_DATASOURCE
|
||||
from vitrage.datasources.ceilometer.properties import CeilometerEventType
|
||||
from vitrage.datasources.ceilometer.properties \
|
||||
import CeilometerProperties as CeilProps
|
||||
from vitrage.tests import base
|
||||
from vitrage.tests.mocks import mock_driver
|
||||
from vitrage.tests.unit.datasources.ceilometer.mock_driver \
|
||||
import MockCeilometerDriver
|
||||
|
||||
|
||||
class CeilometerDriverTest(base.BaseTest):
|
||||
|
||||
OPTS = [
|
||||
cfg.StrOpt(DSOpts.UPDATE_METHOD,
|
||||
default=UpdateMethod.PUSH),
|
||||
]
|
||||
|
||||
# noinspection PyPep8Naming
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
cls.conf = cfg.ConfigOpts()
|
||||
cls.conf.register_opts(cls.OPTS, group=CEILOMETER_DATASOURCE)
|
||||
|
||||
def test_event_alarm_notifications(self):
|
||||
|
||||
aodh_driver = MockCeilometerDriver(self.conf)
|
||||
|
||||
# 1. alarm creation with 'ok' state
|
||||
# prepare data
|
||||
detail_data = {"type": "creation",
|
||||
CeilProps.DETAIL: self._create_alarm_data_type_event(),
|
||||
}
|
||||
generators = \
|
||||
mock_driver.simple_aodh_alarm_notification_generators(
|
||||
alarm_num=1,
|
||||
update_events=1,
|
||||
update_vals=detail_data)
|
||||
alarm = mock_driver.generate_sequential_events_list(generators)[0]
|
||||
alarm_info = alarm.copy()
|
||||
|
||||
# action
|
||||
entity = aodh_driver.enrich_event(alarm, CeilometerEventType.CREATION)
|
||||
|
||||
# Test assertions
|
||||
# alarm with status OK should not be handled
|
||||
self.assertIsNone(entity)
|
||||
|
||||
# 2.alarm state transition from 'ok' to 'alarm'
|
||||
detail_data = {"type": "state transition",
|
||||
CeilProps.DETAIL: {CeilProps.STATE: "alarm"}}
|
||||
alarm.update(detail_data)
|
||||
entity = aodh_driver.enrich_event(alarm,
|
||||
CeilometerEventType.STATE_TRANSITION)
|
||||
|
||||
# Test assertions
|
||||
# alarm state change: ok->alarm, need to be added
|
||||
self.assertIsNotNone(entity)
|
||||
self._validate_aodh_entity_comm_props(entity, alarm_info)
|
||||
self.assertEqual(entity[CeilProps.STATE],
|
||||
alarm[CeilProps.DETAIL][CeilProps.STATE])
|
||||
self.assertEqual(entity[CeilProps.SEVERITY],
|
||||
alarm[CeilProps.SEVERITY])
|
||||
self.assertEqual(entity[DSProps.EVENT_TYPE],
|
||||
CeilometerEventType.STATE_TRANSITION)
|
||||
|
||||
# 3. delete alarm which is 'alarm' state
|
||||
# prepare data
|
||||
detail_data = {"type": "deletion"}
|
||||
alarm.update(detail_data)
|
||||
|
||||
# action
|
||||
entity = aodh_driver.enrich_event(
|
||||
alarm, CeilometerEventType.DELETION)
|
||||
|
||||
# Test assertions
|
||||
self.assertIsNotNone(entity)
|
||||
self._validate_aodh_entity_comm_props(entity, alarm_info)
|
||||
self.assertEqual(entity[DSProps.EVENT_TYPE],
|
||||
CeilometerEventType.DELETION)
|
||||
|
||||
# 4. alarm creation with 'alarm' state
|
||||
# prepare data
|
||||
detail_data = {"type": "creation",
|
||||
CeilProps.DETAIL:
|
||||
self._create_alarm_data_type_event(state="alarm")}
|
||||
generators = \
|
||||
mock_driver.simple_aodh_alarm_notification_generators(
|
||||
alarm_num=1,
|
||||
update_events=1,
|
||||
update_vals=detail_data)
|
||||
alarm = mock_driver.generate_sequential_events_list(generators)[0]
|
||||
alarm_info = alarm.copy()
|
||||
|
||||
# action
|
||||
entity = aodh_driver.enrich_event(
|
||||
alarm, CeilometerEventType.CREATION)
|
||||
|
||||
# Test assertions
|
||||
# alarm with status 'alarm' need to be added
|
||||
self.assertIsNotNone(entity)
|
||||
self._validate_aodh_entity_comm_props(entity, alarm_info)
|
||||
self.assertEqual(entity[CeilProps.STATE],
|
||||
alarm[CeilProps.DETAIL][CeilProps.STATE])
|
||||
self.assertEqual(entity[CeilProps.SEVERITY],
|
||||
alarm[CeilProps.SEVERITY])
|
||||
self.assertIsNone(entity[CeilProps.RESOURCE_ID])
|
||||
self.assertEqual("*", entity[CeilProps.EVENT_TYPE])
|
||||
self.assertEqual(entity[DSProps.EVENT_TYPE],
|
||||
CeilometerEventType.CREATION)
|
||||
|
||||
# 5. alarm rule change
|
||||
# prepare data
|
||||
detail_data = {"type": "rule change",
|
||||
CeilProps.DETAIL: {
|
||||
"severity": "critical",
|
||||
CeilProps.RULE:
|
||||
{"query": [{"field": "traits.resource_id",
|
||||
"type": "",
|
||||
"value": "1",
|
||||
"op": "eq"}],
|
||||
"event_type": "instance.update"}}}
|
||||
alarm.update(detail_data)
|
||||
|
||||
# action
|
||||
entity = aodh_driver.enrich_event(
|
||||
alarm, CeilometerEventType.RULE_CHANGE)
|
||||
|
||||
# Test assertions
|
||||
# alarm rule change: need to be update
|
||||
self.assertIsNotNone(entity)
|
||||
self._validate_aodh_entity_comm_props(entity, alarm_info)
|
||||
self.assertEqual(entity[CeilProps.SEVERITY],
|
||||
alarm[CeilProps.DETAIL][CeilProps.SEVERITY])
|
||||
self.assertEqual(
|
||||
entity[CeilProps.EVENT_TYPE],
|
||||
alarm[CeilProps.DETAIL][CeilProps.RULE][CeilProps.EVENT_TYPE])
|
||||
self.assertEqual("1", entity[CeilProps.RESOURCE_ID])
|
||||
self.assertEqual(entity[DSProps.EVENT_TYPE],
|
||||
CeilometerEventType.RULE_CHANGE)
|
||||
|
||||
# 6. alarm state change from 'alarm' to 'ok'
|
||||
# prepare data
|
||||
detail_data = {"type": "state transition",
|
||||
CeilProps.DETAIL: {CeilProps.STATE: "ok"}}
|
||||
alarm.update(detail_data)
|
||||
|
||||
# action
|
||||
entity = aodh_driver.enrich_event(
|
||||
alarm, CeilometerEventType.STATE_TRANSITION)
|
||||
|
||||
# Test assertions
|
||||
# alarm state change: alarm->OK, need to be deleted
|
||||
self.assertIsNotNone(entity)
|
||||
self._validate_aodh_entity_comm_props(entity, alarm_info)
|
||||
self.assertEqual(entity[DSProps.EVENT_TYPE],
|
||||
CeilometerEventType.STATE_TRANSITION)
|
||||
|
||||
# 7. delete alarm which is 'ok' state
|
||||
# prepare data
|
||||
detail_data = {"type": "deletion"}
|
||||
alarm.update(detail_data)
|
||||
|
||||
# action
|
||||
entity = aodh_driver.enrich_event(
|
||||
alarm, CeilometerEventType.DELETION)
|
||||
|
||||
# Test assertions
|
||||
self.assertIsNone(entity)
|
||||
|
||||
def test_gnocchi_threshold_alarm_notifications(self):
|
||||
aodh_driver = MockCeilometerDriver(self.conf)
|
||||
|
||||
# 1. alarm creation with 'ok' state
|
||||
# prepare data
|
||||
detail_data = {"type": "gnocchi_resources_threshold",
|
||||
CeilProps.DETAIL: self._create_alarm_data_gnocchi()}
|
||||
generators = \
|
||||
mock_driver.simple_aodh_alarm_notification_generators(
|
||||
alarm_num=1,
|
||||
update_events=1,
|
||||
update_vals=detail_data)
|
||||
alarm = mock_driver.generate_sequential_events_list(generators)[0]
|
||||
alarm_info = alarm.copy()
|
||||
|
||||
# action
|
||||
entity = aodh_driver.enrich_event(
|
||||
alarm, CeilometerEventType.CREATION)
|
||||
|
||||
# Test assertions
|
||||
# alarm with status OK should not be handled
|
||||
self.assertIsNone(entity)
|
||||
|
||||
# 2.alarm state transition from 'ok' to 'alarm'
|
||||
detail_data = {"type": "state transition",
|
||||
CeilProps.DETAIL: {CeilProps.STATE: "alarm"}}
|
||||
alarm.update(detail_data)
|
||||
entity = aodh_driver.enrich_event(
|
||||
alarm, CeilometerEventType.STATE_TRANSITION)
|
||||
|
||||
# Test assertions
|
||||
# alarm state change: ok->alarm, need to be added
|
||||
self.assertIsNotNone(entity)
|
||||
self._validate_aodh_entity_comm_props(entity, alarm_info)
|
||||
self.assertEqual(entity[CeilProps.STATE],
|
||||
alarm[CeilProps.DETAIL][CeilProps.STATE])
|
||||
self.assertEqual(entity[CeilProps.SEVERITY],
|
||||
alarm[CeilProps.SEVERITY])
|
||||
|
||||
# 3. delete alarm which is 'alarm' state
|
||||
# prepare data
|
||||
detail_data = {"type": "deletion"}
|
||||
alarm.update(detail_data)
|
||||
|
||||
# action
|
||||
entity = aodh_driver.enrich_event(
|
||||
alarm, CeilometerEventType.DELETION)
|
||||
|
||||
# Test assertions
|
||||
self.assertIsNotNone(entity)
|
||||
self._validate_aodh_entity_comm_props(entity, alarm_info)
|
||||
self.assertEqual(entity[DSProps.EVENT_TYPE],
|
||||
CeilometerEventType.DELETION)
|
||||
|
||||
# 4. alarm creation with 'alarm' state
|
||||
# prepare data
|
||||
detail_data = {"type": "gnocchi_resources_threshold",
|
||||
CeilProps.DETAIL:
|
||||
self._create_alarm_data_gnocchi(state="alarm")}
|
||||
generators = \
|
||||
mock_driver.simple_aodh_alarm_notification_generators(
|
||||
alarm_num=1,
|
||||
update_events=1,
|
||||
update_vals=detail_data)
|
||||
alarm = mock_driver.generate_sequential_events_list(generators)[0]
|
||||
alarm_info = alarm.copy()
|
||||
|
||||
# action
|
||||
entity = aodh_driver.enrich_event(
|
||||
alarm, CeilometerEventType.CREATION)
|
||||
|
||||
# Test assertions
|
||||
# alarm with status 'alarm' need to be added
|
||||
self.assertIsNotNone(entity)
|
||||
self._validate_aodh_entity_comm_props(entity, alarm_info)
|
||||
self.assertEqual(entity[CeilProps.STATE],
|
||||
alarm[CeilProps.DETAIL][CeilProps.STATE])
|
||||
self.assertEqual(entity[CeilProps.SEVERITY],
|
||||
alarm[CeilProps.SEVERITY])
|
||||
self.assertEqual(entity[DSProps.EVENT_TYPE],
|
||||
CeilometerEventType.CREATION)
|
||||
|
||||
# 5. alarm rule change
|
||||
# prepare data
|
||||
detail_data = {"type": "rule change",
|
||||
CeilProps.DETAIL: {
|
||||
"severity": "critical",
|
||||
CeilProps.RULE:
|
||||
{"granularity": "300",
|
||||
"threshold": "0.0123",
|
||||
"comparison_operator": "eq"}}}
|
||||
alarm.update(detail_data)
|
||||
|
||||
# action
|
||||
entity = aodh_driver.enrich_event(
|
||||
alarm, CeilometerEventType.RULE_CHANGE)
|
||||
|
||||
# Test assertions
|
||||
# alarm rule change: need to be update
|
||||
self.assertIsNotNone(entity)
|
||||
self._validate_aodh_entity_comm_props(entity, alarm_info)
|
||||
self.assertEqual(entity[CeilProps.SEVERITY],
|
||||
alarm[CeilProps.DETAIL][CeilProps.SEVERITY])
|
||||
self.assertEqual(entity[DSProps.EVENT_TYPE],
|
||||
CeilometerEventType.RULE_CHANGE)
|
||||
|
||||
# 6. alarm state change from 'alarm' to 'ok'
|
||||
# prepare data
|
||||
detail_data = {"type": "state transition",
|
||||
CeilProps.DETAIL: {CeilProps.STATE: "ok"}}
|
||||
alarm.update(detail_data)
|
||||
|
||||
# action
|
||||
entity = aodh_driver.enrich_event(
|
||||
alarm,
|
||||
CeilometerEventType.STATE_TRANSITION)
|
||||
|
||||
# Test assertions
|
||||
# alarm state change: alarm->OK, need to be deleted
|
||||
self.assertIsNotNone(entity)
|
||||
self._validate_aodh_entity_comm_props(entity, alarm_info)
|
||||
self.assertEqual(entity[DSProps.EVENT_TYPE],
|
||||
CeilometerEventType.STATE_TRANSITION)
|
||||
|
||||
# 7. delete alarm which is 'ok' state
|
||||
# prepare data
|
||||
detail_data = {"type": "deletion"}
|
||||
alarm.update(detail_data)
|
||||
|
||||
# action
|
||||
entity = aodh_driver.enrich_event(
|
||||
alarm, CeilometerEventType.DELETION)
|
||||
|
||||
# Test assertions
|
||||
self.assertIsNone(entity)
|
||||
|
||||
def _create_alarm_data_gnocchi(self,
|
||||
state="ok",
|
||||
type="gnocchi_resources_threshold",
|
||||
rule=None):
|
||||
|
||||
if rule is None:
|
||||
rule = {"granularity": "300",
|
||||
"threshold": "0.001",
|
||||
"comparison_operator": "gt",
|
||||
"resource_type": "instance"
|
||||
}
|
||||
return {CeilProps.DESCRIPTION: "test",
|
||||
CeilProps.TIMESTAMP: "2016-11-09T01:39:13.839584",
|
||||
CeilProps.ENABLED: True,
|
||||
CeilProps.STATE_TIMESTAMP: "2016-11-09T01:39:13.839584",
|
||||
CeilProps.ALARM_ID: "7e5c3754-e2eb-4782-ae00-7da5ded8568b",
|
||||
CeilProps.REPEAT_ACTIONS: False,
|
||||
CeilProps.PROJECT_ID: "c365d18fcc03493187016ae743f0cc4d",
|
||||
CeilProps.NAME: "test",
|
||||
CeilProps.SEVERITY: "low",
|
||||
CeilProps.RESOURCE_ID: "88cd2d1d-8af4-4d00-9b5e-f82f8c8b0f8d",
|
||||
CeilProps.TYPE: type,
|
||||
CeilProps.STATE: state,
|
||||
CeilProps.RULE: rule,
|
||||
CeilProps.STATE_REASON: 'for test'}
|
||||
|
||||
def _create_alarm_data_type_event(self,
|
||||
state="ok",
|
||||
type="event",
|
||||
rule=None):
|
||||
|
||||
if rule is None:
|
||||
rule = {"query": [], "event_type": "*"}
|
||||
return {CeilProps.DESCRIPTION: "test",
|
||||
CeilProps.TIMESTAMP: "2016-11-09T01:39:13.839584",
|
||||
CeilProps.ENABLED: True,
|
||||
CeilProps.STATE_TIMESTAMP: "2016-11-09T01:39:13.839584",
|
||||
CeilProps.ALARM_ID: "7e5c3754-e2eb-4782-ae00-7da5ded8568b",
|
||||
CeilProps.REPEAT_ACTIONS: False,
|
||||
CeilProps.PROJECT_ID: "c365d18fcc03493187016ae743f0cc4d",
|
||||
CeilProps.NAME: "test",
|
||||
CeilProps.SEVERITY: "low",
|
||||
CeilProps.TYPE: type,
|
||||
CeilProps.STATE: state,
|
||||
CeilProps.RULE: rule,
|
||||
CeilProps.STATE_REASON: 'for test'}
|
||||
|
||||
def _validate_aodh_entity_comm_props(self, entity, alarm):
|
||||
|
||||
self.assertEqual(entity[CeilProps.ALARM_ID],
|
||||
alarm[CeilProps.ALARM_ID])
|
||||
self.assertEqual(entity[CeilProps.PROJECT_ID],
|
||||
alarm[CeilProps.PROJECT_ID])
|
||||
self.assertEqual(entity[CeilProps.TIMESTAMP],
|
||||
alarm[CeilProps.TIMESTAMP])
|
||||
self.assertEqual(entity[CeilProps.DESCRIPTION],
|
||||
alarm[CeilProps.DETAIL][CeilProps.DESCRIPTION])
|
||||
self.assertEqual(entity[CeilProps.ENABLED],
|
||||
alarm[CeilProps.DETAIL][CeilProps.ENABLED])
|
||||
self.assertEqual(entity[CeilProps.NAME],
|
||||
alarm[CeilProps.DETAIL][CeilProps.NAME])
|
||||
self.assertEqual(entity[CeilProps.REPEAT_ACTIONS],
|
||||
alarm[CeilProps.DETAIL][CeilProps.REPEAT_ACTIONS])
|
||||
self.assertEqual(entity[CeilProps.TYPE],
|
||||
alarm[CeilProps.DETAIL][CeilProps.TYPE])
|
||||
|
@ -1,161 +1,161 @@
|
||||
# Copyright 2016 - ZTE, Nokia
|
||||
#
|
||||
# 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.
|
||||
|
||||
from oslo_config import cfg
|
||||
from oslo_log import log as logging
|
||||
|
||||
from vitrage.common.constants import DatasourceOpts as DSOpts
|
||||
from vitrage.common.constants import DatasourceProperties as DSProps
|
||||
from vitrage.common.constants import EntityCategory
|
||||
from vitrage.common.constants import UpdateMethod
|
||||
from vitrage.datasources.ceilometer import CEILOMETER_DATASOURCE
|
||||
from vitrage.datasources.ceilometer.properties \
|
||||
import CeilometerProperties as CeilProps
|
||||
from vitrage.datasources.ceilometer.transformer import CeilometerTransformer
|
||||
from vitrage.datasources.transformer_base import TransformerBase
|
||||
from vitrage.tests.mocks import mock_transformer as mock_sync
|
||||
from vitrage.tests.unit.datasources.ceilometer.\
|
||||
ceilometer_transformer_base_test \
|
||||
import CeilometerTransformerBaseTest
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class TestCeilometerAlarmTransformer(CeilometerTransformerBaseTest):
|
||||
|
||||
OPTS = [
|
||||
cfg.StrOpt(DSOpts.UPDATE_METHOD,
|
||||
default=UpdateMethod.PULL),
|
||||
]
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
cls.transformers = {}
|
||||
cls.conf = cfg.ConfigOpts()
|
||||
cls.conf.register_opts(cls.OPTS, group=CEILOMETER_DATASOURCE)
|
||||
cls.transformers[CEILOMETER_DATASOURCE] = \
|
||||
CeilometerTransformer(cls.transformers, cls.conf)
|
||||
|
||||
def test_key_values_with_vitrage_alarm(self):
|
||||
LOG.debug('Ceilometer transformer test: '
|
||||
'get key values(vitrage_alarm)')
|
||||
|
||||
# Test setup
|
||||
entity = {CeilProps.VITRAGE_ID: 'test',
|
||||
DSProps.ENTITY_TYPE: CEILOMETER_DATASOURCE,
|
||||
CeilProps.ALARM_ID: '12345'}
|
||||
transformer = self.transformers[CEILOMETER_DATASOURCE]
|
||||
|
||||
# Test action
|
||||
observed_key_fields = transformer._create_entity_key(entity)
|
||||
|
||||
# Test assertions
|
||||
self.assertEqual('test', observed_key_fields)
|
||||
|
||||
def test_key_values(self):
|
||||
LOG.debug('Ceilometer transformer test: get key values(aodh alarm)')
|
||||
|
||||
# Test setup
|
||||
entity = {DSProps.ENTITY_TYPE: CEILOMETER_DATASOURCE,
|
||||
CeilProps.ALARM_ID: '12345'}
|
||||
transformer = self.transformers[CEILOMETER_DATASOURCE]
|
||||
|
||||
# Test action
|
||||
entity_key_fields = transformer._create_entity_key(entity).split(":")
|
||||
|
||||
# Test assertions
|
||||
self.assertEqual(EntityCategory.ALARM, entity_key_fields[0])
|
||||
self.assertEqual(CEILOMETER_DATASOURCE, entity_key_fields[1])
|
||||
self.assertEqual(entity[CeilProps.ALARM_ID], entity_key_fields[2])
|
||||
|
||||
def test_snapshot_transform(self):
|
||||
LOG.debug('Ceilometer alarm transformer test: '
|
||||
'transform entity event snapshot')
|
||||
|
||||
# Test setup
|
||||
spec_list = mock_sync.simple_aodh_alarm_generators(alarm_num=3,
|
||||
snapshot_events=3)
|
||||
static_events = mock_sync.generate_random_events_list(spec_list)
|
||||
|
||||
for event in static_events:
|
||||
# convert neighbor from dict to vertex object
|
||||
neighbors = event[TransformerBase.QUERY_RESULT]
|
||||
vertices = []
|
||||
for neighbor in neighbors:
|
||||
neighbor_vertex = self._convert_dist_to_vertex(neighbor)
|
||||
vertices.append(self.transformers[CEILOMETER_DATASOURCE].
|
||||
update_uuid_in_vertex(neighbor_vertex))
|
||||
event[TransformerBase.QUERY_RESULT] = vertices
|
||||
|
||||
# Test action
|
||||
wrapper = self.transformers[CEILOMETER_DATASOURCE].transform(event)
|
||||
|
||||
# Test assertions
|
||||
vertex = wrapper.vertex
|
||||
self._validate_aodh_vertex_props(vertex, event)
|
||||
|
||||
neighbors = wrapper.neighbors
|
||||
self.assertEqual(1, len(neighbors))
|
||||
self._validate_neighbors(neighbors, vertex.vertex_id, event)
|
||||
|
||||
self._validate_action(event, wrapper)
|
||||
|
||||
|
||||
class TestCeilometerAlarmPushTransformer(CeilometerTransformerBaseTest):
|
||||
|
||||
OPTS = [
|
||||
cfg.StrOpt(DSOpts.UPDATE_METHOD,
|
||||
default=UpdateMethod.PUSH),
|
||||
]
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
cls.transformers = {}
|
||||
cls.conf = cfg.ConfigOpts()
|
||||
cls.conf.register_opts(cls.OPTS, group=CEILOMETER_DATASOURCE)
|
||||
cls.transformers[CEILOMETER_DATASOURCE] = \
|
||||
CeilometerTransformer(cls.transformers, cls.conf)
|
||||
|
||||
def test_update_transform(self):
|
||||
LOG.debug('Ceilometer update alarm transformer test:'
|
||||
'transform entity event update')
|
||||
|
||||
# Test setup
|
||||
spec_list = \
|
||||
mock_sync.simple_aodh_update_alarm_generators(alarm_num=5,
|
||||
update_events=5)
|
||||
static_events = mock_sync.generate_random_events_list(spec_list)
|
||||
|
||||
for event in static_events:
|
||||
# convert neighbor from dict to vertex object
|
||||
neighbors = event[TransformerBase.QUERY_RESULT]
|
||||
vertices = []
|
||||
for neighbor in neighbors:
|
||||
neighbor_vertex = self._convert_dist_to_vertex(neighbor)
|
||||
vertices.append(self.transformers[CEILOMETER_DATASOURCE].
|
||||
update_uuid_in_vertex(neighbor_vertex))
|
||||
event[TransformerBase.QUERY_RESULT] = vertices
|
||||
|
||||
# Test action
|
||||
wrapper = self.transformers[CEILOMETER_DATASOURCE].transform(event)
|
||||
|
||||
# Test assertions
|
||||
vertex = wrapper.vertex
|
||||
self._validate_aodh_vertex_props(vertex, event)
|
||||
|
||||
neighbors = wrapper.neighbors
|
||||
self.assertEqual(1, len(neighbors))
|
||||
self._validate_neighbors(neighbors, vertex.vertex_id, event)
|
||||
|
||||
self._validate_action(event, wrapper)
|
||||
# Copyright 2016 - ZTE, Nokia
|
||||
#
|
||||
# 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.
|
||||
|
||||
from oslo_config import cfg
|
||||
from oslo_log import log as logging
|
||||
|
||||
from vitrage.common.constants import DatasourceOpts as DSOpts
|
||||
from vitrage.common.constants import DatasourceProperties as DSProps
|
||||
from vitrage.common.constants import EntityCategory
|
||||
from vitrage.common.constants import UpdateMethod
|
||||
from vitrage.datasources.ceilometer import CEILOMETER_DATASOURCE
|
||||
from vitrage.datasources.ceilometer.properties \
|
||||
import CeilometerProperties as CeilProps
|
||||
from vitrage.datasources.ceilometer.transformer import CeilometerTransformer
|
||||
from vitrage.datasources.transformer_base import TransformerBase
|
||||
from vitrage.tests.mocks import mock_transformer as mock_sync
|
||||
from vitrage.tests.unit.datasources.ceilometer.\
|
||||
ceilometer_transformer_base_test \
|
||||
import CeilometerTransformerBaseTest
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class TestCeilometerAlarmTransformer(CeilometerTransformerBaseTest):
|
||||
|
||||
OPTS = [
|
||||
cfg.StrOpt(DSOpts.UPDATE_METHOD,
|
||||
default=UpdateMethod.PULL),
|
||||
]
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
cls.transformers = {}
|
||||
cls.conf = cfg.ConfigOpts()
|
||||
cls.conf.register_opts(cls.OPTS, group=CEILOMETER_DATASOURCE)
|
||||
cls.transformers[CEILOMETER_DATASOURCE] = \
|
||||
CeilometerTransformer(cls.transformers, cls.conf)
|
||||
|
||||
def test_key_values_with_vitrage_alarm(self):
|
||||
LOG.debug('Ceilometer transformer test: '
|
||||
'get key values(vitrage_alarm)')
|
||||
|
||||
# Test setup
|
||||
entity = {CeilProps.VITRAGE_ID: 'test',
|
||||
DSProps.ENTITY_TYPE: CEILOMETER_DATASOURCE,
|
||||
CeilProps.ALARM_ID: '12345'}
|
||||
transformer = self.transformers[CEILOMETER_DATASOURCE]
|
||||
|
||||
# Test action
|
||||
observed_key_fields = transformer._create_entity_key(entity)
|
||||
|
||||
# Test assertions
|
||||
self.assertEqual('test', observed_key_fields)
|
||||
|
||||
def test_key_values(self):
|
||||
LOG.debug('Ceilometer transformer test: get key values(aodh alarm)')
|
||||
|
||||
# Test setup
|
||||
entity = {DSProps.ENTITY_TYPE: CEILOMETER_DATASOURCE,
|
||||
CeilProps.ALARM_ID: '12345'}
|
||||
transformer = self.transformers[CEILOMETER_DATASOURCE]
|
||||
|
||||
# Test action
|
||||
entity_key_fields = transformer._create_entity_key(entity).split(":")
|
||||
|
||||
# Test assertions
|
||||
self.assertEqual(EntityCategory.ALARM, entity_key_fields[0])
|
||||
self.assertEqual(CEILOMETER_DATASOURCE, entity_key_fields[1])
|
||||
self.assertEqual(entity[CeilProps.ALARM_ID], entity_key_fields[2])
|
||||
|
||||
def test_snapshot_transform(self):
|
||||
LOG.debug('Ceilometer alarm transformer test: '
|
||||
'transform entity event snapshot')
|
||||
|
||||
# Test setup
|
||||
spec_list = mock_sync.simple_aodh_alarm_generators(alarm_num=3,
|
||||
snapshot_events=3)
|
||||
static_events = mock_sync.generate_random_events_list(spec_list)
|
||||
|
||||
for event in static_events:
|
||||
# convert neighbor from dict to vertex object
|
||||
neighbors = event[TransformerBase.QUERY_RESULT]
|
||||
vertices = []
|
||||
for neighbor in neighbors:
|
||||
neighbor_vertex = self._convert_dist_to_vertex(neighbor)
|
||||
vertices.append(self.transformers[CEILOMETER_DATASOURCE].
|
||||
update_uuid_in_vertex(neighbor_vertex))
|
||||
event[TransformerBase.QUERY_RESULT] = vertices
|
||||
|
||||
# Test action
|
||||
wrapper = self.transformers[CEILOMETER_DATASOURCE].transform(event)
|
||||
|
||||
# Test assertions
|
||||
vertex = wrapper.vertex
|
||||
self._validate_aodh_vertex_props(vertex, event)
|
||||
|
||||
neighbors = wrapper.neighbors
|
||||
self.assertEqual(1, len(neighbors))
|
||||
self._validate_neighbors(neighbors, vertex.vertex_id, event)
|
||||
|
||||
self._validate_action(event, wrapper)
|
||||
|
||||
|
||||
class TestCeilometerAlarmPushTransformer(CeilometerTransformerBaseTest):
|
||||
|
||||
OPTS = [
|
||||
cfg.StrOpt(DSOpts.UPDATE_METHOD,
|
||||
default=UpdateMethod.PUSH),
|
||||
]
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
cls.transformers = {}
|
||||
cls.conf = cfg.ConfigOpts()
|
||||
cls.conf.register_opts(cls.OPTS, group=CEILOMETER_DATASOURCE)
|
||||
cls.transformers[CEILOMETER_DATASOURCE] = \
|
||||
CeilometerTransformer(cls.transformers, cls.conf)
|
||||
|
||||
def test_update_transform(self):
|
||||
LOG.debug('Ceilometer update alarm transformer test:'
|
||||
'transform entity event update')
|
||||
|
||||
# Test setup
|
||||
spec_list = \
|
||||
mock_sync.simple_aodh_update_alarm_generators(alarm_num=5,
|
||||
update_events=5)
|
||||
static_events = mock_sync.generate_random_events_list(spec_list)
|
||||
|
||||
for event in static_events:
|
||||
# convert neighbor from dict to vertex object
|
||||
neighbors = event[TransformerBase.QUERY_RESULT]
|
||||
vertices = []
|
||||
for neighbor in neighbors:
|
||||
neighbor_vertex = self._convert_dist_to_vertex(neighbor)
|
||||
vertices.append(self.transformers[CEILOMETER_DATASOURCE].
|
||||
update_uuid_in_vertex(neighbor_vertex))
|
||||
event[TransformerBase.QUERY_RESULT] = vertices
|
||||
|
||||
# Test action
|
||||
wrapper = self.transformers[CEILOMETER_DATASOURCE].transform(event)
|
||||
|
||||
# Test assertions
|
||||
vertex = wrapper.vertex
|
||||
self._validate_aodh_vertex_props(vertex, event)
|
||||
|
||||
neighbors = wrapper.neighbors
|
||||
self.assertEqual(1, len(neighbors))
|
||||
self._validate_neighbors(neighbors, vertex.vertex_id, event)
|
||||
|
||||
self._validate_action(event, wrapper)
|
||||
|
Loading…
Reference in New Issue
Block a user