From: Damir Tomic Date: Wed, 1 Jul 2015 07:31:35 +0000 (+0200) Subject: g_leapsec.cpp: X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4ecfdbc1564950010de3d90f9cb676fd046409a8;p=thirdparty%2Fntp.git g_leapsec.cpp: Rename: tests/ntpd/leapsec.cpp -> tests/ntpd/g_leapsec.cpp run-leapsec.c, leapsec.c: new file Makefile.am: added /tests/ntpd/ dir unity tests removed a comment line g_ntpdtest.h: Rename: tests/ntpd/ntpdtest.h -> tests/ntpd/g_ntpdtest.h Makefile.am: added support for unity tests test-libntp.h: added new headers g_ntpdtest.cpp: minor change in the header name Rename: tests/ntpd/ntpdtest.cpp -> tests/ntpd/g_ntpdtest.cpp bk: 55939757LDuYS6xJygO9e0ZD3-1NrQ --- diff --git a/tests/Makefile.am b/tests/Makefile.am index a9f88bae8..3232bc39b 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -2,15 +2,16 @@ NULL = SUBDIRS = DIST_SUBDIRS = -if GTEST_AVAILABLE -SUBDIRS += \ - ntpd \ - $(NULL) -endif +#if GTEST_AVAILABLE +#SUBDIRS += \ +# ntpd \ +# $(NULL) +#endif SUBDIRS += \ bug-2803 \ libntp \ + ntpd \ $(NULL) DIST_SUBDIRS += \ diff --git a/tests/libntp/Makefile.am b/tests/libntp/Makefile.am index 288d38c79..8bf1312fc 100644 --- a/tests/libntp/Makefile.am +++ b/tests/libntp/Makefile.am @@ -4,7 +4,6 @@ CLEANFILES = run_unity = cd $(srcdir) && ruby ../../sntp/unity/auto/generate_test_runner.rb -#removed test-libntp check_PROGRAMS = \ test-a_md5encrypt \ test-atoint \ diff --git a/tests/libntp/test-libntp.h b/tests/libntp/test-libntp.h index eb113cd52..93050b32a 100644 --- a/tests/libntp/test-libntp.h +++ b/tests/libntp/test-libntp.h @@ -1,3 +1,8 @@ +#include "config.h" + +#include "ntp_stdlib.h" +#include "ntp_calendar.h" + time_t timefunc(time_t *ptr); void settime(int y, int m, int d, int H, int M, int S); time_t nowtime; diff --git a/tests/ntpd/Makefile.am b/tests/ntpd/Makefile.am index c5df6e4a3..863042fb2 100644 --- a/tests/ntpd/Makefile.am +++ b/tests/ntpd/Makefile.am @@ -2,10 +2,21 @@ NULL = BUILT_SOURCES = CLEANFILES = -check_PROGRAMS = tests +run_unity = cd $(srcdir) && ruby ../../sntp/unity/auto/generate_test_runner.rb + +check_PROGRAMS = \ + test-leapsec \ + $(NULL) + +if GTEST_AVAILABLE +check_PROGRAMS += tests +else +EXTRA_PROGRAMS = tests +endif LDADD = \ $(top_builddir)/libntp/libntp.a \ + $(top_builddir)/ntpd/libntpd.a \ $(LDADD_LIBNTP) \ $(PTHREAD_LIBS) \ $(LDADD_NTP) \ @@ -13,26 +24,59 @@ LDADD = \ $(GTEST_LIBS) \ $(NULL) +unity_tests_LDADD = \ + $(LDADD) \ + $(top_builddir)/sntp/unity/libunity.a \ + $(LIBM) \ + $(NULL) + AM_CFLAGS = $(CFLAGS_NTP) AM_CXXFLAGS = $(GTEST_CXXFLAGS) AM_CPPFLAGS = $(NTP_INCS) AM_CPPFLAGS += -I$(top_srcdir)/sntp AM_CPPFLAGS += -I$(top_srcdir)/ntpd +AM_CPPFLAGS += -I$(top_srcdir)/tests/libntp AM_CPPFLAGS += $(GTEST_CPPFLAGS) AM_CPPFLAGS += $(CPPFLAGS_NTP) AM_LDFLAGS = $(LDFLAGS_NTP) tests_SOURCES = $(top_srcdir)/sntp/tests_main.cpp \ - ntpdtest.cpp \ + g_ntpdtest.cpp \ $(top_srcdir)/ntpd/ntp_leapsec.c \ - leapsec.cpp \ + g_leapsec.cpp \ $(NULL) -noinst_HEADERS = ntpdtest.h \ +BUILT_SOURCES += \ + $(srcdir)/run-leapsec.c \ + $(NULL) + +noinst_HEADERS = g_ntpdtest.h \ + $(srcdir)/../libntp/test-libntp.h \ $(NULL) +### + +test_leapsec_CFLAGS = \ + -I$(top_srcdir)/sntp/unity \ + $(NULL) +#probably needs -lpthread in LDADD +test_leapsec_LDADD = \ + $(unity_tests_LDADD) \ + $(NULL) + +test_leapsec_SOURCES = \ + leapsec.c \ + run-leapsec.c \ + $(srcdir)/../libntp/test-libntp.c \ + $(NULL) + +$(srcdir)/run-leapsec.c: $(srcdir)/leapsec.c $(std_unity_list) + $(run_unity) leapsec.c run-leapsec.c + +### + TESTS = if !NTP_CROSSCOMPILE @@ -42,8 +86,8 @@ endif ## check-libntp.mf - automake fragment ## slightly adapted for deeper directory -BUILT_SOURCES += check-libntp -CLEANFILES += check-libntp +BUILT_SOURCES += check-libntp check-libunity check-libntpd +CLEANFILES += check-libntp check-libunity check-libntpd check-libntp: ../../libntp/libntp.a @echo stamp > $@ @@ -51,5 +95,17 @@ check-libntp: ../../libntp/libntp.a ../../libntp/libntp.a: cd ../../libntp && $(MAKE) $(AM_MAKEFLAGS) libntp.a +check-libntpd: ../../ntpd/libntpd.a + @echo stamp > $@ + +../../ntpd/libntpd.a: + cd ../../ntpd && $(MAKE) $(AM_MAKEFLAGS) libntpd.a + +check-libunity: ../../sntp/unity/libunity.a + @echo stamp > $@ + +../../sntp/unity/libunity.a: + cd ../../sntp/unity && $(MAKE) $(AM_MAKEFLAGS) libunity.a + include $(top_srcdir)/depsver.mf include $(top_srcdir)/includes.mf diff --git a/tests/ntpd/leapsec.cpp b/tests/ntpd/g_leapsec.cpp similarity index 100% rename from tests/ntpd/leapsec.cpp rename to tests/ntpd/g_leapsec.cpp diff --git a/tests/ntpd/ntpdtest.cpp b/tests/ntpd/g_ntpdtest.cpp similarity index 96% rename from tests/ntpd/ntpdtest.cpp rename to tests/ntpd/g_ntpdtest.cpp index 76b3b1a25..759989643 100644 --- a/tests/ntpd/ntpdtest.cpp +++ b/tests/ntpd/g_ntpdtest.cpp @@ -1,4 +1,4 @@ -#include "ntpdtest.h" +#include "g_ntpdtest.h" /* This file contains various constants that libntp needs to be set * and that is normally defined in ntpd/ntpq/... diff --git a/tests/ntpd/ntpdtest.h b/tests/ntpd/g_ntpdtest.h similarity index 100% rename from tests/ntpd/ntpdtest.h rename to tests/ntpd/g_ntpdtest.h diff --git a/tests/ntpd/leapsec.c b/tests/ntpd/leapsec.c new file mode 100644 index 000000000..a196b39be --- /dev/null +++ b/tests/ntpd/leapsec.c @@ -0,0 +1,1230 @@ +//#include "ntpdtest.h" +#include "config.h" + +//maybe ntp_stdlib and the other one? types? + +#include "ntp.h" +#include "ntp_calendar.h" +#include "ntp_stdlib.h" +#include "ntp_leapsec.h" + +#include "unity.h" + +#include +//#include + +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 const uint32_t lsec2006 = 3345062400u; // +33, 1 Jan 2006, 00:00:00 utc +static const uint32_t lsec2009 = 3439756800u; // +34, 1 Jan 2009, 00:00:00 utc +static const uint32_t lsec2012 = 3550089600u; // +35, 1 Jul 2012, 00:00:00 utc +static const uint32_t lsec2015 = 3644697600u; // +36, 1 Jul 2015, 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) +{ + 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; +} + + +char * CalendarToString(const struct calendar cal) { + char * ss = malloc (sizeof (char) * 100); + + char buffer[100] =""; + sprintf(buffer, "%u", cal.year); + strcat(ss,buffer); + strcat(ss,"-"); + sprintf(buffer, "%u", (u_int)cal.month); + strcat(ss,buffer); + strcat(ss,"-"); + sprintf(buffer, "%u", (u_int)cal.monthday); + strcat(ss,buffer); + strcat(ss," ("); + sprintf(buffer, "%u", (u_int) cal.yearday); + strcat(ss,buffer); + strcat(ss,") "); + sprintf(buffer, "%u", (u_int)cal.hour); + strcat(ss,buffer); + strcat(ss,":"); + sprintf(buffer, "%u", (u_int)cal.minute); + strcat(ss,buffer); + strcat(ss,":"); + sprintf(buffer, "%u", (u_int)cal.second); + strcat(ss,buffer); + //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; +} + + +int IsEqual(const struct calendar expected, const struct 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 TRUE; + } else { + printf("expected: %s but was %s", CalendarToString(expected) ,CalendarToString(actual)); + return FALSE; + + } +} + +//------------------------- + +void setUp() +{ + //init_lib(); + //init_auth(); +extern time_t timefunc; + ntpcal_set_timefunc(timefunc); + settime(1970, 1, 1, 0, 0, 0); + leapsec_ut_pristine(); +} + +void tearDown() +{ + ntpcal_set_timefunc(NULL); +} + +// ===================================================================== +// VALIDATION TESTS +// ===================================================================== + +// ---------------------------------------------------------------------- +void test_ValidateGood() { + const char *cp = leap_ghash; + int rc = leapsec_validate(stringreader, &cp); + TEST_ASSERT_EQUAL(LSVALID_GOODHASH, rc); +} + +// ---------------------------------------------------------------------- +void test_ValidateNoHash() { + const char *cp = leap2; + int rc = leapsec_validate(stringreader, &cp); + TEST_ASSERT_EQUAL(LSVALID_NOHASH, rc); +} + +// ---------------------------------------------------------------------- +void test_ValidateBad() { + const char *cp = leap_bhash; + int rc = leapsec_validate(stringreader, &cp); + TEST_ASSERT_EQUAL(LSVALID_BADHASH, rc); +} + +// ---------------------------------------------------------------------- +void test_ValidateMalformed() { + const char *cp = leap_mhash; + int rc = leapsec_validate(stringreader, &cp); + TEST_ASSERT_EQUAL(LSVALID_BADFORMAT, rc); +} + +// ---------------------------------------------------------------------- +void test_ValidateMalformedShort() { + const char *cp = leap_shash; + int rc = leapsec_validate(stringreader, &cp); + TEST_ASSERT_EQUAL(LSVALID_BADFORMAT, rc); +} + +// ---------------------------------------------------------------------- +void test_ValidateNoLeadZero() { + const char *cp = leap_gthash; + int rc = leapsec_validate(stringreader, &cp); + TEST_ASSERT_EQUAL(LSVALID_GOODHASH, rc); +} + +// ===================================================================== +// BASIC FUNCTIONS +// ===================================================================== + +// ---------------------------------------------------------------------- +// test table selection +void test_tableSelect() { + leap_table_t *pt1, *pt2, *pt3, *pt4; + + pt1 = leapsec_get_table(0); + pt2 = leapsec_get_table(0); + TEST_ASSERT_EQUAL(pt1, pt2); + + pt1 = leapsec_get_table(1); + pt2 = leapsec_get_table(1); + TEST_ASSERT_EQUAL(pt1, pt2); + + pt1 = leapsec_get_table(1); + pt2 = leapsec_get_table(0); + TEST_ASSERT_NOT_EQUAL(pt1, pt2); + + pt1 = leapsec_get_table(0); + pt2 = leapsec_get_table(1); + TEST_ASSERT_NOT_EQUAL(pt1, pt2); + + leapsec_set_table(pt1); + pt2 = leapsec_get_table(0); + pt3 = leapsec_get_table(1); + TEST_ASSERT_EQUAL(pt1, pt2); + TEST_ASSERT_NOT_EQUAL(pt2, pt3); + + pt1 = pt3; + leapsec_set_table(pt1); + pt2 = leapsec_get_table(0); + pt3 = leapsec_get_table(1); + TEST_ASSERT_EQUAL(pt1, pt2); + TEST_ASSERT_NOT_EQUAL(pt2, pt3); +} + +// ---------------------------------------------------------------------- +// load file & check expiration +void test_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); + TEST_ASSERT_EQUAL(1, rc); + rc = leapsec_expired(3439756800u, NULL); + TEST_ASSERT_EQUAL(0, rc); + rc = leapsec_expired(3610569601u, NULL); + TEST_ASSERT_EQUAL(1, rc); +} + +// ---------------------------------------------------------------------- +// load file & check time-to-live +void test_loadFileTTL() { + const char *cp = leap1; + int rc; + leap_table_t * pt = leapsec_get_table(0); + time_t pivot = 0x70000000u; + + const uint32_t limit = 3610569600u; + + rc = leapsec_load(pt, stringreader, &cp, FALSE) + && leapsec_set_table(pt); + TEST_ASSERT_EQUAL(1, rc); // + + // exactly 1 day to live + rc = leapsec_daystolive(limit - 86400, &pivot); + TEST_ASSERT_EQUAL( 1, rc); + // less than 1 day to live + rc = leapsec_daystolive(limit - 86399, &pivot); + TEST_ASSERT_EQUAL( 0, rc); + // hit expiration exactly + rc = leapsec_daystolive(limit, &pivot); + TEST_ASSERT_EQUAL( 0, rc); + // expired since 1 sec + rc = leapsec_daystolive(limit + 1, &pivot); + TEST_ASSERT_EQUAL(-1, rc); +} + +// ===================================================================== +// RANDOM QUERY TESTS +// ===================================================================== + +// ---------------------------------------------------------------------- +// test query in pristine state (bug#2745 misbehaviour) +void test_lsQueryPristineState() { + int rc; + leap_result_t qr; + + rc = leapsec_query(&qr, lsec2012, NULL); + TEST_ASSERT_EQUAL(FALSE, rc); + TEST_ASSERT_EQUAL(0, qr.warped ); + TEST_ASSERT_EQUAL(LSPROX_NOWARN, qr.proximity); +} + +// ---------------------------------------------------------------------- +// ad-hoc jump: leap second at 2009.01.01 -60days +void test_ls2009faraway() { + int rc; + leap_result_t qr; + + rc = setup_load_table(leap1,FALSE); + TEST_ASSERT_EQUAL(1, rc); + + // test 60 days before leap. Nothing scheduled or indicated. + rc = leapsec_query(&qr, lsec2009 - 60*SECSPERDAY, NULL); + TEST_ASSERT_EQUAL(FALSE, rc); + TEST_ASSERT_EQUAL(33, qr.tai_offs); + TEST_ASSERT_EQUAL(0, qr.tai_diff); + TEST_ASSERT_EQUAL(LSPROX_NOWARN, qr.proximity); +} + +// ---------------------------------------------------------------------- +// ad-hoc jump: leap second at 2009.01.01 -1week +void test_ls2009weekaway() { + int rc; + leap_result_t qr; + + rc = setup_load_table(leap1,FALSE); + TEST_ASSERT_EQUAL(1, rc); + + // test 7 days before leap. Leap scheduled, but not yet indicated. + rc = leapsec_query(&qr, lsec2009 - 7*SECSPERDAY, NULL); + TEST_ASSERT_EQUAL(FALSE, rc); + TEST_ASSERT_EQUAL(33, qr.tai_offs); + TEST_ASSERT_EQUAL(1, qr.tai_diff); + TEST_ASSERT_EQUAL(LSPROX_SCHEDULE, qr.proximity); +} + +// ---------------------------------------------------------------------- +// ad-hoc jump: leap second at 2009.01.01 -1hr +void test_ls2009houraway() { + int rc; + leap_result_t qr; + + rc = setup_load_table(leap1,FALSE); + TEST_ASSERT_EQUAL(1, rc); + + // test 1 hour before leap. 61 true seconds to go. + rc = leapsec_query(&qr, lsec2009 - SECSPERHR, NULL); + TEST_ASSERT_EQUAL(FALSE, rc); + TEST_ASSERT_EQUAL(33, qr.tai_offs); + TEST_ASSERT_EQUAL(1, qr.tai_diff); + TEST_ASSERT_EQUAL(LSPROX_ANNOUNCE, qr.proximity); +} + +// ---------------------------------------------------------------------- +// ad-hoc jump: leap second at 2009.01.01 -1sec +void test_ls2009secaway() { + int rc; + leap_result_t qr; + + rc = setup_load_table(leap1,FALSE); + TEST_ASSERT_EQUAL(1, rc); + + // test 1 second before leap (last boundary...) 2 true seconds to go. + rc = leapsec_query(&qr, lsec2009 - 1, NULL); + TEST_ASSERT_EQUAL(FALSE, rc); + TEST_ASSERT_EQUAL(33, qr.tai_offs); + TEST_ASSERT_EQUAL(1, qr.tai_diff); + TEST_ASSERT_EQUAL(LSPROX_ALERT, qr.proximity); +} + +// ---------------------------------------------------------------------- +// ad-hoc jump to leap second at 2009.01.01 +void test_ls2009onspot() { + int rc; + leap_result_t qr; + + rc = setup_load_table(leap1,FALSE); + TEST_ASSERT_EQUAL(1, rc); + + // test on-spot: treat leap second as already gone. + rc = leapsec_query(&qr, lsec2009, NULL); + TEST_ASSERT_EQUAL(FALSE, rc); + TEST_ASSERT_EQUAL(34, qr.tai_offs); + TEST_ASSERT_EQUAL(0, qr.tai_diff); + TEST_ASSERT_EQUAL(LSPROX_NOWARN, qr.proximity); +} + +// ---------------------------------------------------------------------- +// test handling of the leap second at 2009.01.01 without table +void test_ls2009nodata() { + int rc; + leap_result_t qr; + + rc = setup_clear_table(); + TEST_ASSERT_EQUAL(1, rc); + + // test on-spot with empty table + rc = leapsec_query(&qr, lsec2009, NULL); + TEST_ASSERT_EQUAL(FALSE, rc); + TEST_ASSERT_EQUAL(0, qr.tai_offs); + TEST_ASSERT_EQUAL(0, qr.tai_diff); + TEST_ASSERT_EQUAL(LSPROX_NOWARN, qr.proximity); +} + +// ---------------------------------------------------------------------- +// test handling of the leap second at 2009.01.01 with culled data +void test_ls2009limdata() { + int rc; + leap_result_t qr; + + rc = setup_load_table(leap1, TRUE); + TEST_ASSERT_EQUAL(1, rc); + + // test on-spot with limited table - this is tricky. + // The table used ends 2012; depending on the build date, the 2009 entry + // might be included or culled. The resulting TAI offset must be either + // 34 or 35 seconds, depending on the build date of the test. + rc = leapsec_query(&qr, lsec2009, NULL); + TEST_ASSERT_EQUAL(FALSE, rc); + TEST_ASSERT_TRUE(34 <= qr.tai_offs); + TEST_ASSERT_TRUE(35 >= qr.tai_offs); + TEST_ASSERT_EQUAL(0, qr.tai_diff); + TEST_ASSERT_EQUAL(LSPROX_NOWARN, qr.proximity); +} + +// ---------------------------------------------------------------------- +// Far-distance forward jump into a transiton window. +void test_qryJumpFarAhead() { + int rc; + leap_result_t qr; + int last, idx; + int mode; + + for (mode=0; mode < 2; ++mode) { + leapsec_ut_pristine(); + rc = setup_load_table(leap1, FALSE); + TEST_ASSERT_EQUAL(1, rc); + leapsec_electric(mode); + + rc = leapsec_query(&qr, lsec2006, NULL); + TEST_ASSERT_EQUAL(FALSE, rc); + + rc = leapsec_query(&qr, lsec2012, NULL); + TEST_ASSERT_EQUAL(FALSE, rc); + } +} + +// ---------------------------------------------------------------------- +// Forward jump into the next transition window +void test_qryJumpAheadToTransition() { + int rc; + leap_result_t qr; + int last, idx; + int mode; + + for (mode=0; mode < 2; ++mode) { + leapsec_ut_pristine(); + rc = setup_load_table(leap1, FALSE); + TEST_ASSERT_EQUAL(1, rc); + leapsec_electric(mode); + + rc = leapsec_query(&qr, lsec2009-SECSPERDAY, NULL); + TEST_ASSERT_EQUAL(FALSE, rc); + + rc = leapsec_query(&qr, lsec2009+1, NULL); + TEST_ASSERT_EQUAL(TRUE, rc); + } +} + +// ---------------------------------------------------------------------- +// Forward jump over the next transition window +void test_qryJumpAheadOverTransition() { + int rc; + leap_result_t qr; + int last, idx; + int mode; + + for (mode=0; mode < 2; ++mode) { + leapsec_ut_pristine(); + rc = setup_load_table(leap1, FALSE); + TEST_ASSERT_EQUAL(1, rc); + leapsec_electric(mode); + + rc = leapsec_query(&qr, lsec2009-SECSPERDAY, NULL); + TEST_ASSERT_EQUAL(FALSE, rc); + + rc = leapsec_query(&qr, lsec2009+5, NULL); + TEST_ASSERT_EQUAL(FALSE, rc); + } +} + +// ===================================================================== +// TABLE MODIFICATION AT RUNTIME +// ===================================================================== + +// ---------------------------------------------------------------------- +// add dynamic leap second (like from peer/clock) +void test_addDynamic() { + int rc; + leap_result_t qr; + + static const uint32_t insns[] = { + 2982009600u, // 29 # 1 Jul 1994 + 3029443200u, // 30 # 1 Jan 1996 + 3076704000u, // 31 # 1 Jul 1997 + 3124137600u, // 32 # 1 Jan 1999 + 3345062400u, // 33 # 1 Jan 2006 + 3439756800u, // 34 # 1 Jan 2009 + 3550089600u, // 35 # 1 Jul 2012 + 0 // sentinel + }; + + rc = setup_load_table(leap2, FALSE); + TEST_ASSERT_EQUAL(1, rc); + + leap_table_t * pt = leapsec_get_table(0); + int idx; + + for (idx=1; insns[idx]; ++idx) { + rc = leapsec_add_dyn(TRUE, insns[idx] - 20*SECSPERDAY - 100, NULL); + TEST_ASSERT_EQUAL(TRUE, rc); + } + // try to slip in a previous entry + rc = leapsec_add_dyn(TRUE, insns[0] - 20*SECSPERDAY - 100, NULL); + TEST_ASSERT_EQUAL(FALSE, rc); + //leapsec_dump(pt, (leapsec_dumper)fprintf, stdout); +} + +// ---------------------------------------------------------------------- +// add fixed leap seconds (like from network packet) +#if 0 /* currently unused -- possibly revived later */ +void FAILtest_addFixed() { + int rc; + leap_result_t qr; + + static const struct { uint32_t tt; int of; } insns[] = { + {2982009600u, 29},// # 1 Jul 1994 + {3029443200u, 30},// # 1 Jan 1996 + {3076704000u, 31},// # 1 Jul 1997 + {3124137600u, 32},// # 1 Jan 1999 + {3345062400u, 33},// # 1 Jan 2006 + {3439756800u, 34},// # 1 Jan 2009 + {3550089600u, 35},// # 1 Jul 2012 + {0,0} // sentinel + }; + + rc = setup_load_table(leap2, FALSE); + TEST_ASSERT_EQUAL(1, rc); + int idx; + leap_table_t * pt = leapsec_get_table(0); + // try to get in BAD time stamps... + for (idx=0; insns[idx].tt; ++idx) { + rc = leapsec_add_fix( + insns[idx].of, + insns[idx].tt - 20*SECSPERDAY - 100, + insns[idx].tt + SECSPERDAY, + NULL); + TEST_ASSERT_EQUAL(FALSE, rc); + } + // now do it right + for (idx=0; insns[idx].tt; ++idx) { + rc = leapsec_add_fix( + insns[idx].of, + insns[idx].tt, + insns[idx].tt + SECSPERDAY, + NULL); + TEST_ASSERT_EQUAL(TRUE, rc); + } + // try to slip in a previous entry + rc = leapsec_add_fix( + insns[0].of, + insns[0].tt, + insns[0].tt + SECSPERDAY, + NULL); + TEST_ASSERT_EQUAL(FALSE, rc); + //leapsec_dump(pt, (leapsec_dumper)fprintf, stdout); +} +#endif + +// ---------------------------------------------------------------------- +// add fixed leap seconds (like from network packet) +#if 0 /* currently unused -- possibly revived later */ +void FAILtest_addFixedExtend() { + int rc; + leap_result_t qr; + int last, idx; + + static const struct { uint32_t tt; int of; } insns[] = { + {2982009600u, 29},// # 1 Jul 1994 + {3029443200u, 30},// # 1 Jan 1996 + {0,0} // sentinel + }; + + rc = setup_load_table(leap2, FALSE); + TEST_ASSERT_EQUAL(1, rc); + + leap_table_t * pt = leapsec_get_table(FALSE); + for (last=idx=0; insns[idx].tt; ++idx) { + last = idx; + rc = leapsec_add_fix( + insns[idx].of, + insns[idx].tt, + insns[idx].tt + SECSPERDAY, + NULL); + TEST_ASSERT_EQUAL(TRUE, rc); + } + + // try to extend the expiration of the last entry + rc = leapsec_add_fix( + insns[last].of, + insns[last].tt, + insns[last].tt + 128*SECSPERDAY, + NULL); + TEST_ASSERT_EQUAL(TRUE, rc); + + // try to extend the expiration of the last entry with wrong offset + rc = leapsec_add_fix( + insns[last].of+1, + insns[last].tt, + insns[last].tt + 129*SECSPERDAY, + NULL); + TEST_ASSERT_EQUAL(FALSE, rc); + //leapsec_dump(pt, (leapsec_dumper)fprintf, stdout); +} +#endif + +// ---------------------------------------------------------------------- +// add fixed leap seconds (like from network packet) in an otherwise +// empty table and test queries before / between /after the tabulated +// values. +#if 0 /* currently unused -- possibly revived later */ +void FAILtest_setFixedExtend() { + int rc; + leap_result_t qr; + int last, idx; + + static const struct { uint32_t tt; int of; } insns[] = { + {2982009600u, 29},// # 1 Jul 1994 + {3029443200u, 30},// # 1 Jan 1996 + {0,0} // sentinel + }; + + leap_table_t * pt = leapsec_get_table(0); + for (last=idx=0; insns[idx].tt; ++idx) { + last = idx; + rc = leapsec_add_fix( + insns[idx].of, + insns[idx].tt, + insns[idx].tt + 128*SECSPERDAY, + NULL); + TEST_ASSERT_EQUAL(TRUE, rc); + } + + rc = leapsec_query(&qr, insns[0].tt - 86400, NULL); + TEST_ASSERT_EQUAL(28, qr.tai_offs); + + rc = leapsec_query(&qr, insns[0].tt + 86400, NULL); + TEST_ASSERT_EQUAL(29, qr.tai_offs); + + rc = leapsec_query(&qr, insns[1].tt - 86400, NULL); + TEST_ASSERT_EQUAL(29, qr.tai_offs); + + rc = leapsec_query(&qr, insns[1].tt + 86400, NULL); + TEST_ASSERT_EQUAL(30, qr.tai_offs); + + //leapsec_dump(pt, (leapsec_dumper)fprintf, stdout); +} +#endif + +// ===================================================================== +// AUTOKEY LEAP TRANSFER TESTS +// ===================================================================== + +// ---------------------------------------------------------------------- +// Check if the offset can be applied to an empty table ONCE +void test_taiEmptyTable() { + int rc; + + rc = leapsec_autokey_tai(35, lsec2015-30*86400, NULL); + TEST_ASSERT_EQUAL(TRUE, rc); + + rc = leapsec_autokey_tai(35, lsec2015-29*86400, NULL); + TEST_ASSERT_EQUAL(FALSE, rc); +} + +// ---------------------------------------------------------------------- +// Check that with fixed entries the operation fails +void test_taiTableFixed() { + int rc; + + rc = setup_load_table(leap1, FALSE); + TEST_ASSERT_EQUAL(1, rc); + + rc = leapsec_autokey_tai(35, lsec2015-30*86400, NULL); + TEST_ASSERT_EQUAL(FALSE, rc); +} + +// ---------------------------------------------------------------------- +// test adjustment with a dynamic entry already there +void test_taiTableDynamic() { + int rc; + leap_era_t era; + + rc = leapsec_add_dyn(TRUE, lsec2015-20*SECSPERDAY, NULL); + TEST_ASSERT_EQUAL(TRUE, rc); + + leapsec_query_era(&era, lsec2015-10, NULL); + TEST_ASSERT_EQUAL(0, era.taiof); + leapsec_query_era(&era, lsec2015+10, NULL); + TEST_ASSERT_EQUAL(1, era.taiof); + + rc = leapsec_autokey_tai(35, lsec2015-19*86400, NULL); + TEST_ASSERT_EQUAL(TRUE, rc); + + rc = leapsec_autokey_tai(35, lsec2015-19*86400, NULL); + TEST_ASSERT_EQUAL(FALSE, rc); + + leapsec_query_era(&era, lsec2015-10, NULL); + TEST_ASSERT_EQUAL(35, era.taiof); + leapsec_query_era(&era, lsec2015+10, NULL); + TEST_ASSERT_EQUAL(36, era.taiof); +} + +// ---------------------------------------------------------------------- +// test adjustment with a dynamic entry already there in dead zone +void test_taiTableDynamicDeadZone() { + int rc; + + rc = leapsec_add_dyn(TRUE, lsec2015-20*SECSPERDAY, NULL); + TEST_ASSERT_EQUAL(TRUE, rc); + + rc = leapsec_autokey_tai(35, lsec2015-5, NULL); + TEST_ASSERT_EQUAL(FALSE, rc); + + rc = leapsec_autokey_tai(35, lsec2015+5, NULL); + TEST_ASSERT_EQUAL(FALSE, rc); +} + + +// ===================================================================== +// SEQUENCE TESTS +// ===================================================================== + +// ---------------------------------------------------------------------- +// leap second insert at 2009.01.01, electric mode +void test_ls2009seqInsElectric() { + int rc; + leap_result_t qr; + + rc = setup_load_table(leap1,FALSE); + TEST_ASSERT_EQUAL(1, rc); + leapsec_electric(1); + TEST_ASSERT_EQUAL(1, leapsec_electric(-1)); + + rc = leapsec_query(&qr, lsec2009 - 60*SECSPERDAY, NULL); + TEST_ASSERT_EQUAL(FALSE, rc); + TEST_ASSERT_EQUAL(0, qr.warped ); + TEST_ASSERT_EQUAL(LSPROX_NOWARN, qr.proximity); + + rc = leapsec_query(&qr, lsec2009 - 7*SECSPERDAY, NULL); + TEST_ASSERT_EQUAL(FALSE, rc); + TEST_ASSERT_EQUAL(0, qr.warped ); + TEST_ASSERT_EQUAL(LSPROX_SCHEDULE, qr.proximity); + + rc = leapsec_query(&qr, lsec2009 - SECSPERHR, NULL); + TEST_ASSERT_EQUAL(FALSE, rc); + TEST_ASSERT_EQUAL(0, qr.warped ); + TEST_ASSERT_EQUAL(LSPROX_ANNOUNCE, qr.proximity); + + rc = leapsec_query(&qr, lsec2009 - 1, NULL); + TEST_ASSERT_EQUAL(FALSE, rc); + TEST_ASSERT_EQUAL(0, qr.warped ); + TEST_ASSERT_EQUAL(LSPROX_ALERT, qr.proximity); + + rc = leapsec_query(&qr, lsec2009, NULL); + TEST_ASSERT_EQUAL(TRUE, rc); + TEST_ASSERT_EQUAL(0, qr.warped ); + TEST_ASSERT_EQUAL(LSPROX_NOWARN, qr.proximity); + + // second call, same time frame: no trigger! + rc = leapsec_query(&qr, lsec2009, NULL); + TEST_ASSERT_EQUAL(FALSE, rc); + TEST_ASSERT_EQUAL(0, qr.warped ); + TEST_ASSERT_EQUAL(LSPROX_NOWARN, qr.proximity); +} + +// ---------------------------------------------------------------------- +// leap second insert at 2009.01.01, dumb mode +void test_ls2009seqInsDumb() { + int rc; + leap_result_t qr; + + rc = setup_load_table(leap1,FALSE); + TEST_ASSERT_EQUAL(1, rc); + TEST_ASSERT_EQUAL(0, leapsec_electric(-1)); + + rc = leapsec_query(&qr, lsec2009 - 60*SECSPERDAY, NULL); + TEST_ASSERT_EQUAL(FALSE, rc); + TEST_ASSERT_EQUAL(0, qr.warped ); + TEST_ASSERT_EQUAL(LSPROX_NOWARN, qr.proximity); + + rc = leapsec_query(&qr, lsec2009 - 7*SECSPERDAY, NULL); + TEST_ASSERT_EQUAL(FALSE, rc); + TEST_ASSERT_EQUAL(0, qr.warped ); + TEST_ASSERT_EQUAL(LSPROX_SCHEDULE, qr.proximity); + + rc = leapsec_query(&qr, lsec2009 - SECSPERHR, NULL); + TEST_ASSERT_EQUAL(FALSE, rc); + TEST_ASSERT_EQUAL(0, qr.warped ); + TEST_ASSERT_EQUAL(LSPROX_ANNOUNCE, qr.proximity); + + rc = leapsec_query(&qr, lsec2009 - 1, NULL); + TEST_ASSERT_EQUAL(FALSE, rc); + TEST_ASSERT_EQUAL(0, qr.warped ); + TEST_ASSERT_EQUAL(LSPROX_ALERT, qr.proximity); + + rc = leapsec_query(&qr, lsec2009, NULL); + TEST_ASSERT_EQUAL(FALSE, rc); + TEST_ASSERT_EQUAL(0, qr.warped ); + TEST_ASSERT_EQUAL(LSPROX_ALERT, qr.proximity); + + rc = leapsec_query(&qr, lsec2009+1, NULL); + TEST_ASSERT_EQUAL(TRUE, rc); + TEST_ASSERT_EQUAL(-1, qr.warped ); + TEST_ASSERT_EQUAL(LSPROX_NOWARN, qr.proximity); + + // second call, same time frame: no trigger! + rc = leapsec_query(&qr, lsec2009, NULL); + TEST_ASSERT_EQUAL(FALSE, rc); + TEST_ASSERT_EQUAL(0, qr.warped ); + TEST_ASSERT_EQUAL(LSPROX_NOWARN, qr.proximity); +} + + +// ---------------------------------------------------------------------- +// fake leap second remove at 2009.01.01, electric mode +void test_ls2009seqDelElectric() { + int rc; + leap_result_t qr; + + rc = setup_load_table(leap3,FALSE); + TEST_ASSERT_EQUAL(1, rc); + leapsec_electric(1); + TEST_ASSERT_EQUAL(1, leapsec_electric(-1)); + + rc = leapsec_query(&qr, lsec2009 - 60*SECSPERDAY, NULL); + TEST_ASSERT_EQUAL(FALSE, rc); + TEST_ASSERT_EQUAL(0, qr.warped ); + TEST_ASSERT_EQUAL(LSPROX_NOWARN, qr.proximity); + + rc = leapsec_query(&qr, lsec2009 - 7*SECSPERDAY, NULL); + TEST_ASSERT_EQUAL(FALSE, rc); + TEST_ASSERT_EQUAL(0, qr.warped ); + TEST_ASSERT_EQUAL(LSPROX_SCHEDULE, qr.proximity); + + rc = leapsec_query(&qr, lsec2009 - SECSPERHR, NULL); + TEST_ASSERT_EQUAL(FALSE, rc); + TEST_ASSERT_EQUAL(0, qr.warped ); + TEST_ASSERT_EQUAL(LSPROX_ANNOUNCE, qr.proximity); + + rc = leapsec_query(&qr, lsec2009 - 1, NULL); + TEST_ASSERT_EQUAL(FALSE, rc); + TEST_ASSERT_EQUAL(0, qr.warped ); + TEST_ASSERT_EQUAL(LSPROX_ALERT, qr.proximity); + + rc = leapsec_query(&qr, lsec2009, NULL); + TEST_ASSERT_EQUAL(TRUE, rc); + TEST_ASSERT_EQUAL(0, qr.warped ); + TEST_ASSERT_EQUAL(LSPROX_NOWARN, qr.proximity); + + // second call, same time frame: no trigger! + rc = leapsec_query(&qr, lsec2009, NULL); + TEST_ASSERT_EQUAL(FALSE, rc); + TEST_ASSERT_EQUAL(0, qr.warped ); + TEST_ASSERT_EQUAL(LSPROX_NOWARN, qr.proximity); +} + +// ---------------------------------------------------------------------- +// fake leap second remove at 2009.01.01. dumb mode +void test_ls2009seqDelDumb() { + int rc; + leap_result_t qr; + + rc = setup_load_table(leap3,FALSE); + TEST_ASSERT_EQUAL(1, rc); + TEST_ASSERT_EQUAL(0, leapsec_electric(-1)); + + rc = leapsec_query(&qr, lsec2009 - 60*SECSPERDAY, NULL); + TEST_ASSERT_EQUAL(FALSE, rc); + TEST_ASSERT_EQUAL(0, qr.warped ); + TEST_ASSERT_EQUAL(LSPROX_NOWARN, qr.proximity); + + rc = leapsec_query(&qr, lsec2009 - 7*SECSPERDAY, NULL); + TEST_ASSERT_EQUAL(FALSE, rc); + TEST_ASSERT_EQUAL(0, qr.warped ); + TEST_ASSERT_EQUAL(LSPROX_SCHEDULE, qr.proximity); + + rc = leapsec_query(&qr, lsec2009 - SECSPERHR, NULL); + TEST_ASSERT_EQUAL(FALSE, rc); + TEST_ASSERT_EQUAL(0, qr.warped ); + TEST_ASSERT_EQUAL(LSPROX_ANNOUNCE, qr.proximity); + + rc = leapsec_query(&qr, lsec2009 - 2, NULL); + TEST_ASSERT_EQUAL(FALSE, rc); + TEST_ASSERT_EQUAL(0, qr.warped ); + TEST_ASSERT_EQUAL(LSPROX_ALERT, qr.proximity); + + rc = leapsec_query(&qr, lsec2009 - 1, NULL); + TEST_ASSERT_EQUAL(TRUE, rc); + TEST_ASSERT_EQUAL(1, qr.warped ); + TEST_ASSERT_EQUAL(LSPROX_NOWARN, qr.proximity); + + // second call, same time frame: no trigger! + rc = leapsec_query(&qr, lsec2009, NULL); + TEST_ASSERT_EQUAL(FALSE, rc); + TEST_ASSERT_EQUAL(0, qr.warped ); + TEST_ASSERT_EQUAL(LSPROX_NOWARN, qr.proximity); +} + +// ---------------------------------------------------------------------- +// leap second insert at 2012.07.01, electric mode +void test_ls2012seqInsElectric() { + int rc; + leap_result_t qr; + + rc = setup_load_table(leap1,FALSE); + TEST_ASSERT_EQUAL(1, rc); + leapsec_electric(1); + TEST_ASSERT_EQUAL(1, leapsec_electric(-1)); + + rc = leapsec_query(&qr, lsec2012 - 60*SECSPERDAY, NULL); + TEST_ASSERT_EQUAL(FALSE, rc); + TEST_ASSERT_EQUAL(0, qr.warped ); + TEST_ASSERT_EQUAL(LSPROX_NOWARN, qr.proximity); + + rc = leapsec_query(&qr, lsec2012 - 7*SECSPERDAY, NULL); + TEST_ASSERT_EQUAL(FALSE, rc); + TEST_ASSERT_EQUAL(0, qr.warped ); + TEST_ASSERT_EQUAL(LSPROX_SCHEDULE, qr.proximity); + + rc = leapsec_query(&qr, lsec2012 - SECSPERHR, NULL); + TEST_ASSERT_EQUAL(FALSE, rc); + TEST_ASSERT_EQUAL(0, qr.warped ); + TEST_ASSERT_EQUAL(LSPROX_ANNOUNCE, qr.proximity); + + rc = leapsec_query(&qr, lsec2012 - 1, NULL); + TEST_ASSERT_EQUAL(FALSE, rc); + TEST_ASSERT_EQUAL(0, qr.warped ); + TEST_ASSERT_EQUAL(LSPROX_ALERT, qr.proximity); + + rc = leapsec_query(&qr, lsec2012, NULL); + TEST_ASSERT_EQUAL(TRUE, rc); + TEST_ASSERT_EQUAL(0, qr.warped ); + TEST_ASSERT_EQUAL(LSPROX_NOWARN, qr.proximity); + + // second call, same time frame: no trigger! + rc = leapsec_query(&qr, lsec2012, NULL); + TEST_ASSERT_EQUAL(FALSE, rc); + TEST_ASSERT_EQUAL(0, qr.warped ); + TEST_ASSERT_EQUAL(LSPROX_NOWARN, qr.proximity); +} + +// ---------------------------------------------------------------------- +// leap second insert at 2012.07.01, dumb mode +void test_ls2012seqInsDumb() { + int rc; + leap_result_t qr; + + rc = setup_load_table(leap1,FALSE); + TEST_ASSERT_EQUAL(1, rc); + TEST_ASSERT_EQUAL(0, leapsec_electric(-1)); + + rc = leapsec_query(&qr, lsec2012 - 60*SECSPERDAY, NULL); + TEST_ASSERT_EQUAL(FALSE, rc); + TEST_ASSERT_EQUAL(0, qr.warped ); + TEST_ASSERT_EQUAL(LSPROX_NOWARN, qr.proximity); + + rc = leapsec_query(&qr, lsec2012 - 7*SECSPERDAY, NULL); + TEST_ASSERT_EQUAL(FALSE, rc); + TEST_ASSERT_EQUAL(0, qr.warped ); + TEST_ASSERT_EQUAL(LSPROX_SCHEDULE, qr.proximity); + + rc = leapsec_query(&qr, lsec2012 - SECSPERHR, NULL); + TEST_ASSERT_EQUAL(FALSE, rc); + TEST_ASSERT_EQUAL(0, qr.warped ); + TEST_ASSERT_EQUAL(LSPROX_ANNOUNCE, qr.proximity); + + rc = leapsec_query(&qr, lsec2012 - 1, NULL); + TEST_ASSERT_EQUAL(FALSE, rc); + TEST_ASSERT_EQUAL(0, qr.warped ); + TEST_ASSERT_EQUAL(LSPROX_ALERT, qr.proximity); + + // This is just 1 sec before transition! + rc = leapsec_query(&qr, lsec2012, NULL); + TEST_ASSERT_EQUAL(FALSE, rc); + TEST_ASSERT_EQUAL(0, qr.warped ); + TEST_ASSERT_EQUAL(LSPROX_ALERT, qr.proximity); + + // NOW the insert/backwarp must happen + rc = leapsec_query(&qr, lsec2012+1, NULL); + TEST_ASSERT_EQUAL(TRUE, rc); + TEST_ASSERT_EQUAL(-1, qr.warped ); + TEST_ASSERT_EQUAL(LSPROX_NOWARN, qr.proximity); + + // second call with transition time: no trigger! + rc = leapsec_query(&qr, lsec2012, NULL); + TEST_ASSERT_EQUAL(FALSE, rc); + TEST_ASSERT_EQUAL(0, qr.warped ); + TEST_ASSERT_EQUAL(LSPROX_NOWARN, qr.proximity); +} + +// ---------------------------------------------------------------------- +// test repeated query on empty table in dumb mode +void test_lsEmptyTableDumb() { + int rc; + leap_result_t qr; + + //const + time_t pivot; + pivot = lsec2012; + // const + //time_t pivot(lsec2012); + const uint32_t t0 = lsec2012 - 10; + const uint32_t tE = lsec2012 + 10; + + TEST_ASSERT_EQUAL(0, leapsec_electric(-1)); + + uint32_t t; + for (t = t0; t != tE; ++t) { + rc = leapsec_query(&qr, t, &pivot); + TEST_ASSERT_EQUAL(FALSE, rc); + TEST_ASSERT_EQUAL(0, qr.warped ); + TEST_ASSERT_EQUAL(LSPROX_NOWARN, qr.proximity); + } +} + +// ---------------------------------------------------------------------- +// test repeated query on empty table in electric mode +void test_lsEmptyTableElectric() { + int rc; + leap_result_t qr; + + leapsec_electric(1); + TEST_ASSERT_EQUAL(1, leapsec_electric(-1)); + + //const + time_t pivot;//(lsec2012); + pivot = lsec2012; + const uint32_t t0 = lsec2012 - 10; + const uint32_t tE = lsec2012 + 10; + + time_t t; + for (t = t0; t != tE; ++t) { + rc = leapsec_query(&qr, t, &pivot); + TEST_ASSERT_EQUAL(FALSE, rc); + TEST_ASSERT_EQUAL(0, qr.warped ); + TEST_ASSERT_EQUAL(LSPROX_NOWARN, qr.proximity); + } +} diff --git a/tests/ntpd/run-leapsec.c b/tests/ntpd/run-leapsec.c new file mode 100644 index 000000000..42cf08d84 --- /dev/null +++ b/tests/ntpd/run-leapsec.c @@ -0,0 +1,116 @@ +/* AUTOGENERATED FILE. DO NOT EDIT. */ + +//=======Test Runner Used To Run Each Test Below===== +#define RUN_TEST(TestFunc, TestLineNum) \ +{ \ + Unity.CurrentTestName = #TestFunc; \ + Unity.CurrentTestLineNumber = TestLineNum; \ + Unity.NumberOfTests++; \ + if (TEST_PROTECT()) \ + { \ + setUp(); \ + TestFunc(); \ + } \ + if (TEST_PROTECT() && !TEST_IS_IGNORED) \ + { \ + tearDown(); \ + } \ + UnityConcludeTest(); \ +} + +//=======Automagically Detected Files To Include===== +#include "unity.h" +#include +#include + +//=======External Functions This Runner Calls===== +extern void setUp(void); +extern void tearDown(void); +void resetTest(void); +extern void test_ValidateGood(); +extern void test_ValidateNoHash(); +extern void test_ValidateBad(); +extern void test_ValidateMalformed(); +extern void test_ValidateMalformedShort(); +extern void test_ValidateNoLeadZero(); +extern void test_tableSelect(); +extern void test_loadFileExpire(); +extern void test_loadFileTTL(); +extern void test_lsQueryPristineState(); +extern void test_ls2009faraway(); +extern void test_ls2009weekaway(); +extern void test_ls2009houraway(); +extern void test_ls2009secaway(); +extern void test_ls2009onspot(); +extern void test_ls2009nodata(); +extern void test_ls2009limdata(); +extern void test_qryJumpFarAhead(); +extern void test_qryJumpAheadToTransition(); +extern void test_qryJumpAheadOverTransition(); +extern void test_addDynamic(); +extern void test_taiEmptyTable(); +extern void test_taiTableFixed(); +extern void test_taiTableDynamic(); +extern void test_taiTableDynamicDeadZone(); +extern void test_ls2009seqInsElectric(); +extern void test_ls2009seqInsDumb(); +extern void test_ls2009seqDelElectric(); +extern void test_ls2009seqDelDumb(); +extern void test_ls2012seqInsElectric(); +extern void test_ls2012seqInsDumb(); +extern void test_lsEmptyTableDumb(); +extern void test_lsEmptyTableElectric(); + + +//=======Test Reset Option===== +void resetTest() +{ + tearDown(); + setUp(); +} + +char *progname; + + +//=======MAIN===== +int main(int argc, char *argv[]) +{ + progname = argv[0]; + Unity.TestFile = "leapsec.c"; + UnityBegin("leapsec.c"); + RUN_TEST(test_ValidateGood, 334); + RUN_TEST(test_ValidateNoHash, 341); + RUN_TEST(test_ValidateBad, 348); + RUN_TEST(test_ValidateMalformed, 355); + RUN_TEST(test_ValidateMalformedShort, 362); + RUN_TEST(test_ValidateNoLeadZero, 369); + RUN_TEST(test_tableSelect, 381); + RUN_TEST(test_loadFileExpire, 416); + RUN_TEST(test_loadFileTTL, 432); + RUN_TEST(test_lsQueryPristineState, 464); + RUN_TEST(test_ls2009faraway, 476); + RUN_TEST(test_ls2009weekaway, 493); + RUN_TEST(test_ls2009houraway, 510); + RUN_TEST(test_ls2009secaway, 527); + RUN_TEST(test_ls2009onspot, 544); + RUN_TEST(test_ls2009nodata, 561); + RUN_TEST(test_ls2009limdata, 578); + RUN_TEST(test_qryJumpFarAhead, 599); + RUN_TEST(test_qryJumpAheadToTransition, 621); + RUN_TEST(test_qryJumpAheadOverTransition, 643); + RUN_TEST(test_addDynamic, 669); + RUN_TEST(test_taiEmptyTable, 847); + RUN_TEST(test_taiTableFixed, 859); + RUN_TEST(test_taiTableDynamic, 871); + RUN_TEST(test_taiTableDynamicDeadZone, 897); + RUN_TEST(test_ls2009seqInsElectric, 917); + RUN_TEST(test_ls2009seqInsDumb, 960); + RUN_TEST(test_ls2009seqDelElectric, 1008); + RUN_TEST(test_ls2009seqDelDumb, 1051); + RUN_TEST(test_ls2012seqInsElectric, 1093); + RUN_TEST(test_ls2012seqInsDumb, 1136); + RUN_TEST(test_lsEmptyTableDumb, 1185); + RUN_TEST(test_lsEmptyTableElectric, 1210); + + return (UnityEnd()); +}