From 33d5f2fc44ed7d9c20171e6f199ca496186bc80b Mon Sep 17 00:00:00 2001 From: Patrik Dufresne Date: Thu, 12 Apr 2018 14:43:13 -0400 Subject: [PATCH] Make the DeamonPlugin more robust When the execution time of a plugin is miss configure, the plugin is not running. With this commit, will default to daily execution at '23:00' and pring an error message. --- rdiffweb/plugins/remove_older/__init__.py | 4 +- rdiffweb/plugins/set_encoding/__init__.py | 4 +- rdiffweb/rdw_plugin.py | 51 +++++++++++++---------- rdiffweb/tests/test_rdw_plugins.py | 39 ++++++++++++++++- 4 files changed, 69 insertions(+), 29 deletions(-) diff --git a/rdiffweb/plugins/remove_older/__init__.py b/rdiffweb/plugins/remove_older/__init__.py index c3ad1fb9..dc419fcf 100644 --- a/rdiffweb/plugins/remove_older/__init__.py +++ b/rdiffweb/plugins/remove_older/__init__.py @@ -34,9 +34,7 @@ from rdiffweb import rdw_spider_repos, page_main, librdiff from rdiffweb.dispatch import poppath from rdiffweb.i18n import ugettext as _ from rdiffweb.page_main import MainPage -from rdiffweb.rdw_plugin import IPreferencesPanelProvider, ITemplateFilterPlugin, \ - IDeamonPlugin, JobPlugin - +from rdiffweb.rdw_plugin import IPreferencesPanelProvider, ITemplateFilterPlugin, JobPlugin _logger = logging.getLogger(__name__) diff --git a/rdiffweb/plugins/set_encoding/__init__.py b/rdiffweb/plugins/set_encoding/__init__.py index 1cf42931..d9928039 100644 --- a/rdiffweb/plugins/set_encoding/__init__.py +++ b/rdiffweb/plugins/set_encoding/__init__.py @@ -35,9 +35,7 @@ from rdiffweb import rdw_spider_repos, page_main, librdiff from rdiffweb.dispatch import poppath from rdiffweb.i18n import ugettext as _ from rdiffweb.page_main import MainPage -from rdiffweb.rdw_plugin import IPreferencesPanelProvider, ITemplateFilterPlugin, \ - IDeamonPlugin - +from rdiffweb.rdw_plugin import IPreferencesPanelProvider, ITemplateFilterPlugin _logger = logging.getLogger(__name__) diff --git a/rdiffweb/rdw_plugin.py b/rdiffweb/rdw_plugin.py index ba0bf96e..b6d24bfe 100644 --- a/rdiffweb/rdw_plugin.py +++ b/rdiffweb/rdw_plugin.py @@ -31,14 +31,13 @@ import os from pkg_resources import working_set, Environment import pkg_resources import sys +import time from rdiffweb.dispatch import static - # Define logger for this module logger = logging.getLogger(__name__) - PluginInfo = namedtuple( 'PluginInfo', ['name', 'version', 'author', 'description', 'path', 'enabled', 'url', 'copyright']) @@ -430,12 +429,11 @@ class IDeamonPlugin(IRdiffwebPlugin): """ CATEGORY = "Daemon" - @property - def deamon_frequency(self): - """ - Return the frequency of the deamon plugin in seconds. - """ - raise NotImplementedError("frequency is not implemented") + """ + Return the frequency in seconds of execution for this demaon plugin. Default: 60 seconds. + This value cannot be changed once the plugin is started. + """ + deamon_frequency = 60 def deamon_run(self): """ @@ -451,35 +449,44 @@ class JobPlugin(IDeamonPlugin): Sub class should implement `job_execution_time` and `job_run`. """ - deamon_frequency = 300 - job_execution_time = '23:00' _next_execution_time = None def deamon_run(self): - # Determine the next execution time. - if not self._next_execution_time: - self._next_execution_time = self._compute_next_execution_time() - - # Check if task should be run. - now = datetime.datetime.now() - if now < self._next_execution_time: - return - + self._wait() # Run job. try: self.job_run() finally: self._next_execution_time = None - def _compute_next_execution_time(self): + def job_run(self): + """ + Sub-class should implement this function. + """ + raise NotImplementedError("job_run is not implemented") + + def _wait(self): + """ + Sleep until time to execute the job. + """ + now = datetime.datetime.now() + t = self._get_next_execution_time() + time.sleep(t - now) + + def _get_next_execution_time(self): """ Return a date time representing the next execution time. """ + try: + time_str = self.job_execution_time + exec_time = datetime.datetime.strptime(time_str, '%H:%M') + except: + logger.error("invalid execution time [%s], check your config. Using default value.", self.job_execution_time) + exec_time = datetime.datetime.strptime("23:00", '%H:%M') + now = datetime.datetime.now() - time_str = self.job_execution_time - exec_time = datetime.datetime.strptime(time_str, '%H:%M') exec_time = now.replace(hour=exec_time.hour, minute=exec_time.minute, second=0, microsecond=0) if exec_time < now: exec_time = exec_time.replace(day=exec_time.day + 1) diff --git a/rdiffweb/tests/test_rdw_plugins.py b/rdiffweb/tests/test_rdw_plugins.py index 21d07d84..612b73fd 100644 --- a/rdiffweb/tests/test_rdw_plugins.py +++ b/rdiffweb/tests/test_rdw_plugins.py @@ -23,10 +23,13 @@ Created on Jan 29, 2015 from __future__ import unicode_literals +import datetime +from mock.mock import Mock, MagicMock import unittest +from rdiffweb import rdw_plugin from rdiffweb.rdw_config import Configuration -from rdiffweb.rdw_plugin import PluginManager +from rdiffweb.rdw_plugin import PluginManager, JobPlugin class PluginManagerTest(unittest.TestCase): @@ -51,6 +54,40 @@ class PluginManagerTest(unittest.TestCase): self.assertEqual('GPLv3', plugin_info.copyright) +class JobPluginTest(unittest.TestCase): + + def test_get_next_execution_time(self): + """ + Check JobPLugin execution time. + """ + p = JobPlugin() + p.job_execution_time = '2:00' + t = p._get_next_execution_time() + self.assertIsInstance(t, datetime.datetime) + + def test_get_next_execution_time_invalid(self): + """ + Check JobPLugin execution time with invalid value. + """ + p = JobPlugin() + p.job_execution_time = '390' + t1 = p._get_next_execution_time() + p.job_execution_time = '23:00' + t2 = p._get_next_execution_time() + self.assertEqual(t1, t2) + + def test_deamon_run(self): + """ + Check JobPlugin execution. + """ + rdw_plugin.time.sleep = MagicMock() + p = JobPlugin() + p.job_execution_time = '23:00' + p.job_run = lambda: "c" + p.deamon_run() + assert rdw_plugin.time.sleep.called + + if __name__ == "__main__": # import sys;sys.argv = ['', 'Test.testName'] unittest.main() -- GitLab