test: add leapdb unit test

This commit is contained in:
Patrick Oppenlander 2024-02-08 14:36:29 +11:00 committed by Miroslav Lichvar
parent 53823b9f1c
commit 637b77d1bd
2 changed files with 126 additions and 0 deletions

104
test/unit/leapdb.c Normal file
View file

@ -0,0 +1,104 @@
/*
**********************************************************************
* Copyright (C) Patrick Oppenlander 2023
*
* 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 prev_tai_offset = 34;
for (int 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"
};
CNF_Initialise(0, 0);
for (int 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();
}

22
test/unit/leapdb.list Normal file
View file

@ -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