Merge "Vitrage ID and vertex id will be standard openstack uuid from now on - fixed"

This commit is contained in:
Jenkins 2017-04-20 11:42:43 +00:00 committed by Gerrit Code Review
commit ffb1e4b0f7
42 changed files with 528 additions and 172 deletions

View File

@ -22,10 +22,9 @@ from vitrage.common.constants import EdgeProperties as EProps
from vitrage.common.constants import EntityCategory
from vitrage.common.constants import VertexProperties as VProps
from vitrage.datasources.nova.instance import NOVA_INSTANCE_DATASOURCE
from vitrage.datasources import OPENSTACK_CLUSTER
from vitrage.datasources.transformer_base import build_key
from vitrage.datasources.transformer_base import CLUSTER_ID
from vitrage.datasources.transformer_base\
import create_cluster_placeholder_vertex
from vitrage.entity_graph.processor import processor_utils
LOG = log.getLogger(__name__)
@ -191,13 +190,19 @@ class TopologyApis(EntityGraphApisBase):
entities = []
if not root:
root = build_key([EntityCategory.RESOURCE,
OPENSTACK_CLUSTER,
CLUSTER_ID])
if root:
root_vertex = \
self.entity_graph.get_vertex(root)
else:
key_values_hash = processor_utils.get_defining_properties(
create_cluster_placeholder_vertex())
tmp_vertices = self.entity_graph.get_vertices_by_key(
key_values_hash)
if not tmp_vertices:
LOG.debug("No root vertex found")
return set(entities)
root_vertex = tmp_vertices[0]
root_vertex = \
self.entity_graph.get_vertex(root)
local_connected_component_subgraphs = \
ga.connected_component_subgraphs(subgraph)

View File

@ -69,7 +69,8 @@ def init(conf):
evaluator_q = queue.Queue()
e_graph = entity_graph.get_graph_driver(conf)(
'Entity Graph',
'%s:%s:%s' % (EntityCategory.RESOURCE, OPENSTACK_CLUSTER, CLUSTER_ID))
'%s:%s:%s' % (EntityCategory.RESOURCE, OPENSTACK_CLUSTER, CLUSTER_ID),
uuid=True)
scenario_repo = ScenarioRepository(conf)
evaluator = ScenarioEvaluator(conf, e_graph, scenario_repo, evaluator_q)

View File

@ -38,6 +38,7 @@ class VertexProperties(object):
RAWTEXT = 'rawtext'
RESOURCE_ID = 'resource_id'
RESOURCE = 'resource'
IS_REAL_VITRAGE_ID = 'is_real_vitrage_id'
class EdgeProperties(object):

View File

@ -56,6 +56,7 @@ class AodhTransformer(AlarmTransformerBase):
AodhProps.ENABLED: entity_event[AodhProps.ENABLED],
VProps.PROJECT_ID: entity_event.get(AodhProps.PROJECT_ID, None),
AodhProps.REPEAT_ACTIONS: entity_event[AodhProps.REPEAT_ACTIONS],
VProps.RESOURCE_ID: entity_event[AodhProps.RESOURCE_ID],
'alarm_type': entity_event[AodhProps.TYPE]
}

View File

@ -53,7 +53,8 @@ class CollectdTransformer(AlarmTransformerBase):
metadata = {
VProps.NAME: entity_event[CProps.MESSAGE],
VProps.SEVERITY: entity_event[CProps.SEVERITY],
VProps.RAWTEXT: self.generate_raw_text(entity_event)
VProps.RAWTEXT: self.generate_raw_text(entity_event),
VProps.RESOURCE_ID: entity_event[CProps.RESOURCE_NAME]
}
return graph_utils.create_vertex(

View File

@ -40,9 +40,16 @@ class ConsistencyTransformer(ResourceTransformerBase):
@staticmethod
def _create_vertex(entity_event):
metadata = {
VProps.IS_REAL_VITRAGE_ID:
entity_event.get(VProps.IS_REAL_VITRAGE_ID, False)
}
return graph_utils.create_vertex(
entity_event[VProps.VITRAGE_ID],
sample_timestamp=entity_event[DSProps.SAMPLE_DATE])
sample_timestamp=entity_event[DSProps.SAMPLE_DATE],
metadata=metadata
)
def _create_entity_key(self, entity_event):
return None

View File

@ -48,6 +48,7 @@ class NagiosTransformer(AlarmTransformerBase):
metadata = {
VProps.NAME: entity_event[NagiosProperties.SERVICE],
VProps.RESOURCE_ID: entity_event[NagiosProperties.RESOURCE_NAME],
VProps.SEVERITY: entity_event[NagiosProperties.STATUS],
VProps.INFO: entity_event[NagiosProperties.STATUS_INFO]
}

View File

@ -64,7 +64,8 @@ class ZabbixTransformer(AlarmTransformerBase):
VProps.NAME: entity_event[ZProps.DESCRIPTION],
VProps.SEVERITY: TriggerSeverity.str(
entity_event[ZProps.PRIORITY]),
VProps.RAWTEXT: entity_event[ZProps.RAWTEXT]
VProps.RAWTEXT: entity_event[ZProps.RAWTEXT],
VProps.RESOURCE_ID: entity_event[ZProps.RESOURCE_NAME]
}
return graph_utils.create_vertex(

View File

@ -157,7 +157,11 @@ class ConsistencyEnforcer(object):
DSProps.DATASOURCE_ACTION: DatasourceAction.UPDATE,
DSProps.SAMPLE_DATE: str(utcnow()),
DSProps.EVENT_TYPE: action,
VProps.VITRAGE_ID: vertex[VProps.VITRAGE_ID]
VProps.VITRAGE_ID: vertex[VProps.VITRAGE_ID],
VProps.ID: vertex.get(VProps.ID, None),
VProps.TYPE: vertex[VProps.TYPE],
VProps.CATEGORY: vertex[VProps.CATEGORY],
VProps.IS_REAL_VITRAGE_ID: True
}
self.evaluator_queue.put(event)

View File

