1290001Sglebius//#include "ntpdtest.h"
2290001Sglebius#include "config.h"
3290001Sglebius
4290001Sglebius
5290001Sglebius#include "ntp.h"
6290001Sglebius#include "ntp_calendar.h"
7290001Sglebius#include "ntp_stdlib.h"
8290001Sglebius#include "ntp_leapsec.h"
9290001Sglebius
10290001Sglebius#include "unity.h"
11290001Sglebius
12290001Sglebius#include <string.h>
13290001Sglebius
14290001Sglebius#include "test-libntp.h"
15290001Sglebius
16290001Sglebiusstatic const char leap1 [] =
17290001Sglebius    "#\n"
18290001Sglebius    "#@ 	3610569600\n"
19290001Sglebius    "#\n"
20290001Sglebius    "2272060800 10	# 1 Jan 1972\n"
21290001Sglebius    "2287785600	11	# 1 Jul 1972\n"
22290001Sglebius    "2303683200	12	# 1 Jan 1973\n"
23290001Sglebius    "2335219200	13	# 1 Jan 1974\n"
24290001Sglebius    "2366755200	14	# 1 Jan 1975\n"
25290001Sglebius    "2398291200	15	# 1 Jan 1976\n"
26290001Sglebius    "2429913600	16	# 1 Jan 1977\n"
27290001Sglebius    "2461449600	17	# 1 Jan 1978\n"
28290001Sglebius    "2492985600	18	# 1 Jan 1979\n"
29290001Sglebius    "2524521600	19	# 1 Jan 1980\n"
30290001Sglebius    "   \t  \n"
31290001Sglebius    "2571782400	20	# 1 Jul 1981\n"
32290001Sglebius    "2603318400	21	# 1 Jul 1982\n"
33290001Sglebius    "2634854400	22	# 1 Jul 1983\n"
34290001Sglebius    "2698012800	23	# 1 Jul 1985\n"
35290001Sglebius    "2776982400	24	# 1 Jan 1988\n"
36290001Sglebius    "2840140800	25	# 1 Jan 1990\n"
37290001Sglebius    "2871676800	26	# 1 Jan 1991\n"
38290001Sglebius    "2918937600	27	# 1 Jul 1992\n"
39290001Sglebius    "2950473600	28	# 1 Jul 1993\n"
40290001Sglebius    "2982009600	29	# 1 Jul 1994\n"
41290001Sglebius    "3029443200	30	# 1 Jan 1996\n"
42290001Sglebius    "3076704000	31	# 1 Jul 1997\n"
43290001Sglebius    "3124137600	32	# 1 Jan 1999\n"
44290001Sglebius    "3345062400	33	# 1 Jan 2006\n"
45290001Sglebius    "3439756800	34	# 1 Jan 2009\n"
46290001Sglebius    "3550089600	35	# 1 Jul 2012\n"
47290001Sglebius    "#\n"
48290001Sglebius    "#h	dc2e6b0b 5aade95d a0587abd 4e0dacb4 e4d5049e\n"
49290001Sglebius    "#\n";
50290001Sglebius
51290001Sglebiusstatic const char leap2 [] =
52290001Sglebius    "#\n"
53290001Sglebius    "#@ 	2950473700\n"
54290001Sglebius    "#\n"
55290001Sglebius    "2272060800 10	# 1 Jan 1972\n"
56290001Sglebius    "2287785600	11	# 1 Jul 1972\n"
57290001Sglebius    "2303683200	12	# 1 Jan 1973\n"
58290001Sglebius    "2335219200	13	# 1 Jan 1974\n"
59290001Sglebius    "2366755200	14	# 1 Jan 1975\n"
60290001Sglebius    "2398291200	15	# 1 Jan 1976\n"
61290001Sglebius    "2429913600	16	# 1 Jan 1977\n"
62290001Sglebius    "2461449600	17	# 1 Jan 1978\n"
63290001Sglebius    "2492985600	18	# 1 Jan 1979\n"
64290001Sglebius    "2524521600	19	# 1 Jan 1980\n"
65290001Sglebius    "2571782400	20	# 1 Jul 1981\n"
66290001Sglebius    "2603318400	21	# 1 Jul 1982\n"
67290001Sglebius    "2634854400	22	# 1 Jul 1983\n"
68290001Sglebius    "2698012800	23	# 1 Jul 1985\n"
69290001Sglebius    "2776982400	24	# 1 Jan 1988\n"
70290001Sglebius    "2840140800	25	# 1 Jan 1990\n"
71290001Sglebius    "2871676800	26	# 1 Jan 1991\n"
72290001Sglebius    "2918937600	27	# 1 Jul 1992\n"
73290001Sglebius    "2950473600	28	# 1 Jul 1993\n"
74290001Sglebius    "#\n";
75290001Sglebius
76290001Sglebius// Faked table with a leap second removal at 2009
77290001Sglebiusstatic const char leap3 [] =
78290001Sglebius    "#\n"
79290001Sglebius    "#@ 	3610569600\n"
80290001Sglebius    "#\n"
81290001Sglebius    "2272060800 10	# 1 Jan 1972\n"
82290001Sglebius    "2287785600	11	# 1 Jul 1972\n"
83290001Sglebius    "2303683200	12	# 1 Jan 1973\n"
84290001Sglebius    "2335219200	13	# 1 Jan 1974\n"
85290001Sglebius    "2366755200	14	# 1 Jan 1975\n"
86290001Sglebius    "2398291200	15	# 1 Jan 1976\n"
87290001Sglebius    "2429913600	16	# 1 Jan 1977\n"
88290001Sglebius    "2461449600	17	# 1 Jan 1978\n"
89290001Sglebius    "2492985600	18	# 1 Jan 1979\n"
90290001Sglebius    "2524521600	19	# 1 Jan 1980\n"
91290001Sglebius    "2571782400	20	# 1 Jul 1981\n"
92290001Sglebius    "2603318400	21	# 1 Jul 1982\n"
93290001Sglebius    "2634854400	22	# 1 Jul 1983\n"
94290001Sglebius    "2698012800	23	# 1 Jul 1985\n"
95290001Sglebius    "2776982400	24	# 1 Jan 1988\n"
96290001Sglebius    "2840140800	25	# 1 Jan 1990\n"
97290001Sglebius    "2871676800	26	# 1 Jan 1991\n"
98290001Sglebius    "2918937600	27	# 1 Jul 1992\n"
99290001Sglebius    "2950473600	28	# 1 Jul 1993\n"
100290001Sglebius    "2982009600	29	# 1 Jul 1994\n"
101290001Sglebius    "3029443200	30	# 1 Jan 1996\n"
102290001Sglebius    "3076704000	31	# 1 Jul 1997\n"
103290001Sglebius    "3124137600	32	# 1 Jan 1999\n"
104290001Sglebius    "3345062400	33	# 1 Jan 2006\n"
105290001Sglebius    "3439756800	32	# 1 Jan 2009\n"
106290001Sglebius    "3550089600	33	# 1 Jul 2012\n"
107290001Sglebius    "#\n";
108290001Sglebius
109290001Sglebius// short table with good hash
110290001Sglebiusstatic const char leap_ghash [] =
111290001Sglebius    "#\n"
112290001Sglebius    "#@ 	3610569600\n"
113290001Sglebius    "#$ 	3610566000\n"
114290001Sglebius    "#\n"
115290001Sglebius    "2272060800 10	# 1 Jan 1972\n"
116290001Sglebius    "2287785600	11	# 1 Jul 1972\n"
117290001Sglebius    "2303683200	12	# 1 Jan 1973\n"
118290001Sglebius    "2335219200	13	# 1 Jan 1974\n"
119290001Sglebius    "2366755200	14	# 1 Jan 1975\n"
120290001Sglebius    "2398291200	15	# 1 Jan 1976\n"
121290001Sglebius    "2429913600	16	# 1 Jan 1977\n"
122290001Sglebius    "2461449600	17	# 1 Jan 1978\n"
123290001Sglebius    "2492985600	18	# 1 Jan 1979\n"
124290001Sglebius    "2524521600	19	# 1 Jan 1980\n"
125290001Sglebius    "#\n"
126290001Sglebius    "#h 4b304e10 95642b3f c10b91f9 90791725 25f280d0\n"
127290001Sglebius    "#\n";
128290001Sglebius
129290001Sglebius// short table with bad hash
130290001Sglebiusstatic const char leap_bhash [] =
131290001Sglebius    "#\n"
132290001Sglebius    "#@ 	3610569600\n"
133290001Sglebius    "#$ 	3610566000\n"
134290001Sglebius    "#\n"
135290001Sglebius    "2272060800 10	# 1 Jan 1972\n"
136290001Sglebius    "2287785600	11	# 1 Jul 1972\n"
137290001Sglebius    "2303683200	12	# 1 Jan 1973\n"
138290001Sglebius    "2335219200	13	# 1 Jan 1974\n"
139290001Sglebius    "2366755200	14	# 1 Jan 1975\n"
140290001Sglebius    "2398291200	15	# 1 Jan 1976\n"
141290001Sglebius    "2429913600	16	# 1 Jan 1977\n"
142290001Sglebius    "2461449600	17	# 1 Jan 1978\n"
143290001Sglebius    "2492985600	18	# 1 Jan 1979\n"
144290001Sglebius    "2524521600	19	# 1 Jan 1980\n"
145290001Sglebius    "#\n"
146290001Sglebius    "#h	dc2e6b0b 5aade95d a0587abd 4e0dacb4 e4d5049e\n"
147290001Sglebius    "#\n";
148290001Sglebius
149290001Sglebius// short table with malformed hash
150290001Sglebiusstatic const char leap_mhash [] =
151290001Sglebius    "#\n"
152290001Sglebius    "#@ 	3610569600\n"
153290001Sglebius    "#$ 	3610566000\n"
154290001Sglebius    "#\n"
155290001Sglebius    "2272060800 10	# 1 Jan 1972\n"
156290001Sglebius    "2287785600	11	# 1 Jul 1972\n"
157290001Sglebius    "2303683200	12	# 1 Jan 1973\n"
158290001Sglebius    "2335219200	13	# 1 Jan 1974\n"
159290001Sglebius    "2366755200	14	# 1 Jan 1975\n"
160290001Sglebius    "2398291200	15	# 1 Jan 1976\n"
161290001Sglebius    "2429913600	16	# 1 Jan 1977\n"
162290001Sglebius    "2461449600	17	# 1 Jan 1978\n"
163290001Sglebius    "2492985600	18	# 1 Jan 1979\n"
164290001Sglebius    "2524521600	19	# 1 Jan 1980\n"
165290001Sglebius    "#\n"
166290001Sglebius    "#h f2349a02 788b9534 a8f2e141 f2029Q6d 4064a7ee\n"
167290001Sglebius    "#\n";
168290001Sglebius
169290001Sglebius// short table with only 4 hash groups
170290001Sglebiusstatic const char leap_shash [] =
171290001Sglebius    "#\n"
172290001Sglebius    "#@ 	3610569600\n"
173290001Sglebius    "#$ 	3610566000\n"
174290001Sglebius    "#\n"
175290001Sglebius    "2272060800 10	# 1 Jan 1972\n"
176290001Sglebius    "2287785600	11	# 1 Jul 1972\n"
177290001Sglebius    "2303683200	12	# 1 Jan 1973\n"
178290001Sglebius    "2335219200	13	# 1 Jan 1974\n"
179290001Sglebius    "2366755200	14	# 1 Jan 1975\n"
180290001Sglebius    "2398291200	15	# 1 Jan 1976\n"
181290001Sglebius    "2429913600	16	# 1 Jan 1977\n"
182290001Sglebius    "2461449600	17	# 1 Jan 1978\n"
183290001Sglebius    "2492985600	18	# 1 Jan 1979\n"
184290001Sglebius    "2524521600	19	# 1 Jan 1980\n"
185290001Sglebius    "#\n"
186290001Sglebius    "#h f2349a02 788b9534 a8f2e141 f2029Q6d\n"
187290001Sglebius    "#\n";
188290001Sglebius
189290001Sglebius// table with good hash and truncated/missing leading zeros
190290001Sglebiusstatic const char leap_gthash [] = {
191290001Sglebius    "#\n"
192290001Sglebius    "#$	 3535228800\n"
193290001Sglebius    "#\n"
194290001Sglebius    "#	Updated through IERS Bulletin C46\n"
195290001Sglebius    "#	File expires on:  28 June 2014\n"
196290001Sglebius    "#\n"
197290001Sglebius    "#@	3612902400\n"
198290001Sglebius    "#\n"
199290001Sglebius    "2272060800	10	# 1 Jan 1972\n"
200290001Sglebius    "2287785600	11	# 1 Jul 1972\n"
201290001Sglebius    "2303683200	12	# 1 Jan 1973\n"
202290001Sglebius    "2335219200	13	# 1 Jan 1974\n"
203290001Sglebius    "2366755200	14	# 1 Jan 1975\n"
204290001Sglebius    "2398291200	15	# 1 Jan 1976\n"
205290001Sglebius    "2429913600	16	# 1 Jan 1977\n"
206290001Sglebius    "2461449600	17	# 1 Jan 1978\n"
207290001Sglebius    "2492985600	18	# 1 Jan 1979\n"
208290001Sglebius    "2524521600	19	# 1 Jan 1980\n"
209290001Sglebius    "2571782400	20	# 1 Jul 1981\n"
210290001Sglebius    "2603318400	21	# 1 Jul 1982\n"
211290001Sglebius    "2634854400	22	# 1 Jul 1983\n"
212290001Sglebius    "2698012800	23	# 1 Jul 1985\n"
213290001Sglebius    "2776982400	24	# 1 Jan 1988\n"
214290001Sglebius    "2840140800	25	# 1 Jan 1990\n"
215290001Sglebius    "2871676800	26	# 1 Jan 1991\n"
216290001Sglebius    "2918937600	27	# 1 Jul 1992\n"
217290001Sglebius    "2950473600	28	# 1 Jul 1993\n"
218290001Sglebius    "2982009600	29	# 1 Jul 1994\n"
219290001Sglebius    "3029443200	30	# 1 Jan 1996\n"
220290001Sglebius    "3076704000	31	# 1 Jul 1997\n"
221290001Sglebius    "3124137600	32	# 1 Jan 1999\n"
222290001Sglebius    "3345062400	33	# 1 Jan 2006\n"
223290001Sglebius    "3439756800	34	# 1 Jan 2009\n"
224290001Sglebius    "3550089600	35	# 1 Jul 2012\n"
225290001Sglebius    "#\n"
226290001Sglebius    "#h	1151a8f e85a5069 9000fcdb 3d5e5365 1d505b37"
227290001Sglebius};
228290001Sglebius
229290001Sglebiusstatic const uint32_t lsec2006 = 3345062400u; // +33, 1 Jan 2006, 00:00:00 utc
230290001Sglebiusstatic const uint32_t lsec2009 = 3439756800u; // +34, 1 Jan 2009, 00:00:00 utc
231290001Sglebiusstatic const uint32_t lsec2012 = 3550089600u; // +35, 1 Jul 2012, 00:00:00 utc
232290001Sglebiusstatic const uint32_t lsec2015 = 3644697600u; // +36, 1 Jul 2015, 00:00:00 utc
233290001Sglebius
234290001Sglebiusint stringreader(void* farg)
235290001Sglebius{
236290001Sglebius	const char ** cpp = (const char**)farg;
237293896Sglebius
238290001Sglebius	if (**cpp)
239290001Sglebius		return *(*cpp)++;
240290001Sglebius	else
241290001Sglebius		return EOF;
242290001Sglebius}
243290001Sglebius
244290001Sglebiusstatic int/*BOOL*/
245290001Sglebiussetup_load_table(
246290001Sglebius	const char * cp,
247290001Sglebius	int          blim)
248290001Sglebius{
249290001Sglebius	int            rc;
250290001Sglebius	leap_table_t * pt = leapsec_get_table(0);
251293896Sglebius
252290001Sglebius	rc = (pt != NULL) && leapsec_load(pt, stringreader, &cp, blim);
253290001Sglebius	rc = rc && leapsec_set_table(pt);
254290001Sglebius	return rc;
255290001Sglebius}
256290001Sglebius
257290001Sglebiusstatic int/*BOOL*/
258290001Sglebiussetup_clear_table(void)
259290001Sglebius{
260290001Sglebius	int            rc;
261290001Sglebius	leap_table_t * pt = leapsec_get_table(0);
262293896Sglebius
263290001Sglebius	if (pt)
264290001Sglebius		leapsec_clear(pt);
265290001Sglebius	rc = leapsec_set_table(pt);
266290001Sglebius	return rc;
267290001Sglebius}
268290001Sglebius
269290001Sglebius
270293896Sglebiuschar *
271293896SglebiusCalendarToString(const struct calendar cal)
272293896Sglebius{
273290001Sglebius	char * ss = malloc (sizeof (char) * 100);
274290001Sglebius	char buffer[100] ="";
275293896Sglebius
276293896Sglebius	*ss = '\0';
277290001Sglebius	sprintf(buffer, "%u", cal.year);
278290001Sglebius	strcat(ss,buffer);
279290001Sglebius	strcat(ss,"-");
280290001Sglebius	sprintf(buffer, "%u", (u_int)cal.month);
281290001Sglebius	strcat(ss,buffer);
282290001Sglebius	strcat(ss,"-");
283290001Sglebius	sprintf(buffer, "%u", (u_int)cal.monthday);
284290001Sglebius	strcat(ss,buffer);
285290001Sglebius	strcat(ss," (");
286290001Sglebius	sprintf(buffer, "%u", (u_int) cal.yearday);
287290001Sglebius	strcat(ss,buffer);
288290001Sglebius	strcat(ss,") ");
289290001Sglebius	sprintf(buffer, "%u", (u_int)cal.hour);
290290001Sglebius	strcat(ss,buffer);
291290001Sglebius	strcat(ss,":");
292290001Sglebius	sprintf(buffer, "%u", (u_int)cal.minute);
293290001Sglebius	strcat(ss,buffer);
294290001Sglebius	strcat(ss,":");
295290001Sglebius	sprintf(buffer, "%u", (u_int)cal.second);
296290001Sglebius	strcat(ss,buffer);
297290001Sglebius	//ss << cal.year << "-" << (u_int)cal.month << "-" << (u_int)cal.monthday << " (" << cal.yearday << ") " << (u_int)cal.hour << ":" << (u_int)cal.minute << ":" << (u_int)cal.second;
298290001Sglebius	return ss;
299290001Sglebius}
300290001Sglebius
301290001Sglebius
302293896Sglebiusint
303293896SglebiusIsEqual(const struct calendar expected, const struct calendar actual)
304293896Sglebius{
305293896Sglebius
306293896Sglebius	if (   expected.year == actual.year
307293896Sglebius	    && (   expected.yearday == actual.yearday
308293896Sglebius		|| (   expected.month == actual.month
309293896Sglebius		    && expected.monthday == actual.monthday))
310293896Sglebius	    && expected.hour == actual.hour
311293896Sglebius	    && expected.minute == actual.minute
312293896Sglebius	    && expected.second == actual.second) {
313290001Sglebius		return TRUE;
314290001Sglebius	} else {
315293896Sglebius		char *p_exp = CalendarToString(expected);
316293896Sglebius		char *p_act = CalendarToString(actual);
317293896Sglebius
318293896Sglebius		printf("expected: %s but was %s", p_exp, p_act);
319293896Sglebius
320293896Sglebius		free(p_exp);
321293896Sglebius		free(p_act);
322290001Sglebius		return FALSE;
323290001Sglebius	}
324290001Sglebius}
325290001Sglebius
326290001Sglebius//-------------------------
327290001Sglebius
328293896Sglebiusvoid
329293896SglebiussetUp(void)
330290001Sglebius{
331290001Sglebius    ntpcal_set_timefunc(timefunc);
332290001Sglebius    settime(1970, 1, 1, 0, 0, 0);
333290001Sglebius    leapsec_ut_pristine();
334293896Sglebius
335293896Sglebius    return;
336290001Sglebius}
337290001Sglebius
338293896Sglebiusvoid
339293896SglebiustearDown(void)
340290001Sglebius{
341290001Sglebius    ntpcal_set_timefunc(NULL);
342293896Sglebius    return;
343290001Sglebius}
344290001Sglebius
345290001Sglebius// =====================================================================
346290001Sglebius// VALIDATION TESTS
347290001Sglebius// =====================================================================
348290001Sglebius
349290001Sglebius// ----------------------------------------------------------------------
350293896Sglebiusvoid
351293896Sglebiustest_ValidateGood(void)
352293896Sglebius{
353290001Sglebius	const char *cp = leap_ghash;
354290001Sglebius	int         rc = leapsec_validate(stringreader, &cp);
355293896Sglebius
356290001Sglebius	TEST_ASSERT_EQUAL(LSVALID_GOODHASH, rc);
357293896Sglebius	return;
358290001Sglebius}
359290001Sglebius
360290001Sglebius// ----------------------------------------------------------------------
361293896Sglebiusvoid
362293896Sglebiustest_ValidateNoHash(void)
363293896Sglebius{
364290001Sglebius	const char *cp = leap2;
365290001Sglebius	int         rc = leapsec_validate(stringreader, &cp);
366293896Sglebius
367290001Sglebius	TEST_ASSERT_EQUAL(LSVALID_NOHASH, rc);
368293896Sglebius	return;
369290001Sglebius}
370290001Sglebius
371290001Sglebius// ----------------------------------------------------------------------
372293896Sglebiusvoid
373293896Sglebiustest_ValidateBad(void)
374293896Sglebius{
375290001Sglebius	const char *cp = leap_bhash;
376290001Sglebius	int         rc = leapsec_validate(stringreader, &cp);
377293896Sglebius
378290001Sglebius	TEST_ASSERT_EQUAL(LSVALID_BADHASH, rc);
379293896Sglebius
380293896Sglebius	return;
381290001Sglebius}
382290001Sglebius
383290001Sglebius// ----------------------------------------------------------------------
384293896Sglebiusvoid
385293896Sglebiustest_ValidateMalformed(void)
386293896Sglebius{
387290001Sglebius	const char *cp = leap_mhash;
388290001Sglebius	int         rc = leapsec_validate(stringreader, &cp);
389293896Sglebius
390290001Sglebius	TEST_ASSERT_EQUAL(LSVALID_BADFORMAT, rc);
391293896Sglebius
392293896Sglebius	return;
393290001Sglebius}
394290001Sglebius
395290001Sglebius// ----------------------------------------------------------------------
396293896Sglebiusvoid
397293896Sglebiustest_ValidateMalformedShort(void)
398293896Sglebius{
399290001Sglebius	const char *cp = leap_shash;
400290001Sglebius	int         rc = leapsec_validate(stringreader, &cp);
401293896Sglebius
402290001Sglebius	TEST_ASSERT_EQUAL(LSVALID_BADFORMAT, rc);
403293896Sglebius
404293896Sglebius	return;
405290001Sglebius}
406290001Sglebius
407290001Sglebius// ----------------------------------------------------------------------
408293896Sglebiusvoid
409293896Sglebiustest_ValidateNoLeadZero(void)
410293896Sglebius{
411290001Sglebius	const char *cp = leap_gthash;
412290001Sglebius	int         rc = leapsec_validate(stringreader, &cp);
413293896Sglebius
414290001Sglebius	TEST_ASSERT_EQUAL(LSVALID_GOODHASH, rc);
415293896Sglebius
416293896Sglebius	return;
417290001Sglebius}
418290001Sglebius
419290001Sglebius// =====================================================================
420290001Sglebius// BASIC FUNCTIONS
421290001Sglebius// =====================================================================
422290001Sglebius
423290001Sglebius// ----------------------------------------------------------------------
424290001Sglebius// test table selection
425293896Sglebiusvoid
426293896Sglebiustest_tableSelect(void)
427293896Sglebius{
428290001Sglebius	leap_table_t *pt1, *pt2, *pt3, *pt4;
429290001Sglebius
430290001Sglebius	pt1 = leapsec_get_table(0);
431290001Sglebius	pt2 = leapsec_get_table(0);
432290001Sglebius	TEST_ASSERT_EQUAL_MESSAGE(pt1, pt2,"first");
433290001Sglebius
434290001Sglebius	pt1 = leapsec_get_table(1);
435290001Sglebius	pt2 = leapsec_get_table(1);
436290001Sglebius	TEST_ASSERT_EQUAL_MESSAGE(pt1, pt2,"second");
437290001Sglebius
438290001Sglebius	pt1 = leapsec_get_table(1);
439290001Sglebius	pt2 = leapsec_get_table(0);
440290001Sglebius	TEST_ASSERT_NOT_EQUAL(pt1, pt2);
441290001Sglebius
442290001Sglebius	pt1 = leapsec_get_table(0);
443290001Sglebius	pt2 = leapsec_get_table(1);
444290001Sglebius	TEST_ASSERT_NOT_EQUAL(pt1, pt2);
445290001Sglebius
446290001Sglebius	leapsec_set_table(pt1);
447290001Sglebius	pt2 = leapsec_get_table(0);
448290001Sglebius	pt3 = leapsec_get_table(1);
449290001Sglebius	TEST_ASSERT_EQUAL(pt1, pt2);
450290001Sglebius	TEST_ASSERT_NOT_EQUAL(pt2, pt3);
451290001Sglebius
452290001Sglebius	pt1 = pt3;
453290001Sglebius	leapsec_set_table(pt1);
454290001Sglebius	pt2 = leapsec_get_table(0);
455290001Sglebius	pt3 = leapsec_get_table(1);
456290001Sglebius	TEST_ASSERT_EQUAL(pt1, pt2);
457290001Sglebius	TEST_ASSERT_NOT_EQUAL(pt2, pt3);
458293896Sglebius
459293896Sglebius	return;
460290001Sglebius}
461290001Sglebius
462290001Sglebius// ----------------------------------------------------------------------
463290001Sglebius// load file & check expiration
464290001Sglebius
465293896Sglebiusvoid
466293896Sglebiustest_loadFileExpire(void)
467293896Sglebius{
468290001Sglebius	const char *cp = leap1;
469290001Sglebius	int rc;
470290001Sglebius	leap_table_t * pt = leapsec_get_table(0);
471290001Sglebius
472290001Sglebius	rc =   leapsec_load(pt, stringreader, &cp, FALSE)
473290001Sglebius	    && leapsec_set_table(pt);
474290001Sglebius	TEST_ASSERT_EQUAL_MESSAGE(1, rc,"first");
475290001Sglebius	rc = leapsec_expired(3439756800u, NULL);
476290001Sglebius	TEST_ASSERT_EQUAL(0, rc);
477290001Sglebius	rc = leapsec_expired(3610569601u, NULL);
478290001Sglebius	TEST_ASSERT_EQUAL(1, rc);
479293896Sglebius
480293896Sglebius	return;
481290001Sglebius}
482290001Sglebius
483290001Sglebius// ----------------------------------------------------------------------
484290001Sglebius// load file & check time-to-live
485290001Sglebius
486293896Sglebiusvoid
487293896Sglebiustest_loadFileTTL(void)
488293896Sglebius{
489293896Sglebius	const char     *cp = leap1;
490293896Sglebius	int		rc;
491293896Sglebius	leap_table_t  * pt = leapsec_get_table(0);
492293896Sglebius	time_t		pivot = 0x70000000u;
493293896Sglebius	const uint32_t	limit = 3610569600u;
494290001Sglebius
495290001Sglebius	rc =   leapsec_load(pt, stringreader, &cp, FALSE)
496290001Sglebius	    && leapsec_set_table(pt);
497290001Sglebius	TEST_ASSERT_EQUAL(1, rc); //
498290001Sglebius
499290001Sglebius	// exactly 1 day to live
500290001Sglebius	rc = leapsec_daystolive(limit - 86400, &pivot);
501293896Sglebius	TEST_ASSERT_EQUAL( 1, rc);
502290001Sglebius	// less than 1 day to live
503290001Sglebius	rc = leapsec_daystolive(limit - 86399, &pivot);
504293896Sglebius	TEST_ASSERT_EQUAL( 0, rc);
505290001Sglebius	// hit expiration exactly
506290001Sglebius	rc = leapsec_daystolive(limit, &pivot);
507293896Sglebius	TEST_ASSERT_EQUAL( 0, rc);
508290001Sglebius	// expired since 1 sec
509290001Sglebius	rc = leapsec_daystolive(limit + 1, &pivot);
510293896Sglebius	TEST_ASSERT_EQUAL(-1, rc);
511293896Sglebius
512293896Sglebius	return;
513290001Sglebius}
514290001Sglebius
515290001Sglebius// =====================================================================
516290001Sglebius// RANDOM QUERY TESTS
517290001Sglebius// =====================================================================
518290001Sglebius
519290001Sglebius// ----------------------------------------------------------------------
520290001Sglebius// test query in pristine state (bug#2745 misbehaviour)
521293896Sglebiusvoid
522293896Sglebiustest_lsQueryPristineState(void)
523293896Sglebius{
524290001Sglebius	int            rc;
525290001Sglebius	leap_result_t  qr;
526293896Sglebius
527290001Sglebius	rc = leapsec_query(&qr, lsec2012, NULL);
528290001Sglebius	TEST_ASSERT_EQUAL(FALSE, rc);
529290001Sglebius	TEST_ASSERT_EQUAL(0,             qr.warped   );
530290001Sglebius	TEST_ASSERT_EQUAL(LSPROX_NOWARN, qr.proximity);
531293896Sglebius
532293896Sglebius	return;
533290001Sglebius}
534290001Sglebius
535290001Sglebius// ----------------------------------------------------------------------
536290001Sglebius// ad-hoc jump: leap second at 2009.01.01 -60days
537293896Sglebiusvoid
538293896Sglebiustest_ls2009faraway(void)
539293896Sglebius{
540290001Sglebius	int            rc;
541290001Sglebius	leap_result_t  qr;
542290001Sglebius
543290001Sglebius	rc = setup_load_table(leap1,FALSE);
544290001Sglebius	TEST_ASSERT_EQUAL(1, rc);
545290001Sglebius
546290001Sglebius	// test 60 days before leap. Nothing scheduled or indicated.
547290001Sglebius	rc = leapsec_query(&qr, lsec2009 - 60*SECSPERDAY, NULL);
548290001Sglebius	TEST_ASSERT_EQUAL(FALSE, rc);
549290001Sglebius	TEST_ASSERT_EQUAL(33, qr.tai_offs);
550290001Sglebius	TEST_ASSERT_EQUAL(0,  qr.tai_diff);
551290001Sglebius	TEST_ASSERT_EQUAL(LSPROX_NOWARN, qr.proximity);
552293896Sglebius
553293896Sglebius	return;
554290001Sglebius}
555290001Sglebius
556290001Sglebius// ----------------------------------------------------------------------
557290001Sglebius// ad-hoc jump: leap second at 2009.01.01 -1week
558293896Sglebiusvoid
559293896Sglebiustest_ls2009weekaway(void)
560293896Sglebius{
561290001Sglebius	int            rc;
562290001Sglebius	leap_result_t  qr;
563290001Sglebius
564290001Sglebius	rc = setup_load_table(leap1,FALSE);
565290001Sglebius	TEST_ASSERT_EQUAL(1, rc);
566290001Sglebius
567290001Sglebius	// test 7 days before leap. Leap scheduled, but not yet indicated.
568290001Sglebius	rc = leapsec_query(&qr, lsec2009 - 7*SECSPERDAY, NULL);
569290001Sglebius	TEST_ASSERT_EQUAL(FALSE, rc);
570290001Sglebius	TEST_ASSERT_EQUAL(33, qr.tai_offs);
571290001Sglebius	TEST_ASSERT_EQUAL(1,  qr.tai_diff);
572290001Sglebius	TEST_ASSERT_EQUAL(LSPROX_SCHEDULE, qr.proximity);
573293896Sglebius
574293896Sglebius	return;
575290001Sglebius}
576290001Sglebius
577290001Sglebius// ----------------------------------------------------------------------
578290001Sglebius// ad-hoc jump: leap second at 2009.01.01 -1hr
579293896Sglebiusvoid
580293896Sglebiustest_ls2009houraway(void)
581293896Sglebius{
582290001Sglebius	int            rc;
583290001Sglebius	leap_result_t  qr;
584290001Sglebius
585290001Sglebius	rc = setup_load_table(leap1,FALSE);
586290001Sglebius	TEST_ASSERT_EQUAL(1, rc);
587290001Sglebius
588290001Sglebius	// test 1 hour before leap. 61 true seconds to go.
589290001Sglebius	rc = leapsec_query(&qr, lsec2009 - SECSPERHR, NULL);
590290001Sglebius	TEST_ASSERT_EQUAL(FALSE, rc);
591290001Sglebius	TEST_ASSERT_EQUAL(33, qr.tai_offs);
592290001Sglebius	TEST_ASSERT_EQUAL(1,  qr.tai_diff);
593290001Sglebius	TEST_ASSERT_EQUAL(LSPROX_ANNOUNCE, qr.proximity);
594293896Sglebius
595293896Sglebius	return;
596290001Sglebius}
597290001Sglebius
598290001Sglebius// ----------------------------------------------------------------------
599290001Sglebius// ad-hoc jump: leap second at 2009.01.01 -1sec
600293896Sglebiusvoid
601293896Sglebiustest_ls2009secaway(void)
602293896Sglebius{
603290001Sglebius	int            rc;
604290001Sglebius	leap_result_t  qr;
605290001Sglebius
606290001Sglebius	rc = setup_load_table(leap1,FALSE);
607290001Sglebius	TEST_ASSERT_EQUAL(1, rc);
608290001Sglebius
609290001Sglebius	// test 1 second before leap (last boundary...) 2 true seconds to go.
610290001Sglebius	rc = leapsec_query(&qr, lsec2009 - 1, NULL);
611290001Sglebius	TEST_ASSERT_EQUAL(FALSE, rc);
612290001Sglebius	TEST_ASSERT_EQUAL(33, qr.tai_offs);
613290001Sglebius	TEST_ASSERT_EQUAL(1,  qr.tai_diff);
614290001Sglebius	TEST_ASSERT_EQUAL(LSPROX_ALERT, qr.proximity);
615293896Sglebius
616293896Sglebius	return;
617290001Sglebius}
618290001Sglebius
619290001Sglebius// ----------------------------------------------------------------------
620290001Sglebius// ad-hoc jump to leap second at 2009.01.01
621293896Sglebiusvoid
622293896Sglebiustest_ls2009onspot(void)
623293896Sglebius{
624290001Sglebius	int            rc;
625290001Sglebius	leap_result_t  qr;
626290001Sglebius
627290001Sglebius	rc = setup_load_table(leap1,FALSE);
628290001Sglebius	TEST_ASSERT_EQUAL(1, rc);
629290001Sglebius
630290001Sglebius	// test on-spot: treat leap second as already gone.
631290001Sglebius	rc = leapsec_query(&qr, lsec2009, NULL);
632290001Sglebius	TEST_ASSERT_EQUAL(FALSE, rc);
633290001Sglebius	TEST_ASSERT_EQUAL(34, qr.tai_offs);
634290001Sglebius	TEST_ASSERT_EQUAL(0,  qr.tai_diff);
635290001Sglebius	TEST_ASSERT_EQUAL(LSPROX_NOWARN, qr.proximity);
636293896Sglebius
637293896Sglebius	return;
638290001Sglebius}
639290001Sglebius
640290001Sglebius// ----------------------------------------------------------------------
641290001Sglebius// test handling of the leap second at 2009.01.01 without table
642293896Sglebiusvoid
643293896Sglebiustest_ls2009nodata(void)
644293896Sglebius{
645290001Sglebius	int            rc;
646290001Sglebius	leap_result_t  qr;
647290001Sglebius
648290001Sglebius	rc = setup_clear_table();
649290001Sglebius	TEST_ASSERT_EQUAL(1, rc);
650290001Sglebius
651290001Sglebius	// test on-spot with empty table
652290001Sglebius	rc = leapsec_query(&qr, lsec2009, NULL);
653290001Sglebius	TEST_ASSERT_EQUAL(FALSE, rc);
654290001Sglebius	TEST_ASSERT_EQUAL(0,  qr.tai_offs);
655290001Sglebius	TEST_ASSERT_EQUAL(0,  qr.tai_diff);
656290001Sglebius	TEST_ASSERT_EQUAL(LSPROX_NOWARN, qr.proximity);
657293896Sglebius
658293896Sglebius	return;
659290001Sglebius}
660290001Sglebius
661290001Sglebius// ----------------------------------------------------------------------
662290001Sglebius// test handling of the leap second at 2009.01.01 with culled data
663293896Sglebiusvoid
664293896Sglebiustest_ls2009limdata(void)
665293896Sglebius{
666290001Sglebius	int            rc;
667290001Sglebius	leap_result_t  qr;
668290001Sglebius
669290001Sglebius	rc = setup_load_table(leap1, TRUE);
670290001Sglebius	TEST_ASSERT_EQUAL(1, rc);
671290001Sglebius
672290001Sglebius	// test on-spot with limited table - this is tricky.
673290001Sglebius	// The table used ends 2012; depending on the build date, the 2009 entry
674290001Sglebius	// might be included or culled. The resulting TAI offset must be either
675290001Sglebius	// 34 or 35 seconds, depending on the build date of the test.
676290001Sglebius	rc = leapsec_query(&qr, lsec2009, NULL);
677290001Sglebius	TEST_ASSERT_EQUAL(FALSE, rc);
678290001Sglebius	TEST_ASSERT_TRUE(34 <= qr.tai_offs);
679290001Sglebius	TEST_ASSERT_TRUE(35 >= qr.tai_offs);
680290001Sglebius	TEST_ASSERT_EQUAL(0,  qr.tai_diff);
681290001Sglebius	TEST_ASSERT_EQUAL(LSPROX_NOWARN, qr.proximity);
682293896Sglebius
683293896Sglebius	return;
684290001Sglebius}
685290001Sglebius
686290001Sglebius// ----------------------------------------------------------------------
687290001Sglebius// Far-distance forward jump into a transiton window.
688293896Sglebiusvoid
689293896Sglebiustest_qryJumpFarAhead(void)
690293896Sglebius{
691290001Sglebius	int            rc;
692290001Sglebius	leap_result_t  qr;
693290001Sglebius	int            last, idx;
694293896Sglebius	int		mode;
695290001Sglebius
696290001Sglebius	for (mode=0; mode < 2; ++mode) {
697290001Sglebius		leapsec_ut_pristine();
698290001Sglebius		rc = setup_load_table(leap1, FALSE);
699290001Sglebius		TEST_ASSERT_EQUAL(1, rc);
700290001Sglebius		leapsec_electric(mode);
701290001Sglebius
702290001Sglebius		rc = leapsec_query(&qr, lsec2006, NULL);
703290001Sglebius		TEST_ASSERT_EQUAL(FALSE, rc);
704290001Sglebius
705290001Sglebius		rc = leapsec_query(&qr, lsec2012, NULL);
706290001Sglebius		TEST_ASSERT_EQUAL(FALSE, rc);
707290001Sglebius	}
708290001Sglebius}
709290001Sglebius
710290001Sglebius// ----------------------------------------------------------------------
711290001Sglebius// Forward jump into the next transition window
712290001Sglebiusvoid test_qryJumpAheadToTransition(void) {
713293896Sglebius	int		rc;
714293896Sglebius	leap_result_t	qr;
715293896Sglebius	int		last, idx;
716293896Sglebius	int		mode;
717290001Sglebius
718290001Sglebius	for (mode=0; mode < 2; ++mode) {
719290001Sglebius		leapsec_ut_pristine();
720290001Sglebius		rc = setup_load_table(leap1, FALSE);
721290001Sglebius		TEST_ASSERT_EQUAL(1, rc);
722290001Sglebius		leapsec_electric(mode);
723290001Sglebius
724290001Sglebius		rc = leapsec_query(&qr, lsec2009-SECSPERDAY, NULL);
725290001Sglebius		TEST_ASSERT_EQUAL(FALSE, rc);
726290001Sglebius
727290001Sglebius		rc = leapsec_query(&qr, lsec2009+1, NULL);
728290001Sglebius		TEST_ASSERT_EQUAL(TRUE, rc);
729290001Sglebius	}
730293896Sglebius
731293896Sglebius	return;
732290001Sglebius}
733290001Sglebius
734290001Sglebius// ----------------------------------------------------------------------
735290001Sglebius// Forward jump over the next transition window
736293896Sglebiusvoid
737293896Sglebiustest_qryJumpAheadOverTransition(void)
738293896Sglebius{
739293896Sglebius	int		rc;
740293896Sglebius	leap_result_t	qr;
741293896Sglebius	int		last, idx;
742293896Sglebius	int		mode;
743290001Sglebius
744290001Sglebius	for (mode=0; mode < 2; ++mode) {
745290001Sglebius		leapsec_ut_pristine();
746290001Sglebius		rc = setup_load_table(leap1, FALSE);
747290001Sglebius		TEST_ASSERT_EQUAL(1, rc);
748290001Sglebius		leapsec_electric(mode);
749290001Sglebius
750290001Sglebius		rc = leapsec_query(&qr, lsec2009-SECSPERDAY, NULL);
751290001Sglebius		TEST_ASSERT_EQUAL(FALSE, rc);
752290001Sglebius
753290001Sglebius		rc = leapsec_query(&qr, lsec2009+5, NULL);
754290001Sglebius		TEST_ASSERT_EQUAL(FALSE, rc);
755290001Sglebius	}
756293896Sglebius
757293896Sglebius	return;
758290001Sglebius}
759290001Sglebius
760290001Sglebius// =====================================================================
761290001Sglebius// TABLE MODIFICATION AT RUNTIME
762290001Sglebius// =====================================================================
763290001Sglebius
764290001Sglebius// ----------------------------------------------------------------------
765290001Sglebius// add dynamic leap second (like from peer/clock)
766293896Sglebiusvoid
767293896Sglebiustest_addDynamic(void)
768293896Sglebius{
769290001Sglebius	int            rc;
770290001Sglebius	leap_result_t  qr;
771290001Sglebius
772290001Sglebius	static const uint32_t insns[] = {
773290001Sglebius		2982009600u,	//	29	# 1 Jul 1994
774290001Sglebius		3029443200u,	//	30	# 1 Jan 1996
775290001Sglebius		3076704000u,	//	31	# 1 Jul 1997
776290001Sglebius		3124137600u,	//	32	# 1 Jan 1999
777290001Sglebius		3345062400u,	//	33	# 1 Jan 2006
778290001Sglebius		3439756800u,	//	34	# 1 Jan 2009
779290001Sglebius		3550089600u,	//	35	# 1 Jul 2012
780290001Sglebius		0 // sentinel
781290001Sglebius	};
782290001Sglebius
783290001Sglebius	rc = setup_load_table(leap2, FALSE);
784290001Sglebius	TEST_ASSERT_EQUAL(1, rc);
785290001Sglebius
786293896Sglebius	int		idx;
787290001Sglebius
788290001Sglebius	for (idx=1; insns[idx]; ++idx) {
789290001Sglebius		rc = leapsec_add_dyn(TRUE, insns[idx] - 20*SECSPERDAY - 100, NULL);
790290001Sglebius		TEST_ASSERT_EQUAL(TRUE, rc);
791290001Sglebius	}
792290001Sglebius	// try to slip in a previous entry
793290001Sglebius	rc = leapsec_add_dyn(TRUE, insns[0] - 20*SECSPERDAY - 100, NULL);
794290001Sglebius	TEST_ASSERT_EQUAL(FALSE, rc);
795293896Sglebius	//leap_table_t  * pt = leapsec_get_table(0);
796290001Sglebius	//leapsec_dump(pt, (leapsec_dumper)fprintf, stdout);
797293896Sglebius
798293896Sglebius	return;
799290001Sglebius}
800290001Sglebius
801290001Sglebius// ----------------------------------------------------------------------
802290001Sglebius// add fixed leap seconds (like from network packet)
803290001Sglebius#if 0 /* currently unused -- possibly revived later */
804293896Sglebiusvoid
805293896SglebiusFAILtest_addFixed(void)
806293896Sglebius{
807290001Sglebius	int            rc;
808290001Sglebius	leap_result_t  qr;
809290001Sglebius
810290001Sglebius	static const struct { uint32_t tt; int of; } insns[] = {
811290001Sglebius		{2982009600u, 29},//	# 1 Jul 1994
812290001Sglebius		{3029443200u, 30},//	# 1 Jan 1996
813290001Sglebius		{3076704000u, 31},//	# 1 Jul 1997
814290001Sglebius		{3124137600u, 32},//	# 1 Jan 1999
815290001Sglebius		{3345062400u, 33},//	# 1 Jan 2006
816290001Sglebius		{3439756800u, 34},//	# 1 Jan 2009
817290001Sglebius		{3550089600u, 35},//	# 1 Jul 2012
818290001Sglebius		{0,0} // sentinel
819290001Sglebius	};
820290001Sglebius
821290001Sglebius	rc = setup_load_table(leap2, FALSE);
822290001Sglebius	TEST_ASSERT_EQUAL(1, rc);
823293896Sglebius
824290001Sglebius	int idx;
825290001Sglebius	// try to get in BAD time stamps...
826290001Sglebius	for (idx=0; insns[idx].tt; ++idx) {
827290001Sglebius	    rc = leapsec_add_fix(
828290001Sglebius		insns[idx].of,
829290001Sglebius		insns[idx].tt - 20*SECSPERDAY - 100,
830290001Sglebius		insns[idx].tt + SECSPERDAY,
831290001Sglebius		NULL);
832290001Sglebius		TEST_ASSERT_EQUAL(FALSE, rc);
833290001Sglebius	}
834290001Sglebius	// now do it right
835290001Sglebius	for (idx=0; insns[idx].tt; ++idx) {
836290001Sglebius		rc = leapsec_add_fix(
837290001Sglebius		    insns[idx].of,
838290001Sglebius		    insns[idx].tt,
839290001Sglebius		    insns[idx].tt + SECSPERDAY,
840290001Sglebius		    NULL);
841290001Sglebius		TEST_ASSERT_EQUAL(TRUE, rc);
842290001Sglebius	}
843290001Sglebius	// try to slip in a previous entry
844290001Sglebius	rc = leapsec_add_fix(
845290001Sglebius	    insns[0].of,
846290001Sglebius	    insns[0].tt,
847290001Sglebius	    insns[0].tt + SECSPERDAY,
848290001Sglebius	    NULL);
849290001Sglebius	TEST_ASSERT_EQUAL(FALSE, rc);
850293896Sglebius	//leap_table_t * pt = leapsec_get_table(0);
851290001Sglebius	//leapsec_dump(pt, (leapsec_dumper)fprintf, stdout);
852293896Sglebius
853293896Sglebius	return;
854290001Sglebius}
855290001Sglebius#endif
856290001Sglebius
857290001Sglebius// ----------------------------------------------------------------------
858290001Sglebius// add fixed leap seconds (like from network packet)
859290001Sglebius#if 0 /* currently unused -- possibly revived later */
860293896Sglebiusvoid
861293896SglebiusFAILtest_addFixedExtend(void)
862293896Sglebius{
863290001Sglebius	int            rc;
864290001Sglebius	leap_result_t  qr;
865290001Sglebius	int            last, idx;
866290001Sglebius
867290001Sglebius	static const struct { uint32_t tt; int of; } insns[] = {
868290001Sglebius		{2982009600u, 29},//	# 1 Jul 1994
869290001Sglebius		{3029443200u, 30},//	# 1 Jan 1996
870290001Sglebius		{0,0} // sentinel
871290001Sglebius	};
872290001Sglebius
873290001Sglebius	rc = setup_load_table(leap2, FALSE);
874290001Sglebius	TEST_ASSERT_EQUAL(1, rc);
875290001Sglebius
876290001Sglebius	for (last=idx=0; insns[idx].tt; ++idx) {
877290001Sglebius		last = idx;
878290001Sglebius		rc = leapsec_add_fix(
879290001Sglebius		    insns[idx].of,
880290001Sglebius		    insns[idx].tt,
881290001Sglebius		    insns[idx].tt + SECSPERDAY,
882290001Sglebius		    NULL);
883290001Sglebius		TEST_ASSERT_EQUAL(TRUE, rc);
884290001Sglebius	}
885293896Sglebius
886290001Sglebius	// try to extend the expiration of the last entry
887290001Sglebius	rc = leapsec_add_fix(
888290001Sglebius	    insns[last].of,
889290001Sglebius	    insns[last].tt,
890290001Sglebius	    insns[last].tt + 128*SECSPERDAY,
891290001Sglebius	    NULL);
892290001Sglebius	TEST_ASSERT_EQUAL(TRUE, rc);
893293896Sglebius
894290001Sglebius	// try to extend the expiration of the last entry with wrong offset
895290001Sglebius	rc = leapsec_add_fix(
896290001Sglebius	    insns[last].of+1,
897290001Sglebius	    insns[last].tt,
898290001Sglebius	    insns[last].tt + 129*SECSPERDAY,
899290001Sglebius	    NULL);
900290001Sglebius	TEST_ASSERT_EQUAL(FALSE, rc);
901293896Sglebius	//leap_table_t * pt = leapsec_get_table(FALSE);
902290001Sglebius	//leapsec_dump(pt, (leapsec_dumper)fprintf, stdout);
903293896Sglebius
904293896Sglebius	return;
905290001Sglebius}
906290001Sglebius#endif
907290001Sglebius
908290001Sglebius// ----------------------------------------------------------------------
909290001Sglebius// add fixed leap seconds (like from network packet) in an otherwise
910290001Sglebius// empty table and test queries before / between /after the tabulated
911290001Sglebius// values.
912290001Sglebius#if 0 /* currently unused -- possibly revived later */
913293896Sglebiusvoid
914293896SglebiusFAILtest_setFixedExtend(void)
915293896Sglebius{
916290001Sglebius	int            rc;
917290001Sglebius	leap_result_t  qr;
918290001Sglebius	int            last, idx;
919290001Sglebius
920290001Sglebius	static const struct { uint32_t tt; int of; } insns[] = {
921290001Sglebius		{2982009600u, 29},//	# 1 Jul 1994
922290001Sglebius		{3029443200u, 30},//	# 1 Jan 1996
923290001Sglebius		{0,0} // sentinel
924290001Sglebius	};
925290001Sglebius
926290001Sglebius	for (last=idx=0; insns[idx].tt; ++idx) {
927290001Sglebius		last = idx;
928290001Sglebius		rc = leapsec_add_fix(
929290001Sglebius		    insns[idx].of,
930290001Sglebius		    insns[idx].tt,
931290001Sglebius		    insns[idx].tt + 128*SECSPERDAY,
932290001Sglebius		    NULL);
933290001Sglebius		TEST_ASSERT_EQUAL(TRUE, rc);
934290001Sglebius	}
935293896Sglebius
936290001Sglebius	rc = leapsec_query(&qr, insns[0].tt - 86400, NULL);
937290001Sglebius	TEST_ASSERT_EQUAL(28, qr.tai_offs);
938290001Sglebius
939290001Sglebius	rc = leapsec_query(&qr, insns[0].tt + 86400, NULL);
940290001Sglebius	TEST_ASSERT_EQUAL(29, qr.tai_offs);
941290001Sglebius
942290001Sglebius	rc = leapsec_query(&qr, insns[1].tt - 86400, NULL);
943290001Sglebius	TEST_ASSERT_EQUAL(29, qr.tai_offs);
944290001Sglebius
945290001Sglebius	rc = leapsec_query(&qr, insns[1].tt + 86400, NULL);
946290001Sglebius	TEST_ASSERT_EQUAL(30, qr.tai_offs);
947290001Sglebius
948293896Sglebius	//leap_table_t * pt = leapsec_get_table(0);
949290001Sglebius	//leapsec_dump(pt, (leapsec_dumper)fprintf, stdout);
950293896Sglebius
951293896Sglebius	return;
952290001Sglebius}
953290001Sglebius#endif
954290001Sglebius
955290001Sglebius// =====================================================================
956290001Sglebius// AUTOKEY LEAP TRANSFER TESTS
957290001Sglebius// =====================================================================
958290001Sglebius
959290001Sglebius// ----------------------------------------------------------------------
960290001Sglebius// Check if the offset can be applied to an empty table ONCE
961290001Sglebiusvoid test_taiEmptyTable(void) {
962290001Sglebius	int rc;
963290001Sglebius
964293896Sglebius	rc = leapsec_autokey_tai(35, lsec2015-30*86400, NULL);
965290001Sglebius	TEST_ASSERT_EQUAL(TRUE, rc);
966290001Sglebius
967290001Sglebius	rc = leapsec_autokey_tai(35, lsec2015-29*86400, NULL);
968290001Sglebius	TEST_ASSERT_EQUAL(FALSE, rc);
969290001Sglebius}
970290001Sglebius
971290001Sglebius// ----------------------------------------------------------------------
972290001Sglebius// Check that with fixed entries the operation fails
973293896Sglebiusvoid
974293896Sglebiustest_taiTableFixed(void)
975293896Sglebius{
976290001Sglebius	int rc;
977290001Sglebius
978290001Sglebius	rc = setup_load_table(leap1, FALSE);
979290001Sglebius	TEST_ASSERT_EQUAL(1, rc);
980290001Sglebius
981290001Sglebius	rc = leapsec_autokey_tai(35, lsec2015-30*86400, NULL);
982290001Sglebius	TEST_ASSERT_EQUAL(FALSE, rc);
983293896Sglebius
984293896Sglebius	return;
985290001Sglebius}
986290001Sglebius
987290001Sglebius// ----------------------------------------------------------------------
988290001Sglebius// test adjustment with a dynamic entry already there
989293896Sglebiusvoid
990293896Sglebiustest_taiTableDynamic(void)
991293896Sglebius{
992290001Sglebius	int        rc;
993290001Sglebius	leap_era_t era;
994290001Sglebius
995290001Sglebius	rc = leapsec_add_dyn(TRUE, lsec2015-20*SECSPERDAY, NULL);
996290001Sglebius	TEST_ASSERT_EQUAL(TRUE, rc);
997290001Sglebius
998290001Sglebius	leapsec_query_era(&era, lsec2015-10, NULL);
999290001Sglebius	TEST_ASSERT_EQUAL(0, era.taiof);
1000290001Sglebius	leapsec_query_era(&era, lsec2015+10, NULL);
1001290001Sglebius	TEST_ASSERT_EQUAL(1, era.taiof);
1002290001Sglebius
1003293896Sglebius	rc = leapsec_autokey_tai(35, lsec2015-19*86400, NULL);
1004290001Sglebius	TEST_ASSERT_EQUAL(TRUE, rc);
1005290001Sglebius
1006290001Sglebius	rc = leapsec_autokey_tai(35, lsec2015-19*86400, NULL);
1007290001Sglebius	TEST_ASSERT_EQUAL(FALSE, rc);
1008290001Sglebius
1009290001Sglebius	leapsec_query_era(&era, lsec2015-10, NULL);
1010290001Sglebius	TEST_ASSERT_EQUAL(35, era.taiof);
1011290001Sglebius	leapsec_query_era(&era, lsec2015+10, NULL);
1012290001Sglebius	TEST_ASSERT_EQUAL(36, era.taiof);
1013293896Sglebius
1014293896Sglebius	return;
1015290001Sglebius}
1016290001Sglebius
1017290001Sglebius// ----------------------------------------------------------------------
1018290001Sglebius// test adjustment with a dynamic entry already there in dead zone
1019293896Sglebiusvoid
1020293896Sglebiustest_taiTableDynamicDeadZone(void)
1021293896Sglebius{
1022290001Sglebius	int rc;
1023290001Sglebius
1024290001Sglebius	rc = leapsec_add_dyn(TRUE, lsec2015-20*SECSPERDAY, NULL);
1025290001Sglebius	TEST_ASSERT_EQUAL(TRUE, rc);
1026290001Sglebius
1027293896Sglebius	rc = leapsec_autokey_tai(35, lsec2015-5, NULL);
1028290001Sglebius	TEST_ASSERT_EQUAL(FALSE, rc);
1029290001Sglebius
1030290001Sglebius	rc = leapsec_autokey_tai(35, lsec2015+5, NULL);
1031290001Sglebius	TEST_ASSERT_EQUAL(FALSE, rc);
1032293896Sglebius
1033293896Sglebius	return;
1034290001Sglebius}
1035290001Sglebius
1036290001Sglebius
1037290001Sglebius// =====================================================================
1038290001Sglebius// SEQUENCE TESTS
1039290001Sglebius// =====================================================================
1040290001Sglebius
1041290001Sglebius// ----------------------------------------------------------------------
1042290001Sglebius// leap second insert at 2009.01.01, electric mode
1043293896Sglebiusvoid
1044293896Sglebiustest_ls2009seqInsElectric(void)
1045293896Sglebius{
1046290001Sglebius	int            rc;
1047290001Sglebius	leap_result_t  qr;
1048290001Sglebius
1049290001Sglebius	rc = setup_load_table(leap1,FALSE);
1050290001Sglebius	TEST_ASSERT_EQUAL(1, rc);
1051290001Sglebius	leapsec_electric(1);
1052290001Sglebius	TEST_ASSERT_EQUAL(1, leapsec_electric(-1));
1053290001Sglebius
1054290001Sglebius	rc = leapsec_query(&qr, lsec2009 - 60*SECSPERDAY, NULL);
1055290001Sglebius	TEST_ASSERT_EQUAL(FALSE, rc);
1056290001Sglebius	TEST_ASSERT_EQUAL(0,             qr.warped   );
1057290001Sglebius	TEST_ASSERT_EQUAL(LSPROX_NOWARN, qr.proximity);
1058290001Sglebius
1059290001Sglebius	rc = leapsec_query(&qr, lsec2009 - 7*SECSPERDAY, NULL);
1060290001Sglebius	TEST_ASSERT_EQUAL(FALSE, rc);
1061290001Sglebius	TEST_ASSERT_EQUAL(0,               qr.warped   );
1062290001Sglebius	TEST_ASSERT_EQUAL(LSPROX_SCHEDULE, qr.proximity);
1063290001Sglebius
1064290001Sglebius	rc = leapsec_query(&qr, lsec2009 - SECSPERHR, NULL);
1065290001Sglebius	TEST_ASSERT_EQUAL(FALSE, rc);
1066290001Sglebius	TEST_ASSERT_EQUAL(0,               qr.warped   );
1067290001Sglebius	TEST_ASSERT_EQUAL(LSPROX_ANNOUNCE, qr.proximity);
1068290001Sglebius
1069290001Sglebius	rc = leapsec_query(&qr, lsec2009 - 1, NULL);
1070290001Sglebius	TEST_ASSERT_EQUAL(FALSE, rc);
1071290001Sglebius	TEST_ASSERT_EQUAL(0,               qr.warped   );
1072290001Sglebius	TEST_ASSERT_EQUAL(LSPROX_ALERT,    qr.proximity);
1073290001Sglebius
1074290001Sglebius	rc = leapsec_query(&qr, lsec2009, NULL);
1075290001Sglebius	TEST_ASSERT_EQUAL(TRUE, rc);
1076290001Sglebius	TEST_ASSERT_EQUAL(0,             qr.warped   );
1077290001Sglebius	TEST_ASSERT_EQUAL(LSPROX_NOWARN, qr.proximity);
1078290001Sglebius
1079290001Sglebius	// second call, same time frame: no trigger!
1080290001Sglebius	rc = leapsec_query(&qr, lsec2009, NULL);
1081290001Sglebius	TEST_ASSERT_EQUAL(FALSE, rc);
1082290001Sglebius	TEST_ASSERT_EQUAL(0,             qr.warped   );
1083290001Sglebius	TEST_ASSERT_EQUAL(LSPROX_NOWARN, qr.proximity);
1084293896Sglebius
1085293896Sglebius	return;
1086290001Sglebius}
1087290001Sglebius
1088290001Sglebius// ----------------------------------------------------------------------
1089290001Sglebius// leap second insert at 2009.01.01, dumb mode
1090293896Sglebiusvoid
1091293896Sglebiustest_ls2009seqInsDumb(void)
1092293896Sglebius{
1093290001Sglebius	int            rc;
1094290001Sglebius	leap_result_t  qr;
1095290001Sglebius
1096290001Sglebius	rc = setup_load_table(leap1,FALSE);
1097290001Sglebius	TEST_ASSERT_EQUAL(1, rc);
1098290001Sglebius	TEST_ASSERT_EQUAL(0, leapsec_electric(-1));
1099290001Sglebius
1100290001Sglebius	rc = leapsec_query(&qr, lsec2009 - 60*SECSPERDAY, NULL);
1101290001Sglebius	TEST_ASSERT_EQUAL(FALSE, rc);
1102290001Sglebius	TEST_ASSERT_EQUAL(0,             qr.warped   );
1103290001Sglebius	TEST_ASSERT_EQUAL(LSPROX_NOWARN, qr.proximity);
1104290001Sglebius
1105290001Sglebius	rc = leapsec_query(&qr, lsec2009 - 7*SECSPERDAY, NULL);
1106290001Sglebius	TEST_ASSERT_EQUAL(FALSE, rc);
1107290001Sglebius	TEST_ASSERT_EQUAL(0,               qr.warped   );
1108290001Sglebius	TEST_ASSERT_EQUAL(LSPROX_SCHEDULE, qr.proximity);
1109290001Sglebius
1110290001Sglebius	rc = leapsec_query(&qr, lsec2009 - SECSPERHR, NULL);
1111290001Sglebius	TEST_ASSERT_EQUAL(FALSE, rc);
1112290001Sglebius	TEST_ASSERT_EQUAL(0,               qr.warped   );
1113290001Sglebius	TEST_ASSERT_EQUAL(LSPROX_ANNOUNCE, qr.proximity);
1114290001Sglebius
1115290001Sglebius	rc = leapsec_query(&qr, lsec2009 - 1, NULL);
1116290001Sglebius	TEST_ASSERT_EQUAL(FALSE, rc);
1117290001Sglebius	TEST_ASSERT_EQUAL(0,               qr.warped   );
1118290001Sglebius	TEST_ASSERT_EQUAL(LSPROX_ALERT,    qr.proximity);
1119290001Sglebius
1120290001Sglebius	rc = leapsec_query(&qr, lsec2009, NULL);
1121290001Sglebius	TEST_ASSERT_EQUAL(FALSE, rc);
1122290001Sglebius	TEST_ASSERT_EQUAL(0,               qr.warped   );
1123290001Sglebius	TEST_ASSERT_EQUAL(LSPROX_ALERT,    qr.proximity);
1124290001Sglebius
1125290001Sglebius	rc = leapsec_query(&qr, lsec2009+1, NULL);
1126290001Sglebius	TEST_ASSERT_EQUAL(TRUE, rc);
1127290001Sglebius	TEST_ASSERT_EQUAL(-1,             qr.warped   );
1128290001Sglebius	TEST_ASSERT_EQUAL(LSPROX_NOWARN, qr.proximity);
1129290001Sglebius
1130290001Sglebius	// second call, same time frame: no trigger!
1131290001Sglebius	rc = leapsec_query(&qr, lsec2009, NULL);
1132290001Sglebius	TEST_ASSERT_EQUAL(FALSE, rc);
1133290001Sglebius	TEST_ASSERT_EQUAL(0,             qr.warped   );
1134290001Sglebius	TEST_ASSERT_EQUAL(LSPROX_NOWARN, qr.proximity);
1135293896Sglebius
1136293896Sglebius	return;
1137290001Sglebius}
1138290001Sglebius
1139290001Sglebius
1140290001Sglebius// ----------------------------------------------------------------------
1141290001Sglebius// fake leap second remove at 2009.01.01, electric mode
1142293896Sglebiusvoid
1143293896Sglebiustest_ls2009seqDelElectric(void)
1144293896Sglebius{
1145290001Sglebius	int            rc;
1146290001Sglebius	leap_result_t  qr;
1147290001Sglebius
1148290001Sglebius	rc = setup_load_table(leap3,FALSE);
1149290001Sglebius	TEST_ASSERT_EQUAL(1, rc);
1150290001Sglebius	leapsec_electric(1);
1151290001Sglebius	TEST_ASSERT_EQUAL(1, leapsec_electric(-1));
1152290001Sglebius
1153290001Sglebius	rc = leapsec_query(&qr, lsec2009 - 60*SECSPERDAY, NULL);
1154290001Sglebius	TEST_ASSERT_EQUAL(FALSE, rc);
1155290001Sglebius	TEST_ASSERT_EQUAL(0,             qr.warped   );
1156290001Sglebius	TEST_ASSERT_EQUAL(LSPROX_NOWARN, qr.proximity);
1157290001Sglebius
1158290001Sglebius	rc = leapsec_query(&qr, lsec2009 - 7*SECSPERDAY, NULL);
1159290001Sglebius	TEST_ASSERT_EQUAL(FALSE, rc);
1160290001Sglebius	TEST_ASSERT_EQUAL(0,               qr.warped   );
1161290001Sglebius	TEST_ASSERT_EQUAL(LSPROX_SCHEDULE, qr.proximity);
1162290001Sglebius
1163290001Sglebius	rc = leapsec_query(&qr, lsec2009 - SECSPERHR, NULL);
1164290001Sglebius	TEST_ASSERT_EQUAL(FALSE, rc);
1165290001Sglebius	TEST_ASSERT_EQUAL(0,               qr.warped   );
1166290001Sglebius	TEST_ASSERT_EQUAL(LSPROX_ANNOUNCE, qr.proximity);
1167290001Sglebius
1168290001Sglebius	rc = leapsec_query(&qr, lsec2009 - 1, NULL);
1169290001Sglebius	TEST_ASSERT_EQUAL(FALSE, rc);
1170290001Sglebius	TEST_ASSERT_EQUAL(0,               qr.warped   );
1171290001Sglebius	TEST_ASSERT_EQUAL(LSPROX_ALERT,    qr.proximity);
1172290001Sglebius
1173290001Sglebius	rc = leapsec_query(&qr, lsec2009, NULL);
1174290001Sglebius	TEST_ASSERT_EQUAL(TRUE, rc);
1175290001Sglebius	TEST_ASSERT_EQUAL(0,             qr.warped   );
1176290001Sglebius	TEST_ASSERT_EQUAL(LSPROX_NOWARN, qr.proximity);
1177290001Sglebius
1178290001Sglebius	// second call, same time frame: no trigger!
1179290001Sglebius	rc = leapsec_query(&qr, lsec2009, NULL);
1180290001Sglebius	TEST_ASSERT_EQUAL(FALSE, rc);
1181290001Sglebius	TEST_ASSERT_EQUAL(0,             qr.warped   );
1182290001Sglebius	TEST_ASSERT_EQUAL(LSPROX_NOWARN, qr.proximity);
1183293896Sglebius
1184293896Sglebius	return;
1185290001Sglebius}
1186290001Sglebius
1187290001Sglebius// ----------------------------------------------------------------------
1188290001Sglebius// fake leap second remove at 2009.01.01. dumb mode
1189293896Sglebiusvoid
1190293896Sglebiustest_ls2009seqDelDumb(void)
1191293896Sglebius{
1192290001Sglebius	int            rc;
1193290001Sglebius	leap_result_t  qr;
1194290001Sglebius
1195290001Sglebius	rc = setup_load_table(leap3,FALSE);
1196290001Sglebius	TEST_ASSERT_EQUAL(1, rc);
1197290001Sglebius	TEST_ASSERT_EQUAL(0, leapsec_electric(-1));
1198290001Sglebius
1199290001Sglebius	rc = leapsec_query(&qr, lsec2009 - 60*SECSPERDAY, NULL);
1200290001Sglebius	TEST_ASSERT_EQUAL(FALSE, rc);
1201290001Sglebius	TEST_ASSERT_EQUAL(0,             qr.warped   );
1202290001Sglebius	TEST_ASSERT_EQUAL(LSPROX_NOWARN, qr.proximity);
1203290001Sglebius
1204290001Sglebius	rc = leapsec_query(&qr, lsec2009 - 7*SECSPERDAY, NULL);
1205290001Sglebius	TEST_ASSERT_EQUAL(FALSE, rc);
1206290001Sglebius	TEST_ASSERT_EQUAL(0,               qr.warped   );
1207290001Sglebius	TEST_ASSERT_EQUAL(LSPROX_SCHEDULE, qr.proximity);
1208290001Sglebius
1209290001Sglebius	rc = leapsec_query(&qr, lsec2009 - SECSPERHR, NULL);
1210290001Sglebius	TEST_ASSERT_EQUAL(FALSE, rc);
1211290001Sglebius	TEST_ASSERT_EQUAL(0,               qr.warped   );
1212290001Sglebius	TEST_ASSERT_EQUAL(LSPROX_ANNOUNCE, qr.proximity);
1213290001Sglebius
1214290001Sglebius	rc = leapsec_query(&qr, lsec2009 - 2, NULL);
1215290001Sglebius	TEST_ASSERT_EQUAL(FALSE, rc);
1216290001Sglebius	TEST_ASSERT_EQUAL(0,               qr.warped   );
1217290001Sglebius	TEST_ASSERT_EQUAL(LSPROX_ALERT,    qr.proximity);
1218290001Sglebius
1219290001Sglebius	rc = leapsec_query(&qr, lsec2009 - 1, NULL);
1220290001Sglebius	TEST_ASSERT_EQUAL(TRUE, rc);
1221290001Sglebius	TEST_ASSERT_EQUAL(1,             qr.warped   );
1222290001Sglebius	TEST_ASSERT_EQUAL(LSPROX_NOWARN, qr.proximity);
1223290001Sglebius
1224290001Sglebius	// second call, same time frame: no trigger!
1225290001Sglebius	rc = leapsec_query(&qr, lsec2009, NULL);
1226290001Sglebius	TEST_ASSERT_EQUAL(FALSE, rc);
1227290001Sglebius	TEST_ASSERT_EQUAL(0,             qr.warped   );
1228290001Sglebius	TEST_ASSERT_EQUAL(LSPROX_NOWARN, qr.proximity);
1229293896Sglebius
1230293896Sglebius	return;
1231290001Sglebius}
1232290001Sglebius
1233290001Sglebius// ----------------------------------------------------------------------
1234290001Sglebius// leap second insert at 2012.07.01, electric mode
1235293896Sglebiusvoid
1236293896Sglebiustest_ls2012seqInsElectric(void)
1237293896Sglebius{
1238290001Sglebius	int            rc;
1239290001Sglebius	leap_result_t  qr;
1240290001Sglebius
1241290001Sglebius	rc = setup_load_table(leap1,FALSE);
1242290001Sglebius	TEST_ASSERT_EQUAL(1, rc);
1243290001Sglebius	leapsec_electric(1);
1244290001Sglebius	TEST_ASSERT_EQUAL(1, leapsec_electric(-1));
1245290001Sglebius
1246290001Sglebius	rc = leapsec_query(&qr, lsec2012 - 60*SECSPERDAY, NULL);
1247290001Sglebius	TEST_ASSERT_EQUAL(FALSE, rc);
1248290001Sglebius	TEST_ASSERT_EQUAL(0,             qr.warped   );
1249290001Sglebius	TEST_ASSERT_EQUAL(LSPROX_NOWARN, qr.proximity);
1250290001Sglebius
1251290001Sglebius	rc = leapsec_query(&qr, lsec2012 - 7*SECSPERDAY, NULL);
1252290001Sglebius	TEST_ASSERT_EQUAL(FALSE, rc);
1253290001Sglebius	TEST_ASSERT_EQUAL(0,               qr.warped   );
1254290001Sglebius	TEST_ASSERT_EQUAL(LSPROX_SCHEDULE, qr.proximity);
1255290001Sglebius
1256290001Sglebius	rc = leapsec_query(&qr, lsec2012 - SECSPERHR, NULL);
1257290001Sglebius	TEST_ASSERT_EQUAL(FALSE, rc);
1258290001Sglebius	TEST_ASSERT_EQUAL(0,               qr.warped   );
1259290001Sglebius	TEST_ASSERT_EQUAL(LSPROX_ANNOUNCE, qr.proximity);
1260290001Sglebius
1261290001Sglebius	rc = leapsec_query(&qr, lsec2012 - 1, NULL);
1262290001Sglebius	TEST_ASSERT_EQUAL(FALSE, rc);
1263290001Sglebius	TEST_ASSERT_EQUAL(0,               qr.warped   );
1264290001Sglebius	TEST_ASSERT_EQUAL(LSPROX_ALERT,    qr.proximity);
1265290001Sglebius
1266290001Sglebius	rc = leapsec_query(&qr, lsec2012, NULL);
1267290001Sglebius	TEST_ASSERT_EQUAL(TRUE, rc);
1268290001Sglebius	TEST_ASSERT_EQUAL(0,            qr.warped   );
1269290001Sglebius	TEST_ASSERT_EQUAL(LSPROX_NOWARN, qr.proximity);
1270290001Sglebius
1271290001Sglebius	// second call, same time frame: no trigger!
1272290001Sglebius	rc = leapsec_query(&qr, lsec2012, NULL);
1273290001Sglebius	TEST_ASSERT_EQUAL(FALSE, rc);
1274290001Sglebius	TEST_ASSERT_EQUAL(0,             qr.warped   );
1275290001Sglebius	TEST_ASSERT_EQUAL(LSPROX_NOWARN, qr.proximity);
1276293896Sglebius
1277293896Sglebius	return;
1278290001Sglebius}
1279290001Sglebius
1280290001Sglebius// ----------------------------------------------------------------------
1281290001Sglebius// leap second insert at 2012.07.01, dumb mode
1282293896Sglebiusvoid
1283293896Sglebiustest_ls2012seqInsDumb(void)
1284293896Sglebius{
1285290001Sglebius	int            rc;
1286290001Sglebius	leap_result_t  qr;
1287290001Sglebius
1288290001Sglebius	rc = setup_load_table(leap1,FALSE);
1289290001Sglebius	TEST_ASSERT_EQUAL(1, rc);
1290290001Sglebius	TEST_ASSERT_EQUAL(0, leapsec_electric(-1));
1291290001Sglebius
1292290001Sglebius	rc = leapsec_query(&qr, lsec2012 - 60*SECSPERDAY, NULL);
1293290001Sglebius	TEST_ASSERT_EQUAL(FALSE, rc);
1294290001Sglebius	TEST_ASSERT_EQUAL(0,             qr.warped   );
1295290001Sglebius	TEST_ASSERT_EQUAL(LSPROX_NOWARN, qr.proximity);
1296290001Sglebius
1297290001Sglebius	rc = leapsec_query(&qr, lsec2012 - 7*SECSPERDAY, NULL);
1298290001Sglebius	TEST_ASSERT_EQUAL(FALSE, rc);
1299290001Sglebius	TEST_ASSERT_EQUAL(0,               qr.warped   );
1300290001Sglebius	TEST_ASSERT_EQUAL(LSPROX_SCHEDULE, qr.proximity);
1301290001Sglebius
1302290001Sglebius	rc = leapsec_query(&qr, lsec2012 - SECSPERHR, NULL);
1303290001Sglebius	TEST_ASSERT_EQUAL(FALSE, rc);
1304290001Sglebius	TEST_ASSERT_EQUAL(0,               qr.warped   );
1305290001Sglebius	TEST_ASSERT_EQUAL(LSPROX_ANNOUNCE, qr.proximity);
1306290001Sglebius
1307290001Sglebius	rc = leapsec_query(&qr, lsec2012 - 1, NULL);
1308290001Sglebius	TEST_ASSERT_EQUAL(FALSE, rc);
1309290001Sglebius	TEST_ASSERT_EQUAL(0,               qr.warped   );
1310290001Sglebius	TEST_ASSERT_EQUAL(LSPROX_ALERT,    qr.proximity);
1311290001Sglebius
1312290001Sglebius	// This is just 1 sec before transition!
1313290001Sglebius	rc = leapsec_query(&qr, lsec2012, NULL);
1314290001Sglebius	TEST_ASSERT_EQUAL(FALSE, rc);
1315290001Sglebius	TEST_ASSERT_EQUAL(0,            qr.warped   );
1316290001Sglebius	TEST_ASSERT_EQUAL(LSPROX_ALERT, qr.proximity);
1317290001Sglebius
1318290001Sglebius	// NOW the insert/backwarp must happen
1319290001Sglebius	rc = leapsec_query(&qr, lsec2012+1, NULL);
1320290001Sglebius	TEST_ASSERT_EQUAL(TRUE, rc);
1321290001Sglebius	TEST_ASSERT_EQUAL(-1,            qr.warped   );
1322290001Sglebius	TEST_ASSERT_EQUAL(LSPROX_NOWARN, qr.proximity);
1323290001Sglebius
1324290001Sglebius	// second call with transition time: no trigger!
1325290001Sglebius	rc = leapsec_query(&qr, lsec2012, NULL);
1326290001Sglebius	TEST_ASSERT_EQUAL(FALSE, rc);
1327290001Sglebius	TEST_ASSERT_EQUAL(0,             qr.warped   );
1328290001Sglebius	TEST_ASSERT_EQUAL(LSPROX_NOWARN, qr.proximity);
1329293896Sglebius
1330293896Sglebius	return;
1331290001Sglebius}
1332290001Sglebius
1333290001Sglebius// ----------------------------------------------------------------------
1334290001Sglebius// test repeated query on empty table in dumb mode
1335293896Sglebiusvoid
1336293896Sglebiustest_lsEmptyTableDumb(void)
1337293896Sglebius{
1338290001Sglebius	int            rc;
1339290001Sglebius	leap_result_t  qr;
1340290001Sglebius
1341290001Sglebius	//const
1342290001Sglebius	time_t pivot;
1343290001Sglebius	pivot = lsec2012;
1344290001Sglebius	//	const
1345293896Sglebius	//time_t   pivot(lsec2012);
1346290001Sglebius	const uint32_t t0 = lsec2012 - 10;
1347290001Sglebius	const uint32_t tE = lsec2012 + 10;
1348290001Sglebius
1349290001Sglebius	TEST_ASSERT_EQUAL(0, leapsec_electric(-1));
1350290001Sglebius
1351290001Sglebius	uint32_t t;
1352290001Sglebius	for (t = t0; t != tE; ++t) {
1353290001Sglebius		rc = leapsec_query(&qr, t, &pivot);
1354290001Sglebius		TEST_ASSERT_EQUAL(FALSE, rc);
1355290001Sglebius		TEST_ASSERT_EQUAL(0,             qr.warped   );
1356290001Sglebius		TEST_ASSERT_EQUAL(LSPROX_NOWARN, qr.proximity);
1357290001Sglebius	}
1358293896Sglebius
1359293896Sglebius	return;
1360290001Sglebius}
1361290001Sglebius
1362290001Sglebius// ----------------------------------------------------------------------
1363290001Sglebius// test repeated query on empty table in electric mode
1364293896Sglebiusvoid
1365293896Sglebiustest_lsEmptyTableElectric(void)
1366293896Sglebius{
1367290001Sglebius	int            rc;
1368290001Sglebius	leap_result_t  qr;
1369293896Sglebius
1370290001Sglebius	leapsec_electric(1);
1371290001Sglebius	TEST_ASSERT_EQUAL(1, leapsec_electric(-1));
1372290001Sglebius
1373290001Sglebius	//const
1374290001Sglebius	time_t   pivot;//(lsec2012);
1375293896Sglebius	pivot = lsec2012;
1376290001Sglebius	const uint32_t t0 = lsec2012 - 10;
1377290001Sglebius	const uint32_t tE = lsec2012 + 10;
1378290001Sglebius
1379290001Sglebius	time_t t;
1380290001Sglebius	for (t = t0; t != tE; ++t) {
1381290001Sglebius		rc = leapsec_query(&qr, t, &pivot);
1382290001Sglebius		TEST_ASSERT_EQUAL(FALSE, rc);
1383290001Sglebius		TEST_ASSERT_EQUAL(0,             qr.warped   );
1384290001Sglebius		TEST_ASSERT_EQUAL(LSPROX_NOWARN, qr.proximity);
1385290001Sglebius	}
1386293896Sglebius
1387293896Sglebius	return;
1388290001Sglebius}
1389