]> CyberLeo.Net >> Repos - FreeBSD/releng/10.2.git/blob - contrib/ntp/tests/ntpd/leapsec.c
Fix a regression with SA-15:24 patch that prevented NIS from
[FreeBSD/releng/10.2.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         if (**cpp)
238                 return *(*cpp)++;
239         else
240                 return EOF;
241 }
242
243 static int/*BOOL*/
244 setup_load_table(
245         const char * cp,
246         int          blim)
247 {
248         int            rc;
249         leap_table_t * pt = leapsec_get_table(0);
250         rc = (pt != NULL) && leapsec_load(pt, stringreader, &cp, blim);
251         rc = rc && leapsec_set_table(pt);
252         return rc;
253 }
254
255 static int/*BOOL*/
256 setup_clear_table(void)
257 {
258         int            rc;
259         leap_table_t * pt = leapsec_get_table(0);
260         if (pt)
261                 leapsec_clear(pt);
262         rc = leapsec_set_table(pt);
263         return rc;
264 }
265
266
267 char * CalendarToString(const struct calendar cal) {
268         char * ss = malloc (sizeof (char) * 100);
269         
270         char buffer[100] ="";
271         sprintf(buffer, "%u", cal.year);
272         strcat(ss,buffer);
273         strcat(ss,"-");
274         sprintf(buffer, "%u", (u_int)cal.month);
275         strcat(ss,buffer);
276         strcat(ss,"-");
277         sprintf(buffer, "%u", (u_int)cal.monthday);
278         strcat(ss,buffer);
279         strcat(ss," (");
280         sprintf(buffer, "%u", (u_int) cal.yearday);
281         strcat(ss,buffer);
282         strcat(ss,") ");
283         sprintf(buffer, "%u", (u_int)cal.hour);
284         strcat(ss,buffer);
285         strcat(ss,":");
286         sprintf(buffer, "%u", (u_int)cal.minute);
287         strcat(ss,buffer);
288         strcat(ss,":");
289         sprintf(buffer, "%u", (u_int)cal.second);
290         strcat(ss,buffer);
291         //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;
292         return ss;
293 }
294
295
296 int IsEqual(const struct calendar expected, const struct calendar actual) {
297         if (expected.year == actual.year &&
298                 (expected.yearday == actual.yearday ||
299                  (expected.month == actual.month &&
300                   expected.monthday == actual.monthday)) &&
301                 expected.hour == actual.hour &&
302                 expected.minute == actual.minute &&
303                 expected.second == actual.second) {
304                 return TRUE;
305         } else {
306                 printf("expected: %s but was %s", CalendarToString(expected) ,CalendarToString(actual));
307                 return FALSE;
308                         
309         }
310 }
311
312 //-------------------------
313
314 void setUp(void)
315 {
316     ntpcal_set_timefunc(timefunc);
317     settime(1970, 1, 1, 0, 0, 0);
318     leapsec_ut_pristine();
319 }
320
321 void tearDown(void)
322 {
323     ntpcal_set_timefunc(NULL);
324 }
325
326 // =====================================================================
327 // VALIDATION TESTS
328 // =====================================================================
329
330 // ----------------------------------------------------------------------
331 void test_ValidateGood(void) {
332         const char *cp = leap_ghash;
333         int         rc = leapsec_validate(stringreader, &cp);
334         TEST_ASSERT_EQUAL(LSVALID_GOODHASH, rc);
335 }
336
337 // ----------------------------------------------------------------------
338 void test_ValidateNoHash(void) {
339         const char *cp = leap2;
340         int         rc = leapsec_validate(stringreader, &cp);
341         TEST_ASSERT_EQUAL(LSVALID_NOHASH, rc);
342 }
343
344 // ----------------------------------------------------------------------
345 void test_ValidateBad(void) {
346         const char *cp = leap_bhash;
347         int         rc = leapsec_validate(stringreader, &cp);
348         TEST_ASSERT_EQUAL(LSVALID_BADHASH, rc);
349 }
350
351 // ----------------------------------------------------------------------
352 void test_ValidateMalformed(void) {
353         const char *cp = leap_mhash;
354         int         rc = leapsec_validate(stringreader, &cp);
355         TEST_ASSERT_EQUAL(LSVALID_BADFORMAT, rc);
356 }
357
358 // ----------------------------------------------------------------------
359 void test_ValidateMalformedShort(void) {
360         const char *cp = leap_shash;
361         int         rc = leapsec_validate(stringreader, &cp);
362         TEST_ASSERT_EQUAL(LSVALID_BADFORMAT, rc);
363 }
364
365 // ----------------------------------------------------------------------
366 void test_ValidateNoLeadZero(void) {
367         const char *cp = leap_gthash;
368         int         rc = leapsec_validate(stringreader, &cp);
369         TEST_ASSERT_EQUAL(LSVALID_GOODHASH, rc);
370 }
371
372 // =====================================================================
373 // BASIC FUNCTIONS
374 // =====================================================================
375
376 // ----------------------------------------------------------------------
377 // test table selection
378 void test_tableSelect(void) {
379         leap_table_t *pt1, *pt2, *pt3, *pt4;
380
381         pt1 = leapsec_get_table(0);
382         pt2 = leapsec_get_table(0);
383         TEST_ASSERT_EQUAL_MESSAGE(pt1, pt2,"first");
384
385         pt1 = leapsec_get_table(1);
386         pt2 = leapsec_get_table(1);
387         TEST_ASSERT_EQUAL_MESSAGE(pt1, pt2,"second");
388
389         pt1 = leapsec_get_table(1);
390         pt2 = leapsec_get_table(0);
391         TEST_ASSERT_NOT_EQUAL(pt1, pt2);
392
393         pt1 = leapsec_get_table(0);
394         pt2 = leapsec_get_table(1);
395         TEST_ASSERT_NOT_EQUAL(pt1, pt2);
396
397         leapsec_set_table(pt1);
398         pt2 = leapsec_get_table(0);
399         pt3 = leapsec_get_table(1);
400         TEST_ASSERT_EQUAL(pt1, pt2);
401         TEST_ASSERT_NOT_EQUAL(pt2, pt3);
402
403         pt1 = pt3;
404         leapsec_set_table(pt1);
405         pt2 = leapsec_get_table(0);
406         pt3 = leapsec_get_table(1);
407         TEST_ASSERT_EQUAL(pt1, pt2);
408         TEST_ASSERT_NOT_EQUAL(pt2, pt3);
409 }
410
411 // ----------------------------------------------------------------------
412 // load file & check expiration
413
414 void test_loadFileExpire(void) {
415         const char *cp = leap1;
416         int rc;
417         leap_table_t * pt = leapsec_get_table(0);
418
419         rc =   leapsec_load(pt, stringreader, &cp, FALSE)
420             && leapsec_set_table(pt);
421         TEST_ASSERT_EQUAL_MESSAGE(1, rc,"first");
422         rc = leapsec_expired(3439756800u, NULL);
423         TEST_ASSERT_EQUAL(0, rc);
424         rc = leapsec_expired(3610569601u, NULL);
425         TEST_ASSERT_EQUAL(1, rc);
426 }
427
428 // ----------------------------------------------------------------------
429 // load file & check time-to-live
430
431 void test_loadFileTTL(void) {
432         const char *cp = leap1;
433         int rc;
434         leap_table_t * pt = leapsec_get_table(0);
435         time_t         pivot = 0x70000000u;
436
437         const uint32_t limit = 3610569600u;
438
439         rc =   leapsec_load(pt, stringreader, &cp, FALSE)
440             && leapsec_set_table(pt);
441         TEST_ASSERT_EQUAL(1, rc); //
442
443         // exactly 1 day to live
444         rc = leapsec_daystolive(limit - 86400, &pivot);
445         TEST_ASSERT_EQUAL( 1, rc);      
446         // less than 1 day to live
447         rc = leapsec_daystolive(limit - 86399, &pivot);
448         TEST_ASSERT_EQUAL( 0, rc);      
449         // hit expiration exactly
450         rc = leapsec_daystolive(limit, &pivot);
451         TEST_ASSERT_EQUAL( 0, rc);      
452         // expired since 1 sec
453         rc = leapsec_daystolive(limit + 1, &pivot);
454         TEST_ASSERT_EQUAL(-1, rc);      
455 }
456
457 // =====================================================================
458 // RANDOM QUERY TESTS
459 // =====================================================================
460
461 // ----------------------------------------------------------------------
462 // test query in pristine state (bug#2745 misbehaviour)
463 void test_lsQueryPristineState(void) {
464         int            rc;
465         leap_result_t  qr;
466         
467         rc = leapsec_query(&qr, lsec2012, NULL);
468         TEST_ASSERT_EQUAL(FALSE, rc);
469         TEST_ASSERT_EQUAL(0,             qr.warped   );
470         TEST_ASSERT_EQUAL(LSPROX_NOWARN, qr.proximity);
471 }
472
473 // ----------------------------------------------------------------------
474 // ad-hoc jump: leap second at 2009.01.01 -60days
475 void test_ls2009faraway(void) {
476         int            rc;
477         leap_result_t  qr;
478
479         rc = setup_load_table(leap1,FALSE);
480         TEST_ASSERT_EQUAL(1, rc);
481
482         // test 60 days before leap. Nothing scheduled or indicated.
483         rc = leapsec_query(&qr, lsec2009 - 60*SECSPERDAY, NULL);
484         TEST_ASSERT_EQUAL(FALSE, rc);
485         TEST_ASSERT_EQUAL(33, qr.tai_offs);
486         TEST_ASSERT_EQUAL(0,  qr.tai_diff);
487         TEST_ASSERT_EQUAL(LSPROX_NOWARN, qr.proximity);
488 }
489
490 // ----------------------------------------------------------------------
491 // ad-hoc jump: leap second at 2009.01.01 -1week
492 void test_ls2009weekaway(void) {
493         int            rc;
494         leap_result_t  qr;
495
496         rc = setup_load_table(leap1,FALSE);
497         TEST_ASSERT_EQUAL(1, rc);
498
499         // test 7 days before leap. Leap scheduled, but not yet indicated.
500         rc = leapsec_query(&qr, lsec2009 - 7*SECSPERDAY, NULL);
501         TEST_ASSERT_EQUAL(FALSE, rc);
502         TEST_ASSERT_EQUAL(33, qr.tai_offs);
503         TEST_ASSERT_EQUAL(1,  qr.tai_diff);
504         TEST_ASSERT_EQUAL(LSPROX_SCHEDULE, qr.proximity);
505 }
506
507 // ----------------------------------------------------------------------
508 // ad-hoc jump: leap second at 2009.01.01 -1hr
509 void test_ls2009houraway(void) {
510         int            rc;
511         leap_result_t  qr;
512
513         rc = setup_load_table(leap1,FALSE);
514         TEST_ASSERT_EQUAL(1, rc);
515
516         // test 1 hour before leap. 61 true seconds to go.
517         rc = leapsec_query(&qr, lsec2009 - SECSPERHR, NULL);
518         TEST_ASSERT_EQUAL(FALSE, rc);
519         TEST_ASSERT_EQUAL(33, qr.tai_offs);
520         TEST_ASSERT_EQUAL(1,  qr.tai_diff);
521         TEST_ASSERT_EQUAL(LSPROX_ANNOUNCE, qr.proximity);
522 }
523
524 // ----------------------------------------------------------------------
525 // ad-hoc jump: leap second at 2009.01.01 -1sec
526 void test_ls2009secaway(void) {
527         int            rc;
528         leap_result_t  qr;
529
530         rc = setup_load_table(leap1,FALSE);
531         TEST_ASSERT_EQUAL(1, rc);
532
533         // test 1 second before leap (last boundary...) 2 true seconds to go.
534         rc = leapsec_query(&qr, lsec2009 - 1, NULL);
535         TEST_ASSERT_EQUAL(FALSE, rc);
536         TEST_ASSERT_EQUAL(33, qr.tai_offs);
537         TEST_ASSERT_EQUAL(1,  qr.tai_diff);
538         TEST_ASSERT_EQUAL(LSPROX_ALERT, qr.proximity);
539 }
540
541 // ----------------------------------------------------------------------
542 // ad-hoc jump to leap second at 2009.01.01
543 void test_ls2009onspot(void) {
544         int            rc;
545         leap_result_t  qr;
546
547         rc = setup_load_table(leap1,FALSE);
548         TEST_ASSERT_EQUAL(1, rc);
549
550         // test on-spot: treat leap second as already gone.
551         rc = leapsec_query(&qr, lsec2009, NULL);
552         TEST_ASSERT_EQUAL(FALSE, rc);
553         TEST_ASSERT_EQUAL(34, qr.tai_offs);
554         TEST_ASSERT_EQUAL(0,  qr.tai_diff);
555         TEST_ASSERT_EQUAL(LSPROX_NOWARN, qr.proximity);
556 }
557
558 // ----------------------------------------------------------------------
559 // test handling of the leap second at 2009.01.01 without table
560 void test_ls2009nodata(void) {
561         int            rc;
562         leap_result_t  qr;
563
564         rc = setup_clear_table();
565         TEST_ASSERT_EQUAL(1, rc);
566
567         // test on-spot with empty table
568         rc = leapsec_query(&qr, lsec2009, NULL);
569         TEST_ASSERT_EQUAL(FALSE, rc);
570         TEST_ASSERT_EQUAL(0,  qr.tai_offs);
571         TEST_ASSERT_EQUAL(0,  qr.tai_diff);
572         TEST_ASSERT_EQUAL(LSPROX_NOWARN, qr.proximity);
573 }
574
575 // ----------------------------------------------------------------------
576 // test handling of the leap second at 2009.01.01 with culled data
577 void test_ls2009limdata(void) {
578         int            rc;
579         leap_result_t  qr;
580
581         rc = setup_load_table(leap1, TRUE);
582         TEST_ASSERT_EQUAL(1, rc);
583
584         // test on-spot with limited table - this is tricky.
585         // The table used ends 2012; depending on the build date, the 2009 entry
586         // might be included or culled. The resulting TAI offset must be either
587         // 34 or 35 seconds, depending on the build date of the test. 
588         rc = leapsec_query(&qr, lsec2009, NULL);
589         TEST_ASSERT_EQUAL(FALSE, rc);
590         TEST_ASSERT_TRUE(34 <= qr.tai_offs);
591         TEST_ASSERT_TRUE(35 >= qr.tai_offs);
592         TEST_ASSERT_EQUAL(0,  qr.tai_diff);
593         TEST_ASSERT_EQUAL(LSPROX_NOWARN, qr.proximity);
594 }
595
596 // ----------------------------------------------------------------------
597 // Far-distance forward jump into a transiton window.
598 void test_qryJumpFarAhead(void) {
599         int            rc;
600         leap_result_t  qr;
601         int            last, idx;
602         int             mode;
603
604         for (mode=0; mode < 2; ++mode) {
605                 leapsec_ut_pristine();
606                 rc = setup_load_table(leap1, FALSE);
607                 TEST_ASSERT_EQUAL(1, rc);
608                 leapsec_electric(mode);
609
610                 rc = leapsec_query(&qr, lsec2006, NULL);
611                 TEST_ASSERT_EQUAL(FALSE, rc);
612
613                 rc = leapsec_query(&qr, lsec2012, NULL);
614                 TEST_ASSERT_EQUAL(FALSE, rc);
615         }
616 }
617
618 // ----------------------------------------------------------------------
619 // Forward jump into the next transition window
620 void test_qryJumpAheadToTransition(void) {
621         int            rc;
622         leap_result_t  qr;
623         int            last, idx;
624         int             mode;
625
626         for (mode=0; mode < 2; ++mode) {
627                 leapsec_ut_pristine();
628                 rc = setup_load_table(leap1, FALSE);
629                 TEST_ASSERT_EQUAL(1, rc);
630                 leapsec_electric(mode);
631
632                 rc = leapsec_query(&qr, lsec2009-SECSPERDAY, NULL);
633                 TEST_ASSERT_EQUAL(FALSE, rc);
634
635                 rc = leapsec_query(&qr, lsec2009+1, NULL);
636                 TEST_ASSERT_EQUAL(TRUE, rc);
637         }
638 }
639
640 // ----------------------------------------------------------------------
641 // Forward jump over the next transition window
642 void test_qryJumpAheadOverTransition(void) {
643         int            rc;
644         leap_result_t  qr;
645         int            last, idx;
646         int             mode;
647
648         for (mode=0; mode < 2; ++mode) {
649                 leapsec_ut_pristine();
650                 rc = setup_load_table(leap1, FALSE);
651                 TEST_ASSERT_EQUAL(1, rc);
652                 leapsec_electric(mode);
653
654                 rc = leapsec_query(&qr, lsec2009-SECSPERDAY, NULL);
655                 TEST_ASSERT_EQUAL(FALSE, rc);
656
657                 rc = leapsec_query(&qr, lsec2009+5, NULL);
658                 TEST_ASSERT_EQUAL(FALSE, rc);
659         }
660 }
661
662 // =====================================================================
663 // TABLE MODIFICATION AT RUNTIME
664 // =====================================================================
665
666 // ----------------------------------------------------------------------
667 // add dynamic leap second (like from peer/clock)
668 void test_addDynamic(void) {
669         int            rc;
670         leap_result_t  qr;
671
672         static const uint32_t insns[] = {
673                 2982009600u,    //      29      # 1 Jul 1994
674                 3029443200u,    //      30      # 1 Jan 1996
675                 3076704000u,    //      31      # 1 Jul 1997
676                 3124137600u,    //      32      # 1 Jan 1999
677                 3345062400u,    //      33      # 1 Jan 2006
678                 3439756800u,    //      34      # 1 Jan 2009
679                 3550089600u,    //      35      # 1 Jul 2012
680                 0 // sentinel
681         };
682
683         rc = setup_load_table(leap2, FALSE);
684         TEST_ASSERT_EQUAL(1, rc);
685
686         leap_table_t * pt = leapsec_get_table(0);
687         int             idx;
688
689         for (idx=1; insns[idx]; ++idx) {
690                 rc = leapsec_add_dyn(TRUE, insns[idx] - 20*SECSPERDAY - 100, NULL);
691                 TEST_ASSERT_EQUAL(TRUE, rc);
692         }
693         // try to slip in a previous entry
694         rc = leapsec_add_dyn(TRUE, insns[0] - 20*SECSPERDAY - 100, NULL);
695         TEST_ASSERT_EQUAL(FALSE, rc);
696         //leapsec_dump(pt, (leapsec_dumper)fprintf, stdout);
697 }
698
699 // ----------------------------------------------------------------------
700 // add fixed leap seconds (like from network packet)
701 #if 0 /* currently unused -- possibly revived later */
702 void FAILtest_addFixed(void) {
703         int            rc;
704         leap_result_t  qr;
705
706         static const struct { uint32_t tt; int of; } insns[] = {
707                 {2982009600u, 29},//    # 1 Jul 1994
708                 {3029443200u, 30},//    # 1 Jan 1996
709                 {3076704000u, 31},//    # 1 Jul 1997
710                 {3124137600u, 32},//    # 1 Jan 1999
711                 {3345062400u, 33},//    # 1 Jan 2006
712                 {3439756800u, 34},//    # 1 Jan 2009
713                 {3550089600u, 35},//    # 1 Jul 2012
714                 {0,0} // sentinel
715         };
716
717         rc = setup_load_table(leap2, FALSE);
718         TEST_ASSERT_EQUAL(1, rc);
719         int idx;
720         leap_table_t * pt = leapsec_get_table(0);
721         // try to get in BAD time stamps...
722         for (idx=0; insns[idx].tt; ++idx) {
723             rc = leapsec_add_fix(
724                 insns[idx].of,
725                 insns[idx].tt - 20*SECSPERDAY - 100,
726                 insns[idx].tt + SECSPERDAY,
727                 NULL);
728                 TEST_ASSERT_EQUAL(FALSE, rc);
729         }
730         // now do it right
731         for (idx=0; insns[idx].tt; ++idx) {
732                 rc = leapsec_add_fix(
733                     insns[idx].of,
734                     insns[idx].tt,
735                     insns[idx].tt + SECSPERDAY,
736                     NULL);
737                 TEST_ASSERT_EQUAL(TRUE, rc);
738         }
739         // try to slip in a previous entry
740         rc = leapsec_add_fix(
741             insns[0].of,
742             insns[0].tt,
743             insns[0].tt + SECSPERDAY,
744             NULL);
745         TEST_ASSERT_EQUAL(FALSE, rc);
746         //leapsec_dump(pt, (leapsec_dumper)fprintf, stdout);
747 }
748 #endif
749
750 // ----------------------------------------------------------------------
751 // add fixed leap seconds (like from network packet)
752 #if 0 /* currently unused -- possibly revived later */
753 void FAILtest_addFixedExtend(void) {
754         int            rc;
755         leap_result_t  qr;
756         int            last, idx;
757
758         static const struct { uint32_t tt; int of; } insns[] = {
759                 {2982009600u, 29},//    # 1 Jul 1994
760                 {3029443200u, 30},//    # 1 Jan 1996
761                 {0,0} // sentinel
762         };
763
764         rc = setup_load_table(leap2, FALSE);
765         TEST_ASSERT_EQUAL(1, rc);
766
767         leap_table_t * pt = leapsec_get_table(FALSE);
768         for (last=idx=0; insns[idx].tt; ++idx) {
769                 last = idx;
770                 rc = leapsec_add_fix(
771                     insns[idx].of,
772                     insns[idx].tt,
773                     insns[idx].tt + SECSPERDAY,
774                     NULL);
775                 TEST_ASSERT_EQUAL(TRUE, rc);
776         }
777         
778         // try to extend the expiration of the last entry
779         rc = leapsec_add_fix(
780             insns[last].of,
781             insns[last].tt,
782             insns[last].tt + 128*SECSPERDAY,
783             NULL);
784         TEST_ASSERT_EQUAL(TRUE, rc);
785         
786         // try to extend the expiration of the last entry with wrong offset
787         rc = leapsec_add_fix(
788             insns[last].of+1,
789             insns[last].tt,
790             insns[last].tt + 129*SECSPERDAY,
791             NULL);
792         TEST_ASSERT_EQUAL(FALSE, rc);
793         //leapsec_dump(pt, (leapsec_dumper)fprintf, stdout);
794 }
795 #endif
796
797 // ----------------------------------------------------------------------
798 // add fixed leap seconds (like from network packet) in an otherwise
799 // empty table and test queries before / between /after the tabulated
800 // values.
801 #if 0 /* currently unused -- possibly revived later */
802 void FAILtest_setFixedExtend(void) {
803         int            rc;
804         leap_result_t  qr;
805         int            last, idx;
806
807         static const struct { uint32_t tt; int of; } insns[] = {
808                 {2982009600u, 29},//    # 1 Jul 1994
809                 {3029443200u, 30},//    # 1 Jan 1996
810                 {0,0} // sentinel
811         };
812
813         leap_table_t * pt = leapsec_get_table(0);
814         for (last=idx=0; insns[idx].tt; ++idx) {
815                 last = idx;
816                 rc = leapsec_add_fix(
817                     insns[idx].of,
818                     insns[idx].tt,
819                     insns[idx].tt + 128*SECSPERDAY,
820                     NULL);
821                 TEST_ASSERT_EQUAL(TRUE, rc);
822         }
823         
824         rc = leapsec_query(&qr, insns[0].tt - 86400, NULL);
825         TEST_ASSERT_EQUAL(28, qr.tai_offs);
826
827         rc = leapsec_query(&qr, insns[0].tt + 86400, NULL);
828         TEST_ASSERT_EQUAL(29, qr.tai_offs);
829
830         rc = leapsec_query(&qr, insns[1].tt - 86400, NULL);
831         TEST_ASSERT_EQUAL(29, qr.tai_offs);
832
833         rc = leapsec_query(&qr, insns[1].tt + 86400, NULL);
834         TEST_ASSERT_EQUAL(30, qr.tai_offs);
835
836         //leapsec_dump(pt, (leapsec_dumper)fprintf, stdout);
837 }
838 #endif
839
840 // =====================================================================
841 // AUTOKEY LEAP TRANSFER TESTS
842 // =====================================================================
843
844 // ----------------------------------------------------------------------
845 // Check if the offset can be applied to an empty table ONCE
846 void test_taiEmptyTable(void) {
847         int rc;
848
849         rc = leapsec_autokey_tai(35, lsec2015-30*86400, NULL);  
850         TEST_ASSERT_EQUAL(TRUE, rc);
851
852         rc = leapsec_autokey_tai(35, lsec2015-29*86400, NULL);
853         TEST_ASSERT_EQUAL(FALSE, rc);
854 }
855
856 // ----------------------------------------------------------------------
857 // Check that with fixed entries the operation fails
858 void test_taiTableFixed(void) {
859         int rc;
860
861         rc = setup_load_table(leap1, FALSE);
862         TEST_ASSERT_EQUAL(1, rc);
863
864         rc = leapsec_autokey_tai(35, lsec2015-30*86400, NULL);
865         TEST_ASSERT_EQUAL(FALSE, rc);
866 }
867
868 // ----------------------------------------------------------------------
869 // test adjustment with a dynamic entry already there
870 void test_taiTableDynamic(void) {
871         int        rc;
872         leap_era_t era;
873
874         rc = leapsec_add_dyn(TRUE, lsec2015-20*SECSPERDAY, NULL);
875         TEST_ASSERT_EQUAL(TRUE, rc);
876
877         leapsec_query_era(&era, lsec2015-10, NULL);
878         TEST_ASSERT_EQUAL(0, era.taiof);
879         leapsec_query_era(&era, lsec2015+10, NULL);
880         TEST_ASSERT_EQUAL(1, era.taiof);
881
882         rc = leapsec_autokey_tai(35, lsec2015-19*86400, NULL);  
883         TEST_ASSERT_EQUAL(TRUE, rc);
884
885         rc = leapsec_autokey_tai(35, lsec2015-19*86400, NULL);
886         TEST_ASSERT_EQUAL(FALSE, rc);
887
888         leapsec_query_era(&era, lsec2015-10, NULL);
889         TEST_ASSERT_EQUAL(35, era.taiof);
890         leapsec_query_era(&era, lsec2015+10, NULL);
891         TEST_ASSERT_EQUAL(36, era.taiof);
892 }
893
894 // ----------------------------------------------------------------------
895 // test adjustment with a dynamic entry already there in dead zone
896 void test_taiTableDynamicDeadZone(void) {
897         int rc;
898
899         rc = leapsec_add_dyn(TRUE, lsec2015-20*SECSPERDAY, NULL);
900         TEST_ASSERT_EQUAL(TRUE, rc);
901
902         rc = leapsec_autokey_tai(35, lsec2015-5, NULL); 
903         TEST_ASSERT_EQUAL(FALSE, rc);
904
905         rc = leapsec_autokey_tai(35, lsec2015+5, NULL);
906         TEST_ASSERT_EQUAL(FALSE, rc);
907 }
908
909
910 // =====================================================================
911 // SEQUENCE TESTS
912 // =====================================================================
913
914 // ----------------------------------------------------------------------
915 // leap second insert at 2009.01.01, electric mode
916 void test_ls2009seqInsElectric(void) {
917         int            rc;
918         leap_result_t  qr;
919
920         rc = setup_load_table(leap1,FALSE);
921         TEST_ASSERT_EQUAL(1, rc);
922         leapsec_electric(1);
923         TEST_ASSERT_EQUAL(1, leapsec_electric(-1));
924
925         rc = leapsec_query(&qr, lsec2009 - 60*SECSPERDAY, NULL);
926         TEST_ASSERT_EQUAL(FALSE, rc);
927         TEST_ASSERT_EQUAL(0,             qr.warped   );
928         TEST_ASSERT_EQUAL(LSPROX_NOWARN, qr.proximity);
929
930         rc = leapsec_query(&qr, lsec2009 - 7*SECSPERDAY, NULL);
931         TEST_ASSERT_EQUAL(FALSE, rc);
932         TEST_ASSERT_EQUAL(0,               qr.warped   );
933         TEST_ASSERT_EQUAL(LSPROX_SCHEDULE, qr.proximity);
934
935         rc = leapsec_query(&qr, lsec2009 - SECSPERHR, NULL);
936         TEST_ASSERT_EQUAL(FALSE, rc);
937         TEST_ASSERT_EQUAL(0,               qr.warped   );
938         TEST_ASSERT_EQUAL(LSPROX_ANNOUNCE, qr.proximity);
939
940         rc = leapsec_query(&qr, lsec2009 - 1, NULL);
941         TEST_ASSERT_EQUAL(FALSE, rc);
942         TEST_ASSERT_EQUAL(0,               qr.warped   );
943         TEST_ASSERT_EQUAL(LSPROX_ALERT,    qr.proximity);
944
945         rc = leapsec_query(&qr, lsec2009, NULL);
946         TEST_ASSERT_EQUAL(TRUE, rc);
947         TEST_ASSERT_EQUAL(0,             qr.warped   );
948         TEST_ASSERT_EQUAL(LSPROX_NOWARN, qr.proximity);
949
950         // second call, same time frame: no trigger!
951         rc = leapsec_query(&qr, lsec2009, NULL);
952         TEST_ASSERT_EQUAL(FALSE, rc);
953         TEST_ASSERT_EQUAL(0,             qr.warped   );
954         TEST_ASSERT_EQUAL(LSPROX_NOWARN, qr.proximity);
955 }
956
957 // ----------------------------------------------------------------------
958 // leap second insert at 2009.01.01, dumb mode
959 void test_ls2009seqInsDumb(void) {
960         int            rc;
961         leap_result_t  qr;
962
963         rc = setup_load_table(leap1,FALSE);
964         TEST_ASSERT_EQUAL(1, rc);
965         TEST_ASSERT_EQUAL(0, leapsec_electric(-1));
966
967         rc = leapsec_query(&qr, lsec2009 - 60*SECSPERDAY, NULL);
968         TEST_ASSERT_EQUAL(FALSE, rc);
969         TEST_ASSERT_EQUAL(0,             qr.warped   );
970         TEST_ASSERT_EQUAL(LSPROX_NOWARN, qr.proximity);
971
972         rc = leapsec_query(&qr, lsec2009 - 7*SECSPERDAY, NULL);
973         TEST_ASSERT_EQUAL(FALSE, rc);
974         TEST_ASSERT_EQUAL(0,               qr.warped   );
975         TEST_ASSERT_EQUAL(LSPROX_SCHEDULE, qr.proximity);
976
977         rc = leapsec_query(&qr, lsec2009 - SECSPERHR, NULL);
978         TEST_ASSERT_EQUAL(FALSE, rc);
979         TEST_ASSERT_EQUAL(0,               qr.warped   );
980         TEST_ASSERT_EQUAL(LSPROX_ANNOUNCE, qr.proximity);
981
982         rc = leapsec_query(&qr, lsec2009 - 1, NULL);
983         TEST_ASSERT_EQUAL(FALSE, rc);
984         TEST_ASSERT_EQUAL(0,               qr.warped   );
985         TEST_ASSERT_EQUAL(LSPROX_ALERT,    qr.proximity);
986
987         rc = leapsec_query(&qr, lsec2009, NULL);
988         TEST_ASSERT_EQUAL(FALSE, rc);
989         TEST_ASSERT_EQUAL(0,               qr.warped   );
990         TEST_ASSERT_EQUAL(LSPROX_ALERT,    qr.proximity);
991
992         rc = leapsec_query(&qr, lsec2009+1, NULL);
993         TEST_ASSERT_EQUAL(TRUE, rc);
994         TEST_ASSERT_EQUAL(-1,             qr.warped   );
995         TEST_ASSERT_EQUAL(LSPROX_NOWARN, qr.proximity);
996
997         // second call, same time frame: no trigger!
998         rc = leapsec_query(&qr, lsec2009, NULL);
999         TEST_ASSERT_EQUAL(FALSE, rc);
1000         TEST_ASSERT_EQUAL(0,             qr.warped   );
1001         TEST_ASSERT_EQUAL(LSPROX_NOWARN, qr.proximity);
1002 }
1003
1004
1005 // ----------------------------------------------------------------------
1006 // fake leap second remove at 2009.01.01, electric mode
1007 void test_ls2009seqDelElectric(void) {
1008         int            rc;
1009         leap_result_t  qr;
1010
1011         rc = setup_load_table(leap3,FALSE);
1012         TEST_ASSERT_EQUAL(1, rc);
1013         leapsec_electric(1);
1014         TEST_ASSERT_EQUAL(1, leapsec_electric(-1));
1015
1016         rc = leapsec_query(&qr, lsec2009 - 60*SECSPERDAY, NULL);
1017         TEST_ASSERT_EQUAL(FALSE, rc);
1018         TEST_ASSERT_EQUAL(0,             qr.warped   );
1019         TEST_ASSERT_EQUAL(LSPROX_NOWARN, qr.proximity);
1020
1021         rc = leapsec_query(&qr, lsec2009 - 7*SECSPERDAY, NULL);
1022         TEST_ASSERT_EQUAL(FALSE, rc);
1023         TEST_ASSERT_EQUAL(0,               qr.warped   );
1024         TEST_ASSERT_EQUAL(LSPROX_SCHEDULE, qr.proximity);
1025
1026         rc = leapsec_query(&qr, lsec2009 - SECSPERHR, NULL);
1027         TEST_ASSERT_EQUAL(FALSE, rc);
1028         TEST_ASSERT_EQUAL(0,               qr.warped   );
1029         TEST_ASSERT_EQUAL(LSPROX_ANNOUNCE, qr.proximity);
1030
1031         rc = leapsec_query(&qr, lsec2009 - 1, NULL);
1032         TEST_ASSERT_EQUAL(FALSE, rc);
1033         TEST_ASSERT_EQUAL(0,               qr.warped   );
1034         TEST_ASSERT_EQUAL(LSPROX_ALERT,    qr.proximity);
1035
1036         rc = leapsec_query(&qr, lsec2009, NULL);
1037         TEST_ASSERT_EQUAL(TRUE, rc);
1038         TEST_ASSERT_EQUAL(0,             qr.warped   );
1039         TEST_ASSERT_EQUAL(LSPROX_NOWARN, qr.proximity);
1040
1041         // second call, same time frame: no trigger!
1042         rc = leapsec_query(&qr, lsec2009, NULL);
1043         TEST_ASSERT_EQUAL(FALSE, rc);
1044         TEST_ASSERT_EQUAL(0,             qr.warped   );
1045         TEST_ASSERT_EQUAL(LSPROX_NOWARN, qr.proximity);
1046 }
1047
1048 // ----------------------------------------------------------------------
1049 // fake leap second remove at 2009.01.01. dumb mode
1050 void test_ls2009seqDelDumb(void) {
1051         int            rc;
1052         leap_result_t  qr;
1053
1054         rc = setup_load_table(leap3,FALSE);
1055         TEST_ASSERT_EQUAL(1, rc);
1056         TEST_ASSERT_EQUAL(0, leapsec_electric(-1));
1057
1058         rc = leapsec_query(&qr, lsec2009 - 60*SECSPERDAY, NULL);
1059         TEST_ASSERT_EQUAL(FALSE, rc);
1060         TEST_ASSERT_EQUAL(0,             qr.warped   );
1061         TEST_ASSERT_EQUAL(LSPROX_NOWARN, qr.proximity);
1062
1063         rc = leapsec_query(&qr, lsec2009 - 7*SECSPERDAY, NULL);
1064         TEST_ASSERT_EQUAL(FALSE, rc);
1065         TEST_ASSERT_EQUAL(0,               qr.warped   );
1066         TEST_ASSERT_EQUAL(LSPROX_SCHEDULE, qr.proximity);
1067
1068         rc = leapsec_query(&qr, lsec2009 - SECSPERHR, NULL);
1069         TEST_ASSERT_EQUAL(FALSE, rc);
1070         TEST_ASSERT_EQUAL(0,               qr.warped   );
1071         TEST_ASSERT_EQUAL(LSPROX_ANNOUNCE, qr.proximity);
1072
1073         rc = leapsec_query(&qr, lsec2009 - 2, NULL);
1074         TEST_ASSERT_EQUAL(FALSE, rc);
1075         TEST_ASSERT_EQUAL(0,               qr.warped   );
1076         TEST_ASSERT_EQUAL(LSPROX_ALERT,    qr.proximity);
1077
1078         rc = leapsec_query(&qr, lsec2009 - 1, NULL);
1079         TEST_ASSERT_EQUAL(TRUE, rc);
1080         TEST_ASSERT_EQUAL(1,             qr.warped   );
1081         TEST_ASSERT_EQUAL(LSPROX_NOWARN, qr.proximity);
1082
1083         // second call, same time frame: no trigger!
1084         rc = leapsec_query(&qr, lsec2009, NULL);
1085         TEST_ASSERT_EQUAL(FALSE, rc);
1086         TEST_ASSERT_EQUAL(0,             qr.warped   );
1087         TEST_ASSERT_EQUAL(LSPROX_NOWARN, qr.proximity);
1088 }
1089
1090 // ----------------------------------------------------------------------
1091 // leap second insert at 2012.07.01, electric mode
1092 void test_ls2012seqInsElectric(void) {
1093         int            rc;
1094         leap_result_t  qr;
1095
1096         rc = setup_load_table(leap1,FALSE);
1097         TEST_ASSERT_EQUAL(1, rc);
1098         leapsec_electric(1);
1099         TEST_ASSERT_EQUAL(1, leapsec_electric(-1));
1100
1101         rc = leapsec_query(&qr, lsec2012 - 60*SECSPERDAY, NULL);
1102         TEST_ASSERT_EQUAL(FALSE, rc);
1103         TEST_ASSERT_EQUAL(0,             qr.warped   );
1104         TEST_ASSERT_EQUAL(LSPROX_NOWARN, qr.proximity);
1105
1106         rc = leapsec_query(&qr, lsec2012 - 7*SECSPERDAY, NULL);
1107         TEST_ASSERT_EQUAL(FALSE, rc);
1108         TEST_ASSERT_EQUAL(0,               qr.warped   );
1109         TEST_ASSERT_EQUAL(LSPROX_SCHEDULE, qr.proximity);
1110
1111         rc = leapsec_query(&qr, lsec2012 - SECSPERHR, NULL);
1112         TEST_ASSERT_EQUAL(FALSE, rc);
1113         TEST_ASSERT_EQUAL(0,               qr.warped   );
1114         TEST_ASSERT_EQUAL(LSPROX_ANNOUNCE, qr.proximity);
1115
1116         rc = leapsec_query(&qr, lsec2012 - 1, NULL);
1117         TEST_ASSERT_EQUAL(FALSE, rc);
1118         TEST_ASSERT_EQUAL(0,               qr.warped   );
1119         TEST_ASSERT_EQUAL(LSPROX_ALERT,    qr.proximity);
1120
1121         rc = leapsec_query(&qr, lsec2012, NULL);
1122         TEST_ASSERT_EQUAL(TRUE, rc);
1123         TEST_ASSERT_EQUAL(0,            qr.warped   );
1124         TEST_ASSERT_EQUAL(LSPROX_NOWARN, qr.proximity);
1125
1126         // second call, same time frame: no trigger!
1127         rc = leapsec_query(&qr, lsec2012, NULL);
1128         TEST_ASSERT_EQUAL(FALSE, rc);
1129         TEST_ASSERT_EQUAL(0,             qr.warped   );
1130         TEST_ASSERT_EQUAL(LSPROX_NOWARN, qr.proximity);
1131 }
1132
1133 // ----------------------------------------------------------------------
1134 // leap second insert at 2012.07.01, dumb mode
1135 void test_ls2012seqInsDumb(void) {
1136         int            rc;
1137         leap_result_t  qr;
1138
1139         rc = setup_load_table(leap1,FALSE);
1140         TEST_ASSERT_EQUAL(1, rc);
1141         TEST_ASSERT_EQUAL(0, leapsec_electric(-1));
1142
1143         rc = leapsec_query(&qr, lsec2012 - 60*SECSPERDAY, NULL);
1144         TEST_ASSERT_EQUAL(FALSE, rc);
1145         TEST_ASSERT_EQUAL(0,             qr.warped   );
1146         TEST_ASSERT_EQUAL(LSPROX_NOWARN, qr.proximity);
1147
1148         rc = leapsec_query(&qr, lsec2012 - 7*SECSPERDAY, NULL);
1149         TEST_ASSERT_EQUAL(FALSE, rc);
1150         TEST_ASSERT_EQUAL(0,               qr.warped   );
1151         TEST_ASSERT_EQUAL(LSPROX_SCHEDULE, qr.proximity);
1152
1153         rc = leapsec_query(&qr, lsec2012 - SECSPERHR, NULL);
1154         TEST_ASSERT_EQUAL(FALSE, rc);
1155         TEST_ASSERT_EQUAL(0,               qr.warped   );
1156         TEST_ASSERT_EQUAL(LSPROX_ANNOUNCE, qr.proximity);
1157
1158         rc = leapsec_query(&qr, lsec2012 - 1, NULL);
1159         TEST_ASSERT_EQUAL(FALSE, rc);
1160         TEST_ASSERT_EQUAL(0,               qr.warped   );
1161         TEST_ASSERT_EQUAL(LSPROX_ALERT,    qr.proximity);
1162
1163         // This is just 1 sec before transition!
1164         rc = leapsec_query(&qr, lsec2012, NULL);
1165         TEST_ASSERT_EQUAL(FALSE, rc);
1166         TEST_ASSERT_EQUAL(0,            qr.warped   );
1167         TEST_ASSERT_EQUAL(LSPROX_ALERT, qr.proximity);
1168
1169         // NOW the insert/backwarp must happen
1170         rc = leapsec_query(&qr, lsec2012+1, NULL);
1171         TEST_ASSERT_EQUAL(TRUE, rc);
1172         TEST_ASSERT_EQUAL(-1,            qr.warped   );
1173         TEST_ASSERT_EQUAL(LSPROX_NOWARN, qr.proximity);
1174
1175         // second call with transition time: no trigger!
1176         rc = leapsec_query(&qr, lsec2012, NULL);
1177         TEST_ASSERT_EQUAL(FALSE, rc);
1178         TEST_ASSERT_EQUAL(0,             qr.warped   );
1179         TEST_ASSERT_EQUAL(LSPROX_NOWARN, qr.proximity);
1180 }
1181
1182 // ----------------------------------------------------------------------
1183 // test repeated query on empty table in dumb mode
1184 void test_lsEmptyTableDumb(void) {
1185         int            rc;
1186         leap_result_t  qr;
1187
1188         //const
1189         time_t pivot;
1190         pivot = lsec2012;
1191         //      const 
1192         //time_t   pivot(lsec2012);             
1193         const uint32_t t0 = lsec2012 - 10;
1194         const uint32_t tE = lsec2012 + 10;
1195
1196         TEST_ASSERT_EQUAL(0, leapsec_electric(-1));
1197
1198         uint32_t t;
1199         for (t = t0; t != tE; ++t) {
1200                 rc = leapsec_query(&qr, t, &pivot);
1201                 TEST_ASSERT_EQUAL(FALSE, rc);
1202                 TEST_ASSERT_EQUAL(0,             qr.warped   );
1203                 TEST_ASSERT_EQUAL(LSPROX_NOWARN, qr.proximity);
1204         }
1205 }
1206
1207 // ----------------------------------------------------------------------
1208 // test repeated query on empty table in electric mode
1209 void test_lsEmptyTableElectric(void) {
1210         int            rc;
1211         leap_result_t  qr;
1212         
1213         leapsec_electric(1);
1214         TEST_ASSERT_EQUAL(1, leapsec_electric(-1));
1215
1216         //const 
1217         time_t   pivot;//(lsec2012);
1218         pivot = lsec2012;       
1219         const uint32_t t0 = lsec2012 - 10;
1220         const uint32_t tE = lsec2012 + 10;
1221
1222         time_t t;
1223         for (t = t0; t != tE; ++t) {
1224                 rc = leapsec_query(&qr, t, &pivot);
1225                 TEST_ASSERT_EQUAL(FALSE, rc);
1226                 TEST_ASSERT_EQUAL(0,             qr.warped   );
1227                 TEST_ASSERT_EQUAL(LSPROX_NOWARN, qr.proximity);
1228         }
1229 }