summaryrefslogtreecommitdiffstats
path: root/test/unit
diff options
context:
space:
mode:
Diffstat (limited to 'test/unit')
-rw-r--r--test/unit/clientlog.c60
-rw-r--r--test/unit/leapdb.c106
-rw-r--r--test/unit/leapdb.list22
-rw-r--r--test/unit/ntp_sources.c10
4 files changed, 181 insertions, 17 deletions
diff --git a/test/unit/clientlog.c b/test/unit/clientlog.c
index e5bf1f4..96818b2 100644
--- a/test/unit/clientlog.c
+++ b/test/unit/clientlog.c
@@ -1,6 +1,6 @@
/*
**********************************************************************
- * Copyright (C) Miroslav Lichvar 2016, 2021
+ * Copyright (C) Miroslav Lichvar 2016, 2021, 2024
*
* 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
@@ -35,18 +35,18 @@ void
test_unit(void)
{
uint64_t ts64, prev_first_ts64, prev_last_ts64, max_step;
+ int i, j, k, kod, passes, kods, drops, index, shift;
uint32_t index2, prev_first, prev_size;
NTP_Timestamp_Source ts_src, ts_src2;
struct timespec ts, ts2;
- int i, j, k, index, shift;
CLG_Service s;
NTP_int64 ntp_ts;
IPAddr ip;
char conf[][100] = {
"clientloglimit 20000",
"ratelimit interval 3 burst 4 leak 3",
- "cmdratelimit interval 3 burst 4 leak 3",
- "ntsratelimit interval 6 burst 8 leak 3",
+ "ntsratelimit interval 4 burst 8 leak 3",
+ "cmdratelimit interval 6 burst 4 leak 3",
};
CNF_Initialise(0, 0);
@@ -80,19 +80,51 @@ test_unit(void)
DEBUG_LOG("records %u", ARR_GetSize(records));
TEST_CHECK(ARR_GetSize(records) == 128);
- s = CLG_NTP;
+ for (kod = 0; kod <= 2; kod += 2) {
+ for (s = CLG_NTP; s <= CLG_CMDMON; s++) {
+ for (i = passes = kods = drops = 0; i < 10000; i++) {
+ kod_rate[s] = kod;
+ ts.tv_sec += 1;
+ index = CLG_LogServiceAccess(s, &ip, &ts);
+ TEST_CHECK(index >= 0);
+ switch (CLG_LimitServiceRate(s, index)) {
+ case CLG_PASS:
+ passes += 1;
+ break;
+ case CLG_DROP:
+ drops += 1;
+ break;
+ case CLG_KOD:
+ kods += 1;
+ break;
+ default:
+ assert(0);
+ }
+ }
- for (i = j = 0; i < 10000; i++) {
- ts.tv_sec += 1;
- index = CLG_LogServiceAccess(s, &ip, &ts);
- TEST_CHECK(index >= 0);
- if (!CLG_LimitServiceRate(s, index))
- j++;
+ DEBUG_LOG("service %d requests %d passes %d kods %d drops %d",
+ (int)s, i, passes, kods, drops);
+ if (kod)
+ TEST_CHECK(kods * 2.5 < drops && kods * 3.5 > drops);
+ else
+ TEST_CHECK(kods == 0);
+
+ switch (s) {
+ case CLG_NTP:
+ TEST_CHECK(passes > 1750 && passes < 2050);
+ break;
+ case CLG_NTSKE:
+ TEST_CHECK(passes > 1300 && passes < 1600);
+ break;
+ case CLG_CMDMON:
+ TEST_CHECK(passes > 1100 && passes < 1400);
+ break;
+ default:
+ assert(0);
+ }
+ }
}
- DEBUG_LOG("requests %d responses %d", i, j);
- TEST_CHECK(j * 4 < i && j * 6 > i);
-
TEST_CHECK(!ntp_ts_map.timestamps);
UTI_ZeroNtp64(&ntp_ts);
diff --git a/test/unit/leapdb.c b/test/unit/leapdb.c
new file mode 100644
index 0000000..cb27387
--- /dev/null
+++ b/test/unit/leapdb.c
@@ -0,0 +1,106 @@
+/*
+ **********************************************************************
+ * Copyright (C) Patrick Oppenlander 2024
+ *
+ * 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 <leapdb.c>
+#include "test.h"
+
+struct test_vector {
+ time_t when;
+ int tai_offset;
+ NTP_Leap leap;
+ int fake;
+} tests[] = {
+ /* leapdb.list is a cut down version of leap-seconds.list */
+ {3439756800, 34, LEAP_InsertSecond, 0}, /* 1 Jan 2009 */
+ {3550089600, 35, LEAP_InsertSecond, 0}, /* 1 Jul 2012 */
+ {3644697600, 36, LEAP_InsertSecond, 0}, /* 1 Jul 2015 */
+ {3692217600, 37, LEAP_InsertSecond, 0}, /* 1 Jan 2017 */
+ {3786825600, 36, LEAP_DeleteSecond, 1}, /* 1 Jan 2020 fake in leapdb.list */
+};
+
+static void
+test_leap_source(NTP_Leap (*fn)(time_t when, int *tai_offset),
+ int skip_fakes)
+{
+ int i, prev_tai_offset = 34;
+
+ for (i = 0; i < sizeof tests / sizeof tests[0]; ++i) {
+ struct test_vector *t = tests + i;
+
+ NTP_Leap leap;
+ int tai_offset = -1;
+
+ /* Our unit test leapdb.list contains a fake entry removing a leap second.
+ * Skip this when testing with the right/UTC timezone using mktime(). */
+ if (skip_fakes && t->fake)
+ continue;
+
+ /* One second before leap second */
+ leap = fn(t->when - LEAP_SEC_LIST_OFFSET - 1, &tai_offset);
+ TEST_CHECK(leap == t->leap);
+ TEST_CHECK(tai_offset = prev_tai_offset);
+
+ /* Exactly on leap second */
+ leap = fn(t->when - LEAP_SEC_LIST_OFFSET, &tai_offset);
+ TEST_CHECK(leap == LEAP_Normal);
+ TEST_CHECK(tai_offset == t->tai_offset);
+
+ /* One second after leap second */
+ leap = fn(t->when - LEAP_SEC_LIST_OFFSET + 1, &tai_offset);
+ TEST_CHECK(leap == LEAP_Normal);
+ TEST_CHECK(tai_offset == t->tai_offset);
+
+ prev_tai_offset = t->tai_offset;
+ }
+}
+
+void
+test_unit(void)
+{
+ char conf[][100] = {
+ "leapsectz right/UTC",
+ "leapseclist leapdb.list"
+ };
+ int i;
+
+ CNF_Initialise(0, 0);
+ for (i = 0; i < sizeof conf / sizeof conf[0]; i++)
+ CNF_ParseLine(NULL, i + 1, conf[i]);
+ LDB_Initialise();
+
+ if (check_leap_source(get_tz_leap)) {
+ DEBUG_LOG("testing get_tz_leap");
+ test_leap_source(get_tz_leap, 1);
+ } else {
+ DEBUG_LOG("Skipping get_tz_leap test. Either the right/UTC timezone is "
+ "missing, or mktime() doesn't support leap seconds.");
+ }
+
+ DEBUG_LOG("testing get_list_leap");
+ TEST_CHECK(check_leap_source(get_list_leap));
+ test_leap_source(get_list_leap, 0);
+
+ /* This exercises the twice-per-day logic */
+ DEBUG_LOG("testing LDB_GetLeap");
+ test_leap_source(LDB_GetLeap, 1);
+
+ LDB_Finalise();
+ CNF_Finalise();
+}
diff --git a/test/unit/leapdb.list b/test/unit/leapdb.list
new file mode 100644
index 0000000..5dc2188
--- /dev/null
+++ b/test/unit/leapdb.list
@@ -0,0 +1,22 @@
+#
+# Cut down version of leap-seconds.list for unit test.
+#
+# Blank lines need to be ignored, so include a few for testing.
+# Whitespace errors on non-blank lines below are copied from the original file.
+#
+
+# Leap second data update time
+#$ 3676924800
+#
+# File update time
+#@ 3928521600
+
+3439756800 34 # 1 Jan 2009
+3550089600 35 # 1 Jul 2012
+3644697600 36 # 1 Jul 2015
+3692217600 37 # 1 Jan 2017
+3786825600 36 # 1 Jan 2020 (fake entry to test negative leap second)
+
+# FIPS 180-1 hash
+# NOTE! this value has not been recomputed for this unit test file.
+#h 16edd0f0 3666784f 37db6bdd e74ced87 59af48f1
diff --git a/test/unit/ntp_sources.c b/test/unit/ntp_sources.c
index e3d7c4d..a9bdbad 100644
--- a/test/unit/ntp_sources.c
+++ b/test/unit/ntp_sources.c
@@ -125,7 +125,7 @@ void
test_unit(void)
{
char source_line[] = "127.0.0.1 offline", conf[] = "port 0", name[64];
- int i, j, k, slot, found, pool, prev_n;
+ int i, j, k, family, slot, found, pool, prev_n;
uint32_t hash = 0, conf_id;
NTP_Remote_Address addrs[256], addr;
NTP_Local_Address local_addr;
@@ -216,7 +216,7 @@ test_unit(void)
TEST_CHECK(n_sources == 0);
- status = NSR_AddSourceByName("a b", 0, 0, 0, &source.params, &conf_id);
+ status = NSR_AddSourceByName("a b", IPADDR_UNSPEC, 0, 0, 0, &source.params, &conf_id);
TEST_CHECK(status == NSR_InvalidName);
local_addr.ip_addr.family = IPADDR_INET4;
@@ -228,11 +228,13 @@ test_unit(void)
for (i = 0; i < 500; i++) {
for (j = 0; j < 20; j++) {
snprintf(name, sizeof (name), "ntp%d.example.net", (int)(random() % 10));
+ family = random() % 2 ? IPADDR_UNSPEC : random() % 2 ? IPADDR_INET4 : IPADDR_INET6;
pool = random() % 2;
prev_n = n_sources;
DEBUG_LOG("%d/%d adding source %s pool=%d", i, j, name, pool);
- status = NSR_AddSourceByName(name, 0, pool, random() % 2 ? NTP_SERVER : NTP_PEER,
+ status = NSR_AddSourceByName(name, family, 0, pool,
+ random() % 2 ? NTP_SERVER : NTP_PEER,
&source.params, &conf_id);
TEST_CHECK(status == NSR_UnresolvedName);
@@ -242,11 +244,13 @@ test_unit(void)
for (us = unresolved_sources; us->next; us = us->next)
;
TEST_CHECK(strcmp(us->name, name) == 0);
+ TEST_CHECK(us->family == family);
if (pool) {
TEST_CHECK(us->address.ip_addr.family == IPADDR_UNSPEC && us->pool_id >= 0);
} else {
TEST_CHECK(strcmp(NSR_GetName(&us->address.ip_addr), name) == 0);
TEST_CHECK(find_slot2(&us->address, &slot) == 2);
+ TEST_CHECK(get_record(slot)->family == family);
}
if (random() % 2) {