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