Initial revision
[alioth/cvs.git] / lib / test-getdate.sh
1 #! /bin/sh
2
3 # Test that a getdate executable meets its specification.
4 #
5 # Copyright (C) 2004 Free Software Foundation, Inc.
6 #
7 # This program is free software; you can redistribute it and/or modify
8 # it under the terms of the GNU General Public License as published by
9 # the Free Software Foundation; either version 2, or (at your option)
10 # any later version.
11 #
12 # This program is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 # GNU General Public License for more details.
16 #
17 # You should have received a copy of the GNU General Public License
18 # along with this program; if not, write to the Free Software Foundation,
19 # Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
20
21
22
23 ###
24 ### Globals
25 ###
26 LOGFILE=`pwd`/getdate.log
27 if test -f "$LOGFILE"; then
28         mv $LOGFILE $LOGFILE~
29 fi
30
31
32
33 ###
34 ### Functions
35 ###
36 verify ()
37 {
38         echo >>getdate-got
39         if cmp getdate-expected getdate-got >getdate.cmp; then
40                 echo "PASS: $1" >>$LOGFILE
41         else
42                 cat getdate.cmp >>$LOGFILE
43                 echo "** expected: " >>$LOGFILE
44                 cat getdate-expected >>$LOGFILE
45                 echo "** got: " >>$LOGFILE
46                 cat getdate-got >>$LOGFILE
47                 echo "FAIL: $1" | tee -a $LOGFILE >&2
48                 echo "Failed!  See $LOGFILE for more!" >&2
49                 exit 1
50         fi
51 }
52
53
54
55 skip ()
56 {
57         echo "SKIP: $1"${2+" ($2)"} >>$LOGFILE
58 }
59
60
61
62 # Prep for future calls to valid_timezone().
63 #
64 # This should set $UTZ to three spaces, `GMT', `Unrecognized/Unrecognized', or
65 # possibly the empty string, depending on what system we are running on.  With
66 # any luck, this will catch any other existing variations as well.  The way it
67 # is used later does have the disadvantage of rejecting at least the
68 # `Europe/London' timezone for half the year when $UTZ gets set to `GMT', like
69 # happens on NetBSD, but, since I haven't come up with any better ideas and
70 # since rejecting a timezone just causes a few tests to be skipped, this will
71 # have to do for now.
72 #
73 # UTZ stands for Unrecognized Time Zone.
74 UTZ=`TZ=Unrecognized/Unrecognized date +%Z`
75
76 # The following function will return true if $1 is a valid timezone.  It will
77 # return false and set $skipreason, otherwise.
78 #
79 # Clobbers $NTZ & $skipreason.
80 #
81 # SUS2 says `date +%Z' will return `no characters' if `no timezone is
82 # determinable'.  It is, unfortunately, not very specific about what
83 # `determinable' means.  On GNU/Linux, `date +%Z' returns $TZ when $TZ is not
84 # recognized.  NetBSD 1.6.1 "determines" that an unrecognizable value in $TZ
85 # really means `GMT'.  On Cray, the standard is ignored and `date +%Z' returns
86 # three spaces when $TZ is not recognized.  We test for all three cases, plus
87 # the empty string for good measure, though I know of no set of conditions
88 # which will actually cause `date +%Z' to return the empty string SUS2
89 # specifies.
90 #
91 # Due to the current nature of this test, this will not work for the
92 # three-letter zone codes on some systems.  e.g.:
93 #
94 #       test `TZ=EST date +%Z` = "EST"
95 #
96 # should, quite correctly, evaluate to true on most systems, but:
97 #
98 #       TZ=Asia/Calcutta date +%Z
99 #
100 # would return `IST' on GNU/Linux, and hopefully any system which understands
101 # the `Asia/Calcutta' timezone, and `   ' on Cray.  Similarly:
102 #
103 #       TZ=Doesnt_Exist/Doesnt_Exist date +%Z
104 #
105 # returns `Doesnt_Exist/Doesnt_Exist' on GNU/Linux and `   ' on Cray.
106 #
107 # Unfortunately, the %z date format string (-HHMM format time zone) supported
108 # by the GNU `date' command is not part of any standard I know of and,
109 # therefore, is probably not portable.
110 #
111 valid_timezone ()
112 {
113         NTZ=`TZ=$1 date +%Z`
114         if test "$NTZ" = "$UTZ" || test "$NTZ" = "$1"; then
115                 skipreason="$1 is not a recognized timezone on this system"
116                 return `false`
117         else
118                 return `:`
119         fi
120 }
121
122
123
124 ###
125 ### Tests
126 ###
127
128 # Why are these dates tested?
129 #
130 # February 29, 2003
131 #   Is not a leap year - should be invalid.
132 #
133 # 2004-12-40
134 #   Make sure get_date does not "roll" date forward to January 9th.  Some
135 #   versions have been known to do this.
136 #
137 # Dec-5-1972
138 #   This is my birthday.  :)
139 #
140 # 3/29/1974
141 # 1996/05/12 13:57:45
142 #   Because.
143 #
144 # 12-05-12
145 #   This will be my 40th birthday.  Ouch.  :)
146 #
147 # 05/12/96
148 #   Because.
149 #
150 # third tuesday in March, 2078
151 #   Wanted this to work.
152 #
153 # 1969-12-32 2:00:00 UTC
154 # 1970-01-01 2:00:00 UTC
155 # 1969-12-32 2:00:00 +0400
156 # 1970-01-01 2:00:00 +0400
157 # 1969-12-32 2:00:00 -0400
158 # 1970-01-01 2:00:00 -0400
159 #   Playing near the UNIX Epoch boundry condition to make sure date rolling
160 #   is also disabled there.
161 #
162 # 1996-12-12 1 month
163 #   Test a relative date.
164
165
166
167 # The following tests are currently being skipped for being unportable:
168 #
169 # Tue Jan 19 03:14:07 2038 +0000
170 #   For machines with 31-bit time_t, any date past this date will be an
171 #   invalid date. So, any test date with a value greater than this
172 #   time is not portable.
173 #
174 # Feb. 29, 2096 4 years
175 #   4 years from this date is _not_ a leap year, so Feb. 29th does not exist.
176 #
177 # Feb. 29, 2096 8 years
178 #   8 years from this date is a leap year, so Feb. 29th does exist,
179 #   but on many hosts with 32-bit time_t types time, this test will
180 #   fail. So, this is not a portable test.
181 #
182
183 TZ=UTC0; export TZ
184
185 cat >getdate-expected <<EOF
186 Enter date, or blank line to exit.
187         > Bad format - couldn't convert.
188         > Bad format - couldn't convert.
189         > 1972-12-05 00:00:00.000000000
190         > 1974-03-29 00:00:00.000000000
191         > 1996-05-12 13:57:45.000000000
192         > 2012-05-12 00:00:00.000000000
193         > 1996-05-12 00:00:00.000000000
194         > Bad format - couldn't convert.
195         > Bad format - couldn't convert.
196         > 1970-01-01 02:00:00.000000000
197         > Bad format - couldn't convert.
198         > 1969-12-31 22:00:00.000000000
199         > Bad format - couldn't convert.
200         > 1970-01-01 06:00:00.000000000
201         > 1997-01-12 00:00:00.000000000
202         > 
203 EOF
204
205 ./getdate >getdate-got <<EOF
206 February 29, 2003
207 2004-12-40
208 Dec-5-1972
209 3/29/1974
210 1996/05/12 13:57:45
211 12-05-12
212 05/12/96
213 third tuesday in March, 2078
214 1969-12-32 2:00:00 UTC
215 1970-01-01 2:00:00 UTC
216 1969-12-32 2:00:00 +0400
217 1970-01-01 2:00:00 +0400
218 1969-12-32 2:00:00 -0400
219 1970-01-01 2:00:00 -0400
220 1996-12-12 1 month
221 EOF
222
223 verify getdate-1
224
225
226
227 # Why are these dates tested?
228 #
229 # Ian Abbot reported these odd boundry cases.  After daylight savings time went
230 # into effect, non-daylight time zones would cause
231 # "Bad format - couldn't convert." errors, even when the non-daylight zone
232 # happened to be a universal one, like GMT.
233
234 TZ=Europe/London; export TZ
235 if valid_timezone $TZ; then
236         cat >getdate-expected <<EOF
237 Enter date, or blank line to exit.
238         > 2005-03-01 00:00:00.000000000
239         > 2005-03-27 00:00:00.000000000
240         > 2005-03-28 01:00:00.000000000
241         > 2005-03-28 01:00:00.000000000
242         > 2005-03-29 01:00:00.000000000
243         > 2005-03-29 01:00:00.000000000
244         > 2005-03-30 01:00:00.000000000
245         > 2005-03-30 01:00:00.000000000
246         > 2005-03-31 01:00:00.000000000
247         > 2005-03-31 01:00:00.000000000
248         > 2005-04-01 01:00:00.000000000
249         > 2005-04-01 01:00:00.000000000
250         > 2005-04-10 01:00:00.000000000
251         > 2005-04-10 01:00:00.000000000
252         > 2005-04-01 00:00:00.000000000
253         > 
254 EOF
255
256         ./getdate >getdate-got <<EOF
257 2005-3-1 GMT
258 2005-3-27 GMT
259 2005-3-28 GMT
260 2005-3-28 UTC0
261 2005-3-29 GMT
262 2005-3-29 UTC0
263 2005-3-30 GMT
264 2005-3-30 UTC0
265 2005-3-31 GMT
266 2005-3-31 UTC0
267 2005-4-1 GMT
268 2005-4-1 UTC0
269 2005-4-10 GMT
270 2005-4-10 UTC0
271 2005-4-1 BST
272 EOF
273
274         verify getdate-2
275 else
276         skip getdate-2 "$skipreason"
277 fi
278
279
280
281 # Many of the following cases were also submitted by Ian Abbott, but the same
282 # errors are not exhibited.  The original problem had a similar root, but
283 # managed to produce errors with GMT, which is considered a "Universal Zone".
284 # This was fixed.
285 #
286 # The deeper problem has to do with "local zone" processing in getdate.y
287 # that causes local daylight zones to be excluded when local standard time is
288 # in effect and vice versa.  This used to cause trouble with GMT in Britian
289 # when British Summer Time was in effect, but this was overridden for the
290 # "Universal Timezones" (GMT, UTC, & UT), that might double as a local zone in
291 # some locales.  We still see in these tests the local daylight/standard zone
292 # exclusion in EST/EDT.  According to Paul Eggert in a message to
293 # bug-gnulib@gnu.org on 2005-04-12, this is considered a bug but may not be
294 # fixed soon due to its complexity.
295
296 TZ=America/New_York; export TZ
297 if valid_timezone $TZ; then
298         cat >getdate-expected <<EOF
299 Enter date, or blank line to exit.
300         > 2005-03-01 00:00:00.000000000
301         > 2005-02-28 18:00:00.000000000
302         > 2005-04-01 00:00:00.000000000
303         > Bad format - couldn't convert.
304         > 2005-04-30 19:00:00.000000000
305         > 2005-04-30 20:00:00.000000000
306         > 2005-05-01 00:00:00.000000000
307         > 2005-04-30 20:00:00.000000000
308         > Bad format - couldn't convert.
309         > 2005-05-31 19:00:00.000000000
310         > 2005-05-31 20:00:00.000000000
311         > 2005-06-01 00:00:00.000000000
312         > 2005-05-31 20:00:00.000000000
313         > 
314 EOF
315
316         ./getdate >getdate-got <<EOF
317 2005-3-1 EST
318 2005-3-1 BST
319 2005-4-1 EST
320 2005-5-1 EST
321 2005-5-1 BST
322 2005-5-1 GMT
323 2005-5-1 EDT
324 2005-5-1 UTC0
325 2005-6-1 EST
326 2005-6-1 BST
327 2005-6-1 GMT
328 2005-6-1 EDT
329 2005-6-1 UTC0
330 EOF
331
332         verify getdate-3
333 else
334         skip getdate-3 "$skipreason"
335 fi
336
337
338
339 rm getdate-expected getdate-got getdate.cmp
340 exit 0