Re: Inscrutable test failure
by Corion (Patriarch) on Oct 26, 2007 at 20:59 UTC
|
My guess for the Sunday part was, that maybe time zones and/or daylight savings time are tripping you up, because the DST change is next weekend.
But as Tuesday would have to skip 25 hours to come close to a weekend day, I'm not exactly sure there, unless there also is an off-by-one error somewhere, so that you're unclear on whether a week starts with day 1 or day 0.
What you should learn from there is that you shouldn't just output the value from ->is_weekday in your test diagnostics but also the parameter given to it as input. I often use:
my $timestamp = UnixDate(ParseDate('last sunday'), "%s");
if (! is $obj->is_weekday($timestamp), 0, 'Sunday ($ts) is weekend'))
+{
diag "Last sunday = " . localtime($timestamp) . " ($timestamp)";
diag "ParseDate('last sunday'):" . ParseDate('last sunday');
};
That way, you gather more data.
Another lesson to be learned would be to use static timestamps instead of timestamps depending on the time when a test is run. That way you get at least consistent failures/successes, but in your case, that would hide the error in your module(s). | [reply] [d/l] [select] |
|
|
Note that, in the tests, I'm setting the weekdays to 0011111 (Sun/Mon = weekend, Tue-Sat = weekday). Sunday and Tuesday were the chosen days to test specifically because that's where it places the transitions. So, if DST were to cause a one-hour error, it could affect Tuesday's status.
Lesson learned about providing additional data in the messages (and I need to look up diag...), but I don't see how static timestamps would work any better, given that it's Friday right now in the US, but Saturday in Australia. The point of mucking around with Date::Manip was to get a time which is Sunday/Tuesday in the timezone of the machine running the test.
| [reply] [d/l] |
|
|
Static data only gives you reproducibility, not correctness. If you use a static timestamp for testing, and manage to get the DST changes out of the way (or in the past and thus at fixed dates), you will get consistent errors or successes in your test suite. This does not buy you correctness in the live program as the timestamps of the future and conditions on the production machines might well differ.
Obviously, your client doesn't have a firm grip on the identical setup of test and production machines either as the (supposed) differences in timezones between test and production environment show, but maybe you still can get a VMWare image (or Xen, or Parallels or whatever the VM container du jour is) to run your tests in an environment as close to production as possible before approaching your client for installation.
| [reply] |
|
|
|
|
|
Re: Inscrutable test failure
by hossman (Prior) on Oct 26, 2007 at 20:56 UTC
|
You appear to be using Date::Manip ... correct?
- what time zone are all of these boxes running on?
ParseDate assumes the TZ found in the environment when parsing, so "last sunday" in localtime can conceivable be noon the previous saturday (or thefollowing monday) in GMT. on top combine that you take the seconds since epoch returned by UnixDate and you then pass it to localtime ... which is only going to compound your problem.
-
If you are going to use Date::Manip, why not use the Date_IsWorkDay function in conjuntion with teh configurable WorkWeekBeg, and WorkWeekEnd settings?
In general: make the message of your test give you more data (like exactly what 'time' (fully formated with an explicit timezone) you are passing to your function.
| [reply] [d/l] [select] |
|
|
Correct. When I needed to get the epoch time value of "some random sunday" for testing, Date::Manip was the first thing that came to mind.
1) My system is central US time, the test box I installed to is PHT (Phillipines), and I'm not sure whether the one it's failing on is using PHT or German time. Fun, no? But you're right - I had been assuming all operations would be in the machine's local time, regardless of what that may be. Is there a more reliable way to say "give me a time value for a day that is a Sunday/Tuesday in the current time zone"?
2) The provided UI mockup included 7 checkboxes to indicate weekday/weekend status independently for each day, implying that the sets need not be contiguous. Su,Tu,Sa = weekend / M,W,Th,F = weekday doesn't work with a begin/end range.
| [reply] |
|
|
I think you want to use Date_DayOfWeek then, so something like Date_DayOfWeek(UnixDate(ParseDate('last saturday'),'%m', '%d','%y'))
| [reply] [d/l] |
|
|
|
|
Re: Inscrutable test failure
by Krambambuli (Curate) on Oct 26, 2007 at 20:54 UTC
|
On my Linux WS, if I run
locale -c LC_TIME
the first line of the output shows
Sunday;Monday;Tuesday;Wednesday;Thursday;Friday;Saturday
What do you see on your station ? Maybe that is a track to follow. I'm pretty sure that there are locales where this is different, altough I don't know where to look for it.
Hth.
| [reply] |
Re: Inscrutable test failure
by eric256 (Parson) on Oct 26, 2007 at 21:26 UTC
|
On my system (localtime(UnixDate(ParseDate('last sunday'), "%s") || time))[6] returns 0 and (localtime(UnixDate(ParseDate('last saturday'), "%s") || time))[6] returns 6....so I think this obviously varies between systems.
On the other hand... Date_IsWorkDay(ParseDate('last saturday')) works perfectly
| [reply] [d/l] [select] |
|
|
It shouldn't vary between systems. Per the documentation of localtime, "$wday is the day of the week, with 0 indicating Sunday and 3 indicating Wednesday." Sunday should universally be 0 and Saturday should be 6.
In the test, I set the list of weekdays to not be the default M-F to verify that nonstandard ranges are supported, but didn't think to mention that in the initial post. Sorry about the confusion there.
| [reply] [d/l] |
|
|
| [reply] |
Re: Inscrutable test failure
by Krambambuli (Curate) on Oct 27, 2007 at 10:11 UTC
|
Adding just another thought.
As you are mixing basically two different ways of dealing with date&time (Date::Manip and Perl core's localtime), I guess there are also real chances that the two might disagree on what the local timezone is (and as such, how they would deal with the epoch).
Date:Manip says that
---
Date::Manip must be able to determine the timezone the user is in.
It does this by looking in the following places:
$Date::Manip::TZ (set with Date_Init or in Manip.pm)
$ENV{TZ}
the unix ‘date‘ command (if available)
$main::TZ
/etc/TIMEZONE
/etc/timezone
At least one of these should contain a timezone
in one of the supported forms.
If none do by default, the TZ variable must be set with Date_Init.
---
Seems quite possible that the two might disagree - which would make 'last sunday' - which is taken at midnight - easily become 'Saturday' even for a slighty different TZ. (If so, it might be that 'last sunday noon' wouldn't have run into troubles).
I'm really curious now about what you'll find.
| [reply] [d/l] |
|
|
I missed that list in the docs - thanks for pointing it out. That, along with the others' suggestions to improve the reporting on failed tests, gives me someplace meaningful to look for a cause even if I'm not able to interact directly with the problem machine.
| [reply] |