Merge "Remove newline characters and change StandardError to Exception"

This commit is contained in:
Zuul 2017-12-05 08:53:47 +00:00 committed by Gerrit Code Review
commit 793d2450b6
11 changed files with 1403 additions and 1403 deletions

View File

@ -151,5 +151,5 @@ class CollectDPlugin(object):
collectd.register_notification(callback, **kwargs) collectd.register_notification(callback, **kwargs)
class PluginError(StandardError): class PluginError(Exception):
pass pass

View File

@ -1,15 +1,15 @@
# Copyright 2016 - ZTE # Copyright 2016 - ZTE
# #
# Licensed under the Apache License, Version 2.0 (the "License"); you may # 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 # not use this file except in compliance with the License. You may obtain
# a copy of the License at # a copy of the License at
# #
# http://www.apache.org/licenses/LICENSE-2.0 # http://www.apache.org/licenses/LICENSE-2.0
# #
# Unless required by applicable law or agreed to in writing, software # Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
__author__ = 'stack' __author__ = 'stack'

View File

@ -1,115 +1,115 @@
# Copyright 2016 - ZTE, Nokia # Copyright 2016 - ZTE, Nokia
# #
# Licensed under the Apache License, Version 2.0 (the "License"); you may # 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 # not use this file except in compliance with the License. You may obtain
# a copy of the License at # a copy of the License at
# #
# http://www.apache.org/licenses/LICENSE-2.0 # http://www.apache.org/licenses/LICENSE-2.0
# #
# Unless required by applicable law or agreed to in writing, software # Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
from vitrage.common.constants import DatasourceAction from vitrage.common.constants import DatasourceAction
from vitrage.common.constants import DatasourceProperties as DSProps from vitrage.common.constants import DatasourceProperties as DSProps
from vitrage.common.constants import EdgeLabel from vitrage.common.constants import EdgeLabel
from vitrage.common.constants import EntityCategory from vitrage.common.constants import EntityCategory
from vitrage.common.constants import GraphAction from vitrage.common.constants import GraphAction
from vitrage.common.constants import VertexProperties as VProps from vitrage.common.constants import VertexProperties as VProps
from vitrage.datasources.alarm_properties import AlarmProperties as AlarmProps from vitrage.datasources.alarm_properties import AlarmProperties as AlarmProps
from vitrage.datasources.aodh.properties import AodhProperties as AodhProps from vitrage.datasources.aodh.properties import AodhProperties as AodhProps
from vitrage.datasources.aodh.properties import AodhState from vitrage.datasources.aodh.properties import AodhState
from vitrage.datasources.nova.instance import NOVA_INSTANCE_DATASOURCE from vitrage.datasources.nova.instance import NOVA_INSTANCE_DATASOURCE
from vitrage.datasources.transformer_base import TransformerBase from vitrage.datasources.transformer_base import TransformerBase
from vitrage.graph.driver.elements import Vertex from vitrage.graph.driver.elements import Vertex
from vitrage.tests import base from vitrage.tests import base
class AodhTransformerBaseTest(base.BaseTest): class AodhTransformerBaseTest(base.BaseTest):
def _validate_aodh_vertex_props(self, vertex, event): def _validate_aodh_vertex_props(self, vertex, event):
self.assertEqual(EntityCategory.ALARM, vertex[VProps.VITRAGE_CATEGORY]) self.assertEqual(EntityCategory.ALARM, vertex[VProps.VITRAGE_CATEGORY])
self.assertEqual(event[DSProps.ENTITY_TYPE], self.assertEqual(event[DSProps.ENTITY_TYPE],
vertex[VProps.VITRAGE_TYPE]) vertex[VProps.VITRAGE_TYPE])
self.assertEqual(event[AodhProps.NAME], vertex[VProps.NAME]) self.assertEqual(event[AodhProps.NAME], vertex[VProps.NAME])
self.assertEqual(event[AodhProps.SEVERITY], vertex[VProps.SEVERITY]) self.assertEqual(event[AodhProps.SEVERITY], vertex[VProps.SEVERITY])
self.assertEqual(event[AodhProps.DESCRIPTION], self.assertEqual(event[AodhProps.DESCRIPTION],
vertex[AodhProps.DESCRIPTION]) vertex[AodhProps.DESCRIPTION])
self.assertEqual(event[AodhProps.ENABLED], vertex[AodhProps.ENABLED]) self.assertEqual(event[AodhProps.ENABLED], vertex[AodhProps.ENABLED])
self.assertEqual(event[AodhProps.PROJECT_ID], self.assertEqual(event[AodhProps.PROJECT_ID],
vertex[VProps.PROJECT_ID]) vertex[VProps.PROJECT_ID])
self.assertEqual(event[AodhProps.REPEAT_ACTIONS], self.assertEqual(event[AodhProps.REPEAT_ACTIONS],
vertex[AodhProps.REPEAT_ACTIONS]) vertex[AodhProps.REPEAT_ACTIONS])
self.assertEqual(event[AodhProps.TYPE], vertex['alarm_type']) self.assertEqual(event[AodhProps.TYPE], vertex['alarm_type'])
if event[AodhProps.TYPE] == AodhProps.EVENT: if event[AodhProps.TYPE] == AodhProps.EVENT:
self.assertEqual(event[AodhProps.EVENT_TYPE], self.assertEqual(event[AodhProps.EVENT_TYPE],
vertex[AodhProps.EVENT_TYPE]) vertex[AodhProps.EVENT_TYPE])
elif event[AodhProps.TYPE] == AodhProps.THRESHOLD: elif event[AodhProps.TYPE] == AodhProps.THRESHOLD:
self.assertEqual(event[AodhProps.STATE_TIMESTAMP], self.assertEqual(event[AodhProps.STATE_TIMESTAMP],
vertex[AodhProps.STATE_TIMESTAMP]) vertex[AodhProps.STATE_TIMESTAMP])
self.assertEqual(event[DSProps.SAMPLE_DATE], self.assertEqual(event[DSProps.SAMPLE_DATE],
vertex[VProps.VITRAGE_SAMPLE_TIMESTAMP]) vertex[VProps.VITRAGE_SAMPLE_TIMESTAMP])
event_status = event[AodhProps.STATE] event_status = event[AodhProps.STATE]
if event_status == AodhState.OK: if event_status == AodhState.OK:
self.assertEqual(AlarmProps.INACTIVE_STATE, self.assertEqual(AlarmProps.INACTIVE_STATE,
vertex[VProps.STATE]) vertex[VProps.STATE])
else: else:
self.assertEqual(AlarmProps.ACTIVE_STATE, self.assertEqual(AlarmProps.ACTIVE_STATE,
vertex[VProps.STATE]) vertex[VProps.STATE])
self.assertFalse(vertex[VProps.VITRAGE_IS_PLACEHOLDER]) self.assertFalse(vertex[VProps.VITRAGE_IS_PLACEHOLDER])
self.assertFalse(vertex[VProps.VITRAGE_IS_DELETED]) self.assertFalse(vertex[VProps.VITRAGE_IS_DELETED])
def _validate_action(self, alarm, wrapper): def _validate_action(self, alarm, wrapper):
if DSProps.EVENT_TYPE in alarm \ if DSProps.EVENT_TYPE in alarm \
and alarm[DSProps.EVENT_TYPE] in GraphAction.__dict__.values(): and alarm[DSProps.EVENT_TYPE] in GraphAction.__dict__.values():
self.assertEqual(alarm[DSProps.EVENT_TYPE], wrapper.action) self.assertEqual(alarm[DSProps.EVENT_TYPE], wrapper.action)
return return
ds_action = alarm[DSProps.DATASOURCE_ACTION] ds_action = alarm[DSProps.DATASOURCE_ACTION]
if ds_action in (DatasourceAction.SNAPSHOT, DatasourceAction.UPDATE): if ds_action in (DatasourceAction.SNAPSHOT, DatasourceAction.UPDATE):
self.assertEqual(GraphAction.UPDATE_ENTITY, wrapper.action) self.assertEqual(GraphAction.UPDATE_ENTITY, wrapper.action)
else: else:
self.assertEqual(GraphAction.CREATE_ENTITY, wrapper.action) self.assertEqual(GraphAction.CREATE_ENTITY, wrapper.action)
def _validate_neighbors(self, neighbors, alarm_id, event): def _validate_neighbors(self, neighbors, alarm_id, event):
resource_counter = 0 resource_counter = 0
for neighbor in neighbors: for neighbor in neighbors:
resource_id = event[AodhProps.RESOURCE_ID] resource_id = event[AodhProps.RESOURCE_ID]
self._validate_instance_neighbor(neighbor, self._validate_instance_neighbor(neighbor,
resource_id, resource_id,
alarm_id) alarm_id)
resource_counter += 1 resource_counter += 1
self.assertEqual(1, self.assertEqual(1,
resource_counter, resource_counter,
'Alarm can be belonged to only one resource') 'Alarm can be belonged to only one resource')
def _validate_instance_neighbor(self, def _validate_instance_neighbor(self,
alarm_neighbor, alarm_neighbor,
resource_id, resource_id,
alarm_vertex_id): alarm_vertex_id):
# validate neighbor vertex # validate neighbor vertex
self.assertEqual(EntityCategory.RESOURCE, self.assertEqual(EntityCategory.RESOURCE,
alarm_neighbor.vertex[VProps.VITRAGE_CATEGORY]) alarm_neighbor.vertex[VProps.VITRAGE_CATEGORY])
self.assertEqual(NOVA_INSTANCE_DATASOURCE, self.assertEqual(NOVA_INSTANCE_DATASOURCE,
alarm_neighbor.vertex[VProps.VITRAGE_TYPE]) alarm_neighbor.vertex[VProps.VITRAGE_TYPE])
self.assertEqual(resource_id, alarm_neighbor.vertex[VProps.ID]) 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_PLACEHOLDER])
self.assertFalse(alarm_neighbor.vertex[VProps.VITRAGE_IS_DELETED]) self.assertFalse(alarm_neighbor.vertex[VProps.VITRAGE_IS_DELETED])
# Validate neighbor edge # Validate neighbor edge
edge = alarm_neighbor.edge edge = alarm_neighbor.edge
self.assertEqual(edge.target_id, alarm_neighbor.vertex.vertex_id) self.assertEqual(edge.target_id, alarm_neighbor.vertex.vertex_id)
self.assertEqual(edge.source_id, alarm_vertex_id) self.assertEqual(edge.source_id, alarm_vertex_id)
self.assertEqual(edge.label, EdgeLabel.ON) self.assertEqual(edge.label, EdgeLabel.ON)
def _convert_dist_to_vertex(self, neighbor): def _convert_dist_to_vertex(self, neighbor):
ver_id = neighbor[VProps.VITRAGE_CATEGORY] + \ ver_id = neighbor[VProps.VITRAGE_CATEGORY] + \
TransformerBase.KEY_SEPARATOR + neighbor[VProps.VITRAGE_TYPE] + \ TransformerBase.KEY_SEPARATOR + neighbor[VProps.VITRAGE_TYPE] + \
TransformerBase.KEY_SEPARATOR + neighbor[VProps.ID] TransformerBase.KEY_SEPARATOR + neighbor[VProps.ID]
return Vertex(vertex_id=ver_id, properties=neighbor) return Vertex(vertex_id=ver_id, properties=neighbor)

View File

@ -1,27 +1,27 @@
# Copyright 2016 - Nokia # Copyright 2016 - Nokia
# #
# Licensed under the Apache License, Version 2.0 (the "License"); you may # 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 # not use this file except in compliance with the License. You may obtain
# a copy of the License at # a copy of the License at
# #
# http://www.apache.org/licenses/LICENSE-2.0 # http://www.apache.org/licenses/LICENSE-2.0
# #
# Unless required by applicable law or agreed to in writing, software # Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
from vitrage.datasources.aodh.driver import AodhDriver from vitrage.datasources.aodh.driver import AodhDriver
class MockAodhDriver(AodhDriver): class MockAodhDriver(AodhDriver):
"""A aodh driver for tests. """A aodh driver for tests.
""" """
def __init__(self, conf): def __init__(self, conf):
super(MockAodhDriver, self).__init__(conf) super(MockAodhDriver, self).__init__(conf)
def _cache_all_alarms(self): def _cache_all_alarms(self):
pass pass

View File

