diff options
Diffstat (limited to 'tests/ntpd/leapsec.cpp')
-rw-r--r-- | tests/ntpd/leapsec.cpp | 901 |
1 files changed, 901 insertions, 0 deletions
diff --git a/tests/ntpd/leapsec.cpp b/tests/ntpd/leapsec.cpp new file mode 100644 index 000000000000..6ae0cee34c31 --- /dev/null +++ b/tests/ntpd/leapsec.cpp @@ -0,0 +1,901 @@ +#include "ntpdtest.h" + +extern "C" { +#include "ntp.h" +#include "ntp_calendar.h" +#include "ntp_leapsec.h" +} + +#include <string> +#include <sstream> + +static const char leap1 [] = + "#\n" + "#@ 3610569600\n" + "#\n" + "2272060800 10 # 1 Jan 1972\n" + "2287785600 11 # 1 Jul 1972\n" + "2303683200 12 # 1 Jan 1973\n" + "2335219200 13 # 1 Jan 1974\n" + "2366755200 14 # 1 Jan 1975\n" + "2398291200 15 # 1 Jan 1976\n" + "2429913600 16 # 1 Jan 1977\n" + "2461449600 17 # 1 Jan 1978\n" + "2492985600 18 # 1 Jan 1979\n" + "2524521600 19 # 1 Jan 1980\n" + " \t \n" + "2571782400 20 # 1 Jul 1981\n" + "2603318400 21 # 1 Jul 1982\n" + "2634854400 22 # 1 Jul 1983\n" + "2698012800 23 # 1 Jul 1985\n" + "2776982400 24 # 1 Jan 1988\n" + "2840140800 25 # 1 Jan 1990\n" + "2871676800 26 # 1 Jan 1991\n" + "2918937600 27 # 1 Jul 1992\n" + "2950473600 28 # 1 Jul 1993\n" + "2982009600 29 # 1 Jul 1994\n" + "3029443200 30 # 1 Jan 1996\n" + "3076704000 31 # 1 Jul 1997\n" + "3124137600 32 # 1 Jan 1999\n" + "3345062400 33 # 1 Jan 2006\n" + "3439756800 34 # 1 Jan 2009\n" + "3550089600 35 # 1 Jul 2012\n" + "#\n" + "#h dc2e6b0b 5aade95d a0587abd 4e0dacb4 e4d5049e\n" + "#\n"; + +static const char leap2 [] = + "#\n" + "#@ 2950473700\n" + "#\n" + "2272060800 10 # 1 Jan 1972\n" + "2287785600 11 # 1 Jul 1972\n" + "2303683200 12 # 1 Jan 1973\n" + "2335219200 13 # 1 Jan 1974\n" + "2366755200 14 # 1 Jan 1975\n" + "2398291200 15 # 1 Jan 1976\n" + "2429913600 16 # 1 Jan 1977\n" + "2461449600 17 # 1 Jan 1978\n" + "2492985600 18 # 1 Jan 1979\n" + "2524521600 19 # 1 Jan 1980\n" + "2571782400 20 # 1 Jul 1981\n" + "2603318400 21 # 1 Jul 1982\n" + "2634854400 22 # 1 Jul 1983\n" + "2698012800 23 # 1 Jul 1985\n" + "2776982400 24 # 1 Jan 1988\n" + "2840140800 25 # 1 Jan 1990\n" + "2871676800 26 # 1 Jan 1991\n" + "2918937600 27 # 1 Jul 1992\n" + "2950473600 28 # 1 Jul 1993\n" + "#\n"; + +// Faked table with a leap second removal at 2009 +static const char leap3 [] = + "#\n" + "#@ 3610569600\n" + "#\n" + "2272060800 10 # 1 Jan 1972\n" + "2287785600 11 # 1 Jul 1972\n" + "2303683200 12 # 1 Jan 1973\n" + "2335219200 13 # 1 Jan 1974\n" + "2366755200 14 # 1 Jan 1975\n" + "2398291200 15 # 1 Jan 1976\n" + "2429913600 16 # 1 Jan 1977\n" + "2461449600 17 # 1 Jan 1978\n" + "2492985600 18 # 1 Jan 1979\n" + "2524521600 19 # 1 Jan 1980\n" + "2571782400 20 # 1 Jul 1981\n" + "2603318400 21 # 1 Jul 1982\n" + "2634854400 22 # 1 Jul 1983\n" + "2698012800 23 # 1 Jul 1985\n" + "2776982400 24 # 1 Jan 1988\n" + "2840140800 25 # 1 Jan 1990\n" + "2871676800 26 # 1 Jan 1991\n" + "2918937600 27 # 1 Jul 1992\n" + "2950473600 28 # 1 Jul 1993\n" + "2982009600 29 # 1 Jul 1994\n" + "3029443200 30 # 1 Jan 1996\n" + "3076704000 31 # 1 Jul 1997\n" + "3124137600 32 # 1 Jan 1999\n" + "3345062400 33 # 1 Jan 2006\n" + "3439756800 32 # 1 Jan 2009\n" + "3550089600 33 # 1 Jul 2012\n" + "#\n"; + +// short table with good hash +static const char leap_ghash [] = + "#\n" + "#@ 3610569600\n" + "#$ 3610566000\n" + "#\n" + "2272060800 10 # 1 Jan 1972\n" + "2287785600 11 # 1 Jul 1972\n" + "2303683200 12 # 1 Jan 1973\n" + "2335219200 13 # 1 Jan 1974\n" + "2366755200 14 # 1 Jan 1975\n" + "2398291200 15 # 1 Jan 1976\n" + "2429913600 16 # 1 Jan 1977\n" + "2461449600 17 # 1 Jan 1978\n" + "2492985600 18 # 1 Jan 1979\n" + "2524521600 19 # 1 Jan 1980\n" + "#\n" + "#h 4b304e10 95642b3f c10b91f9 90791725 25f280d0\n" + "#\n"; + +// short table with bad hash +static const char leap_bhash [] = + "#\n" + "#@ 3610569600\n" + "#$ 3610566000\n" + "#\n" + "2272060800 10 # 1 Jan 1972\n" + "2287785600 11 # 1 Jul 1972\n" + "2303683200 12 # 1 Jan 1973\n" + "2335219200 13 # 1 Jan 1974\n" + "2366755200 14 # 1 Jan 1975\n" + "2398291200 15 # 1 Jan 1976\n" + "2429913600 16 # 1 Jan 1977\n" + "2461449600 17 # 1 Jan 1978\n" + "2492985600 18 # 1 Jan 1979\n" + "2524521600 19 # 1 Jan 1980\n" + "#\n" + "#h dc2e6b0b 5aade95d a0587abd 4e0dacb4 e4d5049e\n" + "#\n"; + +// short table with malformed hash +static const char leap_mhash [] = + "#\n" + "#@ 3610569600\n" + "#$ 3610566000\n" + "#\n" + "2272060800 10 # 1 Jan 1972\n" + "2287785600 11 # 1 Jul 1972\n" + "2303683200 12 # 1 Jan 1973\n" + "2335219200 13 # 1 Jan 1974\n" + "2366755200 14 # 1 Jan 1975\n" + "2398291200 15 # 1 Jan 1976\n" + "2429913600 16 # 1 Jan 1977\n" + "2461449600 17 # 1 Jan 1978\n" + "2492985600 18 # 1 Jan 1979\n" + "2524521600 19 # 1 Jan 1980\n" + "#\n" + "#h f2349a02 788b9534 a8f2e141 f2029Q6d 4064a7ee\n" + "#\n"; + +// short table with only 4 hash groups +static const char leap_shash [] = + "#\n" + "#@ 3610569600\n" + "#$ 3610566000\n" + "#\n" + "2272060800 10 # 1 Jan 1972\n" + "2287785600 11 # 1 Jul 1972\n" + "2303683200 12 # 1 Jan 1973\n" + "2335219200 13 # 1 Jan 1974\n" + "2366755200 14 # 1 Jan 1975\n" + "2398291200 15 # 1 Jan 1976\n" + "2429913600 16 # 1 Jan 1977\n" + "2461449600 17 # 1 Jan 1978\n" + "2492985600 18 # 1 Jan 1979\n" + "2524521600 19 # 1 Jan 1980\n" + "#\n" + "#h f2349a02 788b9534 a8f2e141 f2029Q6d\n" + "#\n"; + +// table with good hash and truncated/missing leading zeros +static const char leap_gthash [] = { + "#\n" + "#$ 3535228800\n" + "#\n" + "# Updated through IERS Bulletin C46\n" + "# File expires on: 28 June 2014\n" + "#\n" + "#@ 3612902400\n" + "#\n" + "2272060800 10 # 1 Jan 1972\n" + "2287785600 11 # 1 Jul 1972\n" + "2303683200 12 # 1 Jan 1973\n" + "2335219200 13 # 1 Jan 1974\n" + "2366755200 14 # 1 Jan 1975\n" + "2398291200 15 # 1 Jan 1976\n" + "2429913600 16 # 1 Jan 1977\n" + "2461449600 17 # 1 Jan 1978\n" + "2492985600 18 # 1 Jan 1979\n" + "2524521600 19 # 1 Jan 1980\n" + "2571782400 20 # 1 Jul 1981\n" + "2603318400 21 # 1 Jul 1982\n" + "2634854400 22 # 1 Jul 1983\n" + "2698012800 23 # 1 Jul 1985\n" + "2776982400 24 # 1 Jan 1988\n" + "2840140800 25 # 1 Jan 1990\n" + "2871676800 26 # 1 Jan 1991\n" + "2918937600 27 # 1 Jul 1992\n" + "2950473600 28 # 1 Jul 1993\n" + "2982009600 29 # 1 Jul 1994\n" + "3029443200 30 # 1 Jan 1996\n" + "3076704000 31 # 1 Jul 1997\n" + "3124137600 32 # 1 Jan 1999\n" + "3345062400 33 # 1 Jan 2006\n" + "3439756800 34 # 1 Jan 2009\n" + "3550089600 35 # 1 Jul 2012\n" + "#\n" + "#h 1151a8f e85a5069 9000fcdb 3d5e5365 1d505b37" +}; + +static uint32_t lsec2009 = 3439756800u; // 1 Jan 2009, 00:00:00 utc +static uint32_t lsec2012 = 3550089600u; // 1 Jul 2012, 00:00:00 utc + +int stringreader(void* farg) +{ + const char ** cpp = (const char**)farg; + if (**cpp) + return *(*cpp)++; + else + return EOF; +} + +static int/*BOOL*/ +setup_load_table( + const char * cp, + int blim=FALSE) +{ + int rc; + leap_table_t * pt = leapsec_get_table(0); + rc = (pt != NULL) && leapsec_load(pt, stringreader, &cp, blim); + rc = rc && leapsec_set_table(pt); + return rc; +} + +static int/*BOOL*/ +setup_clear_table() +{ + int rc; + leap_table_t * pt = leapsec_get_table(0); + if (pt) + leapsec_clear(pt); + rc = leapsec_set_table(pt); + return rc; +} + + +class leapsecTest : public ntpdtest { +protected: + virtual void SetUp(); + virtual void TearDown(); + + std::string CalendarToString(const calendar &cal) { + std::ostringstream ss; + 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; + return ss.str(); + } + + ::testing::AssertionResult IsEqual(const calendar &expected, const calendar &actual) { + if (expected.year == actual.year && + (expected.yearday == actual.yearday || + (expected.month == actual.month && + expected.monthday == actual.monthday)) && + expected.hour == actual.hour && + expected.minute == actual.minute && + expected.second == actual.second) { + return ::testing::AssertionSuccess(); + } else { + return ::testing::AssertionFailure() + << "expected: " << CalendarToString(expected) << " but was " + << CalendarToString(actual); + } + } +}; + +void leapsecTest::SetUp() +{ + ntpcal_set_timefunc(timefunc); + settime(1970, 1, 1, 0, 0, 0); + leapsec_electric(1); +} + +void leapsecTest::TearDown() +{ + ntpcal_set_timefunc(NULL); +} + +// ===================================================================== +// VALIDATION TESTS +// ===================================================================== + +// ---------------------------------------------------------------------- +TEST_F(leapsecTest, ValidateGood) { + const char *cp = leap_ghash; + int rc = leapsec_validate(stringreader, &cp); + EXPECT_EQ(LSVALID_GOODHASH, rc); +} + +// ---------------------------------------------------------------------- +TEST_F(leapsecTest, ValidateNoHash) { + const char *cp = leap2; + int rc = leapsec_validate(stringreader, &cp); + EXPECT_EQ(LSVALID_NOHASH, rc); +} + +// ---------------------------------------------------------------------- +TEST_F(leapsecTest, ValidateBad) { + const char *cp = leap_bhash; + int rc = leapsec_validate(stringreader, &cp); + EXPECT_EQ(LSVALID_BADHASH, rc); +} + +// ---------------------------------------------------------------------- +TEST_F(leapsecTest, ValidateMalformed) { + const char *cp = leap_mhash; + int rc = leapsec_validate(stringreader, &cp); + EXPECT_EQ(LSVALID_BADFORMAT, rc); +} + +// ---------------------------------------------------------------------- +TEST_F(leapsecTest, ValidateMalformedShort) { + const char *cp = leap_shash; + int rc = leapsec_validate(stringreader, &cp); + EXPECT_EQ(LSVALID_BADFORMAT, rc); +} + +// ---------------------------------------------------------------------- +TEST_F(leapsecTest, ValidateNoLeadZero) { + const char *cp = leap_gthash; + int rc = leapsec_validate(stringreader, &cp); + EXPECT_EQ(LSVALID_GOODHASH, rc); +} + +// ===================================================================== +// BASIC FUNCTIONS +// ===================================================================== + +// ---------------------------------------------------------------------- +// test table selection +TEST_F(leapsecTest, tableSelect) { + leap_table_t *pt1, *pt2, *pt3, *pt4; + + pt1 = leapsec_get_table(0); + pt2 = leapsec_get_table(0); + EXPECT_EQ(pt1, pt2); + + pt1 = leapsec_get_table(1); + pt2 = leapsec_get_table(1); + EXPECT_EQ(pt1, pt2); + + pt1 = leapsec_get_table(1); + pt2 = leapsec_get_table(0); + EXPECT_NE(pt1, pt2); + + pt1 = leapsec_get_table(0); + pt2 = leapsec_get_table(1); + EXPECT_NE(pt1, pt2); + + leapsec_set_table(pt1); + pt2 = leapsec_get_table(0); + pt3 = leapsec_get_table(1); + EXPECT_EQ(pt1, pt2); + EXPECT_NE(pt2, pt3); + + pt1 = pt3; + leapsec_set_table(pt1); + pt2 = leapsec_get_table(0); + pt3 = leapsec_get_table(1); + EXPECT_EQ(pt1, pt2); + EXPECT_NE(pt2, pt3); +} + +// ---------------------------------------------------------------------- +// load file & check expiration +TEST_F(leapsecTest, loadFileExpire) { + const char *cp = leap1; + int rc; + leap_table_t * pt = leapsec_get_table(0); + + rc = leapsec_load(pt, stringreader, &cp, FALSE) + && leapsec_set_table(pt); + EXPECT_EQ(1, rc); + rc = leapsec_expired(3439756800, NULL); + EXPECT_EQ(0, rc); + rc = leapsec_expired(3610569601, NULL); + EXPECT_EQ(1, rc); +} + +// ---------------------------------------------------------------------- +// load file & check time-to-live +TEST_F(leapsecTest, loadFileTTL) { + const char *cp = leap1; + int rc; + leap_table_t * pt = leapsec_get_table(0); + time_t pivot = 0x70000000; + + const uint32_t limit = 3610569600u; + + rc = leapsec_load(pt, stringreader, &cp, FALSE) + && leapsec_set_table(pt); + ASSERT_EQ(1, rc); + + // exactly 1 day to live + rc = leapsec_daystolive(limit - 86400, &pivot); + EXPECT_EQ( 1, rc); + // less than 1 day to live + rc = leapsec_daystolive(limit - 86399, &pivot); + EXPECT_EQ( 0, rc); + // hit expiration exactly + rc = leapsec_daystolive(limit, &pivot); + EXPECT_EQ( 0, rc); + // expired since 1 sec + rc = leapsec_daystolive(limit + 1, &pivot); + EXPECT_EQ(-1, rc); +} + +// ---------------------------------------------------------------------- +// ad-hoc jump: leap second at 2009.01.01 -60days +TEST_F(leapsecTest, ls2009faraway) { + int rc; + leap_result_t qr; + + rc = setup_load_table(leap1); + EXPECT_EQ(1, rc); + + // test 60 days before leap. Nothing scheduled or indicated. + rc = leapsec_query(&qr, lsec2009 - 60*SECSPERDAY, NULL); + EXPECT_EQ(FALSE, rc); + EXPECT_EQ(33, qr.tai_offs); + EXPECT_EQ(0, qr.tai_diff); + EXPECT_EQ(LSPROX_NOWARN, qr.proximity); +} + +// ---------------------------------------------------------------------- +// ad-hoc jump: leap second at 2009.01.01 -1week +TEST_F(leapsecTest, ls2009weekaway) { + int rc; + leap_result_t qr; + + rc = setup_load_table(leap1); + EXPECT_EQ(1, rc); + + // test 7 days before leap. Leap scheduled, but not yet indicated. + rc = leapsec_query(&qr, lsec2009 - 7*SECSPERDAY, NULL); + EXPECT_EQ(FALSE, rc); + EXPECT_EQ(33, qr.tai_offs); + EXPECT_EQ(1, qr.tai_diff); + EXPECT_EQ(LSPROX_SCHEDULE, qr.proximity); +} + +// ---------------------------------------------------------------------- +// ad-hoc jump: leap second at 2009.01.01 -1hr +TEST_F(leapsecTest, ls2009houraway) { + int rc; + leap_result_t qr; + + rc = setup_load_table(leap1); + EXPECT_EQ(1, rc); + + // test 1 hour before leap. 61 true seconds to go. + rc = leapsec_query(&qr, lsec2009 - SECSPERHR, NULL); + EXPECT_EQ(FALSE, rc); + EXPECT_EQ(33, qr.tai_offs); + EXPECT_EQ(1, qr.tai_diff); + EXPECT_EQ(LSPROX_ANNOUNCE, qr.proximity); +} + +// ---------------------------------------------------------------------- +// ad-hoc jump: leap second at 2009.01.01 -1sec +TEST_F(leapsecTest, ls2009secaway) { + int rc; + leap_result_t qr; + + rc = setup_load_table(leap1); + EXPECT_EQ(1, rc); + + // test 1 second before leap (last boundary...) 2 true seconds to go. + rc = leapsec_query(&qr, lsec2009 - 1, NULL); + EXPECT_EQ(FALSE, rc); + EXPECT_EQ(33, qr.tai_offs); + EXPECT_EQ(1, qr.tai_diff); + EXPECT_EQ(LSPROX_ALERT, qr.proximity); +} + +// ---------------------------------------------------------------------- +// ad-hoc jump to leap second at 2009.01.01 +TEST_F(leapsecTest, ls2009onspot) { + int rc; + leap_result_t qr; + + rc = setup_load_table(leap1); + EXPECT_EQ(1, rc); + + // test on-spot: treat leap second as already gone. + rc = leapsec_query(&qr, lsec2009, NULL); + EXPECT_EQ(FALSE, rc); + EXPECT_EQ(34, qr.tai_offs); + EXPECT_EQ(0, qr.tai_diff); + EXPECT_EQ(LSPROX_NOWARN, qr.proximity); +} + +// ---------------------------------------------------------------------- +// test handling of the leap second at 2009.01.01 without table +TEST_F(leapsecTest, ls2009nodata) { + int rc; + leap_result_t qr; + + rc = setup_clear_table(); + EXPECT_EQ(1, rc); + + // test on-spot with empty table + rc = leapsec_query(&qr, lsec2009, NULL); + EXPECT_EQ(FALSE, rc); + EXPECT_EQ(0, qr.tai_offs); + EXPECT_EQ(0, qr.tai_diff); + EXPECT_EQ(LSPROX_NOWARN, qr.proximity); +} + +// ---------------------------------------------------------------------- +// test handling of the leap second at 2009.01.01 with culled data +TEST_F(leapsecTest, ls2009limdata) { + int rc; + leap_result_t qr; + + rc = setup_load_table(leap1, TRUE); + EXPECT_EQ(1, rc); + + // test on-spot with limted table - does not work if build before 2013! + rc = leapsec_query(&qr, lsec2009, NULL); + EXPECT_EQ(FALSE, rc); + EXPECT_EQ(35, qr.tai_offs); + EXPECT_EQ(0, qr.tai_diff); + EXPECT_EQ(LSPROX_NOWARN, qr.proximity); +} + +// ---------------------------------------------------------------------- +// add dynamic leap second (like from peer/clock) +TEST_F(leapsecTest, addDynamic) { + int rc; + leap_result_t qr; + + static const uint32_t insns[] = { + 2982009600, // 29 # 1 Jul 1994 + 3029443200, // 30 # 1 Jan 1996 + 3076704000, // 31 # 1 Jul 1997 + 3124137600, // 32 # 1 Jan 1999 + 3345062400, // 33 # 1 Jan 2006 + 3439756800, // 34 # 1 Jan 2009 + 3550089600, // 35 # 1 Jul 2012 + 0 // sentinel + }; + + rc = setup_load_table(leap2, FALSE); + EXPECT_EQ(1, rc); + + leap_table_t * pt = leapsec_get_table(0); + for (int idx=1; insns[idx]; ++idx) { + rc = leapsec_add_dyn(TRUE, insns[idx] - 20*SECSPERDAY - 100, NULL); + EXPECT_EQ(TRUE, rc); + } + // try to slip in a previous entry + rc = leapsec_add_dyn(TRUE, insns[0] - 20*SECSPERDAY - 100, NULL); + EXPECT_EQ(FALSE, rc); + //leapsec_dump(pt, (leapsec_dumper)fprintf, stdout); +} + +// ---------------------------------------------------------------------- +// add fixed leap seconds (like from network packet) +TEST_F(leapsecTest, addFixed) { + int rc; + leap_result_t qr; + + static const struct { uint32_t tt; int of; } insns[] = { + {2982009600, 29},// # 1 Jul 1994 + {3029443200, 30},// # 1 Jan 1996 + {3076704000, 31},// # 1 Jul 1997 + {3124137600, 32},// # 1 Jan 1999 + {3345062400, 33},// # 1 Jan 2006 + {3439756800, 34},// # 1 Jan 2009 + {3550089600, 35},// # 1 Jul 2012 + {0,0} // sentinel + }; + + rc = setup_load_table(leap2, FALSE); + EXPECT_EQ(1, rc); + + leap_table_t * pt = leapsec_get_table(0); + // try to get in BAD time stamps... + for (int idx=0; insns[idx].tt; ++idx) { + rc = leapsec_add_fix( + insns[idx].of, + insns[idx].tt - 20*SECSPERDAY - 100, + insns[idx].tt + SECSPERDAY, + NULL); + EXPECT_EQ(FALSE, rc); + } + // no do it right + for (int idx=0; insns[idx].tt; ++idx) { + rc = leapsec_add_fix( + insns[idx].of, + insns[idx].tt, + insns[idx].tt + SECSPERDAY, + NULL); + EXPECT_EQ(TRUE, rc); + } + // try to slip in a previous entry + rc = leapsec_add_fix( + insns[0].of, + insns[0].tt, + insns[0].tt + SECSPERDAY, + NULL); + EXPECT_EQ(FALSE, rc); + //leapsec_dump(pt, (leapsec_dumper)fprintf, stdout); +} + +// ===================================================================== +// SEQUENCE TESTS +// ===================================================================== + +// ---------------------------------------------------------------------- +// leap second insert at 2009.01.01, electric mode +TEST_F(leapsecTest, ls2009seqInsElectric) { + int rc; + leap_result_t qr; + + rc = setup_load_table(leap1); + EXPECT_EQ(1, rc); + leapsec_electric(1); + + rc = leapsec_query(&qr, lsec2009 - 60*SECSPERDAY, NULL); + EXPECT_EQ(FALSE, rc); + EXPECT_EQ(0, qr.warped ); + EXPECT_EQ(LSPROX_NOWARN, qr.proximity); + + rc = leapsec_query(&qr, lsec2009 - 7*SECSPERDAY, NULL); + EXPECT_EQ(FALSE, rc); + EXPECT_EQ(0, qr.warped ); + EXPECT_EQ(LSPROX_SCHEDULE, qr.proximity); + + rc = leapsec_query(&qr, lsec2009 - SECSPERHR, NULL); + EXPECT_EQ(FALSE, rc); + EXPECT_EQ(0, qr.warped ); + EXPECT_EQ(LSPROX_ANNOUNCE, qr.proximity); + + rc = leapsec_query(&qr, lsec2009 - 1, NULL); + EXPECT_EQ(FALSE, rc); + EXPECT_EQ(0, qr.warped ); + EXPECT_EQ(LSPROX_ALERT, qr.proximity); + + rc = leapsec_query(&qr, lsec2009, NULL); + EXPECT_EQ(TRUE, rc); + EXPECT_EQ(0, qr.warped ); + EXPECT_EQ(LSPROX_NOWARN, qr.proximity); + + // second call, same time frame: no trigger! + rc = leapsec_query(&qr, lsec2009, NULL); + EXPECT_EQ(FALSE, rc); + EXPECT_EQ(0, qr.warped ); + EXPECT_EQ(LSPROX_NOWARN, qr.proximity); +} + +// ---------------------------------------------------------------------- +// leap second insert at 2009.01.01, dumb mode +TEST_F(leapsecTest, ls2009seqInsDumb) { + int rc; + leap_result_t qr; + + rc = setup_load_table(leap1); + EXPECT_EQ(1, rc); + leapsec_electric(0); + + rc = leapsec_query(&qr, lsec2009 - 60*SECSPERDAY, NULL); + EXPECT_EQ(FALSE, rc); + EXPECT_EQ(0, qr.warped ); + EXPECT_EQ(LSPROX_NOWARN, qr.proximity); + + rc = leapsec_query(&qr, lsec2009 - 7*SECSPERDAY, NULL); + EXPECT_EQ(FALSE, rc); + EXPECT_EQ(0, qr.warped ); + EXPECT_EQ(LSPROX_SCHEDULE, qr.proximity); + + rc = leapsec_query(&qr, lsec2009 - SECSPERHR, NULL); + EXPECT_EQ(FALSE, rc); + EXPECT_EQ(0, qr.warped ); + EXPECT_EQ(LSPROX_ANNOUNCE, qr.proximity); + + rc = leapsec_query(&qr, lsec2009 - 1, NULL); + EXPECT_EQ(FALSE, rc); + EXPECT_EQ(0, qr.warped ); + EXPECT_EQ(LSPROX_ALERT, qr.proximity); + + rc = leapsec_query(&qr, lsec2009, NULL); + EXPECT_EQ(FALSE, rc); + EXPECT_EQ(0, qr.warped ); + EXPECT_EQ(LSPROX_ALERT, qr.proximity); + + rc = leapsec_query(&qr, lsec2009+1, NULL); + EXPECT_EQ(TRUE, rc); + EXPECT_EQ(-1, qr.warped ); + EXPECT_EQ(LSPROX_NOWARN, qr.proximity); + + // second call, same time frame: no trigger! + rc = leapsec_query(&qr, lsec2009, NULL); + EXPECT_EQ(FALSE, rc); + EXPECT_EQ(0, qr.warped ); + EXPECT_EQ(LSPROX_NOWARN, qr.proximity); +} + + +// ---------------------------------------------------------------------- +// fake leap second remove at 2009.01.01, electric mode +TEST_F(leapsecTest, ls2009seqDelElectric) { + int rc; + leap_result_t qr; + + rc = setup_load_table(leap3); + EXPECT_EQ(1, rc); + leapsec_electric(1); + + rc = leapsec_query(&qr, lsec2009 - 60*SECSPERDAY, NULL); + EXPECT_EQ(FALSE, rc); + EXPECT_EQ(0, qr.warped ); + EXPECT_EQ(LSPROX_NOWARN, qr.proximity); + + rc = leapsec_query(&qr, lsec2009 - 7*SECSPERDAY, NULL); + EXPECT_EQ(FALSE, rc); + EXPECT_EQ(0, qr.warped ); + EXPECT_EQ(LSPROX_SCHEDULE, qr.proximity); + + rc = leapsec_query(&qr, lsec2009 - SECSPERHR, NULL); + EXPECT_EQ(FALSE, rc); + EXPECT_EQ(0, qr.warped ); + EXPECT_EQ(LSPROX_ANNOUNCE, qr.proximity); + + rc = leapsec_query(&qr, lsec2009 - 1, NULL); + EXPECT_EQ(FALSE, rc); + EXPECT_EQ(0, qr.warped ); + EXPECT_EQ(LSPROX_ALERT, qr.proximity); + + rc = leapsec_query(&qr, lsec2009, NULL); + EXPECT_EQ(TRUE, rc); + EXPECT_EQ(0, qr.warped ); + EXPECT_EQ(LSPROX_NOWARN, qr.proximity); + + // second call, same time frame: no trigger! + rc = leapsec_query(&qr, lsec2009, NULL); + EXPECT_EQ(FALSE, rc); + EXPECT_EQ(0, qr.warped ); + EXPECT_EQ(LSPROX_NOWARN, qr.proximity); +} + +// ---------------------------------------------------------------------- +// fake leap second remove at 2009.01.01. dumb mode +TEST_F(leapsecTest, ls2009seqDelDumb) { + int rc; + leap_result_t qr; + + rc = setup_load_table(leap3); + EXPECT_EQ(1, rc); + leapsec_electric(0); + + rc = leapsec_query(&qr, lsec2009 - 60*SECSPERDAY, NULL); + EXPECT_EQ(FALSE, rc); + EXPECT_EQ(0, qr.warped ); + EXPECT_EQ(LSPROX_NOWARN, qr.proximity); + + rc = leapsec_query(&qr, lsec2009 - 7*SECSPERDAY, NULL); + EXPECT_EQ(FALSE, rc); + EXPECT_EQ(0, qr.warped ); + EXPECT_EQ(LSPROX_SCHEDULE, qr.proximity); + + rc = leapsec_query(&qr, lsec2009 - SECSPERHR, NULL); + EXPECT_EQ(FALSE, rc); + EXPECT_EQ(0, qr.warped ); + EXPECT_EQ(LSPROX_ANNOUNCE, qr.proximity); + + rc = leapsec_query(&qr, lsec2009 - 2, NULL); + EXPECT_EQ(FALSE, rc); + EXPECT_EQ(0, qr.warped ); + EXPECT_EQ(LSPROX_ALERT, qr.proximity); + + rc = leapsec_query(&qr, lsec2009 - 1, NULL); + EXPECT_EQ(TRUE, rc); + EXPECT_EQ(1, qr.warped ); + EXPECT_EQ(LSPROX_NOWARN, qr.proximity); + + // second call, same time frame: no trigger! + rc = leapsec_query(&qr, lsec2009, NULL); + EXPECT_EQ(FALSE, rc); + EXPECT_EQ(0, qr.warped ); + EXPECT_EQ(LSPROX_NOWARN, qr.proximity); +} + +// ---------------------------------------------------------------------- +// leap second insert at 2012.07.01, electric mode +TEST_F(leapsecTest, ls2012seqInsElectric) { + int rc; + leap_result_t qr; + + rc = setup_load_table(leap1); + EXPECT_EQ(1, rc); + + rc = leapsec_query(&qr, lsec2012 - 60*SECSPERDAY, NULL); + EXPECT_EQ(FALSE, rc); + EXPECT_EQ(0, qr.warped ); + EXPECT_EQ(LSPROX_NOWARN, qr.proximity); + + rc = leapsec_query(&qr, lsec2012 - 7*SECSPERDAY, NULL); + EXPECT_EQ(FALSE, rc); + EXPECT_EQ(0, qr.warped ); + EXPECT_EQ(LSPROX_SCHEDULE, qr.proximity); + + rc = leapsec_query(&qr, lsec2012 - SECSPERHR, NULL); + EXPECT_EQ(FALSE, rc); + EXPECT_EQ(0, qr.warped ); + EXPECT_EQ(LSPROX_ANNOUNCE, qr.proximity); + + rc = leapsec_query(&qr, lsec2012 - 1, NULL); + EXPECT_EQ(FALSE, rc); + EXPECT_EQ(0, qr.warped ); + EXPECT_EQ(LSPROX_ALERT, qr.proximity); + + rc = leapsec_query(&qr, lsec2012, NULL); + EXPECT_EQ(TRUE, rc); + EXPECT_EQ(0, qr.warped ); + EXPECT_EQ(LSPROX_NOWARN, qr.proximity); + + // second call, same time frame: no trigger! + rc = leapsec_query(&qr, lsec2012, NULL); + EXPECT_EQ(FALSE, rc); + EXPECT_EQ(0, qr.warped ); + EXPECT_EQ(LSPROX_NOWARN, qr.proximity); +} + +// ---------------------------------------------------------------------- +// leap second insert at 2012.07.01, dumb mode +TEST_F(leapsecTest, ls2012seqInsDumb) { + int rc; + leap_result_t qr; + + leapsec_electric(0); + EXPECT_EQ(0, leapsec_electric(-1)); + EXPECT_EQ(0, leapsec_electric(-1)); + + rc = setup_load_table(leap1); + EXPECT_EQ(1, rc); + + rc = leapsec_query(&qr, lsec2012 - 60*SECSPERDAY, NULL); + EXPECT_EQ(FALSE, rc); + EXPECT_EQ(0, qr.warped ); + EXPECT_EQ(LSPROX_NOWARN, qr.proximity); + + rc = leapsec_query(&qr, lsec2012 - 7*SECSPERDAY, NULL); + EXPECT_EQ(FALSE, rc); + EXPECT_EQ(0, qr.warped ); + EXPECT_EQ(LSPROX_SCHEDULE, qr.proximity); + + rc = leapsec_query(&qr, lsec2012 - SECSPERHR, NULL); + EXPECT_EQ(FALSE, rc); + EXPECT_EQ(0, qr.warped ); + EXPECT_EQ(LSPROX_ANNOUNCE, qr.proximity); + + rc = leapsec_query(&qr, lsec2012 - 1, NULL); + EXPECT_EQ(FALSE, rc); + EXPECT_EQ(0, qr.warped ); + EXPECT_EQ(LSPROX_ALERT, qr.proximity); + + // This is just 1 sec before transition! + rc = leapsec_query(&qr, lsec2012, NULL); + EXPECT_EQ(FALSE, rc); + EXPECT_EQ(0, qr.warped ); + EXPECT_EQ(LSPROX_ALERT, qr.proximity); + + // NOW the insert/backwarp must happen + rc = leapsec_query(&qr, lsec2012+1, NULL); + EXPECT_EQ(TRUE, rc); + EXPECT_EQ(-1, qr.warped ); + EXPECT_EQ(LSPROX_NOWARN, qr.proximity); + + // second call with transition time: no trigger! + rc = leapsec_query(&qr, lsec2012, NULL); + EXPECT_EQ(FALSE, rc); + EXPECT_EQ(0, qr.warped ); + EXPECT_EQ(LSPROX_NOWARN, qr.proximity); +} + |