Skip to content

Commit

Permalink
little refactoring and put signal to alert model
Browse files Browse the repository at this point in the history
  • Loading branch information
Benjamin Banduhn committed Dec 16, 2015
1 parent 2f88bb4 commit 7e050a6
Show file tree
Hide file tree
Showing 3 changed files with 105 additions and 65 deletions.
59 changes: 37 additions & 22 deletions howl/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from django.utils.translation import ugettext_lazy as _

from .operators import get_operator_class, get_operator_types
from .signals import howl_alert_critical, howl_alert_delete, howl_alert_warn
from .signals import alert_clear, alert_notify, alert_wait


class Observer(models.Model):
Expand All @@ -23,32 +23,14 @@ class Meta:
def __str__(self):
return self.name

def alert(self, compare_value):
def compare(self, compare_value):
operator_class = get_operator_class(self.operator)

if operator_class(self).compare(compare_value):
if Alert.objects.filter(observer=self).exists():
alert = Alert.objects.get(observer=self)
howl_alert_delete.send(sender=self.__class__, instance=alert)
alert.delete()

Alert.clear(self)
return False

obj, created = Alert.objects.get_or_create(observer=self, defaults={'observer': self})

if created:
howl_alert_warn.send(sender=self.__class__, instance=obj)
else:
alert_time = obj.timestamp + timedelta(seconds=self.waiting_period)
if alert_time < datetime.now():
if obj.state == obj.STATE_NOTIFIED and self.alert_every_time:
howl_alert_critical.send(sender=self.__class__, instance=obj)

if obj.state == obj.STATE_WAITING:
obj.state = obj.STATE_NOTIFIED
obj.save()
howl_alert_critical.send(sender=self.__class__, instance=obj)

Alert.set(self, compare_value)
return True


Expand All @@ -61,6 +43,7 @@ class Alert(models.Model):

observer = models.ForeignKey(Observer, verbose_name=_('Observer'))
timestamp = models.DateTimeField(auto_now_add=True)
value = models.CharField(_('Value'), max_length=255)
state = models.PositiveSmallIntegerField(
_('State'), choices=STATE_CHOICES, default=STATE_WAITING)

Expand All @@ -71,3 +54,35 @@ class Meta:

def __str__(self):
return _('Alert (ID: {0}) for {1}').format(self.pk, self.observer.name)

@classmethod
def set(cls, observer, compare_value):
obj, created = Alert.objects.get_or_create(
observer=observer, defaults={'value': compare_value})

if created:
alert_wait.send(sender=cls, instance=obj)
return True

alert_time = obj.timestamp + timedelta(seconds=observer.waiting_period)

if alert_time < datetime.now():
if obj.state == obj.STATE_NOTIFIED and observer.alert_every_time:
obj.value = compare_value
obj.save(update_fields=['value'])
alert_notify.send(sender=cls, instance=obj)

if obj.state == obj.STATE_WAITING:
obj.value = compare_value
obj.state = obj.STATE_NOTIFIED
obj.save(update_fields=['value', 'state'])
alert_notify.send(sender=cls, instance=obj)

@classmethod
def clear(cls, observer):
try:
obj = Alert.objects.get(observer=observer)
alert_clear.send(sender=cls, instance=obj)
obj.delete()
except Alert.DoesNotExist:
pass
6 changes: 3 additions & 3 deletions howl/signals.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from django.dispatch import Signal


howl_alert_warn = Signal(providing_args=['instance'])
howl_alert_critical = Signal(providing_args=['instance'])
howl_alert_delete = Signal(providing_args=['instance'])
alert_clear = Signal(providing_args=['instance'])
alert_notify = Signal(providing_args=['instance'])
alert_wait = Signal(providing_args=['instance'])
105 changes: 65 additions & 40 deletions howl/tests/test_models.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import time

import mock
import pytest

Expand All @@ -20,64 +18,91 @@ def test_repr(self):
(50, 50, False, 0),
(51, 50, True, 1),
])
def test_alert(self, value, compare_value, return_value, count_objects):
def test_compare(self, value, compare_value, return_value, count_objects):
obj = ObserverFactory.create(value=value)

assert Alert.objects.all().count() == 0
assert obj.alert(compare_value) is return_value
assert obj.compare(compare_value) is return_value
assert Alert.objects.all().count() == count_objects

