add tempest tests

add overlapping templates tests for all actions
add reset-server-state action test
add set-state action on instance test

Change-Id: I442f15e66767e5cb4cd0d0c3f6c06f5d02793eb5
This commit is contained in:
Idan Hefetz 2017-11-27 07:27:23 +00:00
parent 1ea07a9014
commit 1245df7121
9 changed files with 591 additions and 87 deletions

View File

@ -76,21 +76,6 @@ class BaseVitrageTempest(base.BaseTestCase):
filtered_list.append(item) filtered_list.append(item)
return filtered_list return filtered_list
def _check_num_instances(self, num_instances=0, state=''):
if len(TempestClients.nova().servers.list()) != num_instances:
return False
return all(instance.__dict__['status'].upper() == state.upper()
for instance in TempestClients.nova().servers.list())
def _check_num_volumes(self, num_volumes=0, state=''):
if len(TempestClients.cinder().volumes.list()) != num_volumes:
return False
return all(volume.__dict__['status'].upper() == state.upper() and
len(volume.__dict__['attachments']) == 1
for volume in TempestClients.cinder().volumes.list())
def _create_graph_from_graph_dictionary(self, api_graph): def _create_graph_from_graph_dictionary(self, api_graph):
self.assertIsNotNone(api_graph) self.assertIsNotNone(api_graph)
graph = NXGraph() graph = NXGraph()

View File

@ -14,17 +14,32 @@
import six import six
def get_first_match(list_of_dicts, subset_dict): def get_first_match(list_of_dicts, **kwargs):
subset_dict = _subset_dict(**kwargs)
for d in list_of_dicts: for d in list_of_dicts:
if is_subset(subset_dict, d): if is_subset(subset_dict, d):
return d return d
def get_all_matchs(list_of_dicts, subset_dict): def get_all_matches(list_of_dicts, **kwargs):
# TODO(idan_hefetz) this method can replace the notorious # TODO(idan_hefetz) this method can replace the notorious
# TODO(idan_hefetz) '_filter_list_by_pairs_parameters' # TODO(idan_hefetz) '_filter_list_by_pairs_parameters'
subset_dict = _subset_dict(**kwargs)
return [d for d in list_of_dicts if is_subset(subset_dict, d)] return [d for d in list_of_dicts if is_subset(subset_dict, d)]
def is_subset(subset, full): def is_subset(subset, full):
return six.viewitems(subset) <= six.viewitems(full) if not subset:
return True
full_dict = full
if type(full) is not dict:
full_dict = full.__dict__
return six.viewitems(subset) <= six.viewitems(full_dict)
def _subset_dict(**kwargs):
subset_dict_final = dict()
for keyword, arg in kwargs.items():
if arg is not None:
subset_dict_final[keyword] = arg
return subset_dict_final

View File

@ -13,13 +13,14 @@
# under the License. # under the License.
import time import time
from vitrage_tempest_tests.tests.common import general_utils as g_utils
from vitrage_tempest_tests.tests.common import glance_utils from vitrage_tempest_tests.tests.common import glance_utils
from vitrage_tempest_tests.tests.common import neutron_utils from vitrage_tempest_tests.tests.common import neutron_utils
from vitrage_tempest_tests.tests.common.tempest_clients import TempestClients from vitrage_tempest_tests.tests.common.tempest_clients import TempestClients
from vitrage_tempest_tests.tests.utils import wait_for_status from vitrage_tempest_tests.tests.utils import wait_for_status
def create_instances(num_instances, set_public_network=False, name='vm'): def create_instances(num_instances=1, set_public_network=False, name='vm'):
nics = [] nics = []
flavor = get_first_flavor() flavor = get_first_flavor()
image = glance_utils.get_first_image() image = glance_utils.get_first_image()
@ -39,14 +40,18 @@ def create_instances(num_instances, set_public_network=False, name='vm'):
return resources return resources
def delete_all_instances(): def delete_all_instances(**kwargs):
instances = TempestClients.nova().servers.list() instances = TempestClients.nova().servers.list()
for instance in instances: instances_to_delete = g_utils.get_all_matches(instances, **kwargs)
for item in instances_to_delete:
try: try:
TempestClients.nova().servers.delete(instance) TempestClients.nova().servers.delete(item)
except Exception: except Exception:
pass pass
wait_for_status(30, _check_num_instances, num_instances=0) wait_for_status(
30,
_check_num_instances,
num_instances=len(instances) - len(instances_to_delete))
time.sleep(2) time.sleep(2)

