Skip to content

Commit

Permalink
dcron: new parameter to get a random time, with a frequency of once a…
Browse files Browse the repository at this point in the history
… day
  • Loading branch information
Sebatyne committed Oct 21, 2016
1 parent 8787716 commit 2b0c61d
Show file tree
Hide file tree
Showing 2 changed files with 96 additions and 7 deletions.
30 changes: 23 additions & 7 deletions slapos/recipe/dcron.py
Expand Up @@ -26,6 +26,8 @@
##############################################################################
import os

from random import randint

from slapos.recipe.librecipe import GenericBaseRecipe
from zc.buildout import UserError

Expand Down Expand Up @@ -54,21 +56,36 @@ def install(self):

class Part(GenericBaseRecipe):

def install(self):
try:
periodicity = self.options['frequency']
except KeyError:
periodicity = self.options['time']
def _options(self, options):
periodicity = None
if options.get('frequency', '') != '':
periodicity = options['frequency']
elif 'time' in options:
periodicity = options['time']
try:
periodicity = systemd_to_cron(periodicity)
except Exception:
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']
name = self.options['name']
filename = os.path.join(cron_d, name)

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]

Expand Down Expand Up @@ -138,4 +155,3 @@ def systemd_to_cron(spec):
continue
raise ValueError
return ' '.join(spec)

73 changes: 73 additions & 0 deletions slapos/test/recipe/test_dcron.py
@@ -1,4 +1,8 @@
import os
import sys
import unittest
from textwrap import dedent
from slapos.recipe import dcron
from slapos.recipe.dcron import systemd_to_cron

class TestDcron(unittest.TestCase):
Expand Down Expand Up @@ -36,3 +40,72 @@ def _(systemd):
_("1-0"); _("1-32"); _("1-14/18")
_("24:0"); _("8/16:0")
_("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()

0 comments on commit 2b0c61d

Please sign in to comment.