Add policy eval tests to vitrage webhook driver
To properly test for the publishing aspect of the driver. Depends-On: https://review.openstack.org/#/c/625749/ Depends-On: https://review.openstack.org/#/c/629029/ Change-Id: I3cb1b1c3e80b49ddbaa9f53506d12abf4f697174
This commit is contained in:
parent
69ec4fca3d
commit
f4bcf65df7
|
@ -14,6 +14,7 @@
|
|||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from oslo_log import log as logging
|
||||
from tempest import config
|
||||
from tempest.lib.common.utils import test_utils
|
||||
from tempest.lib import decorators
|
||||
|
@ -24,6 +25,48 @@ from congress_tempest_plugin.tests.scenario import manager_congress
|
|||
|
||||
|
||||
CONF = config.CONF
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
DS_NAME = 'vitrage'
|
||||
DRIVER_NAME = 'vitrage'
|
||||
TEST_PAYLOAD_ACTIVATE = {
|
||||
"notification": "vitrage.alarm.activate",
|
||||
"payload": {
|
||||
"vitrage_id": "2def31e9-6d9f-4c16-b007-893caa806cd4",
|
||||
"resource": {
|
||||
"vitrage_id": "437f1f4c-ccce-40a4-ac62-1c2f1fd9f6ac",
|
||||
"name": "app-1-server-1-jz6qvznkmnif",
|
||||
"update_timestamp": "2018-01-22 10:00:34.327142+00:00",
|
||||
"vitrage_category": "RESOURCE",
|
||||
"vitrage_operational_state": "OK",
|
||||
"vitrage_type": "nova.instance",
|
||||
"project_id": "8f007e5ba0944e84baa6f2a4f2b5d03a",
|
||||
"id": "9b7d93b9-94ec-41e1-9cec-f28d4f8d702c"},
|
||||
"update_timestamp": "2018-01-22T10:00:34Z",
|
||||
"vitrage_category": "ALARM",
|
||||
"state": "Active",
|
||||
"vitrage_type": "vitrage",
|
||||
"vitrage_operational_severity": "WARNING",
|
||||
"name": "Instance memory performance degraded"}}
|
||||
TEST_PAYLOAD_DEACTIVATE = {
|
||||
"notification": "vitrage.alarm.deactivate",
|
||||
"payload": {
|
||||
"vitrage_id": "2def31e9-6d9f-4c16-b007-893caa806cd4",
|
||||
"resource": {
|
||||
"vitrage_id": "437f1f4c-ccce-40a4-ac62-1c2f1fd9f6ac",
|
||||
"name": "app-1-server-1-jz6qvznkmnif",
|
||||
"update_timestamp": "2018-01-22 11:00:34.327142+00:00",
|
||||
"vitrage_category": "RESOURCE",
|
||||
"vitrage_operational_state": "OK",
|
||||
"vitrage_type": "nova.instance",
|
||||
"project_id": "8f007e5ba0944e84baa6f2a4f2b5d03a",
|
||||
"id": "9b7d93b9-94ec-41e1-9cec-f28d4f8d702c"},
|
||||
"update_timestamp": "2018-01-22T11:00:34Z",
|
||||
"vitrage_category": "ALARM",
|
||||
"state": "Inactive",
|
||||
"vitrage_type": "vitrage",
|
||||
"vitrage_operational_severity": "OK",
|
||||
"name": "Instance memory performance degraded"}}
|
||||
|
||||
|
||||
class TestVitrageDriver(manager_congress.ScenarioPolicyBase):
|
||||
|
@ -38,8 +81,8 @@ class TestVitrageDriver(manager_congress.ScenarioPolicyBase):
|
|||
def setUp(self):
|
||||
super(TestVitrageDriver, self).setUp()
|
||||
vitrage_setting = {
|
||||
'name': 'vitrage',
|
||||
'driver': 'vitrage',
|
||||
'name': DS_NAME,
|
||||
'driver': DRIVER_NAME,
|
||||
'config': None,
|
||||
}
|
||||
self.client = self.os_admin.congress_client
|
||||
|
@ -47,35 +90,6 @@ class TestVitrageDriver(manager_congress.ScenarioPolicyBase):
|
|||
response = self.client.create_datasource(vitrage_setting)
|
||||
self.datasource_id = response['id']
|
||||
|
||||
def tearDown(self):
|
||||
super(TestVitrageDriver, self).tearDown()
|
||||
self.client.delete_datasource(self.datasource_id)
|
||||
|
||||
def _list_datasource_rows(self, datasource, table):
|
||||
return self.client.list_datasource_rows(datasource, table)
|
||||
|
||||
@decorators.attr(type='smoke')
|
||||
def test_vitrage_alarms_table(self):
|
||||
test_payload = {
|
||||
"notification": "vitrage.alarm.activate",
|
||||
"payload": {
|
||||
"vitrage_id": "2def31e9-6d9f-4c16-b007-893caa806cd4",
|
||||
"resource": {
|
||||
"vitrage_id": "437f1f4c-ccce-40a4-ac62-1c2f1fd9f6ac",
|
||||
"name": "app-1-server-1-jz6qvznkmnif",
|
||||
"update_timestamp": "2018-01-22 10:00:34.327142+00:00",
|
||||
"vitrage_category": "RESOURCE",
|
||||
"vitrage_operational_state": "OK",
|
||||
"vitrage_type": "nova.instance",
|
||||
"project_id": "8f007e5ba0944e84baa6f2a4f2b5d03a",
|
||||
"id": "9b7d93b9-94ec-41e1-9cec-f28d4f8d702c"},
|
||||
"update_timestamp": "2018-01-22T10:00:34Z",
|
||||
"vitrage_category": "ALARM",
|
||||
"state": "Active",
|
||||
"vitrage_type": "vitrage",
|
||||
"vitrage_operational_severity": "WARNING",
|
||||
"name": "Instance memory performance degraded"}}
|
||||
|
||||
# Check if service is up
|
||||
@helper.retry_on_exception
|
||||
def _check_service():
|
||||
|
@ -87,7 +101,17 @@ class TestVitrageDriver(manager_congress.ScenarioPolicyBase):
|
|||
raise exceptions.TimeoutException(
|
||||
"Vitrage data source service is not up")
|
||||
|
||||
self.client.send_datasource_webhook(self.datasource_id, test_payload)
|
||||
def tearDown(self):
|
||||
super(TestVitrageDriver, self).tearDown()
|
||||
self.client.delete_datasource(self.datasource_id)
|
||||
|
||||
def _list_datasource_rows(self, datasource, table):
|
||||
return self.client.list_datasource_rows(datasource, table)
|
||||
|
||||
@decorators.attr(type='smoke')
|
||||
def test_vitrage_alarms_table(self):
|
||||
self.client.send_datasource_webhook(
|
||||
self.datasource_id, TEST_PAYLOAD_ACTIVATE)
|
||||
results = self._list_datasource_rows(self.datasource_id, 'alarms')
|
||||
if len(results['results']) != 1:
|
||||
error_msg = ('Unexpected additional rows are '
|
||||
|
@ -113,27 +137,8 @@ class TestVitrageDriver(manager_congress.ScenarioPolicyBase):
|
|||
% (results['results'][0]['data'], expected_row))
|
||||
raise exceptions.InvalidStructure(msg)
|
||||
|
||||
test_payload = {
|
||||
"notification": "vitrage.alarm.deactivate",
|
||||
"payload": {
|
||||
"vitrage_id": "2def31e9-6d9f-4c16-b007-893caa806cd4",
|
||||
"resource": {
|
||||
"vitrage_id": "437f1f4c-ccce-40a4-ac62-1c2f1fd9f6ac",
|
||||
"name": "app-1-server-1-jz6qvznkmnif",
|
||||
"update_timestamp": "2018-01-22 11:00:34.327142+00:00",
|
||||
"vitrage_category": "RESOURCE",
|
||||
"vitrage_operational_state": "OK",
|
||||
"vitrage_type": "nova.instance",
|
||||
"project_id": "8f007e5ba0944e84baa6f2a4f2b5d03a",
|
||||
"id": "9b7d93b9-94ec-41e1-9cec-f28d4f8d702c"},
|
||||
"update_timestamp": "2018-01-22T11:00:34Z",
|
||||
"vitrage_category": "ALARM",
|
||||
"state": "Inactive",
|
||||
"vitrage_type": "vitrage",
|
||||
"vitrage_operational_severity": "OK",
|
||||
"name": "Instance memory performance degraded"}}
|
||||
|
||||
self.client.send_datasource_webhook(self.datasource_id, test_payload)
|
||||
self.client.send_datasource_webhook(
|
||||
self.datasource_id, TEST_PAYLOAD_DEACTIVATE)
|
||||
results = self._list_datasource_rows(self.datasource_id, 'alarms')
|
||||
if len(results['results']) != 1:
|
||||
error_msg = ('Unexpected additional rows are '
|
||||
|
@ -158,3 +163,58 @@ class TestVitrageDriver(manager_congress.ScenarioPolicyBase):
|
|||
msg = ('inserted row %s is not expected row %s'
|
||||
% (results['results'][0]['data'], expected_row))
|
||||
raise exceptions.InvalidStructure(msg)
|
||||
|
||||
@decorators.attr(type='smoke')
|
||||
def test_vitrage_alarms_table_subscribe_then_publish(self):
|
||||
policy_name = self._create_random_policy('vitrage')
|
||||
policy_rule = 'test(name) :- {}:alarms(name=name)'.format(DS_NAME)
|
||||
self._create_policy_rule_retry(policy_name, policy_rule)
|
||||
|
||||
self.client.send_datasource_webhook(
|
||||
self.datasource_id, TEST_PAYLOAD_ACTIVATE)
|
||||
|
||||
@helper.retry_on_exception
|
||||
def _check_policy_eval():
|
||||
rows = self.client.list_policy_rows(policy_name, 'test')['results']
|
||||
if len(rows) < 1:
|
||||
LOG.debug('Too few rows: %s', rows)
|
||||
return False
|
||||
elif len(rows) > 1:
|
||||
LOG.debug('Too many rows: %s', rows)
|
||||
return False
|
||||
elif rows[0]['data'] != ['Instance memory performance degraded']:
|
||||
LOG.debug('Incorrect row data: %s', rows[0]['data'])
|
||||
return False
|
||||
return True
|
||||
|
||||
if not test_utils.call_until_true(func=_check_policy_eval,
|
||||
duration=10, sleep_for=1):
|
||||
raise exceptions.TimeoutException("Data did not converge in time "
|
||||
"or failure in server")
|
||||
|
||||
@decorators.attr(type='smoke')
|
||||
def test_vitrage_alarms_table_publish_then_subscribe(self):
|
||||
self.client.send_datasource_webhook(
|
||||
self.datasource_id, TEST_PAYLOAD_ACTIVATE)
|
||||
policy_name = self._create_random_policy('vitrage')
|
||||
policy_rule = 'test(name) :- {}:alarms(name=name)'.format(DS_NAME)
|
||||
self._create_policy_rule_retry(policy_name, policy_rule)
|
||||
|
||||
@helper.retry_on_exception
|
||||
def _check_policy_eval():
|
||||
rows = self.client.list_policy_rows(policy_name, 'test')['results']
|
||||
if len(rows) < 1:
|
||||
LOG.debug('Too few rows: %s', rows)
|
||||
return False
|
||||
elif len(rows) > 1:
|
||||
LOG.debug('Too many rows: %s', rows)
|
||||
return False
|
||||
elif rows[0]['data'] != ['Instance memory performance degraded']:
|
||||
LOG.debug('Incorrect row data: %s', rows[0]['data'])
|
||||
return False
|
||||
return True
|
||||
|
||||
if not test_utils.call_until_true(func=_check_policy_eval,
|
||||
duration=10, sleep_for=1):
|
||||
raise exceptions.TimeoutException("Data did not converge in time "
|
||||
"or failure in server")
|
||||
|
|
|
@ -18,15 +18,30 @@ import os
|
|||
import tenacity
|
||||
|
||||
|
||||
@tenacity.retry(stop=tenacity.stop_after_attempt(20),
|
||||
wait=tenacity.wait_fixed(1))
|
||||
def retry_check_function_return_value_condition(
|
||||
f, check_condition, error_msg=None, retry_interval=1,
|
||||
retry_attempts=20):
|
||||
"""Check if function f returns value s.t check_condition(value) is True."""
|
||||
|
||||
@tenacity.retry(stop=tenacity.stop_after_attempt(retry_attempts),
|
||||
wait=tenacity.wait_fixed(retry_interval))
|
||||
def retried_function():
|
||||
r = f()
|
||||
if not check_condition(r):
|
||||
raise Exception(error_msg or
|
||||
'Actual return value ({}) does not satisfy '
|
||||
'provided condition'.format(r))
|
||||
return r
|
||||
|
||||
return retried_function()
|
||||
|
||||
|
||||
def retry_check_function_return_value(f, expected_value, error_msg=None):
|
||||
"""Check if function f returns expected value."""
|
||||
if not error_msg:
|
||||
error_msg = 'Expected value "%s" not found' % expected_value
|
||||
r = f()
|
||||
if r != expected_value:
|
||||
raise Exception(error_msg)
|
||||
retry_check_function_return_value_condition(
|
||||
f, lambda v: v == expected_value, error_msg)
|
||||
|
||||
|
||||
def retry_on_exception(f):
|
||||
|
|
|
@ -32,6 +32,7 @@ from congress_tempest_plugin.services.congress_network import qos_client
|
|||
from congress_tempest_plugin.services.congress_network import qos_rule_client
|
||||
from congress_tempest_plugin.services.policy import policy_client
|
||||
# use local copy of tempest scenario manager during upstream refactoring
|
||||
from congress_tempest_plugin.tests.scenario import helper
|
||||
from congress_tempest_plugin.tests.scenario import manager
|
||||
|
||||
CONF = config.CONF
|
||||
|
@ -261,9 +262,9 @@ class ScenarioPolicyBase(manager.NetworkScenarioTest):
|
|||
src=floating_ip))
|
||||
raise
|
||||
|
||||
def _create_random_policy(self):
|
||||
policy_name = "nova_%s" % ''.join(random.choice(string.ascii_lowercase)
|
||||
for x in range(10))
|
||||
def _create_random_policy(self, prefix='nova'):
|
||||
policy_name = prefix + "_%s" % ''.join(
|
||||
random.choice(string.ascii_lowercase) for x in range(10))
|
||||
body = {"name": policy_name}
|
||||
resp = self.os_admin.congress_client.create_policy(body)
|
||||
self.addCleanup(self.os_admin.congress_client.delete_policy,
|
||||
|
@ -287,6 +288,13 @@ class ScenarioPolicyBase(manager.NetworkScenarioTest):
|
|||
raise Exception('Failed to create policy rule (%s, %s)'
|
||||
% (policy_name, rule))
|
||||
|
||||
def _create_policy_rule_retry(
|
||||
self, policy_name, rule, rule_name=None, comment=None):
|
||||
return helper.retry_check_function_return_value_condition(
|
||||
lambda: self._create_policy_rule(
|
||||
policy_name, rule, rule_name, comment),
|
||||
lambda v: True, retry_attempts=20, retry_interval=2)
|
||||
|
||||
|
||||
class DatasourceDriverTestBase(ScenarioPolicyBase):
|
||||
|
||||
|
|
Loading…
Reference in New Issue