@ -1,376 +1,376 @@
# Copyright 2016 - ZTE, Nokia # Copyright 2016 - ZTE, Nokia
# #
# Licensed under the Apache License, Version 2.0 (the "License"); you may # 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 # not use this file except in compliance with the License. You may obtain
# a copy of the License at # a copy of the License at
# #
# http://www.apache.org/licenses/LICENSE-2.0 # http://www.apache.org/licenses/LICENSE-2.0
# #
# Unless required by applicable law or agreed to in writing, software # Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
from oslo_config import cfg from oslo_config import cfg
from vitrage.common.constants import DatasourceOpts as DSOpts from vitrage.common.constants import DatasourceOpts as DSOpts
from vitrage.common.constants import DatasourceProperties as DSProps from vitrage.common.constants import DatasourceProperties as DSProps
from vitrage.common.constants import UpdateMethod from vitrage.common.constants import UpdateMethod
from vitrage.datasources.aodh import AODH_DATASOURCE from vitrage.datasources.aodh import AODH_DATASOURCE
from vitrage.datasources.aodh.properties import AodhEventType from vitrage.datasources.aodh.properties import AodhEventType
from vitrage.datasources.aodh.properties import AodhProperties as AodhProps from vitrage.datasources.aodh.properties import AodhProperties as AodhProps
from vitrage.tests import base from vitrage.tests import base
from vitrage.tests.mocks import mock_driver from vitrage.tests.mocks import mock_driver
from vitrage.tests.unit.datasources.aodh.mock_driver import MockAodhDriver from vitrage.tests.unit.datasources.aodh.mock_driver import MockAodhDriver
class AodhDriverTest(base.BaseTest): class AodhDriverTest(base.BaseTest):
OPTS = [ OPTS = [
cfg.StrOpt(DSOpts.UPDATE_METHOD, cfg.StrOpt(DSOpts.UPDATE_METHOD,
default=UpdateMethod.PUSH), default=UpdateMethod.PUSH),
] ]
# noinspection PyPep8Naming # noinspection PyPep8Naming
@classmethod @classmethod
def setUpClass(cls): def setUpClass(cls):
cls.conf = cfg.ConfigOpts() cls.conf = cfg.ConfigOpts()
cls.conf.register_opts(cls.OPTS, group=AODH_DATASOURCE) cls.conf.register_opts(cls.OPTS, group=AODH_DATASOURCE)
def test_event_alarm_notifications(self): def test_event_alarm_notifications(self):
aodh_driver = MockAodhDriver(self.conf) aodh_driver = MockAodhDriver(self.conf)
# 1. alarm creation with 'ok' state # 1. alarm creation with 'ok' state
# prepare data # prepare data
detail_data = {"type": "creation", detail_data = {"type": "creation",
AodhProps.DETAIL: self._create_alarm_data_type_event()} AodhProps.DETAIL: self._create_alarm_data_type_event()}
generators = \ generators = \
mock_driver.simple_aodh_alarm_notification_generators( mock_driver.simple_aodh_alarm_notification_generators(
alarm_num=1, alarm_num=1,
update_events=1, update_events=1,
update_vals=detail_data) update_vals=detail_data)
alarm = mock_driver.generate_sequential_events_list(generators)[0] alarm = mock_driver.generate_sequential_events_list(generators)[0]
alarm_info = alarm.copy() alarm_info = alarm.copy()
# action # action
entity = aodh_driver.enrich_event(alarm, AodhEventType.CREATION) entity = aodh_driver.enrich_event(alarm, AodhEventType.CREATION)
# Test assertions # Test assertions
# alarm with status OK should not be handled # alarm with status OK should not be handled
self.assertIsNone(entity) self.assertIsNone(entity)
# 2.alarm state transition from 'ok' to 'alarm' # 2.alarm state transition from 'ok' to 'alarm'
detail_data = {"type": "state transition", detail_data = {"type": "state transition",
AodhProps.DETAIL: {AodhProps.STATE: "alarm"}} AodhProps.DETAIL: {AodhProps.STATE: "alarm"}}
alarm.update(detail_data) alarm.update(detail_data)
entity = aodh_driver.enrich_event(alarm, entity = aodh_driver.enrich_event(alarm,
AodhEventType.STATE_TRANSITION) AodhEventType.STATE_TRANSITION)
# Test assertions # Test assertions
# alarm state change: ok->alarm, need to be added # alarm state change: ok->alarm, need to be added
self.assertIsNotNone(entity) self.assertIsNotNone(entity)
self._validate_aodh_entity_comm_props(entity, alarm_info) self._validate_aodh_entity_comm_props(entity, alarm_info)
self.assertEqual(entity[AodhProps.STATE], self.assertEqual(entity[AodhProps.STATE],
alarm[AodhProps.DETAIL][AodhProps.STATE]) alarm[AodhProps.DETAIL][AodhProps.STATE])
self.assertEqual(entity[AodhProps.SEVERITY], self.assertEqual(entity[AodhProps.SEVERITY],
alarm[AodhProps.SEVERITY]) alarm[AodhProps.SEVERITY])
self.assertEqual(entity[DSProps.EVENT_TYPE], self.assertEqual(entity[DSProps.EVENT_TYPE],
AodhEventType.STATE_TRANSITION) AodhEventType.STATE_TRANSITION)
# 3. delete alarm which is 'alarm' state # 3. delete alarm which is 'alarm' state
# prepare data # prepare data
detail_data = {"type": "deletion"} detail_data = {"type": "deletion"}
alarm.update(detail_data) alarm.update(detail_data)
# action # action
entity = aodh_driver.enrich_event(alarm, AodhEventType.DELETION) entity = aodh_driver.enrich_event(alarm, AodhEventType.DELETION)
# Test assertions # Test assertions
self.assertIsNotNone(entity) self.assertIsNotNone(entity)
self._validate_aodh_entity_comm_props(entity, alarm_info) self._validate_aodh_entity_comm_props(entity, alarm_info)
self.assertEqual(entity[DSProps.EVENT_TYPE], self.assertEqual(entity[DSProps.EVENT_TYPE],
AodhEventType.DELETION) AodhEventType.DELETION)
# 4. alarm creation with 'alarm' state # 4. alarm creation with 'alarm' state
# prepare data # prepare data
detail_data = {"type": "creation", detail_data = {"type": "creation",
AodhProps.DETAIL: AodhProps.DETAIL:
self._create_alarm_data_type_event(state="alarm")} self._create_alarm_data_type_event(state="alarm")}
generators = \ generators = \
mock_driver.simple_aodh_alarm_notification_generators( mock_driver.simple_aodh_alarm_notification_generators(
alarm_num=1, alarm_num=1,
update_events=1, update_events=1,
update_vals=detail_data) update_vals=detail_data)
alarm = mock_driver.generate_sequential_events_list(generators)[0] alarm = mock_driver.generate_sequential_events_list(generators)[0]
alarm_info = alarm.copy() alarm_info = alarm.copy()
# action # action
entity = aodh_driver.enrich_event(alarm, AodhEventType.CREATION) entity = aodh_driver.enrich_event(alarm, AodhEventType.CREATION)
# Test assertions # Test assertions
# alarm with status 'alarm' need to be added # alarm with status 'alarm' need to be added
self.assertIsNotNone(entity) self.assertIsNotNone(entity)
self._validate_aodh_entity_comm_props(entity, alarm_info) self._validate_aodh_entity_comm_props(entity, alarm_info)
self.assertEqual(entity[AodhProps.STATE], self.assertEqual(entity[AodhProps.STATE],
alarm[AodhProps.DETAIL][AodhProps.STATE]) alarm[AodhProps.DETAIL][AodhProps.STATE])
self.assertEqual(entity[AodhProps.SEVERITY], self.assertEqual(entity[AodhProps.SEVERITY],
alarm[AodhProps.SEVERITY]) alarm[AodhProps.SEVERITY])
self.assertIsNone(entity[AodhProps.RESOURCE_ID]) self.assertIsNone(entity[AodhProps.RESOURCE_ID])
self.assertEqual("*", entity[AodhProps.EVENT_TYPE]) self.assertEqual("*", entity[AodhProps.EVENT_TYPE])
self.assertEqual(entity[DSProps.EVENT_TYPE], self.assertEqual(entity[DSProps.EVENT_TYPE],
AodhEventType.CREATION) AodhEventType.CREATION)
# 5. alarm rule change # 5. alarm rule change
# prepare data # prepare data
detail_data = {"type": "rule change", detail_data = {"type": "rule change",
AodhProps.DETAIL: { AodhProps.DETAIL: {
"severity": "critical", "severity": "critical",
AodhProps.RULE: AodhProps.RULE:
{"query": [{"field": "traits.resource_id", {"query": [{"field": "traits.resource_id",
"type": "", "type": "",
"value": "1", "value": "1",
"op": "eq"}], "op": "eq"}],
"event_type": "instance.update"}}} "event_type": "instance.update"}}}
alarm.update(detail_data) alarm.update(detail_data)
# action # action
entity = aodh_driver.enrich_event(alarm, entity = aodh_driver.enrich_event(alarm,
AodhEventType.RULE_CHANGE) AodhEventType.RULE_CHANGE)
# Test assertions # Test assertions
# alarm rule change: need to be update # alarm rule change: need to be update
self.assertIsNotNone(entity) self.assertIsNotNone(entity)
self._validate_aodh_entity_comm_props(entity, alarm_info) self._validate_aodh_entity_comm_props(entity, alarm_info)
self.assertEqual(entity[AodhProps.SEVERITY], self.assertEqual(entity[AodhProps.SEVERITY],
alarm[AodhProps.DETAIL][AodhProps.SEVERITY]) alarm[AodhProps.DETAIL][AodhProps.SEVERITY])
self.assertEqual( self.assertEqual(
entity[AodhProps.EVENT_TYPE], entity[AodhProps.EVENT_TYPE],
alarm[AodhProps.DETAIL][AodhProps.RULE][AodhProps.EVENT_TYPE]) alarm[AodhProps.DETAIL][AodhProps.RULE][AodhProps.EVENT_TYPE])
self.assertEqual("1", entity[AodhProps.RESOURCE_ID]) self.assertEqual("1", entity[AodhProps.RESOURCE_ID])
self.assertEqual(entity[DSProps.EVENT_TYPE], self.assertEqual(entity[DSProps.EVENT_TYPE],
AodhEventType.RULE_CHANGE) AodhEventType.RULE_CHANGE)
# 6. alarm state change from 'alarm' to 'ok' # 6. alarm state change from 'alarm' to 'ok'
# prepare data # prepare data
detail_data = {"type": "state transition", detail_data = {"type": "state transition",
AodhProps.DETAIL: {AodhProps.STATE: "ok"}} AodhProps.DETAIL: {AodhProps.STATE: "ok"}}
alarm.update(detail_data) alarm.update(detail_data)
# action # action
entity = aodh_driver.enrich_event(alarm, entity = aodh_driver.enrich_event(alarm,
AodhEventType.STATE_TRANSITION) AodhEventType.STATE_TRANSITION)
# Test assertions # Test assertions
# alarm state change: alarm->OK, need to be deleted # alarm state change: alarm->OK, need to be deleted
self.assertIsNotNone(entity) self.assertIsNotNone(entity)
self._validate_aodh_entity_comm_props(entity, alarm_info) self._validate_aodh_entity_comm_props(entity, alarm_info)
self.assertEqual(entity[DSProps.EVENT_TYPE], self.assertEqual(entity[DSProps.EVENT_TYPE],
AodhEventType.STATE_TRANSITION) AodhEventType.STATE_TRANSITION)
# 7. delete alarm which is 'ok' state # 7. delete alarm which is 'ok' state
# prepare data # prepare data
detail_data = {"type": "deletion"} detail_data = {"type": "deletion"}
alarm.update(detail_data) alarm.update(detail_data)
# action # action
entity = aodh_driver.enrich_event(alarm, AodhEventType.DELETION) entity = aodh_driver.enrich_event(alarm, AodhEventType.DELETION)
# Test assertions # Test assertions
self.assertIsNone(entity) self.assertIsNone(entity)
def test_gnocchi_threshold_alarm_notifications(self): def test_gnocchi_threshold_alarm_notifications(self):
aodh_driver = MockAodhDriver(self.conf) aodh_driver = MockAodhDriver(self.conf)
# 1. alarm creation with 'ok' state # 1. alarm creation with 'ok' state
# prepare data # prepare data
detail_data = {"type": "gnocchi_resources_threshold", detail_data = {"type": "gnocchi_resources_threshold",
AodhProps.DETAIL: self._create_alarm_data_gnocchi()} AodhProps.DETAIL: self._create_alarm_data_gnocchi()}
generators = \ generators = \
mock_driver.simple_aodh_alarm_notification_generators( mock_driver.simple_aodh_alarm_notification_generators(
alarm_num=1, alarm_num=1,
update_events=1, update_events=1,
update_vals=detail_data) update_vals=detail_data)
alarm = mock_driver.generate_sequential_events_list(generators)[0] alarm = mock_driver.generate_sequential_events_list(generators)[0]
alarm_info = alarm.copy() alarm_info = alarm.copy()
# action # action
entity = aodh_driver.enrich_event(alarm, AodhEventType.CREATION) entity = aodh_driver.enrich_event(alarm, AodhEventType.CREATION)
# Test assertions # Test assertions
# alarm with status OK should not be handled # alarm with status OK should not be handled
self.assertIsNone(entity) self.assertIsNone(entity)
# 2.alarm state transition from 'ok' to 'alarm' # 2.alarm state transition from 'ok' to 'alarm'
detail_data = {"type": "state transition", detail_data = {"type": "state transition",
AodhProps.DETAIL: {AodhProps.STATE: "alarm"}} AodhProps.DETAIL: {AodhProps.STATE: "alarm"}}
alarm.update(detail_data) alarm.update(detail_data)
entity = aodh_driver.enrich_event(alarm, entity = aodh_driver.enrich_event(alarm,
AodhEventType.STATE_TRANSITION) AodhEventType.STATE_TRANSITION)
# Test assertions # Test assertions
# alarm state change: ok->alarm, need to be added # alarm state change: ok->alarm, need to be added
self.assertIsNotNone(entity) self.assertIsNotNone(entity)
self._validate_aodh_entity_comm_props(entity, alarm_info) self._validate_aodh_entity_comm_props(entity, alarm_info)
self.assertEqual(entity[AodhProps.STATE], self.assertEqual(entity[AodhProps.STATE],
alarm[AodhProps.DETAIL][AodhProps.STATE]) alarm[AodhProps.DETAIL][AodhProps.STATE])
self.assertEqual(entity[AodhProps.SEVERITY], self.assertEqual(entity[AodhProps.SEVERITY],
alarm[AodhProps.SEVERITY]) alarm[AodhProps.SEVERITY])
# 3. delete alarm which is 'alarm' state # 3. delete alarm which is 'alarm' state
# prepare data # prepare data
detail_data = {"type": "deletion"} detail_data = {"type": "deletion"}
alarm.update(detail_data) alarm.update(detail_data)
# action # action
entity = aodh_driver.enrich_event(alarm, AodhEventType.DELETION) entity = aodh_driver.enrich_event(alarm, AodhEventType.DELETION)
# Test assertions # Test assertions
self.assertIsNotNone(entity) self.assertIsNotNone(entity)
self._validate_aodh_entity_comm_props(entity, alarm_info) self._validate_aodh_entity_comm_props(entity, alarm_info)
self.assertEqual(entity[DSProps.EVENT_TYPE], self.assertEqual(entity[DSProps.EVENT_TYPE],
AodhEventType.DELETION) AodhEventType.DELETION)
# 4. alarm creation with 'alarm' state # 4. alarm creation with 'alarm' state
# prepare data # prepare data
detail_data = {"type": "gnocchi_resources_threshold", detail_data = {"type": "gnocchi_resources_threshold",
AodhProps.DETAIL: AodhProps.DETAIL:
self._create_alarm_data_gnocchi(state="alarm")} self._create_alarm_data_gnocchi(state="alarm")}
generators = \ generators = \
mock_driver.simple_aodh_alarm_notification_generators( mock_driver.simple_aodh_alarm_notification_generators(
alarm_num=1, alarm_num=1,
update_events=1, update_events=1,
update_vals=detail_data) update_vals=detail_data)
alarm = mock_driver.generate_sequential_events_list(generators)[0] alarm = mock_driver.generate_sequential_events_list(generators)[0]
alarm_info = alarm.copy() alarm_info = alarm.copy()
# action # action
entity = aodh_driver.enrich_event(alarm, AodhEventType.CREATION) entity = aodh_driver.enrich_event(alarm, AodhEventType.CREATION)
# Test assertions # Test assertions
# alarm with status 'alarm' need to be added # alarm with status 'alarm' need to be added
self.assertIsNotNone(entity) self.assertIsNotNone(entity)
self._validate_aodh_entity_comm_props(entity, alarm_info) self._validate_aodh_entity_comm_props(entity, alarm_info)
self.assertEqual(entity[AodhProps.STATE], self.assertEqual(entity[AodhProps.STATE],
alarm[AodhProps.DETAIL][AodhProps.STATE]) alarm[AodhProps.DETAIL][AodhProps.STATE])
self.assertEqual(entity[AodhProps.SEVERITY], self.assertEqual(entity[AodhProps.SEVERITY],
alarm[AodhProps.SEVERITY]) alarm[AodhProps.SEVERITY])
self.assertEqual(entity[DSProps.EVENT_TYPE], self.assertEqual(entity[DSProps.EVENT_TYPE],
AodhEventType.CREATION) AodhEventType.CREATION)
# 5. alarm rule change # 5. alarm rule change
# prepare data # prepare data
detail_data = {"type": "rule change", detail_data = {"type": "rule change",
AodhProps.DETAIL: { AodhProps.DETAIL: {
"severity": "critical", "severity": "critical",
AodhProps.RULE: AodhProps.RULE:
{"granularity": "300", {"granularity": "300",
"threshold": "0.0123", "threshold": "0.0123",
"comparison_operator": "eq"}}} "comparison_operator": "eq"}}}
alarm.update(detail_data) alarm.update(detail_data)
# action # action
entity = aodh_driver.enrich_event(alarm, entity = aodh_driver.enrich_event(alarm,
AodhEventType.RULE_CHANGE) AodhEventType.RULE_CHANGE)
# Test assertions # Test assertions
# alarm rule change: need to be update # alarm rule change: need to be update
self.assertIsNotNone(entity) self.assertIsNotNone(entity)
self._validate_aodh_entity_comm_props(entity, alarm_info) self._validate_aodh_entity_comm_props(entity, alarm_info)
self.assertEqual(entity[AodhProps.SEVERITY], self.assertEqual(entity[AodhProps.SEVERITY],
alarm[AodhProps.DETAIL][AodhProps.SEVERITY]) alarm[AodhProps.DETAIL][AodhProps.SEVERITY])
self.assertEqual(entity[DSProps.EVENT_TYPE], self.assertEqual(entity[DSProps.EVENT_TYPE],
AodhEventType.RULE_CHANGE) AodhEventType.RULE_CHANGE)
# 6. alarm state change from 'alarm' to 'ok' # 6. alarm state change from 'alarm' to 'ok'
# prepare data # prepare data
detail_data = {"type": "state transition", detail_data = {"type": "state transition",
AodhProps.DETAIL: {AodhProps.STATE: "ok"}} AodhProps.DETAIL: {AodhProps.STATE: "ok"}}
alarm.update(detail_data) alarm.update(detail_data)
# action # action
entity = aodh_driver.enrich_event(alarm, entity = aodh_driver.enrich_event(alarm,
AodhEventType.STATE_TRANSITION) AodhEventType.STATE_TRANSITION)
# Test assertions # Test assertions
# alarm state change: alarm->OK, need to be deleted # alarm state change: alarm->OK, need to be deleted
self.assertIsNotNone(entity) self.assertIsNotNone(entity)
self._validate_aodh_entity_comm_props(entity, alarm_info) self._validate_aodh_entity_comm_props(entity, alarm_info)
self.assertEqual(entity[DSProps.EVENT_TYPE], self.assertEqual(entity[DSProps.EVENT_TYPE],
AodhEventType.STATE_TRANSITION) AodhEventType.STATE_TRANSITION)
# 7. delete alarm which is 'ok' state # 7. delete alarm which is 'ok' state
# prepare data # prepare data
detail_data = {"type": "deletion"} detail_data = {"type": "deletion"}
alarm.update(detail_data) alarm.update(detail_data)
# action # action
entity = aodh_driver.enrich_event(alarm, AodhEventType.DELETION) entity = aodh_driver.enrich_event(alarm, AodhEventType.DELETION)
# Test assertions # Test assertions
self.assertIsNone(entity) self.assertIsNone(entity)
def _create_alarm_data_gnocchi(self, def _create_alarm_data_gnocchi(self,
state="ok", state="ok",
type="gnocchi_resources_threshold", type="gnocchi_resources_threshold",
rule=None): rule=None):
if rule is None: if rule is None:
rule = {"granularity": "300", rule = {"granularity": "300",
"threshold": "0.001", "threshold": "0.001",
"comparison_operator": "gt", "comparison_operator": "gt",
"resource_type": "instance" "resource_type": "instance"
} }
return {AodhProps.DESCRIPTION: "test", return {AodhProps.DESCRIPTION: "test",
AodhProps.TIMESTAMP: "2016-11-09T01:39:13.839584", AodhProps.TIMESTAMP: "2016-11-09T01:39:13.839584",
AodhProps.ENABLED: True, AodhProps.ENABLED: True,
AodhProps.STATE_TIMESTAMP: "2016-11-09T01:39:13.839584", AodhProps.STATE_TIMESTAMP: "2016-11-09T01:39:13.839584",
AodhProps.ALARM_ID: "7e5c3754-e2eb-4782-ae00-7da5ded8568b", AodhProps.ALARM_ID: "7e5c3754-e2eb-4782-ae00-7da5ded8568b",
AodhProps.REPEAT_ACTIONS: False, AodhProps.REPEAT_ACTIONS: False,
AodhProps.PROJECT_ID: "c365d18fcc03493187016ae743f0cc4d", AodhProps.PROJECT_ID: "c365d18fcc03493187016ae743f0cc4d",
AodhProps.NAME: "test", AodhProps.NAME: "test",
AodhProps.SEVERITY: "low", AodhProps.SEVERITY: "low",
AodhProps.RESOURCE_ID: "88cd2d1d-8af4-4d00-9b5e-f82f8c8b0f8d", AodhProps.RESOURCE_ID: "88cd2d1d-8af4-4d00-9b5e-f82f8c8b0f8d",
AodhProps.TYPE: type, AodhProps.TYPE: type,
AodhProps.STATE: state, AodhProps.STATE: state,
AodhProps.RULE: rule} AodhProps.RULE: rule}
def _create_alarm_data_type_event(self, def _create_alarm_data_type_event(self,
state="ok", state="ok",
type="event", type="event",
rule=None): rule=None):
if rule is None: if rule is None:
rule = {"query": [], "event_type": "*"} rule = {"query": [], "event_type": "*"}
return {AodhProps.DESCRIPTION: "test", return {AodhProps.DESCRIPTION: "test",
AodhProps.TIMESTAMP: "2016-11-09T01:39:13.839584", AodhProps.TIMESTAMP: "2016-11-09T01:39:13.839584",
AodhProps.ENABLED: True, AodhProps.ENABLED: True,
AodhProps.STATE_TIMESTAMP: "2016-11-09T01:39:13.839584", AodhProps.STATE_TIMESTAMP: "2016-11-09T01:39:13.839584",
AodhProps.ALARM_ID: "7e5c3754-e2eb-4782-ae00-7da5ded8568b", AodhProps.ALARM_ID: "7e5c3754-e2eb-4782-ae00-7da5ded8568b",
AodhProps.REPEAT_ACTIONS: False, AodhProps.REPEAT_ACTIONS: False,
AodhProps.PROJECT_ID: "c365d18fcc03493187016ae743f0cc4d", AodhProps.PROJECT_ID: "c365d18fcc03493187016ae743f0cc4d",
AodhProps.NAME: "test", AodhProps.NAME: "test",
AodhProps.SEVERITY: "low", AodhProps.SEVERITY: "low",
AodhProps.TYPE: type, AodhProps.TYPE: type,
AodhProps.STATE: state, AodhProps.STATE: state,
AodhProps.RULE: rule} AodhProps.RULE: rule}
def _validate_aodh_entity_comm_props(self, entity, alarm): def _validate_aodh_entity_comm_props(self, entity, alarm):
self.assertEqual(entity[AodhProps.ALARM_ID], self.assertEqual(entity[AodhProps.ALARM_ID],
alarm[AodhProps.ALARM_ID]) alarm[AodhProps.ALARM_ID])
self.assertEqual(entity[AodhProps.PROJECT_ID], self.assertEqual(entity[AodhProps.PROJECT_ID],
alarm[AodhProps.PROJECT_ID]) alarm[AodhProps.PROJECT_ID])
self.assertEqual(entity[AodhProps.TIMESTAMP], self.assertEqual(entity[AodhProps.TIMESTAMP],
alarm[AodhProps.TIMESTAMP]) alarm[AodhProps.TIMESTAMP])
self.assertEqual(entity[AodhProps.DESCRIPTION], self.assertEqual(entity[AodhProps.DESCRIPTION],
alarm[AodhProps.DETAIL][AodhProps.DESCRIPTION]) alarm[AodhProps.DETAIL][AodhProps.DESCRIPTION])
self.assertEqual(entity[AodhProps.ENABLED], self.assertEqual(entity[AodhProps.ENABLED],
alarm[AodhProps.DETAIL][AodhProps.ENABLED]) alarm[AodhProps.DETAIL][AodhProps.ENABLED])
self.assertEqual(entity[AodhProps.NAME], self.assertEqual(entity[AodhProps.NAME],
alarm[AodhProps.DETAIL][AodhProps.NAME]) alarm[AodhProps.DETAIL][AodhProps.NAME])
self.assertEqual(entity[AodhProps.REPEAT_ACTIONS], self.assertEqual(entity[AodhProps.REPEAT_ACTIONS],
alarm[AodhProps.DETAIL][AodhProps.REPEAT_ACTIONS]) alarm[AodhProps.DETAIL][AodhProps.REPEAT_ACTIONS])
self.assertEqual(entity[AodhProps.TYPE], self.assertEqual(entity[AodhProps.TYPE],
alarm[AodhProps.DETAIL][AodhProps.TYPE]) alarm[AodhProps.DETAIL][AodhProps.TYPE])

