Commit 47b3be06 authored by Nicolas Wavrant's avatar Nicolas Wavrant

dcron: new parameter to get a random time, with a frequency of once a day

parent af5e9617
...@@ -26,6 +26,8 @@ ...@@ -26,6 +26,8 @@
############################################################################## ##############################################################################
import os import os
from random import randint
from slapos.recipe.librecipe import GenericBaseRecipe from slapos.recipe.librecipe import GenericBaseRecipe
from zc.buildout import UserError from zc.buildout import UserError
...@@ -54,21 +56,36 @@ class Recipe(GenericBaseRecipe): ...@@ -54,21 +56,36 @@ class Recipe(GenericBaseRecipe):
class Part(GenericBaseRecipe): class Part(GenericBaseRecipe):
def install(self): def _options(self, options):
try: periodicity = None
periodicity = self.options['frequency'] if options.get('frequency', '') != '':
except KeyError: periodicity = options['frequency']
periodicity = self.options['time'] elif 'time' in options:
periodicity = options['time']
try: try:
periodicity = systemd_to_cron(periodicity) periodicity = systemd_to_cron(periodicity)
except Exception: except Exception:
raise UserError("Invalid systemd calendar spec %r" % periodicity) raise UserError("Invalid systemd calendar spec %r" % periodicity)
if periodicity is None and self.isTrueValue(options.get('once-a-day', False)):
# Migration code, to force a random value for already instanciated softwares
previous_periodicity = self.getValueFromPreviousRun(self.name, 'periodicity')
if previous_periodicity in ("0 0 * * *", '', None):
periodicity = "%d %d * * *" % (randint(0, 59), randint(0, 23))
else:
periodicity = previous_periodicity
if periodicity is None:
raise UserError("Missing one of 'frequency', 'once-a-day' or 'time' parameter")
options['periodicity'] = periodicity
def install(self):
cron_d = self.options['cron-entries'] cron_d = self.options['cron-entries']
name = self.options['name'] name = self.options['name']
filename = os.path.join(cron_d, name) filename = os.path.join(cron_d, name)
with open(filename, 'w') as part: with open(filename, 'w') as part:
part.write('%s %s\n' % (periodicity, self.options['command'])) part.write('%s %s\n' % (self.options['periodicity'], self.options['command']))
return [filename] return [filename]
...@@ -138,4 +155,3 @@ def systemd_to_cron(spec): ...@@ -138,4 +155,3 @@ def systemd_to_cron(spec):
continue continue
raise ValueError raise ValueError
return ' '.join(spec) return ' '.join(spec)
import os
import sys
import unittest import unittest
from textwrap import dedent
from slapos.recipe import dcron
from slapos.recipe.dcron import systemd_to_cron from slapos.recipe.dcron import systemd_to_cron
class TestDcron(unittest.TestCase): class TestDcron(unittest.TestCase):
...@@ -36,3 +40,72 @@ class TestDcron(unittest.TestCase): ...@@ -36,3 +40,72 @@ class TestDcron(unittest.TestCase):
_("1-0"); _("1-32"); _("1-14/18") _("1-0"); _("1-32"); _("1-14/18")
_("24:0"); _("8/16:0") _("24:0"); _("8/16:0")
_("0:60"); _("0:15/45") _("0:60"); _("0:15/45")
def setUp(self):
self.installed_file = './.installed.cfg'
def tearDown(self):
if os.path.exists(self.installed_file):
os.unlink(self.installed_file)
def new_recipe(self, extra_options=None, **kw):
buildout = {
'buildout': {
'bin-directory': '',
'find-links': '',
'allow-hosts': '',
'develop-eggs-directory': '',
'eggs-directory': '',
'python': 'testpython',
'installed': '.installed.cfg',
},
'testpython': {
'executable': sys.executable,
},
'slap-connection': {
'computer-id': '',
'partition-id': '',
'server-url': '',
'software-release-url': '',
}
}
options = {
'cron-entries': '.cron',
'name': 'test',
'command': 'true',
}
if isinstance(extra_options, dict):
options.update(extra_options)
options.update(kw)
return dcron.Part(buildout=buildout, name='cron-entry-test', options=options)
def test_onceADayIsOverwrittenIfGivenFrequency(self):
parameter_dict = {'once-a-day': True}
recipe = self.new_recipe(parameter_dict)
random_periodicity = recipe.options['periodicity']
parameter_dict['frequency'] = '0 1 * * *'
recipe = self.new_recipe(parameter_dict)
new_periodicity = recipe.options['periodicity']
self.assertEqual(new_periodicity, '0 1 * * *')
self.assertNotEqual(random_periodicity, new_periodicity)
def test_periodicityNeverChangeIfOnceADay(self):
parameter_dict = {'once-a-day': True}
periodicity = None
for _ in range(5):
recipe = self.new_recipe(parameter_dict)
recipe_periodicity = recipe.options['periodicity']
if periodicity is not None:
self.assertEqual(periodicity, recipe_periodicity)
else:
periodicity = recipe_periodicity
with open(recipe.buildout['buildout']['installed'], 'w') as file:
file.write(dedent("""
[cron-entry-test]
periodicity = %s
""" % periodicity))
if __name__ == '__main__':
unittest.main()
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment