diff options
Diffstat (limited to 'test/unit')
-rw-r--r-- | test/unit/clientlog.c | 60 | ||||
-rw-r--r-- | test/unit/leapdb.c | 106 | ||||
-rw-r--r-- | test/unit/leapdb.list | 22 | ||||
-rw-r--r-- | test/unit/ntp_sources.c | 10 |
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) { |