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