View File

@ -1,158 +1,158 @@
# Copyright 2016 - ZTE, Nokia # Copyright 2016 - ZTE, Nokia
# #
# Licensed under the Apache License, Version 2.0 (the "License"); you may # 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 # not use this file except in compliance with the License. You may obtain
# a copy of the License at # a copy of the License at
# #
# http://www.apache.org/licenses/LICENSE-2.0 # http://www.apache.org/licenses/LICENSE-2.0
# #
# Unless required by applicable law or agreed to in writing, software # Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
from oslo_config import cfg from oslo_config import cfg
from oslo_log import log as logging from oslo_log import log as logging
from vitrage.common.constants import DatasourceOpts as DSOpts from vitrage.common.constants import DatasourceOpts as DSOpts
from vitrage.common.constants import DatasourceProperties as DSProps from vitrage.common.constants import DatasourceProperties as DSProps
from vitrage.common.constants import EntityCategory from vitrage.common.constants import EntityCategory
from vitrage.common.constants import UpdateMethod from vitrage.common.constants import UpdateMethod
from vitrage.datasources.aodh import AODH_DATASOURCE from vitrage.datasources.aodh import AODH_DATASOURCE
from vitrage.datasources.aodh.properties import AodhProperties as AodhProps from vitrage.datasources.aodh.properties import AodhProperties as AodhProps
from vitrage.datasources.aodh.transformer import AodhTransformer from vitrage.datasources.aodh.transformer import AodhTransformer
from vitrage.datasources.transformer_base import TransformerBase from vitrage.datasources.transformer_base import TransformerBase
from vitrage.tests.mocks import mock_transformer as mock_sync from vitrage.tests.mocks import mock_transformer as mock_sync
from vitrage.tests.unit.datasources.aodh.aodh_transformer_base_test import \ from vitrage.tests.unit.datasources.aodh.aodh_transformer_base_test import \
AodhTransformerBaseTest AodhTransformerBaseTest
LOG = logging.getLogger(__name__) LOG = logging.getLogger(__name__)
class TestAodhAlarmTransformer(AodhTransformerBaseTest): class TestAodhAlarmTransformer(AodhTransformerBaseTest):
OPTS = [ OPTS = [
cfg.StrOpt(DSOpts.UPDATE_METHOD, cfg.StrOpt(DSOpts.UPDATE_METHOD,
default=UpdateMethod.PULL), default=UpdateMethod.PULL),
] ]
@classmethod @classmethod
def setUpClass(cls): def setUpClass(cls):
cls.transformers = {} cls.transformers = {}
cls.conf = cfg.ConfigOpts() cls.conf = cfg.ConfigOpts()
cls.conf.register_opts(cls.OPTS, group=AODH_DATASOURCE) cls.conf.register_opts(cls.OPTS, group=AODH_DATASOURCE)
cls.transformers[AODH_DATASOURCE] = \ cls.transformers[AODH_DATASOURCE] = \
AodhTransformer(cls.transformers, cls.conf) AodhTransformer(cls.transformers, cls.conf)
def test_key_values_with_vitrage_alarm(self): def test_key_values_with_vitrage_alarm(self):
LOG.debug('Aodh transformer test: get key values(vitrage_alarm)') LOG.debug('Aodh transformer test: get key values(vitrage_alarm)')
# Test setup # Test setup
entity = {AodhProps.VITRAGE_ID: 'test', entity = {AodhProps.VITRAGE_ID: 'test',
DSProps.ENTITY_TYPE: AODH_DATASOURCE, DSProps.ENTITY_TYPE: AODH_DATASOURCE,
AodhProps.ALARM_ID: '12345'} AodhProps.ALARM_ID: '12345'}
transformer = self.transformers[AODH_DATASOURCE] transformer = self.transformers[AODH_DATASOURCE]
# Test action # Test action
observed_key_fields = transformer._create_entity_key(entity) observed_key_fields = transformer._create_entity_key(entity)
# Test assertions # Test assertions
self.assertEqual('test', observed_key_fields) self.assertEqual('test', observed_key_fields)
def test_key_values(self): def test_key_values(self):
LOG.debug('Aodh transformer test: get key values(aodh alarm)') LOG.debug('Aodh transformer test: get key values(aodh alarm)')
# Test setup # Test setup
entity = {DSProps.ENTITY_TYPE: AODH_DATASOURCE, entity = {DSProps.ENTITY_TYPE: AODH_DATASOURCE,
AodhProps.ALARM_ID: '12345'} AodhProps.ALARM_ID: '12345'}
transformer = self.transformers[AODH_DATASOURCE] transformer = self.transformers[AODH_DATASOURCE]
# Test action # Test action
entity_key_fields = transformer._create_entity_key(entity).split(":") entity_key_fields = transformer._create_entity_key(entity).split(":")
# Test assertions # Test assertions
self.assertEqual(EntityCategory.ALARM, entity_key_fields[0]) self.assertEqual(EntityCategory.ALARM, entity_key_fields[0])
self.assertEqual(AODH_DATASOURCE, entity_key_fields[1]) self.assertEqual(AODH_DATASOURCE, entity_key_fields[1])
self.assertEqual(entity[AodhProps.ALARM_ID], entity_key_fields[2]) self.assertEqual(entity[AodhProps.ALARM_ID], entity_key_fields[2])
def test_snapshot_transform(self): def test_snapshot_transform(self):
LOG.debug('Aodh alarm transformer test: transform entity event ' LOG.debug('Aodh alarm transformer test: transform entity event '
'snapshot') 'snapshot')
# Test setup # Test setup
spec_list = mock_sync.simple_aodh_alarm_generators(alarm_num=3, spec_list = mock_sync.simple_aodh_alarm_generators(alarm_num=3,
snapshot_events=3) snapshot_events=3)
static_events = mock_sync.generate_random_events_list(spec_list) static_events = mock_sync.generate_random_events_list(spec_list)
for event in static_events: for event in static_events:
# convert neighbor from dict to vertex object # convert neighbor from dict to vertex object
neighbors = event[TransformerBase.QUERY_RESULT] neighbors = event[TransformerBase.QUERY_RESULT]
vertices = [] vertices = []
for neighbor in neighbors: for neighbor in neighbors:
neighbor_vertex = self._convert_dist_to_vertex(neighbor) neighbor_vertex = self._convert_dist_to_vertex(neighbor)
vertices.append(self.transformers[AODH_DATASOURCE]. vertices.append(self.transformers[AODH_DATASOURCE].
update_uuid_in_vertex(neighbor_vertex)) update_uuid_in_vertex(neighbor_vertex))
event[TransformerBase.QUERY_RESULT] = vertices event[TransformerBase.QUERY_RESULT] = vertices
# Test action # Test action
wrapper = self.transformers[AODH_DATASOURCE].transform(event) wrapper = self.transformers[AODH_DATASOURCE].transform(event)
# Test assertions # Test assertions
vertex = wrapper.vertex vertex = wrapper.vertex
self._validate_aodh_vertex_props(vertex, event) self._validate_aodh_vertex_props(vertex, event)
neighbors = wrapper.neighbors neighbors = wrapper.neighbors
self.assertEqual(1, len(neighbors)) self.assertEqual(1, len(neighbors))
self._validate_neighbors(neighbors, vertex.vertex_id, event) self._validate_neighbors(neighbors, vertex.vertex_id, event)
self._validate_action(event, wrapper) self._validate_action(event, wrapper)
class TestAodhAlarmPushTransformer(AodhTransformerBaseTest): class TestAodhAlarmPushTransformer(AodhTransformerBaseTest):
OPTS = [ OPTS = [
cfg.StrOpt(DSOpts.UPDATE_METHOD, cfg.StrOpt(DSOpts.UPDATE_METHOD,
default=UpdateMethod.PUSH), default=UpdateMethod.PUSH),
] ]
@classmethod @classmethod
def setUpClass(cls): def setUpClass(cls):
cls.transformers = {} cls.transformers = {}
cls.conf = cfg.ConfigOpts() cls.conf = cfg.ConfigOpts()
cls.conf.register_opts(cls.OPTS, group=AODH_DATASOURCE) cls.conf.register_opts(cls.OPTS, group=AODH_DATASOURCE)
cls.transformers[AODH_DATASOURCE] = \ cls.transformers[AODH_DATASOURCE] = \
AodhTransformer(cls.transformers, cls.conf) AodhTransformer(cls.transformers, cls.conf)
def test_update_transform(self): def test_update_transform(self):
LOG.debug('Aodh update alarm transformer test:' LOG.debug('Aodh update alarm transformer test:'
'transform entity event update') 'transform entity event update')
# Test setup # Test setup
spec_list = \ spec_list = \
mock_sync.simple_aodh_update_alarm_generators(alarm_num=5, mock_sync.simple_aodh_update_alarm_generators(alarm_num=5,
update_events=5) update_events=5)
static_events = mock_sync.generate_random_events_list(spec_list) static_events = mock_sync.generate_random_events_list(spec_list)
for event in static_events: for event in static_events:
# convert neighbor from dict to vertex object # convert neighbor from dict to vertex object
neighbors = event[TransformerBase.QUERY_RESULT] neighbors = event[TransformerBase.QUERY_RESULT]
vertices = [] vertices = []
for neighbor in neighbors: for neighbor in neighbors:
neighbor_vertex = self._convert_dist_to_vertex(neighbor) neighbor_vertex = self._convert_dist_to_vertex(neighbor)
vertices.append(self.transformers[AODH_DATASOURCE]. vertices.append(self.transformers[AODH_DATASOURCE].
update_uuid_in_vertex(neighbor_vertex)) update_uuid_in_vertex(neighbor_vertex))
event[TransformerBase.QUERY_RESULT] = vertices event[TransformerBase.QUERY_RESULT] = vertices
# Test action # Test action
wrapper = self.transformers[AODH_DATASOURCE].transform(event) wrapper = self.transformers[AODH_DATASOURCE].transform(event)
# Test assertions # Test assertions
vertex = wrapper.vertex vertex = wrapper.vertex
self._validate_aodh_vertex_props(vertex, event) self._validate_aodh_vertex_props(vertex, event)
neighbors = wrapper.neighbors neighbors = wrapper.neighbors
self.assertEqual(1, len(neighbors)) self.assertEqual(1, len(neighbors))
self._validate_neighbors(neighbors, vertex.vertex_id, event) self._validate_neighbors(neighbors, vertex.vertex_id, event)
self._validate_action(event, wrapper) self._validate_action(event, wrapper)

