Add test cases for EventScheduler class
==== Tech Notes ==== - Add test cases - Slight refactoring of EventScheduler class to make it easier to testpull/1189/head
parent
28e0ae9200
commit
3004aada98
|
@ -51,11 +51,12 @@ class EventScheduler(Thread):
|
|||
Load json data with active events from json file.
|
||||
"""
|
||||
if isfile(self.schedule_file):
|
||||
json_data = {}
|
||||
with open(self.schedule_file) as f:
|
||||
try:
|
||||
json_data = json.load(f)
|
||||
except Exception as e:
|
||||
LOG.error(e)
|
||||
LOG.error(e.message)
|
||||
current_time = time.time()
|
||||
for key in json_data:
|
||||
event_list = json_data[key]
|
||||
|
@ -97,31 +98,34 @@ class EventScheduler(Thread):
|
|||
|
||||
def run(self):
|
||||
while self.isRunning:
|
||||
# Remove events
|
||||
self.remove_events()
|
||||
# Fetch newly scheduled events
|
||||
self.fetch_new_events()
|
||||
# Update events
|
||||
self.update_events()
|
||||
|
||||
# Check all events
|
||||
for event in self.events:
|
||||
current_time = time.time()
|
||||
e = self.events[event]
|
||||
# Get scheduled times that has passed
|
||||
passed = [(t, r, d) for (t, r, d) in e if t <= current_time]
|
||||
# and remaining times that we're still waiting for
|
||||
remaining = [(t, r, d) for t, r, d in e if t > current_time]
|
||||
# Trigger registered methods
|
||||
for sched_time, repeat, data in passed:
|
||||
self.emitter.emit(Message(event, data))
|
||||
# if this is a repeated event add a new trigger time
|
||||
if repeat:
|
||||
remaining.append((sched_time + repeat, repeat, data))
|
||||
# update list of events
|
||||
self.events[event] = remaining
|
||||
self.check_state()
|
||||
time.sleep(0.5)
|
||||
|
||||
def check_state(self):
|
||||
# Remove events
|
||||
self.remove_events()
|
||||
# Fetch newly scheduled events
|
||||
self.fetch_new_events()
|
||||
# Update events
|
||||
self.update_events()
|
||||
|
||||
# Check all events
|
||||
for event in self.events:
|
||||
current_time = time.time()
|
||||
e = self.events[event]
|
||||
# Get scheduled times that has passed
|
||||
passed = [(t, r, d) for (t, r, d) in e if t <= current_time]
|
||||
# and remaining times that we're still waiting for
|
||||
remaining = [(t, r, d) for t, r, d in e if t > current_time]
|
||||
# Trigger registered methods
|
||||
for sched_time, repeat, data in passed:
|
||||
self.emitter.emit(Message(event, data))
|
||||
# if this is a repeated event add a new trigger time
|
||||
if repeat:
|
||||
remaining.append((sched_time + repeat, repeat, data))
|
||||
# update list of events
|
||||
self.events[event] = remaining
|
||||
|
||||
def schedule_event(self, event, sched_time, repeat=None, data=None):
|
||||
""" Send event to thread using thread safe queue. """
|
||||
data = data or {}
|
||||
|
|
|
@ -0,0 +1,70 @@
|
|||
import unittest
|
||||
import mock
|
||||
import time
|
||||
|
||||
from mycroft.skills.event_scheduler import EventScheduler
|
||||
|
||||
"""
|
||||
Test cases regarding the event scheduler.
|
||||
"""
|
||||
|
||||
|
||||
class TestEventScheduler(unittest.TestCase):
|
||||
@mock.patch('threading.Thread')
|
||||
@mock.patch('json.dump')
|
||||
@mock.patch('mycroft.skills.event_scheduler.open')
|
||||
def test_create(self, mock_open, mock_json_dump, mock_thread):
|
||||
"""
|
||||
Test creating and shutting down event_scheduler.
|
||||
"""
|
||||
mock_open.return_value = mock.MagicMock(spec=file)
|
||||
emitter = mock.MagicMock()
|
||||
es = EventScheduler(emitter)
|
||||
es.shutdown()
|
||||
self.assertEquals(mock_json_dump.call_args[0][0], {})
|
||||
|
||||
@mock.patch('threading.Thread')
|
||||
@mock.patch('json.dump')
|
||||
@mock.patch('mycroft.skills.event_scheduler.open')
|
||||
def test_add_remove(self, mock_open, mock_json_dump, mock_thread):
|
||||
"""
|
||||
Test add an event and then remove it.
|
||||
"""
|
||||
# Thread start is mocked so will not actually run the thread loop
|
||||
mock_open.return_value = mock.MagicMock(spec=file)
|
||||
emitter = mock.MagicMock()
|
||||
es = EventScheduler(emitter)
|
||||
|
||||
es.schedule_event('test', 90000000000, None)
|
||||
es.schedule_event('test-2', 90000000000, None)
|
||||
|
||||
es.check_state() # run one cycle
|
||||
self.assertTrue('test' in es.events)
|
||||
self.assertTrue('test-2' in es.events)
|
||||
|
||||
es.remove_event('test')
|
||||
es.check_state() # run one cycle
|
||||
self.assertTrue('test' not in es.events)
|
||||
self.assertTrue('test-2' in es.events)
|
||||
es.shutdown()
|
||||
|
||||
@mock.patch('threading.Thread')
|
||||
@mock.patch('json.load')
|
||||
@mock.patch('json.dump')
|
||||
@mock.patch('mycroft.skills.event_scheduler.open')
|
||||
def test_save(self, mock_open, mock_dump, mock_load, mock_thread):
|
||||
"""
|
||||
Test save functionality.
|
||||
"""
|
||||
mock_open.return_value = mock.MagicMock(spec=file)
|
||||
emitter = mock.MagicMock()
|
||||
es = EventScheduler(emitter)
|
||||
|
||||
es.schedule_event('test', 900000000000, None)
|
||||
es.schedule_event('test-repeat', 910000000000, 60)
|
||||
es.check_state()
|
||||
|
||||
es.shutdown()
|
||||
|
||||
self.assertEquals(mock_dump.call_args[0][0],
|
||||
{'test': [(900000000000, None, {})]})
|
Loading…
Reference in New Issue