@mock.patch('howl.models.howl_alert_delete.send')
def test_alert_delete(self, mock):
obj = ObserverFactory.create(value=4)
obj.alert(3)

@pytest.mark.django_db
class TestAlertModel:

def test_repr(self, activate_en):
observer = ObserverFactory.create(name='my observer')
obj = AlertFactory.create(id=23, observer=observer)

assert str(obj) == 'Alert (ID: 23) for my observer'

@mock.patch('howl.models.alert_wait.send')
def test_warn(self, mock):
observer = ObserverFactory.create(value=4, waiting_period=0)
Alert.set(observer, 2)

assert Alert.objects.all().count() == 1
time.sleep(0.5)
obj.alert(4)
assert Alert.objects.all().count() == 0
assert Alert.objects.first().state == Alert.STATE_WAITING
assert mock.call_count == 1

@mock.patch('howl.models.howl_alert_critical.send')
def test_alert_critical(self, mock):
obj = ObserverFactory.create(value=4)
obj.alert(3)
@mock.patch('howl.models.alert_notify.send')
def test_warn_critical_waiting_priod_not_achieved(self, mock):
observer = ObserverFactory.create(value=4, waiting_period=5)
AlertFactory.create(observer=observer)
Alert.set(observer, 2)

assert Alert.objects.all().count() == 1
time.sleep(0.5)
obj.alert(3)
assert Alert.objects.first().state == Alert.STATE_WAITING
assert mock.call_count == 0

@mock.patch('howl.models.alert_notify.send')
def test_warn_critical(self, mock):
observer = ObserverFactory.create(value=4, waiting_period=0)
AlertFactory.create(observer=observer, state=Alert.STATE_WAITING)

Alert.set(observer, 2)

assert Alert.objects.all().count() == 1
assert Alert.objects.first().state == Alert.STATE_NOTIFIED
assert mock.call_count == 1

@mock.patch('howl.models.howl_alert_critical.send')
def test_alert_critical_every_time(self, mock):
obj = ObserverFactory.create(value=4, alert_every_time=True)
obj.alert(3)
assert Alert.objects.all().count() == 1
time.sleep(0.5)
obj.alert(3)
time.sleep(0.5)
obj.alert(3)
@mock.patch('howl.models.alert_notify.send')
def test_warn_notified(self, mock):
observer = ObserverFactory.create(value=4, waiting_period=0)
AlertFactory.create(observer=observer, state=Alert.STATE_NOTIFIED)
Alert.set(observer, 2)

assert Alert.objects.all().count() == 1
assert Alert.objects.first().state == Alert.STATE_NOTIFIED
assert mock.call_count == 2
assert mock.call_count == 0

@mock.patch('howl.models.alert_notify.send')
def test_warn_every_time(self, mock):
observer = ObserverFactory.create(value=4, waiting_period=0, alert_every_time=True)
AlertFactory.create(observer=observer, state=Alert.STATE_NOTIFIED)

@mock.patch('howl.models.howl_alert_warn.send')
def test_alert_waiting_priod_not_achieved(self, mock):
obj = ObserverFactory.create(value=4, waiting_period=5)
obj.alert(3)
assert Alert.objects.all().count() == 1
time.sleep(0.5)
obj.alert(3)
assert Alert.objects.first().state == Alert.STATE_NOTIFIED
assert mock.call_count == 0

Alert.set(observer, 2)

assert Alert.objects.all().count() == 1
assert Alert.objects.first().state == Alert.STATE_WAITING
assert Alert.objects.first().state == Alert.STATE_NOTIFIED
assert mock.call_count == 1

@mock.patch('howl.models.alert_clear.send')
def test_clear(self, mock):
observer = ObserverFactory.create()
AlertFactory.create(observer=observer)
Alert.clear(observer)

@pytest.mark.django_db
class TestAlertModel:
assert Alert.objects.all().count() == 0
assert mock.call_count == 1

def test_repr(self, activate_en):
observer = ObserverFactory.create(name='my observer')
obj = AlertFactory.create(id=23, observer=observer)
@mock.patch('howl.models.alert_clear.send')
def test_clear_no_object(self, mock):
observer = ObserverFactory.create()
Alert.clear(observer)

assert str(obj) == 'Alert (ID: 23) for my observer'
assert Alert.objects.all().count() == 0
assert mock.call_count == 0

0 comments on commit 7e050a6

Please sign in to comment.