diff --git a/cronwrap b/cronwrap index 8892e89..6e4c2d4 100755 --- a/cronwrap +++ b/cronwrap @@ -7,6 +7,7 @@ use File::Path; use Getopt::Long; use Pod::Usage; use Data::Dumper; +use Sys::Hostname; # Digest::SHA supports SHA-1 and SHA-2, but alas Red Hat Enterprise only comes # with Digest::SHA1 use Digest::SHA1; @@ -31,6 +32,8 @@ my $result = GetOptions(\%options, # See below __END__ for usage message in POD format pod2usage(1) if $options{help}; +pod2usage(1) if defined $options{suppress} && $options{suppress} <= 0; +pod2usage(1) if defined $options{jitter} && $options{jitter} <= 0; pod2usage(-exitstatus => 0, -verbose => 2) if $options{man}; # Anything leftover in @ARGV is the job command and arguments @@ -77,6 +80,22 @@ if (! -f $cmdfile) close $cmdfh; } +# +# Jitter +# + +if ($options{jitter}) +{ + # Seed the random number generator with the hostname of this box so that + # we get a consistent random number. We want to run the registration at a + # consistent time on each individual box, but randomize the runs across + # the environment. + srand(hex(substr(Digest::SHA1->sha1_hex(hostname()), -8))); + + # Option is specified in minutes, sleep expects seconds + sleep(int(rand($options{jitter} * 60))); +} + # # Overlap protection # diff --git a/t/jitter.t b/t/jitter.t index aab2f1b..0a9b3db 100644 --- a/t/jitter.t +++ b/t/jitter.t @@ -21,13 +21,13 @@ $number_of_tests_run++; # Ensure that the argument must be a positive integer # -system('./cronwrap --jitter bogus > /dev/null 2>&1'); +system('./cronwrap --jitter bogus true > /dev/null 2>&1'); isnt($?, 0, '--jitter rejects string'); $number_of_tests_run++; -system('./cronwrap --jitter 0 > /dev/null 2>&1'); +system('./cronwrap --jitter 0 true > /dev/null 2>&1'); isnt($?, 0, '--jitter rejects 0'); $number_of_tests_run++; -system('./cronwrap --jitter -1 > /dev/null 2>&1'); +system('./cronwrap --jitter -1 true > /dev/null 2>&1'); isnt($?, 0, '--jitter rejects -1'); $number_of_tests_run++; @@ -37,13 +37,15 @@ $number_of_tests_run++; # # -# However, we do expect the jitter to be consistent on any given machine. -# That we can test +# However, we do expect the jitter to be consistent on any given machine. That +# we can test. One minute (--jitter 1) is good enough for testing as cronwrap +# actually sleeps for a random number of seconds, so even with one minute of +# jitter cronwrap will sleep anywhere from 0-59 seconds. # # Time one run my $start = time; -system('./cronwrap --jitter 5 true'); +system('./cronwrap --jitter 1 true'); my $end = time; my $elapsed = $end - $start; @@ -52,7 +54,7 @@ my $elapsed = $end - $start; foreach (1, 2) { my $start = time; - system('./cronwrap --jitter 15 true'); + system('./cronwrap --jitter 1 true'); my $end = time; my $test_elapsed = $end - $start; diff --git a/t/suppress.t b/t/suppress.t index 6b7c52e..5670b21 100644 --- a/t/suppress.t +++ b/t/suppress.t @@ -23,13 +23,13 @@ $number_of_tests_run++; # Ensure that the argument must be a positive integer # -system('./cronwrap --suppress bogus > /dev/null 2>&1'); +system('./cronwrap --suppress bogus true > /dev/null 2>&1'); isnt($?, 0, '--suppress rejects string'); $number_of_tests_run++; -system('./cronwrap --suppress 0 > /dev/null 2>&1'); +system('./cronwrap --suppress 0 true > /dev/null 2>&1'); isnt($?, 0, '--suppress rejects 0'); $number_of_tests_run++; -system('./cronwrap --suppress -1 > /dev/null 2>&1'); +system('./cronwrap --suppress -1 true > /dev/null 2>&1'); isnt($?, 0, '--suppress rejects -1'); $number_of_tests_run++;