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(a)sysmocom.de>
* (C) 2011-2016 by Holger Hans Peter Freyther <holger(a)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(a)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
--
To view, visit
https://gerrit.osmocom.org/c/osmo-pcap/+/39158?usp=email
To unsubscribe, or for help writing mail filters, visit
https://gerrit.osmocom.org/settings?usp=email
Gerrit-MessageType: newchange
Gerrit-Project: osmo-pcap
Gerrit-Branch: master
Gerrit-Change-Id: Idf17a161c17050bb62793a82e39179a093b35f73
Gerrit-Change-Number: 39158
Gerrit-PatchSet: 1
Gerrit-Owner: pespin <pespin(a)sysmocom.de>