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