@ -15,8 +15,12 @@
from oslo_log import log
from oslo_utils import uuidutils
from vitrage.common.constants import GraphAction
from vitrage.common.constants import VertexProperties as VProps
from vitrage.common.exception import VitrageError
from vitrage.datasources import OPENSTACK_CLUSTER
from vitrage.datasources.transformer_base import TransformerBase
from vitrage.entity_graph.mappings.datasource_info_mapper import \
DatasourceInfoMapper
@ -32,7 +36,8 @@ LOG = log.getLogger(__name__)
class Processor(processor.ProcessorBase):
def __init__(self, conf, initialization_status, e_graph=None):
def __init__(self, conf, initialization_status, e_graph=None,
uuid=False):
super(Processor, self).__init__()
self.conf = conf
self.transformer_manager = TransformerManager(self.conf)
@ -40,7 +45,7 @@ class Processor(processor.ProcessorBase):
self._initialize_events_actions()
self.initialization_status = initialization_status
self.entity_graph = e_graph if e_graph is not None\
else NXGraph("Entity Graph")
else NXGraph("Entity Graph", uuid=uuid)
self._notifier = GraphNotifier(conf)
def process_event(self, event):
@ -74,6 +79,7 @@ class Processor(processor.ProcessorBase):
"""
LOG.debug('Add entity to entity graph:\n%s', new_vertex)
self._find_and_fix_graph_vertex(new_vertex, neighbors)
self.entity_graph.add_vertex(new_vertex)
self._connect_neighbors(neighbors, [], GraphAction.CREATE_ENTITY)
@ -92,6 +98,8 @@ class Processor(processor.ProcessorBase):
LOG.debug('Update entity in entity graph:\n%s', updated_vertex)
if not updated_vertex.get(VProps.IS_REAL_VITRAGE_ID, False):
self._find_and_fix_graph_vertex(updated_vertex, neighbors)
graph_vertex = self.entity_graph.get_vertex(updated_vertex.vertex_id)
if (not graph_vertex) or \
@ -117,7 +125,8 @@ class Processor(processor.ProcessorBase):
"""
LOG.debug('Delete entity from entity graph:\n%s', deleted_vertex)
if not deleted_vertex.get(VProps.IS_REAL_VITRAGE_ID, False):
self._find_and_fix_graph_vertex(deleted_vertex, neighbors)
graph_vertex = self.entity_graph.get_vertex(deleted_vertex.vertex_id)
if graph_vertex and (not PUtils.is_deleted(graph_vertex)) and \
@ -141,21 +150,38 @@ class Processor(processor.ProcessorBase):
def update_relationship(self, entity_vertex, neighbors):
LOG.debug('Update relationship in entity graph:\n%s', neighbors)
if not entity_vertex:
for neighbor in neighbors:
self.entity_graph.update_edge(neighbor.edge)
return
self._find_and_fix_graph_vertex(entity_vertex, [])
self.entity_graph.update_vertex(entity_vertex)
for neighbor in neighbors:
# TODO(Alexey): maybe to check if the vertices exists
if entity_vertex is not None:
self.entity_graph.update_vertex(entity_vertex)
self._find_and_fix_relationship(entity_vertex, neighbor)
self.entity_graph.update_edge(neighbor.edge)
def delete_relationship(self, updated_vertex, neighbors):
LOG.debug('Delete relationship from entity graph:\n%s', neighbors)
if not updated_vertex:
for neighbor in neighbors:
graph_edge = self.entity_graph.get_edge(
neighbor.edge.source_id,
neighbor.edge.target_id,
neighbor.edge.label)
if graph_edge:
self.entity_graph.remove_edge(graph_edge)
return
self._find_and_fix_graph_vertex(updated_vertex, [])
self.entity_graph.update_vertex(updated_vertex)
for neighbor in neighbors:
self._find_and_fix_relationship(updated_vertex, neighbor)
graph_edge = self.entity_graph.get_edge(neighbor.edge.source_id,
neighbor.edge.target_id,
neighbor.edge.label)
if updated_vertex is not None:
self.entity_graph.update_vertex(updated_vertex)
if graph_edge:
PUtils.mark_deleted(self.entity_graph, graph_edge)
@ -168,7 +194,7 @@ class Processor(processor.ProcessorBase):
:type vertex: Vertex
:param neighbors: The neighbors of the deleted vertex
:type neighbors: List
:type neighbors: List - It's just a mock in this method
"""
LOG.debug('Remove deleted entity from entity graph:\n%s', vertex)
@ -308,7 +334,12 @@ class Processor(processor.ProcessorBase):
if action in [GraphAction.UPDATE_ENTITY,
GraphAction.DELETE_ENTITY,
GraphAction.CREATE_ENTITY]:
graph_vertex = self.entity_graph.get_vertex(vertex.vertex_id)
if vertex.get(VProps.IS_REAL_VITRAGE_ID, False):
graph_vertex = self.entity_graph.get_vertex(
vertex.vertex_id)
else:
graph_vertex = self._get_single_graph_vertex_by_props(
vertex)
elif action in [GraphAction.END_MESSAGE,
GraphAction.REMOVE_DELETED_ENTITY,
GraphAction.UPDATE_RELATIONSHIP,
@ -329,3 +360,97 @@ class Processor(processor.ProcessorBase):
return
result = self.entity_graph.get_vertices(attr)
event[TransformerBase.QUERY_RESULT] = result
def _find_and_fix_relationship(self, vertex, neighbor):
prev_neighbor_id = neighbor.vertex[VProps.VITRAGE_ID]
self._find_and_fix_graph_vertex(neighbor.vertex, [])
if neighbor.edge.source_id == prev_neighbor_id:
neighbor.edge.source_id = neighbor.vertex.vertex_id
neighbor.edge.target_id = vertex.vertex_id
else:
neighbor.edge.target_id = neighbor.vertex.vertex_id
neighbor.edge.source_id = vertex.vertex_id
def _find_and_fix_graph_vertex(self,
vertex,
neighbors=None,
include_deleted=False):
"""Search for vertex in graph, and update vertex id and vitrage ID
Search for vertex in graph, and update vertex id and vitrage ID
Both in the Vertex itself, and in it's neighbors and edges
:param new_vertex: The vertex to update
:type new_vertex: Vertex
:param neighbors: The neighbors of the vertex
:type neighbors: list
:param include_deleted: If True, Include deleted entities in the search
:type include_deleted: bool
"""
previous_vitrage_id = vertex[VProps.VITRAGE_ID]
graph_vertex = self._get_single_graph_vertex_by_props(
vertex, include_deleted)
if not graph_vertex or (PUtils.is_deleted(graph_vertex)
and not include_deleted):
vitrage_id = uuidutils.generate_uuid()
if vertex[VProps.TYPE] == OPENSTACK_CLUSTER:
self.entity_graph.root_id = vitrage_id
else:
vitrage_id = graph_vertex[VProps.VITRAGE_ID]
vertex[VProps.VITRAGE_ID] = vitrage_id
vertex.vertex_id = vitrage_id
if not neighbors:
return
for neighbor_vertex, edge in neighbors:
if not neighbor_vertex.get(VProps.IS_REAL_VITRAGE_ID, False):
self._find_and_fix_graph_vertex(neighbor_vertex)
if edge.target_id == previous_vitrage_id:
edge.target_id = vitrage_id
edge.source_id = neighbor_vertex.vertex_id
else:
edge.source_id = vitrage_id
edge.target_id = neighbor_vertex.vertex_id
def _get_single_graph_vertex_by_props(self, vertex, include_deleted=False):
"""Returns a single vertex by it's defining properties
Queries the graph DB for vertices according to the
vertice's "key" properties
In case multiple vertices return from the query,
an exception is issued
:param updated_vertex: The vertex with the defining properties
:type vertex: Vertex
:param include_deleted: Include deleted entities in the query
:type include_deleted: bool
"""
received_graph_vertices = self.entity_graph.get_vertices_by_key(
PUtils.get_defining_properties(vertex))
graph_vertices = []
if include_deleted:
for tmp_vertex in received_graph_vertices:
graph_vertices.append(tmp_vertex)
else:
for tmp_vertex in received_graph_vertices:
if not tmp_vertex.get(VProps.IS_DELETED, False):
graph_vertices.append(tmp_vertex)
if len(graph_vertices) > 1:
raise VitrageError(
'found too many vertices with same properties: %s ',
vertex)
graph_vertex = None if not graph_vertices \
else graph_vertices[0]
return graph_vertex

View File

@ -16,7 +16,12 @@ from dateutil import parser
from oslo_log import log
from pprint import pformat
import six
from vitrage.common.constants import EdgeProperties as EProps
from vitrage.common.constants import EntityCategory
from vitrage.common.constants import VertexProperties as VProps
from vitrage.graph import Edge
from vitrage.graph import Vertex
@ -83,6 +88,21 @@ def get_vertex_types(vertex):
return category, type_
def get_defining_properties(vertex):
defining_props = {VProps.TYPE: six.text_type(vertex[VProps.TYPE])}
if VProps.ID in vertex.properties:
defining_props[VProps.ID] = vertex[VProps.ID]
# In case the entity is an Alarm
if vertex[VProps.CATEGORY] == EntityCategory.ALARM:
if VProps.RESOURCE_ID in vertex.properties:
defining_props[VProps.RESOURCE_ID] = vertex[VProps.RESOURCE_ID]
defining_props[VProps.NAME] = vertex[VProps.NAME]
return hash(pformat(defining_props))
def can_update_vertex(graph_vertex, new_vertex):
return (not graph_vertex) or (not new_vertex[VProps.IS_PLACEHOLDER])

View File

@ -67,6 +67,9 @@ class EvaluatorEventTransformer(transformer_base.TransformerBase):
VProps.IS_PLACEHOLDER: False,
VProps.RESOURCE_ID: event.get(TFields.TARGET)
}
if VProps.IS_REAL_VITRAGE_ID in event:
properties[VProps.IS_REAL_VITRAGE_ID] = \
event.get(VProps.IS_REAL_VITRAGE_ID)
if VProps.VITRAGE_STATE in event:
properties[VProps.VITRAGE_STATE] = \
event.get(VProps.VITRAGE_STATE)
@ -129,7 +132,8 @@ class EvaluatorEventTransformer(transformer_base.TransformerBase):
neighbor_props = {
VProps.IS_PLACEHOLDER: True,
VProps.UPDATE_TIMESTAMP: timestamp,
VProps.SAMPLE_TIMESTAMP: event[VProps.SAMPLE_TIMESTAMP]
VProps.SAMPLE_TIMESTAMP: event[VProps.SAMPLE_TIMESTAMP],
VProps.IS_REAL_VITRAGE_ID: True
}
neighbor = Vertex(event[TFields.TARGET], neighbor_props)
return [Neighbor(neighbor, relation_edge)]

View File

@ -53,7 +53,8 @@ class SetState(base.Recipe):
update_vertex_params = {
VProps.VITRAGE_ID: target_id,
VProps.VITRAGE_STATE: vitrage_state
VProps.VITRAGE_STATE: vitrage_state,
VProps.IS_REAL_VITRAGE_ID: True
}
update_vertex_step = ActionStepWrapper(UPDATE_VERTEX,
update_vertex_params)

View File

@ -13,10 +13,11 @@
# under the License.
from collections import defaultdict
from collections import namedtuple
from hashlib import md5
from oslo_log import log
from oslo_utils import uuidutils
from vitrage.evaluator.base import Template
from vitrage.evaluator.template_data import RELATIONSHIP
from vitrage.evaluator.template_data import TemplateData
@ -85,7 +86,7 @@ class ScenarioRepository(object):
if not result.is_valid_config:
LOG.info('Unable to load template: %s' % result.comment)
template_uuid = md5(str(template_def).encode()).hexdigest()
template_uuid = uuidutils.generate_uuid()
self.templates[str(template_uuid)] = Template(template_uuid,
template_def,
current_time,

View File

@ -36,7 +36,8 @@ class Direction(object):
@six.add_metaclass(abc.ABCMeta)
class Graph(object):
def __init__(self, name, graph_type, vertices=None, edges=None):
def __init__(self, name, graph_type, vertices=None, edges=None,
uuid=False):
"""Create a Graph instance
:type name: str
@ -48,6 +49,7 @@ class Graph(object):
self.name = name
self.graph_type = graph_type
self.root_id = None
self.uuid = uuid
self.notifier = Notifier()
def subscribe(self, function):
@ -338,6 +340,20 @@ class Graph(object):
"""
pass
@abc.abstractmethod
def get_vertices_by_key(self,
key_values_hash):
"""Get vertices list according to their hash key
The hash key is derived from their properties :
See processor_utils - get_defining_properties
:param key_values_hash: hash key
:type key_values_hash str
"""
pass
@abc.abstractmethod
def neighbors(self, v_id, vertex_attr_filter=None,
edge_attr_filter=None, direction=Direction.BOTH):

View File

@ -11,6 +11,7 @@
# 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 collections import defaultdict
import copy
import json
@ -21,6 +22,7 @@ from networkx.readwrite import json_graph
from oslo_log import log as logging
from vitrage.common.constants import VertexProperties as VProps
from vitrage.entity_graph.processor import processor_utils as PUtils
from vitrage.graph.algo_driver.networkx_algorithm import NXAlgorithm
from vitrage.graph.driver.elements import Edge
from vitrage.graph.driver.elements import Vertex
@ -50,9 +52,12 @@ class NXGraph(Graph):
name='networkx_graph',
root_id=None,
vertices=None,
edges=None):
super(NXGraph, self).__init__(name, NXGraph.GRAPH_TYPE)
edges=None,
uuid=False):
super(NXGraph, self).__init__(name, NXGraph.GRAPH_TYPE, uuid=uuid)
self._g = nx.MultiDiGraph()
if uuid:
self.key_to_vertex_ids = defaultdict(list)
self.root_id = root_id
self.add_vertices(vertices)
self.add_edges(edges)
@ -81,6 +86,13 @@ class NXGraph(Graph):
def _add_vertex(self, v):
properties_copy = copy.copy(v.properties)
self._g.add_node(n=v.vertex_id, attr_dict=properties_copy)
if self.uuid:
self._update_keys_map(v)
def _update_keys_map(self, v):
key_hash = PUtils.get_defining_properties(v)
if v.vertex_id not in self.key_to_vertex_ids[key_hash]:
self.key_to_vertex_ids[key_hash].append(v.vertex_id)
@Notifier.update_notify
def add_edge(self, e):
@ -197,6 +209,16 @@ class NXGraph(Graph):
:type v: Vertex
"""
if self.uuid:
vertex = self.get_vertex(v.vertex_id)
if vertex:
key_hash = PUtils.get_defining_properties(vertex)
if key_hash in self.key_to_vertex_ids and\
v.vertex_id in self.key_to_vertex_ids[key_hash]:
self.key_to_vertex_ids[key_hash].remove(v.vertex_id)
if len(self.key_to_vertex_ids[key_hash]) == 0:
del self.key_to_vertex_ids[key_hash]
self._g.remove_node(n=v.vertex_id)
def remove_edge(self, e):
@ -207,7 +229,7 @@ class NXGraph(Graph):
self._g.remove_edge(u=e.source_id, v=e.target_id, key=e.label)
def get_vertices(self,
vertex_attr_filter=None,
vertex_attr_filter=None, # Dictionary of key value
query_dict=None):
def check_vertex(vertex_data):
return check_filter(vertex_data[1], vertex_attr_filter)
@ -226,6 +248,15 @@ class NXGraph(Graph):
else:
return []
def get_vertices_by_key(self, key_values_hash):
if key_values_hash in self.key_to_vertex_ids:
vertices = []
for vertex_id in self.key_to_vertex_ids[key_values_hash]:
vertices.append(self.get_vertex(vertex_id))
return vertices
return []
def neighbors(self, v_id, vertex_attr_filter=None, edge_attr_filter=None,
direction=Direction.BOTH):