View File

@ -1,15 +1,15 @@
# Copyright 2017 - ZTE # Copyright 2017 - ZTE
# #
# Licensed under the Apache License, Version 2.0 (the "License"); you may # 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 # not use this file except in compliance with the License. You may obtain
# a copy of the License at # a copy of the License at
# #
# http://www.apache.org/licenses/LICENSE-2.0 # http://www.apache.org/licenses/LICENSE-2.0
# #
# Unless required by applicable law or agreed to in writing, software # Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
__author__ = 'stack' __author__ = 'stack'

View File

@ -1,119 +1,119 @@
# Copyright 2017 - ZTE, Nokia # Copyright 2017 - ZTE, Nokia
# #
# Licensed under the Apache License, Version 2.0 (the "License"); you may # 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 # not use this file except in compliance with the License. You may obtain
# a copy of the License at # a copy of the License at
# #
# http://www.apache.org/licenses/LICENSE-2.0 # http://www.apache.org/licenses/LICENSE-2.0
# #
# Unless required by applicable law or agreed to in writing, software # Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
from vitrage.common.constants import DatasourceAction from vitrage.common.constants import DatasourceAction
from vitrage.common.constants import DatasourceProperties as DSProps from vitrage.common.constants import DatasourceProperties as DSProps
from vitrage.common.constants import EdgeLabel from vitrage.common.constants import EdgeLabel
from vitrage.common.constants import EntityCategory from vitrage.common.constants import EntityCategory
from vitrage.common.constants import GraphAction from vitrage.common.constants import GraphAction
from vitrage.common.constants import VertexProperties as VProps from vitrage.common.constants import VertexProperties as VProps
from vitrage.datasources.alarm_properties import AlarmProperties as AlarmProps from vitrage.datasources.alarm_properties import AlarmProperties as AlarmProps
from vitrage.datasources.ceilometer.properties \ from vitrage.datasources.ceilometer.properties \
import CeilometerProperties as CeilProps import CeilometerProperties as CeilProps
from vitrage.datasources.ceilometer.properties import CeilometerState from vitrage.datasources.ceilometer.properties import CeilometerState
from vitrage.datasources.nova.instance import NOVA_INSTANCE_DATASOURCE from vitrage.datasources.nova.instance import NOVA_INSTANCE_DATASOURCE
from vitrage.datasources.transformer_base import TransformerBase from vitrage.datasources.transformer_base import TransformerBase
from vitrage.graph.driver.elements import Vertex from vitrage.graph.driver.elements import Vertex
from vitrage.tests import base from vitrage.tests import base
class CeilometerTransformerBaseTest(base.BaseTest): class CeilometerTransformerBaseTest(base.BaseTest):
def _validate_aodh_vertex_props(self, vertex, event): def _validate_aodh_vertex_props(self, vertex, event):
self.assertEqual(EntityCategory.ALARM, self.assertEqual(EntityCategory.ALARM,
vertex[VProps.VITRAGE_CATEGORY]) vertex[VProps.VITRAGE_CATEGORY])
self.assertEqual(event[DSProps.ENTITY_TYPE], self.assertEqual(event[DSProps.ENTITY_TYPE],
vertex[VProps.VITRAGE_TYPE]) vertex[VProps.VITRAGE_TYPE])
self.assertEqual(event[CeilProps.NAME], vertex[VProps.NAME]) self.assertEqual(event[CeilProps.NAME], vertex[VProps.NAME])
self.assertEqual(event[CeilProps.SEVERITY], self.assertEqual(event[CeilProps.SEVERITY],
vertex[VProps.SEVERITY]) vertex[VProps.SEVERITY])
self.assertEqual(event[CeilProps.DESCRIPTION], self.assertEqual(event[CeilProps.DESCRIPTION],
vertex[CeilProps.DESCRIPTION]) vertex[CeilProps.DESCRIPTION])
self.assertEqual(event[CeilProps.ENABLED], self.assertEqual(event[CeilProps.ENABLED],
vertex[CeilProps.ENABLED]) vertex[CeilProps.ENABLED])
self.assertEqual(event[CeilProps.PROJECT_ID], self.assertEqual(event[CeilProps.PROJECT_ID],
vertex[VProps.PROJECT_ID]) vertex[VProps.PROJECT_ID])
self.assertEqual(event[CeilProps.REPEAT_ACTIONS], self.assertEqual(event[CeilProps.REPEAT_ACTIONS],
vertex[CeilProps.REPEAT_ACTIONS]) vertex[CeilProps.REPEAT_ACTIONS])
self.assertEqual(event[CeilProps.TYPE], vertex['alarm_type']) self.assertEqual(event[CeilProps.TYPE], vertex['alarm_type'])
if event[CeilProps.TYPE] == CeilProps.EVENT: if event[CeilProps.TYPE] == CeilProps.EVENT:
self.assertEqual(event[CeilProps.EVENT_TYPE], self.assertEqual(event[CeilProps.EVENT_TYPE],
vertex[CeilProps.EVENT_TYPE]) vertex[CeilProps.EVENT_TYPE])
elif event[CeilProps.TYPE] == CeilProps.THRESHOLD: elif event[CeilProps.TYPE] == CeilProps.THRESHOLD:
self.assertEqual(event[CeilProps.STATE_TIMESTAMP], self.assertEqual(event[CeilProps.STATE_TIMESTAMP],
vertex[CeilProps.STATE_TIMESTAMP]) vertex[CeilProps.STATE_TIMESTAMP])
self.assertEqual(event[DSProps.SAMPLE_DATE], self.assertEqual(event[DSProps.SAMPLE_DATE],
vertex[VProps.VITRAGE_SAMPLE_TIMESTAMP]) vertex[VProps.VITRAGE_SAMPLE_TIMESTAMP])
event_status = event[CeilProps.STATE] event_status = event[CeilProps.STATE]
if event_status == CeilometerState.OK: if event_status == CeilometerState.OK:
self.assertEqual(AlarmProps.INACTIVE_STATE, self.assertEqual(AlarmProps.INACTIVE_STATE,
vertex[VProps.STATE]) vertex[VProps.STATE])
else: else:
self.assertEqual(AlarmProps.ACTIVE_STATE, self.assertEqual(AlarmProps.ACTIVE_STATE,
vertex[VProps.STATE]) vertex[VProps.STATE])
self.assertFalse(vertex[VProps.VITRAGE_IS_PLACEHOLDER]) self.assertFalse(vertex[VProps.VITRAGE_IS_PLACEHOLDER])
self.assertFalse(vertex[VProps.VITRAGE_IS_DELETED]) self.assertFalse(vertex[VProps.VITRAGE_IS_DELETED])
def _validate_action(self, alarm, wrapper): def _validate_action(self, alarm, wrapper):
if DSProps.EVENT_TYPE in alarm \ if DSProps.EVENT_TYPE in alarm \
and alarm[DSProps.EVENT_TYPE] in GraphAction.__dict__.values(): and alarm[DSProps.EVENT_TYPE] in GraphAction.__dict__.values():
self.assertEqual(alarm[DSProps.EVENT_TYPE], wrapper.action) self.assertEqual(alarm[DSProps.EVENT_TYPE], wrapper.action)
return return
ds_action = alarm[DSProps.DATASOURCE_ACTION] ds_action = alarm[DSProps.DATASOURCE_ACTION]
if ds_action in (DatasourceAction.SNAPSHOT, DatasourceAction.UPDATE): if ds_action in (DatasourceAction.SNAPSHOT, DatasourceAction.UPDATE):
self.assertEqual(GraphAction.UPDATE_ENTITY, wrapper.action) self.assertEqual(GraphAction.UPDATE_ENTITY, wrapper.action)
else: else:
self.assertEqual(GraphAction.CREATE_ENTITY, wrapper.action) self.assertEqual(GraphAction.CREATE_ENTITY, wrapper.action)
def _validate_neighbors(self, neighbors, alarm_id, event): def _validate_neighbors(self, neighbors, alarm_id, event):
resource_counter = 0 resource_counter = 0
for neighbor in neighbors: for neighbor in neighbors:
resource_id = event[CeilProps.RESOURCE_ID] resource_id = event[CeilProps.RESOURCE_ID]
self._validate_instance_neighbor(neighbor, self._validate_instance_neighbor(neighbor,
resource_id, resource_id,
alarm_id) alarm_id)
resource_counter += 1 resource_counter += 1
self.assertEqual(1, self.assertEqual(1,
resource_counter, resource_counter,
'Alarm can be belonged to only one resource') 'Alarm can be belonged to only one resource')
def _validate_instance_neighbor(self, def _validate_instance_neighbor(self,
alarm_neighbor, alarm_neighbor,
resource_id, resource_id,
alarm_vertex_id): alarm_vertex_id):
# validate neighbor vertex # validate neighbor vertex
self.assertEqual(EntityCategory.RESOURCE, self.assertEqual(EntityCategory.RESOURCE,
alarm_neighbor.vertex[VProps.VITRAGE_CATEGORY]) alarm_neighbor.vertex[VProps.VITRAGE_CATEGORY])
self.assertEqual(NOVA_INSTANCE_DATASOURCE, self.assertEqual(NOVA_INSTANCE_DATASOURCE,
alarm_neighbor.vertex[VProps.VITRAGE_TYPE]) alarm_neighbor.vertex[VProps.VITRAGE_TYPE])
self.assertEqual(resource_id, alarm_neighbor.vertex[VProps.ID]) 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_PLACEHOLDER])
self.assertFalse(alarm_neighbor.vertex[VProps.VITRAGE_IS_DELETED]) self.assertFalse(alarm_neighbor.vertex[VProps.VITRAGE_IS_DELETED])
# Validate neighbor edge # Validate neighbor edge
edge = alarm_neighbor.edge edge = alarm_neighbor.edge
self.assertEqual(edge.target_id, alarm_neighbor.vertex.vertex_id) self.assertEqual(edge.target_id, alarm_neighbor.vertex.vertex_id)
self.assertEqual(edge.source_id, alarm_vertex_id) self.assertEqual(edge.source_id, alarm_vertex_id)
self.assertEqual(edge.label, EdgeLabel.ON) self.assertEqual(edge.label, EdgeLabel.ON)
def _convert_dist_to_vertex(self, neighbor): def _convert_dist_to_vertex(self, neighbor):
ver_id = neighbor[VProps.VITRAGE_CATEGORY] + \ ver_id = neighbor[VProps.VITRAGE_CATEGORY] + \
TransformerBase.KEY_SEPARATOR + neighbor[VProps.VITRAGE_TYPE] + \ TransformerBase.KEY_SEPARATOR + neighbor[VProps.VITRAGE_TYPE] + \
TransformerBase.KEY_SEPARATOR + neighbor[VProps.ID] TransformerBase.KEY_SEPARATOR + neighbor[VProps.ID]
return Vertex(vertex_id=ver_id, properties=neighbor) return Vertex(vertex_id=ver_id, properties=neighbor)

