Added new test notification_crud.py. Refactored other files for code reuse
This commit is contained in:
parent
09341015f6
commit
a46ec61d59
53
tests/alarm.py
Normal file
53
tests/alarm.py
Normal file
@ -0,0 +1,53 @@
|
||||
from __future__ import print_function
|
||||
import sys
|
||||
|
||||
|
||||
def get_state(mon_client, alarm_id):
|
||||
result = get(mon_client, alarm_id)
|
||||
return result['state']
|
||||
|
||||
|
||||
def get(mon_client, alarm_id):
|
||||
result = mon_client.alarms.get(**{'alarm_id': alarm_id})
|
||||
return result
|
||||
|
||||
|
||||
def disable(mon_client, alarm_id):
|
||||
patch(mon_client, alarm_id, {'enabled': False})
|
||||
|
||||
|
||||
def enable(mon_client, alarm_id):
|
||||
patch(mon_client, alarm_id, {'enabled': True})
|
||||
|
||||
|
||||
def set_state(mon_client, alarm_id, state):
|
||||
patch(mon_client, alarm_id, {'state': state})
|
||||
new_state = get_state(mon_client, alarm_id)
|
||||
if new_state != state:
|
||||
print('Expected new state %s but found %s' %
|
||||
(state, new_state), file=sys.stderr)
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def patch(mon_client, alarm_id, fields):
|
||||
fields['alarm_id'] = alarm_id
|
||||
mon_client.alarms.patch(**fields)
|
||||
|
||||
|
||||
def set_optional_field(name, value, fields):
|
||||
if value is not None:
|
||||
fields[name] = value
|
||||
|
||||
|
||||
def create(mon_client, name, description, expression, ok_actions,
|
||||
alarm_actions, undetermined_actions):
|
||||
fields = {}
|
||||
fields['name'] = name
|
||||
fields['expression'] = expression
|
||||
set_optional_field('description', description, fields)
|
||||
set_optional_field('ok_actions', ok_actions, fields)
|
||||
set_optional_field('alarm_actions', alarm_actions, fields)
|
||||
set_optional_field('undetermined_actions', undetermined_actions, fields)
|
||||
result = mon_client.alarms.create(**fields)
|
||||
return result['id']
|
@ -8,8 +8,8 @@ import json
|
||||
import subprocess
|
||||
|
||||
|
||||
def find_notifications(alarm_id):
|
||||
args = ['sudo', 'cat', '/var/mail/root']
|
||||
def find_notifications(alarm_id, user):
|
||||
args = ['sudo', 'cat', '/var/mail/' + user]
|
||||
result = []
|
||||
try:
|
||||
stdout = subprocess.check_output(args)
|
||||
@ -20,3 +20,30 @@ def find_notifications(alarm_id):
|
||||
if alarm_id in line:
|
||||
result.append(json.loads(line)['state'])
|
||||
return result
|
||||
|
||||
|
||||
def create(mon_client, name, email):
|
||||
kwargs = {'name': name, 'address': email, 'type': 'EMAIL'}
|
||||
result = mon_client.notifications.create(**kwargs)
|
||||
return result['id']
|
||||
|
||||
|
||||
def update(mon_client, notification_id, name, email):
|
||||
kwargs = {'id': notification_id, 'name': name, 'address': email,
|
||||
'type': 'EMAIL'}
|
||||
result = mon_client.notifications.update(**kwargs)
|
||||
return result['id']
|
||||
|
||||
|
||||
def get(mon_client, notification_id):
|
||||
kwargs = {'notification_id': notification_id}
|
||||
result = mon_client.notifications.get(**kwargs)
|
||||
return result
|
||||
|
||||
|
||||
def find_by_name(mon_client, name):
|
||||
result = mon_client.notifications.list(**{})
|
||||
for notification in result:
|
||||
if notification['name'] == name:
|
||||
return notification
|
||||
return None
|
||||
|
194
tests/notification_crud.py
Normal file
194
tests/notification_crud.py
Normal file
@ -0,0 +1,194 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
"""Notification Engine Test
|
||||
CRUD test
|
||||
"""
|
||||
from __future__ import print_function
|
||||
import sys
|
||||
import platform
|
||||
import os
|
||||
import time
|
||||
from monclient import client
|
||||
import notification
|
||||
import monclient.exc as exc
|
||||
import alarm
|
||||
|
||||
|
||||
def call_mon_api(method, fields):
|
||||
|
||||
try:
|
||||
resp = method(**fields)
|
||||
except exc.HTTPException as he:
|
||||
print(he.code)
|
||||
print(he.message)
|
||||
sys.exit(1)
|
||||
else:
|
||||
return resp
|
||||
|
||||
|
||||
def cycle_states(mon_client, alarm_id, states):
|
||||
print('Cycling alarm states through %s' % (states))
|
||||
for state in states:
|
||||
alarm.set_state(mon_client, alarm_id, state)
|
||||
|
||||
|
||||
def check_notification(alarm_id, user, expected_state, existing):
|
||||
for i in range(0, 20):
|
||||
notifications = notification.find_notifications(alarm_id, user)
|
||||
if len(notifications) > existing:
|
||||
break
|
||||
time.sleep(1)
|
||||
|
||||
if len(notifications) <= existing:
|
||||
print('Did not receive new notification in %d seconds for user %s' %
|
||||
(i+1, user), file=sys.stderr)
|
||||
return False
|
||||
|
||||
if (len(notifications) - existing) > 1:
|
||||
print('Received %d new notifications instead of 1 for user %s' %
|
||||
(len(notifications) - existing, user), file=sys.stderr)
|
||||
return False
|
||||
|
||||
new_state = notifications[existing]
|
||||
if new_state != expected_state:
|
||||
print('Expected state %s for user %s but found state %s' %
|
||||
(expected_state, user, new_state), file=sys.stderr)
|
||||
return False
|
||||
print('Found notification for state %s for user %s in %d seconds' %
|
||||
(expected_state, user, i), file=sys.stderr)
|
||||
return True
|
||||
|
||||
|
||||
def find_or_create_notification(mon_client, name, email):
|
||||
notif = notification.find_by_name(mon_client, name)
|
||||
if notif is not None:
|
||||
if notif['address'] != email:
|
||||
print('Notification named %s exists but address is %s not %s' %
|
||||
(name, notif['address'], email), file=sys.stderr)
|
||||
return None
|
||||
return notif['id']
|
||||
else:
|
||||
return notification.create(mon_client, name, email)
|
||||
|
||||
|
||||
def check_notifications(alarm_id, email1, email2, email3, state1, state2,
|
||||
state3, existing):
|
||||
if not check_notification(alarm_id, email1, state1, existing):
|
||||
return False
|
||||
if not check_notification(alarm_id, email2, state2, existing):
|
||||
return False
|
||||
if not check_notification(alarm_id, email3, state3, existing):
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def print_actions(state, action_ids):
|
||||
addresses = []
|
||||
for action_id in action_ids:
|
||||
action_notification = notification.get(mon_client, action_id)
|
||||
addresses.append(action_notification['address'])
|
||||
print("Notification for %s state sent to %s" % (state, addresses))
|
||||
|
||||
|
||||
def print_notification_setup(mon_client, alarm_id):
|
||||
alarm_data = alarm.get(mon_client, alarm_id)
|
||||
print_actions('ALARM', alarm_data['alarm_actions'])
|
||||
print_actions('OK', alarm_data['ok_actions'])
|
||||
print_actions('UNDETERMINED', alarm_data['undetermined_actions'])
|
||||
|
||||
|
||||
def main():
|
||||
hostname = platform.node()
|
||||
|
||||
if hostname == 'mini-mon':
|
||||
api_host = '192.168.10.4'
|
||||
elif hostname == 'kafka':
|
||||
api_host = 'localhost'
|
||||
else:
|
||||
print('This test must be run on the kafka or mini-mon VM, aborting',
|
||||
file=sys.stderr)
|
||||
return 1
|
||||
|
||||
# Delete notification for OK.Cycle OK, ALARM, UNDETERMINED
|
||||
# Ensure proper notifications got written for ALARM, UNDETERMINED
|
||||
|
||||
states = ['OK', 'ALARM', 'UNDETERMINED']
|
||||
api_version = '2_0'
|
||||
endpoint = 'http://' + api_host + ':8080/v2.0'
|
||||
kwargs = {'token': '82510970543135'}
|
||||
global mon_client
|
||||
mon_client = client.Client(api_version, endpoint, **kwargs)
|
||||
|
||||
try:
|
||||
# Create 3 notifications with different emails, root, kafka, mon-agent
|
||||
email1 = "root"
|
||||
email2 = "kafka"
|
||||
email3 = "mon-agent"
|
||||
notification_id_1 = find_or_create_notification(mon_client, email1,
|
||||
email1 + "@localhost")
|
||||
notification_id_2 = find_or_create_notification(mon_client, email2,
|
||||
email2 + "@localhost")
|
||||
notification_id_3 = find_or_create_notification(mon_client, email3,
|
||||
email3 + "@localhost")
|
||||
|
||||
# Create an alarm. Cycle OK, ALARM, UNDETERMINED,
|
||||
alarm_name = "Test Notifications-" + str(os.getpid())
|
||||
expr = 'max(not_real_metric{}) > 10'
|
||||
alarm_id = alarm.create(mon_client, alarm_name, None, expr,
|
||||
notification_id_1, notification_id_2,
|
||||
notification_id_3)
|
||||
print('Created Alarm %s' % alarm_id)
|
||||
print_notification_setup(mon_client, alarm_id)
|
||||
print('Test initial cycle of Alarms')
|
||||
cycle_states(mon_client, alarm_id, states)
|
||||
|
||||
# Ensure proper notifications got written to each
|
||||
if not check_notifications(alarm_id, email1, email2, email3,
|
||||
states[0], states[1], states[2], 0):
|
||||
return 1
|
||||
|
||||
# Disable alarm. Cycle OK, ALARM, UNDETERMINED,
|
||||
print('Disable Alarm')
|
||||
alarm.disable(mon_client, alarm_id)
|
||||
cycle_states(mon_client, alarm_id, states)
|
||||
|
||||
# Ensure no new notifications
|
||||
if not check_notifications(alarm_id, email1, email2, email3,
|
||||
states[0], states[1], states[2], 0):
|
||||
return 1
|
||||
|
||||
# Enable alarm. Cycle OK, ALARM, UNDETERMINED
|
||||
print('Enable Alarm')
|
||||
alarm.enable(mon_client, alarm_id)
|
||||
cycle_states(mon_client, alarm_id, states)
|
||||
|
||||
# Ensure proper notifications got written to each
|
||||
if not check_notifications(alarm_id, email1, email2, email3,
|
||||
states[0], states[1], states[2], 1):
|
||||
return 1
|
||||
|
||||
# Switch Alarm notifications around. Cycle OK, ALARM, UNDETERMINED,
|
||||
print("Switch around Alarm notifications")
|
||||
alarm.patch(mon_client, alarm_id,
|
||||
{'ok_actions': [notification_id_2],
|
||||
'alarm_actions': [notification_id_3],
|
||||
'undetermined_actions': [notification_id_1]})
|
||||
print_notification_setup(mon_client, alarm_id)
|
||||
cycle_states(mon_client, alarm_id, states)
|
||||
|
||||
# Ensure proper notifications got written to each
|
||||
if not check_notifications(alarm_id, email2, email3, email1,
|
||||
states[0], states[1], states[2], 2):
|
||||
return 1
|
||||
|
||||
# Switch the email addresses around. Cycle OK, ALARM, UNDETERMINED,
|
||||
# Ensure proper notifications got written to each
|
||||
return 0
|
||||
except exc.HTTPException as he:
|
||||
print(he.code)
|
||||
print(he.message)
|
||||
return 1
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
@ -8,34 +8,17 @@ import sys
|
||||
import time
|
||||
from monclient import client
|
||||
from notification import find_notifications
|
||||
import monclient.exc as exc
|
||||
|
||||
|
||||
def call_mon_api(method, fields):
|
||||
|
||||
try:
|
||||
resp = method(**fields)
|
||||
except exc.HTTPException as he:
|
||||
print(he.code)
|
||||
print(he.message)
|
||||
sys.exit(1)
|
||||
else:
|
||||
return resp
|
||||
import alarm
|
||||
|
||||
|
||||
def find_alarm_id(mon_client):
|
||||
result = call_mon_api(mon_client.alarms.list, {})
|
||||
result = mon_client.alarms.list(**{})
|
||||
if len(result) == 0:
|
||||
print('No existing alarms, create one and rerun test', file=sys.stderr)
|
||||
return None
|
||||
return result[0]['id']
|
||||
|
||||
|
||||
def get_alarm_state(mon_client, alarm_id):
|
||||
result = call_mon_api(mon_client.alarms.get, {'alarm_id': alarm_id})
|
||||
return result['state']
|
||||
|
||||
|
||||
def main():
|
||||
if len(sys.argv) == 1:
|
||||
print('usage: %s count [alarm-id]' % sys.argv[0], file=sys.stderr)
|
||||
@ -55,32 +38,26 @@ def main():
|
||||
if alarm_id is None:
|
||||
return 1
|
||||
|
||||
user = 'root'
|
||||
start_time = time.time()
|
||||
initial_state = get_alarm_state(mon_client, alarm_id)
|
||||
initial_state = alarm.get_state(mon_client, alarm_id)
|
||||
state = initial_state
|
||||
fields = {'alarm_id': alarm_id}
|
||||
|
||||
existing_notifications = find_notifications(alarm_id)
|
||||
existing_notifications = find_notifications(alarm_id, user)
|
||||
notifications_sent = num_cycles * 2
|
||||
for _ in range(0, notifications_sent):
|
||||
if state == 'OK':
|
||||
state = 'ALARM'
|
||||
else:
|
||||
state = 'OK'
|
||||
fields['state'] = state
|
||||
call_mon_api(mon_client.alarms.patch, fields)
|
||||
new_state = get_alarm_state(mon_client, alarm_id)
|
||||
if new_state != state:
|
||||
print('Expected new state %s but found %s' %
|
||||
(state, new_state), file=sys.stderr)
|
||||
if not alarm.set_state(mon_client, alarm_id, state):
|
||||
return 1
|
||||
# time.sleep(1)
|
||||
|
||||
print("Took %d seconds to send %d alarm state changes" %
|
||||
((time.time() - start_time), num_cycles * 2))
|
||||
|
||||
for i in range(0, 30):
|
||||
notifications = find_notifications(alarm_id)
|
||||
notifications = find_notifications(alarm_id, user)
|
||||
notifications_found = len(notifications) - len(existing_notifications)
|
||||
if notifications_found >= notifications_sent:
|
||||
break
|
||||
|
Loading…
x
Reference in New Issue
Block a user