Merge "add aodh transformer unit test"
This commit is contained in:
commit
357fe8c793
@ -129,3 +129,32 @@ def simple_zone_generators(zone_num, snapshot_events=0, snap_vals=None):
|
||||
}
|
||||
]
|
||||
return tg.get_trace_generators(test_entity_spec_list)
|
||||
|
||||
|
||||
def simple_aodh_alarm_generators(alarm_num,
|
||||
snapshot_events=0, snap_vals=None):
|
||||
"""A simple function for returning aodh alarm generators.
|
||||
|
||||
Returns generators for a given number of alarms.
|
||||
|
||||
:param alarm_num: number of alarms
|
||||
:param snapshot_events: number of snapshot events
|
||||
:param snap_vals: values of snapshot
|
||||
:return: generators for alarm_num alarms as specified
|
||||
"""
|
||||
|
||||
mapping = [('alarm-{0}'.format(ind), 'resource-{0}'.format(ind))
|
||||
for ind in range(alarm_num)
|
||||
]
|
||||
|
||||
test_entity_spec_list = [
|
||||
{tg.DYNAMIC_INFO_FKEY: tg.TRANS_AODH_SNAPSHOT_D,
|
||||
tg.DYNAMIC_INFO_FPATH: tg.MOCK_TRANSFORMER_PATH,
|
||||
tg.STATIC_INFO_FKEY: None,
|
||||
tg.MAPPING_KEY: mapping,
|
||||
tg.EXTERNAL_INFO_KEY: snap_vals,
|
||||
tg.NAME_KEY: 'Aodh snapshot generator',
|
||||
tg.NUM_EVENTS: snapshot_events
|
||||
}
|
||||
]
|
||||
return tg.get_trace_generators(test_entity_spec_list)
|
||||
|
@ -30,6 +30,7 @@ from vitrage.tests.mocks.entity_model import BasicEntityModel as Bem
|
||||
import vitrage.tests.mocks.utils as utils
|
||||
|
||||
DYNAMIC_INFO_FKEY = 'filename'
|
||||
DYNAMIC_INFO_FPATH = 'filepath'
|
||||
STATIC_INFO_FKEY = 'static_filename'
|
||||
NAME_KEY = 'name'
|
||||
MAPPING_KEY = 'mapping'
|
||||
@ -41,6 +42,8 @@ GENERATOR = 'generator'
|
||||
|
||||
# specification files for input types
|
||||
# Mock driver specs
|
||||
MOCK_DRIVER_PATH = '%s/mock_configurations/driver' % \
|
||||
utils.get_resources_dir()
|
||||
DRIVER_HOST_SNAPSHOT_D = 'driver_host_snapshot_dynamic.json'
|
||||
DRIVER_INST_SNAPSHOT_D = 'driver_inst_snapshot_dynamic.json'
|
||||
DRIVER_INST_SNAPSHOT_S = 'driver_inst_snapshot_static.json'
|
||||
@ -58,6 +61,9 @@ DRIVER_ZONE_SNAPSHOT_D = 'driver_zone_snapshot_dynamic.json'
|
||||
|
||||
|
||||
# Mock transformer Specs (i.e., what the transformer outputs)
|
||||
MOCK_TRANSFORMER_PATH = '%s/mock_configurations/transformer' % \
|
||||
utils.get_resources_dir()
|
||||
TRANS_AODH_SNAPSHOT_D = 'transformer_aodh_snapshot_dynamic.json'
|
||||
TRANS_INST_SNAPSHOT_D = 'transformer_inst_snapshot_dynamic.json'
|
||||
TRANS_INST_SNAPSHOT_S = 'transformer_inst_snapshot_static.json'
|
||||
TRANS_HOST_SNAPSHOT_D = 'transformer_host_snapshot_dynamic.json'
|
||||
@ -113,11 +119,15 @@ class EventTraceGenerator(object):
|
||||
DRIVER_CONSISTENCY_UPDATE_D:
|
||||
_get_consistency_update_driver_values,
|
||||
|
||||
TRANS_AODH_SNAPSHOT_D: _get_trans_aodh_alarm_snapshot_values,
|
||||
TRANS_INST_SNAPSHOT_D: _get_trans_vm_snapshot_values,
|
||||
TRANS_HOST_SNAPSHOT_D: _get_trans_host_snapshot_values,
|
||||
TRANS_ZONE_SNAPSHOT_D: _get_trans_zone_snapshot_values}
|
||||
|
||||
dynam_specs = utils.load_specs(spec[DYNAMIC_INFO_FKEY])
|
||||
target_folder = spec[DYNAMIC_INFO_FPATH] \
|
||||
if spec.get(DYNAMIC_INFO_FPATH) else None
|
||||
dynam_specs = utils.load_specs(spec[DYNAMIC_INFO_FKEY],
|
||||
target_folder=target_folder)
|
||||
dynamic_spec_filename = spec[DYNAMIC_INFO_FKEY].split('/')[-1]
|
||||
static_specs = static_info_parsers[dynamic_spec_filename](spec)
|
||||
self.name = spec.get(NAME_KEY, 'generator')
|
||||
@ -569,6 +579,31 @@ def _get_trans_zone_snapshot_values(spec):
|
||||
return static_values
|
||||
|
||||
|
||||
def _get_trans_aodh_alarm_snapshot_values(spec):
|
||||
"""Generates the static transformer values for each vm.
|
||||
|
||||
:param spec: specification of event generation.
|
||||
:type spec: dict
|
||||
:return: list of static transformer values for each vm.
|
||||
:rtype: list
|
||||
"""
|
||||
|
||||
alarm_resources_mapping = spec[MAPPING_KEY]
|
||||
static_info_re = None
|
||||
if spec[STATIC_INFO_FKEY] is not None:
|
||||
static_info_re = utils.load_specs(spec[STATIC_INFO_FKEY])
|
||||
|
||||
static_values = []
|
||||
for alarm_id, resource_id in alarm_resources_mapping:
|
||||
mapping = {'alarm_id': alarm_id,
|
||||
'resource_id': resource_id,
|
||||
'graph_query_result': [{'id': resource_id}]}
|
||||
static_values.append(combine_data(
|
||||
static_info_re, mapping, spec.get(EXTERNAL_INFO_KEY, None)
|
||||
))
|
||||
return static_values
|
||||
|
||||
|
||||
def combine_data(static_info_re, mapping_info, external_info):
|
||||
if external_info:
|
||||
mapping_info = utils.merge_vals(mapping_info, external_info)
|
||||
|
@ -0,0 +1,37 @@
|
||||
{
|
||||
"alarm_id": "21127fbd-7633-494e-8e5c-fdf415cdec0c",
|
||||
"description": "test",
|
||||
"enabled": "True",
|
||||
"name": "test",
|
||||
"project_id": "f0895991f44044ccba8e62b201b70360",
|
||||
"repeat_actions": "False",
|
||||
"severity": "low",
|
||||
"state": "alarm",
|
||||
"timestamp": "2016-11-29T06:31:50.094836",
|
||||
"state_timestamp": "2016-11-11T01:58:36.054090",
|
||||
"type": "event",
|
||||
"event_type": "compute.instance.*",
|
||||
"resource_id": "3dcee183-ca42-4ccb-84af-9f0196b2e160",
|
||||
"vitrage_event_type": "alarm.creation",
|
||||
"vitrage_entity_type": "aodh",
|
||||
"vitrage_datasource_action": "snapshot",
|
||||
"vitrage_sample_date": "2016-11-29T06:31:50.094836",
|
||||
"graph_query_result": [
|
||||
{
|
||||
"category": "RESOURCE",
|
||||
"is_placeholder": false,
|
||||
"is_deleted": false,
|
||||
"name": "dwj",
|
||||
"update_timestamp": "2016-12-02 07:18:05.628479+00:00",
|
||||
"sample_timestamp": "2016-12-02 07:18:05.628479+00:00",
|
||||
"operational_state": "OK",
|
||||
"aggregated_state": "ACTIVE",
|
||||
"state": "ACTIVE",
|
||||
"graph_index": 3,
|
||||
"project_id": "f0895991f44044ccba8e62b201b70360",
|
||||
"type": "nova.instance",
|
||||
"id": "3dcee183-ca42-4ccb-84af-9f0196b2e160"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
15
vitrage/tests/unit/datasources/aodh/__init__.py
Normal file
15
vitrage/tests/unit/datasources/aodh/__init__.py
Normal file
@ -0,0 +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'
|
197
vitrage/tests/unit/datasources/aodh/test_aodh_transformer.py
Normal file
197
vitrage/tests/unit/datasources/aodh/test_aodh_transformer.py
Normal file
@ -0,0 +1,197 @@
|
||||
# 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 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 UpdateMethod
|
||||
from vitrage.common.constants import VertexProperties as VProps
|
||||
from vitrage.datasources.alarm_properties import AlarmProperties as AlarmProps
|
||||
from vitrage.datasources.aodh import AODH_DATASOURCE
|
||||
from vitrage.datasources.aodh.properties import AodhProperties as AodhProps
|
||||
from vitrage.datasources.aodh.properties import AodhState
|
||||
from vitrage.datasources.aodh.transformer import AodhTransformer
|
||||
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
|
||||
from vitrage.tests.mocks import mock_transformer as mock_sync
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class TestAodhAlarmTransformer(base.BaseTest):
|
||||
|
||||
OPTS = [
|
||||
cfg.StrOpt('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_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:
|
||||
vertices.append(self._convert_dist_to_vertex(neighbor))
|
||||
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)
|
||||
|
||||
def _validate_aodh_vertex_props(self, vertex, event):
|
||||
|
||||
self.assertEqual(EntityCategory.ALARM, vertex[VProps.CATEGORY])
|
||||
self.assertEqual(event[DSProps.ENTITY_TYPE], vertex[VProps.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.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.IS_PLACEHOLDER])
|
||||
self.assertFalse(vertex[VProps.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.CATEGORY])
|
||||
self.assertEqual(NOVA_INSTANCE_DATASOURCE,
|
||||
alarm_neighbor.vertex[VProps.TYPE])
|
||||
self.assertEqual(resource_id, alarm_neighbor.vertex[VProps.ID])
|
||||
self.assertFalse(alarm_neighbor.vertex[VProps.IS_PLACEHOLDER])
|
||||
self.assertFalse(alarm_neighbor.vertex[VProps.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.CATEGORY] + \
|
||||
TransformerBase.KEY_SEPARATOR + neighbor[VProps.TYPE] + \
|
||||
TransformerBase.KEY_SEPARATOR + neighbor[VProps.ID]
|
||||
return Vertex(vertex_id=ver_id, properties=neighbor)
|
Loading…
Reference in New Issue
Block a user