View File

@ -1,27 +1,27 @@
# Copyright 2017 - Nokia # Copyright 2017 - Nokia
# #
# Licensed under the Apache License, Version 2.0 (the "License"); you may # 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 # not use this file except in compliance with the License. You may obtain
# a copy of the License at # a copy of the License at
# #
# http://www.apache.org/licenses/LICENSE-2.0 # http://www.apache.org/licenses/LICENSE-2.0
# #
# Unless required by applicable law or agreed to in writing, software # Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
from vitrage.datasources.ceilometer.driver import CeilometerDriver from vitrage.datasources.ceilometer.driver import CeilometerDriver
class MockCeilometerDriver(CeilometerDriver): class MockCeilometerDriver(CeilometerDriver):
"""A aodh driver for tests. """A aodh driver for tests.
""" """
def __init__(self, conf): def __init__(self, conf):
super(MockCeilometerDriver, self).__init__(conf) super(MockCeilometerDriver, self).__init__(conf)
def _cache_all_alarms(self): def _cache_all_alarms(self):
pass pass

View File

@ -1,389 +1,389 @@
# Copyright 2017 - ZTE, Nokia # Copyright 2017 - ZTE, Nokia
# #
# Licensed under the Apache License, Version 2.0 (the "License"); you may # 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 # not use this file except in compliance with the License. You may obtain
# a copy of the License at # a copy of the License at
# #
# http://www.apache.org/licenses/LICENSE-2.0 # http://www.apache.org/licenses/LICENSE-2.0
# #
# Unless required by applicable law or agreed to in writing, software # Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
from oslo_config import cfg from oslo_config import cfg
from vitrage.common.constants import DatasourceOpts as DSOpts from vitrage.common.constants import DatasourceOpts as DSOpts
from vitrage.common.constants import DatasourceProperties as DSProps from vitrage.common.constants import DatasourceProperties as DSProps
from vitrage.common.constants import UpdateMethod from vitrage.common.constants import UpdateMethod
from vitrage.datasources.ceilometer import CEILOMETER_DATASOURCE from vitrage.datasources.ceilometer import CEILOMETER_DATASOURCE
from vitrage.datasources.ceilometer.properties import CeilometerEventType from vitrage.datasources.ceilometer.properties import CeilometerEventType
from vitrage.datasources.ceilometer.properties \ from vitrage.datasources.ceilometer.properties \
import CeilometerProperties as CeilProps import CeilometerProperties as CeilProps
from vitrage.tests import base from vitrage.tests import base
from vitrage.tests.mocks import mock_driver from vitrage.tests.mocks import mock_driver
from vitrage.tests.unit.datasources.ceilometer.mock_driver \ from vitrage.tests.unit.datasources.ceilometer.mock_driver \
import MockCeilometerDriver import MockCeilometerDriver
class CeilometerDriverTest(base.BaseTest): class CeilometerDriverTest(base.BaseTest):
OPTS = [ OPTS = [
cfg.StrOpt(DSOpts.UPDATE_METHOD, cfg.StrOpt(DSOpts.UPDATE_METHOD,
default=UpdateMethod.PUSH), default=UpdateMethod.PUSH),
] ]
# noinspection PyPep8Naming # noinspection PyPep8Naming
@classmethod @classmethod
def setUpClass(cls): def setUpClass(cls):
cls.conf = cfg.ConfigOpts() cls.conf = cfg.ConfigOpts()
cls.conf.register_opts(cls.OPTS, group=CEILOMETER_DATASOURCE) cls.conf.register_opts(cls.OPTS, group=CEILOMETER_DATASOURCE)
def test_event_alarm_notifications(self): def test_event_alarm_notifications(self):
aodh_driver = MockCeilometerDriver(self.conf) aodh_driver = MockCeilometerDriver(self.conf)
# 1. alarm creation with 'ok' state # 1. alarm creation with 'ok' state
# prepare data # prepare data
detail_data = {"type": "creation", detail_data = {"type": "creation",
CeilProps.DETAIL: self._create_alarm_data_type_event(), CeilProps.DETAIL: self._create_alarm_data_type_event(),
} }
generators = \ generators = \
mock_driver.simple_aodh_alarm_notification_generators( mock_driver.simple_aodh_alarm_notification_generators(
alarm_num=1, alarm_num=1,
update_events=1, update_events=1,
update_vals=detail_data) update_vals=detail_data)
alarm = mock_driver.generate_sequential_events_list(generators)[0] alarm = mock_driver.generate_sequential_events_list(generators)[0]
alarm_info = alarm.copy() alarm_info = alarm.copy()
# action # action
entity = aodh_driver.enrich_event(alarm, CeilometerEventType.CREATION) entity = aodh_driver.enrich_event(alarm, CeilometerEventType.CREATION)
# Test assertions # Test assertions
# alarm with status OK should not be handled # alarm with status OK should not be handled
self.assertIsNone(entity) self.assertIsNone(entity)
# 2.alarm state transition from 'ok' to 'alarm' # 2.alarm state transition from 'ok' to 'alarm'
detail_data = {"type": "state transition", detail_data = {"type": "state transition",
CeilProps.DETAIL: {CeilProps.STATE: "alarm"}} CeilProps.DETAIL: {CeilProps.STATE: "alarm"}}
alarm.update(detail_data) alarm.update(detail_data)
entity = aodh_driver.enrich_event(alarm, entity = aodh_driver.enrich_event(alarm,
CeilometerEventType.STATE_TRANSITION) CeilometerEventType.STATE_TRANSITION)
# Test assertions # Test assertions
# alarm state change: ok->alarm, need to be added # alarm state change: ok->alarm, need to be added
self.assertIsNotNone(entity) self.assertIsNotNone(entity)
self._validate_aodh_entity_comm_props(entity, alarm_info) self._validate_aodh_entity_comm_props(entity, alarm_info)
self.assertEqual(entity[CeilProps.STATE], self.assertEqual(entity[CeilProps.STATE],
alarm[CeilProps.DETAIL][CeilProps.STATE]) alarm[CeilProps.DETAIL][CeilProps.STATE])
self.assertEqual(entity[CeilProps.SEVERITY], self.assertEqual(entity[CeilProps.SEVERITY],
alarm[CeilProps.SEVERITY]) alarm[CeilProps.SEVERITY])
self.assertEqual(entity[DSProps.EVENT_TYPE], self.assertEqual(entity[DSProps.EVENT_TYPE],
CeilometerEventType.STATE_TRANSITION) CeilometerEventType.STATE_TRANSITION)
# 3. delete alarm which is 'alarm' state # 3. delete alarm which is 'alarm' state
# prepare data # prepare data
detail_data = {"type": "deletion"} detail_data = {"type": "deletion"}
alarm.update(detail_data) alarm.update(detail_data)
# action # action
entity = aodh_driver.enrich_event( entity = aodh_driver.enrich_event(
alarm, CeilometerEventType.DELETION) alarm, CeilometerEventType.DELETION)
# Test assertions # Test assertions
self.assertIsNotNone(entity) self.assertIsNotNone(entity)
self._validate_aodh_entity_comm_props(entity, alarm_info) self._validate_aodh_entity_comm_props(entity, alarm_info)
self.assertEqual(entity[DSProps.EVENT_TYPE], self.assertEqual(entity[DSProps.EVENT_TYPE],
CeilometerEventType.DELETION) CeilometerEventType.DELETION)
# 4. alarm creation with 'alarm' state # 4. alarm creation with 'alarm' state
# prepare data # prepare data
detail_data = {"type": "creation", detail_data = {"type": "creation",
CeilProps.DETAIL: CeilProps.DETAIL:
self._create_alarm_data_type_event(state="alarm")} self._create_alarm_data_type_event(state="alarm")}
generators = \ generators = \
mock_driver.simple_aodh_alarm_notification_generators( mock_driver.simple_aodh_alarm_notification_generators(
alarm_num=1, alarm_num=1,
update_events=1, update_events=1,
update_vals=detail_data) update_vals=detail_data)
alarm = mock_driver.generate_sequential_events_list(generators)[0] alarm = mock_driver.generate_sequential_events_list(generators)[0]
alarm_info = alarm.copy() alarm_info = alarm.copy()
# action # action
entity = aodh_driver.enrich_event( entity = aodh_driver.enrich_event(
alarm, CeilometerEventType.CREATION) alarm, CeilometerEventType.CREATION)
# Test assertions # Test assertions
# alarm with status 'alarm' need to be added # alarm with status 'alarm' need to be added
self.assertIsNotNone(entity) self.assertIsNotNone(entity)
self._validate_aodh_entity_comm_props(entity, alarm_info) self._validate_aodh_entity_comm_props(entity, alarm_info)
self.assertEqual(entity[CeilProps.STATE], self.assertEqual(entity[CeilProps.STATE],
alarm[CeilProps.DETAIL][CeilProps.STATE]) alarm[CeilProps.DETAIL][CeilProps.STATE])
self.assertEqual(entity[CeilProps.SEVERITY], self.assertEqual(entity[CeilProps.SEVERITY],
alarm[CeilProps.SEVERITY]) alarm[CeilProps.SEVERITY])
self.assertIsNone(entity[CeilProps.RESOURCE_ID]) self.assertIsNone(entity[CeilProps.RESOURCE_ID])
self.assertEqual("*", entity[CeilProps.EVENT_TYPE]) self.assertEqual("*", entity[CeilProps.EVENT_TYPE])
self.assertEqual(entity[DSProps.EVENT_TYPE], self.assertEqual(entity[DSProps.EVENT_TYPE],
CeilometerEventType.CREATION) CeilometerEventType.CREATION)
# 5. alarm rule change # 5. alarm rule change
# prepare data # prepare data
detail_data = {"type": "rule change", detail_data = {"type": "rule change",
CeilProps.DETAIL: { CeilProps.DETAIL: {
"severity": "critical", "severity": "critical",
CeilProps.RULE: CeilProps.RULE:
{"query": [{"field": "traits.resource_id", {"query": [{"field": "traits.resource_id",
"type": "", "type": "",
"value": "1", "value": "1",
"op": "eq"}], "op": "eq"}],
"event_type": "instance.update"}}} "event_type": "instance.update"}}}
alarm.update(detail_data) alarm.update(detail_data)
# action # action
entity = aodh_driver.enrich_event( entity = aodh_driver.enrich_event(
alarm, CeilometerEventType.RULE_CHANGE) alarm, CeilometerEventType.RULE_CHANGE)
# Test assertions # Test assertions
# alarm rule change: need to be update # alarm rule change: need to be update
self.assertIsNotNone(entity) self.assertIsNotNone(entity)
self._validate_aodh_entity_comm_props(entity, alarm_info) self._validate_aodh_entity_comm_props(entity, alarm_info)
self.assertEqual(entity[CeilProps.SEVERITY], self.assertEqual(entity[CeilProps.SEVERITY],
alarm[CeilProps.DETAIL][CeilProps.SEVERITY]) alarm[CeilProps.DETAIL][CeilProps.SEVERITY])
self.assertEqual( self.assertEqual(
entity[CeilProps.EVENT_TYPE], entity[CeilProps.EVENT_TYPE],
alarm[CeilProps.DETAIL][CeilProps.RULE][CeilProps.EVENT_TYPE]) alarm[CeilProps.DETAIL][CeilProps.RULE][CeilProps.EVENT_TYPE])
self.assertEqual("1", entity[CeilProps.RESOURCE_ID]) self.assertEqual("1", entity[CeilProps.RESOURCE_ID])
self.assertEqual(entity[DSProps.EVENT_TYPE], self.assertEqual(entity[DSProps.EVENT_TYPE],
CeilometerEventType.RULE_CHANGE) CeilometerEventType.RULE_CHANGE)
# 6. alarm state change from 'alarm' to 'ok' # 6. alarm state change from 'alarm' to 'ok'
# prepare data # prepare data
detail_data = {"type": "state transition", detail_data = {"type": "state transition",
CeilProps.DETAIL: {CeilProps.STATE: "ok"}} CeilProps.DETAIL: {CeilProps.STATE: "ok"}}
alarm.update(detail_data) alarm.update(detail_data)
# action # action
entity = aodh_driver.enrich_event( entity = aodh_driver.enrich_event(
alarm, CeilometerEventType.STATE_TRANSITION) alarm, CeilometerEventType.STATE_TRANSITION)
# Test assertions # Test assertions
# alarm state change: alarm->OK, need to be deleted # alarm state change: alarm->OK, need to be deleted
self.assertIsNotNone(entity) self.assertIsNotNone(entity)
self._validate_aodh_entity_comm_props(entity, alarm_info) self._validate_aodh_entity_comm_props(entity, alarm_info)
self.assertEqual(entity[DSProps.EVENT_TYPE], self.assertEqual(entity[DSProps.EVENT_TYPE],
CeilometerEventType.STATE_TRANSITION) CeilometerEventType.STATE_TRANSITION)
# 7. delete alarm which is 'ok' state # 7. delete alarm which is 'ok' state
# prepare data # prepare data
detail_data = {"type": "deletion"} detail_data = {"type": "deletion"}
alarm.update(detail_data) alarm.update(detail_data)
# action # action
entity = aodh_driver.enrich_event( entity = aodh_driver.enrich_event(
alarm, CeilometerEventType.DELETION) alarm, CeilometerEventType.DELETION)
# Test assertions # Test assertions
self.assertIsNone(entity) self.assertIsNone(entity)
def test_gnocchi_threshold_alarm_notifications(self): def test_gnocchi_threshold_alarm_notifications(self):
aodh_driver = MockCeilometerDriver(self.conf) aodh_driver = MockCeilometerDriver(self.conf)
# 1. alarm creation with 'ok' state # 1. alarm creation with 'ok' state
# prepare data # prepare data
detail_data = {"type": "gnocchi_resources_threshold", detail_data = {"type": "gnocchi_resources_threshold",
CeilProps.DETAIL: self._create_alarm_data_gnocchi()} CeilProps.DETAIL: self._create_alarm_data_gnocchi()}
generators = \ generators = \
mock_driver.simple_aodh_alarm_notification_generators( mock_driver.simple_aodh_alarm_notification_generators(
alarm_num=1, alarm_num=1,
update_events=1, update_events=1,
update_vals=detail_data) update_vals=detail_data)
alarm = mock_driver.generate_sequential_events_list(generators)[0] alarm = mock_driver.generate_sequential_events_list(generators)[0]
alarm_info = alarm.copy() alarm_info = alarm.copy()
# action # action
entity = aodh_driver.enrich_event( entity = aodh_driver.enrich_event(
alarm, CeilometerEventType.CREATION) alarm, CeilometerEventType.CREATION)
# Test assertions # Test assertions
# alarm with status OK should not be handled # alarm with status OK should not be handled
self.assertIsNone(entity) self.assertIsNone(entity)
# 2.alarm state transition from 'ok' to 'alarm' # 2.alarm state transition from 'ok' to 'alarm'
detail_data = {"type": "state transition", detail_data = {"type": "state transition",
CeilProps.DETAIL: {CeilProps.STATE: "alarm"}} CeilProps.DETAIL: {CeilProps.STATE: "alarm"}}
alarm.update(detail_data) alarm.update(detail_data)
entity = aodh_driver.enrich_event( entity = aodh_driver.enrich_event(
alarm, CeilometerEventType.STATE_TRANSITION) alarm, CeilometerEventType.STATE_TRANSITION)
# Test assertions # Test assertions
# alarm state change: ok->alarm, need to be added # alarm state change: ok->alarm, need to be added
self.assertIsNotNone(entity) self.assertIsNotNone(entity)
self._validate_aodh_entity_comm_props(entity, alarm_info) self._validate_aodh_entity_comm_props(entity, alarm_info)
self.assertEqual(entity[CeilProps.STATE], self.assertEqual(entity[CeilProps.STATE],
alarm[CeilProps.DETAIL][CeilProps.STATE]) alarm[CeilProps.DETAIL][CeilProps.STATE])
self.assertEqual(entity[CeilProps.SEVERITY], self.assertEqual(entity[CeilProps.SEVERITY],
alarm[CeilProps.SEVERITY]) alarm[CeilProps.SEVERITY])
# 3. delete alarm which is 'alarm' state # 3. delete alarm which is 'alarm' state
# prepare data # prepare data
detail_data = {"type": "deletion"} detail_data = {"type": "deletion"}
alarm.update(detail_data) alarm.update(detail_data)
# action # action
entity = aodh_driver.enrich_event( entity = aodh_driver.enrich_event(
alarm, CeilometerEventType.DELETION) alarm, CeilometerEventType.DELETION)
# Test assertions # Test assertions
self.assertIsNotNone(entity) self.assertIsNotNone(entity)
self._validate_aodh_entity_comm_props(entity, alarm_info) self._validate_aodh_entity_comm_props(entity, alarm_info)
self.assertEqual(entity[DSProps.EVENT_TYPE], self.assertEqual(entity[DSProps.EVENT_TYPE],
CeilometerEventType.DELETION) CeilometerEventType.DELETION)
# 4. alarm creation with 'alarm' state # 4. alarm creation with 'alarm' state
# prepare data # prepare data
detail_data = {"type": "gnocchi_resources_threshold", detail_data = {"type": "gnocchi_resources_threshold",
CeilProps.DETAIL: CeilProps.DETAIL:
self._create_alarm_data_gnocchi(state="alarm")} self._create_alarm_data_gnocchi(state="alarm")}
generators = \ generators = \
mock_driver.simple_aodh_alarm_notification_generators( mock_driver.simple_aodh_alarm_notification_generators(
alarm_num=1, alarm_num=1,
update_events=1, update_events=1,
update_vals=detail_data) update_vals=detail_data)
alarm = mock_driver.generate_sequential_events_list(generators)[0] alarm = mock_driver.generate_sequential_events_list(generators)[0]
alarm_info = alarm.copy() alarm_info = alarm.copy()
# action # action
entity = aodh_driver.enrich_event( entity = aodh_driver.enrich_event(
alarm, CeilometerEventType.CREATION) alarm, CeilometerEventType.CREATION)
# Test assertions # Test assertions
# alarm with status 'alarm' need to be added # alarm with status 'alarm' need to be added
self.assertIsNotNone(entity) self.assertIsNotNone(entity)
self._validate_aodh_entity_comm_props(entity, alarm_info) self._validate_aodh_entity_comm_props(entity, alarm_info)
self.assertEqual(entity[CeilProps.STATE], self.assertEqual(entity[CeilProps.STATE],
alarm[CeilProps.DETAIL][CeilProps.STATE]) alarm[CeilProps.DETAIL][CeilProps.STATE])
self.assertEqual(entity[CeilProps.SEVERITY], self.assertEqual(entity[CeilProps.SEVERITY],
alarm[CeilProps.SEVERITY]) alarm[CeilProps.SEVERITY])
self.assertEqual(entity[DSProps.EVENT_TYPE], self.assertEqual(entity[DSProps.EVENT_TYPE],
CeilometerEventType.CREATION) CeilometerEventType.CREATION)
# 5. alarm rule change # 5. alarm rule change
# prepare data # prepare data
detail_data = {"type": "rule change", detail_data = {"type": "rule change",
CeilProps.DETAIL: { CeilProps.DETAIL: {
"severity": "critical", "severity": "critical",
CeilProps.RULE: CeilProps.RULE:
{"granularity": "300", {"granularity": "300",
"threshold": "0.0123", "threshold": "0.0123",
"comparison_operator": "eq"}}} "comparison_operator": "eq"}}}
alarm.update(detail_data) alarm.update(detail_data)
# action # action
entity = aodh_driver.enrich_event( entity = aodh_driver.enrich_event(
alarm, CeilometerEventType.RULE_CHANGE) alarm, CeilometerEventType.RULE_CHANGE)
# Test assertions # Test assertions
# alarm rule change: need to be update # alarm rule change: need to be update
self.assertIsNotNone(entity) self.assertIsNotNone(entity)
self._validate_aodh_entity_comm_props(entity, alarm_info) self._validate_aodh_entity_comm_props(entity, alarm_info)
self.assertEqual(entity[CeilProps.SEVERITY], self.assertEqual(entity[CeilProps.SEVERITY],
alarm[CeilProps.DETAIL][CeilProps.SEVERITY]) alarm[CeilProps.DETAIL][CeilProps.SEVERITY])
self.assertEqual(entity[DSProps.EVENT_TYPE], self.assertEqual(entity[DSProps.EVENT_TYPE],
CeilometerEventType.RULE_CHANGE) CeilometerEventType.RULE_CHANGE)
# 6. alarm state change from 'alarm' to 'ok' # 6. alarm state change from 'alarm' to 'ok'
# prepare data # prepare data
detail_data = {"type": "state transition", detail_data = {"type": "state transition",
CeilProps.DETAIL: {CeilProps.STATE: "ok"}} CeilProps.DETAIL: {CeilProps.STATE: "ok"}}
alarm.update(detail_data) alarm.update(detail_data)
# action # action
entity = aodh_driver.enrich_event( entity = aodh_driver.enrich_event(
alarm, alarm,
CeilometerEventType.STATE_TRANSITION) CeilometerEventType.STATE_TRANSITION)
# Test assertions # Test assertions
# alarm state change: alarm->OK, need to be deleted # alarm state change: alarm->OK, need to be deleted
self.assertIsNotNone(entity) self.assertIsNotNone(entity)
self._validate_aodh_entity_comm_props(entity, alarm_info) self._validate_aodh_entity_comm_props(entity, alarm_info)
self.assertEqual(entity[DSProps.EVENT_TYPE], self.assertEqual(entity[DSProps.EVENT_TYPE],
CeilometerEventType.STATE_TRANSITION) CeilometerEventType.STATE_TRANSITION)
# 7. delete alarm which is 'ok' state # 7. delete alarm which is 'ok' state
# prepare data # prepare data
detail_data = {"type": "deletion"} detail_data = {"type": "deletion"}
alarm.update(detail_data) alarm.update(detail_data)
# action # action
entity = aodh_driver.enrich_event( entity = aodh_driver.enrich_event(
alarm, CeilometerEventType.DELETION) alarm, CeilometerEventType.DELETION)
# Test assertions # Test assertions
self.assertIsNone(entity) self.assertIsNone(entity)
def _create_alarm_data_gnocchi(self, def _create_alarm_data_gnocchi(self,
state="ok", state="ok",
type="gnocchi_resources_threshold", type="gnocchi_resources_threshold",
rule=None): rule=None):
if rule is None: if rule is None:
rule = {"granularity": "300", rule = {"granularity": "300",
"threshold": "0.001", "threshold": "0.001",
"comparison_operator": "gt", "comparison_operator": "gt",
"resource_type": "instance" "resource_type": "instance"
} }
return {CeilProps.DESCRIPTION: "test", return {CeilProps.DESCRIPTION: "test",
CeilProps.TIMESTAMP: "2016-11-09T01:39:13.839584", CeilProps.TIMESTAMP: "2016-11-09T01:39:13.839584",
CeilProps.ENABLED: True, CeilProps.ENABLED: True,
CeilProps.STATE_TIMESTAMP: "2016-11-09T01:39:13.839584", CeilProps.STATE_TIMESTAMP: "2016-11-09T01:39:13.839584",
CeilProps.ALARM_ID: "7e5c3754-e2eb-4782-ae00-7da5ded8568b", CeilProps.ALARM_ID: "7e5c3754-e2eb-4782-ae00-7da5ded8568b",
CeilProps.REPEAT_ACTIONS: False, CeilProps.REPEAT_ACTIONS: False,
CeilProps.PROJECT_ID: "c365d18fcc03493187016ae743f0cc4d", CeilProps.PROJECT_ID: "c365d18fcc03493187016ae743f0cc4d",
CeilProps.NAME: "test", CeilProps.NAME: "test",
CeilProps.SEVERITY: "low", CeilProps.SEVERITY: "low",
CeilProps.RESOURCE_ID: "88cd2d1d-8af4-4d00-9b5e-f82f8c8b0f8d", CeilProps.RESOURCE_ID: "88cd2d1d-8af4-4d00-9b5e-f82f8c8b0f8d",
CeilProps.TYPE: type, CeilProps.TYPE: type,
CeilProps.STATE: state, CeilProps.STATE: state,
CeilProps.RULE: rule, CeilProps.RULE: rule,
CeilProps.STATE_REASON: 'for test'} CeilProps.STATE_REASON: 'for test'}
def _create_alarm_data_type_event(self, def _create_alarm_data_type_event(self,
state="ok", state="ok",
type="event", type="event",
rule=None): rule=None):
if rule is None: if rule is None:
rule = {"query": [], "event_type": "*"} rule = {"query": [], "event_type": "*"}
return {CeilProps.DESCRIPTION: "test", return {CeilProps.DESCRIPTION: "test",
CeilProps.TIMESTAMP: "2016-11-09T01:39:13.839584", CeilProps.TIMESTAMP: "2016-11-09T01:39:13.839584",
CeilProps.ENABLED: True, CeilProps.ENABLED: True,
CeilProps.STATE_TIMESTAMP: "2016-11-09T01:39:13.839584", CeilProps.STATE_TIMESTAMP: "2016-11-09T01:39:13.839584",
CeilProps.ALARM_ID: "7e5c3754-e2eb-4782-ae00-7da5ded8568b", CeilProps.ALARM_ID: "7e5c3754-e2eb-4782-ae00-7da5ded8568b",
CeilProps.REPEAT_ACTIONS: False, CeilProps.REPEAT_ACTIONS: False,
CeilProps.PROJECT_ID: "c365d18fcc03493187016ae743f0cc4d", CeilProps.PROJECT_ID: "c365d18fcc03493187016ae743f0cc4d",
CeilProps.NAME: "test", CeilProps.NAME: "test",
CeilProps.SEVERITY: "low", CeilProps.SEVERITY: "low",
CeilProps.TYPE: type, CeilProps.TYPE: type,
CeilProps.STATE: state, CeilProps.STATE: state,
CeilProps.RULE: rule, CeilProps.RULE: rule,
CeilProps.STATE_REASON: 'for test'} CeilProps.STATE_REASON: 'for test'}
def _validate_aodh_entity_comm_props(self, entity, alarm): def _validate_aodh_entity_comm_props(self, entity, alarm):
self.assertEqual(entity[CeilProps.ALARM_ID], self.assertEqual(entity[CeilProps.ALARM_ID],
alarm[CeilProps.ALARM_ID]) alarm[CeilProps.ALARM_ID])
self.assertEqual(entity[CeilProps.PROJECT_ID], self.assertEqual(entity[CeilProps.PROJECT_ID],
alarm[CeilProps.PROJECT_ID]) alarm[CeilProps.PROJECT_ID])
self.assertEqual(entity[CeilProps.TIMESTAMP], self.assertEqual(entity[CeilProps.TIMESTAMP],
alarm[CeilProps.TIMESTAMP]) alarm[CeilProps.TIMESTAMP])
self.assertEqual(entity[CeilProps.DESCRIPTION], self.assertEqual(entity[CeilProps.DESCRIPTION],
alarm[CeilProps.DETAIL][CeilProps.DESCRIPTION]) alarm[CeilProps.DETAIL][CeilProps.DESCRIPTION])
self.assertEqual(entity[CeilProps.ENABLED], self.assertEqual(entity[CeilProps.ENABLED],
alarm[CeilProps.DETAIL][CeilProps.ENABLED]) alarm[CeilProps.DETAIL][CeilProps.ENABLED])
self.assertEqual(entity[CeilProps.NAME], self.assertEqual(entity[CeilProps.NAME],
alarm[CeilProps.DETAIL][CeilProps.NAME]) alarm[CeilProps.DETAIL][CeilProps.NAME])
self.assertEqual(entity[CeilProps.REPEAT_ACTIONS], self.assertEqual(entity[CeilProps.REPEAT_ACTIONS],
alarm[CeilProps.DETAIL][CeilProps.REPEAT_ACTIONS]) alarm[CeilProps.DETAIL][CeilProps.REPEAT_ACTIONS])
self.assertEqual(entity[CeilProps.TYPE], self.assertEqual(entity[CeilProps.TYPE],
alarm[CeilProps.DETAIL][CeilProps.TYPE]) alarm[CeilProps.DETAIL][CeilProps.TYPE])

