Skip to content

Testing timezone enabled cron

February 14, 2007

My proof of concept for cron to understand timezones has moved to being closer to production code and I’m in the process of trying to get it put back in to Solaris. The biggest sticking point at the moment appears to be that the UNIX standards all say you can’t do this in a crontab file.

Meanwhile following Adam’s point that it’s tested or it’s broken I have started work on a test suite to test the new functionality in the blind optimism that a way around the standards can be found.

First I wrote a script that understands the five time fields used by cron and a timezone and can tell you if it is running when it should not. It is called crontest and can be run from cron like this:

15,45 * 1-18,20 2 * exec lang/sh/crontest 15,45 \* 1-18,20 2 \* Africa/Addis_Ababa

When it thinks things have gone wrong it prints an error with the process id and the parent process id so that it can be tied back to the entry in /var/cron/log.


Now I just need a crontab file that contains all the possible cron entries. Hmm that is not so easy. However if I can fill the crontab file with random entries I should get good coverage. So I have another script, crontab_create which generates random, but legal, crontab entries which call the crontest script. So I end up with a crontab that looks like this:


TZ=Asia/Tbilisi 42,50 0 1-25,27-28,30 1 * exec lang/sh/crontest 42,50 0 1-25,27-28,30 1 \* Asia/Tbilisi 37,45 0-21,23 1-20,22-23,25 * * exec lang/sh/crontest 37,45 0-21,23 1-20,22-23,25 \* \* Asia/Tbilisi 32,40 0-16,18-19,21 * 1 * exec lang/sh/crontest 32,40 0-16,18-19,21 \* 1 \* Asia/Tbilisi 27,35 * 1-10,12-13,15-21,23 1-11 * exec lang/sh/crontest 27,35 \* 1-10,12-13,15-21,23 1-11 \* Asia/Tbilisi 22,30,57,59 0-6,8-9,11-17,19 1-5,7-8,10-16,18-28,30 1-6,8-9,11 * exec lang/sh/crontest 22,30,57,59 0-6,8-9,11-17,19 1-5,7-8,10-16,18-28,30 1-6,8-9,11 \* Asia/Tbilisi TZ=Asia/Tehran 17,25,52,54-56 0-1,3-4,6-12,14 2-3,5-11,13-23,25 1,3-4,6 * exec lang/sh/crontest 17,25,52,54-56 0-1,3-4,6-12,14 2-3,5-11,13-23,25 1,3-4,6 \* Asia/Tehran 12,20,47,49-51 1-7,9-19,21 * * * exec lang/sh/crontest 12,20,47,49-51 1-7,9-19,21 \* \* \* Asia/Tehran 7,15,42,44-46 0-2,4-14,16 1,3-13,15-22,24,26-27,29 1-2,4 * exec lang/sh/crontest 7,15,42,44-46 0-2,4-14,16 1,3-13,15-22,24,26-27,29 1-2,4 \* Asia/Tehran 2,10,37,39-41 0-9,11-18,20,22 1-8,10-17,19,21-22,24 1-9,11 * exec lang/sh/crontest 2,10,37,39-41 0-9,11-18,20,22 1-8,10-17,19,21-22,24 1-9,11 \* Asia/Tehran 5,32,34-36 0-4,6-13,15,17-18,20 1-3,5-12,14,16-17,19 1-4,6 * exec lang/sh/crontest 5,32,34-36 0-4,6-13,15,17-18,20 1-3,5-12,14,16-17,19 1-4,6 \* Asia/Tehran TZ=Asia/Thimphu 0,27,29-31 1-8,10,12-13,15 1-7,9,11-12,14 * * exec lang/sh/crontest 0,27,29-31 1-8,10,12-13,15 1-7,9,11-12,14 \* \* Asia/Thimphu 22,24-26 * 1-2,4,6-7,9 1-3,5,7-8,10 * exec lang/sh/crontest 22,24-26 \* 1-2,4,6-7,9 1-3,5,7-8,10 \* Asia/Thimphu 17,19-21 0,2-3,5 1-2,4-26,28-30 2-3,5 * exec lang/sh/crontest 17,19-21 0,2-3,5 1-2,4-26,28-30 2-3,5 \* Asia/Thimphu 12,14-16 0-22 * * * exec lang/sh/crontest 12,14-16 0-22 \* \* \* Asia/Thimphu 7,9-11 * 1-16,18-20,22 1 * exec lang/sh/crontest 7,9-11 \* 1-16,18-20,22 1 \* Asia/Thimphu TZ=Asia/Tokyo 2,4-6,56,59 0-12,14-16,18 1-11,13-15,17 1 * exec lang/sh/crontest 2,4-6,56,59 0-12,14-16,18 1-11,13-15,17 1 \* Asia/Tokyo 0-1,51,54 0-7,9-11,13 1-6,8-10,12 1-7,9-11 * exec lang/sh/crontest 0-1,51,54 0-7,9-11,13 1-6,8-10,12 1-7,9-11 \* Asia/Tokyo 46,49,55 0-2,4-6,8 1,3-5,7 1-2,4-6,8 * exec lang/sh/crontest 46,49,55 0-2,4-6,8 1,3-5,7 1-2,4-6,8 \* Asia/Tokyo 41,44,50 0-1,3 2 1,3 * exec lang/sh/crontest 41,44,50 0-1,3 2 1,3 \* Asia/Tokyo 36,39,45 0 1 * * exec lang/sh/crontest 36,39,45 0 1 \* \* Asia/Tokyo TZ=Asia/Ulaanbaatar

I needed some tuning so it would not be starting more than 100 jobs in anyone minute or at least it would not every minute as cron would then delay some jobs which in turn throws up false positives. I now have it with 551 timezones and 2756 cron entries which. There is probably (certainly) an optimization on the script to generate the cron entries so that they only run in the current month or at least for the likely length of the test.


It has been running for 24 hours on my home server. I can see the entries run from the log and I’ve not had any email telling me things have been submitted at the wrong time. So I am reasonably happy. Just to prove that it does what I think it does I added a line were the arguments to the script did not match the time specification of an entry that is running. Sure enough I get email (the crontab entry I changed the 25 minute to 50):


Your "cron" job on pearson exec lang/sh/crontest 23,25 0-11,13-18,20 1-10,12-17,19 \* \* GMT  produced the following output:  17182:24396: Bad min: Should be 23,25 is 50:

This covers the easy cases to test that jobs that run run at the correct time. The harder part is to verify that every job that should run does run. Need to think that one through.

Advertisements

From → Solaris

Leave a Comment

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: