]> CyberLeo.Net >> Repos - FreeBSD/releng/9.3.git/blob - contrib/ntp/tests/ntpd/leapsec.c
o Fix invalid TCP checksums with pf(4). [EN-16:02.pf]
[FreeBSD/releng/9.3.git] / contrib / ntp / tests / ntpd / leapsec.c
1 //#include "ntpdtest.h"
2 #include "config.h"
3
4
5 #include "ntp.h"
6 #include "ntp_calendar.h"
7 #include "ntp_stdlib.h"
8 #include "ntp_leapsec.h"
9
10 #include "unity.h"
11
12 #include <string.h>
13
14 #include "test-libntp.h"
15
16 static const char leap1 [] =
17     "#\n"
18     "#@         3610569600\n"
19     "#\n"
20     "2272060800 10      # 1 Jan 1972\n"
21     "2287785600 11      # 1 Jul 1972\n"
22     "2303683200 12      # 1 Jan 1973\n"
23     "2335219200 13      # 1 Jan 1974\n"
24     "2366755200 14      # 1 Jan 1975\n"
25     "2398291200 15      # 1 Jan 1976\n"
26     "2429913600 16      # 1 Jan 1977\n"
27     "2461449600 17      # 1 Jan 1978\n"
28     "2492985600 18      # 1 Jan 1979\n"
29     "2524521600 19      # 1 Jan 1980\n"
30     "   \t  \n"
31     "2571782400 20      # 1 Jul 1981\n"
32     "2603318400 21      # 1 Jul 1982\n"
33     "2634854400 22      # 1 Jul 1983\n"
34     "2698012800 23      # 1 Jul 1985\n"
35     "2776982400 24      # 1 Jan 1988\n"
36     "2840140800 25      # 1 Jan 1990\n"
37     "2871676800 26      # 1 Jan 1991\n"
38     "2918937600 27      # 1 Jul 1992\n"
39     "2950473600 28      # 1 Jul 1993\n"
40     "2982009600 29      # 1 Jul 1994\n"
41     "3029443200 30      # 1 Jan 1996\n"
42     "3076704000 31      # 1 Jul 1997\n"
43     "3124137600 32      # 1 Jan 1999\n"
44     "3345062400 33      # 1 Jan 2006\n"
45     "3439756800 34      # 1 Jan 2009\n"
46     "3550089600 35      # 1 Jul 2012\n"
47     "#\n"
48     "#h dc2e6b0b 5aade95d a0587abd 4e0dacb4 e4d5049e\n"
49     "#\n";
50
51 static const char leap2 [] =
52     "#\n"
53     "#@         2950473700\n"
54     "#\n"
55     "2272060800 10      # 1 Jan 1972\n"
56     "2287785600 11      # 1 Jul 1972\n"
57     "2303683200 12      # 1 Jan 1973\n"
58     "2335219200 13      # 1 Jan 1974\n"
59     "2366755200 14      # 1 Jan 1975\n"
60     "2398291200 15      # 1 Jan 1976\n"
61     "2429913600 16      # 1 Jan 1977\n"
62     "2461449600 17      # 1 Jan 1978\n"
63     "2492985600 18      # 1 Jan 1979\n"
64     "2524521600 19      # 1 Jan 1980\n"
65     "2571782400 20      # 1 Jul 1981\n"
66     "2603318400 21      # 1 Jul 1982\n"
67     "2634854400 22      # 1 Jul 1983\n"
68     "2698012800 23      # 1 Jul 1985\n"
69     "2776982400 24      # 1 Jan 1988\n"
70     "2840140800 25      # 1 Jan 1990\n"
71     "2871676800 26      # 1 Jan 1991\n"
72     "2918937600 27      # 1 Jul 1992\n"
73     "2950473600 28      # 1 Jul 1993\n"
74     "#\n";
75
76 // Faked table with a leap second removal at 2009 
77 static const char leap3 [] =
78     "#\n"
79     "#@         3610569600\n"
80     "#\n"
81     "2272060800 10      # 1 Jan 1972\n"
82     "2287785600 11      # 1 Jul 1972\n"
83     "2303683200 12      # 1 Jan 1973\n"
84     "2335219200 13      # 1 Jan 1974\n"
85     "2366755200 14      # 1 Jan 1975\n"
86     "2398291200 15      # 1 Jan 1976\n"
87     "2429913600 16      # 1 Jan 1977\n"
88     "2461449600 17      # 1 Jan 1978\n"
89     "2492985600 18      # 1 Jan 1979\n"
90     "2524521600 19      # 1 Jan 1980\n"
91     "2571782400 20      # 1 Jul 1981\n"
92     "2603318400 21      # 1 Jul 1982\n"
93     "2634854400 22      # 1 Jul 1983\n"
94     "2698012800 23      # 1 Jul 1985\n"
95     "2776982400 24      # 1 Jan 1988\n"
96     "2840140800 25      # 1 Jan 1990\n"
97     "2871676800 26      # 1 Jan 1991\n"
98     "2918937600 27      # 1 Jul 1992\n"
99     "2950473600 28      # 1 Jul 1993\n"
100     "2982009600 29      # 1 Jul 1994\n"
101     "3029443200 30      # 1 Jan 1996\n"
102     "3076704000 31      # 1 Jul 1997\n"
103     "3124137600 32      # 1 Jan 1999\n"
104     "3345062400 33      # 1 Jan 2006\n"
105     "3439756800 32      # 1 Jan 2009\n"
106     "3550089600 33      # 1 Jul 2012\n"
107     "#\n";
108
109 // short table with good hash
110 static const char leap_ghash [] =
111     "#\n"
112     "#@         3610569600\n"
113     "#$         3610566000\n"
114     "#\n"
115     "2272060800 10      # 1 Jan 1972\n"
116     "2287785600 11      # 1 Jul 1972\n"
117     "2303683200 12      # 1 Jan 1973\n"
118     "2335219200 13      # 1 Jan 1974\n"
119     "2366755200 14      # 1 Jan 1975\n"
120     "2398291200 15      # 1 Jan 1976\n"
121     "2429913600 16      # 1 Jan 1977\n"
122     "2461449600 17      # 1 Jan 1978\n"
123     "2492985600 18      # 1 Jan 1979\n"
124     "2524521600 19      # 1 Jan 1980\n"
125     "#\n"
126     "#h 4b304e10 95642b3f c10b91f9 90791725 25f280d0\n"
127     "#\n";
128
129 // short table with bad hash
130 static const char leap_bhash [] =
131     "#\n"
132     "#@         3610569600\n"
133     "#$         3610566000\n"
134     "#\n"
135     "2272060800 10      # 1 Jan 1972\n"
136     "2287785600 11      # 1 Jul 1972\n"
137     "2303683200 12      # 1 Jan 1973\n"
138     "2335219200 13      # 1 Jan 1974\n"
139     "2366755200 14      # 1 Jan 1975\n"
140     "2398291200 15      # 1 Jan 1976\n"
141     "2429913600 16      # 1 Jan 1977\n"
142     "2461449600 17      # 1 Jan 1978\n"
143     "2492985600 18      # 1 Jan 1979\n"
144     "2524521600 19      # 1 Jan 1980\n"
145     "#\n"
146     "#h dc2e6b0b 5aade95d a0587abd 4e0dacb4 e4d5049e\n"
147     "#\n";
148
149 // short table with malformed hash
150 static const char leap_mhash [] =
151     "#\n"
152     "#@         3610569600\n"
153     "#$         3610566000\n"
154     "#\n"
155     "2272060800 10      # 1 Jan 1972\n"
156     "2287785600 11      # 1 Jul 1972\n"
157     "2303683200 12      # 1 Jan 1973\n"
158     "2335219200 13      # 1 Jan 1974\n"
159     "2366755200 14      # 1 Jan 1975\n"
160     "2398291200 15      # 1 Jan 1976\n"
161     "2429913600 16      # 1 Jan 1977\n"
162     "2461449600 17      # 1 Jan 1978\n"
163     "2492985600 18      # 1 Jan 1979\n"
164     "2524521600 19      # 1 Jan 1980\n"
165     "#\n"
166     "#h f2349a02 788b9534 a8f2e141 f2029Q6d 4064a7ee\n"
167     "#\n";
168
169 // short table with only 4 hash groups
170 static const char leap_shash [] =
171     "#\n"
172     "#@         3610569600\n"
173     "#$         3610566000\n"
174     "#\n"
175     "2272060800 10      # 1 Jan 1972\n"
176     "2287785600 11      # 1 Jul 1972\n"
177     "2303683200 12      # 1 Jan 1973\n"
178     "2335219200 13      # 1 Jan 1974\n"
179     "2366755200 14      # 1 Jan 1975\n"
180     "2398291200 15      # 1 Jan 1976\n"
181     "2429913600 16      # 1 Jan 1977\n"
182     "2461449600 17      # 1 Jan 1978\n"
183     "2492985600 18      # 1 Jan 1979\n"
184     "2524521600 19      # 1 Jan 1980\n"
185     "#\n"
186     "#h f2349a02 788b9534 a8f2e141 f2029Q6d\n"
187     "#\n";
188
189 // table with good hash and truncated/missing leading zeros
190 static const char leap_gthash [] = {
191     "#\n"
192     "#$  3535228800\n"
193     "#\n"
194     "#  Updated through IERS Bulletin C46\n"
195     "#  File expires on:  28 June 2014\n"
196     "#\n"
197     "#@ 3612902400\n"
198     "#\n"
199     "2272060800 10      # 1 Jan 1972\n"
200     "2287785600 11      # 1 Jul 1972\n"
201     "2303683200 12      # 1 Jan 1973\n"
202     "2335219200 13      # 1 Jan 1974\n"
203     "2366755200 14      # 1 Jan 1975\n"
204     "2398291200 15      # 1 Jan 1976\n"
205     "2429913600 16      # 1 Jan 1977\n"
206     "2461449600 17      # 1 Jan 1978\n"
207     "2492985600 18      # 1 Jan 1979\n"
208     "2524521600 19      # 1 Jan 1980\n"
209     "2571782400 20      # 1 Jul 1981\n"
210     "2603318400 21      # 1 Jul 1982\n"
211     "2634854400 22      # 1 Jul 1983\n"
212     "2698012800 23      # 1 Jul 1985\n"
213     "2776982400 24      # 1 Jan 1988\n"
214     "2840140800 25      # 1 Jan 1990\n"
215     "2871676800 26      # 1 Jan 1991\n"
216     "2918937600 27      # 1 Jul 1992\n"
217     "2950473600 28      # 1 Jul 1993\n"
218     "2982009600 29      # 1 Jul 1994\n"
219     "3029443200 30      # 1 Jan 1996\n"
220     "3076704000 31      # 1 Jul 1997\n"
221     "3124137600 32      # 1 Jan 1999\n"
222     "3345062400 33      # 1 Jan 2006\n"
223     "3439756800 34      # 1 Jan 2009\n"
224     "3550089600 35      # 1 Jul 2012\n"
225     "#\n"
226     "#h 1151a8f e85a5069 9000fcdb 3d5e5365 1d505b37"
227 };
228
229 static const uint32_t lsec2006 = 3345062400u; // +33, 1 Jan 2006, 00:00:00 utc
230 static const uint32_t lsec2009 = 3439756800u; // +34, 1 Jan 2009, 00:00:00 utc
231 static const uint32_t lsec2012 = 3550089600u; // +35, 1 Jul 2012, 00:00:00 utc
232 static const uint32_t lsec2015 = 3644697600u; // +36, 1 Jul 2015, 00:00:00 utc
233
234 int stringreader(void* farg)
235 {
236         const char ** cpp = (const char**)farg;
237
238         if (**cpp)
239                 return *(*cpp)++;
240         else
241                 return EOF;
242 }
243
244 static int/*BOOL*/
245 setup_load_table(
246         const char * cp,
247         int          blim)
248 {
249         int            rc;
250         leap_table_t * pt = leapsec_get_table(0);
251
252         rc = (pt != NULL) && leapsec_load(pt, stringreader, &cp, blim);
253         rc = rc && leapsec_set_table(pt);
254         return rc;
255 }
256
257 static int/*BOOL*/
258 setup_clear_table(void)
259 {
260         int            rc;
261         leap_table_t * pt = leapsec_get_table(0);
262
263         if (pt)
264                 leapsec_clear(pt);
265         rc = leapsec_set_table(pt);
266         return rc;
267 }
268
269
270 char *
271 CalendarToString(const struct calendar cal)
272 {
273         char * ss = malloc (sizeof (char) * 100);
274         char buffer[100] ="";
275
276         *ss = '\0';
277         sprintf(buffer, "%u", cal.year);
278         strcat(ss,buffer);
279         strcat(ss,"-");
280         sprintf(buffer, "%u", (u_int)cal.month);
281         strcat(ss,buffer);
282         strcat(ss,"-");
283         sprintf(buffer, "%u", (u_int)cal.monthday);
284         strcat(ss,buffer);
285         strcat(ss," (");
286         sprintf(buffer, "%u", (u_int) cal.yearday);
287         strcat(ss,buffer);
288         strcat(ss,") ");
289         sprintf(buffer, "%u", (u_int)cal.hour);
290         strcat(ss,buffer);
291         strcat(ss,":");
292         sprintf(buffer, "%u", (u_int)cal.minute);
293         strcat(ss,buffer);
294         strcat(ss,":");
295         sprintf(buffer, "%u", (u_int)cal.second);
296         strcat(ss,buffer);
297         //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;
298         return ss;
299 }
300
301
302 int
303 IsEqual(const struct calendar expected, const struct calendar actual)
304 {
305
306         if (   expected.year == actual.year
307             && (   expected.yearday == actual.yearday
308                 || (   expected.month == actual.month
309                     && expected.monthday == actual.monthday))
310             && expected.hour == actual.hour
311             && expected.minute == actual.minute
312             && expected.second == actual.second) {
313                 return TRUE;
314         } else {
315                 char *p_exp = CalendarToString(expected);
316                 char *p_act = CalendarToString(actual);
317
318                 printf("expected: %s but was %s", p_exp, p_act);
319
320                 free(p_exp);
321                 free(p_act);
322                 return FALSE;
323         }
324 }
325
326 //-------------------------
327
328 void
329 setUp(void)
330 {
331     ntpcal_set_timefunc(timefunc);
332     settime(1970, 1, 1, 0, 0, 0);
333     leapsec_ut_pristine();
334
335     return;
336 }
337
338 void
339 tearDown(void)
340 {
341     ntpcal_set_timefunc(NULL);
342     return;
343 }
344
345 // =====================================================================
346 // VALIDATION TESTS
347 // =====================================================================
348
349 // ----------------------------------------------------------------------
350 void
351 test_ValidateGood(void)
352 {
353         const char *cp = leap_ghash;
354         int         rc = leapsec_validate(stringreader, &cp);
355
356         TEST_ASSERT_EQUAL(LSVALID_GOODHASH, rc);
357         return;
358 }
359
360 // ----------------------------------------------------------------------
361 void
362 test_ValidateNoHash(void)
363 {
364         const char *cp = leap2;
365         int         rc = leapsec_validate(stringreader, &cp);
366
367         TEST_ASSERT_EQUAL(LSVALID_NOHASH, rc);
368         return;
369 }
370
371 // ----------------------------------------------------------------------
372 void
373 test_ValidateBad(void)
374 {
375         const char *cp = leap_bhash;
376         int         rc = leapsec_validate(stringreader, &cp);
377
378         TEST_ASSERT_EQUAL(LSVALID_BADHASH, rc);
379
380         return;
381 }
382
383 // ----------------------------------------------------------------------
384 void
385 test_ValidateMalformed(void)
386 {
387         const char *cp = leap_mhash;
388         int         rc = leapsec_validate(stringreader, &cp);
389
390         TEST_ASSERT_EQUAL(LSVALID_BADFORMAT, rc);
391
392         return;
393 }
394
395 // ----------------------------------------------------------------------
396 void
397 test_ValidateMalformedShort(void)
398 {
399         const char *cp = leap_shash;
400         int         rc = leapsec_validate(stringreader, &cp);
401
402         TEST_ASSERT_EQUAL(LSVALID_BADFORMAT, rc);
403
404         return;
405 }
406
407 // ----------------------------------------------------------------------
408 void
409 test_ValidateNoLeadZero(void)
410 {
411         const char *cp = leap_gthash;
412         int         rc = leapsec_validate(stringreader, &cp);
413
414         TEST_ASSERT_EQUAL(LSVALID_GOODHASH, rc);
415
416         return;
417 }
418
419 // =====================================================================
420 // BASIC FUNCTIONS
421 // =====================================================================
422
423 // ----------------------------------------------------------------------
424 // test table selection
425 void
426 test_tableSelect(void)
427 {
428         leap_table_t *pt1, *pt2, *pt3, *pt4;
429
430         pt1 = leapsec_get_table(0);
431         pt2 = leapsec_get_table(0);
432         TEST_ASSERT_EQUAL_MESSAGE(pt1, pt2,"first");
433
434         pt1 = leapsec_get_table(1);
435         pt2 = leapsec_get_table(1);
436         TEST_ASSERT_EQUAL_MESSAGE(pt1, pt2,"second");
437
438         pt1 = leapsec_get_table(1);
439         pt2 = leapsec_get_table(0);
440         TEST_ASSERT_NOT_EQUAL(pt1, pt2);
441
442         pt1 = leapsec_get_table(0);
443         pt2 = leapsec_get_table(1);
444         TEST_ASSERT_NOT_EQUAL(pt1, pt2);
445
446         leapsec_set_table(pt1);
447         pt2 = leapsec_get_table(0);
448         pt3 = leapsec_get_table(1);
449         TEST_ASSERT_EQUAL(pt1, pt2);
450         TEST_ASSERT_NOT_EQUAL(pt2, pt3);
451
452         pt1 = pt3;
453         leapsec_set_table(pt1);
454         pt2 = leapsec_get_table(0);
455         pt3 = leapsec_get_table(1);
456         TEST_ASSERT_EQUAL(pt1, pt2);
457         TEST_ASSERT_NOT_EQUAL(pt2, pt3);
458
459         return;
460 }
461
462 // ----------------------------------------------------------------------
463 // load file & check expiration
464
465 void
466 test_loadFileExpire(void)
467 {
468         const char *cp = leap1;
469         int rc;
470         leap_table_t * pt = leapsec_get_table(0);
471
472         rc =   leapsec_load(pt, stringreader, &cp, FALSE)
473             && leapsec_set_table(pt);
474         TEST_ASSERT_EQUAL_MESSAGE(1, rc,"first");
475         rc = leapsec_expired(3439756800u, NULL);
476         TEST_ASSERT_EQUAL(0, rc);
477         rc = leapsec_expired(3610569601u, NULL);
478         TEST_ASSERT_EQUAL(1, rc);
479
480         return;
481 }
482
483 // ----------------------------------------------------------------------
484 // load file & check time-to-live
485
486 void
487 test_loadFileTTL(void)
488 {
489         const char     *cp = leap1;
490         int             rc;
491         leap_table_t  * pt = leapsec_get_table(0);
492         time_t          pivot = 0x70000000u;
493         const uint32_t  limit = 3610569600u;
494
495         rc =   leapsec_load(pt, stringreader, &cp, FALSE)
496             && leapsec_set_table(pt);
497         TEST_ASSERT_EQUAL(1, rc); //
498
499         // exactly 1 day to live
500         rc = leapsec_daystolive(limit - 86400, &pivot);
501         TEST_ASSERT_EQUAL( 1, rc);
502         // less than 1 day to live
503         rc = leapsec_daystolive(limit - 86399, &pivot);
504         TEST_ASSERT_EQUAL( 0, rc);
505         // hit expiration exactly
506         rc = leapsec_daystolive(limit, &pivot);
507         TEST_ASSERT_EQUAL( 0, rc);
508         // expired since 1 sec
509         rc = leapsec_daystolive(limit + 1, &pivot);
510         TEST_ASSERT_EQUAL(-1, rc);
511
512         return;
513 }
514
515 // =====================================================================
516 // RANDOM QUERY TESTS
517 // =====================================================================
518
519 // ----------------------------------------------------------------------
520 // test query in pristine state (bug#2745 misbehaviour)
521 void
522 test_lsQueryPristineState(void)
523 {
524         int            rc;
525         leap_result_t  qr;
526
527         rc = leapsec_query(&qr, lsec2012, NULL);
528         TEST_ASSERT_EQUAL(FALSE, rc);
529         TEST_ASSERT_EQUAL(0,             qr.warped   );
530         TEST_ASSERT_EQUAL(LSPROX_NOWARN, qr.proximity);
531
532         return;
533 }
534
535 // ----------------------------------------------------------------------
536 // ad-hoc jump: leap second at 2009.01.01 -60days
537 void
538 test_ls2009faraway(void)
539 {
540         int            rc;
541         leap_result_t  qr;
542
543         rc = setup_load_table(leap1,FALSE);
544         TEST_ASSERT_EQUAL(1, rc);
545
546         // test 60 days before leap. Nothing scheduled or indicated.
547         rc = leapsec_query(&qr, lsec2009 - 60*SECSPERDAY, NULL);
548         TEST_ASSERT_EQUAL(FALSE, rc);
549         TEST_ASSERT_EQUAL(33, qr.tai_offs);
550         TEST_ASSERT_EQUAL(0,  qr.tai_diff);
551         TEST_ASSERT_EQUAL(LSPROX_NOWARN, qr.proximity);
552
553         return;
554 }
555
556 // ----------------------------------------------------------------------
557 // ad-hoc jump: leap second at 2009.01.01 -1week
558 void
559 test_ls2009weekaway(void)
560 {
561         int            rc;
562         leap_result_t  qr;
563
564         rc = setup_load_table(leap1,FALSE);
565         TEST_ASSERT_EQUAL(1, rc);
566
567         // test 7 days before leap. Leap scheduled, but not yet indicated.
568         rc = leapsec_query(&qr, lsec2009 - 7*SECSPERDAY, NULL);
569         TEST_ASSERT_EQUAL(FALSE, rc);
570         TEST_ASSERT_EQUAL(33, qr.tai_offs);
571         TEST_ASSERT_EQUAL(1,  qr.tai_diff);
572         TEST_ASSERT_EQUAL(LSPROX_SCHEDULE, qr.proximity);
573
574         return;
575 }
576
577 // ----------------------------------------------------------------------
578 // ad-hoc jump: leap second at 2009.01.01 -1hr
579 void
580 test_ls2009houraway(void)
581 {
582         int            rc;
583         leap_result_t  qr;
584
585         rc = setup_load_table(leap1,FALSE);
586         TEST_ASSERT_EQUAL(1, rc);
587
588         // test 1 hour before leap. 61 true seconds to go.
589         rc = leapsec_query(&qr, lsec2009 - SECSPERHR, NULL);
590         TEST_ASSERT_EQUAL(FALSE, rc);
591         TEST_ASSERT_EQUAL(33, qr.tai_offs);
592         TEST_ASSERT_EQUAL(1,  qr.tai_diff);
593         TEST_ASSERT_EQUAL(LSPROX_ANNOUNCE, qr.proximity);
594
595         return;
596 }
597
598 // ----------------------------------------------------------------------
599 // ad-hoc jump: leap second at 2009.01.01 -1sec
600 void
601 test_ls2009secaway(void)
602 {
603         int            rc;
604         leap_result_t  qr;
605
606         rc = setup_load_table(leap1,FALSE);
607         TEST_ASSERT_EQUAL(1, rc);
608
609         // test 1 second before leap (last boundary...) 2 true seconds to go.
610         rc = leapsec_query(&qr, lsec2009 - 1, NULL);
611         TEST_ASSERT_EQUAL(FALSE, rc);
612         TEST_ASSERT_EQUAL(33, qr.tai_offs);
613         TEST_ASSERT_EQUAL(1,  qr.tai_diff);
614         TEST_ASSERT_EQUAL(LSPROX_ALERT, qr.proximity);
615
616         return;
617 }
618
619 // ----------------------------------------------------------------------
620 // ad-hoc jump to leap second at 2009.01.01
621 void
622 test_ls2009onspot(void)
623 {
624         int            rc;
625         leap_result_t  qr;
626
627         rc = setup_load_table(leap1,FALSE);
628         TEST_ASSERT_EQUAL(1, rc);
629
630         // test on-spot: treat leap second as already gone.
631         rc = leapsec_query(&qr, lsec2009, NULL);
632         TEST_ASSERT_EQUAL(FALSE, rc);
633         TEST_ASSERT_EQUAL(34, qr.tai_offs);
634         TEST_ASSERT_EQUAL(0,  qr.tai_diff);
635         TEST_ASSERT_EQUAL(LSPROX_NOWARN, qr.proximity);
636
637         return;
638 }
639
640 // ----------------------------------------------------------------------
641 // test handling of the leap second at 2009.01.01 without table
642 void
643 test_ls2009nodata(void)
644 {
645         int            rc;
646         leap_result_t  qr;
647
648         rc = setup_clear_table();
649         TEST_ASSERT_EQUAL(1, rc);
650
651         // test on-spot with empty table
652         rc = leapsec_query(&qr, lsec2009, NULL);
653         TEST_ASSERT_EQUAL(FALSE, rc);
654         TEST_ASSERT_EQUAL(0,  qr.tai_offs);
655         TEST_ASSERT_EQUAL(0,  qr.tai_diff);
656         TEST_ASSERT_EQUAL(LSPROX_NOWARN, qr.proximity);
657
658         return;
659 }
660
661 // ----------------------------------------------------------------------
662 // test handling of the leap second at 2009.01.01 with culled data
663 void
664 test_ls2009limdata(void)
665 {
666         int            rc;
667         leap_result_t  qr;
668
669         rc = setup_load_table(leap1, TRUE);
670         TEST_ASSERT_EQUAL(1, rc);
671
672         // test on-spot with limited table - this is tricky.
673         // The table used ends 2012; depending on the build date, the 2009 entry
674         // might be included or culled. The resulting TAI offset must be either
675         // 34 or 35 seconds, depending on the build date of the test. 
676         rc = leapsec_query(&qr, lsec2009, NULL);
677         TEST_ASSERT_EQUAL(FALSE, rc);
678         TEST_ASSERT_TRUE(34 <= qr.tai_offs);
679         TEST_ASSERT_TRUE(35 >= qr.tai_offs);
680         TEST_ASSERT_EQUAL(0,  qr.tai_diff);
681         TEST_ASSERT_EQUAL(LSPROX_NOWARN, qr.proximity);
682
683         return;
684 }
685
686 // ----------------------------------------------------------------------
687 // Far-distance forward jump into a transiton window.
688 void
689 test_qryJumpFarAhead(void)
690 {
691         int            rc;
692         leap_result_t  qr;
693         int            last, idx;
694         int             mode;
695
696         for (mode=0; mode < 2; ++mode) {
697                 leapsec_ut_pristine();
698                 rc = setup_load_table(leap1, FALSE);
699                 TEST_ASSERT_EQUAL(1, rc);
700                 leapsec_electric(mode);
701
702                 rc = leapsec_query(&qr, lsec2006, NULL);
703                 TEST_ASSERT_EQUAL(FALSE, rc);
704
705                 rc = leapsec_query(&qr, lsec2012, NULL);
706                 TEST_ASSERT_EQUAL(FALSE, rc);
707         }
708 }
709
710 // ----------------------------------------------------------------------
711 // Forward jump into the next transition window
712 void test_qryJumpAheadToTransition(void) {
713         int             rc;
714         leap_result_t   qr;
715         int             last, idx;
716         int             mode;
717
718         for (mode=0; mode < 2; ++mode) {
719                 leapsec_ut_pristine();
720                 rc = setup_load_table(leap1, FALSE);
721                 TEST_ASSERT_EQUAL(1, rc);
722                 leapsec_electric(mode);
723
724                 rc = leapsec_query(&qr, lsec2009-SECSPERDAY, NULL);
725                 TEST_ASSERT_EQUAL(FALSE, rc);
726
727                 rc = leapsec_query(&qr, lsec2009+1, NULL);
728                 TEST_ASSERT_EQUAL(TRUE, rc);
729         }
730
731         return;
732 }
733
734 // ----------------------------------------------------------------------
735 // Forward jump over the next transition window
736 void
737 test_qryJumpAheadOverTransition(void)
738 {
739         int             rc;
740         leap_result_t   qr;
741         int             last, idx;
742         int             mode;
743
744         for (mode=0; mode < 2; ++mode) {
745                 leapsec_ut_pristine();
746                 rc = setup_load_table(leap1, FALSE);
747                 TEST_ASSERT_EQUAL(1, rc);
748                 leapsec_electric(mode);
749
750                 rc = leapsec_query(&qr, lsec2009-SECSPERDAY, NULL);
751                 TEST_ASSERT_EQUAL(FALSE, rc);
752
753                 rc = leapsec_query(&qr, lsec2009+5, NULL);
754                 TEST_ASSERT_EQUAL(FALSE, rc);
755         }
756
757         return;
758 }
759
760 // =====================================================================
761 // TABLE MODIFICATION AT RUNTIME
762 // =====================================================================
763
764 // ----------------------------------------------------------------------
765 // add dynamic leap second (like from peer/clock)
766 void
767 test_addDynamic(void)
768 {
769         int            rc;
770         leap_result_t  qr;
771
772         static const uint32_t insns[] = {
773                 2982009600u,    //      29      # 1 Jul 1994
774                 3029443200u,    //      30      # 1 Jan 1996
775                 3076704000u,    //      31      # 1 Jul 1997
776                 3124137600u,    //      32      # 1 Jan 1999
777                 3345062400u,    //      33      # 1 Jan 2006
778                 3439756800u,    //      34      # 1 Jan 2009
779                 3550089600u,    //      35      # 1 Jul 2012
780                 0 // sentinel
781         };
782
783         rc = setup_load_table(leap2, FALSE);
784         TEST_ASSERT_EQUAL(1, rc);
785
786         int             idx;
787
788         for (idx=1; insns[idx]; ++idx) {
789                 rc = leapsec_add_dyn(TRUE, insns[idx] - 20*SECSPERDAY - 100, NULL);
790                 TEST_ASSERT_EQUAL(TRUE, rc);
791         }
792         // try to slip in a previous entry
793         rc = leapsec_add_dyn(TRUE, insns[0] - 20*SECSPERDAY - 100, NULL);
794         TEST_ASSERT_EQUAL(FALSE, rc);
795         //leap_table_t  * pt = leapsec_get_table(0);
796         //leapsec_dump(pt, (leapsec_dumper)fprintf, stdout);
797
798         return;
799 }
800
801 // ----------------------------------------------------------------------
802 // add fixed leap seconds (like from network packet)
803 #if 0 /* currently unused -- possibly revived later */
804 void
805 FAILtest_addFixed(void)
806 {
807         int            rc;
808         leap_result_t  qr;
809
810         static const struct { uint32_t tt; int of; } insns[] = {
811                 {2982009600u, 29},//    # 1 Jul 1994
812                 {3029443200u, 30},//    # 1 Jan 1996
813                 {3076704000u, 31},//    # 1 Jul 1997
814                 {3124137600u, 32},//    # 1 Jan 1999
815                 {3345062400u, 33},//    # 1 Jan 2006
816                 {3439756800u, 34},//    # 1 Jan 2009
817                 {3550089600u, 35},//    # 1 Jul 2012
818                 {0,0} // sentinel
819         };
820
821         rc = setup_load_table(leap2, FALSE);
822         TEST_ASSERT_EQUAL(1, rc);
823
824         int idx;
825         // try to get in BAD time stamps...
826         for (idx=0; insns[idx].tt; ++idx) {
827             rc = leapsec_add_fix(
828                 insns[idx].of,
829                 insns[idx].tt - 20*SECSPERDAY - 100,
830                 insns[idx].tt + SECSPERDAY,
831                 NULL);
832                 TEST_ASSERT_EQUAL(FALSE, rc);
833         }
834         // now do it right
835         for (idx=0; insns[idx].tt; ++idx) {
836                 rc = leapsec_add_fix(
837                     insns[idx].of,
838                     insns[idx].tt,
839                     insns[idx].tt + SECSPERDAY,
840                     NULL);
841                 TEST_ASSERT_EQUAL(TRUE, rc);
842         }
843         // try to slip in a previous entry
844         rc = leapsec_add_fix(
845             insns[0].of,
846             insns[0].tt,
847             insns[0].tt + SECSPERDAY,
848             NULL);
849         TEST_ASSERT_EQUAL(FALSE, rc);
850         //leap_table_t * pt = leapsec_get_table(0);
851         //leapsec_dump(pt, (leapsec_dumper)fprintf, stdout);
852
853         return;
854 }
855 #endif
856
857 // ----------------------------------------------------------------------
858 // add fixed leap seconds (like from network packet)
859 #if 0 /* currently unused -- possibly revived later */
860 void
861 FAILtest_addFixedExtend(void)
862 {
863         int            rc;
864         leap_result_t  qr;
865         int            last, idx;
866
867         static const struct { uint32_t tt; int of; } insns[] = {
868                 {2982009600u, 29},//    # 1 Jul 1994
869                 {3029443200u, 30},//    # 1 Jan 1996
870                 {0,0} // sentinel
871         };
872
873         rc = setup_load_table(leap2, FALSE);
874         TEST_ASSERT_EQUAL(1, rc);
875
876         for (last=idx=0; insns[idx].tt; ++idx) {
877                 last = idx;
878                 rc = leapsec_add_fix(
879                     insns[idx].of,
880                     insns[idx].tt,
881                     insns[idx].tt + SECSPERDAY,
882                     NULL);
883                 TEST_ASSERT_EQUAL(TRUE, rc);
884         }
885
886         // try to extend the expiration of the last entry
887         rc = leapsec_add_fix(
888             insns[last].of,
889             insns[last].tt,
890             insns[last].tt + 128*SECSPERDAY,
891             NULL);
892         TEST_ASSERT_EQUAL(TRUE, rc);
893
894         // try to extend the expiration of the last entry with wrong offset
895         rc = leapsec_add_fix(
896             insns[last].of+1,
897             insns[last].tt,
898             insns[last].tt + 129*SECSPERDAY,
899             NULL);
900         TEST_ASSERT_EQUAL(FALSE, rc);
901         //leap_table_t * pt = leapsec_get_table(FALSE);
902         //leapsec_dump(pt, (leapsec_dumper)fprintf, stdout);
903
904         return;
905 }
906 #endif
907
908 // ----------------------------------------------------------------------
909 // add fixed leap seconds (like from network packet) in an otherwise
910 // empty table and test queries before / between /after the tabulated
911 // values.
912 #if 0 /* currently unused -- possibly revived later */
913 void
914 FAILtest_setFixedExtend(void)
915 {
916         int            rc;
917         leap_result_t  qr;
918         int            last, idx;
919
920         static const struct { uint32_t tt; int of; } insns[] = {
921                 {2982009600u, 29},//    # 1 Jul 1994
922                 {3029443200u, 30},//    # 1 Jan 1996
923                 {0,0} // sentinel
924         };
925
926         for (last=idx=0; insns[idx].tt; ++idx) {
927                 last = idx;
928                 rc = leapsec_add_fix(
929                     insns[idx].of,
930                     insns[idx].tt,
931                     insns[idx].tt + 128*SECSPERDAY,
932                     NULL);
933                 TEST_ASSERT_EQUAL(TRUE, rc);
934         }
935
936         rc = leapsec_query(&qr, insns[0].tt - 86400, NULL);
937         TEST_ASSERT_EQUAL(28, qr.tai_offs);
938
939         rc = leapsec_query(&qr, insns[0].tt + 86400, NULL);
940         TEST_ASSERT_EQUAL(29, qr.tai_offs);
941
942         rc = leapsec_query(&qr, insns[1].tt - 86400, NULL);
943         TEST_ASSERT_EQUAL(29, qr.tai_offs);
944
945         rc = leapsec_query(&qr, insns[1].tt + 86400, NULL);
946         TEST_ASSERT_EQUAL(30, qr.tai_offs);
947
948         //leap_table_t * pt = leapsec_get_table(0);
949         //leapsec_dump(pt, (leapsec_dumper)fprintf, stdout);
950
951         return;
952 }
953 #endif
954
955 // =====================================================================
956 // AUTOKEY LEAP TRANSFER TESTS
957 // =====================================================================
958
959 // ----------------------------------------------------------------------
960 // Check if the offset can be applied to an empty table ONCE
961 void test_taiEmptyTable(void) {
962         int rc;
963
964         rc = leapsec_autokey_tai(35, lsec2015-30*86400, NULL);
965         TEST_ASSERT_EQUAL(TRUE, rc);
966
967         rc = leapsec_autokey_tai(35, lsec2015-29*86400, NULL);
968         TEST_ASSERT_EQUAL(FALSE, rc);
969 }
970
971 // ----------------------------------------------------------------------
972 // Check that with fixed entries the operation fails
973 void
974 test_taiTableFixed(void)
975 {
976         int rc;
977
978         rc = setup_load_table(leap1, FALSE);
979         TEST_ASSERT_EQUAL(1, rc);
980
981         rc = leapsec_autokey_tai(35, lsec2015-30*86400, NULL);
982         TEST_ASSERT_EQUAL(FALSE, rc);
983
984         return;
985 }
986
987 // ----------------------------------------------------------------------
988 // test adjustment with a dynamic entry already there
989 void
990 test_taiTableDynamic(void)
991 {
992         int        rc;
993         leap_era_t era;
994
995         rc = leapsec_add_dyn(TRUE, lsec2015-20*SECSPERDAY, NULL);
996         TEST_ASSERT_EQUAL(TRUE, rc);
997
998         leapsec_query_era(&era, lsec2015-10, NULL);
999         TEST_ASSERT_EQUAL(0, era.taiof);
1000         leapsec_query_era(&era, lsec2015+10, NULL);
1001         TEST_ASSERT_EQUAL(1, era.taiof);
1002
1003         rc = leapsec_autokey_tai(35, lsec2015-19*86400, NULL);
1004         TEST_ASSERT_EQUAL(TRUE, rc);
1005
1006         rc = leapsec_autokey_tai(35, lsec2015-19*86400, NULL);
1007         TEST_ASSERT_EQUAL(FALSE, rc);
1008
1009         leapsec_query_era(&era, lsec2015-10, NULL);
1010         TEST_ASSERT_EQUAL(35, era.taiof);
1011         leapsec_query_era(&era, lsec2015+10, NULL);
1012         TEST_ASSERT_EQUAL(36, era.taiof);
1013
1014         return;
1015 }
1016
1017 // ----------------------------------------------------------------------
1018 // test adjustment with a dynamic entry already there in dead zone
1019 void
1020 test_taiTableDynamicDeadZone(void)
1021 {
1022         int rc;
1023
1024         rc = leapsec_add_dyn(TRUE, lsec2015-20*SECSPERDAY, NULL);
1025         TEST_ASSERT_EQUAL(TRUE, rc);
1026
1027         rc = leapsec_autokey_tai(35, lsec2015-5, NULL);
1028         TEST_ASSERT_EQUAL(FALSE, rc);
1029
1030         rc = leapsec_autokey_tai(35, lsec2015+5, NULL);
1031         TEST_ASSERT_EQUAL(FALSE, rc);
1032
1033         return;
1034 }
1035
1036
1037 // =====================================================================
1038 // SEQUENCE TESTS
1039 // =====================================================================
1040
1041 // ----------------------------------------------------------------------
1042 // leap second insert at 2009.01.01, electric mode
1043 void
1044 test_ls2009seqInsElectric(void)
1045 {
1046         int            rc;
1047         leap_result_t  qr;
1048
1049         rc = setup_load_table(leap1,FALSE);
1050         TEST_ASSERT_EQUAL(1, rc);
1051         leapsec_electric(1);
1052         TEST_ASSERT_EQUAL(1, leapsec_electric(-1));
1053
1054         rc = leapsec_query(&qr, lsec2009 - 60*SECSPERDAY, NULL);
1055         TEST_ASSERT_EQUAL(FALSE, rc);
1056         TEST_ASSERT_EQUAL(0,             qr.warped   );
1057         TEST_ASSERT_EQUAL(LSPROX_NOWARN, qr.proximity);
1058
1059         rc = leapsec_query(&qr, lsec2009 - 7*SECSPERDAY, NULL);
1060         TEST_ASSERT_EQUAL(FALSE, rc);
1061         TEST_ASSERT_EQUAL(0,               qr.warped   );
1062         TEST_ASSERT_EQUAL(LSPROX_SCHEDULE, qr.proximity);
1063
1064         rc = leapsec_query(&qr, lsec2009 - SECSPERHR, NULL);
1065         TEST_ASSERT_EQUAL(FALSE, rc);
1066         TEST_ASSERT_EQUAL(0,               qr.warped   );
1067         TEST_ASSERT_EQUAL(LSPROX_ANNOUNCE, qr.proximity);
1068
1069         rc = leapsec_query(&qr, lsec2009 - 1, NULL);
1070         TEST_ASSERT_EQUAL(FALSE, rc);
1071         TEST_ASSERT_EQUAL(0,               qr.warped   );
1072         TEST_ASSERT_EQUAL(LSPROX_ALERT,    qr.proximity);
1073
1074         rc = leapsec_query(&qr, lsec2009, NULL);
1075         TEST_ASSERT_EQUAL(TRUE, rc);
1076         TEST_ASSERT_EQUAL(0,             qr.warped   );
1077         TEST_ASSERT_EQUAL(LSPROX_NOWARN, qr.proximity);
1078
1079         // second call, same time frame: no trigger!
1080         rc = leapsec_query(&qr, lsec2009, NULL);
1081         TEST_ASSERT_EQUAL(FALSE, rc);
1082         TEST_ASSERT_EQUAL(0,             qr.warped   );
1083         TEST_ASSERT_EQUAL(LSPROX_NOWARN, qr.proximity);
1084
1085         return;
1086 }
1087
1088 // ----------------------------------------------------------------------
1089 // leap second insert at 2009.01.01, dumb mode
1090 void
1091 test_ls2009seqInsDumb(void)
1092 {
1093         int            rc;
1094         leap_result_t  qr;
1095
1096         rc = setup_load_table(leap1,FALSE);
1097         TEST_ASSERT_EQUAL(1, rc);
1098         TEST_ASSERT_EQUAL(0, leapsec_electric(-1));
1099
1100         rc = leapsec_query(&qr, lsec2009 - 60*SECSPERDAY, NULL);
1101         TEST_ASSERT_EQUAL(FALSE, rc);
1102         TEST_ASSERT_EQUAL(0,             qr.warped   );
1103         TEST_ASSERT_EQUAL(LSPROX_NOWARN, qr.proximity);
1104
1105         rc = leapsec_query(&qr, lsec2009 - 7*SECSPERDAY, NULL);
1106         TEST_ASSERT_EQUAL(FALSE, rc);
1107         TEST_ASSERT_EQUAL(0,               qr.warped   );
1108         TEST_ASSERT_EQUAL(LSPROX_SCHEDULE, qr.proximity);
1109
1110         rc = leapsec_query(&qr, lsec2009 - SECSPERHR, NULL);
1111         TEST_ASSERT_EQUAL(FALSE, rc);
1112         TEST_ASSERT_EQUAL(0,               qr.warped   );
1113         TEST_ASSERT_EQUAL(LSPROX_ANNOUNCE, qr.proximity);
1114
1115         rc = leapsec_query(&qr, lsec2009 - 1, NULL);
1116         TEST_ASSERT_EQUAL(FALSE, rc);
1117         TEST_ASSERT_EQUAL(0,               qr.warped   );
1118         TEST_ASSERT_EQUAL(LSPROX_ALERT,    qr.proximity);
1119
1120         rc = leapsec_query(&qr, lsec2009, NULL);
1121         TEST_ASSERT_EQUAL(FALSE, rc);
1122         TEST_ASSERT_EQUAL(0,               qr.warped   );
1123         TEST_ASSERT_EQUAL(LSPROX_ALERT,    qr.proximity);
1124
1125         rc = leapsec_query(&qr, lsec2009+1, NULL);
1126         TEST_ASSERT_EQUAL(TRUE, rc);
1127         TEST_ASSERT_EQUAL(-1,             qr.warped   );
1128         TEST_ASSERT_EQUAL(LSPROX_NOWARN, qr.proximity);
1129
1130         // second call, same time frame: no trigger!
1131         rc = leapsec_query(&qr, lsec2009, NULL);
1132         TEST_ASSERT_EQUAL(FALSE, rc);
1133         TEST_ASSERT_EQUAL(0,             qr.warped   );
1134         TEST_ASSERT_EQUAL(LSPROX_NOWARN, qr.proximity);
1135
1136         return;
1137 }
1138
1139
1140 // ----------------------------------------------------------------------
1141 // fake leap second remove at 2009.01.01, electric mode
1142 void
1143 test_ls2009seqDelElectric(void)
1144 {
1145         int            rc;
1146         leap_result_t  qr;
1147
1148         rc = setup_load_table(leap3,FALSE);
1149         TEST_ASSERT_EQUAL(1, rc);
1150         leapsec_electric(1);
1151         TEST_ASSERT_EQUAL(1, leapsec_electric(-1));
1152
1153         rc = leapsec_query(&qr, lsec2009 - 60*SECSPERDAY, NULL);
1154         TEST_ASSERT_EQUAL(FALSE, rc);
1155         TEST_ASSERT_EQUAL(0,             qr.warped   );
1156         TEST_ASSERT_EQUAL(LSPROX_NOWARN, qr.proximity);
1157
1158         rc = leapsec_query(&qr, lsec2009 - 7*SECSPERDAY, NULL);
1159         TEST_ASSERT_EQUAL(FALSE, rc);
1160         TEST_ASSERT_EQUAL(0,               qr.warped   );
1161         TEST_ASSERT_EQUAL(LSPROX_SCHEDULE, qr.proximity);
1162
1163         rc = leapsec_query(&qr, lsec2009 - SECSPERHR, NULL);
1164         TEST_ASSERT_EQUAL(FALSE, rc);
1165         TEST_ASSERT_EQUAL(0,               qr.warped   );
1166         TEST_ASSERT_EQUAL(LSPROX_ANNOUNCE, qr.proximity);
1167
1168         rc = leapsec_query(&qr, lsec2009 - 1, NULL);
1169         TEST_ASSERT_EQUAL(FALSE, rc);
1170         TEST_ASSERT_EQUAL(0,               qr.warped   );
1171         TEST_ASSERT_EQUAL(LSPROX_ALERT,    qr.proximity);
1172
1173         rc = leapsec_query(&qr, lsec2009, NULL);
1174         TEST_ASSERT_EQUAL(TRUE, rc);
1175         TEST_ASSERT_EQUAL(0,             qr.warped   );
1176         TEST_ASSERT_EQUAL(LSPROX_NOWARN, qr.proximity);
1177
1178         // second call, same time frame: no trigger!
1179         rc = leapsec_query(&qr, lsec2009, NULL);
1180         TEST_ASSERT_EQUAL(FALSE, rc);
1181         TEST_ASSERT_EQUAL(0,             qr.warped   );
1182         TEST_ASSERT_EQUAL(LSPROX_NOWARN, qr.proximity);
1183
1184         return;
1185 }
1186
1187 // ----------------------------------------------------------------------
1188 // fake leap second remove at 2009.01.01. dumb mode
1189 void
1190 test_ls2009seqDelDumb(void)
1191 {
1192         int            rc;
1193         leap_result_t  qr;
1194
1195         rc = setup_load_table(leap3,FALSE);
1196         TEST_ASSERT_EQUAL(1, rc);
1197         TEST_ASSERT_EQUAL(0, leapsec_electric(-1));
1198
1199         rc = leapsec_query(&qr, lsec2009 - 60*SECSPERDAY, NULL);
1200         TEST_ASSERT_EQUAL(FALSE, rc);
1201         TEST_ASSERT_EQUAL(0,             qr.warped   );
1202         TEST_ASSERT_EQUAL(LSPROX_NOWARN, qr.proximity);
1203
1204         rc = leapsec_query(&qr, lsec2009 - 7*SECSPERDAY, NULL);
1205         TEST_ASSERT_EQUAL(FALSE, rc);
1206         TEST_ASSERT_EQUAL(0,               qr.warped   );
1207         TEST_ASSERT_EQUAL(LSPROX_SCHEDULE, qr.proximity);
1208
1209         rc = leapsec_query(&qr, lsec2009 - SECSPERHR, NULL);
1210         TEST_ASSERT_EQUAL(FALSE, rc);
1211         TEST_ASSERT_EQUAL(0,               qr.warped   );
1212         TEST_ASSERT_EQUAL(LSPROX_ANNOUNCE, qr.proximity);
1213
1214         rc = leapsec_query(&qr, lsec2009 - 2, NULL);
1215         TEST_ASSERT_EQUAL(FALSE, rc);
1216         TEST_ASSERT_EQUAL(0,               qr.warped   );
1217         TEST_ASSERT_EQUAL(LSPROX_ALERT,    qr.proximity);
1218
1219         rc = leapsec_query(&qr, lsec2009 - 1, NULL);
1220         TEST_ASSERT_EQUAL(TRUE, rc);
1221         TEST_ASSERT_EQUAL(1,             qr.warped   );
1222         TEST_ASSERT_EQUAL(LSPROX_NOWARN, qr.proximity);
1223
1224         // second call, same time frame: no trigger!
1225         rc = leapsec_query(&qr, lsec2009, NULL);
1226         TEST_ASSERT_EQUAL(FALSE, rc);
1227         TEST_ASSERT_EQUAL(0,             qr.warped   );
1228         TEST_ASSERT_EQUAL(LSPROX_NOWARN, qr.proximity);
1229
1230         return;
1231 }
1232
1233 // ----------------------------------------------------------------------
1234 // leap second insert at 2012.07.01, electric mode
1235 void
1236 test_ls2012seqInsElectric(void)
1237 {
1238         int            rc;
1239         leap_result_t  qr;
1240
1241         rc = setup_load_table(leap1,FALSE);
1242         TEST_ASSERT_EQUAL(1, rc);
1243         leapsec_electric(1);
1244         TEST_ASSERT_EQUAL(1, leapsec_electric(-1));
1245
1246         rc = leapsec_query(&qr, lsec2012 - 60*SECSPERDAY, NULL);
1247         TEST_ASSERT_EQUAL(FALSE, rc);
1248         TEST_ASSERT_EQUAL(0,             qr.warped   );
1249         TEST_ASSERT_EQUAL(LSPROX_NOWARN, qr.proximity);
1250
1251         rc = leapsec_query(&qr, lsec2012 - 7*SECSPERDAY, NULL);
1252         TEST_ASSERT_EQUAL(FALSE, rc);
1253         TEST_ASSERT_EQUAL(0,               qr.warped   );
1254         TEST_ASSERT_EQUAL(LSPROX_SCHEDULE, qr.proximity);
1255
1256         rc = leapsec_query(&qr, lsec2012 - SECSPERHR, NULL);
1257         TEST_ASSERT_EQUAL(FALSE, rc);
1258         TEST_ASSERT_EQUAL(0,               qr.warped   );
1259         TEST_ASSERT_EQUAL(LSPROX_ANNOUNCE, qr.proximity);
1260
1261         rc = leapsec_query(&qr, lsec2012 - 1, NULL);
1262         TEST_ASSERT_EQUAL(FALSE, rc);
1263         TEST_ASSERT_EQUAL(0,               qr.warped   );
1264         TEST_ASSERT_EQUAL(LSPROX_ALERT,    qr.proximity);
1265
1266         rc = leapsec_query(&qr, lsec2012, NULL);
1267         TEST_ASSERT_EQUAL(TRUE, rc);
1268         TEST_ASSERT_EQUAL(0,            qr.warped   );
1269         TEST_ASSERT_EQUAL(LSPROX_NOWARN, qr.proximity);
1270
1271         // second call, same time frame: no trigger!
1272         rc = leapsec_query(&qr, lsec2012, NULL);
1273         TEST_ASSERT_EQUAL(FALSE, rc);
1274         TEST_ASSERT_EQUAL(0,             qr.warped   );
1275         TEST_ASSERT_EQUAL(LSPROX_NOWARN, qr.proximity);
1276
1277         return;
1278 }
1279
1280 // ----------------------------------------------------------------------
1281 // leap second insert at 2012.07.01, dumb mode
1282 void
1283 test_ls2012seqInsDumb(void)
1284 {
1285         int            rc;
1286         leap_result_t  qr;
1287
1288         rc = setup_load_table(leap1,FALSE);
1289         TEST_ASSERT_EQUAL(1, rc);
1290         TEST_ASSERT_EQUAL(0, leapsec_electric(-1));
1291
1292         rc = leapsec_query(&qr, lsec2012 - 60*SECSPERDAY, NULL);
1293         TEST_ASSERT_EQUAL(FALSE, rc);
1294         TEST_ASSERT_EQUAL(0,             qr.warped   );
1295         TEST_ASSERT_EQUAL(LSPROX_NOWARN, qr.proximity);
1296
1297         rc = leapsec_query(&qr, lsec2012 - 7*SECSPERDAY, NULL);
1298         TEST_ASSERT_EQUAL(FALSE, rc);
1299         TEST_ASSERT_EQUAL(0,               qr.warped   );
1300         TEST_ASSERT_EQUAL(LSPROX_SCHEDULE, qr.proximity);
1301
1302         rc = leapsec_query(&qr, lsec2012 - SECSPERHR, NULL);
1303         TEST_ASSERT_EQUAL(FALSE, rc);
1304         TEST_ASSERT_EQUAL(0,               qr.warped   );
1305         TEST_ASSERT_EQUAL(LSPROX_ANNOUNCE, qr.proximity);
1306
1307         rc = leapsec_query(&qr, lsec2012 - 1, NULL);
1308         TEST_ASSERT_EQUAL(FALSE, rc);
1309         TEST_ASSERT_EQUAL(0,               qr.warped   );
1310         TEST_ASSERT_EQUAL(LSPROX_ALERT,    qr.proximity);
1311
1312         // This is just 1 sec before transition!
1313         rc = leapsec_query(&qr, lsec2012, NULL);
1314         TEST_ASSERT_EQUAL(FALSE, rc);
1315         TEST_ASSERT_EQUAL(0,            qr.warped   );
1316         TEST_ASSERT_EQUAL(LSPROX_ALERT, qr.proximity);
1317
1318         // NOW the insert/backwarp must happen
1319         rc = leapsec_query(&qr, lsec2012+1, NULL);
1320         TEST_ASSERT_EQUAL(TRUE, rc);
1321         TEST_ASSERT_EQUAL(-1,            qr.warped   );
1322         TEST_ASSERT_EQUAL(LSPROX_NOWARN, qr.proximity);
1323
1324         // second call with transition time: no trigger!
1325         rc = leapsec_query(&qr, lsec2012, NULL);
1326         TEST_ASSERT_EQUAL(FALSE, rc);
1327         TEST_ASSERT_EQUAL(0,             qr.warped   );
1328         TEST_ASSERT_EQUAL(LSPROX_NOWARN, qr.proximity);
1329
1330         return;
1331 }
1332
1333 // ----------------------------------------------------------------------
1334 // test repeated query on empty table in dumb mode
1335 void
1336 test_lsEmptyTableDumb(void)
1337 {
1338         int            rc;
1339         leap_result_t  qr;
1340
1341         //const
1342         time_t pivot;
1343         pivot = lsec2012;
1344         //      const 
1345         //time_t   pivot(lsec2012);
1346         const uint32_t t0 = lsec2012 - 10;
1347         const uint32_t tE = lsec2012 + 10;
1348
1349         TEST_ASSERT_EQUAL(0, leapsec_electric(-1));
1350
1351         uint32_t t;
1352         for (t = t0; t != tE; ++t) {
1353                 rc = leapsec_query(&qr, t, &pivot);
1354                 TEST_ASSERT_EQUAL(FALSE, rc);
1355                 TEST_ASSERT_EQUAL(0,             qr.warped   );
1356                 TEST_ASSERT_EQUAL(LSPROX_NOWARN, qr.proximity);
1357         }
1358
1359         return;
1360 }
1361
1362 // ----------------------------------------------------------------------
1363 // test repeated query on empty table in electric mode
1364 void
1365 test_lsEmptyTableElectric(void)
1366 {
1367         int            rc;
1368         leap_result_t  qr;
1369
1370         leapsec_electric(1);
1371         TEST_ASSERT_EQUAL(1, leapsec_electric(-1));
1372
1373         //const 
1374         time_t   pivot;//(lsec2012);
1375         pivot = lsec2012;
1376         const uint32_t t0 = lsec2012 - 10;
1377         const uint32_t tE = lsec2012 + 10;
1378
1379         time_t t;
1380         for (t = t0; t != tE; ++t) {
1381                 rc = leapsec_query(&qr, t, &pivot);
1382                 TEST_ASSERT_EQUAL(FALSE, rc);
1383                 TEST_ASSERT_EQUAL(0,             qr.warped   );
1384                 TEST_ASSERT_EQUAL(LSPROX_NOWARN, qr.proximity);
1385         }
1386
1387         return;
1388 }