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.
|
Load json data with active events from json file.
|
||||||
"""
|
"""
|
||||||
if isfile(self.schedule_file):
|
if isfile(self.schedule_file):
|
||||||
|
json_data = {}
|
||||||
with open(self.schedule_file) as f:
|
with open(self.schedule_file) as f:
|
||||||
try:
|
try:
|
||||||
json_data = json.load(f)
|
json_data = json.load(f)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
LOG.error(e)
|
LOG.error(e.message)
|
||||||
current_time = time.time()
|
current_time = time.time()
|
||||||
for key in json_data:
|
for key in json_data:
|
||||||
event_list = json_data[key]
|
event_list = json_data[key]
|
||||||
|
@ -97,31 +98,34 @@ class EventScheduler(Thread):
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
while self.isRunning:
|
while self.isRunning:
|
||||||
# Remove events
|
self.check_state()
|
||||||
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
|
|
||||||
time.sleep(0.5)
|
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):
|
def schedule_event(self, event, sched_time, repeat=None, data=None):
|
||||||
""" Send event to thread using thread safe queue. """
|
""" Send event to thread using thread safe queue. """
|
||||||
data = data or {}
|
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