]> git.ipfire.org Git - thirdparty/ntp.git/commitdiff
* [Bug 2745] ntpd -x steps clock on leap second
authorJuergen Perlinger <perlinger@ntp.org>
Fri, 8 May 2015 21:35:42 +0000 (23:35 +0200)
committerJuergen Perlinger <perlinger@ntp.org>
Fri, 8 May 2015 21:35:42 +0000 (23:35 +0200)
   Fixed an initial-value problem that caused misbehaviour in absence of any leapsecond information.

bk: 554d2c2eJdwiC4Mn2mal_ZCFPG9RUg

ChangeLog
ntpd/ntp_leapsec.c
ntpd/ntp_leapsec.h
tests/ntpd/leapsec.cpp

index 15bfe2f2bf41d1c26f9fa769849673c63d0340e6..13e05e7dc20cb28c6d80af1c19b80192401c7b5a 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -8,6 +8,8 @@
   of 'limited'.
 * [Bug 2650] fix includefile processing.
 * [Bug 2745] ntpd -x steps clock on leap second
+   Fixed an initial-value problem that caused misbehaviour in absence of
+   any leapsecond information.
    Do leap second stepping only of the step adjustment is beyond the
    proper jump distance limit and step correction is allowed at all.
 * [Bug 2776] Improve ntpq's 'help keytype'.
