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
stringreader(void * farg)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*/
setup_load_table(const char * cp,int blim)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*/
setup_clear_table(void)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 *
CalendarToString(const struct calendar cal)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
IsEqual(const struct calendar expected,const struct calendar actual)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
setUp(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
tearDown(void)339 tearDown(void)
340 {
341 ntpcal_set_timefunc(NULL);
342 return;
343 }
344
345 // =====================================================================
346 // VALIDATION TESTS
347 // =====================================================================
348
349 // ----------------------------------------------------------------------
350 void
test_ValidateGood(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
test_ValidateNoHash(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
test_ValidateBad(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
test_ValidateMalformed(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
test_ValidateMalformedShort(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
test_ValidateNoLeadZero(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
test_tableSelect(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
test_loadFileExpire(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
test_loadFileTTL(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
test_lsQueryPristineState(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
test_ls2009faraway(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
test_ls2009weekaway(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
test_ls2009houraway(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
test_ls2009secaway(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
test_ls2009onspot(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
test_ls2009nodata(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
test_ls2009limdata(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
test_qryJumpFarAhead(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
test_qryJumpAheadToTransition(void)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
test_qryJumpAheadOverTransition(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
test_addDynamic(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
test_taiEmptyTable(void)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
test_taiTableFixed(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
test_taiTableDynamic(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
test_taiTableDynamicDeadZone(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
test_ls2009seqInsElectric(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
test_ls2009seqInsDumb(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
test_ls2009seqDelElectric(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
test_ls2009seqDelDumb(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
test_ls2012seqInsElectric(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
test_ls2012seqInsDumb(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
test_lsEmptyTableDumb(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
test_lsEmptyTableElectric(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 }
1389