CGI/Perl Guide | Learning Center | Forums | Advertise | Login
Site Search: in

  Main Index MAIN
INDEX
Search Posts SEARCH
POSTS
Who's Online WHO'S
ONLINE
Log in LOG
IN

Home: Perl Programming Help: Intermediate:
Artificial System Clock (time machine for testing)

 



JohnBoy
New User

Nov 10, 2008, 1:58 PM

Post #1 of 3 (773 views)
Artificial System Clock (time machine for testing) Can't Post

Hello. I would like to introduce the concept of an Artificial System Clock (ASC). For a detailed explanation of ASCs, visit http://www.timechannels.com

In a language like Java, you implement this by making a class that has a method on it, perhaps called getSystemDate(). This method looks at some kind of global, static variable for the current "state" of the ASC. By default, it's Off, and in the Off state the getSystemDate() method returns the current, real date-time. But if you set the global state variable to On, and provide a specific date-time value, then the getSystemDate() method returns that specific date-time.

You then go through your code base, and everywhere that you are obtaining the date-time directly, you replace it with a call to this getSystemDate() method.

Once you do this, you have an ASC. You have effectively tricked your whole application into thinking that it is a different date-time, without having to alter the server's clock, and this is enormously valuable for testing purposes.

I would like to solicit professional opinions on how I went about implementing the ASC/TimeChannels client software for Perl.

Here is the implementing class I wrote for Perl:


Code
#!/usr/bin/perl 

# This is the TimeChannels Artificial System Clock implementation class for Perl.
# Everywhere in your application codebase that obtains the date/time directly, replace with a call
# to the getSystemDate() sub in this file.
#
# For simple unit-testing, you can call setToStaticTestState() and pass it a specific date-time value.
#
# For system, integration, acpt testing, call setToTestState() and pass it a specific channel id you have setup in
# the TimeChannels.com control panel.
#
# Return to normal time by calling setToProductionState()
#
# NOTE: Requires LWP bundle in order to work.
# Use this line:
#
# perl -MCPAN -e 'install Bundle::LWP'
#
# to install it.

package TimeChannels;
require LWP::UserAgent;
use strict;
use Time::Local;

my $tcURL = "http://www.timechannels.com/GetChannel";
my $tcURLms = "http://www.timechannels.com/GetChannelMS";
my $tcAscState = "TimeChannels.state.Production";
my $tcChannel = "0";
my $tcAscDateTime = 0;
my $tcServiceURL = "http://www.timechannels.com/GetChannel";
my $tcMillisecondMode = "false";

sub getState {
return $tcAscState;
}

sub setToProductionState {
$tcAscState = "TimeChannels.state.Production";
}

sub setToStaticTestState {
my ($parm1, $parm2) = @_;
$tcAscState = "TimeChannels.state.TestDate";
$tcAscDateTime = $parm2;
}

sub setToTestState {
my ($parm1, $parm2) = @_;
$tcAscState = "TimeChannels.state.TestChannel";
$tcChannel = $parm2;
}

sub setToMillisecondMode {
$tcMillisecondMode = "true";
$tcServiceURL = $tcURLms;
}

sub setToStandardMode {
$tcMillisecondMode = "false";
$tcServiceURL = $tcURL;
}

sub getSystemDate {
if ($tcAscState eq "TimeChannels.state.Production") {
return time;
}

if ($tcAscState eq "TimeChannels.state.TestDate") {
return $tcAscDateTime;
}

if ($tcAscState eq "TimeChannels.state.TestChannel") {
return TimeChannels->getChannelFromTimeChannelsService();
}

return time;
}


sub getChannelFromTimeChannelsService {
my $url = $tcServiceURL . '?channel=' . $tcChannel;
use LWP::Simple;
my $channelValue = get $url;
die "Could not get date-time channel from $url" unless defined $channelValue;
my $retVal = time;

if ($tcMillisecondMode eq "true") {
$retVal = (1 * $channelValue) / 1000;
}
else {
my $year = substr($channelValue, 0, 4);
my $month = (1 * substr($channelValue, 5, 2)) - 1;
my $day = 1* substr($channelValue, 8, 2);
my $hour = 1 * substr($channelValue, 11, 2);
my $minute = 1 * substr($channelValue, 14, 2);
my $ampm = substr($channelValue, 17, 2);

if ($ampm eq "PM") {
$hour += 12;
}

$retVal = timelocal(0, $minute, $hour, $day, $month, $year);
}

return $retVal;
}


How does this look to you? It tests out fine, and I will post the testing/sample usage code soon. But I know next to nothing about Perl, and I would be grateful if anyone with more Perl experience than me would take a look and let me know if you see any potential issues.

Many thanks to all who reply.

John


(This post was edited by JohnBoy on Nov 10, 2008, 2:46 PM)


KevinR
Veteran


Nov 10, 2008, 3:36 PM

Post #2 of 3 (764 views)
Re: [JohnBoy] Artificial System Clock (time machine for testing) [In reply to] Can't Post

There is a class of modules on CPAN called WebService. Maybe your service could be included:

WebService::ASC

This would make it part of the perl community and your module could be reviewed and tested by any interested party.

I suggest you post on www.perlmonks.com if you haven't already where there is a larger number of active perl coders, some of whom are active perl contributors and module authors. They can suggest changes to you and advise on signing up to PAUSE and contributing your code as a module.
-------------------------------------------------


(This post was edited by KevinR on Nov 10, 2008, 3:51 PM)


JohnBoy
New User

Jun 11, 2009, 1:06 PM

Post #3 of 3 (548 views)
Re: [KevinR] Artificial System Clock (time machine for testing) [In reply to] Can't Post

Thanks very much for the suggestion - I'll go check out those resources.

John

 
 


Search for (options) Powered by Gossamer Forum v.1.2.0

Web Applications & Managed Hosting Powered by Gossamer Threads
Visit our Mailing List Archives