diff --git a/Makefile.am b/Makefile.am index 9503c04..459931e 100644 --- a/Makefile.am +++ b/Makefile.am @@ -65,6 +65,7 @@ handwritten_tests = \ t/builtinfw_query.pl \ t/get_ip_from_if.pl \ t/geturl_connectivity.pl \ + t/interval_expired.pl \ t/is-and-extract-ipv4.pl \ t/is-and-extract-ipv6.pl \ t/is-and-extract-ipv6-global.pl \ diff --git a/ddclient.in b/ddclient.in index f6bf5ae..c0fa54e 100755 --- a/ddclient.in +++ b/ddclient.in @@ -104,7 +104,7 @@ my $programd = $0; $programd =~ s%^.*/%%; my $program = $programd; $program =~ s/d$//; -my $now = time; +our $now = time; my $hostname = hostname(); # subst_var(subst, default) returns subst unless it looks like @foo@ in which case it returns @@ -140,7 +140,8 @@ $ENV{'PATH'} = (exists($ENV{PATH}) ? "$ENV{PATH}:" : "") . "/sbin:/usr/sbin:/bin our %globals; our %config; -my ($result, %cache); +our %cache; +my $result; my $saved_cache; my %saved_opt; my $daemon; @@ -2465,6 +2466,8 @@ sub interval { $value = $1 * 60*60; } elsif ($value =~ /^(\d+)(days|d)/i) { $value = $1 * 60*60*24; + } elsif ($value =~ qr/^(?:inf(?:init[ye])?|indefinite(?:ly)?|never|forever|always)$/i) { + $value = 'inf'; } elsif ($value !~ /^\d+$/) { $value = undef; } @@ -2473,6 +2476,7 @@ sub interval { sub interval_expired { my ($host, $time, $interval) = @_; + return 0 if ($config{$host}{$interval} // 0) == 'inf'; return 1 if !exists $cache{$host}; return 1 if !exists $cache{$host}{$time} || !$cache{$host}{$time}; return 1 if !exists $config{$host}{$interval} || !$config{$host}{$interval}; diff --git a/t/interval_expired.pl b/t/interval_expired.pl new file mode 100644 index 0000000..1043dea --- /dev/null +++ b/t/interval_expired.pl @@ -0,0 +1,51 @@ +use Test::More; +SKIP: { eval { require Test::Warnings; } or skip($@, 1); } +eval { require 'ddclient'; } or BAIL_OUT($@); + +my $h = 't/interval_expired.pl'; + +my $default_now = 1000000000; + +my @test_cases = ( + { + interval => 'inf', + want => 0, + }, + { + now => 'inf', + interval => 'inf', + want => 0, + }, + { + cache => '-inf', + interval => 'inf', + want => 0, + }, + { + cache => undef, # Falsy cache value. + interval => 'inf', + want => 0, + }, + { + now => 0, + cache => 0, # Different kind of falsy cache value. + interval => 'inf', + want => 0, + }, +); + +for my $tc (@test_cases) { + $tc->{now} //= $default_now; + # For convenience, $tc->{cache} is an offset from $tc->{now}, not an absolute time.. + my $cachetime = $tc->{now} + $tc->{cache} if defined($tc->{cache}); + $ddclient::config{$h} = {'interval' => $tc->{interval}}; + %ddclient::config if 0; # suppress spurious warning "Name used only once: possible typo" + $ddclient::cache{$h} = {'cached-time' => $cachetime} if defined($cachetime); + %ddclient::cache if 0; # suppress spurious warning "Name used only once: possible typo" + $ddclient::now = $tc->{now}; + $ddclient::now if 0; # suppress spurious warning "Name used only once: possible typo" + my $desc = "now=$tc->{now}, cache=${\($cachetime // 'undef')}, interval=$tc->{interval}"; + is(ddclient::interval_expired($h, 'cached-time', 'interval'), $tc->{want}, $desc); +} + +done_testing();