View File

@ -1,161 +1,161 @@
# Copyright 2016 - ZTE, Nokia # Copyright 2016 - ZTE, Nokia
# #
# Licensed under the Apache License, Version 2.0 (the "License"); you may # 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 # not use this file except in compliance with the License. You may obtain
# a copy of the License at # a copy of the License at
# #
# http://www.apache.org/licenses/LICENSE-2.0 # http://www.apache.org/licenses/LICENSE-2.0
# #
# Unless required by applicable law or agreed to in writing, software # Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
from oslo_config import cfg from oslo_config import cfg
from oslo_log import log as logging from oslo_log import log as logging
from vitrage.common.constants import DatasourceOpts as DSOpts from vitrage.common.constants import DatasourceOpts as DSOpts
from vitrage.common.constants import DatasourceProperties as DSProps from vitrage.common.constants import DatasourceProperties as DSProps
from vitrage.common.constants import EntityCategory from vitrage.common.constants import EntityCategory
from vitrage.common.constants import UpdateMethod from vitrage.common.constants import UpdateMethod
from vitrage.datasources.ceilometer import CEILOMETER_DATASOURCE from vitrage.datasources.ceilometer import CEILOMETER_DATASOURCE
from vitrage.datasources.ceilometer.properties \ from vitrage.datasources.ceilometer.properties \
import CeilometerProperties as CeilProps import CeilometerProperties as CeilProps
from vitrage.datasources.ceilometer.transformer import CeilometerTransformer from vitrage.datasources.ceilometer.transformer import CeilometerTransformer
from vitrage.datasources.transformer_base import TransformerBase from vitrage.datasources.transformer_base import TransformerBase
from vitrage.tests.mocks import mock_transformer as mock_sync from vitrage.tests.mocks import mock_transformer as mock_sync
from vitrage.tests.unit.datasources.ceilometer.\ from vitrage.tests.unit.datasources.ceilometer.\
ceilometer_transformer_base_test \ ceilometer_transformer_base_test \
import CeilometerTransformerBaseTest import CeilometerTransformerBaseTest
LOG = logging.getLogger(__name__) LOG = logging.getLogger(__name__)
class TestCeilometerAlarmTransformer(CeilometerTransformerBaseTest): class TestCeilometerAlarmTransformer(CeilometerTransformerBaseTest):
OPTS = [ OPTS = [
cfg.StrOpt(DSOpts.UPDATE_METHOD, cfg.StrOpt(DSOpts.UPDATE_METHOD,
default=UpdateMethod.PULL), default=UpdateMethod.PULL),
] ]
@classmethod @classmethod
def setUpClass(cls): def setUpClass(cls):
cls.transformers = {} cls.transformers = {}
cls.conf = cfg.ConfigOpts() cls.conf = cfg.ConfigOpts()
cls.conf.register_opts(cls.OPTS, group=CEILOMETER_DATASOURCE) cls.conf.register_opts(cls.OPTS, group=CEILOMETER_DATASOURCE)
cls.transformers[CEILOMETER_DATASOURCE] = \ cls.transformers[CEILOMETER_DATASOURCE] = \
CeilometerTransformer(cls.transformers, cls.conf) CeilometerTransformer(cls.transformers, cls.conf)
def test_key_values_with_vitrage_alarm(self): def test_key_values_with_vitrage_alarm(self):
LOG.debug('Ceilometer transformer test: ' LOG.debug('Ceilometer transformer test: '
'get key values(vitrage_alarm)') 'get key values(vitrage_alarm)')
# Test setup # Test setup
entity = {CeilProps.VITRAGE_ID: 'test', entity = {CeilProps.VITRAGE_ID: 'test',
DSProps.ENTITY_TYPE: CEILOMETER_DATASOURCE, DSProps.ENTITY_TYPE: CEILOMETER_DATASOURCE,
CeilProps.ALARM_ID: '12345'} CeilProps.ALARM_ID: '12345'}
transformer = self.transformers[CEILOMETER_DATASOURCE] transformer = self.transformers[CEILOMETER_DATASOURCE]
# Test action # Test action
observed_key_fields = transformer._create_entity_key(entity) observed_key_fields = transformer._create_entity_key(entity)
# Test assertions # Test assertions
self.assertEqual('test', observed_key_fields) self.assertEqual('test', observed_key_fields)
def test_key_values(self): def test_key_values(self):
LOG.debug('Ceilometer transformer test: get key values(aodh alarm)') LOG.debug('Ceilometer transformer test: get key values(aodh alarm)')
# Test setup # Test setup
entity = {DSProps.ENTITY_TYPE: CEILOMETER_DATASOURCE, entity = {DSProps.ENTITY_TYPE: CEILOMETER_DATASOURCE,
CeilProps.ALARM_ID: '12345'} CeilProps.ALARM_ID: '12345'}
transformer = self.transformers[CEILOMETER_DATASOURCE] transformer = self.transformers[CEILOMETER_DATASOURCE]
# Test action # Test action
entity_key_fields = transformer._create_entity_key(entity).split(":") entity_key_fields = transformer._create_entity_key(entity).split(":")
# Test assertions # Test assertions
self.assertEqual(EntityCategory.ALARM, entity_key_fields[0]) self.assertEqual(EntityCategory.ALARM, entity_key_fields[0])
self.assertEqual(CEILOMETER_DATASOURCE, entity_key_fields[1]) self.assertEqual(CEILOMETER_DATASOURCE, entity_key_fields[1])
self.assertEqual(entity[CeilProps.ALARM_ID], entity_key_fields[2]) self.assertEqual(entity[CeilProps.ALARM_ID], entity_key_fields[2])
def test_snapshot_transform(self): def test_snapshot_transform(self):
LOG.debug('Ceilometer alarm transformer test: ' LOG.debug('Ceilometer alarm transformer test: '
'transform entity event snapshot') 'transform entity event snapshot')
# Test setup # Test setup
spec_list = mock_sync.simple_aodh_alarm_generators(alarm_num=3, spec_list = mock_sync.simple_aodh_alarm_generators(alarm_num=3,
snapshot_events=3) snapshot_events=3)
static_events = mock_sync.generate_random_events_list(spec_list) static_events = mock_sync.generate_random_events_list(spec_list)
for event in static_events: for event in static_events:
# convert neighbor from dict to vertex object # convert neighbor from dict to vertex object
neighbors = event[TransformerBase.QUERY_RESULT] neighbors = event[TransformerBase.QUERY_RESULT]
vertices = [] vertices = []
for neighbor in neighbors: for neighbor in neighbors:
neighbor_vertex = self._convert_dist_to_vertex(neighbor) neighbor_vertex = self._convert_dist_to_vertex(neighbor)
vertices.append(self.transformers[CEILOMETER_DATASOURCE]. vertices.append(self.transformers[CEILOMETER_DATASOURCE].
update_uuid_in_vertex(neighbor_vertex)) update_uuid_in_vertex(neighbor_vertex))
event[TransformerBase.QUERY_RESULT] = vertices event[TransformerBase.QUERY_RESULT] = vertices
# Test action # Test action
wrapper = self.transformers[CEILOMETER_DATASOURCE].transform(event) wrapper = self.transformers[CEILOMETER_DATASOURCE].transform(event)
# Test assertions # Test assertions
vertex = wrapper.vertex vertex = wrapper.vertex
self._validate_aodh_vertex_props(vertex, event) self._validate_aodh_vertex_props(vertex, event)
neighbors = wrapper.neighbors neighbors = wrapper.neighbors
self.assertEqual(1, len(neighbors)) self.assertEqual(1, len(neighbors))
self._validate_neighbors(neighbors, vertex.vertex_id, event) self._validate_neighbors(neighbors, vertex.vertex_id, event)
self._validate_action(event, wrapper) self._validate_action(event, wrapper)
class TestCeilometerAlarmPushTransformer(CeilometerTransformerBaseTest): class TestCeilometerAlarmPushTransformer(CeilometerTransformerBaseTest):
OPTS = [ OPTS = [
cfg.StrOpt(DSOpts.UPDATE_METHOD, cfg.StrOpt(DSOpts.UPDATE_METHOD,
default=UpdateMethod.PUSH), default=UpdateMethod.PUSH),
] ]
@classmethod @classmethod
def setUpClass(cls): def setUpClass(cls):
cls.transformers = {} cls.transformers = {}
cls.conf = cfg.ConfigOpts() cls.conf = cfg.ConfigOpts()
cls.conf.register_opts(cls.OPTS, group=CEILOMETER_DATASOURCE) cls.conf.register_opts(cls.OPTS, group=CEILOMETER_DATASOURCE)
cls.transformers[CEILOMETER_DATASOURCE] = \ cls.transformers[CEILOMETER_DATASOURCE] = \
CeilometerTransformer(cls.transformers, cls.conf) CeilometerTransformer(cls.transformers, cls.conf)
def test_update_transform(self): def test_update_transform(self):
LOG.debug('Ceilometer update alarm transformer test:' LOG.debug('Ceilometer update alarm transformer test:'
'transform entity event update') 'transform entity event update')
# Test setup # Test setup
spec_list = \ spec_list = \
mock_sync.simple_aodh_update_alarm_generators(alarm_num=5, mock_sync.simple_aodh_update_alarm_generators(alarm_num=5,
update_events=5) update_events=5)
static_events = mock_sync.generate_random_events_list(spec_list) static_events = mock_sync.generate_random_events_list(spec_list)
for event in static_events: for event in static_events:
# convert neighbor from dict to vertex object # convert neighbor from dict to vertex object
neighbors = event[TransformerBase.QUERY_RESULT] neighbors = event[TransformerBase.QUERY_RESULT]
vertices = [] vertices = []
for neighbor in neighbors: for neighbor in neighbors:
neighbor_vertex = self._convert_dist_to_vertex(neighbor) neighbor_vertex = self._convert_dist_to_vertex(neighbor)
vertices.append(self.transformers[CEILOMETER_DATASOURCE]. vertices.append(self.transformers[CEILOMETER_DATASOURCE].
update_uuid_in_vertex(neighbor_vertex)) update_uuid_in_vertex(neighbor_vertex))
event[TransformerBase.QUERY_RESULT] = vertices event[TransformerBase.QUERY_RESULT] = vertices
# Test action # Test action
wrapper = self.transformers[CEILOMETER_DATASOURCE].transform(event) wrapper = self.transformers[CEILOMETER_DATASOURCE].transform(event)
# Test assertions # Test assertions
vertex = wrapper.vertex vertex = wrapper.vertex
self._validate_aodh_vertex_props(vertex, event) self._validate_aodh_vertex_props(vertex, event)
neighbors = wrapper.neighbors neighbors = wrapper.neighbors
self.assertEqual(1, len(neighbors)) self.assertEqual(1, len(neighbors))
self._validate_neighbors(neighbors, vertex.vertex_id, event) self._validate_neighbors(neighbors, vertex.vertex_id, event)
self._validate_action(event, wrapper) self._validate_action(event, wrapper)