
Allows for per-trigger-definition debugging. Simply add debug_level=1 to your trigger definition. debug_level=2 gives detailed explainations of why your stream didn't fire or trigger. This way, you can leave the overall debug level at INFO and still get details on the stream you're working on. Yagi worker now uses idle() callback for debug updates. and minor cleanups for pep8/HACKING Change-Id: Id0af7a0adbcc47335ad250130958932c708b5c18
270 lines
13 KiB
Python
270 lines
13 KiB
Python
import unittest2 as unittest
|
|
|
|
import mock
|
|
|
|
import datetime
|
|
import timex
|
|
|
|
from winchester import db as winch_db
|
|
from winchester import debugging
|
|
from winchester import definition
|
|
from winchester import trigger_manager
|
|
|
|
|
|
class TestTriggerManager(unittest.TestCase):
|
|
|
|
def setUp(self):
|
|
super(TestTriggerManager, self).setUp()
|
|
self.debugger = debugging.NoOpDebugger()
|
|
|
|
@mock.patch.object(trigger_manager.ConfigManager, 'wrap')
|
|
def test_save_event(self, mock_config_wrap):
|
|
tm = trigger_manager.TriggerManager('test')
|
|
tm.db = mock.MagicMock(spec=tm.db)
|
|
event = dict(message_id='1234-test-5678',
|
|
timestamp=datetime.datetime(2014,8,1,10,9,8,77777),
|
|
event_type='test.thing',
|
|
test_trait="foobar",
|
|
other_test_trait=42)
|
|
self.assertTrue(tm.save_event(event))
|
|
tm.db.create_event.assert_called_once_with('1234-test-5678', 'test.thing',
|
|
datetime.datetime(2014,8,1,10,9,8,77777),
|
|
dict(test_trait='foobar', other_test_trait=42))
|
|
|
|
@mock.patch.object(trigger_manager.ConfigManager, 'wrap')
|
|
def test_save_event_dup(self, mock_config_wrap):
|
|
tm = trigger_manager.TriggerManager('test')
|
|
tm.db = mock.MagicMock(spec=tm.db)
|
|
tm.db.create_event.side_effect = winch_db.DuplicateError("test boom!")
|
|
event = dict(message_id='1234-test-5678',
|
|
timestamp=datetime.datetime(2014,8,1,10,9,8,77777),
|
|
event_type='test.thing',
|
|
test_trait="foobar",
|
|
other_test_trait=42)
|
|
self.assertFalse(tm.save_event(event))
|
|
tm.db.create_event.assert_called_once_with('1234-test-5678', 'test.thing',
|
|
datetime.datetime(2014,8,1,10,9,8,77777),
|
|
dict(test_trait='foobar', other_test_trait=42))
|
|
|
|
@mock.patch('winchester.trigger_manager.EventCondenser', autospec=True)
|
|
@mock.patch.object(trigger_manager.ConfigManager, 'wrap')
|
|
def test_convert_notification(self, mock_config_wrap, mock_condenser):
|
|
tm = trigger_manager.TriggerManager('test')
|
|
tm.db = mock.MagicMock(spec=tm.db)
|
|
tm.distiller = mock.MagicMock(spec=tm.distiller)
|
|
test_event = "I'm a test event!"
|
|
tm.distiller.to_event.return_value = True
|
|
cond = mock_condenser.return_value
|
|
cond.validate.return_value = True
|
|
cond.get_event.return_value = test_event
|
|
tm.save_event = mock.MagicMock()
|
|
tm.save_event.return_value = True
|
|
|
|
res = tm.convert_notification('test notification here')
|
|
mock_condenser.assert_called_once_with(tm.db)
|
|
cond.clear.assert_called_once_with()
|
|
cond.validate.assert_called_once_with()
|
|
tm.distiller.to_event.assert_called_once_with('test notification here', cond)
|
|
self.assertEquals(res, test_event)
|
|
|
|
@mock.patch('winchester.trigger_manager.EventCondenser', autospec=True)
|
|
@mock.patch.object(trigger_manager.ConfigManager, 'wrap')
|
|
def test_convert_notification_dropped(self, mock_config_wrap, mock_condenser):
|
|
tm = trigger_manager.TriggerManager('test')
|
|
tm.db = mock.MagicMock(spec=tm.db)
|
|
tm.distiller = mock.MagicMock(spec=tm.distiller)
|
|
test_event = "I'm a test event!"
|
|
tm.distiller.to_event.return_value = False
|
|
cond = mock_condenser.return_value
|
|
cond.validate.return_value = True
|
|
cond.get_event.return_value = test_event
|
|
tm.save_event = mock.MagicMock()
|
|
tm.save_event.return_value = True
|
|
|
|
test_notif = dict(event_type='test.notification.here', message_id='4242-4242')
|
|
res = tm.convert_notification(test_notif)
|
|
mock_condenser.assert_called_once_with(tm.db)
|
|
cond.clear.assert_called_once_with()
|
|
self.assertFalse(cond.validate.called)
|
|
tm.distiller.to_event.assert_called_once_with(test_notif, cond)
|
|
self.assertFalse(tm.save_event.called)
|
|
self.assertIsNone(res)
|
|
|
|
@mock.patch('winchester.trigger_manager.EventCondenser', autospec=True)
|
|
@mock.patch.object(trigger_manager.ConfigManager, 'wrap')
|
|
def test_convert_notification_invalid(self, mock_config_wrap, mock_condenser):
|
|
tm = trigger_manager.TriggerManager('test')
|
|
tm.db = mock.MagicMock(spec=tm.db)
|
|
tm.distiller = mock.MagicMock(spec=tm.distiller)
|
|
test_event = "I'm a test event!"
|
|
tm.distiller.to_event.return_value = True
|
|
cond = mock_condenser.return_value
|
|
cond.validate.return_value = False
|
|
cond.get_event.return_value = test_event
|
|
tm.save_event = mock.MagicMock()
|
|
tm.save_event.return_value = True
|
|
|
|
test_notif = dict(event_type='test.notification.here', message_id='4242-4242')
|
|
res = tm.convert_notification(test_notif)
|
|
mock_condenser.assert_called_once_with(tm.db)
|
|
cond.clear.assert_called_once_with()
|
|
cond.validate.assert_called_once_with()
|
|
tm.distiller.to_event.assert_called_once_with(test_notif, cond)
|
|
self.assertFalse(tm.save_event.called)
|
|
self.assertIsNone(res)
|
|
|
|
@mock.patch.object(trigger_manager.ConfigManager, 'wrap')
|
|
def test_add_or_create_stream(self, mock_config_wrap):
|
|
tm = trigger_manager.TriggerManager('test')
|
|
tm.db = mock.MagicMock(spec=tm.db)
|
|
tm.db.get_active_stream.return_value = 'Existing Stream'
|
|
tm.current_time = mock.MagicMock()
|
|
trigger_def = mock.MagicMock()
|
|
dist_traits = 'some traits'
|
|
event = "eventful!"
|
|
|
|
ret = tm._add_or_create_stream(trigger_def, event, dist_traits)
|
|
tm.db.get_active_stream.assert_called_once_with(trigger_def.name,
|
|
dist_traits, tm.current_time.return_value)
|
|
self.assertFalse(tm.db.create_stream.called)
|
|
tm.db.add_event_stream.assert_called_once_with(
|
|
tm.db.get_active_stream.return_value,
|
|
event, trigger_def.expiration)
|
|
self.assertEqual(ret, tm.db.get_active_stream.return_value)
|
|
|
|
@mock.patch.object(trigger_manager.ConfigManager, 'wrap')
|
|
def test_add_or_create_stream_create(self, mock_config_wrap):
|
|
tm = trigger_manager.TriggerManager('test')
|
|
tm.db = mock.MagicMock(spec=tm.db)
|
|
tm.db.get_active_stream.return_value = None
|
|
tm.current_time = mock.MagicMock()
|
|
trigger_def = mock.MagicMock()
|
|
dist_traits = 'some traits'
|
|
event = "eventful!"
|
|
|
|
ret = tm._add_or_create_stream(trigger_def, event, dist_traits)
|
|
tm.db.get_active_stream.assert_called_once_with(trigger_def.name, dist_traits,
|
|
tm.current_time.return_value)
|
|
tm.db.create_stream.assert_called_once_with(trigger_def.name, event, dist_traits,
|
|
trigger_def.expiration)
|
|
self.assertFalse(tm.db.add_event_stream.called)
|
|
self.assertEqual(ret, tm.db.create_stream.return_value)
|
|
|
|
@mock.patch.object(trigger_manager.ConfigManager, 'wrap')
|
|
def test_ready_to_fire(self, mock_config_wrap):
|
|
tm = trigger_manager.TriggerManager('test')
|
|
tm.db = mock.MagicMock(spec=tm.db)
|
|
tm.current_time = mock.MagicMock()
|
|
trigger_def = mock.MagicMock()
|
|
test_stream = mock.MagicMock()
|
|
|
|
tm._ready_to_fire(test_stream, trigger_def)
|
|
trigger_def.get_fire_timestamp.assert_called_once_with(tm.current_time.return_value)
|
|
tm.db.stream_ready_to_fire.assert_called_once_with(test_stream,
|
|
trigger_def.get_fire_timestamp.return_value)
|
|
|
|
@mock.patch.object(trigger_manager.ConfigManager, 'wrap')
|
|
def test_add_notification(self, mock_config_wrap):
|
|
tm = trigger_manager.TriggerManager('test')
|
|
tm.convert_notification = mock.MagicMock()
|
|
tm.add_event = mock.MagicMock()
|
|
|
|
tm.add_notification("test notification")
|
|
tm.convert_notification.assert_called_once_with("test notification")
|
|
tm.add_event.assert_called_once_with(tm.convert_notification.return_value)
|
|
|
|
@mock.patch.object(trigger_manager.ConfigManager, 'wrap')
|
|
def test_add_notification_invalid_or_dropped(self, mock_config_wrap):
|
|
tm = trigger_manager.TriggerManager('test')
|
|
tm.convert_notification = mock.MagicMock()
|
|
tm.add_event = mock.MagicMock()
|
|
tm.convert_notification.return_value = None
|
|
|
|
tm.add_notification("test notification")
|
|
tm.convert_notification.assert_called_once_with("test notification")
|
|
self.assertFalse(tm.add_event.called)
|
|
|
|
@mock.patch.object(trigger_manager.ConfigManager, 'wrap')
|
|
def test_add_event(self, mock_config_wrap):
|
|
tm = trigger_manager.TriggerManager('test')
|
|
tm.db = mock.MagicMock(spec=tm.db)
|
|
tm.trigger_definitions = [mock.MagicMock() for n in range(3)]
|
|
for d in tm.trigger_definitions:
|
|
d.debugger = self.debugger
|
|
m_def = tm.trigger_definitions[2]
|
|
tm.trigger_definitions[0].match.return_value = None
|
|
tm.trigger_definitions[1].match.return_value = None
|
|
event = mock.MagicMock(name='event', spec=dict)
|
|
tm.save_event = mock.MagicMock()
|
|
tm._add_or_create_stream = mock.MagicMock()
|
|
tm._add_or_create_stream.return_value.fire_timestamp = None
|
|
tm._ready_to_fire = mock.MagicMock()
|
|
m_def.should_fire.return_value = True
|
|
|
|
tm.add_event(event)
|
|
tm.save_event.assert_called_once_with(event)
|
|
for td in tm.trigger_definitions:
|
|
td.match.assert_called_once_with(event)
|
|
m_def.get_distinguishing_traits.assert_called_once_with(event,
|
|
m_def.match.return_value)
|
|
tm._add_or_create_stream.assert_called_once_with(m_def, event,
|
|
m_def.get_distinguishing_traits.return_value)
|
|
tm.db.get_stream_events.assert_called_once_with(
|
|
tm._add_or_create_stream.return_value)
|
|
m_def.should_fire.assert_called_once_with(
|
|
tm.db.get_stream_events.return_value)
|
|
tm._ready_to_fire.assert_called_once_with(
|
|
tm._add_or_create_stream.return_value, m_def)
|
|
|
|
@mock.patch.object(trigger_manager.ConfigManager, 'wrap')
|
|
def test_add_event_on_ready_stream(self, mock_config_wrap):
|
|
tm = trigger_manager.TriggerManager('test')
|
|
tm.db = mock.MagicMock(spec=tm.db)
|
|
tm.trigger_definitions = [mock.MagicMock() for n in range(3)]
|
|
m_def = tm.trigger_definitions[2]
|
|
tm.trigger_definitions[0].match.return_value = None
|
|
tm.trigger_definitions[1].match.return_value = None
|
|
event = mock.MagicMock(name='event', spec=dict)
|
|
tm.save_event = mock.MagicMock()
|
|
tm._add_or_create_stream = mock.MagicMock()
|
|
tm._add_or_create_stream.return_value.fire_timestamp = "Fire!"
|
|
tm._ready_to_fire = mock.MagicMock()
|
|
m_def.should_fire.return_value = True
|
|
|
|
tm.add_event(event)
|
|
tm.save_event.assert_called_once_with(event)
|
|
for td in tm.trigger_definitions:
|
|
td.match.assert_called_once_with(event)
|
|
m_def.get_distinguishing_traits.assert_called_once_with(event,
|
|
m_def.match.return_value)
|
|
tm._add_or_create_stream.assert_called_once_with(m_def, event,
|
|
m_def.get_distinguishing_traits.return_value)
|
|
self.assertFalse(tm.db.get_stream_events.called)
|
|
self.assertFalse(m_def.should_fire.called)
|
|
self.assertFalse(tm._ready_to_fire.called)
|
|
|
|
@mock.patch.object(trigger_manager.ConfigManager, 'wrap')
|
|
def test_add_event_no_match(self, mock_config_wrap):
|
|
tm = trigger_manager.TriggerManager('test')
|
|
tm.db = mock.MagicMock(spec=tm.db)
|
|
tm.trigger_definitions = [mock.MagicMock() for n in range(3)]
|
|
tm.trigger_definitions[0].match.return_value = None
|
|
tm.trigger_definitions[1].match.return_value = None
|
|
tm.trigger_definitions[2].match.return_value = None
|
|
event = mock.MagicMock(name='event', spec=dict)
|
|
tm.save_event = mock.MagicMock()
|
|
tm._add_or_create_stream = mock.MagicMock()
|
|
tm._add_or_create_stream.return_value.fire_timestamp = "Fire!"
|
|
tm._ready_to_fire = mock.MagicMock()
|
|
|
|
tm.add_event(event)
|
|
tm.save_event.assert_called_once_with(event)
|
|
for td in tm.trigger_definitions:
|
|
td.match.assert_called_once_with(event)
|
|
for td in tm.trigger_definitions:
|
|
self.assertFalse(td.get_distinguishing_traits.called)
|
|
self.assertFalse(td.should_fire.called)
|
|
self.assertFalse(tm._add_or_create_stream.called)
|
|
self.assertFalse(tm.db.get_stream_events.called)
|
|
self.assertFalse(tm._ready_to_fire.called)
|