From 10ad46eb7377ff504a65783a7a604b248b50f20a Mon Sep 17 00:00:00 2001
From: Ed Santiago <santiago@redhat.com>
Date: Wed, 1 Jul 2020 13:43:38 -0600
Subject: BATS system tests for new sdnotify

Signed-off-by: Ed Santiago <santiago@redhat.com>
---
 test/system/260-sdnotify.bats | 142 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 142 insertions(+)
 create mode 100644 test/system/260-sdnotify.bats

diff --git a/test/system/260-sdnotify.bats b/test/system/260-sdnotify.bats
new file mode 100644
index 000000000..c37eea15a
--- /dev/null
+++ b/test/system/260-sdnotify.bats
@@ -0,0 +1,142 @@
+#!/usr/bin/env bats   -*- bats -*-
+#
+# Tests for systemd sdnotify
+#
+
+load helpers
+
+# Shared throughout this module: PID of socat process, and path to its log
+_SOCAT_PID=
+_SOCAT_LOG=
+
+function setup() {
+    skip_if_remote
+
+    # TODO: remove this once CI systems have newer crun and container-selinux
+    skip "TEMPORARY SKIP - until CI systems get new crun, container-selinux"
+
+    basic_setup
+}
+
+function teardown() {
+    unset NOTIFY_SOCKET
+
+    _stop_socat
+
+    basic_teardown
+}
+
+###############################################################################
+# BEGIN helpers
+
+# Run socat process on a socket, logging to well-known path. Each received
+# packet is logged with a newline appended, for ease of parsing the log file.
+function _start_socat() {
+    _SOCAT_LOG="$PODMAN_TMPDIR/socat.log"
+
+    rm -f $_SOCAT_LOG
+    socat unix-recvfrom:"$NOTIFY_SOCKET",fork \
+          system:"(cat;echo) >> $_SOCAT_LOG" &
+    _SOCAT_PID=$!
+}
+
+# Stop the socat background process and clean up logs
+function _stop_socat() {
+    if [[ -n "$_SOCAT_PID" ]]; then
+        kill $_SOCAT_PID
+    fi
+    _SOCAT_PID=
+
+    if [[ -n "$_SOCAT_LOG" ]]; then
+        rm -f $_SOCAT_LOG
+    fi
+}
+
+# Check that MAINPID=xxxxx points to a running conmon process
+function _assert_mainpid_is_conmon() {
+    local mainpid=$(expr "$1" : "MAINPID=\([0-9]\+\)")
+    test -n "$mainpid" || die "Could not parse '$1' as 'MAINPID=nnnn'"
+
+    test -d /proc/$mainpid || die "sdnotify MAINPID=$mainpid - but /proc/$mainpid does not exist"
+
+    # e.g. /proc/12345/exe -> /usr/bin/conmon
+    local mainpid_bin=$(readlink /proc/$mainpid/exe)
+    is "$mainpid_bin" ".*/conmon" "sdnotify MAINPID=$mainpid is conmon process"
+}
+
+# END   helpers
+###############################################################################
+# BEGIN tests themselves
+
+@test "sdnotify : ignore" {
+    export NOTIFY_SOCKET=$PODMAN_TMPDIR/ignore.sock
+    _start_socat
+
+    run_podman 1 run --rm --sdnotify=ignore $IMAGE printenv NOTIFY_SOCKET
+    is "$output" "" "\$NOTIFY_SOCKET in container"
+
+    is "$(< $_SOCAT_LOG)" "" "nothing received on socket"
+    _stop_socat
+}
+
+@test "sdnotify : conmon" {
+    export NOTIFY_SOCKET=$PODMAN_TMPDIR/conmon.sock
+    _start_socat
+
+    run_podman run -d --name sdnotify_conmon_c \
+               --sdnotify=conmon \
+               $IMAGE \
+               sh -c 'printenv NOTIFY_SOCKET;echo READY;while ! test -f /stop;do sleep 0.1;done'
+    cid="$output"
+    wait_for_ready $cid
+
+    run_podman logs sdnotify_conmon_c
+    is "$output" "READY" "\$NOTIFY_SOCKET in container"
+
+    run cat $_SOCAT_LOG
+    is "${lines[-1]}" "READY=1" "final output from sdnotify"
+
+    _assert_mainpid_is_conmon "${lines[0]}"
+
+    # Done. Stop container, clean up.
+    run_podman exec $cid touch /stop
+    run_podman rm $cid
+    _stop_socat
+}
+
+@test "sdnotify : container" {
+    # Sigh... we need to pull a humongous image because it has systemd-notify.
+    # FIXME: is there a smaller image we could use?
+    _FEDORA=registry.fedoraproject.org/fedora:latest
+
+    # Pull that image. Retry in case of flakes.
+    run_podman pull $_FEDORA || \
+        run_podman pull $_FEDORA || \
+        run_podman pull $_FEDORA
+
+    export NOTIFY_SOCKET=$PODMAN_TMPDIR/container.sock
+    _start_socat
+
+    run_podman run -d --sdnotify=container $_FEDORA \
+               sh -c 'printenv NOTIFY_SOCKET;echo READY;systemd-notify --ready;while ! test -f /stop;do sleep 0.1;done'
+    cid="$output"
+    wait_for_ready $cid
+
+    run_podman logs $cid
+    is "${lines[0]}" "/.*/container\.sock/notify" "NOTIFY_SOCKET is passed to container"
+
+    # With container, READY=1 isn't necessarily the last message received;
+    # just look for it anywhere in received messages
+    run cat $_SOCAT_LOG
+    is "$output" ".*READY=1" "received READY=1 through notify socket"
+
+    _assert_mainpid_is_conmon "${lines[0]}"
+
+    # Done. Stop container, clean up.
+    run_podman exec $cid touch /stop
+    run_podman rm $cid
+    run_podman rmi $_FEDORA
+    _stop_socat
+}
+
+# vim: filetype=sh
-- 
cgit v1.2.3-54-g00ecf