View File

@ -23,7 +23,8 @@ from vitrage.common.constants import VertexProperties as VProps
from vitrage.datasources import NOVA_HOST_DATASOURCE
from vitrage.datasources import NOVA_INSTANCE_DATASOURCE
from vitrage.datasources import NOVA_ZONE_DATASOURCE
from vitrage.datasources import OPENSTACK_CLUSTER
from vitrage.datasources.transformer_base \
import create_cluster_placeholder_vertex
from vitrage.graph.driver.networkx_graph import NXGraph
import vitrage.graph.utils as graph_utils
from vitrage.tests.unit.entity_graph.base import TestEntityGraphUnitBase
@ -143,7 +144,7 @@ class TestApis(TestEntityGraphUnitBase):
graph_type='graph',
depth=10,
query=None,
root='RESOURCE:openstack.cluster:OpenStack Cluster',
root=None,
all_tenants=False)
graph_topology = json.loads(graph_topology)
@ -165,7 +166,7 @@ class TestApis(TestEntityGraphUnitBase):
graph_type='graph',
depth=10,
query=None,
root='RESOURCE:openstack.cluster:OpenStack Cluster',
root=None,
all_tenants=False)
graph_topology = json.loads(graph_topology)
@ -187,7 +188,7 @@ class TestApis(TestEntityGraphUnitBase):
graph_type='graph',
depth=10,
query=None,
root='RESOURCE:openstack.cluster:OpenStack Cluster',
root=None,
all_tenants=True)
graph_topology = json.loads(graph_topology)
@ -389,12 +390,10 @@ class TestApis(TestEntityGraphUnitBase):
self.assertEqual(resource[VProps.PROJECT_ID], project_id)
def _create_graph(self):
graph = NXGraph('Multi tenancy graph')
graph = NXGraph('Multi tenancy graph', uuid=True)
# create vertices
cluster_vertex = self._create_resource(
'RESOURCE:openstack.cluster:OpenStack Cluster',
OPENSTACK_CLUSTER)
cluster_vertex = create_cluster_placeholder_vertex()
zone_vertex = self._create_resource('zone_1',
NOVA_ZONE_DATASOURCE)
host_vertex = self._create_resource('host_1',
@ -411,18 +410,38 @@ class TestApis(TestEntityGraphUnitBase):
instance_4_vertex = self._create_resource('instance_4',
NOVA_INSTANCE_DATASOURCE,
project_id='project_2')
alarm_on_host_vertex = self._create_alarm('alarm_on_host',
'alarm_on_host')
alarm_on_instance_1_vertex = self._create_alarm('alarm_on_instance_1',
'deduced_alarm',
project_id='project_1')
alarm_on_instance_2_vertex = self._create_alarm('alarm_on_instance_2',
'deduced_alarm')
alarm_on_instance_3_vertex = self._create_alarm('alarm_on_instance_3',
'deduced_alarm',
project_id='project_2')
alarm_on_instance_4_vertex = self._create_alarm('alarm_on_instance_4',
'deduced_alarm')
alarm_on_host_vertex = self._create_alarm(
'alarm_on_host',
'alarm_on_host',
metadata={'type': 'nova.host',
'name': 'host_1',
'resource_id': 'host_1'})
alarm_on_instance_1_vertex = self._create_alarm(
'alarm_on_instance_1',
'deduced_alarm',
project_id='project_1',
metadata={'type': 'nova.instance',
'name': 'instance_1',
'resource_id': 'sdg7849ythksjdg'})
alarm_on_instance_2_vertex = self._create_alarm(
'alarm_on_instance_2',
'deduced_alarm',
metadata={'type': 'nova.instance',
'name': 'instance_2',
'resource_id': 'nbfhsdugf'})
alarm_on_instance_3_vertex = self._create_alarm(
'alarm_on_instance_3',
'deduced_alarm',
project_id='project_2',
metadata={'type': 'nova.instance',
'name': 'instance_3',
'resource_id': 'nbffhsdasdugf'})
alarm_on_instance_4_vertex = self._create_alarm(
'alarm_on_instance_4',
'deduced_alarm',
metadata={'type': 'nova.instance',
'name': 'instance_4',
'resource_id': 'ngsuy76hgd87f'})
# create links
edges = list()

View File

@ -22,11 +22,13 @@ from vitrage.tests.unit.entity_graph.base import TestEntityGraphUnitBase
class TestFunctionalBase(TestEntityGraphUnitBase):
def _create_processor_with_graph(self, conf, processor=None):
def _create_processor_with_graph(self, conf, processor=None,
uuid=False):
events = self._create_mock_events()
if not processor:
processor = proc.Processor(conf, InitializationStatus())
processor = proc.Processor(conf, InitializationStatus(),
uuid=uuid)
for event in events:
processor.process_event(event)

View File

@ -53,7 +53,7 @@ class TestAodhAlarms(TestDataSourcesBase):
def test_aodh_alarms_validity(self):
# Setup
processor = self._create_processor_with_graph(self.conf)
processor = self._create_processor_with_graph(self.conf, uuid=True)
self.assertEqual(self._num_total_expected_vertices(),
len(processor.entity_graph))

View File

@ -52,7 +52,7 @@ class TestCinderVolume(TestDataSourcesBase):
def test_cinder_volume_validity(self):
# Setup
processor = self._create_processor_with_graph(self.conf)
processor = self._create_processor_with_graph(self.conf, uuid=True)
self.assertEqual(self._num_total_expected_vertices(),
len(processor.entity_graph))

View File

@ -52,7 +52,7 @@ class TestHeatStack(TestDataSourcesBase):
def test_heat_stack_validity(self):
# Setup
processor = self._create_processor_with_graph(self.conf)
processor = self._create_processor_with_graph(self.conf, uuid=True)
self.assertEqual(self._num_total_expected_vertices(),
len(processor.entity_graph))

View File

@ -51,7 +51,7 @@ class TestNagios(TestDataSourcesBase):
def test_nagios_validity(self):
# Setup
processor = self._create_processor_with_graph(self.conf)
processor = self._create_processor_with_graph(self.conf, uuid=True)
self.assertEqual(self._num_total_expected_vertices(),
len(processor.entity_graph))

View File

@ -30,7 +30,7 @@ class TestNovaDatasources(TestDataSourcesBase):
cls.load_datasources(cls.conf)
def test_nova_datasources(self):
processor = self._create_processor_with_graph(self.conf)
processor = self._create_processor_with_graph(self.conf, uuid=True)
self.assertEqual(self._num_total_expected_vertices(),
processor.entity_graph.num_vertices())

View File

@ -55,7 +55,7 @@ class TestStaticPhysical(TestDataSourcesBase):
def test_static_physical_validity(self):
# Setup
processor = self._create_processor_with_graph(self.conf)
processor = self._create_processor_with_graph(self.conf, uuid=True)
transformers = processor.transformer_manager.transformers
transformers[SWITCH] = transformers[STATIC_PHYSICAL_DATASOURCE]
self.assertEqual(self._num_total_expected_vertices(),

View File

@ -74,7 +74,8 @@ class TestConsistencyFunctional(TestFunctionalBase):
cls.conf.register_opts(cls.DATASOURCES_OPTS, group='datasources')
cls.load_datasources(cls.conf)
cls.processor = Processor(cls.conf, cls.initialization_status)
cls.processor = Processor(cls.conf, cls.initialization_status,
uuid=True)
cls.event_queue = queue.Queue()
scenario_repo = ScenarioRepository(cls.conf)
cls.evaluator = ScenarioEvaluator(cls.conf,
@ -93,7 +94,8 @@ class TestConsistencyFunctional(TestFunctionalBase):
# Setup
num_of_host_alarms = self.NUM_HOSTS - 2
num_instances_per_host = 4
self._create_processor_with_graph(self.conf, processor=self.processor)
self._create_processor_with_graph(self.conf, processor=self.processor,
uuid=True)
self._add_alarms()
self._set_end_messages()
self.assertEqual(self._num_total_expected_vertices() +
@ -167,7 +169,8 @@ class TestConsistencyFunctional(TestFunctionalBase):
self.assertEqual(6, len(deleted_instance_vertices))
def _periodic_process_setup_stage(self, consistency_interval):
self._create_processor_with_graph(self.conf, processor=self.processor)
self._create_processor_with_graph(self.conf, processor=self.processor,
uuid=True)
current_time = utcnow()
# set all vertices to be have timestamp that consistency won't get

View File

@ -34,7 +34,7 @@ class TestProcessorFunctional(TestFunctionalBase):
cls.load_datasources(cls.conf)
def test_create_entity_graph(self):
processor = self._create_processor_with_graph(self.conf)
processor = self._create_processor_with_graph(self.conf, uuid=True)
self.assertEqual(self._num_total_expected_vertices(),
processor.entity_graph.num_vertices())

View File

@ -17,7 +17,6 @@ from oslo_config import cfg
from vitrage.common.constants import DatasourceAction as DSAction
from vitrage.common.constants import GraphAction
from vitrage.common.constants import VertexProperties as VProps
from vitrage.datasources.nova.instance.transformer import InstanceTransformer
from vitrage.entity_graph.initialization_status import InitializationStatus
from vitrage.entity_graph.mappings.operational_resource_state import \
OperationalResourceState
@ -38,7 +37,8 @@ class TestDatasourceInfoMapperFunctional(TestFunctionalBase):
def test_state_on_update(self):
# setup
processor = proc.Processor(self.conf, InitializationStatus())
processor = proc.Processor(self.conf, InitializationStatus(),
uuid=True)
event = self._create_event(spec_type='INSTANCE_SPEC',
datasource_action=DSAction.INIT_SNAPSHOT)
@ -46,9 +46,9 @@ class TestDatasourceInfoMapperFunctional(TestFunctionalBase):
processor.process_event(event)
# test assertions
instance_transformer = InstanceTransformer({}, self.conf)
vitrage_id = instance_transformer._create_entity_key(event)
vertex = processor.entity_graph.get_vertex(vitrage_id)
entity = processor.transformer_manager.transform(event)
processor._find_and_fix_graph_vertex(entity.vertex, [])
vertex = processor.entity_graph.get_vertex(entity.vertex.vertex_id)
self.assertEqual('ACTIVE', vertex[VProps.AGGREGATED_STATE])
self.assertEqual(OperationalResourceState.OK,
vertex[VProps.OPERATIONAL_STATE])

View File

@ -49,7 +49,7 @@ class TestActionExecutor(TestFunctionalBase):
def test_execute_update_vertex(self):
# Test Setup
processor = self._create_processor_with_graph(self.conf)
processor = self._create_processor_with_graph(self.conf, uuid=True)
vertex_attrs = {VProps.TYPE: NOVA_HOST_DATASOURCE}
host_vertices = processor.entity_graph.get_vertices(
@ -97,7 +97,7 @@ class TestActionExecutor(TestFunctionalBase):
def test_execute_add_edge(self):
# Test Setup
processor = self._create_processor_with_graph(self.conf)
processor = self._create_processor_with_graph(self.conf, uuid=True)
vertex_attrs = {VProps.TYPE: NOVA_HOST_DATASOURCE}
host_vertices = processor.entity_graph.get_vertices(
@ -147,7 +147,7 @@ class TestActionExecutor(TestFunctionalBase):
def test_execute_add_vertex(self):
# Test Setup
processor = self._create_processor_with_graph(self.conf)
processor = self._create_processor_with_graph(self.conf, uuid=True)
vertex_attrs = {VProps.TYPE: NOVA_HOST_DATASOURCE}
host_vertices = processor.entity_graph.get_vertices(
@ -159,7 +159,9 @@ class TestActionExecutor(TestFunctionalBase):
props = {
TFields.ALARM_NAME: 'VM_CPU_SUBOPTIMAL_PERFORMANCE',
TFields.SEVERITY: 'CRITICAL',
VProps.STATE: AlarmProps.ACTIVE_STATE
VProps.STATE: AlarmProps.ACTIVE_STATE,
VProps.RESOURCE_ID: host[VProps.ID],
VProps.VITRAGE_ID: 'DUMMY_ID'
}
# Raise alarm action adds new vertex with type vitrage to the graph
@ -171,8 +173,6 @@ class TestActionExecutor(TestFunctionalBase):
event_queue = queue.Queue()
action_executor = ActionExecutor(event_queue)
expected_alarm_id = 'ALARM:vitrage:%s:%s' % (props[TFields.ALARM_NAME],
host.vertex_id)
# Test Action
action_executor.execute(action_spec, ActionMode.DO)
processor.process_event(event_queue.get())
@ -184,12 +184,7 @@ class TestActionExecutor(TestFunctionalBase):
self.assertEqual(len(before_alarms) + 1, len(after_alarms))
self.assert_is_not_empty(after_alarms)
alarms = [alarm for alarm in after_alarms
if alarm.vertex_id == expected_alarm_id]
# Expected exactly one alarm with expected id
self.assertEqual(1, len(alarms))
alarm = alarms[0]
alarm = after_alarms[0]
self.assertEqual(alarm.properties[VProps.CATEGORY],
EntityCategory.ALARM)
@ -205,7 +200,7 @@ class TestActionExecutor(TestFunctionalBase):
def test_execute_add_and_remove_vertex(self):
# Test Setup
processor = self._create_processor_with_graph(self.conf)
processor = self._create_processor_with_graph(self.conf, uuid=True)
vertex_attrs = {VProps.TYPE: NOVA_HOST_DATASOURCE}
host_vertices = processor.entity_graph.get_vertices(
@ -217,7 +212,8 @@ class TestActionExecutor(TestFunctionalBase):
props = {
TFields.ALARM_NAME: 'VM_CPU_SUBOPTIMAL_PERFORMANCE',
TFields.SEVERITY: 'CRITICAL',
VProps.STATE: AlarmProps.ACTIVE_STATE
VProps.STATE: AlarmProps.ACTIVE_STATE,
VProps.RESOURCE_ID: host[VProps.ID]
}
action_spec = ActionSpecs(ActionType.RAISE_ALARM, targets, props)
@ -271,4 +267,6 @@ class TestActionExecutor(TestFunctionalBase):
'type': 'add_vertex',
'vitrage_entity_type': 'vitrage',
'severity': 'CRITICAL',
'vitrage_id': 'mock_vitrage_id',
'category': 'RESOURCE',
'sample_timestamp': '2016-03-17 11:33:32.443002+00:00'}

View File

@ -40,6 +40,7 @@ from vitrage.utils.datetime import utcnow
_TARGET_HOST = 'host-2'
_TARGET_ZONE = 'zone-1'
_NAGIOS_TEST_INFO = {'resource_name': _TARGET_HOST,
'resource_id': _TARGET_HOST,
DSProps.DATASOURCE_ACTION: DatasourceAction.SNAPSHOT}
@ -70,6 +71,7 @@ class TestScenarioEvaluator(TestFunctionalBase):
event_queue, processor, evaluator = self._init_system()
host_v = self._get_entity_from_graph(NOVA_HOST_DATASOURCE,
_TARGET_HOST,
_TARGET_HOST,
processor.entity_graph)
self.assertEqual('AVAILABLE', host_v[VProps.AGGREGATED_STATE],
@ -98,6 +100,7 @@ class TestScenarioEvaluator(TestFunctionalBase):
event_queue, processor, evaluator = self._init_system()
host_v = self._get_entity_from_graph(NOVA_HOST_DATASOURCE,
_TARGET_HOST,
_TARGET_HOST,
processor.entity_graph)
self.assertEqual('AVAILABLE', host_v[VProps.AGGREGATED_STATE],
@ -144,6 +147,7 @@ class TestScenarioEvaluator(TestFunctionalBase):
event_queue, processor, evaluator = self._init_system()
host_v = self._get_entity_from_graph(NOVA_HOST_DATASOURCE,
_TARGET_HOST,
_TARGET_HOST,
processor.entity_graph)
self.assertEqual('AVAILABLE', host_v[VProps.AGGREGATED_STATE],
@ -183,6 +187,7 @@ class TestScenarioEvaluator(TestFunctionalBase):
event_queue, processor, evaluator = self._init_system()
host_v = self._get_entity_from_graph(NOVA_HOST_DATASOURCE,
_TARGET_HOST,
_TARGET_HOST,
processor.entity_graph)
self.assertEqual('AVAILABLE', host_v[VProps.AGGREGATED_STATE],
@ -478,21 +483,31 @@ class TestScenarioEvaluator(TestFunctionalBase):
# test asserts
self.assertEqual(num_orig_vertices + num_added_vertices +
num_deduced_vertices + num_nagios_alarm_vertices,
num_deduced_vertices + num_nagios_alarm_vertices +
# This is due to keeping alarm history :
# new alarm doesn't update same deleted alarm.
# Instead, it keeps the old one and creates a new one
1,
entity_graph.num_vertices())
self.assertEqual(num_orig_edges + num_added_edges + num_deduced_edges +
num_nagios_alarm_edges, entity_graph.num_edges())
num_nagios_alarm_edges + 1, entity_graph.num_edges())
query = {VProps.CATEGORY: EntityCategory.ALARM, VProps.TYPE: 'vitrage'}
port_neighbors = entity_graph.neighbors(port_vertex.vertex_id,
vertex_attr_filter=query)
self.assertEqual(1, len(port_neighbors))
self.assertEqual(port_neighbors[0][VProps.CATEGORY],
EntityCategory.ALARM)
self.assertEqual(port_neighbors[0][VProps.TYPE], 'vitrage')
self.assertEqual(port_neighbors[0][VProps.NAME],
'simple_port_deduced_alarm')
self.assertEqual(port_neighbors[0][VProps.IS_DELETED], False)
query = {VProps.CATEGORY: EntityCategory.ALARM, VProps.TYPE: 'vitrage',
VProps.IS_DELETED: True}
is_deleted = True
for counter in range(0, 1):
port_neighbors = entity_graph.neighbors(port_vertex.vertex_id,
vertex_attr_filter=query)
self.assertEqual(1, len(port_neighbors))
self.assertEqual(port_neighbors[0][VProps.CATEGORY],
EntityCategory.ALARM)
self.assertEqual(port_neighbors[0][VProps.TYPE], 'vitrage')
self.assertEqual(port_neighbors[0][VProps.NAME],
'simple_port_deduced_alarm')
self.assertEqual(port_neighbors[0][VProps.IS_DELETED], is_deleted)
query = {VProps.CATEGORY: EntityCategory.ALARM,
VProps.TYPE: 'vitrage', VProps.IS_DELETED: False}
is_deleted = False
query = {VProps.CATEGORY: EntityCategory.ALARM, VProps.TYPE: 'nagios'}
port_neighbors = entity_graph.neighbors(port_vertex.vertex_id,
@ -517,21 +532,35 @@ class TestScenarioEvaluator(TestFunctionalBase):
# test asserts
self.assertEqual(num_orig_vertices + num_added_vertices +
num_deduced_vertices + num_nagios_alarm_vertices,
num_deduced_vertices + num_nagios_alarm_vertices +
# This is due to keeping alarm history :
# new alarm doesn't update same deleted alarm.
# Instead, it keeps the old one and creates a new one
1,
entity_graph.num_vertices())
self.assertEqual(num_orig_edges + num_added_edges + num_deduced_edges +
num_nagios_alarm_edges, entity_graph.num_edges())
num_nagios_alarm_edges + 1, entity_graph.num_edges())
query = {VProps.CATEGORY: EntityCategory.ALARM, VProps.TYPE: 'vitrage'}
port_neighbors = entity_graph.neighbors(port_vertex.vertex_id,
vertex_attr_filter=query)
self.assertEqual(1, len(port_neighbors))
self.assertEqual(port_neighbors[0][VProps.CATEGORY],
EntityCategory.ALARM)
self.assertEqual(port_neighbors[0][VProps.TYPE], 'vitrage')
self.assertEqual(port_neighbors[0][VProps.NAME],
'simple_port_deduced_alarm')
self.assertEqual(port_neighbors[0][VProps.IS_DELETED], True)
query = {VProps.CATEGORY: EntityCategory.ALARM, VProps.TYPE: 'vitrage',
VProps.IS_DELETED: True}
is_deleted = True
for counter in range(0, 1):
port_neighbors = entity_graph.neighbors(port_vertex.vertex_id,
vertex_attr_filter=query)
self.assertEqual(2, len(port_neighbors))
for in_counter in range(0, 1):
self.assertEqual(port_neighbors[in_counter][VProps.CATEGORY],
EntityCategory.ALARM)
self.assertEqual(port_neighbors[in_counter][VProps.TYPE],
'vitrage')
self.assertEqual(port_neighbors[in_counter][VProps.NAME],
'simple_port_deduced_alarm')
self.assertEqual(
port_neighbors[in_counter][VProps.IS_DELETED], is_deleted)
query = {VProps.CATEGORY: EntityCategory.ALARM,
VProps.TYPE: 'vitrage', VProps.IS_DELETED: False}
is_deleted = False
query = {VProps.CATEGORY: EntityCategory.ALARM, VProps.TYPE: 'nagios'}
port_neighbors = entity_graph.neighbors(port_vertex.vertex_id,
@ -551,21 +580,37 @@ class TestScenarioEvaluator(TestFunctionalBase):
# test asserts
self.assertEqual(num_orig_vertices + num_added_vertices +
num_deduced_vertices + num_nagios_alarm_vertices,
num_deduced_vertices + num_nagios_alarm_vertices +
# This is due to keeping alarm history :
# new alarm doesn't update same deleted alarm.
# Instead, it keeps the old one and creates a new one
# Since this is the second test, there are already two
# alarms of this type
2,
entity_graph.num_vertices())
self.assertEqual(num_orig_edges + num_added_edges + num_deduced_edges +
num_nagios_alarm_edges, entity_graph.num_edges())
num_nagios_alarm_edges + 2, entity_graph.num_edges())
query = {VProps.CATEGORY: EntityCategory.ALARM, VProps.TYPE: 'vitrage'}
port_neighbors = entity_graph.neighbors(port_vertex.vertex_id,
vertex_attr_filter=query)
self.assertEqual(1, len(port_neighbors))
self.assertEqual(port_neighbors[0][VProps.CATEGORY],
EntityCategory.ALARM)
self.assertEqual(port_neighbors[0][VProps.TYPE], 'vitrage')
self.assertEqual(port_neighbors[0][VProps.NAME],
'simple_port_deduced_alarm')
self.assertEqual(port_neighbors[0][VProps.IS_DELETED], False)
query = {VProps.CATEGORY: EntityCategory.ALARM,
VProps.TYPE: 'vitrage', VProps.IS_DELETED: True}
is_deleted = True
for counter in range(0, 1):
port_neighbors = entity_graph.neighbors(port_vertex.vertex_id,
vertex_attr_filter=query)
self.assertEqual(2, len(port_neighbors))
for in_counter in range(0, 1):
self.assertEqual(port_neighbors[in_counter][VProps.CATEGORY],
EntityCategory.ALARM)
self.assertEqual(port_neighbors[in_counter][VProps.TYPE],
'vitrage')
self.assertEqual(port_neighbors[in_counter][VProps.NAME],
'simple_port_deduced_alarm')
self.assertEqual(
port_neighbors[in_counter][VProps.IS_DELETED], is_deleted)
query = {VProps.CATEGORY: EntityCategory.ALARM,
VProps.TYPE: 'vitrage', VProps.IS_DELETED: False}
is_deleted = False
query = {VProps.CATEGORY: EntityCategory.ALARM, VProps.TYPE: 'nagios'}
port_neighbors = entity_graph.neighbors(port_vertex.vertex_id,
@ -710,10 +755,14 @@ class TestScenarioEvaluator(TestFunctionalBase):
processor.process_event(event_queue.get())
self.assertEqual(num_orig_vertices + num_added_vertices +
num_deduced_vertices + num_network_alarm_vertices,
num_deduced_vertices + num_network_alarm_vertices +
# This is due to keeping alarm history :
# new alarm doesn't update same deleted alarm.
# Instead, it keeps the old one and creates a new one
1,
entity_graph.num_vertices())
self.assertEqual(num_orig_edges + num_added_edges + num_deduced_edges +
num_network_alarm_edges, entity_graph.num_edges())
num_network_alarm_edges + 1, entity_graph.num_edges())
query = {VProps.CATEGORY: EntityCategory.ALARM}
network_neighbors = entity_graph.neighbors(network_vertex.vertex_id,
@ -725,15 +774,25 @@ class TestScenarioEvaluator(TestFunctionalBase):
self.assertEqual(network_neighbors[0][VProps.NAME], 'NETWORK_PROBLEM')
self.assertEqual(network_neighbors[0][VProps.IS_DELETED], True)
zone_neighbors = entity_graph.neighbors(zone_vertex.vertex_id,
vertex_attr_filter=query)
self.assertEqual(1, len(zone_neighbors))
self.assertEqual(zone_neighbors[0][VProps.CATEGORY],
EntityCategory.ALARM)
self.assertEqual(zone_neighbors[0][VProps.TYPE], 'vitrage')
self.assertEqual(zone_neighbors[0][VProps.NAME],
'complex_zone_deduced_alarm')
self.assertEqual(zone_neighbors[0][VProps.IS_DELETED], False)
query = {VProps.CATEGORY: EntityCategory.ALARM,
VProps.IS_DELETED: True}
is_deleted = True
# Alarm History is saved. We are testing the deleted alarm and
# then we are testing the live alarm
for counter in range(0, 1):
zone_neighbors = entity_graph.neighbors(zone_vertex.vertex_id,
vertex_attr_filter=query)
self.assertEqual(1, len(zone_neighbors))
self.assertEqual(zone_neighbors[0][VProps.CATEGORY],
EntityCategory.ALARM)
self.assertEqual(zone_neighbors[0][VProps.TYPE], 'vitrage')
self.assertEqual(zone_neighbors[0][VProps.NAME],
'complex_zone_deduced_alarm')
self.assertEqual(zone_neighbors[0][VProps.IS_DELETED], is_deleted)
query = {VProps.CATEGORY: EntityCategory.ALARM,
VProps.IS_DELETED: False}
is_deleted = False
def get_host_after_event(self, event_queue, nagios_event,
processor, target_host):
@ -741,12 +800,13 @@ class TestScenarioEvaluator(TestFunctionalBase):
while not event_queue.empty():
processor.process_event(event_queue.get())
host_v = self._get_entity_from_graph(NOVA_HOST_DATASOURCE,
target_host,
target_host,
processor.entity_graph)
return host_v
def _init_system(self):
processor = self._create_processor_with_graph(self.conf)
processor = self._create_processor_with_graph(self.conf, uuid=True)
event_queue = queue.Queue()
evaluator = ScenarioEvaluator(self.conf, processor.entity_graph,
self.scenario_repository, event_queue,
@ -754,8 +814,11 @@ class TestScenarioEvaluator(TestFunctionalBase):
return event_queue, processor, evaluator
@staticmethod
def _get_entity_from_graph(entity_type, entity_name, entity_graph):
def _get_entity_from_graph(entity_type, entity_name,
entity_id,
entity_graph):
vertex_attrs = {VProps.TYPE: entity_type,
VProps.ID: entity_id,
VProps.NAME: entity_name}
vertices = entity_graph.get_vertices(vertex_attr_filter=vertex_attrs)
# assert len(vertices) == 1, "incorrect number of vertices"

View File

@ -9,6 +9,9 @@
"service": "compute",
"vitrage_entity_type": "nova.host",
"zone": "zone0",
"id": "compute-0-0.local",
"category": "RESOURCE",
"vitrage_id": "compute-0-0.local",
"vitrage_datasource_action": "init_snapshot",
"vitrage_sample_date": "2015-12-01T12:46:41Z"
}

View File

@ -72,6 +72,7 @@
"key_name": null,
"OS-EXT-SRV-ATTR:hypervisor_hostname": "nyakar-devstack",
"name": "vm2",
"category": "RESOURCE",
"created": "2015-11-25T14:18:07Z",
"tenant_id": "0683517e1e354d2ba25cba6937f44e79",
"os-extended-volumes:volumes_attached": [],

View File

@ -12,6 +12,9 @@
"vitrage_entity_type": "nova.zone",
"vitrage_datasource_action": "snapshot",
"zoneName": "zone0",
"id": "zone0",
"vitrage_id": "zone0",
"category": "RESOURCE",
"zoneState": {
"available": "True"
}

View File

@ -208,8 +208,6 @@ class NovaZoneTransformerTest(base.BaseTest):
self.assertEqual(cluster_neighbor.vertex[VProps.VITRAGE_ID],
cluster_neighbor.vertex.vertex_id)
self.assertEqual('RESOURCE:openstack.cluster:OpenStack Cluster',
cluster_neighbor.vertex[VProps.VITRAGE_ID])
self.assertEqual(False,
cluster_neighbor.vertex[VProps.IS_DELETED])
self.assertEqual(EntityCategory.RESOURCE,

View File

@ -114,7 +114,8 @@ class TestEntityGraphUnitBase(base.BaseTest):
# add instance entity with host
if processor is None:
processor = proc.Processor(self.conf, InitializationStatus())
processor = proc.Processor(self.conf, InitializationStatus(),
uuid=True)
vertex, neighbors, event_type = processor.transformer_manager\
.transform(event)
@ -146,7 +147,7 @@ class TestEntityGraphUnitBase(base.BaseTest):
return events_list[0]
@staticmethod
def _create_alarm(vitrage_id, alarm_type, project_id=None):
def _create_alarm(vitrage_id, alarm_type, project_id=None, metadata=None):
return graph_utils.create_vertex(
vitrage_id,
entity_id=vitrage_id,
@ -156,7 +157,8 @@ class TestEntityGraphUnitBase(base.BaseTest):
is_deleted=False,
sample_timestamp=None,
is_placeholder=False,
project_id=project_id
project_id=project_id,
metadata=metadata
)
@staticmethod

View File

@ -51,7 +51,8 @@ class TestProcessor(TestEntityGraphUnitBase):
def test_process_event(self):
# check create instance event
processor = proc.Processor(self.conf, InitializationStatus())
processor = proc.Processor(self.conf, InitializationStatus(),
uuid=True)
event = self._create_event(spec_type=self.INSTANCE_SPEC,
datasource_action=DSAction.INIT_SNAPSHOT)
processor.process_event(event)
@ -145,10 +146,17 @@ class TestProcessor(TestEntityGraphUnitBase):
new_edge = graph_utils.create_edge(vertex1.vertex_id,
vertex2.vertex_id,
'backup')
new_neighbors = [Neighbor(None, new_edge)]
mock_neighbor = graph_utils.create_vertex(
"asdjashdkahsdashdalksjhd",
entity_id="wtw64768476",
entity_category="RESOURCE",
entity_type="nova.instance",
entity_state="AVAILABLE",
)
new_neighbors = [Neighbor(mock_neighbor, new_edge)]
# action
processor.update_relationship(None, new_neighbors)
processor.update_relationship(vertex1, new_neighbors)
# test assertions
self.assertEqual(3, processor.entity_graph.num_edges())
@ -169,10 +177,10 @@ class TestProcessor(TestEntityGraphUnitBase):
'backup')
processor.entity_graph.add_edge(new_edge)
self.assertEqual(3, processor.entity_graph.num_edges())
new_neighbors = [Neighbor(None, new_edge)]
new_neighbors = [Neighbor(vertex1, new_edge)]
# action
processor.delete_relationship(None, new_neighbors)
processor.delete_relationship(vertex2, new_neighbors)
# test assertions
edge_from_graph = processor.entity_graph.get_edge(vertex1.vertex_id,

View File

@ -21,6 +21,8 @@ from vitrage.evaluator.template_fields import TemplateFields as TFields
from vitrage.graph import Vertex
from vitrage.tests import base
_SET_STATES_PARAM_LEN = 3
class SetStateRecipeTest(base.BaseTest):
@ -47,7 +49,7 @@ class SetStateRecipeTest(base.BaseTest):
self.assertEqual(UPDATE_VERTEX, action_steps[0].type)
update_vertex_step_params = action_steps[0].params
self.assertEqual(2, len(update_vertex_step_params))
self.assertEqual(_SET_STATES_PARAM_LEN, len(update_vertex_step_params))
vitrage_state = update_vertex_step_params[VProps.VITRAGE_STATE]
self.assertEqual(self.props[TFields.STATE], vitrage_state)
@ -67,7 +69,7 @@ class SetStateRecipeTest(base.BaseTest):
self.assertEqual(UPDATE_VERTEX, action_steps[0].type)
update_vertex_step_params = action_steps[0].params
self.assertEqual(2, len(update_vertex_step_params))
self.assertEqual(_SET_STATES_PARAM_LEN, len(update_vertex_step_params))
vitrage_state = update_vertex_step_params[VProps.VITRAGE_STATE]
self.assertIsNone(vitrage_state)

View File

@ -26,6 +26,7 @@ from oslo_log import log as logging
from vitrage.common.constants import EdgeLabel as ELabel
from vitrage.common.constants import EntityCategory
from vitrage.common.constants import VertexProperties as VProps
from vitrage.common.exception import VitrageError
from vitrage.datasources.nova.host import NOVA_HOST_DATASOURCE
from vitrage.datasources.nova.instance import NOVA_INSTANCE_DATASOURCE
@ -75,7 +76,9 @@ v_alarm = graph_utils.create_vertex(
vitrage_id=ALARM + '444444444444',
entity_id='444444444444',
entity_type=ALARM_ON_VM,
entity_category=ALARM)
entity_category=ALARM,
metadata={VProps.RESOURCE_ID: '333333333333',
VProps.NAME: 'anotheralarm'})
v_switch = graph_utils.create_vertex(
vitrage_id=SWITCH + '1212121212',
entity_id='1212121212',
@ -95,12 +98,14 @@ e_node_to_switch = graph_utils.create_edge(
def add_connected_vertex(graph, entity_type, entity_subtype, entity_id,
edge_type, other_vertex, reverse=False):
edge_type, other_vertex, reverse=False,
metadata=None):
vertex = graph_utils.create_vertex(
vitrage_id=entity_subtype + str(entity_id),
entity_id=entity_id,
entity_category=entity_type,
entity_type=entity_subtype)
entity_type=entity_subtype,
metadata=metadata)
edge = graph_utils.create_edge(
source_id=other_vertex.vertex_id if reverse else vertex.vertex_id,
target_id=vertex.vertex_id if reverse else other_vertex.vertex_id,
@ -136,7 +141,8 @@ class GraphTestBase(base.BaseTest):
start = time.time()
g = NXGraph(name, EntityCategory.RESOURCE + ':' +
OPENSTACK_CLUSTER + ':' +
CLUSTER_ID)
CLUSTER_ID,
uuid=True)
g.add_vertex(v_node)
g.add_vertex(v_switch)
g.add_edge(e_node_to_switch)
@ -158,7 +164,9 @@ class GraphTestBase(base.BaseTest):
for j in range(num_of_alarms_per_host):
add_connected_vertex(g, ALARM, ALARM_ON_HOST,
cls.host_alarm_id, ELabel.ON,
host_to_add)
host_to_add, False,
{VProps.RESOURCE_ID: host_id,
VProps.NAME: host_id})
cls.host_alarm_id += 1
# Add Host Tests
@ -183,7 +191,9 @@ class GraphTestBase(base.BaseTest):
for k in range(num_of_alarms_per_vm):
add_connected_vertex(g, ALARM, ALARM_ON_VM,
cls.vm_alarm_id, ELabel.ON,
vm_to_add)
vm_to_add, False,
{VProps.RESOURCE_ID: cls.vm_id - 1,
VProps.NAME: cls.vm_id - 1})
cls.vm_alarm_id += 1
end = time.time()

View File

@ -103,7 +103,9 @@ class TestGraph(GraphTestBase):
vitrage_id='123',
entity_id='456',
entity_category=NOVA_INSTANCE_DATASOURCE,
metadata={'some_meta': 'DATA'}
metadata={'some_meta': 'DATA',
'type': 'nova.instance',
'resource_id': 'sdg7849ythksjdg'}
)
g.add_vertex(another_vertex)
v = g.get_vertex(another_vertex.vertex_id)
@ -254,7 +256,8 @@ class TestGraph(GraphTestBase):
v4 = v_alarm
v5 = utils.create_vertex(
vitrage_id='kuku',
entity_category=NOVA_HOST_DATASOURCE)
entity_type=NOVA_HOST_DATASOURCE,
entity_category=EntityCategory.RESOURCE)
g = NXGraph('test_neighbors')
g.add_vertex(v1)

View File

@ -21,7 +21,6 @@ Tests for `vitrage` graph driver algorithms
from vitrage.common.constants import EdgeLabel
from vitrage.common.constants import EdgeProperties as EProps
from vitrage.common.constants import VertexProperties as VProps
from vitrage.datasources.heat.stack import HEAT_STACK_DATASOURCE
from vitrage.datasources.neutron.network import NEUTRON_NETWORK_DATASOURCE
from vitrage.graph.algo_driver.algorithm import Mapping

View File

@ -19,6 +19,8 @@ from datetime import datetime
from oslo_log import log as logging
from oslotest import base
import unittest
from vitrage.common.constants import EntityCategory
from vitrage.common.constants import EventProperties as EventProps
from vitrage.common.constants import VertexProperties as VProps
@ -39,22 +41,40 @@ class TestEvents(base.BaseTestCase):
cls.vitrage_client = \
v_client.Client('1', session=keystone_client.get_session(cls.conf))
def test_send_doctor_event(self):
def test_send_doctor_event_with_resource_id(self):
"""Sending an event in Doctor format should result in an alarm"""
details = {
'hostname': 'host123',
'source': 'sample_monitor',
'cause': 'another alarm',
'severity': 'critical',
'status': 'down',
'monitor_id': 'sample monitor',
'resource_id': 'host123',
'monitor_event_id': '456',
}
self._test_send_doctor_event(details)
@unittest.skip("testing skipping")
def test_send_doctor_event_without_resource_id(self):
"""Sending an event in Doctor format should result in an alarm"""
details = {
'hostname': 'host123',
'source': 'sample_monitor',
'cause': 'another alarm',
'severity': 'critical',
'status': 'down',
'monitor_id': 'sample monitor',
'monitor_event_id': '456',
}
self._test_send_doctor_event(details)
def _test_send_doctor_event(self, details):
try:
# post an event to the message bus
event_time = datetime.now()
event_time_iso = event_time.isoformat()
event_type = 'compute.host.down'
details = {
'hostname': 'host123',
'source': 'sample_monitor',
'cause': 'another alarm',
'severity': 'critical',
'status': 'down',
'monitor_id': 'sample monitor',
'monitor_event_id': '456',
}
self.vitrage_client.event.post(event_time_iso, event_type, details)
@ -67,12 +87,15 @@ class TestEvents(base.BaseTestCase):
alarm = api_alarms[0]
event_time_tz = six.u(event_time.strftime('%Y-%m-%dT%H:%M:%SZ'))
self._check_alarm(alarm, event_time_tz, event_type, details)
event_time = datetime.now()
event_time_iso = event_time.isoformat()
details['status'] = 'up'
self.vitrage_client.event.post(event_time_iso, event_type, details)
except Exception as e:
LOG.exception(e)
raise
finally:
# do what?
LOG.warning('done')
def _check_alarms(self):

View File

@ -29,8 +29,7 @@ class BaseTopologyTest(BaseApiTest):
def _rollback_to_default(self):
self._delete_entities()
api_graph = self.vitrage_client.topology.get(
limit=4,
root='RESOURCE:openstack.cluster:OpenStack Cluster',
root=None,
all_tenants=True)
graph = self._create_graph_from_graph_dictionary(api_graph)
entities = self._entities_validation_data()

View File

@ -31,6 +31,7 @@ NOVA_QUERY = '{"and": [{"==": {"category": "RESOURCE"}},' \
'{"==": {"type": "nova.instance"}},' \
'{"==": {"type": "nova.host"}},' \
'{"==": {"type": "nova.zone"}}]}]}'
CLUSTER_VERTEX_ID = 'RESOURCE:openstack.cluster:OpenStack Cluster'
class TestTopology(BaseTopologyTest):
@ -277,7 +278,7 @@ class TestTopology(BaseTopologyTest):
# Calculate expected results
api_graph = self.vitrage_client.topology.get(
limit=2,
root='RESOURCE:openstack.cluster:OpenStack Cluster',
root=CLUSTER_VERTEX_ID,
all_tenants=True)
graph = self._create_graph_from_graph_dictionary(api_graph)
entities = self._entities_validation_data(
@ -310,7 +311,7 @@ class TestTopology(BaseTopologyTest):
# Calculate expected results
api_graph = self.vitrage_client.topology.get(
limit=3,
root='RESOURCE:openstack.cluster:OpenStack Cluster',
root=CLUSTER_VERTEX_ID,
all_tenants=True)
graph = self._create_graph_from_graph_dictionary(api_graph)
entities = self._entities_validation_data(
@ -348,14 +349,13 @@ class TestTopology(BaseTopologyTest):
# Calculate expected results
self.vitrage_client.topology.get(
limit=2,
root='RESOURCE:openstack.cluster:OpenStack Cluster',
root=None,
all_tenants=True)
except ClientException as e:
self.assertEqual(403, e.code)
self.assertEqual(
str(e),
str(e.message),
"Graph-type 'graph' requires a 'root' with 'depth'")
raise
finally:
self._rollback_to_default()