test: new test, notify.sh, systemd and s6 readiness notification

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This commit is contained in:
Joachim Wiberg
2022-10-16 20:06:26 +02:00
parent 912a281ee2
commit 47d837bf6a
4 changed files with 152 additions and 7 deletions
+1
View File
@@ -53,6 +53,7 @@ TESTS += cond-start-task.sh
TESTS += failing-sysv.sh
TESTS += global-envs.sh
TESTS += initctl-status-subset.sh
TESTS += notify.sh
TESTS += pre-post-serv.sh
TESTS += restart-self.sh
TESTS += runlevel.sh
+52 -7
View File
@@ -14,6 +14,10 @@
#include <unistd.h>
#define PROGNM "serv"
#define log warnx
volatile sig_atomic_t reloading = 1;
volatile sig_atomic_t running = 1;
static void verify_env(char *arg)
{
@@ -71,8 +75,17 @@ static void inc_restarts(void)
static void sig(int signo)
{
warnx("We got signal %d ...", signo);
exit(0);
log("Got signal %d ...", signo);
switch (signo) {
case SIGHUP:
reloading = 1;
break;
case SIGTERM:
running = 0;
break;
}
}
static void pidfile(char *pidfn)
@@ -86,7 +99,7 @@ static void pidfile(char *pidfn)
pidfn = fn;
}
pid = getpid();
warnx("Creating PID file %s with %d", pidfn, pid);
log("Creating PID file %s with %d", pidfn, pid);
fp = fopen(pidfn, "w");
if (!fp)
@@ -106,6 +119,7 @@ static int usage(int rc)
" -e K:V Verify K environment variable is V value\n"
" -E K Verify K is not set in the environment\n"
" -n Run in foreground\n"
" -N SOCK Send 'READY=1\\n' on $NOTIFY_SOCKET or SOCK\n"
" -p Create PID file despite running in foreground\n"
" -P FILE Create PID file using FILE\n"
" -r SVC Call initctl to restart service SVC (self)\n"
@@ -119,16 +133,20 @@ static int usage(int rc)
return rc;
}
#include <sys/socket.h>
int main(int argc, char *argv[])
{
int do_background = 1;
int notify_s6 = 0;
int do_pidfile = 1;
int do_restart = 0;
int do_notify = 0;
char *pidfn = NULL;
char cmd[80];
int c;
while ((c = getopt(argc, argv, "e:E:hnpP:r:")) != EOF) {
while ((c = getopt(argc, argv, "e:E:hnN:pP:r:")) != EOF) {
switch (c) {
case 'h':
return usage(0);
@@ -142,6 +160,10 @@ int main(int argc, char *argv[])
do_background = 0;
do_pidfile--;
break;
case 'N':
do_notify = atoi(optarg);
notify_s6 = 1;
break;
case 'p':
do_pidfile++;
break;
@@ -165,13 +187,36 @@ int main(int argc, char *argv[])
/* Signal handlers first *then* PID file */
signal(SIGTERM, sig);
signal(SIGHUP, sig);
/* Tell world where we are, but not if bg w/o pid file */
if (do_pidfile == 1)
pidfile(pidfn);
warnx("Entering while(1) loop");
while (1) {
if (!do_notify) {
const char *sock = getenv("NOTIFY_SOCKET");
/* systemd style */
if (sock)
do_notify = atoi(sock);
}
log("Entering while(1) loop");
while (running) {
if (reloading) {
if (do_notify > 0) {
log("Notifying Finit on socket %d, READY=1", do_notify);
if (write(do_notify, "READY=1\n", 8) == -1)
err(1, "Failed sending ready notification to Finit");
if (notify_s6) {
log("s6 notify, closing socket %d ...", do_notify);
close(do_notify);
do_notify = 0;
}
}
reloading = 0;
}
sleep(1);
if (do_restart) {
inc_restarts();
@@ -181,6 +226,6 @@ int main(int argc, char *argv[])
}
}
warnx("Leaving ...");
log("Leaving ...");
return 0;
}
Executable
+79
View File
@@ -0,0 +1,79 @@
#!/bin/sh
# Verify service readiness notification
set -eu
#set -x
TEST_DIR=$(dirname "$0")
test_setup()
{
say "Test start $(date)"
texec sh -c "mkdir -p /etc/default"
}
test_teardown()
{
say "Test done $(date)"
say "Running test teardown."
texec rm -f "$FINIT_CONF"
}
test_one()
{
type=$1
service=$2
num=$(texec sh -c "find /proc/1/fd |wc -l")
say "finit: number of open file descriptors before test: $num"
say "Add $type stanza to $FINIT_CONF"
texec sh -c "echo $service > $FINIT_CONF"
say 'Reload Finit'
texec sh -c "initctl reload"
sleep 1
texec sh -c "initctl status serv"
assert_status "serv" "running"
sleep 2
texec sh -c "initctl cond dump"
assert_cond "service/serv/ready"
say "Verify 'ready' is set after SIGHUP ..."
texec sh -c "initctl reload serv"
sleep 2
assert_status "serv" "running"
assert_cond "service/serv/ready"
texec sh -c "initctl stop serv"
sleep 1
assert_status "serv" "stopped"
assert_nocond "service/serv/ready"
# sleep 2
# num=$(texec sh -c "find /proc/1/fd |wc -l")
# say "finit: number of open file descriptors after test: $num"
}
# shellcheck source=/dev/null
. "$TEST_DIR/tenv/lib.sh"
texec sh -c "initctl debug"
test_one "s6" "service log:stdout notify:s6 serv -np -N %n -- s6 readiness"
test_one "systemd" "service log:stdout notify:systemd serv -np -- systemd readiness"
test_one "s6" "service log:stdout notify:s6 serv -np -N %n -- s6 readiness"
test_one "systemd" "service log:stdout notify:systemd serv -np -- systemd readiness"
test_one "s6" "service log:stdout notify:s6 serv -np -N %n -- s6 readiness"
test_one "systemd" "service log:stdout notify:systemd serv -np -- systemd readiness"
test_one "s6" "service log:stdout notify:s6 serv -np -N %n -- s6 readiness"
test_one "systemd" "service log:stdout notify:systemd serv -np -- systemd readiness"
return 0
+20
View File
@@ -52,6 +52,25 @@ assert_desc()
assert "Service description == $1" "$(texec initctl status "$2" | grep 'Description' | sed 's/Description : //')" = "$1"
}
assert_status()
{
service=$1
status=$2
assert "Service $service $status" "$(texec initctl -p status "$service" | awk '/Status/{print $3}')" = "$status"
}
assert_cond()
{
cond=$1
assert "Condition $cond asserted" "$(texec initctl -v cond get "$cond")" = "on"
}
assert_nocond()
{
cond=$1
assert "Condition $cond cleared" "$(texec initctl -v cond get "$cond")" = "off"
}
# shellcheck disable=SC2086
assert_pidfile()
{
@@ -98,6 +117,7 @@ assert()
fi
log "$fg_green" ✔ "$__assert_msg"
return 0
}
retry()