pespin has uploaded this change for review. ( https://gerrit.osmocom.org/c/osmo-pcap/+/39158?usp=email )
Change subject: pcap-server: Make rotate-localtime feature configurable through VTY ......................................................................
pcap-server: Make rotate-localtime feature configurable through VTY
TODO: * Finish unit tests * Do some manual testing. * Write documentation
Change-Id: Idf17a161c17050bb62793a82e39179a093b35f73 --- M .gitignore M configure.ac M include/osmo-pcap/osmo_pcap_server.h M src/osmo_server_main.c M src/osmo_server_network.c M src/osmo_server_vty.c M tests/Makefile.am A tests/rotate_localtime/Makefile.am A tests/rotate_localtime/rotate_localtime_test.c A tests/rotate_localtime/rotate_localtime_test.err A tests/rotate_localtime/rotate_localtime_test.ok M tests/testsuite.at 12 files changed, 1,669 insertions(+), 5 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/osmo-pcap refs/changes/58/39158/1
diff --git a/.gitignore b/.gitignore index 274543c..affbe30 100644 --- a/.gitignore +++ b/.gitignore @@ -10,11 +10,11 @@ #configure aclocal.m4 autom4te.cache/ -config.log -config.status +config.* configure depcomp install-sh +ltmain.sh missing stamp-h1 compile diff --git a/configure.ac b/configure.ac index 72f1385..35892e6 100644 --- a/configure.ac +++ b/configure.ac @@ -60,6 +60,12 @@ AC_PROG_CC AC_PROG_INSTALL AC_PROG_RANLIB +LT_INIT + +dnl patching ${archive_cmds} to affect generation of file "libtool" to fix linking with clang +AS_CASE(["$LD"],[*clang*], + [AS_CASE(["${host_os}"], + [*linux*],[archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'])])
dnl check for pkg-config (explained in detail in libosmocore/configure.ac) AC_PATH_PROG(PKG_CONFIG_INSTALLED, pkg-config, no) @@ -194,4 +200,5 @@ doc/examples/Makefile doc/manuals/Makefile tests/Makefile + tests/rotate_localtime/Makefile Makefile) diff --git a/include/osmo-pcap/osmo_pcap_server.h b/include/osmo-pcap/osmo_pcap_server.h index 622daa7..0a43a69 100644 --- a/include/osmo-pcap/osmo_pcap_server.h +++ b/include/osmo-pcap/osmo_pcap_server.h @@ -48,6 +48,16 @@ #define STATE_INITIAL 0 #define STATE_DATA 1
+/*! Rate counter interval */ +enum time_interval { + TIME_INTERVAL_SEC, /*!< second */ + TIME_INTERVAL_MIN, /*!< minute */ + TIME_INTERVAL_HOUR, /*!< hour */ + TIME_INTERVAL_DAY, /*!< day */ + TIME_INTERVAL_MONTH, /*!< month */ + TIME_INTERVAL_YEAR, /*!< year */ +}; + enum { PEER_CTR_CONNECT, PEER_CTR_BYTES, @@ -134,6 +144,12 @@ bool max_size_enabled; int max_snaplen;
+ struct { + bool enabled; + enum time_interval intv; + unsigned int modulus; + } rotate_localtime; + /* statistics */ struct rate_ctr_group *ctrg; }; diff --git a/src/osmo_server_main.c b/src/osmo_server_main.c index 8924b86..a04de9b 100644 --- a/src/osmo_server_main.c +++ b/src/osmo_server_main.c @@ -253,6 +253,10 @@ pcap_server->max_size = 1073741824; /* 1024^3, 1GB **/ pcap_server->max_size_enabled = true; pcap_server->max_snaplen = DEFAULT_SNAPLEN; + /* By default rotate daily: */ + pcap_server->rotate_localtime.enabled = true; + pcap_server->rotate_localtime.intv = TIME_INTERVAL_DAY; + pcap_server->rotate_localtime.modulus = 1;
if (vty_read_config_file(config_file, NULL) < 0) { LOGP(DSERVER, LOGL_ERROR, diff --git a/src/osmo_server_network.c b/src/osmo_server_network.c index e53ce01..0d217d5 100644 --- a/src/osmo_server_network.c +++ b/src/osmo_server_network.c @@ -1,6 +1,7 @@ /* * osmo-pcap-server code * + * (C) 2024 by sysmocom - s.f.m.c. GmbH info@sysmocom.de * (C) 2011-2016 by Holger Hans Peter Freyther holger@moiji-mobile.com * (C) 2011 by On-Waves * All Rights Reserved @@ -227,11 +228,120 @@ return true; }
+/* Checks if we are in a new record period since last time we wrote to a pcap, to know (return true) whether a new pcap file needs to be opened. + * It calculates period based on intv and mod. */ +/* NOTE: Kept non-static to be able to validate it with unit tests. */ +bool check_localtime(const struct tm *last_write, const struct tm *tm, enum time_interval intv, unsigned int mod) +{ + unsigned long long last_start, current_start; + + switch (intv) { + case TIME_INTERVAL_SEC: + if (last_write->tm_sec == tm->tm_sec && + last_write->tm_min == tm->tm_min && + last_write->tm_hour == tm->tm_hour && + last_write->tm_mday == tm->tm_mday && + last_write->tm_mon == tm->tm_mon && + last_write->tm_year == tm->tm_year) + return false; + /* If minute/hour/day/month/year changed (passed through second 0), always rotate: */ + if (last_write->tm_min < tm->tm_min || + last_write->tm_hour < tm->tm_hour || + last_write->tm_mday < tm->tm_mday || + last_write->tm_mon < tm->tm_mon || + last_write->tm_year < tm->tm_year) + return true; + /* Same minute/hour/day/month/year, second changed. Check if we are still in same period: */ + last_start = last_write->tm_sec - (last_write->tm_sec % mod); + current_start = tm->tm_sec - (tm->tm_sec % mod); + if (current_start <= last_start) + return false; + return true; + case TIME_INTERVAL_MIN: + if (last_write->tm_min == tm->tm_min && + last_write->tm_hour == tm->tm_hour && + last_write->tm_mday == tm->tm_mday && + last_write->tm_mon == tm->tm_mon && + last_write->tm_year == tm->tm_year) + return false; + /* If hour/day/month/year changed (passed through minute 0), always rotate: */ + if (last_write->tm_hour < tm->tm_hour || + last_write->tm_mday < tm->tm_mday || + last_write->tm_mon < tm->tm_mon || + last_write->tm_year < tm->tm_year) + return true; + /* Same hour/day/month/year, minute changed. Check if we are still in same period: */ + last_start = last_write->tm_min - (last_write->tm_min % mod); + current_start = tm->tm_min - (tm->tm_min % mod); + if (current_start <= last_start) + return false; + return true; + case TIME_INTERVAL_HOUR: + if (last_write->tm_hour == tm->tm_hour && + last_write->tm_mday == tm->tm_mday && + last_write->tm_mon == tm->tm_mon && + last_write->tm_year == tm->tm_year) + return false; + /* If day/month/year changed (passed through hour 0), always rotate: */ + if (last_write->tm_mday < tm->tm_mday || + last_write->tm_mon < tm->tm_mon || + last_write->tm_year < tm->tm_year) + return true; + /* Same day/month/year, hour changed. Check if we are still in same period: */ + last_start = last_write->tm_hour - (last_write->tm_hour % mod); + current_start = tm->tm_hour - (tm->tm_hour % mod); + if (current_start <= last_start) + return false; + return true; + case TIME_INTERVAL_DAY: + if (last_write->tm_mday == tm->tm_mday && + last_write->tm_mon == tm->tm_mon && + last_write->tm_year == tm->tm_year) + return false; + /* If month/year changed (passed through day 1), always rotate: */ + if (last_write->tm_mon < tm->tm_mon || + last_write->tm_year < tm->tm_year) + return true; + /* Same month/year, day changed. Check if we are still in same period: */ + /* Note: tm_mday is [1, 31], hence the -1 below: */ + last_start = (last_write->tm_mday - 1) - ((last_write->tm_mday - 1) % mod); + current_start = (tm->tm_mday - 1) - ((tm->tm_mday - 1) % mod); + if (current_start <= last_start) + return false; + return true; + case TIME_INTERVAL_MONTH: + if (last_write->tm_mon == tm->tm_mon && + last_write->tm_year == tm->tm_year) + return false; + /* If year changed (passed through month 1), always rotate: */ + if (last_write->tm_year < tm->tm_year) + return true; + /* Same year, month changed. Check if we are still in same period: */ + last_start = last_write->tm_mon - (last_write->tm_mon % mod); + current_start = tm->tm_mon - (tm->tm_mon % mod); + if (current_start <= last_start) + return false; + return true; + case TIME_INTERVAL_YEAR: + /* Year changed. Check if we are still in same period: */ + last_start = last_write->tm_year - (last_write->tm_year % mod); + current_start = tm->tm_year - (tm->tm_year % mod); + if (current_start <= last_start) + return false; + return true; + default: + OSMO_ASSERT(false); + } +} + static bool check_restart_pcap_localtime(struct osmo_pcap_conn *conn, const struct tm *tm) { - if (conn->last_write.tm_mday == tm->tm_mday && - conn->last_write.tm_mon == tm->tm_mon && - conn->last_write.tm_year == tm->tm_year) + if (!pcap_server->rotate_localtime.enabled) + return false; + + if (!check_localtime(&conn->last_write, tm, + pcap_server->rotate_localtime.intv, + pcap_server->rotate_localtime.modulus)) return false; LOGP(DSERVER, LOGL_NOTICE, "Rolling over file for %s (localtime)\n", conn->name); restart_pcap(conn); diff --git a/src/osmo_server_vty.c b/src/osmo_server_vty.c index 507a477..46d5e05 100644 --- a/src/osmo_server_vty.c +++ b/src/osmo_server_vty.c @@ -41,6 +41,16 @@ 1, };
+static const struct value_string time_interval_names[] = { + { TIME_INTERVAL_SEC, "second" }, + { TIME_INTERVAL_MIN, "minute" }, + { TIME_INTERVAL_HOUR, "hour" }, + { TIME_INTERVAL_DAY, "day" }, + { TIME_INTERVAL_MONTH, "month" }, + { TIME_INTERVAL_YEAR, "year" }, + { 0, NULL } +}; + static void write_tls(struct vty *vty, struct osmo_pcap_server *pcap_server) { if (!pcap_server->tls_on) @@ -93,6 +103,15 @@ vty_out(vty, " server ip %s%s", pcap_server->addr, VTY_NEWLINE); if (pcap_server->port > 0) vty_out(vty, " server port %d%s", pcap_server->port, VTY_NEWLINE); + if (pcap_server->rotate_localtime.enabled) { + const char *name = get_value_string(time_interval_names, pcap_server->rotate_localtime.intv); + if (pcap_server->rotate_localtime.modulus == 1) + vty_out(vty, " rotate-localtime %s%s", name, VTY_NEWLINE); + else + vty_out(vty, " rotate-localtime %s mod %u%s", name, pcap_server->rotate_localtime.modulus, VTY_NEWLINE); + } else { + vty_out(vty, " no rotate-localtime%s", VTY_NEWLINE); + } if (pcap_server->max_size_enabled) vty_out(vty, " max-file-size %llu%s", (unsigned long long)pcap_server->max_size, VTY_NEWLINE); else @@ -194,6 +213,81 @@ return CMD_SUCCESS; }
+DEFUN(cfg_server_no_rotate_localtime, + cfg_server_no_rotate_localtime_cmd, + "no rotate-localtime", + NO_STR "Rotate pcap based on local time clock-wall frecuency\n") +{ + pcap_server->rotate_localtime.enabled = false; + return CMD_SUCCESS; +} + + +static int apply_rotate_localtime(struct vty *vty, enum time_interval intv, unsigned int modulus) +{ + unsigned int max_mod = 0; + switch (pcap_server->rotate_localtime.intv) { + case TIME_INTERVAL_SEC: + max_mod = 60; + break; + case TIME_INTERVAL_MIN: + max_mod = 60; + break; + case TIME_INTERVAL_HOUR: + max_mod = 24; + break; + case TIME_INTERVAL_DAY: + max_mod = 31; + break; + case TIME_INTERVAL_MONTH: + max_mod = 12; + break; + case TIME_INTERVAL_YEAR: + max_mod = 4294967295; + break; + default: + return CMD_WARNING; + } + + if (modulus > max_mod) { + vty_out(vty, "%%Modulus %u too big for interval %s, maximum value is %u%s", + modulus, get_value_string(time_interval_names, intv), max_mod, VTY_NEWLINE); + return CMD_WARNING; + } + + pcap_server->rotate_localtime.enabled = true; + pcap_server->rotate_localtime.intv = intv; + pcap_server->rotate_localtime.modulus = modulus; + return CMD_SUCCESS; +} + +DEFUN(cfg_server_rotate_localtime, + cfg_server_rotate_localtime_cmd, + "rotate-localtime (second|minute|hour|day|month|year)", + "Rotate pcap based on local time clock-wall periodicity\n" + "Rotate every Second\n" + "Rotate every Minute\n" + "Rotate every Hour\n" + "Rotate every Day\n") +{ + return apply_rotate_localtime(vty, get_string_value(time_interval_names, argv[0]), 1); +} + +DEFUN(cfg_server_rotate_localtime_mod_n, + cfg_server_rotate_localtime_mod_n_cmd, + "rotate-localtime (second|minute|hour|day|month|year) mod <1-4294967295>", + "Rotate pcap based on local time clock-wall periodicity\n" + "Rotate every Second\n" + "Rotate every Minute\n" + "Rotate every Hour\n" + "Rotate every Day\n" + "Rotate every Nth second/minute/hour/day/month/year" + "Nth second/minute/hour/day/month/year") +{ + unsigned long long modulus = strtoull(argv[1], NULL, 10); + return apply_rotate_localtime(vty, get_string_value(time_interval_names, argv[0]), modulus); +} + DEFUN(cfg_server_max_size, cfg_server_max_size_cmd, "max-file-size NR", @@ -575,6 +669,9 @@ install_element(SERVER_NODE, &cfg_server_file_permission_mask_cmd); install_element(SERVER_NODE, &cfg_server_ip_cmd); install_element(SERVER_NODE, &cfg_server_port_cmd); + install_element(SERVER_NODE, &cfg_server_no_rotate_localtime_cmd); + install_element(SERVER_NODE, &cfg_server_rotate_localtime_cmd); + install_element(SERVER_NODE, &cfg_server_rotate_localtime_mod_n_cmd); install_element(SERVER_NODE, &cfg_server_max_size_cmd); install_element(SERVER_NODE, &cfg_server_no_max_size_cmd); install_element(SERVER_NODE, &cfg_server_max_snaplen_cmd); diff --git a/tests/Makefile.am b/tests/Makefile.am index 2098927..456e162 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -1,3 +1,7 @@ +SUBDIRS = \ + rotate_localtime \ + $(NULL) + # The `:;' works around a Bash 3.2 bug when the output is not writeable. $(srcdir)/package.m4: $(top_srcdir)/configure.ac :;{ \ diff --git a/tests/rotate_localtime/Makefile.am b/tests/rotate_localtime/Makefile.am new file mode 100644 index 0000000..fca9ff8 --- /dev/null +++ b/tests/rotate_localtime/Makefile.am @@ -0,0 +1,43 @@ +AM_CPPFLAGS = \ + -I$(top_srcdir)/include \ + $(NULL) + +AM_CFLAGS = \ + -Wall \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOGB_CFLAGS) \ + $(LIBOSMOVTY_CFLAGS) \ + $(LIBOSMOCORE_CFLAGS) \ + $(PCAP_CFLAGS) \ + $(LIBGNUTLS_CFLAGS) \ + $(NULL) + +AM_LDFLAGS = -no-install + +EXTRA_DIST = \ + rotate_localtime_test.ok \ + rotate_localtime_test.err \ + $(NULL) + +check_PROGRAMS = \ + rotate_localtime_test \ + $(NULL) + +rotate_localtime_test_SOURCES = \ + rotate_localtime_test.c \ + $(NULL) + +rotate_localtime_test_LDADD = \ + $(top_builddir)/src/osmo_server_network.o \ + $(top_builddir)/src/osmo_server_stats.o \ + $(top_builddir)/src/osmo_tls.o \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOVTY_LIBS) \ + $(LIBGNUTLS_LIBS) \ + $(LIBZMQ_LIBS) \ + $(NULL) + + +.PHONY: update_exp +update_exp: + $(builddir)/rotate_localtime_test >$(srcdir)/rotate_localtime_test.ok 2>$(srcdir)/rotate_localtime_test.err diff --git a/tests/rotate_localtime/rotate_localtime_test.c b/tests/rotate_localtime/rotate_localtime_test.c new file mode 100644 index 0000000..c04d8c7 --- /dev/null +++ b/tests/rotate_localtime/rotate_localtime_test.c @@ -0,0 +1,1022 @@ +/* (C) 2024 by sysmocom - s.f.m.c. GmbH info@sysmocom.de + * + * All Rights Reserved + * + * SPDX-License-Identifier: AGPL-3.0+ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. + * + */ + +#include <stdint.h> +#include <stdio.h> +#include <unistd.h> +#include <stdbool.h> +#include <getopt.h> +#include <time.h> + +#include <osmocom/core/logging.h> +#include <osmocom/core/application.h> + +#include <osmo-pcap/osmo_pcap_server.h> + +struct osmo_pcap_server *pcap_server; + +extern bool check_localtime(const struct tm *last_write, const struct tm *tm, enum time_interval intv, unsigned int mod); + +static void init_tm(struct tm *tm, int year, int month, int day, int hour, int min, int sec) +{ + memset(tm, 0, sizeof(*tm)); + tm->tm_sec = sec; + tm->tm_min = min; + tm->tm_hour = hour; + tm->tm_mday = day; + tm->tm_mon = month; + tm->tm_year = year - 1900; +} + +static enum time_interval test_intv; +static unsigned int test_mod; + +static void _run_test(struct tm *last_write, const struct tm *now, bool exp_ret, const char *file, int line) +{ + char buf1[128], buf2[128]; + strftime(buf1, sizeof(buf1), "%Y-%m-%d_%H:%M:%S", last_write); + strftime(buf2, sizeof(buf2), "%Y-%m-%d_%H:%M:%S", now); + + bool ret = check_localtime(last_write, now, test_intv, test_mod); + fprintf(stderr, "{%s} check_localtime(last_write=%s, intv=%u, mod=%u) -> %s\n", + buf2, buf1, test_intv, test_mod, + ret ? "REOPEN" : "KEEP"); + *last_write = *now; + if (ret != exp_ret) + osmo_panic("%s:%d: ret (%d) != exp_ret (%d)", file, line, ret, exp_ret); +} +#define run_test(last_write, now, exp_ret) _run_test(last_write, now, exp_ret, __FILE__, __LINE__) + + +static void test_check_localtime_second_mod_1(void) +{ + fprintf(stderr, "%s start\n", __func__); + + struct tm now, last_write; + memset(&last_write, 0, sizeof(last_write)); + test_intv = TIME_INTERVAL_SEC; + test_mod = 1; + + init_tm(&now, 2010, 2, 3, 4, 5, 6); + + run_test(&last_write, &now, true); + run_test(&last_write, &now, false); + run_test(&last_write, &now, false); + + now.tm_sec++; + run_test(&last_write, &now, true); + now.tm_sec++; + run_test(&last_write, &now, true); + now.tm_sec = 0; + run_test(&last_write, &now, false); + + now.tm_min += 1; + run_test(&last_write, &now, true); + run_test(&last_write, &now, false); + + now.tm_min += 1; + now.tm_sec += 23; + run_test(&last_write, &now, true); + run_test(&last_write, &now, false); + + now.tm_hour += 3; + now.tm_min += 0; + run_test(&last_write, &now, true); + run_test(&last_write, &now, false); + + now.tm_year += 3; + now.tm_mon += 2; + run_test(&last_write, &now, true); + run_test(&last_write, &now, false); + + fprintf(stderr, "%s end\n", __func__); +} + +static void test_check_localtime_second_mod_40(void) +{ + fprintf(stderr, "%s start\n", __func__); + + struct tm now, last_write; + memset(&last_write, 0, sizeof(last_write)); + test_intv = TIME_INTERVAL_SEC; + test_mod = 40; + + init_tm(&now, 2010, 2, 3, 4, 5, 0); + + run_test(&last_write, &now, true); + run_test(&last_write, &now, false); + run_test(&last_write, &now, false); + + now.tm_sec = 1; + run_test(&last_write, &now, false); + now.tm_sec = 30; + run_test(&last_write, &now, false); + now.tm_sec = 39; + run_test(&last_write, &now, false); + now.tm_sec = 41; + run_test(&last_write, &now, true); + + now.tm_min += 1; + run_test(&last_write, &now, true); + run_test(&last_write, &now, false); + + now.tm_min += 1; + now.tm_sec += 23; + run_test(&last_write, &now, true); + run_test(&last_write, &now, false); + + now.tm_hour += 3; + now.tm_min += 0; + run_test(&last_write, &now, true); + run_test(&last_write, &now, false); + + now.tm_year += 3; + now.tm_mon += 2; + run_test(&last_write, &now, true); + run_test(&last_write, &now, false); + + fprintf(stderr, "%s end\n", __func__); +} + +static void test_check_localtime_minute_mod_1(void) +{ + fprintf(stderr, "%s start\n", __func__); + + struct tm now, last_write; + memset(&last_write, 0, sizeof(last_write)); + test_intv = TIME_INTERVAL_MIN; + test_mod = 1; + + init_tm(&now, 2010, 2, 3, 4, 5, 6); + + run_test(&last_write, &now, true); + run_test(&last_write, &now, false); + run_test(&last_write, &now, false); + + now.tm_sec++; + run_test(&last_write, &now, false); + now.tm_sec++; + run_test(&last_write, &now, false); + now.tm_sec = 0; + run_test(&last_write, &now, false); + + now.tm_min++; + run_test(&last_write, &now, true); + now.tm_min++; + run_test(&last_write, &now, true); + now.tm_sec += 40; + run_test(&last_write, &now, false); + + now.tm_min += 2; + now.tm_sec = 20; + run_test(&last_write, &now, true); + + now.tm_min++; + now.tm_sec = 0; + run_test(&last_write, &now, true); + run_test(&last_write, &now, false); + + now.tm_hour++; + run_test(&last_write, &now, true); + run_test(&last_write, &now, false); + + now.tm_min += 48; + now.tm_sec += 3; + run_test(&last_write, &now, true); + + now.tm_min = 59; + run_test(&last_write, &now, true); + now.tm_hour++; + now.tm_min = 0; + run_test(&last_write, &now, true); + + now.tm_mday++; + run_test(&last_write, &now, true); + now.tm_mday += 20; + run_test(&last_write, &now, true); + now.tm_mon += 6; + run_test(&last_write, &now, true); + now.tm_year += 6; + run_test(&last_write, &now, true); + now.tm_sec += 6; + run_test(&last_write, &now, false); + now.tm_min++; + run_test(&last_write, &now, true); + + fprintf(stderr, "%s end\n", __func__); +} + +static void test_check_localtime_minute_mod_2(void) +{ + fprintf(stderr, "%s start\n", __func__); + + struct tm now, last_write; + memset(&last_write, 0, sizeof(last_write)); + test_intv = TIME_INTERVAL_MIN; + test_mod = 2; + + init_tm(&now, 2013, 2, 3, 4, 4, 6); + + run_test(&last_write, &now, true); + run_test(&last_write, &now, false); + run_test(&last_write, &now, false); + + now.tm_sec++; + run_test(&last_write, &now, false); + now.tm_sec++; + run_test(&last_write, &now, false); + now.tm_sec = 0; + run_test(&last_write, &now, false); + + now.tm_min++; + run_test(&last_write, &now, false); + now.tm_min++; + run_test(&last_write, &now, true); + now.tm_sec += 40; + run_test(&last_write, &now, false); + + now.tm_min += 2; + now.tm_sec = 20; + run_test(&last_write, &now, true); + + now.tm_min++; + now.tm_sec = 0; + run_test(&last_write, &now, false); + run_test(&last_write, &now, false); + + now.tm_hour++; + run_test(&last_write, &now, true); + run_test(&last_write, &now, false); + + now.tm_min += 48; + now.tm_sec += 3; + run_test(&last_write, &now, true); + + now.tm_min = 59; + run_test(&last_write, &now, true); + now.tm_hour++; + now.tm_min = 0; + run_test(&last_write, &now, true); + + now.tm_mday++; + run_test(&last_write, &now, true); + now.tm_mday += 20; + run_test(&last_write, &now, true); + now.tm_mon += 6; + run_test(&last_write, &now, true); + now.tm_year += 6; + run_test(&last_write, &now, true); + now.tm_sec += 6; + run_test(&last_write, &now, false); + now.tm_min++; + run_test(&last_write, &now, false); + now.tm_min++; + run_test(&last_write, &now, true); + now.tm_min++; + run_test(&last_write, &now, false); + now.tm_min++; + run_test(&last_write, &now, true); + now.tm_min += 2; + run_test(&last_write, &now, true); + + fprintf(stderr, "%s end\n", __func__); +} + +static void test_check_localtime_minute_mod_15(void) +{ + fprintf(stderr, "%s start\n", __func__); + + struct tm now, last_write; + memset(&last_write, 0, sizeof(last_write)); + test_intv = TIME_INTERVAL_MIN; + test_mod = 15; + + init_tm(&now, 2025, 2, 3, 4, 2, 6); + + run_test(&last_write, &now, true); + run_test(&last_write, &now, false); + run_test(&last_write, &now, false); + + now.tm_sec++; + run_test(&last_write, &now, false); + now.tm_sec++; + run_test(&last_write, &now, false); + now.tm_sec = 0; + run_test(&last_write, &now, false); + + now.tm_min = 8; + run_test(&last_write, &now, false); + now.tm_min = 10; + run_test(&last_write, &now, false); + now.tm_min = 13; + run_test(&last_write, &now, false); + now.tm_min = 15; + run_test(&last_write, &now, true); + now.tm_min = 18; + run_test(&last_write, &now, false); + now.tm_min = 29; + run_test(&last_write, &now, false); + now.tm_min = 30; + run_test(&last_write, &now, true); + now.tm_min = 45; + run_test(&last_write, &now, true); + now.tm_sec += 40; + run_test(&last_write, &now, false); + now.tm_hour += 1; + now.tm_min = 0; + run_test(&last_write, &now, true); + run_test(&last_write, &now, false); + now.tm_hour += 1; + now.tm_min += 45; + run_test(&last_write, &now, true); + run_test(&last_write, &now, false); + now.tm_min += 45; + run_test(&last_write, &now, true); + now.tm_min += 12; + run_test(&last_write, &now, false); + + now.tm_min++; + now.tm_sec = 0; + run_test(&last_write, &now, false); + run_test(&last_write, &now, false); + + now.tm_min += 48; + now.tm_sec += 3; + run_test(&last_write, &now, true); + run_test(&last_write, &now, false); + + now.tm_mday++; + run_test(&last_write, &now, true); + now.tm_mday += 20; + run_test(&last_write, &now, true); + now.tm_mon += 6; + run_test(&last_write, &now, true); + now.tm_year += 6; + run_test(&last_write, &now, true); + now.tm_sec += 6; + run_test(&last_write, &now, false); + now.tm_min = 2; + run_test(&last_write, &now, false); + + fprintf(stderr, "%s end\n", __func__); +} + +static void test_check_localtime_hour_mod_1(void) +{ + fprintf(stderr, "%s start\n", __func__); + + struct tm now, last_write; + memset(&last_write, 0, sizeof(last_write)); + test_intv = TIME_INTERVAL_HOUR; + test_mod = 1; + + init_tm(&now, 2010, 2, 3, 4, 5, 6); + + run_test(&last_write, &now, true); + run_test(&last_write, &now, false); + run_test(&last_write, &now, false); + + now.tm_sec++; + run_test(&last_write, &now, false); + now.tm_sec++; + run_test(&last_write, &now, false); + now.tm_sec = 0; + run_test(&last_write, &now, false); + now.tm_min++; + run_test(&last_write, &now, false); + now.tm_min++; + run_test(&last_write, &now, false); + now.tm_min = 0; + run_test(&last_write, &now, false); + + now.tm_hour++; + run_test(&last_write, &now, true); + now.tm_hour++; + run_test(&last_write, &now, true); + now.tm_min += 40; + run_test(&last_write, &now, false); + + now.tm_hour += 2; + now.tm_sec = 20; + run_test(&last_write, &now, true); + + now.tm_hour++; + now.tm_min = 0; + now.tm_sec = 0; + run_test(&last_write, &now, true); + run_test(&last_write, &now, false); + + now.tm_hour++; + run_test(&last_write, &now, true); + run_test(&last_write, &now, false); + + now.tm_hour += 22; + now.tm_min += 3; + run_test(&last_write, &now, true); + + now.tm_hour = 59; + now.tm_min = 59; + run_test(&last_write, &now, true); + now.tm_mday++; + now.tm_hour = 0; + run_test(&last_write, &now, true); + + now.tm_mday++; + run_test(&last_write, &now, true); + now.tm_mday += 20; + run_test(&last_write, &now, true); + now.tm_mon += 6; + run_test(&last_write, &now, true); + now.tm_year += 6; + run_test(&last_write, &now, true); + now.tm_sec += 6; + run_test(&last_write, &now, false); + now.tm_hour++; + run_test(&last_write, &now, true); + + fprintf(stderr, "%s end\n", __func__); +} + +static void test_check_localtime_hour_mod_12(void) +{ + fprintf(stderr, "%s start\n", __func__); + + struct tm now, last_write; + memset(&last_write, 0, sizeof(last_write)); + test_intv = TIME_INTERVAL_HOUR; + test_mod = 12; + + init_tm(&now, 2025, 2, 3, 4, 2, 6); + + run_test(&last_write, &now, true); + run_test(&last_write, &now, false); + run_test(&last_write, &now, false); + + now.tm_min++; + run_test(&last_write, &now, false); + now.tm_min++; + now.tm_sec++; + run_test(&last_write, &now, false); + now.tm_min = 0; + run_test(&last_write, &now, false); + + now.tm_hour = 8; + run_test(&last_write, &now, false); + now.tm_hour = 10; + run_test(&last_write, &now, false); + now.tm_hour = 13; + run_test(&last_write, &now, true); + now.tm_hour = 15; + run_test(&last_write, &now, false); + now.tm_hour = 18; + run_test(&last_write, &now, false); + now.tm_hour = 23; + run_test(&last_write, &now, false); + now.tm_sec += 40; + run_test(&last_write, &now, false); + now.tm_mday += 1; + now.tm_hour = 0; + run_test(&last_write, &now, true); + run_test(&last_write, &now, false); + now.tm_mday += 1; + now.tm_hour += 15; + run_test(&last_write, &now, true); + run_test(&last_write, &now, false); + + now.tm_min++; + now.tm_sec = 0; + run_test(&last_write, &now, false); + run_test(&last_write, &now, false); + + now.tm_min += 48; + now.tm_sec += 3; + run_test(&last_write, &now, false); + run_test(&last_write, &now, false); + + now.tm_mday++; + run_test(&last_write, &now, true); + now.tm_mday += 20; + run_test(&last_write, &now, true); + now.tm_mon += 6; + run_test(&last_write, &now, true); + now.tm_year += 6; + run_test(&last_write, &now, true); + now.tm_sec += 6; + run_test(&last_write, &now, false); + now.tm_min = 2; + run_test(&last_write, &now, false); + + fprintf(stderr, "%s end\n", __func__); +} + +static void test_check_localtime_day_mod_1(void) +{ + fprintf(stderr, "%s start\n", __func__); + + struct tm now, last_write; + memset(&last_write, 0, sizeof(last_write)); + test_intv = TIME_INTERVAL_DAY; + test_mod = 1; + + init_tm(&now, 2010, 2, 3, 4, 5, 6); + + run_test(&last_write, &now, true); + run_test(&last_write, &now, false); + run_test(&last_write, &now, false); + + now.tm_sec++; + run_test(&last_write, &now, false); + now.tm_sec++; + run_test(&last_write, &now, false); + now.tm_sec = 0; + run_test(&last_write, &now, false); + now.tm_min++; + run_test(&last_write, &now, false); + now.tm_min++; + run_test(&last_write, &now, false); + now.tm_min = 0; + run_test(&last_write, &now, false); + now.tm_hour++; + run_test(&last_write, &now, false); + now.tm_hour++; + run_test(&last_write, &now, false); + now.tm_hour = 0; + run_test(&last_write, &now, false); + + now.tm_mday++; + run_test(&last_write, &now, true); + now.tm_mday++; + run_test(&last_write, &now, true); + now.tm_hour += 3; + run_test(&last_write, &now, false); + + now.tm_mday += 2; + now.tm_sec = 20; + run_test(&last_write, &now, true); + + now.tm_mday++; + now.tm_min = 0; + now.tm_sec = 0; + run_test(&last_write, &now, true); + run_test(&last_write, &now, false); + + now.tm_mday++; + run_test(&last_write, &now, true); + run_test(&last_write, &now, false); + + now.tm_mday += 3; + now.tm_min += 3; + run_test(&last_write, &now, true); + + now.tm_hour = 59; + now.tm_min = 59; + run_test(&last_write, &now, false); + now.tm_mday++; + now.tm_hour = 0; + run_test(&last_write, &now, true); + + now.tm_mon += 6; + run_test(&last_write, &now, true); + now.tm_year += 6; + run_test(&last_write, &now, true); + now.tm_sec += 6; + run_test(&last_write, &now, false); + now.tm_mday++; + run_test(&last_write, &now, true); + + fprintf(stderr, "%s end\n", __func__); +} + +static void test_check_localtime_day_mod_10(void) +{ + fprintf(stderr, "%s start\n", __func__); + + struct tm now, last_write; + memset(&last_write, 0, sizeof(last_write)); + test_intv = TIME_INTERVAL_DAY; + test_mod = 10; + + init_tm(&now, 2025, 2, 3, 4, 2, 6); + + run_test(&last_write, &now, true); + run_test(&last_write, &now, false); + run_test(&last_write, &now, false); + + now.tm_hour++; + run_test(&last_write, &now, false); + now.tm_hour++; + now.tm_min++; + now.tm_sec++; + run_test(&last_write, &now, false); + now.tm_hour = 0; + run_test(&last_write, &now, false); + + now.tm_mday = 6; + run_test(&last_write, &now, false); + now.tm_mday = 10; + run_test(&last_write, &now, false); + now.tm_mday = 11; + run_test(&last_write, &now, true); + now.tm_mday = 15; + run_test(&last_write, &now, false); + now.tm_mday = 18; + run_test(&last_write, &now, false); + now.tm_mday = 23; + run_test(&last_write, &now, true); + now.tm_sec += 40; + run_test(&last_write, &now, false); + now.tm_mday += 1; + now.tm_hour = 0; + run_test(&last_write, &now, false); + run_test(&last_write, &now, false); + now.tm_mon += 1; + now.tm_mday += 1; + run_test(&last_write, &now, true); + run_test(&last_write, &now, false); + + now.tm_hour++; + now.tm_min = 0; + now.tm_sec = 0; + run_test(&last_write, &now, false); + run_test(&last_write, &now, false); + + now.tm_hour += 12; + now.tm_min += 48; + now.tm_sec += 3; + run_test(&last_write, &now, false); + run_test(&last_write, &now, false); + + now.tm_mon++; + run_test(&last_write, &now, true); + now.tm_mon += 2; + run_test(&last_write, &now, true); + now.tm_year += 4; + run_test(&last_write, &now, true); + now.tm_year += 6; + run_test(&last_write, &now, true); + now.tm_sec += 6; + run_test(&last_write, &now, false); + now.tm_min = 2; + run_test(&last_write, &now, false); + + fprintf(stderr, "%s end\n", __func__); +} + +static void test_check_localtime_month_mod_1(void) +{ + fprintf(stderr, "%s start\n", __func__); + + struct tm now, last_write; + memset(&last_write, 0, sizeof(last_write)); + test_intv = TIME_INTERVAL_MONTH; + test_mod = 1; + + init_tm(&now, 2010, 2, 3, 4, 5, 6); + + run_test(&last_write, &now, true); + run_test(&last_write, &now, false); + run_test(&last_write, &now, false); + + now.tm_sec++; + run_test(&last_write, &now, false); + now.tm_sec++; + run_test(&last_write, &now, false); + now.tm_sec = 0; + run_test(&last_write, &now, false); + now.tm_min++; + run_test(&last_write, &now, false); + now.tm_min++; + run_test(&last_write, &now, false); + now.tm_min = 0; + run_test(&last_write, &now, false); + now.tm_hour++; + run_test(&last_write, &now, false); + now.tm_hour++; + run_test(&last_write, &now, false); + now.tm_hour = 0; + run_test(&last_write, &now, false); + now.tm_mday++; + run_test(&last_write, &now, false); + now.tm_mday++; + run_test(&last_write, &now, false); + now.tm_mday = 0; + run_test(&last_write, &now, false); + + now.tm_mon++; + run_test(&last_write, &now, true); + now.tm_mon++; + run_test(&last_write, &now, true); + now.tm_mday += 3; + run_test(&last_write, &now, false); + + now.tm_mon += 2; + now.tm_sec = 20; + run_test(&last_write, &now, true); + + now.tm_mon++; + now.tm_mday = 0; + now.tm_hour = 0; + now.tm_min = 0; + now.tm_sec = 0; + run_test(&last_write, &now, true); + run_test(&last_write, &now, false); + + now.tm_mon++; + run_test(&last_write, &now, true); + run_test(&last_write, &now, false); + + now.tm_mon += 3; + now.tm_mday += 3; + now.tm_min += 3; + run_test(&last_write, &now, true); + + now.tm_mday = 27; + now.tm_hour = 59; + now.tm_min = 59; + run_test(&last_write, &now, false); + now.tm_mon++; + now.tm_hour = 0; + run_test(&last_write, &now, true); + + now.tm_year += 6; + run_test(&last_write, &now, true); + now.tm_sec += 6; + run_test(&last_write, &now, false); + now.tm_mon++; + run_test(&last_write, &now, true); + + fprintf(stderr, "%s end\n", __func__); +} + +static void test_check_localtime_month_mod_3(void) +{ + fprintf(stderr, "%s start\n", __func__); + + struct tm now, last_write; + memset(&last_write, 0, sizeof(last_write)); + test_intv = TIME_INTERVAL_MONTH; + test_mod = 3; + + init_tm(&now, 2025, 1, 3, 4, 2, 6); + + run_test(&last_write, &now, true); + run_test(&last_write, &now, false); + run_test(&last_write, &now, false); + + now.tm_mday++; + run_test(&last_write, &now, false); + now.tm_mday++; + now.tm_min++; + now.tm_sec++; + run_test(&last_write, &now, false); + now.tm_hour = 0; + run_test(&last_write, &now, false); + + now.tm_mon = 3; + run_test(&last_write, &now, true); + now.tm_mon = 4; + run_test(&last_write, &now, false); + now.tm_mon = 6; + run_test(&last_write, &now, true); + now.tm_mon = 8; + run_test(&last_write, &now, false); + now.tm_mon = 9; + run_test(&last_write, &now, true); + run_test(&last_write, &now, false); + now.tm_sec += 40; + run_test(&last_write, &now, false); + now.tm_mday += 1; + now.tm_hour = 0; + run_test(&last_write, &now, false); + run_test(&last_write, &now, false); + now.tm_mon += 3; + now.tm_mday += 1; + run_test(&last_write, &now, true); + run_test(&last_write, &now, false); + + now.tm_hour++; + now.tm_min = 0; + now.tm_sec = 0; + run_test(&last_write, &now, false); + run_test(&last_write, &now, false); + + now.tm_hour += 12; + now.tm_min += 48; + now.tm_sec += 3; + run_test(&last_write, &now, false); + run_test(&last_write, &now, false); + + now.tm_year += 4; + run_test(&last_write, &now, true); + now.tm_year += 6; + run_test(&last_write, &now, true); + now.tm_sec += 6; + run_test(&last_write, &now, false); + now.tm_min = 2; + run_test(&last_write, &now, false); + + fprintf(stderr, "%s end\n", __func__); +} + +static void test_check_localtime_year_mod_1(void) +{ + fprintf(stderr, "%s start\n", __func__); + + struct tm now, last_write; + memset(&last_write, 0, sizeof(last_write)); + test_intv = TIME_INTERVAL_YEAR; + test_mod = 1; + + init_tm(&now, 2010, 2, 3, 4, 5, 6); + + run_test(&last_write, &now, true); + run_test(&last_write, &now, false); + run_test(&last_write, &now, false); + + now.tm_sec++; + run_test(&last_write, &now, false); + now.tm_sec++; + run_test(&last_write, &now, false); + now.tm_sec = 0; + run_test(&last_write, &now, false); + now.tm_min++; + run_test(&last_write, &now, false); + now.tm_min++; + run_test(&last_write, &now, false); + now.tm_min = 0; + run_test(&last_write, &now, false); + now.tm_hour++; + run_test(&last_write, &now, false); + now.tm_hour++; + run_test(&last_write, &now, false); + now.tm_hour = 0; + run_test(&last_write, &now, false); + now.tm_mday++; + run_test(&last_write, &now, false); + now.tm_mday++; + run_test(&last_write, &now, false); + now.tm_mday = 0; + run_test(&last_write, &now, false); + now.tm_mon++; + run_test(&last_write, &now, false); + now.tm_mon++; + run_test(&last_write, &now, false); + now.tm_mon = 0; + run_test(&last_write, &now, false); + + now.tm_year++; + run_test(&last_write, &now, true); + now.tm_year++; + run_test(&last_write, &now, true); + now.tm_mon += 3; + run_test(&last_write, &now, false); + + now.tm_year += 2; + now.tm_sec = 20; + run_test(&last_write, &now, true); + + now.tm_year++; + now.tm_mday = 0; + now.tm_hour = 0; + now.tm_min = 0; + now.tm_sec = 0; + run_test(&last_write, &now, true); + run_test(&last_write, &now, false); + + now.tm_year++; + run_test(&last_write, &now, true); + run_test(&last_write, &now, false); + + now.tm_year += 3; + now.tm_mday += 3; + now.tm_min += 3; + run_test(&last_write, &now, true); + + now.tm_mon = 3; + now.tm_mday = 27; + now.tm_hour = 59; + now.tm_min = 59; + run_test(&last_write, &now, false); + now.tm_year++; + now.tm_hour = 0; + run_test(&last_write, &now, true); + + now.tm_year += 6; + run_test(&last_write, &now, true); + now.tm_sec += 6; + run_test(&last_write, &now, false); + now.tm_year++; + run_test(&last_write, &now, true); + + fprintf(stderr, "%s end\n", __func__); +} + +static void test_check_localtime_year_mod_2(void) +{ + fprintf(stderr, "%s start\n", __func__); + + struct tm now, last_write; + memset(&last_write, 0, sizeof(last_write)); + test_intv = TIME_INTERVAL_YEAR; + test_mod = 2; + + init_tm(&now, 2025, 1, 3, 4, 2, 6); + + run_test(&last_write, &now, true); + run_test(&last_write, &now, false); + run_test(&last_write, &now, false); + + now.tm_mday++; + run_test(&last_write, &now, false); + now.tm_mon++; + now.tm_mday++; + now.tm_min++; + now.tm_sec++; + run_test(&last_write, &now, false); + now.tm_hour = 0; + run_test(&last_write, &now, false); + + now.tm_year = 2026; + run_test(&last_write, &now, true); + now.tm_year = 2027; + run_test(&last_write, &now, false); + now.tm_year = 2028; + run_test(&last_write, &now, true); + now.tm_year = 2029; + run_test(&last_write, &now, false); + run_test(&last_write, &now, false); + now.tm_year = 9; + run_test(&last_write, &now, false); + run_test(&last_write, &now, false); + now.tm_sec += 40; + run_test(&last_write, &now, false); + now.tm_mday += 1; + now.tm_hour = 0; + run_test(&last_write, &now, false); + run_test(&last_write, &now, false); + now.tm_year += 3; + now.tm_mday += 1; + run_test(&last_write, &now, true); + run_test(&last_write, &now, false); + + now.tm_hour++; + now.tm_min = 0; + now.tm_sec = 0; + run_test(&last_write, &now, false); + run_test(&last_write, &now, false); + + now.tm_hour += 12; + now.tm_min += 48; + now.tm_sec += 3; + run_test(&last_write, &now, false); + run_test(&last_write, &now, false); + + now.tm_year += 4; + run_test(&last_write, &now, true); + now.tm_year += 6; + run_test(&last_write, &now, true); + now.tm_sec += 6; + run_test(&last_write, &now, false); + now.tm_min = 2; + run_test(&last_write, &now, false); + + fprintf(stderr, "%s end\n", __func__); +} + +int main(int argc, char **argv) +{ + /* actual tests */ + test_check_localtime_second_mod_1(); + test_check_localtime_second_mod_40(); + test_check_localtime_minute_mod_1(); + test_check_localtime_minute_mod_2(); + test_check_localtime_minute_mod_15(); + test_check_localtime_hour_mod_1(); + test_check_localtime_hour_mod_12(); + test_check_localtime_day_mod_1(); + test_check_localtime_day_mod_10(); + test_check_localtime_month_mod_1(); + test_check_localtime_month_mod_3(); + test_check_localtime_year_mod_1(); + test_check_localtime_year_mod_2(); + return 0; +} + diff --git a/tests/rotate_localtime/rotate_localtime_test.err b/tests/rotate_localtime/rotate_localtime_test.err new file mode 100644 index 0000000..32d97c8 --- /dev/null +++ b/tests/rotate_localtime/rotate_localtime_test.err @@ -0,0 +1,355 @@ +test_check_localtime_second_mod_1 start +{2010-03-03_04:05:06} check_localtime(last_write=1900-01-00_00:00:00, intv=0, mod=1) -> REOPEN +{2010-03-03_04:05:06} check_localtime(last_write=2010-03-03_04:05:06, intv=0, mod=1) -> KEEP +{2010-03-03_04:05:06} check_localtime(last_write=2010-03-03_04:05:06, intv=0, mod=1) -> KEEP +{2010-03-03_04:05:07} check_localtime(last_write=2010-03-03_04:05:06, intv=0, mod=1) -> REOPEN +{2010-03-03_04:05:08} check_localtime(last_write=2010-03-03_04:05:07, intv=0, mod=1) -> REOPEN +{2010-03-03_04:05:00} check_localtime(last_write=2010-03-03_04:05:08, intv=0, mod=1) -> KEEP +{2010-03-03_04:06:00} check_localtime(last_write=2010-03-03_04:05:00, intv=0, mod=1) -> REOPEN +{2010-03-03_04:06:00} check_localtime(last_write=2010-03-03_04:06:00, intv=0, mod=1) -> KEEP +{2010-03-03_04:07:23} check_localtime(last_write=2010-03-03_04:06:00, intv=0, mod=1) -> REOPEN +{2010-03-03_04:07:23} check_localtime(last_write=2010-03-03_04:07:23, intv=0, mod=1) -> KEEP +{2010-03-03_07:07:23} check_localtime(last_write=2010-03-03_04:07:23, intv=0, mod=1) -> REOPEN +{2010-03-03_07:07:23} check_localtime(last_write=2010-03-03_07:07:23, intv=0, mod=1) -> KEEP +{2013-05-03_07:07:23} check_localtime(last_write=2010-03-03_07:07:23, intv=0, mod=1) -> REOPEN +{2013-05-03_07:07:23} check_localtime(last_write=2013-05-03_07:07:23, intv=0, mod=1) -> KEEP +test_check_localtime_second_mod_1 end +test_check_localtime_second_mod_40 start +{2010-03-03_04:05:00} check_localtime(last_write=1900-01-00_00:00:00, intv=0, mod=40) -> REOPEN +{2010-03-03_04:05:00} check_localtime(last_write=2010-03-03_04:05:00, intv=0, mod=40) -> KEEP +{2010-03-03_04:05:00} check_localtime(last_write=2010-03-03_04:05:00, intv=0, mod=40) -> KEEP +{2010-03-03_04:05:01} check_localtime(last_write=2010-03-03_04:05:00, intv=0, mod=40) -> KEEP +{2010-03-03_04:05:30} check_localtime(last_write=2010-03-03_04:05:01, intv=0, mod=40) -> KEEP +{2010-03-03_04:05:39} check_localtime(last_write=2010-03-03_04:05:30, intv=0, mod=40) -> KEEP +{2010-03-03_04:05:41} check_localtime(last_write=2010-03-03_04:05:39, intv=0, mod=40) -> REOPEN +{2010-03-03_04:06:41} check_localtime(last_write=2010-03-03_04:05:41, intv=0, mod=40) -> REOPEN +{2010-03-03_04:06:41} check_localtime(last_write=2010-03-03_04:06:41, intv=0, mod=40) -> KEEP +{2010-03-03_04:07:64} check_localtime(last_write=2010-03-03_04:06:41, intv=0, mod=40) -> REOPEN +{2010-03-03_04:07:64} check_localtime(last_write=2010-03-03_04:07:64, intv=0, mod=40) -> KEEP +{2010-03-03_07:07:64} check_localtime(last_write=2010-03-03_04:07:64, intv=0, mod=40) -> REOPEN +{2010-03-03_07:07:64} check_localtime(last_write=2010-03-03_07:07:64, intv=0, mod=40) -> KEEP +{2013-05-03_07:07:64} check_localtime(last_write=2010-03-03_07:07:64, intv=0, mod=40) -> REOPEN +{2013-05-03_07:07:64} check_localtime(last_write=2013-05-03_07:07:64, intv=0, mod=40) -> KEEP +test_check_localtime_second_mod_40 end +test_check_localtime_minute_mod_1 start +{2010-03-03_04:05:06} check_localtime(last_write=1900-01-00_00:00:00, intv=1, mod=1) -> REOPEN +{2010-03-03_04:05:06} check_localtime(last_write=2010-03-03_04:05:06, intv=1, mod=1) -> KEEP +{2010-03-03_04:05:06} check_localtime(last_write=2010-03-03_04:05:06, intv=1, mod=1) -> KEEP +{2010-03-03_04:05:07} check_localtime(last_write=2010-03-03_04:05:06, intv=1, mod=1) -> KEEP +{2010-03-03_04:05:08} check_localtime(last_write=2010-03-03_04:05:07, intv=1, mod=1) -> KEEP +{2010-03-03_04:05:00} check_localtime(last_write=2010-03-03_04:05:08, intv=1, mod=1) -> KEEP +{2010-03-03_04:06:00} check_localtime(last_write=2010-03-03_04:05:00, intv=1, mod=1) -> REOPEN +{2010-03-03_04:07:00} check_localtime(last_write=2010-03-03_04:06:00, intv=1, mod=1) -> REOPEN +{2010-03-03_04:07:40} check_localtime(last_write=2010-03-03_04:07:00, intv=1, mod=1) -> KEEP +{2010-03-03_04:09:20} check_localtime(last_write=2010-03-03_04:07:40, intv=1, mod=1) -> REOPEN +{2010-03-03_04:10:00} check_localtime(last_write=2010-03-03_04:09:20, intv=1, mod=1) -> REOPEN +{2010-03-03_04:10:00} check_localtime(last_write=2010-03-03_04:10:00, intv=1, mod=1) -> KEEP +{2010-03-03_05:10:00} check_localtime(last_write=2010-03-03_04:10:00, intv=1, mod=1) -> REOPEN +{2010-03-03_05:10:00} check_localtime(last_write=2010-03-03_05:10:00, intv=1, mod=1) -> KEEP +{2010-03-03_05:58:03} check_localtime(last_write=2010-03-03_05:10:00, intv=1, mod=1) -> REOPEN +{2010-03-03_05:59:03} check_localtime(last_write=2010-03-03_05:58:03, intv=1, mod=1) -> REOPEN +{2010-03-03_06:00:03} check_localtime(last_write=2010-03-03_05:59:03, intv=1, mod=1) -> REOPEN +{2010-03-04_06:00:03} check_localtime(last_write=2010-03-03_06:00:03, intv=1, mod=1) -> REOPEN +{2010-03-24_06:00:03} check_localtime(last_write=2010-03-04_06:00:03, intv=1, mod=1) -> REOPEN +{2010-09-24_06:00:03} check_localtime(last_write=2010-03-24_06:00:03, intv=1, mod=1) -> REOPEN +{2016-09-24_06:00:03} check_localtime(last_write=2010-09-24_06:00:03, intv=1, mod=1) -> REOPEN +{2016-09-24_06:00:09} check_localtime(last_write=2016-09-24_06:00:03, intv=1, mod=1) -> KEEP +{2016-09-24_06:01:09} check_localtime(last_write=2016-09-24_06:00:09, intv=1, mod=1) -> REOPEN +test_check_localtime_minute_mod_1 end +test_check_localtime_minute_mod_2 start +{2013-03-03_04:04:06} check_localtime(last_write=1900-01-00_00:00:00, intv=1, mod=2) -> REOPEN +{2013-03-03_04:04:06} check_localtime(last_write=2013-03-03_04:04:06, intv=1, mod=2) -> KEEP +{2013-03-03_04:04:06} check_localtime(last_write=2013-03-03_04:04:06, intv=1, mod=2) -> KEEP +{2013-03-03_04:04:07} check_localtime(last_write=2013-03-03_04:04:06, intv=1, mod=2) -> KEEP +{2013-03-03_04:04:08} check_localtime(last_write=2013-03-03_04:04:07, intv=1, mod=2) -> KEEP +{2013-03-03_04:04:00} check_localtime(last_write=2013-03-03_04:04:08, intv=1, mod=2) -> KEEP +{2013-03-03_04:05:00} check_localtime(last_write=2013-03-03_04:04:00, intv=1, mod=2) -> KEEP +{2013-03-03_04:06:00} check_localtime(last_write=2013-03-03_04:05:00, intv=1, mod=2) -> REOPEN +{2013-03-03_04:06:40} check_localtime(last_write=2013-03-03_04:06:00, intv=1, mod=2) -> KEEP +{2013-03-03_04:08:20} check_localtime(last_write=2013-03-03_04:06:40, intv=1, mod=2) -> REOPEN +{2013-03-03_04:09:00} check_localtime(last_write=2013-03-03_04:08:20, intv=1, mod=2) -> KEEP +{2013-03-03_04:09:00} check_localtime(last_write=2013-03-03_04:09:00, intv=1, mod=2) -> KEEP +{2013-03-03_05:09:00} check_localtime(last_write=2013-03-03_04:09:00, intv=1, mod=2) -> REOPEN +{2013-03-03_05:09:00} check_localtime(last_write=2013-03-03_05:09:00, intv=1, mod=2) -> KEEP +{2013-03-03_05:57:03} check_localtime(last_write=2013-03-03_05:09:00, intv=1, mod=2) -> REOPEN +{2013-03-03_05:59:03} check_localtime(last_write=2013-03-03_05:57:03, intv=1, mod=2) -> REOPEN +{2013-03-03_06:00:03} check_localtime(last_write=2013-03-03_05:59:03, intv=1, mod=2) -> REOPEN +{2013-03-04_06:00:03} check_localtime(last_write=2013-03-03_06:00:03, intv=1, mod=2) -> REOPEN +{2013-03-24_06:00:03} check_localtime(last_write=2013-03-04_06:00:03, intv=1, mod=2) -> REOPEN +{2013-09-24_06:00:03} check_localtime(last_write=2013-03-24_06:00:03, intv=1, mod=2) -> REOPEN +{2019-09-24_06:00:03} check_localtime(last_write=2013-09-24_06:00:03, intv=1, mod=2) -> REOPEN +{2019-09-24_06:00:09} check_localtime(last_write=2019-09-24_06:00:03, intv=1, mod=2) -> KEEP +{2019-09-24_06:01:09} check_localtime(last_write=2019-09-24_06:00:09, intv=1, mod=2) -> KEEP +{2019-09-24_06:02:09} check_localtime(last_write=2019-09-24_06:01:09, intv=1, mod=2) -> REOPEN +{2019-09-24_06:03:09} check_localtime(last_write=2019-09-24_06:02:09, intv=1, mod=2) -> KEEP +{2019-09-24_06:04:09} check_localtime(last_write=2019-09-24_06:03:09, intv=1, mod=2) -> REOPEN +{2019-09-24_06:06:09} check_localtime(last_write=2019-09-24_06:04:09, intv=1, mod=2) -> REOPEN +test_check_localtime_minute_mod_2 end +test_check_localtime_minute_mod_15 start +{2025-03-03_04:02:06} check_localtime(last_write=1900-01-00_00:00:00, intv=1, mod=15) -> REOPEN +{2025-03-03_04:02:06} check_localtime(last_write=2025-03-03_04:02:06, intv=1, mod=15) -> KEEP +{2025-03-03_04:02:06} check_localtime(last_write=2025-03-03_04:02:06, intv=1, mod=15) -> KEEP +{2025-03-03_04:02:07} check_localtime(last_write=2025-03-03_04:02:06, intv=1, mod=15) -> KEEP +{2025-03-03_04:02:08} check_localtime(last_write=2025-03-03_04:02:07, intv=1, mod=15) -> KEEP +{2025-03-03_04:02:00} check_localtime(last_write=2025-03-03_04:02:08, intv=1, mod=15) -> KEEP +{2025-03-03_04:08:00} check_localtime(last_write=2025-03-03_04:02:00, intv=1, mod=15) -> KEEP +{2025-03-03_04:10:00} check_localtime(last_write=2025-03-03_04:08:00, intv=1, mod=15) -> KEEP +{2025-03-03_04:13:00} check_localtime(last_write=2025-03-03_04:10:00, intv=1, mod=15) -> KEEP +{2025-03-03_04:15:00} check_localtime(last_write=2025-03-03_04:13:00, intv=1, mod=15) -> REOPEN +{2025-03-03_04:18:00} check_localtime(last_write=2025-03-03_04:15:00, intv=1, mod=15) -> KEEP +{2025-03-03_04:29:00} check_localtime(last_write=2025-03-03_04:18:00, intv=1, mod=15) -> KEEP +{2025-03-03_04:30:00} check_localtime(last_write=2025-03-03_04:29:00, intv=1, mod=15) -> REOPEN +{2025-03-03_04:45:00} check_localtime(last_write=2025-03-03_04:30:00, intv=1, mod=15) -> REOPEN +{2025-03-03_04:45:40} check_localtime(last_write=2025-03-03_04:45:00, intv=1, mod=15) -> KEEP +{2025-03-03_05:00:40} check_localtime(last_write=2025-03-03_04:45:40, intv=1, mod=15) -> REOPEN +{2025-03-03_05:00:40} check_localtime(last_write=2025-03-03_05:00:40, intv=1, mod=15) -> KEEP +{2025-03-03_06:45:40} check_localtime(last_write=2025-03-03_05:00:40, intv=1, mod=15) -> REOPEN +{2025-03-03_06:45:40} check_localtime(last_write=2025-03-03_06:45:40, intv=1, mod=15) -> KEEP +{2025-03-03_06:90:40} check_localtime(last_write=2025-03-03_06:45:40, intv=1, mod=15) -> REOPEN +{2025-03-03_06:102:40} check_localtime(last_write=2025-03-03_06:90:40, intv=1, mod=15) -> KEEP +{2025-03-03_06:103:00} check_localtime(last_write=2025-03-03_06:102:40, intv=1, mod=15) -> KEEP +{2025-03-03_06:103:00} check_localtime(last_write=2025-03-03_06:103:00, intv=1, mod=15) -> KEEP +{2025-03-03_06:151:03} check_localtime(last_write=2025-03-03_06:103:00, intv=1, mod=15) -> REOPEN +{2025-03-03_06:151:03} check_localtime(last_write=2025-03-03_06:151:03, intv=1, mod=15) -> KEEP +{2025-03-04_06:151:03} check_localtime(last_write=2025-03-03_06:151:03, intv=1, mod=15) -> REOPEN +{2025-03-24_06:151:03} check_localtime(last_write=2025-03-04_06:151:03, intv=1, mod=15) -> REOPEN +{2025-09-24_06:151:03} check_localtime(last_write=2025-03-24_06:151:03, intv=1, mod=15) -> REOPEN +{2031-09-24_06:151:03} check_localtime(last_write=2025-09-24_06:151:03, intv=1, mod=15) -> REOPEN +{2031-09-24_06:151:09} check_localtime(last_write=2031-09-24_06:151:03, intv=1, mod=15) -> KEEP +{2031-09-24_06:02:09} check_localtime(last_write=2031-09-24_06:151:09, intv=1, mod=15) -> KEEP +test_check_localtime_minute_mod_15 end +test_check_localtime_hour_mod_1 start +{2010-03-03_04:05:06} check_localtime(last_write=1900-01-00_00:00:00, intv=2, mod=1) -> REOPEN +{2010-03-03_04:05:06} check_localtime(last_write=2010-03-03_04:05:06, intv=2, mod=1) -> KEEP +{2010-03-03_04:05:06} check_localtime(last_write=2010-03-03_04:05:06, intv=2, mod=1) -> KEEP +{2010-03-03_04:05:07} check_localtime(last_write=2010-03-03_04:05:06, intv=2, mod=1) -> KEEP +{2010-03-03_04:05:08} check_localtime(last_write=2010-03-03_04:05:07, intv=2, mod=1) -> KEEP +{2010-03-03_04:05:00} check_localtime(last_write=2010-03-03_04:05:08, intv=2, mod=1) -> KEEP +{2010-03-03_04:06:00} check_localtime(last_write=2010-03-03_04:05:00, intv=2, mod=1) -> KEEP +{2010-03-03_04:07:00} check_localtime(last_write=2010-03-03_04:06:00, intv=2, mod=1) -> KEEP +{2010-03-03_04:00:00} check_localtime(last_write=2010-03-03_04:07:00, intv=2, mod=1) -> KEEP +{2010-03-03_05:00:00} check_localtime(last_write=2010-03-03_04:00:00, intv=2, mod=1) -> REOPEN +{2010-03-03_06:00:00} check_localtime(last_write=2010-03-03_05:00:00, intv=2, mod=1) -> REOPEN +{2010-03-03_06:40:00} check_localtime(last_write=2010-03-03_06:00:00, intv=2, mod=1) -> KEEP +{2010-03-03_08:40:20} check_localtime(last_write=2010-03-03_06:40:00, intv=2, mod=1) -> REOPEN +{2010-03-03_09:00:00} check_localtime(last_write=2010-03-03_08:40:20, intv=2, mod=1) -> REOPEN +{2010-03-03_09:00:00} check_localtime(last_write=2010-03-03_09:00:00, intv=2, mod=1) -> KEEP +{2010-03-03_10:00:00} check_localtime(last_write=2010-03-03_09:00:00, intv=2, mod=1) -> REOPEN +{2010-03-03_10:00:00} check_localtime(last_write=2010-03-03_10:00:00, intv=2, mod=1) -> KEEP +{2010-03-03_32:03:00} check_localtime(last_write=2010-03-03_10:00:00, intv=2, mod=1) -> REOPEN +{2010-03-03_59:59:00} check_localtime(last_write=2010-03-03_32:03:00, intv=2, mod=1) -> REOPEN +{2010-03-04_00:59:00} check_localtime(last_write=2010-03-03_59:59:00, intv=2, mod=1) -> REOPEN +{2010-03-05_00:59:00} check_localtime(last_write=2010-03-04_00:59:00, intv=2, mod=1) -> REOPEN +{2010-03-25_00:59:00} check_localtime(last_write=2010-03-05_00:59:00, intv=2, mod=1) -> REOPEN +{2010-09-25_00:59:00} check_localtime(last_write=2010-03-25_00:59:00, intv=2, mod=1) -> REOPEN +{2016-09-25_00:59:00} check_localtime(last_write=2010-09-25_00:59:00, intv=2, mod=1) -> REOPEN +{2016-09-25_00:59:06} check_localtime(last_write=2016-09-25_00:59:00, intv=2, mod=1) -> KEEP +{2016-09-25_01:59:06} check_localtime(last_write=2016-09-25_00:59:06, intv=2, mod=1) -> REOPEN +test_check_localtime_hour_mod_1 end +test_check_localtime_hour_mod_12 start +{2025-03-03_04:02:06} check_localtime(last_write=1900-01-00_00:00:00, intv=2, mod=12) -> REOPEN +{2025-03-03_04:02:06} check_localtime(last_write=2025-03-03_04:02:06, intv=2, mod=12) -> KEEP +{2025-03-03_04:02:06} check_localtime(last_write=2025-03-03_04:02:06, intv=2, mod=12) -> KEEP +{2025-03-03_04:03:06} check_localtime(last_write=2025-03-03_04:02:06, intv=2, mod=12) -> KEEP +{2025-03-03_04:04:07} check_localtime(last_write=2025-03-03_04:03:06, intv=2, mod=12) -> KEEP +{2025-03-03_04:00:07} check_localtime(last_write=2025-03-03_04:04:07, intv=2, mod=12) -> KEEP +{2025-03-03_08:00:07} check_localtime(last_write=2025-03-03_04:00:07, intv=2, mod=12) -> KEEP +{2025-03-03_10:00:07} check_localtime(last_write=2025-03-03_08:00:07, intv=2, mod=12) -> KEEP +{2025-03-03_13:00:07} check_localtime(last_write=2025-03-03_10:00:07, intv=2, mod=12) -> REOPEN +{2025-03-03_15:00:07} check_localtime(last_write=2025-03-03_13:00:07, intv=2, mod=12) -> KEEP +{2025-03-03_18:00:07} check_localtime(last_write=2025-03-03_15:00:07, intv=2, mod=12) -> KEEP +{2025-03-03_23:00:07} check_localtime(last_write=2025-03-03_18:00:07, intv=2, mod=12) -> KEEP +{2025-03-03_23:00:47} check_localtime(last_write=2025-03-03_23:00:07, intv=2, mod=12) -> KEEP +{2025-03-04_00:00:47} check_localtime(last_write=2025-03-03_23:00:47, intv=2, mod=12) -> REOPEN +{2025-03-04_00:00:47} check_localtime(last_write=2025-03-04_00:00:47, intv=2, mod=12) -> KEEP +{2025-03-05_15:00:47} check_localtime(last_write=2025-03-04_00:00:47, intv=2, mod=12) -> REOPEN +{2025-03-05_15:00:47} check_localtime(last_write=2025-03-05_15:00:47, intv=2, mod=12) -> KEEP +{2025-03-05_15:01:00} check_localtime(last_write=2025-03-05_15:00:47, intv=2, mod=12) -> KEEP +{2025-03-05_15:01:00} check_localtime(last_write=2025-03-05_15:01:00, intv=2, mod=12) -> KEEP +{2025-03-05_15:49:03} check_localtime(last_write=2025-03-05_15:01:00, intv=2, mod=12) -> KEEP +{2025-03-05_15:49:03} check_localtime(last_write=2025-03-05_15:49:03, intv=2, mod=12) -> KEEP +{2025-03-06_15:49:03} check_localtime(last_write=2025-03-05_15:49:03, intv=2, mod=12) -> REOPEN +{2025-03-26_15:49:03} check_localtime(last_write=2025-03-06_15:49:03, intv=2, mod=12) -> REOPEN +{2025-09-26_15:49:03} check_localtime(last_write=2025-03-26_15:49:03, intv=2, mod=12) -> REOPEN +{2031-09-26_15:49:03} check_localtime(last_write=2025-09-26_15:49:03, intv=2, mod=12) -> REOPEN +{2031-09-26_15:49:09} check_localtime(last_write=2031-09-26_15:49:03, intv=2, mod=12) -> KEEP +{2031-09-26_15:02:09} check_localtime(last_write=2031-09-26_15:49:09, intv=2, mod=12) -> KEEP +test_check_localtime_hour_mod_12 end +test_check_localtime_day_mod_1 start +{2010-03-03_04:05:06} check_localtime(last_write=1900-01-00_00:00:00, intv=3, mod=1) -> REOPEN +{2010-03-03_04:05:06} check_localtime(last_write=2010-03-03_04:05:06, intv=3, mod=1) -> KEEP +{2010-03-03_04:05:06} check_localtime(last_write=2010-03-03_04:05:06, intv=3, mod=1) -> KEEP +{2010-03-03_04:05:07} check_localtime(last_write=2010-03-03_04:05:06, intv=3, mod=1) -> KEEP +{2010-03-03_04:05:08} check_localtime(last_write=2010-03-03_04:05:07, intv=3, mod=1) -> KEEP +{2010-03-03_04:05:00} check_localtime(last_write=2010-03-03_04:05:08, intv=3, mod=1) -> KEEP +{2010-03-03_04:06:00} check_localtime(last_write=2010-03-03_04:05:00, intv=3, mod=1) -> KEEP +{2010-03-03_04:07:00} check_localtime(last_write=2010-03-03_04:06:00, intv=3, mod=1) -> KEEP +{2010-03-03_04:00:00} check_localtime(last_write=2010-03-03_04:07:00, intv=3, mod=1) -> KEEP +{2010-03-03_05:00:00} check_localtime(last_write=2010-03-03_04:00:00, intv=3, mod=1) -> KEEP +{2010-03-03_06:00:00} check_localtime(last_write=2010-03-03_05:00:00, intv=3, mod=1) -> KEEP +{2010-03-03_00:00:00} check_localtime(last_write=2010-03-03_06:00:00, intv=3, mod=1) -> KEEP +{2010-03-04_00:00:00} check_localtime(last_write=2010-03-03_00:00:00, intv=3, mod=1) -> REOPEN +{2010-03-05_00:00:00} check_localtime(last_write=2010-03-04_00:00:00, intv=3, mod=1) -> REOPEN +{2010-03-05_03:00:00} check_localtime(last_write=2010-03-05_00:00:00, intv=3, mod=1) -> KEEP +{2010-03-07_03:00:20} check_localtime(last_write=2010-03-05_03:00:00, intv=3, mod=1) -> REOPEN +{2010-03-08_03:00:00} check_localtime(last_write=2010-03-07_03:00:20, intv=3, mod=1) -> REOPEN +{2010-03-08_03:00:00} check_localtime(last_write=2010-03-08_03:00:00, intv=3, mod=1) -> KEEP +{2010-03-09_03:00:00} check_localtime(last_write=2010-03-08_03:00:00, intv=3, mod=1) -> REOPEN +{2010-03-09_03:00:00} check_localtime(last_write=2010-03-09_03:00:00, intv=3, mod=1) -> KEEP +{2010-03-12_03:03:00} check_localtime(last_write=2010-03-09_03:00:00, intv=3, mod=1) -> REOPEN +{2010-03-12_59:59:00} check_localtime(last_write=2010-03-12_03:03:00, intv=3, mod=1) -> KEEP +{2010-03-13_00:59:00} check_localtime(last_write=2010-03-12_59:59:00, intv=3, mod=1) -> REOPEN +{2010-09-13_00:59:00} check_localtime(last_write=2010-03-13_00:59:00, intv=3, mod=1) -> REOPEN +{2016-09-13_00:59:00} check_localtime(last_write=2010-09-13_00:59:00, intv=3, mod=1) -> REOPEN +{2016-09-13_00:59:06} check_localtime(last_write=2016-09-13_00:59:00, intv=3, mod=1) -> KEEP +{2016-09-14_00:59:06} check_localtime(last_write=2016-09-13_00:59:06, intv=3, mod=1) -> REOPEN +test_check_localtime_day_mod_1 end +test_check_localtime_day_mod_10 start +{2025-03-03_04:02:06} check_localtime(last_write=1900-01-00_00:00:00, intv=3, mod=10) -> REOPEN +{2025-03-03_04:02:06} check_localtime(last_write=2025-03-03_04:02:06, intv=3, mod=10) -> KEEP +{2025-03-03_04:02:06} check_localtime(last_write=2025-03-03_04:02:06, intv=3, mod=10) -> KEEP +{2025-03-03_05:02:06} check_localtime(last_write=2025-03-03_04:02:06, intv=3, mod=10) -> KEEP +{2025-03-03_06:03:07} check_localtime(last_write=2025-03-03_05:02:06, intv=3, mod=10) -> KEEP +{2025-03-03_00:03:07} check_localtime(last_write=2025-03-03_06:03:07, intv=3, mod=10) -> KEEP +{2025-03-06_00:03:07} check_localtime(last_write=2025-03-03_00:03:07, intv=3, mod=10) -> KEEP +{2025-03-10_00:03:07} check_localtime(last_write=2025-03-06_00:03:07, intv=3, mod=10) -> KEEP +{2025-03-11_00:03:07} check_localtime(last_write=2025-03-10_00:03:07, intv=3, mod=10) -> REOPEN +{2025-03-15_00:03:07} check_localtime(last_write=2025-03-11_00:03:07, intv=3, mod=10) -> KEEP +{2025-03-18_00:03:07} check_localtime(last_write=2025-03-15_00:03:07, intv=3, mod=10) -> KEEP +{2025-03-23_00:03:07} check_localtime(last_write=2025-03-18_00:03:07, intv=3, mod=10) -> REOPEN +{2025-03-23_00:03:47} check_localtime(last_write=2025-03-23_00:03:07, intv=3, mod=10) -> KEEP +{2025-03-24_00:03:47} check_localtime(last_write=2025-03-23_00:03:47, intv=3, mod=10) -> KEEP +{2025-03-24_00:03:47} check_localtime(last_write=2025-03-24_00:03:47, intv=3, mod=10) -> KEEP +{2025-04-25_00:03:47} check_localtime(last_write=2025-03-24_00:03:47, intv=3, mod=10) -> REOPEN +{2025-04-25_00:03:47} check_localtime(last_write=2025-04-25_00:03:47, intv=3, mod=10) -> KEEP +{2025-04-25_01:00:00} check_localtime(last_write=2025-04-25_00:03:47, intv=3, mod=10) -> KEEP +{2025-04-25_01:00:00} check_localtime(last_write=2025-04-25_01:00:00, intv=3, mod=10) -> KEEP +{2025-04-25_13:48:03} check_localtime(last_write=2025-04-25_01:00:00, intv=3, mod=10) -> KEEP +{2025-04-25_13:48:03} check_localtime(last_write=2025-04-25_13:48:03, intv=3, mod=10) -> KEEP +{2025-05-25_13:48:03} check_localtime(last_write=2025-04-25_13:48:03, intv=3, mod=10) -> REOPEN +{2025-07-25_13:48:03} check_localtime(last_write=2025-05-25_13:48:03, intv=3, mod=10) -> REOPEN +{2029-07-25_13:48:03} check_localtime(last_write=2025-07-25_13:48:03, intv=3, mod=10) -> REOPEN +{2035-07-25_13:48:03} check_localtime(last_write=2029-07-25_13:48:03, intv=3, mod=10) -> REOPEN +{2035-07-25_13:48:09} check_localtime(last_write=2035-07-25_13:48:03, intv=3, mod=10) -> KEEP +{2035-07-25_13:02:09} check_localtime(last_write=2035-07-25_13:48:09, intv=3, mod=10) -> KEEP +test_check_localtime_day_mod_10 end +test_check_localtime_month_mod_1 start +{2010-03-03_04:05:06} check_localtime(last_write=1900-01-00_00:00:00, intv=4, mod=1) -> REOPEN +{2010-03-03_04:05:06} check_localtime(last_write=2010-03-03_04:05:06, intv=4, mod=1) -> KEEP +{2010-03-03_04:05:06} check_localtime(last_write=2010-03-03_04:05:06, intv=4, mod=1) -> KEEP +{2010-03-03_04:05:07} check_localtime(last_write=2010-03-03_04:05:06, intv=4, mod=1) -> KEEP +{2010-03-03_04:05:08} check_localtime(last_write=2010-03-03_04:05:07, intv=4, mod=1) -> KEEP +{2010-03-03_04:05:00} check_localtime(last_write=2010-03-03_04:05:08, intv=4, mod=1) -> KEEP +{2010-03-03_04:06:00} check_localtime(last_write=2010-03-03_04:05:00, intv=4, mod=1) -> KEEP +{2010-03-03_04:07:00} check_localtime(last_write=2010-03-03_04:06:00, intv=4, mod=1) -> KEEP +{2010-03-03_04:00:00} check_localtime(last_write=2010-03-03_04:07:00, intv=4, mod=1) -> KEEP +{2010-03-03_05:00:00} check_localtime(last_write=2010-03-03_04:00:00, intv=4, mod=1) -> KEEP +{2010-03-03_06:00:00} check_localtime(last_write=2010-03-03_05:00:00, intv=4, mod=1) -> KEEP +{2010-03-03_00:00:00} check_localtime(last_write=2010-03-03_06:00:00, intv=4, mod=1) -> KEEP +{2010-03-04_00:00:00} check_localtime(last_write=2010-03-03_00:00:00, intv=4, mod=1) -> KEEP +{2010-03-05_00:00:00} check_localtime(last_write=2010-03-04_00:00:00, intv=4, mod=1) -> KEEP +{2010-03-00_00:00:00} check_localtime(last_write=2010-03-05_00:00:00, intv=4, mod=1) -> KEEP +{2010-04-00_00:00:00} check_localtime(last_write=2010-03-00_00:00:00, intv=4, mod=1) -> REOPEN +{2010-05-00_00:00:00} check_localtime(last_write=2010-04-00_00:00:00, intv=4, mod=1) -> REOPEN +{2010-05-03_00:00:00} check_localtime(last_write=2010-05-00_00:00:00, intv=4, mod=1) -> KEEP +{2010-07-03_00:00:20} check_localtime(last_write=2010-05-03_00:00:00, intv=4, mod=1) -> REOPEN +{2010-08-00_00:00:00} check_localtime(last_write=2010-07-03_00:00:20, intv=4, mod=1) -> REOPEN +{2010-08-00_00:00:00} check_localtime(last_write=2010-08-00_00:00:00, intv=4, mod=1) -> KEEP +{2010-09-00_00:00:00} check_localtime(last_write=2010-08-00_00:00:00, intv=4, mod=1) -> REOPEN +{2010-09-00_00:00:00} check_localtime(last_write=2010-09-00_00:00:00, intv=4, mod=1) -> KEEP +{2010-12-03_00:03:00} check_localtime(last_write=2010-09-00_00:00:00, intv=4, mod=1) -> REOPEN +{2010-12-27_59:59:00} check_localtime(last_write=2010-12-03_00:03:00, intv=4, mod=1) -> KEEP +{2010-13-27_00:59:00} check_localtime(last_write=2010-12-27_59:59:00, intv=4, mod=1) -> REOPEN +{2016-13-27_00:59:00} check_localtime(last_write=2010-13-27_00:59:00, intv=4, mod=1) -> REOPEN +{2016-13-27_00:59:06} check_localtime(last_write=2016-13-27_00:59:00, intv=4, mod=1) -> KEEP +{2016-14-27_00:59:06} check_localtime(last_write=2016-13-27_00:59:06, intv=4, mod=1) -> REOPEN +test_check_localtime_month_mod_1 end +test_check_localtime_month_mod_3 start +{2025-02-03_04:02:06} check_localtime(last_write=1900-01-00_00:00:00, intv=4, mod=3) -> REOPEN +{2025-02-03_04:02:06} check_localtime(last_write=2025-02-03_04:02:06, intv=4, mod=3) -> KEEP +{2025-02-03_04:02:06} check_localtime(last_write=2025-02-03_04:02:06, intv=4, mod=3) -> KEEP +{2025-02-04_04:02:06} check_localtime(last_write=2025-02-03_04:02:06, intv=4, mod=3) -> KEEP +{2025-02-05_04:03:07} check_localtime(last_write=2025-02-04_04:02:06, intv=4, mod=3) -> KEEP +{2025-02-05_00:03:07} check_localtime(last_write=2025-02-05_04:03:07, intv=4, mod=3) -> KEEP +{2025-04-05_00:03:07} check_localtime(last_write=2025-02-05_00:03:07, intv=4, mod=3) -> REOPEN +{2025-05-05_00:03:07} check_localtime(last_write=2025-04-05_00:03:07, intv=4, mod=3) -> KEEP +{2025-07-05_00:03:07} check_localtime(last_write=2025-05-05_00:03:07, intv=4, mod=3) -> REOPEN +{2025-09-05_00:03:07} check_localtime(last_write=2025-07-05_00:03:07, intv=4, mod=3) -> KEEP +{2025-10-05_00:03:07} check_localtime(last_write=2025-09-05_00:03:07, intv=4, mod=3) -> REOPEN +{2025-10-05_00:03:07} check_localtime(last_write=2025-10-05_00:03:07, intv=4, mod=3) -> KEEP +{2025-10-05_00:03:47} check_localtime(last_write=2025-10-05_00:03:07, intv=4, mod=3) -> KEEP +{2025-10-06_00:03:47} check_localtime(last_write=2025-10-05_00:03:47, intv=4, mod=3) -> KEEP +{2025-10-06_00:03:47} check_localtime(last_write=2025-10-06_00:03:47, intv=4, mod=3) -> KEEP +{2025-13-07_00:03:47} check_localtime(last_write=2025-10-06_00:03:47, intv=4, mod=3) -> REOPEN +{2025-13-07_00:03:47} check_localtime(last_write=2025-13-07_00:03:47, intv=4, mod=3) -> KEEP +{2025-13-07_01:00:00} check_localtime(last_write=2025-13-07_00:03:47, intv=4, mod=3) -> KEEP +{2025-13-07_01:00:00} check_localtime(last_write=2025-13-07_01:00:00, intv=4, mod=3) -> KEEP +{2025-13-07_13:48:03} check_localtime(last_write=2025-13-07_01:00:00, intv=4, mod=3) -> KEEP +{2025-13-07_13:48:03} check_localtime(last_write=2025-13-07_13:48:03, intv=4, mod=3) -> KEEP +{2029-13-07_13:48:03} check_localtime(last_write=2025-13-07_13:48:03, intv=4, mod=3) -> REOPEN +{2035-13-07_13:48:03} check_localtime(last_write=2029-13-07_13:48:03, intv=4, mod=3) -> REOPEN +{2035-13-07_13:48:09} check_localtime(last_write=2035-13-07_13:48:03, intv=4, mod=3) -> KEEP +{2035-13-07_13:02:09} check_localtime(last_write=2035-13-07_13:48:09, intv=4, mod=3) -> KEEP +test_check_localtime_month_mod_3 end +test_check_localtime_year_mod_1 start +{2010-03-03_04:05:06} check_localtime(last_write=1900-01-00_00:00:00, intv=5, mod=1) -> REOPEN +{2010-03-03_04:05:06} check_localtime(last_write=2010-03-03_04:05:06, intv=5, mod=1) -> KEEP +{2010-03-03_04:05:06} check_localtime(last_write=2010-03-03_04:05:06, intv=5, mod=1) -> KEEP +{2010-03-03_04:05:07} check_localtime(last_write=2010-03-03_04:05:06, intv=5, mod=1) -> KEEP +{2010-03-03_04:05:08} check_localtime(last_write=2010-03-03_04:05:07, intv=5, mod=1) -> KEEP +{2010-03-03_04:05:00} check_localtime(last_write=2010-03-03_04:05:08, intv=5, mod=1) -> KEEP +{2010-03-03_04:06:00} check_localtime(last_write=2010-03-03_04:05:00, intv=5, mod=1) -> KEEP +{2010-03-03_04:07:00} check_localtime(last_write=2010-03-03_04:06:00, intv=5, mod=1) -> KEEP +{2010-03-03_04:00:00} check_localtime(last_write=2010-03-03_04:07:00, intv=5, mod=1) -> KEEP +{2010-03-03_05:00:00} check_localtime(last_write=2010-03-03_04:00:00, intv=5, mod=1) -> KEEP +{2010-03-03_06:00:00} check_localtime(last_write=2010-03-03_05:00:00, intv=5, mod=1) -> KEEP +{2010-03-03_00:00:00} check_localtime(last_write=2010-03-03_06:00:00, intv=5, mod=1) -> KEEP +{2010-03-04_00:00:00} check_localtime(last_write=2010-03-03_00:00:00, intv=5, mod=1) -> KEEP +{2010-03-05_00:00:00} check_localtime(last_write=2010-03-04_00:00:00, intv=5, mod=1) -> KEEP +{2010-03-00_00:00:00} check_localtime(last_write=2010-03-05_00:00:00, intv=5, mod=1) -> KEEP +{2010-04-00_00:00:00} check_localtime(last_write=2010-03-00_00:00:00, intv=5, mod=1) -> KEEP +{2010-05-00_00:00:00} check_localtime(last_write=2010-04-00_00:00:00, intv=5, mod=1) -> KEEP +{2010-01-00_00:00:00} check_localtime(last_write=2010-05-00_00:00:00, intv=5, mod=1) -> KEEP +{2011-01-00_00:00:00} check_localtime(last_write=2010-01-00_00:00:00, intv=5, mod=1) -> REOPEN +{2012-01-00_00:00:00} check_localtime(last_write=2011-01-00_00:00:00, intv=5, mod=1) -> REOPEN +{2012-04-00_00:00:00} check_localtime(last_write=2012-01-00_00:00:00, intv=5, mod=1) -> KEEP +{2014-04-00_00:00:20} check_localtime(last_write=2012-04-00_00:00:00, intv=5, mod=1) -> REOPEN +{2015-04-00_00:00:00} check_localtime(last_write=2014-04-00_00:00:20, intv=5, mod=1) -> REOPEN +{2015-04-00_00:00:00} check_localtime(last_write=2015-04-00_00:00:00, intv=5, mod=1) -> KEEP +{2016-04-00_00:00:00} check_localtime(last_write=2015-04-00_00:00:00, intv=5, mod=1) -> REOPEN +{2016-04-00_00:00:00} check_localtime(last_write=2016-04-00_00:00:00, intv=5, mod=1) -> KEEP +{2019-04-03_00:03:00} check_localtime(last_write=2016-04-00_00:00:00, intv=5, mod=1) -> REOPEN +{2019-04-27_59:59:00} check_localtime(last_write=2019-04-03_00:03:00, intv=5, mod=1) -> KEEP +{2020-04-27_00:59:00} check_localtime(last_write=2019-04-27_59:59:00, intv=5, mod=1) -> REOPEN +{2026-04-27_00:59:00} check_localtime(last_write=2020-04-27_00:59:00, intv=5, mod=1) -> REOPEN +{2026-04-27_00:59:06} check_localtime(last_write=2026-04-27_00:59:00, intv=5, mod=1) -> KEEP +{2027-04-27_00:59:06} check_localtime(last_write=2026-04-27_00:59:06, intv=5, mod=1) -> REOPEN +test_check_localtime_year_mod_1 end +test_check_localtime_year_mod_2 start +{2025-02-03_04:02:06} check_localtime(last_write=1900-01-00_00:00:00, intv=5, mod=2) -> REOPEN +{2025-02-03_04:02:06} check_localtime(last_write=2025-02-03_04:02:06, intv=5, mod=2) -> KEEP +{2025-02-03_04:02:06} check_localtime(last_write=2025-02-03_04:02:06, intv=5, mod=2) -> KEEP +{2025-02-04_04:02:06} check_localtime(last_write=2025-02-03_04:02:06, intv=5, mod=2) -> KEEP +{2025-03-05_04:03:07} check_localtime(last_write=2025-02-04_04:02:06, intv=5, mod=2) -> KEEP +{2025-03-05_00:03:07} check_localtime(last_write=2025-03-05_04:03:07, intv=5, mod=2) -> KEEP +{3926-03-05_00:03:07} check_localtime(last_write=2025-03-05_00:03:07, intv=5, mod=2) -> REOPEN +{3927-03-05_00:03:07} check_localtime(last_write=3926-03-05_00:03:07, intv=5, mod=2) -> KEEP +{3928-03-05_00:03:07} check_localtime(last_write=3927-03-05_00:03:07, intv=5, mod=2) -> REOPEN +{3929-03-05_00:03:07} check_localtime(last_write=3928-03-05_00:03:07, intv=5, mod=2) -> KEEP +{3929-03-05_00:03:07} check_localtime(last_write=3929-03-05_00:03:07, intv=5, mod=2) -> KEEP +{1909-03-05_00:03:07} check_localtime(last_write=3929-03-05_00:03:07, intv=5, mod=2) -> KEEP +{1909-03-05_00:03:07} check_localtime(last_write=1909-03-05_00:03:07, intv=5, mod=2) -> KEEP +{1909-03-05_00:03:47} check_localtime(last_write=1909-03-05_00:03:07, intv=5, mod=2) -> KEEP +{1909-03-06_00:03:47} check_localtime(last_write=1909-03-05_00:03:47, intv=5, mod=2) -> KEEP +{1909-03-06_00:03:47} check_localtime(last_write=1909-03-06_00:03:47, intv=5, mod=2) -> KEEP +{1912-03-07_00:03:47} check_localtime(last_write=1909-03-06_00:03:47, intv=5, mod=2) -> REOPEN +{1912-03-07_00:03:47} check_localtime(last_write=1912-03-07_00:03:47, intv=5, mod=2) -> KEEP +{1912-03-07_01:00:00} check_localtime(last_write=1912-03-07_00:03:47, intv=5, mod=2) -> KEEP +{1912-03-07_01:00:00} check_localtime(last_write=1912-03-07_01:00:00, intv=5, mod=2) -> KEEP +{1912-03-07_13:48:03} check_localtime(last_write=1912-03-07_01:00:00, intv=5, mod=2) -> KEEP +{1912-03-07_13:48:03} check_localtime(last_write=1912-03-07_13:48:03, intv=5, mod=2) -> KEEP +{1916-03-07_13:48:03} check_localtime(last_write=1912-03-07_13:48:03, intv=5, mod=2) -> REOPEN +{1922-03-07_13:48:03} check_localtime(last_write=1916-03-07_13:48:03, intv=5, mod=2) -> REOPEN +{1922-03-07_13:48:09} check_localtime(last_write=1922-03-07_13:48:03, intv=5, mod=2) -> KEEP +{1922-03-07_13:02:09} check_localtime(last_write=1922-03-07_13:48:09, intv=5, mod=2) -> KEEP +test_check_localtime_year_mod_2 end diff --git a/tests/rotate_localtime/rotate_localtime_test.ok b/tests/rotate_localtime/rotate_localtime_test.ok new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/tests/rotate_localtime/rotate_localtime_test.ok diff --git a/tests/testsuite.at b/tests/testsuite.at index d928bb6..a1ff910 100644 --- a/tests/testsuite.at +++ b/tests/testsuite.at @@ -1,3 +1,9 @@ AT_INIT AT_BANNER([Regression tests.])
+AT_SETUP([rotate_localtime_test]) +AT_KEYWORDS([rotate_localtime_test]) +cat $abs_srcdir/rotate_localtime/rotate_localtime_test.ok > expout +cat $abs_srcdir/rotate_localtime/rotate_localtime_test.err > experr +AT_CHECK([$abs_top_builddir/tests/rotate_localtime/rotate_localtime_test], [], [expout], [experr]) +AT_CLEANUP