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:
Eric K 2018-12-17 15:48:35 -08:00 committed by Akhil jain
parent 69ec4fca3d
commit f4bcf65df7
3 changed files with 144 additions and 61 deletions

View File

@ -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")

View File

@ -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):

View File

@ -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):