View File

@ -13,11 +13,11 @@
# under the License. # under the License.
from datetime import datetime from datetime import datetime
from vitrage.common.constants import VertexProperties as VProps
from vitrage.datasources import NOVA_HOST_DATASOURCE from vitrage.datasources import NOVA_HOST_DATASOURCE
from vitrage.datasources import NOVA_INSTANCE_DATASOURCE
from vitrage_tempest_tests.tests.api.event.base import DOWN from vitrage_tempest_tests.tests.api.event.base import DOWN
from vitrage_tempest_tests.tests.api.event.base import UP from vitrage_tempest_tests.tests.api.event.base import UP
from vitrage_tempest_tests.tests.common.general_utils import get_first_match from vitrage_tempest_tests.tests.common import general_utils as g_utils
from vitrage_tempest_tests.tests.common.tempest_clients import TempestClients from vitrage_tempest_tests.tests.common.tempest_clients import TempestClients
@ -36,6 +36,13 @@ def generate_fake_host_alarm(hostname, event_type, enabled=True):
TempestClients.vitrage().event.post(event_time_iso, event_type, details) TempestClients.vitrage().event.post(event_time_iso, event_type, details)
def get_first_host(): def get_first_host(**kwargs):
nodes = TempestClients.vitrage().topology.get(all_tenants=True)['nodes'] hosts = TempestClients.vitrage().resource.list(
return get_first_match(nodes, {VProps.VITRAGE_TYPE: NOVA_HOST_DATASOURCE}) NOVA_HOST_DATASOURCE, all_tenants=True)
return g_utils.get_first_match(hosts, **kwargs)
def get_first_instance(**kwargs):
instances = TempestClients.vitrage().resource.list(
NOVA_INSTANCE_DATASOURCE, all_tenants=True)
return g_utils.get_first_match(instances, **kwargs)

View File

@ -0,0 +1,76 @@
# Copyright 2017 - Nokia
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import time
from oslo_log import log as logging
from vitrage.common.constants import VertexProperties as VProps
from vitrage_tempest_tests.tests.base import BaseVitrageTempest
from vitrage_tempest_tests.tests.common import general_utils as g_utils
from vitrage_tempest_tests.tests.common.tempest_clients import TempestClients
from vitrage_tempest_tests.tests.common import vitrage_utils
LOG = logging.getLogger(__name__)
class TestActionsBase(BaseVitrageTempest):
@classmethod
def setUpClass(cls):
super(TestActionsBase, cls).setUpClass()
host = vitrage_utils.get_first_host()
if not host:
raise Exception("No host found")
if not host.get(VProps.VITRAGE_AGGREGATED_STATE) == 'AVAILABLE':
raise Exception("Host is not running %s", str(host))
cls.orig_host = host
def _trigger_do_action(self, trigger_name):
vitrage_utils.generate_fake_host_alarm(
self.orig_host.get('name'),
enabled=True,
event_type=trigger_name
)
time.sleep(2)
def _trigger_undo_action(self, trigger_name):
vitrage_utils.generate_fake_host_alarm(
self.orig_host.get('name'),
enabled=False,
event_type=trigger_name
)
time.sleep(2)
def _check_deduced(self, deduced_count, deduced_props, resource_id):
alarms = TempestClients.vitrage().alarm.list(
vitrage_id=resource_id,
all_tenants=True)
deduces = g_utils.get_all_matches(alarms, **deduced_props)
self.assertEqual(
deduced_count,
len(deduces),
'Expected %s deduces\n - \n%s\n - \n%s' %
(str(deduced_count), str(alarms), str(deduces)))
def _check_rca(self, rca, expected_alarms, inspected):
self.assertEqual(len(expected_alarms), len(rca['nodes']))
for expected_alarm in expected_alarms:
self.assertIsNotNone(
g_utils.get_first_match(rca['nodes'], **expected_alarm),
'expected_alarm is not in the rca %s' % str(expected_alarm))
rca_inspected = rca['nodes'][rca['inspected_index']]
self.assertEqual(
True,
g_utils.is_subset(inspected, rca_inspected),
'Invalid inspected item \n%s\n%s' %
(str(rca_inspected), str(inspected)))

