xref: /netbsd-src/external/bsd/ntp/dist/tests/ntpd/leapsec.c (revision eabc0478de71e4e011a5b4e0392741e01d491794)
1*eabc0478Schristos /*	$NetBSD: leapsec.c,v 1.4 2024/08/18 20:47:27 christos Exp $	*/
248f8ae19Schristos 
3a6f3f22fSchristos //#include "ntpdtest.h"
4a6f3f22fSchristos #include "config.h"
5a6f3f22fSchristos 
6a6f3f22fSchristos 
7a6f3f22fSchristos #include "ntp.h"
8a6f3f22fSchristos #include "ntp_calendar.h"
9a6f3f22fSchristos #include "ntp_stdlib.h"
10a6f3f22fSchristos #include "ntp_leapsec.h"
11a6f3f22fSchristos 
12a6f3f22fSchristos #include "unity.h"
13a6f3f22fSchristos 
14a6f3f22fSchristos #include <string.h>
15a6f3f22fSchristos 
1656f2724eSchristos extern	void	setUp(void);
1756f2724eSchristos extern	void	tearDown(void);
1856f2724eSchristos 
19a6f3f22fSchristos #include "test-libntp.h"
20a6f3f22fSchristos 
21a6f3f22fSchristos static const char leap1 [] =
22a6f3f22fSchristos     "#\n"
23a6f3f22fSchristos     "#@ 	3610569600\n"
24a6f3f22fSchristos     "#\n"
25a6f3f22fSchristos     "2272060800 10	# 1 Jan 1972\n"
26a6f3f22fSchristos     "2287785600	11	# 1 Jul 1972\n"
27a6f3f22fSchristos     "2303683200	12	# 1 Jan 1973\n"
28a6f3f22fSchristos     "2335219200	13	# 1 Jan 1974\n"
29a6f3f22fSchristos     "2366755200	14	# 1 Jan 1975\n"
30a6f3f22fSchristos     "2398291200	15	# 1 Jan 1976\n"
31a6f3f22fSchristos     "2429913600	16	# 1 Jan 1977\n"
32a6f3f22fSchristos     "2461449600	17	# 1 Jan 1978\n"
33a6f3f22fSchristos     "2492985600	18	# 1 Jan 1979\n"
34a6f3f22fSchristos     "2524521600	19	# 1 Jan 1980\n"
35a6f3f22fSchristos     "   \t  \n"
36a6f3f22fSchristos     "2571782400	20	# 1 Jul 1981\n"
37a6f3f22fSchristos     "2603318400	21	# 1 Jul 1982\n"
38a6f3f22fSchristos     "2634854400	22	# 1 Jul 1983\n"
39a6f3f22fSchristos     "2698012800	23	# 1 Jul 1985\n"
40a6f3f22fSchristos     "2776982400	24	# 1 Jan 1988\n"
41a6f3f22fSchristos     "2840140800	25	# 1 Jan 1990\n"
42a6f3f22fSchristos     "2871676800	26	# 1 Jan 1991\n"
43a6f3f22fSchristos     "2918937600	27	# 1 Jul 1992\n"
44a6f3f22fSchristos     "2950473600	28	# 1 Jul 1993\n"
45a6f3f22fSchristos     "2982009600	29	# 1 Jul 1994\n"
46a6f3f22fSchristos     "3029443200	30	# 1 Jan 1996\n"
47a6f3f22fSchristos     "3076704000	31	# 1 Jul 1997\n"
48a6f3f22fSchristos     "3124137600	32	# 1 Jan 1999\n"
49a6f3f22fSchristos     "3345062400	33	# 1 Jan 2006\n"
50a6f3f22fSchristos     "3439756800	34	# 1 Jan 2009\n"
51a6f3f22fSchristos     "3550089600	35	# 1 Jul 2012\n"
52a6f3f22fSchristos     "#\n"
53a6f3f22fSchristos     "#h	dc2e6b0b 5aade95d a0587abd 4e0dacb4 e4d5049e\n"
54a6f3f22fSchristos     "#\n";
55a6f3f22fSchristos 
56a6f3f22fSchristos static const char leap2 [] =
57a6f3f22fSchristos     "#\n"
58a6f3f22fSchristos     "#@ 	2950473700\n"
59a6f3f22fSchristos     "#\n"
60a6f3f22fSchristos     "2272060800 10	# 1 Jan 1972\n"
61a6f3f22fSchristos     "2287785600	11	# 1 Jul 1972\n"
62a6f3f22fSchristos     "2303683200	12	# 1 Jan 1973\n"
63a6f3f22fSchristos     "2335219200	13	# 1 Jan 1974\n"
64a6f3f22fSchristos     "2366755200	14	# 1 Jan 1975\n"
65a6f3f22fSchristos     "2398291200	15	# 1 Jan 1976\n"
66a6f3f22fSchristos     "2429913600	16	# 1 Jan 1977\n"
67a6f3f22fSchristos     "2461449600	17	# 1 Jan 1978\n"
68a6f3f22fSchristos     "2492985600	18	# 1 Jan 1979\n"
69a6f3f22fSchristos     "2524521600	19	# 1 Jan 1980\n"
70a6f3f22fSchristos     "2571782400	20	# 1 Jul 1981\n"
71a6f3f22fSchristos     "2603318400	21	# 1 Jul 1982\n"
72a6f3f22fSchristos     "2634854400	22	# 1 Jul 1983\n"
73a6f3f22fSchristos     "2698012800	23	# 1 Jul 1985\n"
74a6f3f22fSchristos     "2776982400	24	# 1 Jan 1988\n"
75a6f3f22fSchristos     "2840140800	25	# 1 Jan 1990\n"
76a6f3f22fSchristos     "2871676800	26	# 1 Jan 1991\n"
77a6f3f22fSchristos     "2918937600	27	# 1 Jul 1992\n"
78a6f3f22fSchristos     "2950473600	28	# 1 Jul 1993\n"
79a6f3f22fSchristos     "#\n";
80a6f3f22fSchristos 
81a6f3f22fSchristos // Faked table with a leap second removal at 2009
82a6f3f22fSchristos static const char leap3 [] =
83a6f3f22fSchristos     "#\n"
84a6f3f22fSchristos     "#@ 	3610569600\n"
85a6f3f22fSchristos     "#\n"
86a6f3f22fSchristos     "2272060800 10	# 1 Jan 1972\n"
87a6f3f22fSchristos     "2287785600	11	# 1 Jul 1972\n"
88a6f3f22fSchristos     "2303683200	12	# 1 Jan 1973\n"
89a6f3f22fSchristos     "2335219200	13	# 1 Jan 1974\n"
90a6f3f22fSchristos     "2366755200	14	# 1 Jan 1975\n"
91a6f3f22fSchristos     "2398291200	15	# 1 Jan 1976\n"
92a6f3f22fSchristos     "2429913600	16	# 1 Jan 1977\n"
93a6f3f22fSchristos     "2461449600	17	# 1 Jan 1978\n"
94a6f3f22fSchristos     "2492985600	18	# 1 Jan 1979\n"
95a6f3f22fSchristos     "2524521600	19	# 1 Jan 1980\n"
96a6f3f22fSchristos     "2571782400	20	# 1 Jul 1981\n"
97a6f3f22fSchristos     "2603318400	21	# 1 Jul 1982\n"
98a6f3f22fSchristos     "2634854400	22	# 1 Jul 1983\n"
99a6f3f22fSchristos     "2698012800	23	# 1 Jul 1985\n"
100a6f3f22fSchristos     "2776982400	24	# 1 Jan 1988\n"
101a6f3f22fSchristos     "2840140800	25	# 1 Jan 1990\n"
102a6f3f22fSchristos     "2871676800	26	# 1 Jan 1991\n"
103a6f3f22fSchristos     "2918937600	27	# 1 Jul 1992\n"
104a6f3f22fSchristos     "2950473600	28	# 1 Jul 1993\n"
105a6f3f22fSchristos     "2982009600	29	# 1 Jul 1994\n"
106a6f3f22fSchristos     "3029443200	30	# 1 Jan 1996\n"
107a6f3f22fSchristos     "3076704000	31	# 1 Jul 1997\n"
108a6f3f22fSchristos     "3124137600	32	# 1 Jan 1999\n"
109a6f3f22fSchristos     "3345062400	33	# 1 Jan 2006\n"
110a6f3f22fSchristos     "3439756800	32	# 1 Jan 2009\n"
111a6f3f22fSchristos     "3550089600	33	# 1 Jul 2012\n"
112a6f3f22fSchristos     "#\n";
113a6f3f22fSchristos 
114a6f3f22fSchristos // short table with good hash
115a6f3f22fSchristos static const char leap_ghash [] =
116a6f3f22fSchristos     "#\n"
117a6f3f22fSchristos     "#@ 	3610569600\n"
118a6f3f22fSchristos     "#$ 	3610566000\n"
119a6f3f22fSchristos     "#\n"
120a6f3f22fSchristos     "2272060800 10	# 1 Jan 1972\n"
121a6f3f22fSchristos     "2287785600	11	# 1 Jul 1972\n"
122a6f3f22fSchristos     "2303683200	12	# 1 Jan 1973\n"
123a6f3f22fSchristos     "2335219200	13	# 1 Jan 1974\n"
124a6f3f22fSchristos     "2366755200	14	# 1 Jan 1975\n"
125a6f3f22fSchristos     "2398291200	15	# 1 Jan 1976\n"
126a6f3f22fSchristos     "2429913600	16	# 1 Jan 1977\n"
127a6f3f22fSchristos     "2461449600	17	# 1 Jan 1978\n"
128a6f3f22fSchristos     "2492985600	18	# 1 Jan 1979\n"
129a6f3f22fSchristos     "2524521600	19	# 1 Jan 1980\n"
130a6f3f22fSchristos     "#\n"
131a6f3f22fSchristos     "#h 4b304e10 95642b3f c10b91f9 90791725 25f280d0\n"
132a6f3f22fSchristos     "#\n";
133a6f3f22fSchristos 
134a6f3f22fSchristos // short table with bad hash
135a6f3f22fSchristos static const char leap_bhash [] =
136a6f3f22fSchristos     "#\n"
137a6f3f22fSchristos     "#@ 	3610569600\n"
138a6f3f22fSchristos     "#$ 	3610566000\n"
139a6f3f22fSchristos     "#\n"
140a6f3f22fSchristos     "2272060800 10	# 1 Jan 1972\n"
141a6f3f22fSchristos     "2287785600	11	# 1 Jul 1972\n"
142a6f3f22fSchristos     "2303683200	12	# 1 Jan 1973\n"
143a6f3f22fSchristos     "2335219200	13	# 1 Jan 1974\n"
144a6f3f22fSchristos     "2366755200	14	# 1 Jan 1975\n"
145a6f3f22fSchristos     "2398291200	15	# 1 Jan 1976\n"
146a6f3f22fSchristos     "2429913600	16	# 1 Jan 1977\n"
147a6f3f22fSchristos     "2461449600	17	# 1 Jan 1978\n"
148a6f3f22fSchristos     "2492985600	18	# 1 Jan 1979\n"
149a6f3f22fSchristos     "2524521600	19	# 1 Jan 1980\n"
150a6f3f22fSchristos     "#\n"
151a6f3f22fSchristos     "#h	dc2e6b0b 5aade95d a0587abd 4e0dacb4 e4d5049e\n"
152a6f3f22fSchristos     "#\n";
153a6f3f22fSchristos 
154a6f3f22fSchristos // short table with malformed hash
155a6f3f22fSchristos static const char leap_mhash [] =
156a6f3f22fSchristos     "#\n"
157a6f3f22fSchristos     "#@ 	3610569600\n"
158a6f3f22fSchristos     "#$ 	3610566000\n"
159a6f3f22fSchristos     "#\n"
160a6f3f22fSchristos     "2272060800 10	# 1 Jan 1972\n"
161a6f3f22fSchristos     "2287785600	11	# 1 Jul 1972\n"
162a6f3f22fSchristos     "2303683200	12	# 1 Jan 1973\n"
163a6f3f22fSchristos     "2335219200	13	# 1 Jan 1974\n"
164a6f3f22fSchristos     "2366755200	14	# 1 Jan 1975\n"
165a6f3f22fSchristos     "2398291200	15	# 1 Jan 1976\n"
166a6f3f22fSchristos     "2429913600	16	# 1 Jan 1977\n"
167a6f3f22fSchristos     "2461449600	17	# 1 Jan 1978\n"
168a6f3f22fSchristos     "2492985600	18	# 1 Jan 1979\n"
169a6f3f22fSchristos     "2524521600	19	# 1 Jan 1980\n"
170a6f3f22fSchristos     "#\n"
171a6f3f22fSchristos     "#h f2349a02 788b9534 a8f2e141 f2029Q6d 4064a7ee\n"
172a6f3f22fSchristos     "#\n";
173a6f3f22fSchristos 
174a6f3f22fSchristos // short table with only 4 hash groups
175a6f3f22fSchristos static const char leap_shash [] =
176a6f3f22fSchristos     "#\n"
177a6f3f22fSchristos     "#@ 	3610569600\n"
178a6f3f22fSchristos     "#$ 	3610566000\n"
179a6f3f22fSchristos     "#\n"
180a6f3f22fSchristos     "2272060800 10	# 1 Jan 1972\n"
181a6f3f22fSchristos     "2287785600	11	# 1 Jul 1972\n"
182a6f3f22fSchristos     "2303683200	12	# 1 Jan 1973\n"
183a6f3f22fSchristos     "2335219200	13	# 1 Jan 1974\n"
184a6f3f22fSchristos     "2366755200	14	# 1 Jan 1975\n"
185a6f3f22fSchristos     "2398291200	15	# 1 Jan 1976\n"
186a6f3f22fSchristos     "2429913600	16	# 1 Jan 1977\n"
187a6f3f22fSchristos     "2461449600	17	# 1 Jan 1978\n"
188a6f3f22fSchristos     "2492985600	18	# 1 Jan 1979\n"
189a6f3f22fSchristos     "2524521600	19	# 1 Jan 1980\n"
190a6f3f22fSchristos     "#\n"
191a6f3f22fSchristos     "#h f2349a02 788b9534 a8f2e141 f2029Q6d\n"
192a6f3f22fSchristos     "#\n";
193a6f3f22fSchristos 
194a6f3f22fSchristos // table with good hash and truncated/missing leading zeros
195a6f3f22fSchristos static const char leap_gthash [] = {
196a6f3f22fSchristos     "#\n"
197a6f3f22fSchristos     "#$	 3535228800\n"
198a6f3f22fSchristos     "#\n"
199a6f3f22fSchristos     "#	Updated through IERS Bulletin C46\n"
200a6f3f22fSchristos     "#	File expires on:  28 June 2014\n"
201a6f3f22fSchristos     "#\n"
202a6f3f22fSchristos     "#@	3612902400\n"
203a6f3f22fSchristos     "#\n"
204a6f3f22fSchristos     "2272060800	10	# 1 Jan 1972\n"
205a6f3f22fSchristos     "2287785600	11	# 1 Jul 1972\n"
206a6f3f22fSchristos     "2303683200	12	# 1 Jan 1973\n"
207a6f3f22fSchristos     "2335219200	13	# 1 Jan 1974\n"
208a6f3f22fSchristos     "2366755200	14	# 1 Jan 1975\n"
209a6f3f22fSchristos     "2398291200	15	# 1 Jan 1976\n"
210a6f3f22fSchristos     "2429913600	16	# 1 Jan 1977\n"
211a6f3f22fSchristos     "2461449600	17	# 1 Jan 1978\n"
212a6f3f22fSchristos     "2492985600	18	# 1 Jan 1979\n"
213a6f3f22fSchristos     "2524521600	19	# 1 Jan 1980\n"
214a6f3f22fSchristos     "2571782400	20	# 1 Jul 1981\n"
215a6f3f22fSchristos     "2603318400	21	# 1 Jul 1982\n"
216a6f3f22fSchristos     "2634854400	22	# 1 Jul 1983\n"
217a6f3f22fSchristos     "2698012800	23	# 1 Jul 1985\n"
218a6f3f22fSchristos     "2776982400	24	# 1 Jan 1988\n"
219a6f3f22fSchristos     "2840140800	25	# 1 Jan 1990\n"
220a6f3f22fSchristos     "2871676800	26	# 1 Jan 1991\n"
221a6f3f22fSchristos     "2918937600	27	# 1 Jul 1992\n"
222a6f3f22fSchristos     "2950473600	28	# 1 Jul 1993\n"
223a6f3f22fSchristos     "2982009600	29	# 1 Jul 1994\n"
224a6f3f22fSchristos     "3029443200	30	# 1 Jan 1996\n"
225a6f3f22fSchristos     "3076704000	31	# 1 Jul 1997\n"
226a6f3f22fSchristos     "3124137600	32	# 1 Jan 1999\n"
227a6f3f22fSchristos     "3345062400	33	# 1 Jan 2006\n"
228a6f3f22fSchristos     "3439756800	34	# 1 Jan 2009\n"
229a6f3f22fSchristos     "3550089600	35	# 1 Jul 2012\n"
230a6f3f22fSchristos     "#\n"
231a6f3f22fSchristos     "#h	1151a8f e85a5069 9000fcdb 3d5e5365 1d505b37"
232a6f3f22fSchristos };
233a6f3f22fSchristos 
234a6f3f22fSchristos static const uint32_t lsec2006 = 3345062400u; // +33, 1 Jan 2006, 00:00:00 utc
235a6f3f22fSchristos static const uint32_t lsec2009 = 3439756800u; // +34, 1 Jan 2009, 00:00:00 utc
236a6f3f22fSchristos static const uint32_t lsec2012 = 3550089600u; // +35, 1 Jul 2012, 00:00:00 utc
237a6f3f22fSchristos static const uint32_t lsec2015 = 3644697600u; // +36, 1 Jul 2015, 00:00:00 utc
238a6f3f22fSchristos 
23956f2724eSchristos static int stringreader(void* farg)
240a6f3f22fSchristos {
241a6f3f22fSchristos 	const char ** cpp = (const char**)farg;
2424c290c01Schristos 
243a6f3f22fSchristos 	if (**cpp)
244a6f3f22fSchristos 		return *(*cpp)++;
245a6f3f22fSchristos 	else
246a6f3f22fSchristos 		return EOF;
247a6f3f22fSchristos }
248a6f3f22fSchristos 
249a6f3f22fSchristos static int/*BOOL*/
250a6f3f22fSchristos setup_load_table(
251a6f3f22fSchristos 	const char * cp,
252a6f3f22fSchristos 	int          blim)
253a6f3f22fSchristos {
254a6f3f22fSchristos 	int            rc;
255a6f3f22fSchristos 	leap_table_t * pt = leapsec_get_table(0);
2564c290c01Schristos 
257a6f3f22fSchristos 	rc = (pt != NULL) && leapsec_load(pt, stringreader, &cp, blim);
258a6f3f22fSchristos 	rc = rc && leapsec_set_table(pt);
259a6f3f22fSchristos 	return rc;
260a6f3f22fSchristos }
261a6f3f22fSchristos 
262a6f3f22fSchristos static int/*BOOL*/
263a6f3f22fSchristos setup_clear_table(void)
264a6f3f22fSchristos {
265a6f3f22fSchristos 	int            rc;
266a6f3f22fSchristos 	leap_table_t * pt = leapsec_get_table(0);
2674c290c01Schristos 
268a6f3f22fSchristos 	if (pt)
269a6f3f22fSchristos 		leapsec_clear(pt);
270a6f3f22fSchristos 	rc = leapsec_set_table(pt);
271a6f3f22fSchristos 	return rc;
272a6f3f22fSchristos }
273a6f3f22fSchristos 
27456f2724eSchristos #if 0 /* formatting & compare currently not used... */
27556f2724eSchristos static const char *
2764c290c01Schristos CalendarToString(const struct calendar cal)
2774c290c01Schristos {
27856f2724eSchristos 	char * str;
2794c290c01Schristos 
28056f2724eSchristos 	LIB_GETBUF(str);
28156f2724eSchristos 	snprintf(str, LIB_BUFLENGTH,
28256f2724eSchristos 		 "%04hu-%02hhu-%02hhu (%hu) %02hhu:%02hhu:%02hhu",
28356f2724eSchristos 		 cal.year, cal.month, cal.monthday, cal.yearday,
28456f2724eSchristos 		 cal.hour, cal.minute, cal.second);
28556f2724eSchristos 	return str;
286a6f3f22fSchristos }
287a6f3f22fSchristos 
28856f2724eSchristos static int
2894c290c01Schristos IsEqual(const struct calendar expected, const struct calendar actual)
2904c290c01Schristos {
2914c290c01Schristos 
2924c290c01Schristos 	if (   expected.year == actual.year
2934c290c01Schristos 	    && (   expected.yearday == actual.yearday
2944c290c01Schristos 		|| (   expected.month == actual.month
2954c290c01Schristos 		    && expected.monthday == actual.monthday))
2964c290c01Schristos 	    && expected.hour == actual.hour
2974c290c01Schristos 	    && expected.minute == actual.minute
2984c290c01Schristos 	    && expected.second == actual.second) {
299a6f3f22fSchristos 		return TRUE;
300a6f3f22fSchristos 	} else {
30156f2724eSchristos 		const char *p_exp = CalendarToString(expected);
30256f2724eSchristos 		const char *p_act = CalendarToString(actual);
3034c290c01Schristos 		printf("expected: %s but was %s", p_exp, p_act);
3044c290c01Schristos 		return FALSE;
305a6f3f22fSchristos 	}
306a6f3f22fSchristos }
30756f2724eSchristos #endif /*0*/
308a6f3f22fSchristos 
309a6f3f22fSchristos //-------------------------
310a6f3f22fSchristos 
3114c290c01Schristos void
3124c290c01Schristos setUp(void)
313a6f3f22fSchristos {
314a6f3f22fSchristos     ntpcal_set_timefunc(timefunc);
315a6f3f22fSchristos     settime(1970, 1, 1, 0, 0, 0);
316a6f3f22fSchristos     leapsec_ut_pristine();
317a6f3f22fSchristos }
318a6f3f22fSchristos 
3194c290c01Schristos void
3204c290c01Schristos tearDown(void)
321a6f3f22fSchristos {
322a6f3f22fSchristos     ntpcal_set_timefunc(NULL);
323a6f3f22fSchristos }
324a6f3f22fSchristos 
325a6f3f22fSchristos // =====================================================================
326a6f3f22fSchristos // VALIDATION TESTS
327a6f3f22fSchristos // =====================================================================
328a6f3f22fSchristos 
329a6f3f22fSchristos // ----------------------------------------------------------------------
33056f2724eSchristos extern void test_ValidateGood(void);
33156f2724eSchristos void test_ValidateGood(void)
3324c290c01Schristos {
333a6f3f22fSchristos 	const char *cp = leap_ghash;
334a6f3f22fSchristos 	int         rc = leapsec_validate(stringreader, &cp);
3354c290c01Schristos 
336a6f3f22fSchristos 	TEST_ASSERT_EQUAL(LSVALID_GOODHASH, rc);
337a6f3f22fSchristos }
338a6f3f22fSchristos 
339a6f3f22fSchristos // ----------------------------------------------------------------------
34056f2724eSchristos extern void test_ValidateNoHash(void);
34156f2724eSchristos void test_ValidateNoHash(void)
3424c290c01Schristos {
343a6f3f22fSchristos 	const char *cp = leap2;
344a6f3f22fSchristos 	int         rc = leapsec_validate(stringreader, &cp);
3454c290c01Schristos 
346a6f3f22fSchristos 	TEST_ASSERT_EQUAL(LSVALID_NOHASH, rc);
347a6f3f22fSchristos }
348a6f3f22fSchristos 
349a6f3f22fSchristos // ----------------------------------------------------------------------
35056f2724eSchristos extern void test_ValidateBad(void);
35156f2724eSchristos void test_ValidateBad(void)
3524c290c01Schristos {
353a6f3f22fSchristos 	const char *cp = leap_bhash;
354a6f3f22fSchristos 	int         rc = leapsec_validate(stringreader, &cp);
3554c290c01Schristos 
356a6f3f22fSchristos 	TEST_ASSERT_EQUAL(LSVALID_BADHASH, rc);
357a6f3f22fSchristos }
358a6f3f22fSchristos 
359a6f3f22fSchristos // ----------------------------------------------------------------------
36056f2724eSchristos extern void test_ValidateMalformed(void);
36156f2724eSchristos void test_ValidateMalformed(void)
3624c290c01Schristos {
363a6f3f22fSchristos 	const char *cp = leap_mhash;
364a6f3f22fSchristos 	int         rc = leapsec_validate(stringreader, &cp);
3654c290c01Schristos 
366a6f3f22fSchristos 	TEST_ASSERT_EQUAL(LSVALID_BADFORMAT, rc);
367a6f3f22fSchristos }
368a6f3f22fSchristos 
369a6f3f22fSchristos // ----------------------------------------------------------------------
37056f2724eSchristos extern void test_ValidateMalformedShort(void);
37156f2724eSchristos void test_ValidateMalformedShort(void)
3724c290c01Schristos {
373a6f3f22fSchristos 	const char *cp = leap_shash;
374a6f3f22fSchristos 	int         rc = leapsec_validate(stringreader, &cp);
3754c290c01Schristos 
376a6f3f22fSchristos 	TEST_ASSERT_EQUAL(LSVALID_BADFORMAT, rc);
377a6f3f22fSchristos }
378a6f3f22fSchristos 
379a6f3f22fSchristos // ----------------------------------------------------------------------
38056f2724eSchristos extern void test_ValidateNoLeadZero(void);
38156f2724eSchristos void test_ValidateNoLeadZero(void)
3824c290c01Schristos {
383a6f3f22fSchristos 	const char *cp = leap_gthash;
384a6f3f22fSchristos 	int         rc = leapsec_validate(stringreader, &cp);
3854c290c01Schristos 
386a6f3f22fSchristos 	TEST_ASSERT_EQUAL(LSVALID_GOODHASH, rc);
387a6f3f22fSchristos }
388a6f3f22fSchristos 
389a6f3f22fSchristos // =====================================================================
390a6f3f22fSchristos // BASIC FUNCTIONS
391a6f3f22fSchristos // =====================================================================
392a6f3f22fSchristos 
393a6f3f22fSchristos // ----------------------------------------------------------------------
394a6f3f22fSchristos // test table selection
39556f2724eSchristos extern void test_tableSelect(void);
39656f2724eSchristos void test_tableSelect(void)
3974c290c01Schristos {
39856f2724eSchristos     leap_table_t *pt1, *pt2, *pt3;
399a6f3f22fSchristos 
400a6f3f22fSchristos 	pt1 = leapsec_get_table(0);
401a6f3f22fSchristos 	pt2 = leapsec_get_table(0);
402a6f3f22fSchristos 	TEST_ASSERT_EQUAL_MESSAGE(pt1, pt2,"first");
403a6f3f22fSchristos 
404a6f3f22fSchristos 	pt1 = leapsec_get_table(1);
405a6f3f22fSchristos 	pt2 = leapsec_get_table(1);
406a6f3f22fSchristos 	TEST_ASSERT_EQUAL_MESSAGE(pt1, pt2,"second");
407a6f3f22fSchristos 
408a6f3f22fSchristos 	pt1 = leapsec_get_table(1);
409a6f3f22fSchristos 	pt2 = leapsec_get_table(0);
410a6f3f22fSchristos 	TEST_ASSERT_NOT_EQUAL(pt1, pt2);
411a6f3f22fSchristos 
412a6f3f22fSchristos 	pt1 = leapsec_get_table(0);
413a6f3f22fSchristos 	pt2 = leapsec_get_table(1);
414a6f3f22fSchristos 	TEST_ASSERT_NOT_EQUAL(pt1, pt2);
415a6f3f22fSchristos 
416a6f3f22fSchristos 	leapsec_set_table(pt1);
417a6f3f22fSchristos 	pt2 = leapsec_get_table(0);
418a6f3f22fSchristos 	pt3 = leapsec_get_table(1);
419a6f3f22fSchristos 	TEST_ASSERT_EQUAL(pt1, pt2);
420a6f3f22fSchristos 	TEST_ASSERT_NOT_EQUAL(pt2, pt3);
421a6f3f22fSchristos 
422a6f3f22fSchristos 	pt1 = pt3;
423a6f3f22fSchristos 	leapsec_set_table(pt1);
424a6f3f22fSchristos 	pt2 = leapsec_get_table(0);
425a6f3f22fSchristos 	pt3 = leapsec_get_table(1);
426a6f3f22fSchristos 	TEST_ASSERT_EQUAL(pt1, pt2);
427a6f3f22fSchristos 	TEST_ASSERT_NOT_EQUAL(pt2, pt3);
428a6f3f22fSchristos }
429a6f3f22fSchristos 
430a6f3f22fSchristos // ----------------------------------------------------------------------
431a6f3f22fSchristos // load file & check expiration
43256f2724eSchristos extern void test_loadFileExpire(void);
43356f2724eSchristos void test_loadFileExpire(void)
4344c290c01Schristos {
435a6f3f22fSchristos 	const char *cp = leap1;
436a6f3f22fSchristos 	int rc;
437a6f3f22fSchristos 	leap_table_t * pt = leapsec_get_table(0);
438a6f3f22fSchristos 
439a6f3f22fSchristos 	rc =   leapsec_load(pt, stringreader, &cp, FALSE)
440a6f3f22fSchristos 	    && leapsec_set_table(pt);
441a6f3f22fSchristos 	TEST_ASSERT_EQUAL_MESSAGE(1, rc,"first");
442a6f3f22fSchristos 	rc = leapsec_expired(3439756800u, NULL);
443a6f3f22fSchristos 	TEST_ASSERT_EQUAL(0, rc);
444a6f3f22fSchristos 	rc = leapsec_expired(3610569601u, NULL);
445a6f3f22fSchristos 	TEST_ASSERT_EQUAL(1, rc);
446a6f3f22fSchristos }
447a6f3f22fSchristos 
448a6f3f22fSchristos // ----------------------------------------------------------------------
449a6f3f22fSchristos // load file & check time-to-live
45056f2724eSchristos extern void test_loadFileTTL(void);
45156f2724eSchristos void test_loadFileTTL(void)
4524c290c01Schristos {
453a6f3f22fSchristos 	const char     *cp = leap1;
454a6f3f22fSchristos 	int		rc;
455a6f3f22fSchristos 	leap_table_t  * pt = leapsec_get_table(0);
456a6f3f22fSchristos 	time_t		pivot = 0x70000000u;
457a6f3f22fSchristos 	const uint32_t	limit = 3610569600u;
458a6f3f22fSchristos 
459a6f3f22fSchristos 	rc =   leapsec_load(pt, stringreader, &cp, FALSE)
460a6f3f22fSchristos 	    && leapsec_set_table(pt);
461a6f3f22fSchristos 	TEST_ASSERT_EQUAL(1, rc); //
462a6f3f22fSchristos 
463a6f3f22fSchristos 	// exactly 1 day to live
464a6f3f22fSchristos 	rc = leapsec_daystolive(limit - 86400, &pivot);
465a6f3f22fSchristos 	TEST_ASSERT_EQUAL( 1, rc);
466a6f3f22fSchristos 	// less than 1 day to live
467a6f3f22fSchristos 	rc = leapsec_daystolive(limit - 86399, &pivot);
468a6f3f22fSchristos 	TEST_ASSERT_EQUAL( 0, rc);
469a6f3f22fSchristos 	// hit expiration exactly
470a6f3f22fSchristos 	rc = leapsec_daystolive(limit, &pivot);
471a6f3f22fSchristos 	TEST_ASSERT_EQUAL( 0, rc);
472a6f3f22fSchristos 	// expired since 1 sec
473a6f3f22fSchristos 	rc = leapsec_daystolive(limit + 1, &pivot);
474a6f3f22fSchristos 	TEST_ASSERT_EQUAL(-1, rc);
475a6f3f22fSchristos }
476a6f3f22fSchristos 
477a6f3f22fSchristos // =====================================================================
478a6f3f22fSchristos // RANDOM QUERY TESTS
479a6f3f22fSchristos // =====================================================================
480a6f3f22fSchristos 
481a6f3f22fSchristos // ----------------------------------------------------------------------
482a6f3f22fSchristos // test query in pristine state (bug#2745 misbehaviour)
48356f2724eSchristos extern void test_lsQueryPristineState(void);
48456f2724eSchristos void test_lsQueryPristineState(void)
4854c290c01Schristos {
486a6f3f22fSchristos 	int            rc;
487a6f3f22fSchristos 	leap_result_t  qr;
488a6f3f22fSchristos 
489a6f3f22fSchristos 	rc = leapsec_query(&qr, lsec2012, NULL);
490a6f3f22fSchristos 	TEST_ASSERT_EQUAL(FALSE, rc);
491a6f3f22fSchristos 	TEST_ASSERT_EQUAL(0,             qr.warped   );
492a6f3f22fSchristos 	TEST_ASSERT_EQUAL(LSPROX_NOWARN, qr.proximity);
493a6f3f22fSchristos }
494a6f3f22fSchristos 
495a6f3f22fSchristos // ----------------------------------------------------------------------
496a6f3f22fSchristos // ad-hoc jump: leap second at 2009.01.01 -60days
49756f2724eSchristos extern void test_ls2009faraway(void);
49856f2724eSchristos void test_ls2009faraway(void)
4994c290c01Schristos {
500a6f3f22fSchristos 	int            rc;
501a6f3f22fSchristos 	leap_result_t  qr;
502a6f3f22fSchristos 
503a6f3f22fSchristos 	rc = setup_load_table(leap1,FALSE);
504a6f3f22fSchristos 	TEST_ASSERT_EQUAL(1, rc);
505a6f3f22fSchristos 
506a6f3f22fSchristos 	// test 60 days before leap. Nothing scheduled or indicated.
507a6f3f22fSchristos 	rc = leapsec_query(&qr, lsec2009 - 60*SECSPERDAY, NULL);
508a6f3f22fSchristos 	TEST_ASSERT_EQUAL(FALSE, rc);
509a6f3f22fSchristos 	TEST_ASSERT_EQUAL(33, qr.tai_offs);
510a6f3f22fSchristos 	TEST_ASSERT_EQUAL(0,  qr.tai_diff);
511a6f3f22fSchristos 	TEST_ASSERT_EQUAL(LSPROX_NOWARN, qr.proximity);
512a6f3f22fSchristos }
513a6f3f22fSchristos 
514a6f3f22fSchristos // ----------------------------------------------------------------------
515a6f3f22fSchristos // ad-hoc jump: leap second at 2009.01.01 -1week
51656f2724eSchristos extern void test_ls2009weekaway(void);
51756f2724eSchristos void test_ls2009weekaway(void)
5184c290c01Schristos {
519a6f3f22fSchristos 	int            rc;
520a6f3f22fSchristos 	leap_result_t  qr;
521a6f3f22fSchristos 
522a6f3f22fSchristos 	rc = setup_load_table(leap1,FALSE);
523a6f3f22fSchristos 	TEST_ASSERT_EQUAL(1, rc);
524a6f3f22fSchristos 
525a6f3f22fSchristos 	// test 7 days before leap. Leap scheduled, but not yet indicated.
526a6f3f22fSchristos 	rc = leapsec_query(&qr, lsec2009 - 7*SECSPERDAY, NULL);
527a6f3f22fSchristos 	TEST_ASSERT_EQUAL(FALSE, rc);
528a6f3f22fSchristos 	TEST_ASSERT_EQUAL(33, qr.tai_offs);
529a6f3f22fSchristos 	TEST_ASSERT_EQUAL(1,  qr.tai_diff);
530a6f3f22fSchristos 	TEST_ASSERT_EQUAL(LSPROX_SCHEDULE, qr.proximity);
531a6f3f22fSchristos }
532a6f3f22fSchristos 
533a6f3f22fSchristos // ----------------------------------------------------------------------
534a6f3f22fSchristos // ad-hoc jump: leap second at 2009.01.01 -1hr
53556f2724eSchristos extern void test_ls2009houraway(void);
53656f2724eSchristos void test_ls2009houraway(void)
5374c290c01Schristos {
538a6f3f22fSchristos 	int            rc;
539a6f3f22fSchristos 	leap_result_t  qr;
540a6f3f22fSchristos 
541a6f3f22fSchristos 	rc = setup_load_table(leap1,FALSE);
542a6f3f22fSchristos 	TEST_ASSERT_EQUAL(1, rc);
543a6f3f22fSchristos 
544a6f3f22fSchristos 	// test 1 hour before leap. 61 true seconds to go.
545a6f3f22fSchristos 	rc = leapsec_query(&qr, lsec2009 - SECSPERHR, NULL);
546a6f3f22fSchristos 	TEST_ASSERT_EQUAL(FALSE, rc);
547a6f3f22fSchristos 	TEST_ASSERT_EQUAL(33, qr.tai_offs);
548a6f3f22fSchristos 	TEST_ASSERT_EQUAL(1,  qr.tai_diff);
549a6f3f22fSchristos 	TEST_ASSERT_EQUAL(LSPROX_ANNOUNCE, qr.proximity);
550a6f3f22fSchristos }
551a6f3f22fSchristos 
552a6f3f22fSchristos // ----------------------------------------------------------------------
553a6f3f22fSchristos // ad-hoc jump: leap second at 2009.01.01 -1sec
55456f2724eSchristos extern void test_ls2009secaway(void);
55556f2724eSchristos void test_ls2009secaway(void)
5564c290c01Schristos {
557a6f3f22fSchristos 	int            rc;
558a6f3f22fSchristos 	leap_result_t  qr;
559a6f3f22fSchristos 
560a6f3f22fSchristos 	rc = setup_load_table(leap1,FALSE);
561a6f3f22fSchristos 	TEST_ASSERT_EQUAL(1, rc);
562a6f3f22fSchristos 
563a6f3f22fSchristos 	// test 1 second before leap (last boundary...) 2 true seconds to go.
564a6f3f22fSchristos 	rc = leapsec_query(&qr, lsec2009 - 1, NULL);
565a6f3f22fSchristos 	TEST_ASSERT_EQUAL(FALSE, rc);
566a6f3f22fSchristos 	TEST_ASSERT_EQUAL(33, qr.tai_offs);
567a6f3f22fSchristos 	TEST_ASSERT_EQUAL(1,  qr.tai_diff);
568a6f3f22fSchristos 	TEST_ASSERT_EQUAL(LSPROX_ALERT, qr.proximity);
569a6f3f22fSchristos }
570a6f3f22fSchristos 
571a6f3f22fSchristos // ----------------------------------------------------------------------
572a6f3f22fSchristos // ad-hoc jump to leap second at 2009.01.01
57356f2724eSchristos extern void test_ls2009onspot(void);
57456f2724eSchristos void test_ls2009onspot(void)
5754c290c01Schristos {
576a6f3f22fSchristos 	int            rc;
577a6f3f22fSchristos 	leap_result_t  qr;
578a6f3f22fSchristos 
579a6f3f22fSchristos 	rc = setup_load_table(leap1,FALSE);
580a6f3f22fSchristos 	TEST_ASSERT_EQUAL(1, rc);
581a6f3f22fSchristos 
582a6f3f22fSchristos 	// test on-spot: treat leap second as already gone.
583a6f3f22fSchristos 	rc = leapsec_query(&qr, lsec2009, NULL);
584a6f3f22fSchristos 	TEST_ASSERT_EQUAL(FALSE, rc);
585a6f3f22fSchristos 	TEST_ASSERT_EQUAL(34, qr.tai_offs);
586a6f3f22fSchristos 	TEST_ASSERT_EQUAL(0,  qr.tai_diff);
587a6f3f22fSchristos 	TEST_ASSERT_EQUAL(LSPROX_NOWARN, qr.proximity);
588a6f3f22fSchristos }
589a6f3f22fSchristos 
590a6f3f22fSchristos // ----------------------------------------------------------------------
591a6f3f22fSchristos // test handling of the leap second at 2009.01.01 without table
59256f2724eSchristos extern void test_ls2009nodata(void);
59356f2724eSchristos void test_ls2009nodata(void)
5944c290c01Schristos {
595a6f3f22fSchristos 	int            rc;
596a6f3f22fSchristos 	leap_result_t  qr;
597a6f3f22fSchristos 
598a6f3f22fSchristos 	rc = setup_clear_table();
599a6f3f22fSchristos 	TEST_ASSERT_EQUAL(1, rc);
600a6f3f22fSchristos 
601a6f3f22fSchristos 	// test on-spot with empty table
602a6f3f22fSchristos 	rc = leapsec_query(&qr, lsec2009, NULL);
603a6f3f22fSchristos 	TEST_ASSERT_EQUAL(FALSE, rc);
604a6f3f22fSchristos 	TEST_ASSERT_EQUAL(0,  qr.tai_offs);
605a6f3f22fSchristos 	TEST_ASSERT_EQUAL(0,  qr.tai_diff);
606a6f3f22fSchristos 	TEST_ASSERT_EQUAL(LSPROX_NOWARN, qr.proximity);
607a6f3f22fSchristos }
608a6f3f22fSchristos 
609a6f3f22fSchristos // ----------------------------------------------------------------------
610a6f3f22fSchristos // test handling of the leap second at 2009.01.01 with culled data
61156f2724eSchristos extern void test_ls2009limdata(void);
61256f2724eSchristos void test_ls2009limdata(void)
6134c290c01Schristos {
614a6f3f22fSchristos 	int            rc;
615a6f3f22fSchristos 	leap_result_t  qr;
616a6f3f22fSchristos 
617a6f3f22fSchristos 	rc = setup_load_table(leap1, TRUE);
618a6f3f22fSchristos 	TEST_ASSERT_EQUAL(1, rc);
619a6f3f22fSchristos 
620a6f3f22fSchristos 	// test on-spot with limited table - this is tricky.
621a6f3f22fSchristos 	// The table used ends 2012; depending on the build date, the 2009 entry
622a6f3f22fSchristos 	// might be included or culled. The resulting TAI offset must be either
623a6f3f22fSchristos 	// 34 or 35 seconds, depending on the build date of the test.
624a6f3f22fSchristos 	rc = leapsec_query(&qr, lsec2009, NULL);
625a6f3f22fSchristos 	TEST_ASSERT_EQUAL(FALSE, rc);
626a6f3f22fSchristos 	TEST_ASSERT_TRUE(34 <= qr.tai_offs);
627a6f3f22fSchristos 	TEST_ASSERT_TRUE(35 >= qr.tai_offs);
628a6f3f22fSchristos 	TEST_ASSERT_EQUAL(0,  qr.tai_diff);
629a6f3f22fSchristos 	TEST_ASSERT_EQUAL(LSPROX_NOWARN, qr.proximity);
630a6f3f22fSchristos }
631a6f3f22fSchristos 
632a6f3f22fSchristos // ----------------------------------------------------------------------
633a6f3f22fSchristos // Far-distance forward jump into a transiton window.
63456f2724eSchristos extern void test_qryJumpFarAhead(void);
63556f2724eSchristos void test_qryJumpFarAhead(void)
6364c290c01Schristos {
637a6f3f22fSchristos 	int		rc;
638a6f3f22fSchristos 	leap_result_t	qr;
639a6f3f22fSchristos 	int		mode;
640a6f3f22fSchristos 
641a6f3f22fSchristos 	for (mode=0; mode < 2; ++mode) {
642a6f3f22fSchristos 		leapsec_ut_pristine();
643a6f3f22fSchristos 		rc = setup_load_table(leap1, FALSE);
644a6f3f22fSchristos 		TEST_ASSERT_EQUAL(1, rc);
645a6f3f22fSchristos 		leapsec_electric(mode);
646a6f3f22fSchristos 
647a6f3f22fSchristos 		rc = leapsec_query(&qr, lsec2006, NULL);
648a6f3f22fSchristos 		TEST_ASSERT_EQUAL(FALSE, rc);
649a6f3f22fSchristos 
650a6f3f22fSchristos 		rc = leapsec_query(&qr, lsec2012, NULL);
651a6f3f22fSchristos 		TEST_ASSERT_EQUAL(FALSE, rc);
652a6f3f22fSchristos 	}
653a6f3f22fSchristos }
654a6f3f22fSchristos 
655a6f3f22fSchristos // ----------------------------------------------------------------------
656a6f3f22fSchristos // Forward jump into the next transition window
65756f2724eSchristos extern void test_qryJumpAheadToTransition(void);
65856f2724eSchristos void test_qryJumpAheadToTransition(void)
65956f2724eSchristos {
660a6f3f22fSchristos 	int		rc;
661a6f3f22fSchristos 	leap_result_t	qr;
662a6f3f22fSchristos 	int		mode;
663a6f3f22fSchristos 
664a6f3f22fSchristos 	for (mode=0; mode < 2; ++mode) {
665a6f3f22fSchristos 		leapsec_ut_pristine();
666a6f3f22fSchristos 		rc = setup_load_table(leap1, FALSE);
667a6f3f22fSchristos 		TEST_ASSERT_EQUAL(1, rc);
668a6f3f22fSchristos 		leapsec_electric(mode);
669a6f3f22fSchristos 
670a6f3f22fSchristos 		rc = leapsec_query(&qr, lsec2009-SECSPERDAY, NULL);
671a6f3f22fSchristos 		TEST_ASSERT_EQUAL(FALSE, rc);
672a6f3f22fSchristos 
673a6f3f22fSchristos 		rc = leapsec_query(&qr, lsec2009+1, NULL);
674a6f3f22fSchristos 		TEST_ASSERT_EQUAL(TRUE, rc);
675a6f3f22fSchristos 	}
676a6f3f22fSchristos }
677a6f3f22fSchristos 
678a6f3f22fSchristos // ----------------------------------------------------------------------
679a6f3f22fSchristos // Forward jump over the next transition window
68056f2724eSchristos extern void test_qryJumpAheadOverTransition(void);
68156f2724eSchristos void test_qryJumpAheadOverTransition(void)
6824c290c01Schristos {
683a6f3f22fSchristos 	int		rc;
684a6f3f22fSchristos 	leap_result_t	qr;
685a6f3f22fSchristos 	int		mode;
686a6f3f22fSchristos 
687a6f3f22fSchristos 	for (mode=0; mode < 2; ++mode) {
688a6f3f22fSchristos 		leapsec_ut_pristine();
689a6f3f22fSchristos 		rc = setup_load_table(leap1, FALSE);
690a6f3f22fSchristos 		TEST_ASSERT_EQUAL(1, rc);
691a6f3f22fSchristos 		leapsec_electric(mode);
692a6f3f22fSchristos 
693a6f3f22fSchristos 		rc = leapsec_query(&qr, lsec2009-SECSPERDAY, NULL);
694a6f3f22fSchristos 		TEST_ASSERT_EQUAL(FALSE, rc);
695a6f3f22fSchristos 
696a6f3f22fSchristos 		rc = leapsec_query(&qr, lsec2009+5, NULL);
697a6f3f22fSchristos 		TEST_ASSERT_EQUAL(FALSE, rc);
698a6f3f22fSchristos 	}
699a6f3f22fSchristos }
700a6f3f22fSchristos 
701a6f3f22fSchristos // =====================================================================
702a6f3f22fSchristos // TABLE MODIFICATION AT RUNTIME
703a6f3f22fSchristos // =====================================================================
704a6f3f22fSchristos 
705a6f3f22fSchristos // ----------------------------------------------------------------------
706a6f3f22fSchristos // add dynamic leap second (like from peer/clock)
70756f2724eSchristos extern void test_addDynamic(void);
70856f2724eSchristos void test_addDynamic(void)
7094c290c01Schristos {
710a6f3f22fSchristos 	int            rc;
711a6f3f22fSchristos 
712a6f3f22fSchristos 	static const uint32_t insns[] = {
713a6f3f22fSchristos 		2982009600u,	//	29	# 1 Jul 1994
714a6f3f22fSchristos 		3029443200u,	//	30	# 1 Jan 1996
715a6f3f22fSchristos 		3076704000u,	//	31	# 1 Jul 1997
716a6f3f22fSchristos 		3124137600u,	//	32	# 1 Jan 1999
717a6f3f22fSchristos 		3345062400u,	//	33	# 1 Jan 2006
718a6f3f22fSchristos 		3439756800u,	//	34	# 1 Jan 2009
719a6f3f22fSchristos 		3550089600u,	//	35	# 1 Jul 2012
720a6f3f22fSchristos 		0 // sentinel
721a6f3f22fSchristos 	};
722a6f3f22fSchristos 
723a6f3f22fSchristos 	rc = setup_load_table(leap2, FALSE);
724a6f3f22fSchristos 	TEST_ASSERT_EQUAL(1, rc);
725a6f3f22fSchristos 
726a6f3f22fSchristos 	int		idx;
727a6f3f22fSchristos 
728a6f3f22fSchristos 	for (idx=1; insns[idx]; ++idx) {
729a6f3f22fSchristos 		rc = leapsec_add_dyn(TRUE, insns[idx] - 20*SECSPERDAY - 100, NULL);
730a6f3f22fSchristos 		TEST_ASSERT_EQUAL(TRUE, rc);
731a6f3f22fSchristos 	}
732a6f3f22fSchristos 	// try to slip in a previous entry
733a6f3f22fSchristos 	rc = leapsec_add_dyn(TRUE, insns[0] - 20*SECSPERDAY - 100, NULL);
734a6f3f22fSchristos 	TEST_ASSERT_EQUAL(FALSE, rc);
7354c290c01Schristos 	//leap_table_t  * pt = leapsec_get_table(0);
736a6f3f22fSchristos 	//leapsec_dump(pt, (leapsec_dumper)fprintf, stdout);
737a6f3f22fSchristos }
738a6f3f22fSchristos 
739a6f3f22fSchristos // ----------------------------------------------------------------------
740a6f3f22fSchristos // add fixed leap seconds (like from network packet)
741a6f3f22fSchristos #if 0 /* currently unused -- possibly revived later */
74256f2724eSchristos extern void no_test_addFixed(void);
74356f2724eSchristos void no_test_addFixed(void)
7444c290c01Schristos {
745a6f3f22fSchristos 	int            rc;
746a6f3f22fSchristos 	leap_result_t  qr;
747a6f3f22fSchristos 
748a6f3f22fSchristos 	static const struct { uint32_t tt; int of; } insns[] = {
749a6f3f22fSchristos 		{2982009600u, 29},//	# 1 Jul 1994
750a6f3f22fSchristos 		{3029443200u, 30},//	# 1 Jan 1996
751a6f3f22fSchristos 		{3076704000u, 31},//	# 1 Jul 1997
752a6f3f22fSchristos 		{3124137600u, 32},//	# 1 Jan 1999
753a6f3f22fSchristos 		{3345062400u, 33},//	# 1 Jan 2006
754a6f3f22fSchristos 		{3439756800u, 34},//	# 1 Jan 2009
755a6f3f22fSchristos 		{3550089600u, 35},//	# 1 Jul 2012
756a6f3f22fSchristos 		{0,0} // sentinel
757a6f3f22fSchristos 	};
758a6f3f22fSchristos 
759a6f3f22fSchristos 	rc = setup_load_table(leap2, FALSE);
760a6f3f22fSchristos 	TEST_ASSERT_EQUAL(1, rc);
7614c290c01Schristos 
762a6f3f22fSchristos 	int idx;
763a6f3f22fSchristos 	// try to get in BAD time stamps...
764a6f3f22fSchristos 	for (idx=0; insns[idx].tt; ++idx) {
765a6f3f22fSchristos 	    rc = leapsec_add_fix(
766a6f3f22fSchristos 		insns[idx].of,
767a6f3f22fSchristos 		insns[idx].tt - 20*SECSPERDAY - 100,
768a6f3f22fSchristos 		insns[idx].tt + SECSPERDAY,
769a6f3f22fSchristos 		NULL);
770a6f3f22fSchristos 		TEST_ASSERT_EQUAL(FALSE, rc);
771a6f3f22fSchristos 	}
772a6f3f22fSchristos 	// now do it right
773a6f3f22fSchristos 	for (idx=0; insns[idx].tt; ++idx) {
774a6f3f22fSchristos 		rc = leapsec_add_fix(
775a6f3f22fSchristos 		    insns[idx].of,
776a6f3f22fSchristos 		    insns[idx].tt,
777a6f3f22fSchristos 		    insns[idx].tt + SECSPERDAY,
778a6f3f22fSchristos 		    NULL);
779a6f3f22fSchristos 		TEST_ASSERT_EQUAL(TRUE, rc);
780a6f3f22fSchristos 	}
781a6f3f22fSchristos 	// try to slip in a previous entry
782a6f3f22fSchristos 	rc = leapsec_add_fix(
783a6f3f22fSchristos 	    insns[0].of,
784a6f3f22fSchristos 	    insns[0].tt,
785a6f3f22fSchristos 	    insns[0].tt + SECSPERDAY,
786a6f3f22fSchristos 	    NULL);
787a6f3f22fSchristos 	TEST_ASSERT_EQUAL(FALSE, rc);
7884c290c01Schristos 	//leap_table_t * pt = leapsec_get_table(0);
789a6f3f22fSchristos 	//leapsec_dump(pt, (leapsec_dumper)fprintf, stdout);
790a6f3f22fSchristos }
791a6f3f22fSchristos #endif
792a6f3f22fSchristos 
793a6f3f22fSchristos // ----------------------------------------------------------------------
794a6f3f22fSchristos // add fixed leap seconds (like from network packet)
795a6f3f22fSchristos #if 0 /* currently unused -- possibly revived later */
79656f2724eSchristos extern void no_test_addFixedExtend(void);
79756f2724eSchristos void no_test_addFixedExtend(void)
7984c290c01Schristos {
799a6f3f22fSchristos 	int            rc;
800a6f3f22fSchristos 	leap_result_t  qr;
801a6f3f22fSchristos 	int            last, idx;
802a6f3f22fSchristos 
803a6f3f22fSchristos 	static const struct { uint32_t tt; int of; } insns[] = {
804a6f3f22fSchristos 		{2982009600u, 29},//	# 1 Jul 1994
805a6f3f22fSchristos 		{3029443200u, 30},//	# 1 Jan 1996
806a6f3f22fSchristos 		{0,0} // sentinel
807a6f3f22fSchristos 	};
808a6f3f22fSchristos 
809a6f3f22fSchristos 	rc = setup_load_table(leap2, FALSE);
810a6f3f22fSchristos 	TEST_ASSERT_EQUAL(1, rc);
811a6f3f22fSchristos 
812a6f3f22fSchristos 	for (last=idx=0; insns[idx].tt; ++idx) {
813a6f3f22fSchristos 		last = idx;
814a6f3f22fSchristos 		rc = leapsec_add_fix(
815a6f3f22fSchristos 		    insns[idx].of,
816a6f3f22fSchristos 		    insns[idx].tt,
817a6f3f22fSchristos 		    insns[idx].tt + SECSPERDAY,
818a6f3f22fSchristos 		    NULL);
819a6f3f22fSchristos 		TEST_ASSERT_EQUAL(TRUE, rc);
820a6f3f22fSchristos 	}
821a6f3f22fSchristos 
822a6f3f22fSchristos 	// try to extend the expiration of the last entry
823a6f3f22fSchristos 	rc = leapsec_add_fix(
824a6f3f22fSchristos 	    insns[last].of,
825a6f3f22fSchristos 	    insns[last].tt,
826a6f3f22fSchristos 	    insns[last].tt + 128*SECSPERDAY,
827a6f3f22fSchristos 	    NULL);
828a6f3f22fSchristos 	TEST_ASSERT_EQUAL(TRUE, rc);
829a6f3f22fSchristos 
830a6f3f22fSchristos 	// try to extend the expiration of the last entry with wrong offset
831a6f3f22fSchristos 	rc = leapsec_add_fix(
832a6f3f22fSchristos 	    insns[last].of+1,
833a6f3f22fSchristos 	    insns[last].tt,
834a6f3f22fSchristos 	    insns[last].tt + 129*SECSPERDAY,
835a6f3f22fSchristos 	    NULL);
836a6f3f22fSchristos 	TEST_ASSERT_EQUAL(FALSE, rc);
8374c290c01Schristos 	//leap_table_t * pt = leapsec_get_table(FALSE);
838a6f3f22fSchristos 	//leapsec_dump(pt, (leapsec_dumper)fprintf, stdout);
839a6f3f22fSchristos }
840a6f3f22fSchristos #endif
841a6f3f22fSchristos 
842a6f3f22fSchristos // ----------------------------------------------------------------------
843a6f3f22fSchristos // add fixed leap seconds (like from network packet) in an otherwise
844a6f3f22fSchristos // empty table and test queries before / between /after the tabulated
845a6f3f22fSchristos // values.
846a6f3f22fSchristos #if 0 /* currently unused -- possibly revived later */
84756f2724eSchristos extern void no_test_setFixedExtend(void);
84856f2724eSchristos void no_test_setFixedExtend(void)
8494c290c01Schristos {
850a6f3f22fSchristos 	int            rc;
851a6f3f22fSchristos 	leap_result_t  qr;
852a6f3f22fSchristos 	int            last, idx;
853a6f3f22fSchristos 
854a6f3f22fSchristos 	static const struct { uint32_t tt; int of; } insns[] = {
855a6f3f22fSchristos 		{2982009600u, 29},//	# 1 Jul 1994
856a6f3f22fSchristos 		{3029443200u, 30},//	# 1 Jan 1996
857a6f3f22fSchristos 		{0,0} // sentinel
858a6f3f22fSchristos 	};
859a6f3f22fSchristos 
860a6f3f22fSchristos 	for (last=idx=0; insns[idx].tt; ++idx) {
861a6f3f22fSchristos 		last = idx;
862a6f3f22fSchristos 		rc = leapsec_add_fix(
863a6f3f22fSchristos 		    insns[idx].of,
864a6f3f22fSchristos 		    insns[idx].tt,
865a6f3f22fSchristos 		    insns[idx].tt + 128*SECSPERDAY,
866a6f3f22fSchristos 		    NULL);
867a6f3f22fSchristos 		TEST_ASSERT_EQUAL(TRUE, rc);
868a6f3f22fSchristos 	}
869a6f3f22fSchristos 
870a6f3f22fSchristos 	rc = leapsec_query(&qr, insns[0].tt - 86400, NULL);
871a6f3f22fSchristos 	TEST_ASSERT_EQUAL(28, qr.tai_offs);
872a6f3f22fSchristos 
873a6f3f22fSchristos 	rc = leapsec_query(&qr, insns[0].tt + 86400, NULL);
874a6f3f22fSchristos 	TEST_ASSERT_EQUAL(29, qr.tai_offs);
875a6f3f22fSchristos 
876a6f3f22fSchristos 	rc = leapsec_query(&qr, insns[1].tt - 86400, NULL);
877a6f3f22fSchristos 	TEST_ASSERT_EQUAL(29, qr.tai_offs);
878a6f3f22fSchristos 
879a6f3f22fSchristos 	rc = leapsec_query(&qr, insns[1].tt + 86400, NULL);
880a6f3f22fSchristos 	TEST_ASSERT_EQUAL(30, qr.tai_offs);
881a6f3f22fSchristos 
8824c290c01Schristos 	//leap_table_t * pt = leapsec_get_table(0);
883a6f3f22fSchristos 	//leapsec_dump(pt, (leapsec_dumper)fprintf, stdout);
884a6f3f22fSchristos }
885a6f3f22fSchristos #endif
886a6f3f22fSchristos 
887a6f3f22fSchristos // =====================================================================
888a6f3f22fSchristos // AUTOKEY LEAP TRANSFER TESTS
889a6f3f22fSchristos // =====================================================================
890a6f3f22fSchristos 
891a6f3f22fSchristos // ----------------------------------------------------------------------
892a6f3f22fSchristos // Check if the offset can be applied to an empty table ONCE
89356f2724eSchristos extern void test_taiEmptyTable(void);
89456f2724eSchristos void test_taiEmptyTable(void)
89556f2724eSchristos {
896a6f3f22fSchristos 	int rc;
897a6f3f22fSchristos 
898a6f3f22fSchristos 	rc = leapsec_autokey_tai(35, lsec2015-30*86400, NULL);
899a6f3f22fSchristos 	TEST_ASSERT_EQUAL(TRUE, rc);
900a6f3f22fSchristos 
901a6f3f22fSchristos 	rc = leapsec_autokey_tai(35, lsec2015-29*86400, NULL);
902a6f3f22fSchristos 	TEST_ASSERT_EQUAL(FALSE, rc);
903a6f3f22fSchristos }
904a6f3f22fSchristos 
905a6f3f22fSchristos // ----------------------------------------------------------------------
906a6f3f22fSchristos // Check that with fixed entries the operation fails
90756f2724eSchristos extern void test_taiTableFixed(void);
90856f2724eSchristos void test_taiTableFixed(void)
9094c290c01Schristos {
910a6f3f22fSchristos 	int rc;
911a6f3f22fSchristos 
912a6f3f22fSchristos 	rc = setup_load_table(leap1, FALSE);
913a6f3f22fSchristos 	TEST_ASSERT_EQUAL(1, rc);
914a6f3f22fSchristos 
915a6f3f22fSchristos 	rc = leapsec_autokey_tai(35, lsec2015-30*86400, NULL);
916a6f3f22fSchristos 	TEST_ASSERT_EQUAL(FALSE, rc);
917a6f3f22fSchristos }
918a6f3f22fSchristos 
919a6f3f22fSchristos // ----------------------------------------------------------------------
920a6f3f22fSchristos // test adjustment with a dynamic entry already there
92156f2724eSchristos extern void test_taiTableDynamic(void);
92256f2724eSchristos void test_taiTableDynamic(void)
9234c290c01Schristos {
924a6f3f22fSchristos 	int        rc;
925a6f3f22fSchristos 	leap_era_t era;
926a6f3f22fSchristos 
927a6f3f22fSchristos 	rc = leapsec_add_dyn(TRUE, lsec2015-20*SECSPERDAY, NULL);
928a6f3f22fSchristos 	TEST_ASSERT_EQUAL(TRUE, rc);
929a6f3f22fSchristos 
930a6f3f22fSchristos 	leapsec_query_era(&era, lsec2015-10, NULL);
931a6f3f22fSchristos 	TEST_ASSERT_EQUAL(0, era.taiof);
932a6f3f22fSchristos 	leapsec_query_era(&era, lsec2015+10, NULL);
933a6f3f22fSchristos 	TEST_ASSERT_EQUAL(1, era.taiof);
934a6f3f22fSchristos 
935a6f3f22fSchristos 	rc = leapsec_autokey_tai(35, lsec2015-19*86400, NULL);
936a6f3f22fSchristos 	TEST_ASSERT_EQUAL(TRUE, rc);
937a6f3f22fSchristos 
938a6f3f22fSchristos 	rc = leapsec_autokey_tai(35, lsec2015-19*86400, NULL);
939a6f3f22fSchristos 	TEST_ASSERT_EQUAL(FALSE, rc);
940a6f3f22fSchristos 
941a6f3f22fSchristos 	leapsec_query_era(&era, lsec2015-10, NULL);
942a6f3f22fSchristos 	TEST_ASSERT_EQUAL(35, era.taiof);
943a6f3f22fSchristos 	leapsec_query_era(&era, lsec2015+10, NULL);
944a6f3f22fSchristos 	TEST_ASSERT_EQUAL(36, era.taiof);
945a6f3f22fSchristos }
946a6f3f22fSchristos 
947a6f3f22fSchristos // ----------------------------------------------------------------------
948a6f3f22fSchristos // test adjustment with a dynamic entry already there in dead zone
94956f2724eSchristos extern void test_taiTableDynamicDeadZone(void);
95056f2724eSchristos void test_taiTableDynamicDeadZone(void)
9514c290c01Schristos {
952a6f3f22fSchristos 	int rc;
953a6f3f22fSchristos 
954a6f3f22fSchristos 	rc = leapsec_add_dyn(TRUE, lsec2015-20*SECSPERDAY, NULL);
955a6f3f22fSchristos 	TEST_ASSERT_EQUAL(TRUE, rc);
956a6f3f22fSchristos 
957a6f3f22fSchristos 	rc = leapsec_autokey_tai(35, lsec2015-5, NULL);
958a6f3f22fSchristos 	TEST_ASSERT_EQUAL(FALSE, rc);
959a6f3f22fSchristos 
960a6f3f22fSchristos 	rc = leapsec_autokey_tai(35, lsec2015+5, NULL);
961a6f3f22fSchristos 	TEST_ASSERT_EQUAL(FALSE, rc);
962a6f3f22fSchristos }
963a6f3f22fSchristos 
964a6f3f22fSchristos 
965a6f3f22fSchristos // =====================================================================
966a6f3f22fSchristos // SEQUENCE TESTS
967a6f3f22fSchristos // =====================================================================
968a6f3f22fSchristos 
969a6f3f22fSchristos // ----------------------------------------------------------------------
970a6f3f22fSchristos // leap second insert at 2009.01.01, electric mode
97156f2724eSchristos extern void test_ls2009seqInsElectric(void);
97256f2724eSchristos void test_ls2009seqInsElectric(void)
9734c290c01Schristos {
974a6f3f22fSchristos 	int            rc;
975a6f3f22fSchristos 	leap_result_t  qr;
976a6f3f22fSchristos 
977a6f3f22fSchristos 	rc = setup_load_table(leap1,FALSE);
978a6f3f22fSchristos 	TEST_ASSERT_EQUAL(1, rc);
979a6f3f22fSchristos 	leapsec_electric(1);
980a6f3f22fSchristos 	TEST_ASSERT_EQUAL(1, leapsec_electric(-1));
981a6f3f22fSchristos 
982a6f3f22fSchristos 	rc = leapsec_query(&qr, lsec2009 - 60*SECSPERDAY, NULL);
983a6f3f22fSchristos 	TEST_ASSERT_EQUAL(FALSE, rc);
984a6f3f22fSchristos 	TEST_ASSERT_EQUAL(0,             qr.warped   );
985a6f3f22fSchristos 	TEST_ASSERT_EQUAL(LSPROX_NOWARN, qr.proximity);
986a6f3f22fSchristos 
987a6f3f22fSchristos 	rc = leapsec_query(&qr, lsec2009 - 7*SECSPERDAY, NULL);
988a6f3f22fSchristos 	TEST_ASSERT_EQUAL(FALSE, rc);
989a6f3f22fSchristos 	TEST_ASSERT_EQUAL(0,               qr.warped   );
990a6f3f22fSchristos 	TEST_ASSERT_EQUAL(LSPROX_SCHEDULE, qr.proximity);
991a6f3f22fSchristos 
992a6f3f22fSchristos 	rc = leapsec_query(&qr, lsec2009 - SECSPERHR, NULL);
993a6f3f22fSchristos 	TEST_ASSERT_EQUAL(FALSE, rc);
994a6f3f22fSchristos 	TEST_ASSERT_EQUAL(0,               qr.warped   );
995a6f3f22fSchristos 	TEST_ASSERT_EQUAL(LSPROX_ANNOUNCE, qr.proximity);
996a6f3f22fSchristos 
997a6f3f22fSchristos 	rc = leapsec_query(&qr, lsec2009 - 1, NULL);
998a6f3f22fSchristos 	TEST_ASSERT_EQUAL(FALSE, rc);
999a6f3f22fSchristos 	TEST_ASSERT_EQUAL(0,               qr.warped   );
1000a6f3f22fSchristos 	TEST_ASSERT_EQUAL(LSPROX_ALERT,    qr.proximity);
1001a6f3f22fSchristos 
1002a6f3f22fSchristos 	rc = leapsec_query(&qr, lsec2009, NULL);
1003a6f3f22fSchristos 	TEST_ASSERT_EQUAL(TRUE, rc);
1004a6f3f22fSchristos 	TEST_ASSERT_EQUAL(0,             qr.warped   );
1005a6f3f22fSchristos 	TEST_ASSERT_EQUAL(LSPROX_NOWARN, qr.proximity);
1006a6f3f22fSchristos 
1007a6f3f22fSchristos 	// second call, same time frame: no trigger!
1008a6f3f22fSchristos 	rc = leapsec_query(&qr, lsec2009, NULL);
1009a6f3f22fSchristos 	TEST_ASSERT_EQUAL(FALSE, rc);
1010a6f3f22fSchristos 	TEST_ASSERT_EQUAL(0,             qr.warped   );
1011a6f3f22fSchristos 	TEST_ASSERT_EQUAL(LSPROX_NOWARN, qr.proximity);
1012a6f3f22fSchristos }
1013a6f3f22fSchristos 
1014a6f3f22fSchristos // ----------------------------------------------------------------------
1015a6f3f22fSchristos // leap second insert at 2009.01.01, dumb mode
101656f2724eSchristos extern void test_ls2009seqInsDumb(void);
101756f2724eSchristos void test_ls2009seqInsDumb(void)
10184c290c01Schristos {
1019a6f3f22fSchristos 	int            rc;
1020a6f3f22fSchristos 	leap_result_t  qr;
1021a6f3f22fSchristos 
1022a6f3f22fSchristos 	rc = setup_load_table(leap1,FALSE);
1023a6f3f22fSchristos 	TEST_ASSERT_EQUAL(1, rc);
1024a6f3f22fSchristos 	TEST_ASSERT_EQUAL(0, leapsec_electric(-1));
1025a6f3f22fSchristos 
1026a6f3f22fSchristos 	rc = leapsec_query(&qr, lsec2009 - 60*SECSPERDAY, NULL);
1027a6f3f22fSchristos 	TEST_ASSERT_EQUAL(FALSE, rc);
1028a6f3f22fSchristos 	TEST_ASSERT_EQUAL(0,             qr.warped   );
1029a6f3f22fSchristos 	TEST_ASSERT_EQUAL(LSPROX_NOWARN, qr.proximity);
1030a6f3f22fSchristos 
1031a6f3f22fSchristos 	rc = leapsec_query(&qr, lsec2009 - 7*SECSPERDAY, NULL);
1032a6f3f22fSchristos 	TEST_ASSERT_EQUAL(FALSE, rc);
1033a6f3f22fSchristos 	TEST_ASSERT_EQUAL(0,               qr.warped   );
1034a6f3f22fSchristos 	TEST_ASSERT_EQUAL(LSPROX_SCHEDULE, qr.proximity);
1035a6f3f22fSchristos 
1036a6f3f22fSchristos 	rc = leapsec_query(&qr, lsec2009 - SECSPERHR, NULL);
1037a6f3f22fSchristos 	TEST_ASSERT_EQUAL(FALSE, rc);
1038a6f3f22fSchristos 	TEST_ASSERT_EQUAL(0,               qr.warped   );
1039a6f3f22fSchristos 	TEST_ASSERT_EQUAL(LSPROX_ANNOUNCE, qr.proximity);
1040a6f3f22fSchristos 
1041a6f3f22fSchristos 	rc = leapsec_query(&qr, lsec2009 - 1, NULL);
1042a6f3f22fSchristos 	TEST_ASSERT_EQUAL(FALSE, rc);
1043a6f3f22fSchristos 	TEST_ASSERT_EQUAL(0,               qr.warped   );
1044a6f3f22fSchristos 	TEST_ASSERT_EQUAL(LSPROX_ALERT,    qr.proximity);
1045a6f3f22fSchristos 
1046a6f3f22fSchristos 	rc = leapsec_query(&qr, lsec2009, NULL);
1047a6f3f22fSchristos 	TEST_ASSERT_EQUAL(FALSE, rc);
1048a6f3f22fSchristos 	TEST_ASSERT_EQUAL(0,               qr.warped   );
1049a6f3f22fSchristos 	TEST_ASSERT_EQUAL(LSPROX_ALERT,    qr.proximity);
1050a6f3f22fSchristos 
1051a6f3f22fSchristos 	rc = leapsec_query(&qr, lsec2009+1, NULL);
1052a6f3f22fSchristos 	TEST_ASSERT_EQUAL(TRUE, rc);
1053a6f3f22fSchristos 	TEST_ASSERT_EQUAL(-1,             qr.warped   );
1054a6f3f22fSchristos 	TEST_ASSERT_EQUAL(LSPROX_NOWARN, qr.proximity);
1055a6f3f22fSchristos 
1056a6f3f22fSchristos 	// second call, same time frame: no trigger!
1057a6f3f22fSchristos 	rc = leapsec_query(&qr, lsec2009, NULL);
1058a6f3f22fSchristos 	TEST_ASSERT_EQUAL(FALSE, rc);
1059a6f3f22fSchristos 	TEST_ASSERT_EQUAL(0,             qr.warped   );
1060a6f3f22fSchristos 	TEST_ASSERT_EQUAL(LSPROX_NOWARN, qr.proximity);
1061a6f3f22fSchristos }
1062a6f3f22fSchristos 
1063a6f3f22fSchristos // ----------------------------------------------------------------------
1064a6f3f22fSchristos // fake leap second remove at 2009.01.01, electric mode
106556f2724eSchristos extern void test_ls2009seqDelElectric(void);
106656f2724eSchristos void test_ls2009seqDelElectric(void)
10674c290c01Schristos {
1068a6f3f22fSchristos 	int            rc;
1069a6f3f22fSchristos 	leap_result_t  qr;
1070a6f3f22fSchristos 
1071a6f3f22fSchristos 	rc = setup_load_table(leap3,FALSE);
1072a6f3f22fSchristos 	TEST_ASSERT_EQUAL(1, rc);
1073a6f3f22fSchristos 	leapsec_electric(1);
1074a6f3f22fSchristos 	TEST_ASSERT_EQUAL(1, leapsec_electric(-1));
1075a6f3f22fSchristos 
1076a6f3f22fSchristos 	rc = leapsec_query(&qr, lsec2009 - 60*SECSPERDAY, NULL);
1077a6f3f22fSchristos 	TEST_ASSERT_EQUAL(FALSE, rc);
1078a6f3f22fSchristos 	TEST_ASSERT_EQUAL(0,             qr.warped   );
1079a6f3f22fSchristos 	TEST_ASSERT_EQUAL(LSPROX_NOWARN, qr.proximity);
1080a6f3f22fSchristos 
1081a6f3f22fSchristos 	rc = leapsec_query(&qr, lsec2009 - 7*SECSPERDAY, NULL);
1082a6f3f22fSchristos 	TEST_ASSERT_EQUAL(FALSE, rc);
1083a6f3f22fSchristos 	TEST_ASSERT_EQUAL(0,               qr.warped   );
1084a6f3f22fSchristos 	TEST_ASSERT_EQUAL(LSPROX_SCHEDULE, qr.proximity);
1085a6f3f22fSchristos 
1086a6f3f22fSchristos 	rc = leapsec_query(&qr, lsec2009 - SECSPERHR, NULL);
1087a6f3f22fSchristos 	TEST_ASSERT_EQUAL(FALSE, rc);
1088a6f3f22fSchristos 	TEST_ASSERT_EQUAL(0,               qr.warped   );
1089a6f3f22fSchristos 	TEST_ASSERT_EQUAL(LSPROX_ANNOUNCE, qr.proximity);
1090a6f3f22fSchristos 
1091a6f3f22fSchristos 	rc = leapsec_query(&qr, lsec2009 - 1, NULL);
1092a6f3f22fSchristos 	TEST_ASSERT_EQUAL(FALSE, rc);
1093a6f3f22fSchristos 	TEST_ASSERT_EQUAL(0,               qr.warped   );
1094a6f3f22fSchristos 	TEST_ASSERT_EQUAL(LSPROX_ALERT,    qr.proximity);
1095a6f3f22fSchristos 
1096a6f3f22fSchristos 	rc = leapsec_query(&qr, lsec2009, NULL);
1097a6f3f22fSchristos 	TEST_ASSERT_EQUAL(TRUE, rc);
1098a6f3f22fSchristos 	TEST_ASSERT_EQUAL(0,             qr.warped   );
1099a6f3f22fSchristos 	TEST_ASSERT_EQUAL(LSPROX_NOWARN, qr.proximity);
1100a6f3f22fSchristos 
1101a6f3f22fSchristos 	// second call, same time frame: no trigger!
1102a6f3f22fSchristos 	rc = leapsec_query(&qr, lsec2009, NULL);
1103a6f3f22fSchristos 	TEST_ASSERT_EQUAL(FALSE, rc);
1104a6f3f22fSchristos 	TEST_ASSERT_EQUAL(0,             qr.warped   );
1105a6f3f22fSchristos 	TEST_ASSERT_EQUAL(LSPROX_NOWARN, qr.proximity);
1106a6f3f22fSchristos }
1107a6f3f22fSchristos 
1108a6f3f22fSchristos // ----------------------------------------------------------------------
1109a6f3f22fSchristos // fake leap second remove at 2009.01.01. dumb mode
111056f2724eSchristos extern void test_ls2009seqDelDumb(void);
111156f2724eSchristos void test_ls2009seqDelDumb(void)
11124c290c01Schristos {
1113a6f3f22fSchristos 	int            rc;
1114a6f3f22fSchristos 	leap_result_t  qr;
1115a6f3f22fSchristos 
1116a6f3f22fSchristos 	rc = setup_load_table(leap3,FALSE);
1117a6f3f22fSchristos 	TEST_ASSERT_EQUAL(1, rc);
1118a6f3f22fSchristos 	TEST_ASSERT_EQUAL(0, leapsec_electric(-1));
1119a6f3f22fSchristos 
1120a6f3f22fSchristos 	rc = leapsec_query(&qr, lsec2009 - 60*SECSPERDAY, NULL);
1121a6f3f22fSchristos 	TEST_ASSERT_EQUAL(FALSE, rc);
1122a6f3f22fSchristos 	TEST_ASSERT_EQUAL(0,             qr.warped   );
1123a6f3f22fSchristos 	TEST_ASSERT_EQUAL(LSPROX_NOWARN, qr.proximity);
1124a6f3f22fSchristos 
1125a6f3f22fSchristos 	rc = leapsec_query(&qr, lsec2009 - 7*SECSPERDAY, NULL);
1126a6f3f22fSchristos 	TEST_ASSERT_EQUAL(FALSE, rc);
1127a6f3f22fSchristos 	TEST_ASSERT_EQUAL(0,               qr.warped   );
1128a6f3f22fSchristos 	TEST_ASSERT_EQUAL(LSPROX_SCHEDULE, qr.proximity);
1129a6f3f22fSchristos 
1130a6f3f22fSchristos 	rc = leapsec_query(&qr, lsec2009 - SECSPERHR, NULL);
1131a6f3f22fSchristos 	TEST_ASSERT_EQUAL(FALSE, rc);
1132a6f3f22fSchristos 	TEST_ASSERT_EQUAL(0,               qr.warped   );
1133a6f3f22fSchristos 	TEST_ASSERT_EQUAL(LSPROX_ANNOUNCE, qr.proximity);
1134a6f3f22fSchristos 
1135a6f3f22fSchristos 	rc = leapsec_query(&qr, lsec2009 - 2, NULL);
1136a6f3f22fSchristos 	TEST_ASSERT_EQUAL(FALSE, rc);
1137a6f3f22fSchristos 	TEST_ASSERT_EQUAL(0,               qr.warped   );
1138a6f3f22fSchristos 	TEST_ASSERT_EQUAL(LSPROX_ALERT,    qr.proximity);
1139a6f3f22fSchristos 
1140a6f3f22fSchristos 	rc = leapsec_query(&qr, lsec2009 - 1, NULL);
1141a6f3f22fSchristos 	TEST_ASSERT_EQUAL(TRUE, rc);
1142a6f3f22fSchristos 	TEST_ASSERT_EQUAL(1,             qr.warped   );
1143a6f3f22fSchristos 	TEST_ASSERT_EQUAL(LSPROX_NOWARN, qr.proximity);
1144a6f3f22fSchristos 
1145a6f3f22fSchristos 	// second call, same time frame: no trigger!
1146a6f3f22fSchristos 	rc = leapsec_query(&qr, lsec2009, NULL);
1147a6f3f22fSchristos 	TEST_ASSERT_EQUAL(FALSE, rc);
1148a6f3f22fSchristos 	TEST_ASSERT_EQUAL(0,             qr.warped   );
1149a6f3f22fSchristos 	TEST_ASSERT_EQUAL(LSPROX_NOWARN, qr.proximity);
1150a6f3f22fSchristos }
1151a6f3f22fSchristos 
1152a6f3f22fSchristos // ----------------------------------------------------------------------
1153a6f3f22fSchristos // leap second insert at 2012.07.01, electric mode
115456f2724eSchristos extern void test_ls2012seqInsElectric(void);
115556f2724eSchristos void test_ls2012seqInsElectric(void)
11564c290c01Schristos {
1157a6f3f22fSchristos 	int            rc;
1158a6f3f22fSchristos 	leap_result_t  qr;
1159a6f3f22fSchristos 
1160a6f3f22fSchristos 	rc = setup_load_table(leap1,FALSE);
1161a6f3f22fSchristos 	TEST_ASSERT_EQUAL(1, rc);
1162a6f3f22fSchristos 	leapsec_electric(1);
1163a6f3f22fSchristos 	TEST_ASSERT_EQUAL(1, leapsec_electric(-1));
1164a6f3f22fSchristos 
1165a6f3f22fSchristos 	rc = leapsec_query(&qr, lsec2012 - 60*SECSPERDAY, NULL);
1166a6f3f22fSchristos 	TEST_ASSERT_EQUAL(FALSE, rc);
1167a6f3f22fSchristos 	TEST_ASSERT_EQUAL(0,             qr.warped   );
1168a6f3f22fSchristos 	TEST_ASSERT_EQUAL(LSPROX_NOWARN, qr.proximity);
1169a6f3f22fSchristos 
1170a6f3f22fSchristos 	rc = leapsec_query(&qr, lsec2012 - 7*SECSPERDAY, NULL);
1171a6f3f22fSchristos 	TEST_ASSERT_EQUAL(FALSE, rc);
1172a6f3f22fSchristos 	TEST_ASSERT_EQUAL(0,               qr.warped   );
1173a6f3f22fSchristos 	TEST_ASSERT_EQUAL(LSPROX_SCHEDULE, qr.proximity);
1174a6f3f22fSchristos 
1175a6f3f22fSchristos 	rc = leapsec_query(&qr, lsec2012 - SECSPERHR, NULL);
1176a6f3f22fSchristos 	TEST_ASSERT_EQUAL(FALSE, rc);
1177a6f3f22fSchristos 	TEST_ASSERT_EQUAL(0,               qr.warped   );
1178a6f3f22fSchristos 	TEST_ASSERT_EQUAL(LSPROX_ANNOUNCE, qr.proximity);
1179a6f3f22fSchristos 
1180a6f3f22fSchristos 	rc = leapsec_query(&qr, lsec2012 - 1, NULL);
1181a6f3f22fSchristos 	TEST_ASSERT_EQUAL(FALSE, rc);
1182a6f3f22fSchristos 	TEST_ASSERT_EQUAL(0,               qr.warped   );
1183a6f3f22fSchristos 	TEST_ASSERT_EQUAL(LSPROX_ALERT,    qr.proximity);
1184a6f3f22fSchristos 
1185a6f3f22fSchristos 	rc = leapsec_query(&qr, lsec2012, NULL);
1186a6f3f22fSchristos 	TEST_ASSERT_EQUAL(TRUE, rc);
1187a6f3f22fSchristos 	TEST_ASSERT_EQUAL(0,            qr.warped   );
1188a6f3f22fSchristos 	TEST_ASSERT_EQUAL(LSPROX_NOWARN, qr.proximity);
1189a6f3f22fSchristos 
1190a6f3f22fSchristos 	// second call, same time frame: no trigger!
1191a6f3f22fSchristos 	rc = leapsec_query(&qr, lsec2012, NULL);
1192a6f3f22fSchristos 	TEST_ASSERT_EQUAL(FALSE, rc);
1193a6f3f22fSchristos 	TEST_ASSERT_EQUAL(0,             qr.warped   );
1194a6f3f22fSchristos 	TEST_ASSERT_EQUAL(LSPROX_NOWARN, qr.proximity);
1195a6f3f22fSchristos }
1196a6f3f22fSchristos 
1197a6f3f22fSchristos // ----------------------------------------------------------------------
1198a6f3f22fSchristos // leap second insert at 2012.07.01, dumb mode
119956f2724eSchristos extern void test_ls2012seqInsDumb(void);
120056f2724eSchristos void test_ls2012seqInsDumb(void)
12014c290c01Schristos {
1202a6f3f22fSchristos 	int            rc;
1203a6f3f22fSchristos 	leap_result_t  qr;
1204a6f3f22fSchristos 
1205a6f3f22fSchristos 	rc = setup_load_table(leap1,FALSE);
1206a6f3f22fSchristos 	TEST_ASSERT_EQUAL(1, rc);
1207a6f3f22fSchristos 	TEST_ASSERT_EQUAL(0, leapsec_electric(-1));
1208a6f3f22fSchristos 
1209a6f3f22fSchristos 	rc = leapsec_query(&qr, lsec2012 - 60*SECSPERDAY, NULL);
1210a6f3f22fSchristos 	TEST_ASSERT_EQUAL(FALSE, rc);
1211a6f3f22fSchristos 	TEST_ASSERT_EQUAL(0,             qr.warped   );
1212a6f3f22fSchristos 	TEST_ASSERT_EQUAL(LSPROX_NOWARN, qr.proximity);
1213a6f3f22fSchristos 
1214a6f3f22fSchristos 	rc = leapsec_query(&qr, lsec2012 - 7*SECSPERDAY, NULL);
1215a6f3f22fSchristos 	TEST_ASSERT_EQUAL(FALSE, rc);
1216a6f3f22fSchristos 	TEST_ASSERT_EQUAL(0,               qr.warped   );
1217a6f3f22fSchristos 	TEST_ASSERT_EQUAL(LSPROX_SCHEDULE, qr.proximity);
1218a6f3f22fSchristos 
1219a6f3f22fSchristos 	rc = leapsec_query(&qr, lsec2012 - SECSPERHR, NULL);
1220a6f3f22fSchristos 	TEST_ASSERT_EQUAL(FALSE, rc);
1221a6f3f22fSchristos 	TEST_ASSERT_EQUAL(0,               qr.warped   );
1222a6f3f22fSchristos 	TEST_ASSERT_EQUAL(LSPROX_ANNOUNCE, qr.proximity);
1223a6f3f22fSchristos 
1224a6f3f22fSchristos 	rc = leapsec_query(&qr, lsec2012 - 1, NULL);
1225a6f3f22fSchristos 	TEST_ASSERT_EQUAL(FALSE, rc);
1226a6f3f22fSchristos 	TEST_ASSERT_EQUAL(0,               qr.warped   );
1227a6f3f22fSchristos 	TEST_ASSERT_EQUAL(LSPROX_ALERT,    qr.proximity);
1228a6f3f22fSchristos 
1229a6f3f22fSchristos 	// This is just 1 sec before transition!
1230a6f3f22fSchristos 	rc = leapsec_query(&qr, lsec2012, NULL);
1231a6f3f22fSchristos 	TEST_ASSERT_EQUAL(FALSE, rc);
1232a6f3f22fSchristos 	TEST_ASSERT_EQUAL(0,            qr.warped   );
1233a6f3f22fSchristos 	TEST_ASSERT_EQUAL(LSPROX_ALERT, qr.proximity);
1234a6f3f22fSchristos 
1235a6f3f22fSchristos 	// NOW the insert/backwarp must happen
1236a6f3f22fSchristos 	rc = leapsec_query(&qr, lsec2012+1, NULL);
1237a6f3f22fSchristos 	TEST_ASSERT_EQUAL(TRUE, rc);
1238a6f3f22fSchristos 	TEST_ASSERT_EQUAL(-1,            qr.warped   );
1239a6f3f22fSchristos 	TEST_ASSERT_EQUAL(LSPROX_NOWARN, qr.proximity);
1240a6f3f22fSchristos 
1241a6f3f22fSchristos 	// second call with transition time: no trigger!
1242a6f3f22fSchristos 	rc = leapsec_query(&qr, lsec2012, NULL);
1243a6f3f22fSchristos 	TEST_ASSERT_EQUAL(FALSE, rc);
1244a6f3f22fSchristos 	TEST_ASSERT_EQUAL(0,             qr.warped   );
1245a6f3f22fSchristos 	TEST_ASSERT_EQUAL(LSPROX_NOWARN, qr.proximity);
1246a6f3f22fSchristos }
1247a6f3f22fSchristos 
1248a6f3f22fSchristos // ----------------------------------------------------------------------
1249a6f3f22fSchristos // test repeated query on empty table in dumb mode
125056f2724eSchristos extern void test_lsEmptyTableDumb(void);
125156f2724eSchristos void test_lsEmptyTableDumb(void)
12524c290c01Schristos {
1253a6f3f22fSchristos 	int            rc;
1254a6f3f22fSchristos 	leap_result_t  qr;
1255a6f3f22fSchristos 
125656f2724eSchristos 	const time_t   pivot = lsec2012;
1257a6f3f22fSchristos 	const uint32_t t0 = lsec2012 - 10;
1258a6f3f22fSchristos 	const uint32_t tE = lsec2012 + 10;
1259a6f3f22fSchristos 
1260a6f3f22fSchristos 	TEST_ASSERT_EQUAL(0, leapsec_electric(-1));
1261a6f3f22fSchristos 
1262a6f3f22fSchristos 	uint32_t t;
1263a6f3f22fSchristos 	for (t = t0; t != tE; ++t) {
1264a6f3f22fSchristos 		rc = leapsec_query(&qr, t, &pivot);
1265a6f3f22fSchristos 		TEST_ASSERT_EQUAL(FALSE, rc);
1266a6f3f22fSchristos 		TEST_ASSERT_EQUAL(0,             qr.warped   );
1267a6f3f22fSchristos 		TEST_ASSERT_EQUAL(LSPROX_NOWARN, qr.proximity);
1268a6f3f22fSchristos 	}
1269a6f3f22fSchristos }
1270a6f3f22fSchristos 
1271a6f3f22fSchristos // ----------------------------------------------------------------------
1272a6f3f22fSchristos // test repeated query on empty table in electric mode
127356f2724eSchristos extern void test_lsEmptyTableElectric(void);
127456f2724eSchristos void test_lsEmptyTableElectric(void)
12754c290c01Schristos {
1276a6f3f22fSchristos 	int            rc;
1277a6f3f22fSchristos 	leap_result_t  qr;
1278a6f3f22fSchristos 
1279a6f3f22fSchristos 	leapsec_electric(1);
1280a6f3f22fSchristos 	TEST_ASSERT_EQUAL(1, leapsec_electric(-1));
1281a6f3f22fSchristos 
128256f2724eSchristos 	const time_t   pivot = lsec2012;
1283a6f3f22fSchristos 	const uint32_t t0 = lsec2012 - 10;
1284a6f3f22fSchristos 	const uint32_t tE = lsec2012 + 10;
1285a6f3f22fSchristos 
1286a6f3f22fSchristos 	time_t t;
1287a6f3f22fSchristos 	for (t = t0; t != tE; ++t) {
1288a6f3f22fSchristos 		rc = leapsec_query(&qr, t, &pivot);
1289a6f3f22fSchristos 		TEST_ASSERT_EQUAL(FALSE, rc);
1290a6f3f22fSchristos 		TEST_ASSERT_EQUAL(0,             qr.warped   );
1291a6f3f22fSchristos 		TEST_ASSERT_EQUAL(LSPROX_NOWARN, qr.proximity);
1292a6f3f22fSchristos 	}
1293a6f3f22fSchristos }
1294