]> git.ipfire.org Git - thirdparty/chrony.git/commitdiff
test/unit: add sources unit test
authorMiroslav Lichvar <mlichvar@redhat.com>
Mon, 15 Feb 2016 15:08:15 +0000 (16:08 +0100)
committerMiroslav Lichvar <mlichvar@redhat.com>
Tue, 16 Feb 2016 12:43:33 +0000 (13:43 +0100)
test/unit/sources.c [new file with mode: 0644]

diff --git a/test/unit/sources.c b/test/unit/sources.c
new file mode 100644 (file)
index 0000000..d748cc2
--- /dev/null
@@ -0,0 +1,137 @@
+/*
+ **********************************************************************
+ * Copyright (C) Miroslav Lichvar  2016
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ * 
+ **********************************************************************
+ */
+
+#include <sources.c>
+#include "test.h"
+
+void
+test_unit(void)
+{
+  SRC_Instance srcs[16];
+  RPT_SourceReport report;
+  IPAddr addr;
+  int i, j, k, l, samples, sel_options;
+  double offset, delay, disp;
+  struct timeval tv;
+
+  CNF_Initialise(0);
+  LCL_Initialise();
+  TST_RegisterDummyDrivers();
+  SCH_Initialise();
+  SRC_Initialise();
+  REF_Initialise();
+
+  REF_SetMode(REF_ModeIgnore);
+
+  for (i = 0; i < 1000; i++) {
+    DEBUG_LOG(0, "iteration %d", i);
+
+    for (j = 0; j < sizeof (srcs) / sizeof (srcs[0]); j++) {
+      TEST_CHECK(n_sources == j);
+
+      TST_GetRandomAddress(&addr, IPADDR_UNSPEC, -1);
+
+      sel_options = i & random() & (SRC_SELECT_NOSELECT | SRC_SELECT_PREFER |
+                                    SRC_SELECT_TRUST | SRC_SELECT_REQUIRE);
+
+      DEBUG_LOG(0, "added source %d options %d", j, sel_options);
+      srcs[j] = SRC_CreateNewInstance(UTI_IPToRefid(&addr), SRC_NTP, sel_options, &addr,
+                                         SRC_DEFAULT_MINSAMPLES, SRC_DEFAULT_MAXSAMPLES);
+      SRC_UpdateReachability(srcs[j], 1);
+
+      samples = (i + j) % 5 + 3;
+
+      offset = TST_GetRandomDouble(-1.0, 1.0);
+
+      for (k = 0; k < samples; k++) {
+        SCH_GetLastEventTime(&tv, NULL, NULL);
+        UTI_AddDoubleToTimeval(&tv, TST_GetRandomDouble(k - samples, k - samples + 1), &tv);
+
+        offset += TST_GetRandomDouble(-1.0e-2, 1.0e-2);
+        delay = TST_GetRandomDouble(1.0e-6, 1.0e-1);
+        disp = TST_GetRandomDouble(1.0e-6, 1.0e-1);
+
+        DEBUG_LOG(0, "source %d sample %d offset %f delay %f disp %f", j, k,
+                  offset, delay, disp);
+
+        SRC_AccumulateSample(srcs[j], &tv, offset, delay, disp, delay, disp,
+                             1, LEAP_Normal);
+      }
+
+      for (k = 0; k <= j; k++) {
+        int passed = 0, trusted = 0, trusted_passed = 0, required = 0, required_passed = 0;
+        double trusted_lo = DBL_MAX, trusted_hi = DBL_MIN;
+        double passed_lo = DBL_MAX, passed_hi = DBL_MIN;
+
+        SRC_SelectSource(srcs[k]);
+        DEBUG_LOG(0, "source %d status %d", k, sources[k]->status);
+
+        for (l = 0; l <= j; l++) {
+          TEST_CHECK(sources[l]->status > SRC_OK && sources[l]->status <= SRC_SELECTED);
+          if (sources[l]->sel_options & SRC_SELECT_NOSELECT) {
+            TEST_CHECK(sources[l]->status == SRC_UNSELECTABLE);
+          } else if (sources[l]->status != SRC_BAD_DISTANCE) {
+            if (sources[l]->status >= SRC_NONPREFERRED) {
+              passed++;
+              if (passed_lo > sources[l]->sel_info.lo_limit)
+                passed_lo = sources[l]->sel_info.lo_limit;
+              if (passed_hi < sources[l]->sel_info.hi_limit)
+                passed_hi = sources[l]->sel_info.hi_limit;
+            }
+            if (sources[l]->sel_options & SRC_SELECT_TRUST) {
+              trusted++;
+              if (trusted_lo > sources[l]->sel_info.lo_limit)
+                trusted_lo = sources[l]->sel_info.lo_limit;
+              if (trusted_hi < sources[l]->sel_info.hi_limit)
+                trusted_hi = sources[l]->sel_info.hi_limit;
+              if (sources[l]->status >= SRC_NONPREFERRED)
+                trusted_passed++;
+            }
+            if (sources[l]->sel_options & SRC_SELECT_REQUIRE) {
+              required++;
+              if (sources[l]->status >= SRC_NONPREFERRED)
+                required_passed++;
+            }
+            if (sources[l]->sel_options & SRC_SELECT_PREFER)
+              TEST_CHECK(sources[l]->status != SRC_NONPREFERRED);
+          }
+        }
+
+        DEBUG_LOG(0, "sources %d passed %d trusted %d/%d required %d/%d", j, passed,
+                  trusted_passed, trusted, required_passed, required);
+
+        TEST_CHECK(!trusted || !passed || (passed_lo >= trusted_lo && passed_hi <= trusted_hi));
+        TEST_CHECK(!passed || trusted != 1 || (trusted == 1 && trusted_passed == 1));
+        TEST_CHECK(!passed || !required || required_passed > 0);
+      }
+    }
+
+    for (j = 0; j < sizeof (srcs) / sizeof (srcs[0]); j++) {
+      SRC_ReportSource(j, &report, &tv);
+      SRC_DestroyInstance(srcs[j]);
+    }
+  }
+
+  REF_Finalise();
+  SRC_Finalise();
+  SCH_Finalise();
+  LCL_Finalise();
+  CNF_Finalise();
+}