View File

@ -20,16 +20,19 @@ from vitrage.common.constants import VertexProperties as VProps
from vitrage.datasources.doctor import DOCTOR_DATASOURCE from vitrage.datasources.doctor import DOCTOR_DATASOURCE
from vitrage.evaluator.actions.evaluator_event_transformer import \ from vitrage.evaluator.actions.evaluator_event_transformer import \
VITRAGE_DATASOURCE VITRAGE_DATASOURCE
from vitrage_tempest_tests.tests.base import BaseVitrageTempest
from vitrage_tempest_tests.tests.common import general_utils as g_utils from vitrage_tempest_tests.tests.common import general_utils as g_utils
from vitrage_tempest_tests.tests.common import nova_utils
from vitrage_tempest_tests.tests.common.tempest_clients import TempestClients from vitrage_tempest_tests.tests.common.tempest_clients import TempestClients
from vitrage_tempest_tests.tests.common import vitrage_utils from vitrage_tempest_tests.tests.common import vitrage_utils
from vitrage_tempest_tests.tests.e2e.test_actions_base import TestActionsBase
from vitrage_tempest_tests.tests import utils from vitrage_tempest_tests.tests import utils
LOG = logging.getLogger(__name__) LOG = logging.getLogger(__name__)
TRIGGER_ALARM_1 = 'e2e.test_basic_actions.trigger.alarm1' TRIGGER_ALARM_1 = 'e2e.test_basic_actions.trigger.alarm1'
TRIGGER_ALARM_2 = 'e2e.test_basic_actions.trigger.alarm2' TRIGGER_ALARM_2 = 'e2e.test_basic_actions.trigger.alarm2'
TRIGGER_ALARM_3 = 'e2e.test_basic_actions.trigger.alarm3'
TRIGGER_ALARM_4 = 'e2e.test_basic_actions.trigger.alarm4'
DEDUCED = 'e2e.test_basic_actions.deduced.alarm' DEDUCED = 'e2e.test_basic_actions.deduced.alarm'
TRIGGER_ALARM_2_PROPS = { TRIGGER_ALARM_2_PROPS = {
@ -45,35 +48,9 @@ DEDUCED_PROPS = {
} }
class TestBasicActions(BaseVitrageTempest): class TestBasicActions(TestActionsBase):
@classmethod
def setUpClass(cls):
super(TestBasicActions, cls).setUpClass()
host = vitrage_utils.get_first_host()
if not host:
raise Exception("No host found")
if not host.get(VProps.VITRAGE_AGGREGATED_STATE) == 'AVAILABLE':
raise Exception("Host is not running %s", str(host))
cls.orig_host = host
def _trigger_do_action(self, trigger_name):
vitrage_utils.generate_fake_host_alarm(
self.orig_host.get('name'),
enabled=True,
event_type=trigger_name
)
time.sleep(2)
def _trigger_undo_action(self, trigger_name):
vitrage_utils.generate_fake_host_alarm(
self.orig_host.get('name'),
enabled=False,
event_type=trigger_name
)
time.sleep(2)
@utils.tempest_logger @utils.tempest_logger
def test_action_set_state(self): def test_action_set_state_host(self):
try: try:
# Do # Do
@ -90,26 +67,56 @@ class TestBasicActions(BaseVitrageTempest):
self.assertEqual( self.assertEqual(
self.orig_host.get(VProps.VITRAGE_AGGREGATED_STATE), self.orig_host.get(VProps.VITRAGE_AGGREGATED_STATE),
curr_host.get(VProps.VITRAGE_AGGREGATED_STATE), curr_host.get(VProps.VITRAGE_AGGREGATED_STATE),
'state should change after set_state action') 'state should change after undo set_state action')
except Exception as e: except Exception as e:
self._handle_exception(e) self._handle_exception(e)
raise raise
finally: finally:
self._trigger_undo_action(TRIGGER_ALARM_1) self._trigger_undo_action(TRIGGER_ALARM_1)
@utils.tempest_logger
def test_action_set_state_instance(self):
vm_id = ""
try:
vm_id = nova_utils.create_instances(set_public_network=True)[0].id
# Do
orig_instance = vitrage_utils.get_first_instance(id=vm_id)
self._trigger_do_action(TRIGGER_ALARM_3)
curr_instance = vitrage_utils.get_first_instance(id=vm_id)
self.assertEqual(
'ERROR',
curr_instance.get(VProps.VITRAGE_AGGREGATED_STATE),
'state should change after set_state action')
# Undo
self._trigger_undo_action(TRIGGER_ALARM_3)
curr_instance = vitrage_utils.get_first_instance(id=vm_id)
self.assertEqual(
orig_instance.get(VProps.VITRAGE_AGGREGATED_STATE),
curr_instance.get(VProps.VITRAGE_AGGREGATED_STATE),
'state should change after undo set_state action')
except Exception as e:
self._handle_exception(e)
raise
finally:
self._trigger_undo_action(TRIGGER_ALARM_3)
nova_utils.delete_all_instances(id=vm_id)
@utils.tempest_logger @utils.tempest_logger
def test_action_mark_down_host(self): def test_action_mark_down_host(self):
try: try:
host_name = self.orig_host.get(VProps.NAME) host_name = self.orig_host.get(VProps.NAME)
# Do # Do
self._trigger_do_action(TRIGGER_ALARM_1) self._trigger_do_action(TRIGGER_ALARM_4)
nova_service = TempestClients.nova().services.list( nova_service = TempestClients.nova().services.list(
host=host_name, binary='nova-compute')[0] host=host_name, binary='nova-compute')[0]
self.assertEqual("down", str(nova_service.state)) self.assertEqual("down", str(nova_service.state))
# Undo # Undo
self._trigger_undo_action(TRIGGER_ALARM_1) self._trigger_undo_action(TRIGGER_ALARM_4)
nova_service = TempestClients.nova().services.list( nova_service = TempestClients.nova().services.list(
host=host_name, binary='nova-compute')[0] host=host_name, binary='nova-compute')[0]
self.assertEqual("up", str(nova_service.state)) self.assertEqual("up", str(nova_service.state))
@ -117,7 +124,31 @@ class TestBasicActions(BaseVitrageTempest):
self._handle_exception(e) self._handle_exception(e)
raise raise
finally: finally:
self._trigger_undo_action(TRIGGER_ALARM_1) self._trigger_undo_action(TRIGGER_ALARM_4)
# nova.host datasource may take up to snapshot_intreval to update
time.sleep(130)
@utils.tempest_logger
def test_action_mark_down_instance(self):
vm_id = ""
try:
vm_id = nova_utils.create_instances(set_public_network=True)[0].id
# Do
self._trigger_do_action(TRIGGER_ALARM_3)
nova_instance = TempestClients.nova().servers.get(vm_id)
self.assertEqual("ERROR", str(nova_instance.status))
# Undo
self._trigger_undo_action(TRIGGER_ALARM_3)
nova_instance = TempestClients.nova().servers.get(vm_id)
self.assertEqual("ACTIVE", str(nova_instance.status))
except Exception as e:
self._handle_exception(e)
raise
finally:
pass
self._trigger_undo_action(TRIGGER_ALARM_3)
nova_utils.delete_all_instances(id=vm_id)
@utils.tempest_logger @utils.tempest_logger
def test_action_deduce_alarm(self): def test_action_deduce_alarm(self):
@ -137,17 +168,6 @@ class TestBasicActions(BaseVitrageTempest):
finally: finally:
self._trigger_undo_action(TRIGGER_ALARM_2) self._trigger_undo_action(TRIGGER_ALARM_2)
def _check_deduced(self, deduced_count, deduced_props, resource_id):
alarms = TempestClients.vitrage().alarm.list(
vitrage_id=resource_id,
all_tenants=True)
deduces = g_utils.get_all_matchs(alarms, deduced_props)
self.assertEqual(
deduced_count,
len(deduces),
'Expected %s deduces\n - \n%s\n - \n%s' %
(str(deduced_count), str(alarms), str(deduces)))
@utils.tempest_logger @utils.tempest_logger
def test_action_add_causal_relationship(self): def test_action_add_causal_relationship(self):
try: try:
@ -156,9 +176,10 @@ class TestBasicActions(BaseVitrageTempest):
alarms = TempestClients.vitrage().alarm.list( alarms = TempestClients.vitrage().alarm.list(
vitrage_id=self.orig_host.get(VProps.VITRAGE_ID), vitrage_id=self.orig_host.get(VProps.VITRAGE_ID),
all_tenants=True) all_tenants=True)
self.assertEqual(True, len(alarms) >= 2, 'alarms %s' % str(alarms))
deduced = g_utils.get_all_matchs(alarms, DEDUCED_PROPS)[0] deduced = g_utils.get_first_match(alarms, **DEDUCED_PROPS)
trigger = g_utils.get_all_matchs(alarms, TRIGGER_ALARM_2_PROPS)[0] trigger = g_utils.get_first_match(alarms, **TRIGGER_ALARM_2_PROPS)
# Get Rca for the deduced # Get Rca for the deduced
rca = TempestClients.vitrage().rca.get( rca = TempestClients.vitrage().rca.get(
@ -174,16 +195,3 @@ class TestBasicActions(BaseVitrageTempest):
raise raise
finally: finally:
self._trigger_undo_action(TRIGGER_ALARM_2) self._trigger_undo_action(TRIGGER_ALARM_2)
def _check_rca(self, rca, expected_alarms, inspected):
self.assertEqual(len(expected_alarms), len(rca['nodes']))
for expected_alarm in expected_alarms:
self.assertIsNotNone(
g_utils.get_first_match(rca['nodes'], expected_alarm),
'expected_alarm is not in the rca %s' % str(expected_alarm))
rca_inspected = rca['nodes'][rca['inspected_index']]
self.assertEqual(
True,
g_utils.is_subset(inspected, rca_inspected),
'Invalid inspected item \n%s\n%s' %
(str(rca_inspected), str(inspected)))

View File

@ -0,0 +1,234 @@
# Copyright 2017 - Nokia
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import time
from oslo_log import log as logging
from vitrage.common.constants import EntityCategory
from vitrage.common.constants import VertexProperties as VProps
from vitrage.datasources.doctor import DOCTOR_DATASOURCE
from vitrage.evaluator.actions.evaluator_event_transformer import \
VITRAGE_DATASOURCE
from vitrage_tempest_tests.tests.common import general_utils as g_utils
from vitrage_tempest_tests.tests.common.tempest_clients import TempestClients
from vitrage_tempest_tests.tests.common import vitrage_utils
from vitrage_tempest_tests.tests.e2e.test_actions_base import TestActionsBase
from vitrage_tempest_tests.tests import utils
LOG = logging.getLogger(__name__)
TRIGGER_ALARM_1 = 'e2e.test_overlapping_actions.trigger.alarm1'
TRIGGER_ALARM_2 = 'e2e.test_overlapping_actions.trigger.alarm2'
TRIGGER_ALARM_3 = 'e2e.test_overlapping_actions.trigger.alarm3'
TRIGGER_ALARM_4 = 'e2e.test_overlapping_actions.trigger.alarm4'
DEDUCED = 'e2e.test_overlapping_actions.deduced.alarm'
TRIGGER_ALARM_1_PROPS = {
VProps.NAME: TRIGGER_ALARM_1,
VProps.VITRAGE_CATEGORY: EntityCategory.ALARM,
VProps.VITRAGE_TYPE: DOCTOR_DATASOURCE,
}
TRIGGER_ALARM_2_PROPS = {
VProps.NAME: TRIGGER_ALARM_2,
VProps.VITRAGE_CATEGORY: EntityCategory.ALARM,
VProps.VITRAGE_TYPE: DOCTOR_DATASOURCE,
}
DEDUCED_PROPS = {
VProps.NAME: DEDUCED,
VProps.VITRAGE_CATEGORY: EntityCategory.ALARM,
VProps.VITRAGE_TYPE: VITRAGE_DATASOURCE,
}
class TestOverlappingcActions(TestActionsBase):
@utils.tempest_logger
def test_overlapping_action_set_state(self):
try:
# Do - first
self._trigger_do_action(TRIGGER_ALARM_1)
curr_host = vitrage_utils.get_first_host()
self.assertEqual(
'ERROR',
curr_host.get(VProps.VITRAGE_AGGREGATED_STATE),
'state should change after set_state action')
# Do - second
self._trigger_do_action(TRIGGER_ALARM_2)
curr_host = vitrage_utils.get_first_host()
self.assertEqual(
'ERROR',
curr_host.get(VProps.VITRAGE_AGGREGATED_STATE),
'state should remain unchanged')
# Undo - first
self._trigger_undo_action(TRIGGER_ALARM_1)
curr_host = vitrage_utils.get_first_host()
self.assertEqual(
'ERROR',
curr_host.get(VProps.VITRAGE_AGGREGATED_STATE),
'state should remain unchanged')
# Undo - second
self._trigger_undo_action(TRIGGER_ALARM_2)
curr_host = vitrage_utils.get_first_host()
self.assertEqual(
self.orig_host.get(VProps.VITRAGE_AGGREGATED_STATE),
curr_host.get(VProps.VITRAGE_AGGREGATED_STATE),
'state should change after undo set_state action')
except Exception as e:
self._handle_exception(e)
raise
finally:
self._trigger_undo_action(TRIGGER_ALARM_1)
self._trigger_undo_action(TRIGGER_ALARM_2)
@utils.tempest_logger
def test_overlapping_action_mark_down(self):
try:
host_name = self.orig_host.get(VProps.NAME)
# Do - first
self._trigger_do_action(TRIGGER_ALARM_3)
nova_service = TempestClients.nova().services.list(
host=host_name, binary='nova-compute')[0]
self.assertEqual("down", str(nova_service.state))
# Do - second
self._trigger_do_action(TRIGGER_ALARM_4)
nova_service = TempestClients.nova().services.list(
host=host_name, binary='nova-compute')[0]
self.assertEqual("down", str(nova_service.state))
# Undo - first
self._trigger_undo_action(TRIGGER_ALARM_3)
nova_service = TempestClients.nova().services.list(
host=host_name, binary='nova-compute')[0]
self.assertEqual("down", str(nova_service.state))
# Undo - second
self._trigger_undo_action(TRIGGER_ALARM_4)
nova_service = TempestClients.nova().services.list(
host=host_name, binary='nova-compute')[0]
self.assertEqual("up", str(nova_service.state))
except Exception as e:
self._handle_exception(e)
raise
finally:
self._trigger_undo_action(TRIGGER_ALARM_3)
self._trigger_undo_action(TRIGGER_ALARM_4)
# nova.host datasource may take up to snapshot_intreval to update
time.sleep(130)
@utils.tempest_logger
def test_overlapping_action_deduce_alarm(self):
try:
host_id = self.orig_host.get(VProps.VITRAGE_ID)
# Do - first
self._trigger_do_action(TRIGGER_ALARM_1)
self._check_deduced(1, DEDUCED_PROPS, host_id)
# Do - second
self._trigger_do_action(TRIGGER_ALARM_2)
self._check_deduced(1, DEDUCED_PROPS, host_id)
# Undo - first
self._trigger_undo_action(TRIGGER_ALARM_1)
self._check_deduced(1, DEDUCED_PROPS, host_id)
# Undo - second
self._trigger_undo_action(TRIGGER_ALARM_2)
self._check_deduced(0, DEDUCED_PROPS, host_id)
except Exception as e:
self._handle_exception(e)
raise
finally:
self._trigger_undo_action(TRIGGER_ALARM_1)
self._trigger_undo_action(TRIGGER_ALARM_2)
@utils.tempest_logger
def test_overlapping_action_add_causal_relationship(self):
try:
# ---- Do first & second ----
self._trigger_do_action(TRIGGER_ALARM_1)
self._trigger_do_action(TRIGGER_ALARM_2)
alarms = TempestClients.vitrage().alarm.list(
vitrage_id=self.orig_host.get(VProps.VITRAGE_ID),
all_tenants=True)
deduced = g_utils.get_first_match(alarms, **DEDUCED_PROPS)
trigger1 = g_utils.get_first_match(alarms, **TRIGGER_ALARM_1_PROPS)
trigger2 = g_utils.get_first_match(alarms, **TRIGGER_ALARM_2_PROPS)
# Get Rca for the deduced
rca = TempestClients.vitrage().rca.get(
deduced[VProps.VITRAGE_ID], all_tenants=True)
self._check_rca(rca, [deduced, trigger1, trigger2], DEDUCED_PROPS)
# Get Rca for trigger 1
rca = TempestClients.vitrage().rca.get(
trigger1[VProps.VITRAGE_ID], all_tenants=True)
self._check_rca(rca, [deduced, trigger1], TRIGGER_ALARM_1_PROPS)
# Get Rca for trigger 2
rca = TempestClients.vitrage().rca.get(
trigger2[VProps.VITRAGE_ID], all_tenants=True)
self._check_rca(rca, [deduced, trigger2], TRIGGER_ALARM_2_PROPS)
# ---- Undo - first ----
self._trigger_undo_action(TRIGGER_ALARM_1)
alarms = TempestClients.vitrage().alarm.list(
vitrage_id=self.orig_host.get(VProps.VITRAGE_ID),
all_tenants=True)
deduced = g_utils.get_first_match(alarms, **DEDUCED_PROPS)
trigger2 = g_utils.get_first_match(alarms, **TRIGGER_ALARM_2_PROPS)
# Get Rca for the deduced
rca = TempestClients.vitrage().rca.get(
deduced[VProps.VITRAGE_ID], all_tenants=True)
self._check_rca(rca, [deduced, trigger2], DEDUCED_PROPS)
# Get Rca for trigger 2
rca = TempestClients.vitrage().rca.get(
trigger2[VProps.VITRAGE_ID], all_tenants=True)
self._check_rca(rca, [deduced, trigger2], TRIGGER_ALARM_2_PROPS)
# ---- Undo - second ----
self._trigger_undo_action(TRIGGER_ALARM_2)
alarms = TempestClients.vitrage().alarm.list(
vitrage_id=self.orig_host.get(VProps.VITRAGE_ID),
all_tenants=True)
self.assertEqual(
0,
len(g_utils.get_all_matches(alarms, **TRIGGER_ALARM_1_PROPS)),
'trigger alarm 1 should have been removed')
self.assertEqual(
0,
len(g_utils.get_all_matches(alarms, **TRIGGER_ALARM_2_PROPS)),
'trigger alarm 2 should have been removed')
self.assertEqual(
0,
len(g_utils.get_all_matches(alarms, **DEDUCED_PROPS)),
'deduced alarm should have been removed')
except Exception as e:
self._handle_exception(e)
raise
finally:
self._trigger_undo_action(TRIGGER_ALARM_1)
self._trigger_undo_action(TRIGGER_ALARM_2)

View File

@ -11,6 +11,14 @@ definitions:
category: ALARM category: ALARM
name: e2e.test_basic_actions.trigger.alarm2 name: e2e.test_basic_actions.trigger.alarm2
template_id: trigger_alarm_2 template_id: trigger_alarm_2
- entity:
category: ALARM
name: e2e.test_basic_actions.trigger.alarm3
template_id: trigger_alarm_3
- entity:
category: ALARM
name: e2e.test_basic_actions.trigger.alarm4
template_id: trigger_alarm_4
- entity: - entity:
category: ALARM category: ALARM
type: vitrage type: vitrage
@ -20,6 +28,10 @@ definitions:
category: RESOURCE category: RESOURCE
type: nova.host type: nova.host
template_id: host template_id: host
- entity:
category: RESOURCE
type: nova.instance
template_id: instance
relationships: relationships:
- relationship: - relationship:
source: trigger_alarm_1 source: trigger_alarm_1
@ -31,11 +43,26 @@ definitions:
relationship_type: on relationship_type: on
target: host target: host
template_id : trigger_alarm_2_on_host template_id : trigger_alarm_2_on_host
- relationship:
source: trigger_alarm_3
relationship_type: on
target: host
template_id : trigger_alarm_3_on_host
- relationship:
source: trigger_alarm_4
relationship_type: on
target: host
template_id : trigger_alarm_4_on_host
- relationship: - relationship:
source: deduced_alarm source: deduced_alarm
relationship_type: on relationship_type: on
target: host target: host
template_id : deduced_alarm_on_host template_id : deduced_alarm_on_host
- relationship:
source: host
target: instance
relationship_type: contains
template_id: host_contains_instance
scenarios: scenarios:
- scenario: - scenario:
condition: trigger_alarm_1_on_host condition: trigger_alarm_1_on_host
@ -46,6 +73,9 @@ scenarios:
target: host target: host
properties: properties:
state: ERROR state: ERROR
- scenario:
condition: trigger_alarm_4_on_host
actions:
- action: - action:
action_type: mark_down action_type: mark_down
action_target: action_target:
@ -68,3 +98,16 @@ scenarios:
action_target: action_target:
source: trigger_alarm_2 source: trigger_alarm_2
target: deduced_alarm target: deduced_alarm
- scenario:
condition: trigger_alarm_3_on_host and host_contains_instance
actions:
- action:
action_type: set_state
action_target:
target: instance
properties:
state: ERROR
- action:
action_type: mark_down
action_target:
target: instance

View File

@ -0,0 +1,131 @@
metadata:
name: e2e_test_overlapping_actions
description: this template includes vitrage basic actions
definitions:
entities:
- entity:
category: ALARM
name: e2e.test_overlapping_actions.trigger.alarm1
template_id: trigger_alarm_1
- entity:
category: ALARM
name: e2e.test_overlapping_actions.trigger.alarm2
template_id: trigger_alarm_2
- entity:
category: ALARM
name: e2e.test_overlapping_actions.trigger.alarm3
template_id: trigger_alarm_3
- entity:
category: ALARM
name: e2e.test_overlapping_actions.trigger.alarm4
template_id: trigger_alarm_4
- entity:
category: ALARM
type: vitrage
name: e2e.test_overlapping_actions.deduced.alarm
template_id: deduced_alarm
- entity:
category: RESOURCE
type: nova.host
template_id: host
relationships:
- relationship:
source: trigger_alarm_1
relationship_type: on
target: host
template_id : trigger_alarm_1_on_host
- relationship:
source: trigger_alarm_2
relationship_type: on
target: host
template_id : trigger_alarm_2_on_host
- relationship:
source: trigger_alarm_3
relationship_type: on
target: host
template_id : trigger_alarm_3_on_host
- relationship:
source: trigger_alarm_4
relationship_type: on
target: host
template_id : trigger_alarm_4_on_host
- relationship:
source: deduced_alarm
relationship_type: on
target: host
template_id : deduced_alarm_on_host
scenarios:
# First part - trigger_alarm_1_on_host or trigger_alarm_3_on_host:
- scenario:
condition: trigger_alarm_1_on_host
actions:
- action:
action_type: set_state
action_target:
target: host
properties:
state: ERROR
- scenario:
condition: trigger_alarm_3_on_host
actions:
- action:
action_type: mark_down
action_target:
target: host
- scenario:
condition: trigger_alarm_1_on_host
actions:
- action:
action_type: raise_alarm
action_target:
target: host
properties:
alarm_name: e2e.test_overlapping_actions.deduced.alarm
severity: WARNING
- scenario:
condition: trigger_alarm_1_on_host and deduced_alarm_on_host
actions:
- action:
action_type: add_causal_relationship
action_target:
source: trigger_alarm_1
target: deduced_alarm
# Second part - trigger_alarm_2_on_host or trigger_alarm_4_on_host:
- scenario:
condition: trigger_alarm_2_on_host
actions:
- action:
action_type: set_state
action_target:
target: host
properties:
state: ERROR
- scenario:
condition: trigger_alarm_4_on_host
actions:
- action:
action_type: mark_down
action_target:
target: host
- scenario:
condition: trigger_alarm_2_on_host
actions:
- action:
action_type: raise_alarm
action_target:
target: host
properties:
alarm_name: e2e.test_overlapping_actions.deduced.alarm
severity: WARNING
- scenario:
condition: trigger_alarm_2_on_host and deduced_alarm_on_host
actions:
- action:
action_type: add_causal_relationship
action_target:
source: trigger_alarm_2
target: deduced_alarm