task handler unit test revamp & bugfix
revamped task handler unit tests found bug when a False persistent kwarg is passed to the add method. Resolved it. All evennia unit tests pass. Default run level and run level 2.
This commit is contained in:
parent
84193dd9a7
commit
99568148c6
2 changed files with 197 additions and 146 deletions
|
|
@ -67,7 +67,7 @@ class TaskHandlerTask:
|
||||||
d.pause()
|
d.pause()
|
||||||
|
|
||||||
def unpause(self):
|
def unpause(self):
|
||||||
"""Process all callbacks made since pause() was called."""
|
"""Unpause a task, run the task if it has passed delay time."""
|
||||||
d = self.deferred
|
d = self.deferred
|
||||||
if d:
|
if d:
|
||||||
d.unpause()
|
d.unpause()
|
||||||
|
|
@ -328,8 +328,9 @@ class TaskHandler(object):
|
||||||
|
|
||||||
# record the task to the tasks dictionary
|
# record the task to the tasks dictionary
|
||||||
persistent = kwargs.get("persistent", False)
|
persistent = kwargs.get("persistent", False)
|
||||||
if persistent:
|
if "persistent" in kwargs:
|
||||||
del kwargs["persistent"]
|
del kwargs["persistent"]
|
||||||
|
if persistent:
|
||||||
safe_args = []
|
safe_args = []
|
||||||
safe_kwargs = {}
|
safe_kwargs = {}
|
||||||
|
|
||||||
|
|
@ -358,10 +359,10 @@ class TaskHandler(object):
|
||||||
else:
|
else:
|
||||||
safe_kwargs[key] = value
|
safe_kwargs[key] = value
|
||||||
|
|
||||||
self.tasks[task_id] = (comp_time, callback, safe_args, safe_kwargs, True, None)
|
self.tasks[task_id] = (comp_time, callback, safe_args, safe_kwargs, persistent, None)
|
||||||
self.save()
|
self.save()
|
||||||
else: # this is a non-persitent task
|
else: # this is a non-persitent task
|
||||||
self.tasks[task_id] = (comp_time, callback, args, kwargs, True, None)
|
self.tasks[task_id] = (comp_time, callback, args, kwargs, persistent, None)
|
||||||
|
|
||||||
# defer the task
|
# defer the task
|
||||||
callback = self.do_task
|
callback = self.do_task
|
||||||
|
|
|
||||||
|
|
@ -323,163 +323,213 @@ class TestDelay(EvenniaTest):
|
||||||
Test utils.delay.
|
Test utils.delay.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def test_delay(self):
|
def setUp(self):
|
||||||
|
super().setUp()
|
||||||
# get a reference of TASK_HANDLER
|
# get a reference of TASK_HANDLER
|
||||||
timedelay = 5
|
self.timedelay = 5
|
||||||
global _TASK_HANDLER
|
global _TASK_HANDLER
|
||||||
if _TASK_HANDLER is None:
|
if _TASK_HANDLER is None:
|
||||||
from evennia.scripts.taskhandler import TASK_HANDLER as _TASK_HANDLER
|
from evennia.scripts.taskhandler import TASK_HANDLER as _TASK_HANDLER
|
||||||
_TASK_HANDLER.clock = task.Clock()
|
_TASK_HANDLER.clock = task.Clock()
|
||||||
self.char1.ndb.dummy_var = False
|
self.char1.ndb.dummy_var = False
|
||||||
# test a persistent deferral, that completes after delay time
|
|
||||||
t = utils.delay(timedelay, dummy_func, self.char1.dbref, persistent=True)
|
def tearDown(self):
|
||||||
# call the task early to test Task.call and TaskHandler.call_task
|
super().tearDown()
|
||||||
result = t.call()
|
_TASK_HANDLER.clear()
|
||||||
self.assertTrue(result)
|
|
||||||
del result
|
def test_call_early(self):
|
||||||
self.assertEqual(self.char1.ndb.dummy_var, 'dummy_func ran')
|
# call a task early with call
|
||||||
self.assertTrue(_TASK_HANDLER.active(t.get_id())) # test Task.get_id
|
for pers in (True, False):
|
||||||
self.assertTrue(t.active())
|
t = utils.delay(self.timedelay, dummy_func, self.char1.dbref, persistent=pers)
|
||||||
self.char1.ndb.dummy_var = False # Set variable to continue completion after delay time test.
|
result = t.call()
|
||||||
_TASK_HANDLER.clock.advance(timedelay) # make time pass
|
self.assertTrue(result)
|
||||||
self.assertTrue(t.called) # test Task.called property
|
self.assertEqual(self.char1.ndb.dummy_var, 'dummy_func ran')
|
||||||
self.assertEqual(self.char1.ndb.dummy_var, 'dummy_func ran')
|
self.assertTrue(t.exists())
|
||||||
self.char1.ndb.dummy_var = False
|
self.assertTrue(t.active())
|
||||||
# test a persistent deferral, that completes on a manual call
|
self.char1.ndb.dummy_var = False
|
||||||
t = utils.delay(timedelay, dummy_func, self.char1.dbref, persistent=True)
|
|
||||||
self.assertTrue(t.active())
|
def test_do_task(self):
|
||||||
result = t.do_task()
|
# call the task early with do_task
|
||||||
self.assertTrue(result)
|
for pers in (True, False):
|
||||||
self.assertFalse(t.exists())
|
t = utils.delay(self.timedelay, dummy_func, self.char1.dbref, persistent=pers)
|
||||||
_TASK_HANDLER.clock.advance(timedelay) # make time pass, important keep
|
# call the task early to test Task.call and TaskHandler.call_task
|
||||||
self.assertEqual(self.char1.ndb.dummy_var, 'dummy_func ran')
|
result = t.do_task()
|
||||||
self.char1.ndb.dummy_var = False
|
self.assertTrue(result)
|
||||||
# test a non persisten deferral, that completes after delay time.
|
self.assertEqual(self.char1.ndb.dummy_var, 'dummy_func ran')
|
||||||
|
self.assertFalse(t.exists())
|
||||||
|
self.char1.ndb.dummy_var = False
|
||||||
|
|
||||||
|
def test_deferred_call(self):
|
||||||
|
# wait for deferred to call
|
||||||
|
timedelay = self.timedelay
|
||||||
|
for pers in (False, True):
|
||||||
|
t = utils.delay(timedelay, dummy_func, self.char1.dbref, persistent=pers)
|
||||||
|
self.assertTrue(t.active())
|
||||||
|
_TASK_HANDLER.clock.advance(timedelay) # make time pass
|
||||||
|
self.assertEqual(self.char1.ndb.dummy_var, 'dummy_func ran')
|
||||||
|
self.assertFalse(t.exists())
|
||||||
|
self.char1.ndb.dummy_var = False
|
||||||
|
|
||||||
|
def test_short_deferred_call(self):
|
||||||
|
# wait for deferred to call with a very short time
|
||||||
|
timedelay = .1
|
||||||
|
for pers in (False, True):
|
||||||
|
t = utils.delay(timedelay, dummy_func, self.char1.dbref, persistent=pers)
|
||||||
|
self.assertTrue(t.active())
|
||||||
|
_TASK_HANDLER.clock.advance(timedelay) # make time pass
|
||||||
|
self.assertEqual(self.char1.ndb.dummy_var, 'dummy_func ran')
|
||||||
|
self.assertFalse(t.exists())
|
||||||
|
self.char1.ndb.dummy_var = False
|
||||||
|
|
||||||
|
def test_active(self):
|
||||||
|
timedelay = self.timedelay
|
||||||
t = utils.delay(timedelay, dummy_func, self.char1.dbref)
|
t = utils.delay(timedelay, dummy_func, self.char1.dbref)
|
||||||
|
self.assertTrue(_TASK_HANDLER.active(t.get_id()))
|
||||||
self.assertTrue(t.active())
|
self.assertTrue(t.active())
|
||||||
_TASK_HANDLER.clock.advance(timedelay) # make time pass
|
_TASK_HANDLER.clock.advance(timedelay) # make time pass
|
||||||
self.assertEqual(self.char1.ndb.dummy_var, 'dummy_func ran')
|
self.assertFalse(_TASK_HANDLER.active(t.get_id()))
|
||||||
self.char1.ndb.dummy_var = False
|
|
||||||
# test a non-persistent deferral, that completes on a manual call
|
|
||||||
t = utils.delay(timedelay, dummy_func, self.char1.dbref)
|
|
||||||
self.assertTrue(t.active())
|
|
||||||
result = t.do_task()
|
|
||||||
self.assertTrue(result)
|
|
||||||
self.assertFalse(t.exists())
|
|
||||||
_TASK_HANDLER.clock.advance(timedelay) # make time pass, important keep
|
|
||||||
self.assertEqual(self.char1.ndb.dummy_var, 'dummy_func ran')
|
|
||||||
self.char1.ndb.dummy_var = False
|
|
||||||
# test a non persisten deferral, with a short timedelay
|
|
||||||
t = utils.delay(.1, dummy_func, self.char1.dbref)
|
|
||||||
self.assertTrue(t.active())
|
|
||||||
_TASK_HANDLER.clock.advance(.1) # make time pass
|
|
||||||
self.assertEqual(self.char1.ndb.dummy_var, 'dummy_func ran')
|
|
||||||
self.char1.ndb.dummy_var = False
|
|
||||||
# test canceling a deferral.
|
|
||||||
# after this the task_id 1 remains used by this canceled but unused task
|
|
||||||
t = utils.delay(timedelay, dummy_func, self.char1.dbref)
|
|
||||||
self.assertTrue(t.active())
|
|
||||||
success = t.cancel()
|
|
||||||
self.assertFalse(t.active())
|
self.assertFalse(t.active())
|
||||||
self.assertTrue(success)
|
|
||||||
self.assertTrue(t.exists())
|
def test_called(self):
|
||||||
_TASK_HANDLER.clock.advance(timedelay) # make time pass
|
timedelay = self.timedelay
|
||||||
self.assertEqual(self.char1.ndb.dummy_var, False)
|
|
||||||
self.char1.ndb.dummy_var = False
|
|
||||||
# test removing an active task
|
|
||||||
t = utils.delay(timedelay, dummy_func, self.char1.dbref)
|
t = utils.delay(timedelay, dummy_func, self.char1.dbref)
|
||||||
self.assertTrue(t.active())
|
self.assertFalse(t.called)
|
||||||
success = t.remove()
|
|
||||||
self.assertFalse(t.active())
|
|
||||||
_TASK_HANDLER.clock.advance(timedelay) # make time pass
|
_TASK_HANDLER.clock.advance(timedelay) # make time pass
|
||||||
self.assertEqual(self.char1.ndb.dummy_var, False)
|
self.assertTrue(t.called)
|
||||||
self.assertFalse(t.exists())
|
|
||||||
self.char1.ndb.dummy_var = False
|
def test_cancel(self):
|
||||||
# test removing a canceled task
|
timedelay = self.timedelay
|
||||||
t = utils.delay(timedelay, dummy_func, self.char1.dbref)
|
for pers in (False, True):
|
||||||
self.assertTrue(t.active())
|
t = utils.delay(timedelay, dummy_func, self.char1.dbref, persistent=pers)
|
||||||
deferal_inst = t.get_deferred()
|
self.assertTrue(t.active())
|
||||||
deferal_inst.cancel()
|
success = t.cancel()
|
||||||
self.assertFalse(t.active())
|
self.assertFalse(t.active())
|
||||||
success = t.remove()
|
self.assertTrue(success)
|
||||||
_TASK_HANDLER.clock.advance(timedelay) # make time pass
|
self.assertTrue(t.exists())
|
||||||
self.assertEqual(self.char1.ndb.dummy_var, False)
|
_TASK_HANDLER.clock.advance(timedelay) # make time pass
|
||||||
self.assertFalse(t.exists())
|
self.assertEqual(self.char1.ndb.dummy_var, False)
|
||||||
self.char1.ndb.dummy_var = False
|
|
||||||
# test pause, paused and unpause
|
def test_remove(self):
|
||||||
t = utils.delay(timedelay, dummy_func, self.char1.dbref)
|
timedelay = self.timedelay
|
||||||
self.assertTrue(t.active())
|
for pers in (False, True):
|
||||||
t.pause()
|
t = utils.delay(timedelay, dummy_func, self.char1.dbref, persistent=pers)
|
||||||
self.assertTrue(t.paused)
|
self.assertTrue(t.active())
|
||||||
t.unpause()
|
success = t.remove()
|
||||||
self.assertFalse(t.paused)
|
self.assertTrue(success)
|
||||||
self.assertEqual(self.char1.ndb.dummy_var, False)
|
self.assertFalse(t.active())
|
||||||
t.pause()
|
self.assertFalse(t.exists())
|
||||||
_TASK_HANDLER.clock.advance(timedelay) # make time pass
|
_TASK_HANDLER.clock.advance(timedelay) # make time pass
|
||||||
self.assertEqual(self.char1.ndb.dummy_var, False)
|
self.assertEqual(self.char1.ndb.dummy_var, False)
|
||||||
t.unpause()
|
|
||||||
self.assertEqual(self.char1.ndb.dummy_var, 'dummy_func ran')
|
def test_remove_canceled(self):
|
||||||
self.char1.ndb.dummy_var = False
|
# remove a canceled task
|
||||||
# test automated removal of stale tasks.
|
timedelay = self.timedelay
|
||||||
t = utils.delay(timedelay, dummy_func, self.char1.dbref, persistent=True)
|
for pers in (False, True):
|
||||||
t.cancel()
|
t = utils.delay(timedelay, dummy_func, self.char1.dbref, persistent=pers)
|
||||||
self.assertFalse(t.active())
|
self.assertTrue(t.active())
|
||||||
_TASK_HANDLER.clock.advance(timedelay) # make time pass
|
success = t.cancel()
|
||||||
self.assertTrue(t.get_id() in _TASK_HANDLER.to_save)
|
self.assertTrue(success)
|
||||||
self.assertTrue(t.get_id() in _TASK_HANDLER.tasks)
|
self.assertTrue(t.exists())
|
||||||
|
self.assertFalse(t.active())
|
||||||
|
success = t.remove()
|
||||||
|
self.assertTrue(success)
|
||||||
|
self.assertFalse(t.exists())
|
||||||
|
_TASK_HANDLER.clock.advance(timedelay) # make time pass
|
||||||
|
self.assertEqual(self.char1.ndb.dummy_var, False)
|
||||||
|
|
||||||
|
def test_pause_unpause(self):
|
||||||
|
# remove a canceled task
|
||||||
|
timedelay = self.timedelay
|
||||||
|
for pers in (False, True):
|
||||||
|
t = utils.delay(timedelay, dummy_func, self.char1.dbref, persistent=pers)
|
||||||
|
self.assertTrue(t.active())
|
||||||
|
t.pause()
|
||||||
|
self.assertTrue(t.paused)
|
||||||
|
t.unpause()
|
||||||
|
self.assertFalse(t.paused)
|
||||||
|
self.assertEqual(self.char1.ndb.dummy_var, False)
|
||||||
|
t.pause()
|
||||||
|
_TASK_HANDLER.clock.advance(timedelay) # make time pass
|
||||||
|
self.assertEqual(self.char1.ndb.dummy_var, False)
|
||||||
|
t.unpause()
|
||||||
|
self.assertEqual(self.char1.ndb.dummy_var, 'dummy_func ran')
|
||||||
|
self.char1.ndb.dummy_var = False
|
||||||
|
|
||||||
|
def test_auto_stale_task_removal(self):
|
||||||
|
# automated removal of stale tasks.
|
||||||
|
timedelay = self.timedelay
|
||||||
|
for pers in (False, True):
|
||||||
|
t = utils.delay(timedelay, dummy_func, self.char1.dbref, persistent=pers)
|
||||||
|
t.cancel()
|
||||||
|
self.assertFalse(t.active())
|
||||||
|
_TASK_HANDLER.clock.advance(timedelay) # make time pass
|
||||||
|
if pers:
|
||||||
|
self.assertTrue(t.get_id() in _TASK_HANDLER.to_save)
|
||||||
|
self.assertTrue(t.get_id() in _TASK_HANDLER.tasks)
|
||||||
|
# Make task handler's now time, after the stale timeout
|
||||||
|
_TASK_HANDLER._now = datetime.now() + timedelta(seconds=_TASK_HANDLER.stale_timeout + timedelay + 1)
|
||||||
# add a task to test automatic removal
|
# add a task to test automatic removal
|
||||||
_TASK_HANDLER._now = datetime.now() + timedelta(seconds=_TASK_HANDLER.stale_timeout + 6) # task handler time to 6 seconds after stale timeout
|
t2 = utils.delay(timedelay, dummy_func, self.char1.dbref)
|
||||||
t2 = utils.delay(timedelay, dummy_func, self.char1.dbref, persistent=True)
|
if pers:
|
||||||
self.assertFalse(t.get_id() in _TASK_HANDLER.to_save)
|
self.assertFalse(t.get_id() in _TASK_HANDLER.to_save)
|
||||||
self.assertFalse(t.get_id() in _TASK_HANDLER.tasks)
|
self.assertFalse(t.get_id() in _TASK_HANDLER.tasks)
|
||||||
self.assertEqual(self.char1.ndb.dummy_var, False)
|
self.assertEqual(self.char1.ndb.dummy_var, False)
|
||||||
# test manual cleanup
|
_TASK_HANDLER.clear()
|
||||||
t2.cancel()
|
|
||||||
_TASK_HANDLER.clock.advance(timedelay) # advance twisted reactor time past callback time
|
def test_manual_stale_task_removal(self):
|
||||||
_TASK_HANDLER._now = datetime.now() + timedelta(seconds=30) # set TaskHandler's time to 30 seconnds from now
|
# manual removal of stale tasks.
|
||||||
# test before stale_timeout time
|
timedelay = self.timedelay
|
||||||
_TASK_HANDLER.clean_stale_tasks() # cleanup of stale tasks in in the save method
|
for pers in (False, True):
|
||||||
# still in the task handler because stale timeout has not been reached
|
t = utils.delay(timedelay, dummy_func, self.char1.dbref, persistent=pers)
|
||||||
self.assertTrue(t2.get_id() in _TASK_HANDLER.to_save)
|
t.cancel()
|
||||||
self.assertTrue(t2.get_id() in _TASK_HANDLER.tasks)
|
self.assertFalse(t.active())
|
||||||
# advance past stale timeout
|
_TASK_HANDLER.clock.advance(timedelay) # make time pass
|
||||||
_TASK_HANDLER._now = datetime.now() + timedelta(seconds=_TASK_HANDLER.stale_timeout + 6) # task handler time to 6 seconds after stale timeout
|
if pers:
|
||||||
_TASK_HANDLER.clean_stale_tasks() # cleanup of stale tasks in in the save method
|
self.assertTrue(t.get_id() in _TASK_HANDLER.to_save)
|
||||||
self.assertFalse(t2.get_id() in _TASK_HANDLER.to_save)
|
self.assertTrue(t.get_id() in _TASK_HANDLER.tasks)
|
||||||
self.assertFalse(t2.get_id() in _TASK_HANDLER.tasks)
|
# Make task handler's now time, after the stale timeout
|
||||||
self.char1.ndb.dummy_var = False
|
_TASK_HANDLER._now = datetime.now() + timedelta(seconds=_TASK_HANDLER.stale_timeout + timedelay + 1)
|
||||||
_TASK_HANDLER._now = False
|
_TASK_HANDLER.clean_stale_tasks() # cleanup of stale tasks in in the save method
|
||||||
# if _TASK_HANDLER.stale_timeout is 0 or less, automatic cleanup should not run
|
if pers:
|
||||||
|
self.assertFalse(t.get_id() in _TASK_HANDLER.to_save)
|
||||||
|
self.assertFalse(t.get_id() in _TASK_HANDLER.tasks)
|
||||||
|
self.assertEqual(self.char1.ndb.dummy_var, False)
|
||||||
|
_TASK_HANDLER.clear()
|
||||||
|
|
||||||
|
def test_disable_stale_removal(self):
|
||||||
|
# manual removal of stale tasks.
|
||||||
|
timedelay = self.timedelay
|
||||||
_TASK_HANDLER.stale_timeout = 0
|
_TASK_HANDLER.stale_timeout = 0
|
||||||
t = utils.delay(timedelay, dummy_func, self.char1.dbref, persistent=True)
|
for pers in (False, True):
|
||||||
t.cancel()
|
t = utils.delay(timedelay, dummy_func, self.char1.dbref, persistent=pers)
|
||||||
self.assertFalse(t.active())
|
t.cancel()
|
||||||
_TASK_HANDLER.clock.advance(timedelay) # advance twisted's reactor past callback time
|
self.assertFalse(t.active())
|
||||||
self.assertTrue(t.get_id() in _TASK_HANDLER.to_save)
|
_TASK_HANDLER.clock.advance(timedelay) # make time pass
|
||||||
self.assertTrue(t.get_id() in _TASK_HANDLER.tasks)
|
if pers:
|
||||||
# add a task to test automatic removal
|
self.assertTrue(t.get_id() in _TASK_HANDLER.to_save)
|
||||||
_TASK_HANDLER._now = datetime.now() + timedelta(seconds=_TASK_HANDLER.stale_timeout + 6) # task handler time to 6 seconds after stale timeout
|
self.assertTrue(t.get_id() in _TASK_HANDLER.tasks)
|
||||||
t2 = utils.delay(timedelay, dummy_func, self.char1.dbref, persistent=True)
|
# Make task handler's now time, after the stale timeout
|
||||||
self.assertTrue(t.get_id() in _TASK_HANDLER.to_save)
|
_TASK_HANDLER._now = datetime.now() + timedelta(seconds=_TASK_HANDLER.stale_timeout + timedelay + 1)
|
||||||
self.assertTrue(t.get_id() in _TASK_HANDLER.tasks)
|
t2 = utils.delay(timedelay, dummy_func, self.char1.dbref)
|
||||||
self.assertEqual(self.char1.ndb.dummy_var, False)
|
if pers:
|
||||||
_TASK_HANDLER.clear()
|
self.assertTrue(t.get_id() in _TASK_HANDLER.to_save)
|
||||||
self.char1.ndb.dummy_var = False
|
self.assertTrue(t.get_id() in _TASK_HANDLER.tasks)
|
||||||
_TASK_HANDLER._now = False
|
self.assertEqual(self.char1.ndb.dummy_var, False)
|
||||||
# replicate a restart
|
# manual removal should still work
|
||||||
_TASK_HANDLER.clear()
|
_TASK_HANDLER.clean_stale_tasks() # cleanup of stale tasks in in the save method
|
||||||
_TASK_HANDLER.save()
|
if pers:
|
||||||
self.assertFalse(_TASK_HANDLER.tasks)
|
self.assertFalse(t.get_id() in _TASK_HANDLER.to_save)
|
||||||
self.assertFalse(_TASK_HANDLER.to_save)
|
self.assertFalse(t.get_id() in _TASK_HANDLER.tasks)
|
||||||
# create a persistent task.
|
_TASK_HANDLER.clear()
|
||||||
t = utils.delay(timedelay, dummy_func, self.char1.dbref, persistent=True)
|
|
||||||
_TASK_HANDLER.save()
|
def test_server_restart(self):
|
||||||
_TASK_HANDLER.clear(False) # remove all tasks, do not save this change.
|
# emulate a server restart
|
||||||
|
timedelay = self.timedelay
|
||||||
|
utils.delay(timedelay, dummy_func, self.char1.dbref, persistent=True)
|
||||||
|
_TASK_HANDLER.clear(False) # remove all tasks from task handler, do not save this change.
|
||||||
_TASK_HANDLER.clock.advance(timedelay) # advance twisted reactor time past callback time
|
_TASK_HANDLER.clock.advance(timedelay) # advance twisted reactor time past callback time
|
||||||
self.assertEqual(self.char1.ndb.dummy_var, False) # task has not run
|
self.assertEqual(self.char1.ndb.dummy_var, False) # task has not run
|
||||||
_TASK_HANDLER.load()
|
_TASK_HANDLER.load() # load persistent tasks from database.
|
||||||
_TASK_HANDLER.create_delays()
|
_TASK_HANDLER.create_delays() # create new deffered instances from persistent tasks
|
||||||
_TASK_HANDLER.clock.advance(timedelay) # Clock must advance to trigger, even if past timedelay
|
_TASK_HANDLER.clock.advance(timedelay) # Clock must advance to trigger, even if past timedelay
|
||||||
self.assertEqual(self.char1.ndb.dummy_var, 'dummy_func ran')
|
self.assertEqual(self.char1.ndb.dummy_var, 'dummy_func ran')
|
||||||
_TASK_HANDLER.clear()
|
|
||||||
self.char1.ndb.dummy_var = False
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue