also add -fwrapv to CFLAGS (addresses #698908)
[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 `false`
122         else
123                 return `:`
124         fi
125 }
126
127
128
129 ###
130 ### Tests
131 ###
132
133 # Why are these dates tested?
134 #
135 # February 29, 2003
136 #   Is not a leap year - should be invalid.
137 #
138 # 2004-12-40
139 #   Make sure get_date does not "roll" date forward to January 9th.  Some
140 #   versions have been known to do this.
141 #
142 # Dec-5-1972
143 #   This is my birthday.  :)
144 #
145 # 3/29/1974
146 # 1996/05/12 13:57:45
147 #   Because.
148 #
149 # 12-05-12
150 #   This will be my 40th birthday.  Ouch.  :)
151 #
152 # 05/12/96
153 #   Because.
154 #
155 # third tuesday in March, 2078
156 #   Wanted this to work.
157 #
158 # 1969-12-32 2:00:00 UTC
159 # 1970-01-01 2:00:00 UTC
160 # 1969-12-32 2:00:00 +0400
161 # 1970-01-01 2:00:00 +0400
162 # 1969-12-32 2:00:00 -0400
163 # 1970-01-01 2:00:00 -0400
164 #   Playing near the UNIX Epoch boundry condition to make sure date rolling
165 #   is also disabled there.
166 #
167 # 1996-12-12 1 month
168 #   Test a relative date.
169
170
171
172 # The following tests are currently being skipped for being unportable:
173 #
174 # Tue Jan 19 03:14:07 2038 +0000
175 #   For machines with 31-bit time_t, any date past this date will be an
176 #   invalid date. So, any test date with a value greater than this
177 #   time is not portable.
178 #
179 # Feb. 29, 2096 4 years
180 #   4 years from this date is _not_ a leap year, so Feb. 29th does not exist.
181 #
182 # Feb. 29, 2096 8 years
183 #   8 years from this date is a leap year, so Feb. 29th does exist,
184 #   but on many hosts with 32-bit time_t types time, this test will
185 #   fail. So, this is not a portable test.
186 #
187
188 TZ=UTC0; export TZ
189
190 cat >getdate-expected <<EOF
191 Enter date, or blank line to exit.
192 > Bad format - couldn't convert.
193 > Bad format - couldn't convert.
194 >      92361600 =       1972-12-05 00:00:00.000000000
195 >     133747200 =       1974-03-29 00:00:00.000000000
196 >     831909465 =       1996-05-12 13:57:45.000000000
197 >    1336780800 =       2012-05-12 00:00:00.000000000
198 >     831859200 =       1996-05-12 00:00:00.000000000
199 > Bad format - couldn't convert.
200 > Bad format - couldn't convert.
201 >          7200 =       1970-01-01 02:00:00.000000000
202 > Bad format - couldn't convert.
203 >         -7200 =       1969-12-31 22:00:00.000000000
204 > Bad format - couldn't convert.
205 >         21600 =       1970-01-01 06:00:00.000000000
206 >     853027200 =       1997-01-12 00:00:00.000000000
207
208 EOF
209
210 ./getdate >getdate-got <<EOF
211 February 29, 2003
212 2004-12-40
213 Dec-5-1972
214 3/29/1974
215 1996/05/12 13:57:45
216 12-05-12
217 05/12/96
218 third tuesday in March, 2078
219 1969-12-32 2:00:00 UTC
220 1970-01-01 2:00:00 UTC
221 1969-12-32 2:00:00 +0400
222 1970-01-01 2:00:00 +0400
223 1969-12-32 2:00:00 -0400
224 1970-01-01 2:00:00 -0400
225 1996-12-12 1 month
226 EOF
227
228 verify getdate-1
229
230
231
232 # Why are these dates tested?
233 #
234 # Ian Abbot reported these odd boundry cases.  After daylight savings time went
235 # into effect, non-daylight time zones would cause
236 # "Bad format - couldn't convert." errors, even when the non-daylight zone
237 # happened to be a universal one, like GMT.
238
239 TZ=Europe/London; export TZ
240 if valid_timezone $TZ; then
241         cat >getdate-expected <<EOF
242 Enter date, or blank line to exit.
243 >    1109635200 =       2005-03-01 00:00:00.000000000
244 >    1111881600 =       2005-03-27 00:00:00.000000000
245 >    1111968000 =       2005-03-28 01:00:00.000000000
246 >    1111968000 =       2005-03-28 01:00:00.000000000
247 >    1112054400 =       2005-03-29 01:00:00.000000000
248 >    1112054400 =       2005-03-29 01:00:00.000000000
249 >    1112140800 =       2005-03-30 01:00:00.000000000
250 >    1112140800 =       2005-03-30 01:00:00.000000000
251 >    1112227200 =       2005-03-31 01:00:00.000000000
252 >    1112227200 =       2005-03-31 01:00:00.000000000
253 >    1112313600 =       2005-04-01 01:00:00.000000000
254 >    1112313600 =       2005-04-01 01:00:00.000000000
255 >    1113091200 =       2005-04-10 01:00:00.000000000
256 >    1113091200 =       2005-04-10 01:00:00.000000000
257 >    1112310000 =       2005-04-01 00:00:00.000000000
258
259 EOF
260
261         ./getdate >getdate-got <<EOF
262 2005-3-1 GMT
263 2005-3-27 GMT
264 2005-3-28 GMT
265 2005-3-28 UTC0
266 2005-3-29 GMT
267 2005-3-29 UTC0
268 2005-3-30 GMT
269 2005-3-30 UTC0
270 2005-3-31 GMT
271 2005-3-31 UTC0
272 2005-4-1 GMT
273 2005-4-1 UTC0
274 2005-4-10 GMT
275 2005-4-10 UTC0
276 2005-4-1 BST
277 EOF
278
279         verify getdate-2
280 else
281         skip getdate-2 "$skipreason"
282 fi
283
284
285
286 # Many of the following cases were also submitted by Ian Abbott, but the same
287 # errors are not exhibited.  The original problem had a similar root, but
288 # managed to produce errors with GMT, which is considered a "Universal Zone".
289 # This was fixed.
290 #
291 # The deeper problem has to do with "local zone" processing in getdate.y
292 # that causes local daylight zones to be excluded when local standard time is
293 # in effect and vice versa.  This used to cause trouble with GMT in Britian
294 # when British Summer Time was in effect, but this was overridden for the
295 # "Universal Timezones" (GMT, UTC, & UT), that might double as a local zone in
296 # some locales.  We still see in these tests the local daylight/standard zone
297 # exclusion in EST/EDT.  According to Paul Eggert in a message to
298 # bug-gnulib@gnu.org on 2005-04-12, this is considered a bug but may not be
299 # fixed soon due to its complexity.
300
301 TZ=America/New_York; export TZ
302 if valid_timezone $TZ; then
303         cat >getdate-expected <<EOF
304 Enter date, or blank line to exit.
305 >    1109653200 =       2005-03-01 00:00:00.000000000
306 >    1109631600 =       2005-02-28 18:00:00.000000000
307 >    1112331600 =       2005-04-01 00:00:00.000000000
308 > Bad format - couldn't convert.
309 >    1114902000 =       2005-04-30 19:00:00.000000000
310 >    1114905600 =       2005-04-30 20:00:00.000000000
311 >    1114920000 =       2005-05-01 00:00:00.000000000
312 >    1114905600 =       2005-04-30 20:00:00.000000000
313 > Bad format - couldn't convert.
314 >    1117580400 =       2005-05-31 19:00:00.000000000
315 >    1117584000 =       2005-05-31 20:00:00.000000000
316 >    1117598400 =       2005-06-01 00:00:00.000000000
317 >    1117584000 =       2005-05-31 20:00:00.000000000
318
319 EOF
320
321         ./getdate >getdate-got <<EOF
322 2005-3-1 EST
323 2005-3-1 BST
324 2005-4-1 EST
325 2005-5-1 EST
326 2005-5-1 BST
327 2005-5-1 GMT
328 2005-5-1 EDT
329 2005-5-1 UTC0
330 2005-6-1 EST
331 2005-6-1 BST
332 2005-6-1 GMT
333 2005-6-1 EDT
334 2005-6-1 UTC0
335 EOF
336
337         verify getdate-3
338 else
339         skip getdate-3 "$skipreason"
340 fi
341
342
343
344 rm getdate-expected getdate-got getdate.cmp
345 exit 0