337 lines
6.6 KiB
C
337 lines
6.6 KiB
C
/*
|
|
* Copyright (c) 2019 Peter Bigot Consulting
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
/* Tests where time_t requires a 64-bit value */
|
|
|
|
#include <errno.h>
|
|
#include <ztest.h>
|
|
#include "timeutil_test.h"
|
|
|
|
static const struct timeutil_test_data tests[] = {
|
|
/* 32-bit, but algorithm subtraction underflows */
|
|
{ .ux = -2147483648,
|
|
.civil = "1901-12-13 20:45:52 Fri 347",
|
|
.tm = {
|
|
.tm_sec = 52,
|
|
.tm_min = 45,
|
|
.tm_hour = 20,
|
|
.tm_mday = 13,
|
|
.tm_mon = 11,
|
|
.tm_year = 1,
|
|
.tm_wday = 5,
|
|
.tm_yday = 346,
|
|
} },
|
|
{ .ux = (time_t)-2147483649,
|
|
.civil = "1901-12-13 20:45:51 Fri 347",
|
|
.tm = {
|
|
.tm_sec = 51,
|
|
.tm_min = 45,
|
|
.tm_hour = 20,
|
|
.tm_mday = 13,
|
|
.tm_mon = 11,
|
|
.tm_year = 1,
|
|
.tm_wday = 5,
|
|
.tm_yday = 346,
|
|
} },
|
|
{ .ux = (time_t)2147483648,
|
|
.civil = "2038-01-19 03:14:08 Tue 019",
|
|
.tm = {
|
|
.tm_sec = 8,
|
|
.tm_min = 14,
|
|
.tm_hour = 3,
|
|
.tm_mday = 19,
|
|
.tm_mon = 0,
|
|
.tm_year = 138,
|
|
.tm_wday = 2,
|
|
.tm_yday = 18,
|
|
} },
|
|
{ .ux = (time_t)64060588799,
|
|
.civil = "3999-12-31 23:59:59 Fri 365",
|
|
.tm = {
|
|
.tm_sec = 59,
|
|
.tm_min = 59,
|
|
.tm_hour = 23,
|
|
.tm_mday = 31,
|
|
.tm_mon = 11,
|
|
.tm_year = 2099,
|
|
.tm_wday = 5,
|
|
.tm_yday = 364,
|
|
} },
|
|
{ .ux = (time_t)64060588800,
|
|
.civil = "4000-01-01 00:00:00 Sat 001",
|
|
.tm = {
|
|
.tm_sec = 0,
|
|
.tm_min = 0,
|
|
.tm_hour = 0,
|
|
.tm_mday = 1,
|
|
.tm_mon = 0,
|
|
.tm_year = 2100,
|
|
.tm_wday = 6,
|
|
.tm_yday = 0,
|
|
} },
|
|
/* Normal century is a common year */
|
|
{ .ux = (time_t)-2208988801,
|
|
.civil = "1899-12-31 23:59:59 Sun 365",
|
|
.tm = {
|
|
.tm_sec = 59,
|
|
.tm_min = 59,
|
|
.tm_hour = 23,
|
|
.tm_mday = 31,
|
|
.tm_mon = 11,
|
|
.tm_year = -1,
|
|
.tm_wday = 0,
|
|
.tm_yday = 364,
|
|
} },
|
|
{ .ux = (time_t)-2208988800,
|
|
.civil = "1900-01-01 00:00:00 Mon 001",
|
|
.tm = {
|
|
.tm_sec = 0,
|
|
.tm_min = 0,
|
|
.tm_hour = 0,
|
|
.tm_mday = 1,
|
|
.tm_mon = 0,
|
|
.tm_year = 0,
|
|
.tm_wday = 1,
|
|
.tm_yday = 0,
|
|
} },
|
|
{ .ux = (time_t)-2203977600,
|
|
.civil = "1900-02-28 00:00:00 Wed 059",
|
|
.tm = {
|
|
.tm_sec = 0,
|
|
.tm_min = 0,
|
|
.tm_hour = 0,
|
|
.tm_mday = 28,
|
|
.tm_mon = 1,
|
|
.tm_year = 0,
|
|
.tm_wday = 3,
|
|
.tm_yday = 58,
|
|
} },
|
|
{ .ux = (time_t)-2203891200,
|
|
.civil = "1900-03-01 00:00:00 Thu 060",
|
|
.tm = {
|
|
.tm_sec = 0,
|
|
.tm_min = 0,
|
|
.tm_hour = 0,
|
|
.tm_mday = 1,
|
|
.tm_mon = 2,
|
|
.tm_year = 0,
|
|
.tm_wday = 4,
|
|
.tm_yday = 59,
|
|
} },
|
|
{ .ux = (time_t)-2177539200,
|
|
.civil = "1900-12-31 00:00:00 Mon 365",
|
|
.tm = {
|
|
.tm_sec = 0,
|
|
.tm_min = 0,
|
|
.tm_hour = 0,
|
|
.tm_mday = 31,
|
|
.tm_mon = 11,
|
|
.tm_year = 0,
|
|
.tm_wday = 1,
|
|
.tm_yday = 364,
|
|
} },
|
|
{ .ux = (time_t)-2177452800,
|
|
.civil = "1901-01-01 00:00:00 Tue 001",
|
|
.tm = {
|
|
.tm_sec = 0,
|
|
.tm_min = 0,
|
|
.tm_hour = 0,
|
|
.tm_mday = 1,
|
|
.tm_mon = 0,
|
|
.tm_year = 1,
|
|
.tm_wday = 2,
|
|
.tm_yday = 0,
|
|
} },
|
|
|
|
/* Extrema, check against proleptic Gregorian calendar data:
|
|
* https://www.timeanddate.com/calendar/?year=1&country=22
|
|
*/
|
|
{ .ux = (time_t)-62167305600,
|
|
.civil = "-1-12-31 00:00:00 Fri 365",
|
|
.tm = {
|
|
.tm_sec = 0,
|
|
.tm_min = 0,
|
|
.tm_hour = 0,
|
|
.tm_mday = 31,
|
|
.tm_mon = 11,
|
|
.tm_year = -1901,
|
|
.tm_wday = 5,
|
|
.tm_yday = 364,
|
|
} },
|
|
{ .ux = (time_t)-62167219200,
|
|
.civil = "0-01-01 00:00:00 Sat 001",
|
|
.tm = {
|
|
.tm_sec = 0,
|
|
.tm_min = 0,
|
|
.tm_hour = 0,
|
|
.tm_mday = 1,
|
|
.tm_mon = 0,
|
|
.tm_year = -1900,
|
|
.tm_wday = 6,
|
|
.tm_yday = 0,
|
|
} },
|
|
{ .ux = (time_t)-62135596801,
|
|
.civil = "0-12-31 23:59:59 Sun 366",
|
|
.tm = {
|
|
.tm_sec = 59,
|
|
.tm_min = 59,
|
|
.tm_hour = 23,
|
|
.tm_mday = 31,
|
|
.tm_mon = 11,
|
|
.tm_year = -1900,
|
|
.tm_wday = 0,
|
|
.tm_yday = 365,
|
|
} },
|
|
{ .ux = (time_t)-62135596800,
|
|
.civil = "1-01-01 00:00:00 Mon 001",
|
|
.tm = {
|
|
.tm_sec = 0,
|
|
.tm_min = 0,
|
|
.tm_hour = 0,
|
|
.tm_mday = 1,
|
|
.tm_mon = 0,
|
|
.tm_year = -1899,
|
|
.tm_wday = 1,
|
|
.tm_yday = 0,
|
|
} },
|
|
{ .ux = (time_t)-62135596800,
|
|
.civil = "1-01-01 00:00:00 Mon 001",
|
|
.tm = {
|
|
.tm_sec = 0,
|
|
.tm_min = 0,
|
|
.tm_hour = 0,
|
|
.tm_mday = 1,
|
|
.tm_mon = 0,
|
|
.tm_year = -1899,
|
|
.tm_wday = 1,
|
|
.tm_yday = 0,
|
|
} },
|
|
};
|
|
|
|
static void test_time32_errno_clear(void)
|
|
{
|
|
const struct timeutil_test_data *tp = &(const struct timeutil_test_data){
|
|
.ux = 0,
|
|
.civil = "1970-01-01 00:00:00 Thu 001",
|
|
.tm = {
|
|
.tm_sec = 0,
|
|
.tm_min = 0,
|
|
.tm_hour = 0,
|
|
.tm_mday = 1,
|
|
.tm_mon = 0,
|
|
.tm_year = 70,
|
|
.tm_wday = 4,
|
|
.tm_yday = 0,
|
|
},
|
|
};
|
|
|
|
errno = EINVAL;
|
|
|
|
time_t ux = timeutil_timegm(&tp->tm);
|
|
|
|
zassert_equal(ux, tp->ux,
|
|
"conversion incorrect");
|
|
zassert_equal(errno, 0,
|
|
"errno was not cleared");
|
|
}
|
|
|
|
static void test_time32_epochm1(void)
|
|
{
|
|
const struct timeutil_test_data *tp = &(const struct timeutil_test_data){
|
|
.ux = -1,
|
|
.civil = "1969-12-31 23:59:59 Wed 365",
|
|
.tm = {
|
|
.tm_sec = 59,
|
|
.tm_min = 59,
|
|
.tm_hour = 23,
|
|
.tm_mday = 31,
|
|
.tm_mon = 11,
|
|
.tm_year = 69,
|
|
.tm_wday = 3,
|
|
.tm_yday = 364,
|
|
},
|
|
};
|
|
|
|
errno = EINVAL;
|
|
|
|
time_t ux = timeutil_timegm(&tp->tm);
|
|
|
|
zassert_equal(ux, tp->ux,
|
|
"conversion incorrect");
|
|
zassert_equal(errno, 0,
|
|
"final errno state bad");
|
|
}
|
|
|
|
static void test_time32_underflow(void)
|
|
{
|
|
const int64_t unix64 = -2147483649;
|
|
const struct timeutil_test_data *tp = &(const struct timeutil_test_data){
|
|
.civil = "1901-12-13 20:45:51 Fri 347",
|
|
.tm = {
|
|
.tm_sec = 51,
|
|
.tm_min = 45,
|
|
.tm_hour = 20,
|
|
.tm_mday = 13,
|
|
.tm_mon = 11,
|
|
.tm_year = 1,
|
|
.tm_wday = 5,
|
|
.tm_yday = 346,
|
|
},
|
|
};
|
|
|
|
zassert_equal(timeutil_timegm64(&tp->tm), unix64,
|
|
"fullscale failed");
|
|
errno = 0;
|
|
|
|
time_t ux = timeutil_timegm(&tp->tm);
|
|
|
|
zassert_equal(ux, -1,
|
|
"underflow undetected");
|
|
zassert_equal(errno, ERANGE,
|
|
"final errno state bad");
|
|
}
|
|
|
|
static void test_time32_overflow(void)
|
|
{
|
|
const int64_t unix64 = 2147483648;
|
|
const struct timeutil_test_data *tp = &(const struct timeutil_test_data){
|
|
.civil = "2038-01-19 03:14:08 Tue 019",
|
|
.tm = {
|
|
.tm_sec = 8,
|
|
.tm_min = 14,
|
|
.tm_hour = 3,
|
|
.tm_mday = 19,
|
|
.tm_mon = 0,
|
|
.tm_year = 138,
|
|
.tm_wday = 2,
|
|
.tm_yday = 18,
|
|
},
|
|
};
|
|
|
|
zassert_equal(timeutil_timegm64(&tp->tm), unix64,
|
|
"fullscale failed");
|
|
errno = 0;
|
|
|
|
time_t ux = timeutil_timegm(&tp->tm);
|
|
|
|
zassert_equal(ux, -1,
|
|
"overflow undetected");
|
|
zassert_equal(errno, ERANGE,
|
|
"final errno state bad");
|
|
}
|
|
|
|
void test_s64(void)
|
|
{
|
|
if (sizeof(time_t) < 8U) {
|
|
test_time32_errno_clear();
|
|
test_time32_epochm1();
|
|
test_time32_underflow();
|
|
test_time32_overflow();
|
|
return;
|
|
}
|
|
timeutil_check(tests, sizeof(tests) / sizeof(*tests));
|
|
}
|