index eeef89f3c6481bac7e0d359df1f1be6be24af190..09185b5ccad3cce957146d55e5580956b1bd68f8 100644 (file)
@@ -107,8 +107,17 @@ leapsec_get_table(
        leap_table_t *p1, *p2;
 
        p1 = _lptr;
-       p1 = &_ltab[p1 == &_ltab[1]];
-       p2 = &_ltab[p1 == &_ltab[0]];
+       if (p1 == &_ltab[0]) {
+               p2 = &_ltab[1];
+       } else if (p1 == &_ltab[1]) {
+               p2 = &_ltab[0];
+       } else {
+               p1 = &_ltab[0];
+               p2 = &_ltab[1];
+               reset_times(p1);
+               reset_times(p2);
+               _lptr = p1;
+       }
        if (alternate) {
                memcpy(p2, p1, sizeof(leap_table_t));
                p1 = p2;
@@ -282,13 +291,21 @@ leapsec_query(
        pt    = leapsec_get_table(FALSE);
        memset(qr, 0, sizeof(leap_result_t));
 
+#if 0
+       printf("ebase=%s  dtime=%s\n", lstostr(&pt->head.ebase), lstostr(&pt->head.dtime));
+       if (ucmpv64(&pt->head.dtime, &pt->head.ebase) <= 0) {
+               /* Initial state and empty table. Fix it. */
+               reload_limits(pt, &ts64);
+               printf("\n\n PRESET INITAL CONDITION\n\n\n");
+       } else
+#endif
        if (ucmpv64(&ts64, &pt->head.ebase) < 0) {
                /* Most likely after leap frame reset. Could also be a
                 * backstep of the system clock. Anyway, get the new
                 * leap era frame.
                 */
                reload_limits(pt, &ts64);
-       } else if (ucmpv64(&ts64, &pt->head.dtime) >= 0)        {
+       } else if (ucmpv64(&ts64, &pt->head.dtime) >= 0) {
                /* Boundary crossed in forward direction. This might
                 * indicate a leap transition, so we prepare for that
                 * case.
@@ -1005,6 +1022,15 @@ static char * lstostr(
        return buf;
 }
 
+/* reset the global state for unit tests */
+void
+leapsec_ut_pristine(void)
+{
+       memset(_ltab, 0, sizeof(_ltab));
+       _lptr     = NULL;
+       _electric = 0;
+}
+
 
 
 /* -*- that's all folks! -*- */
index 75edcc4608f76c6b5a84d258ede1c1668f47f2b3..c9af1ea4564b9ae6bbaa4b70061f505e2ba65f4c 100644 (file)
@@ -215,4 +215,7 @@ extern int/*BOOL*/ leapsec_query(leap_result_t *qr, uint32_t ntpts,
  */
 extern int/*BOOL*/ leapsec_frame(leap_result_t *qr);
 
+/* reset global state for unit tests */
+extern void leapsec_ut_pristine(void);
+
 #endif /* !defined(NTP_LEAPSEC_H) */
index 47eb06956cd1c87649d4432dda190c5a8ef2539a..0115951542b638eb389f441f5817e6f6d5104082 100644 (file)
@@ -292,7 +292,7 @@ void leapsecTest::SetUp()
 {
     ntpcal_set_timefunc(timefunc);
     settime(1970, 1, 1, 0, 0, 0);
-    leapsec_electric(1);
+    leapsec_ut_pristine();
 }
 
 void leapsecTest::TearDown()
@@ -429,6 +429,18 @@ TEST_F(leapsecTest, loadFileTTL) {
        EXPECT_EQ(-1, rc);      
 }
 
+// ----------------------------------------------------------------------
+// test query in pristine state (bug#2745 misbehaviour)
+TEST_F(leapsecTest, lsQueryPristineState) {
+       int            rc;
+       leap_result_t  qr;
+       
+       rc = leapsec_query(&qr, lsec2012, NULL);
+       EXPECT_EQ(FALSE, rc);
+       EXPECT_EQ(0,             qr.warped   );
+       EXPECT_EQ(LSPROX_NOWARN, qr.proximity);
+}
+
 // ----------------------------------------------------------------------
 // ad-hoc jump: leap second at 2009.01.01 -60days
 TEST_F(leapsecTest, ls2009faraway) {
@@ -641,6 +653,7 @@ TEST_F(leapsecTest, ls2009seqInsElectric) {
        rc = setup_load_table(leap1);
        EXPECT_EQ(1, rc);
        leapsec_electric(1);
+       EXPECT_EQ(1, leapsec_electric(-1));
 
        rc = leapsec_query(&qr, lsec2009 - 60*SECSPERDAY, NULL);
        EXPECT_EQ(FALSE, rc);
@@ -682,7 +695,7 @@ TEST_F(leapsecTest, ls2009seqInsDumb) {
 
        rc = setup_load_table(leap1);
        EXPECT_EQ(1, rc);
-       leapsec_electric(0);
+       EXPECT_EQ(0, leapsec_electric(-1));
 
        rc = leapsec_query(&qr, lsec2009 - 60*SECSPERDAY, NULL);
        EXPECT_EQ(FALSE, rc);
@@ -731,6 +744,7 @@ TEST_F(leapsecTest, ls2009seqDelElectric) {
        rc = setup_load_table(leap3);
        EXPECT_EQ(1, rc);
        leapsec_electric(1);
+       EXPECT_EQ(1, leapsec_electric(-1));
 
        rc = leapsec_query(&qr, lsec2009 - 60*SECSPERDAY, NULL);
        EXPECT_EQ(FALSE, rc);
@@ -772,7 +786,7 @@ TEST_F(leapsecTest, ls2009seqDelDumb) {
 
        rc = setup_load_table(leap3);
        EXPECT_EQ(1, rc);
-       leapsec_electric(0);
+       EXPECT_EQ(0, leapsec_electric(-1));
 
        rc = leapsec_query(&qr, lsec2009 - 60*SECSPERDAY, NULL);
        EXPECT_EQ(FALSE, rc);
@@ -814,6 +828,8 @@ TEST_F(leapsecTest, ls2012seqInsElectric) {
 
        rc = setup_load_table(leap1);
        EXPECT_EQ(1, rc);
+       leapsec_electric(1);
+       EXPECT_EQ(1, leapsec_electric(-1));
 
        rc = leapsec_query(&qr, lsec2012 - 60*SECSPERDAY, NULL);
        EXPECT_EQ(FALSE, rc);
@@ -853,12 +869,9 @@ 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);
+       EXPECT_EQ(0, leapsec_electric(-1));
 
        rc = leapsec_query(&qr, lsec2012 - 60*SECSPERDAY, NULL);
        EXPECT_EQ(FALSE, rc);
@@ -909,10 +922,8 @@ TEST_F(leapsecTest, lsEmptyTableDumb) {
        const uint32_t t0   (lsec2012 - 10);
        const uint32_t tE   (lsec2012 + 10);
 
-       leapsec_electric(0);
        EXPECT_EQ(0, leapsec_electric(-1));
 
-       leapsec_clear(leapsec_get_table(FALSE));
        for (uint32_t t = t0; t != tE; ++t) {
                rc = leapsec_query(&qr, t, &pivot);
                EXPECT_EQ(FALSE, rc);
@@ -934,7 +945,6 @@ TEST_F(leapsecTest, lsEmptyTableElectric) {
        const uint32_t t0   (lsec2012 - 10);
        const uint32_t tE   (lsec2012 + 10);
 
-       leapsec_clear(leapsec_get_table(FALSE));
        for (time_t t = t0; t != tE; ++t) {
                rc = leapsec_query(&qr, t, &pivot);
                EXPECT_EQ(FALSE, rc);