Test::Recent - check a time is recent
use Test::More; use Test::Recent qw(recent); # check things happened in the last ten seconds recent DateTime->now, "now is recent!"; recent "2012-12-23 00:00:00", "end of mayan calendar happened recently?"; # check things happened in the last hour recent "2012-12-23 00:00:00", DateTime::Duration->new( hours => 1 ), "mayan"; recent "2012-12-23 00:00:00", "1 hour", "mayan"
Simple module to check things happened recently.
These are exported on demand or may be called fully qualified
Tests (using the Test::Builder framework) if the time occurred within the duration ago from the current time. If no duration is passed, ten seconds is assumed.
Returns true if and only if the time occurred within the duration ago from the current time.
This module supports the following things being passed in as a date and time:
i.e. anything that DateTime::Format::ISO8601 can parse
i.e. something of the form YYYY-MM-DD HH:MM:SS.ssssss+TZ
YYYY-MM-DD HH:MM:SS.ssssss+TZ
Older versions of this module used DateTimeX::Easy to parse the datetime, but this proved to be unreliable.
By default Test::Recent fails any timestamp that comes from the future as not being recent, which is sensible behavior if you expect the timestamps to be generated on the same machine as you're running the test on.
However, there are several situations where this might not be what you want.
If your network is faster than the clock drift between the machine you're running the test on and the machine (e.g. the database server) that's creating the timestamp then you might get future timestamps.
Some situations can result in creating a timestamp from the future due to rounding errors. For example executing this on postgresql:
SELECT EXTRACT(epoch FROM current_timestamp)::integer;
Will give you a timestamp in the future 50% of the time.
There's two things you can do:
Instead of passing just a single duration, you can pass an arrayref containing two durations:
recent $datetime, [ 10, 5 ], "is within 10 sec ago, or 5 secs from now"; recent $datatime, [ DateTime::Duration->new( seconds => 10 ), DateTime::Duration->new( seconds => 5 ), ], "is within 10 sec ago, or 5 secs from now"; occured_within_ago $datetime, [ 10, 5 ] or die "boom!"; occured_within_ago $datatime, [ DateTime::Duration->new( seconds => 10 ), DateTime::Duration->new( seconds => 5 ), ] or die "boom";
You can set a global variable that will always allow so much into the future:
local $Test::Recent::future_duration = 5; recent $datetime, 10, "is within 10 sec ago, or 5 secs from now"; local $Test::Recent::future_duration = DateTime::Duration->new( seconds => 5 ); recent $datetime, 10, "is within 10 sec ago, or 5 secs from now";
Sometimes you want someone else's concept of now. For example, you might want to pull back the time from the database server and compare against that rather than your own local clock.
This can be done by setting the $Test::Recent::RelativeTo variable. For safety's sake, this should probably be done with local:
$Test::Recent::RelativeTo
{ local $Test::Recent::RelativeTo = $dbh->selectcol_arrayref("SELECT NOW()")->[0]; recent($time); }
You can set $Test::Recent::RelativeTo to anything that Test::Recent can parse.
Written by Mark Fowler <mark@twoshortplanks.com>
Copyright OmniTI 2012. All Rights Reserved. Copyright Circonus 2014. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
This module ignores sub-seconds. This is primarily because the current implementation of DateTime's now method does not return nanoseconds, meaning that technically now returns a time that is in the past and might occur before a timestamp you hand in that contained nanoseconds (and therefore would erroneously be not concidered "recent")
now
Bugs should be reported via this distribution's CPAN RT queue. This can be found at https://rt.cpan.org/Dist/Display.html?Test-Recent
You can also address issues by forking this distribution on github and sending pull requests. It can be found at http://github.com/2shortplanks/Test-Recent
In order not to depend on another DateTime library, this module converts postgres style TIMESTAMP WITH TIME ZONE by using a regular expression and simply ignoring microseconds. This potentially introduces a one second inaccuracy in the recent handling.
DateTime::Format::ISO8601, Time::Duration::Parse
To install Test::Recent, copy and paste the appropriate command in to your terminal.
cpanm
cpanm Test::Recent
CPAN shell
perl -MCPAN -e shell install Test::Recent
For more information on module installation, please visit the detailed CPAN module installation guide.