Dev ci #1
@@ -0,0 +1,223 @@
|
|||||||
|
#!/usr/bin/env bats
|
||||||
|
#
|
||||||
|
# Behavioral tests for entrypoint.sh.
|
||||||
|
#
|
||||||
|
# Strategy: run the real entrypoint.sh (real socat/nc, no mocks) against a
|
||||||
|
# throwaway TCP target and a scratch socket directory, so what's exercised
|
||||||
|
# matches production exactly. UNIX-LISTEN binds immediately without the TCP
|
||||||
|
# target being reachable, so TARGET_HOST/TARGET_PORT can safely point at
|
||||||
|
# nothing for most tests.
|
||||||
|
#
|
||||||
|
# Process PIDs are looked up on demand via `pgrep -f` against a unique,
|
||||||
|
# per-test path/name rather than captured with `$!` — under bats-core's own
|
||||||
|
# subshell/job-control plumbing, `$!` does not reliably resolve to the
|
||||||
|
# process actually started here.
|
||||||
|
|
||||||
|
setup() {
|
||||||
|
TEST_DIR="$(mktemp -d)"
|
||||||
|
cp "$BATS_TEST_DIRNAME/../entrypoint.sh" "$TEST_DIR/"
|
||||||
|
cp "$BATS_TEST_DIRNAME/../VERSION" "$TEST_DIR/"
|
||||||
|
chmod +x "$TEST_DIR/entrypoint.sh"
|
||||||
|
|
||||||
|
export TARGET_HOST=127.0.0.1
|
||||||
|
export TARGET_PORT=1
|
||||||
|
export UNIX_SOCKET_NAME="test-$BATS_TEST_NUMBER.sock"
|
||||||
|
export UNIX_SOCKET_PATH="$TEST_DIR/socket"
|
||||||
|
export HOST_SOCKET_PATH="$TEST_DIR/host"
|
||||||
|
unset DEBUG_LEVEL
|
||||||
|
}
|
||||||
|
|
||||||
|
teardown() {
|
||||||
|
pkill -9 -f "$TEST_DIR/entrypoint.sh" 2>/dev/null
|
||||||
|
pkill -9 -f "UNIX-LISTEN:.*$UNIX_SOCKET_NAME" 2>/dev/null
|
||||||
|
pkill -9 -f "nc .*34599" 2>/dev/null
|
||||||
|
rm -rf "$TEST_DIR"
|
||||||
|
}
|
||||||
|
|
||||||
|
run_entrypoint_bg() {
|
||||||
|
LOG="$TEST_DIR/out.log"
|
||||||
|
( cd "$TEST_DIR" && exec ./entrypoint.sh >"$LOG" 2>&1 ) &
|
||||||
|
disown 2>/dev/null || true
|
||||||
|
}
|
||||||
|
|
||||||
|
entrypoint_pid() {
|
||||||
|
pgrep -f "$TEST_DIR/entrypoint.sh" | head -n1
|
||||||
|
}
|
||||||
|
|
||||||
|
socat_pid() {
|
||||||
|
pgrep -f "UNIX-LISTEN:.*$UNIX_SOCKET_NAME" | head -n1
|
||||||
|
}
|
||||||
|
|
||||||
|
wait_for_log() {
|
||||||
|
pattern="$1"
|
||||||
|
tries=0
|
||||||
|
while [ "$tries" -lt 20 ]; do
|
||||||
|
grep -qE "$pattern" "$LOG" 2>/dev/null && return 0
|
||||||
|
tries=$((tries + 1))
|
||||||
|
sleep 0.25
|
||||||
|
done
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
wait_for_pid_gone() {
|
||||||
|
pid="$1"
|
||||||
|
tries=0
|
||||||
|
while kill -0 "$pid" 2>/dev/null && [ "$tries" -lt 20 ]; do
|
||||||
|
tries=$((tries + 1))
|
||||||
|
sleep 0.25
|
||||||
|
done
|
||||||
|
! kill -0 "$pid" 2>/dev/null
|
||||||
|
}
|
||||||
|
|
||||||
|
# ---- Environment variable validation -------------------------------------
|
||||||
|
|
||||||
|
@test "fails when TARGET_HOST is missing" {
|
||||||
|
unset TARGET_HOST
|
||||||
|
run "$TEST_DIR/entrypoint.sh"
|
||||||
|
[ "$status" -eq 1 ]
|
||||||
|
[[ "$output" == *"TARGET_HOST environment variable is required"* ]]
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "fails when TARGET_PORT is missing" {
|
||||||
|
unset TARGET_PORT
|
||||||
|
run "$TEST_DIR/entrypoint.sh"
|
||||||
|
[ "$status" -eq 1 ]
|
||||||
|
[[ "$output" == *"TARGET_PORT environment variable is required"* ]]
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "fails when UNIX_SOCKET_NAME is missing" {
|
||||||
|
unset UNIX_SOCKET_NAME
|
||||||
|
run "$TEST_DIR/entrypoint.sh"
|
||||||
|
[ "$status" -eq 1 ]
|
||||||
|
[[ "$output" == *"UNIX_SOCKET_NAME environment variable is required"* ]]
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "fails when UNIX_SOCKET_PATH is missing" {
|
||||||
|
unset UNIX_SOCKET_PATH
|
||||||
|
run "$TEST_DIR/entrypoint.sh"
|
||||||
|
[ "$status" -eq 1 ]
|
||||||
|
[[ "$output" == *"UNIX_SOCKET_PATH environment variable is required"* ]]
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "fails when HOST_SOCKET_PATH is missing" {
|
||||||
|
unset HOST_SOCKET_PATH
|
||||||
|
run "$TEST_DIR/entrypoint.sh"
|
||||||
|
[ "$status" -eq 1 ]
|
||||||
|
[[ "$output" == *"HOST_SOCKET_PATH environment variable is required"* ]]
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "prints the version banner from the VERSION file" {
|
||||||
|
echo "9.9.9" > "$TEST_DIR/VERSION"
|
||||||
|
run_entrypoint_bg
|
||||||
|
wait_for_log "Socat socket is active|Socat socket not found"
|
||||||
|
grep -q "Version 9.9.9" "$LOG"
|
||||||
|
}
|
||||||
|
|
||||||
|
# ---- Socket path preparation ----------------------------------------------
|
||||||
|
|
||||||
|
@test "removes a pre-existing file at the socket path before starting" {
|
||||||
|
mkdir -p "$UNIX_SOCKET_PATH"
|
||||||
|
touch "$UNIX_SOCKET_PATH/$UNIX_SOCKET_NAME"
|
||||||
|
run_entrypoint_bg
|
||||||
|
wait_for_log "Socat socket is active|Socat socket not found"
|
||||||
|
grep -q "exists, removing it" "$LOG"
|
||||||
|
grep -q "Removed existing socket" "$LOG"
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "creates the socket directory when it does not exist" {
|
||||||
|
[ ! -d "$UNIX_SOCKET_PATH" ]
|
||||||
|
run_entrypoint_bg
|
||||||
|
wait_for_log "Socat socket is active|Socat socket not found"
|
||||||
|
grep -q "Created directory $UNIX_SOCKET_PATH" "$LOG"
|
||||||
|
[ -d "$UNIX_SOCKET_PATH" ]
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "reports the socat-created socket as active once it is listening" {
|
||||||
|
run_entrypoint_bg
|
||||||
|
wait_for_log "Socat socket is active|Socat socket not found"
|
||||||
|
grep -q "Socat socket is active" "$LOG"
|
||||||
|
[ -S "$UNIX_SOCKET_PATH/$UNIX_SOCKET_NAME" ]
|
||||||
|
}
|
||||||
|
|
||||||
|
# ---- Target connectivity check (informational, non-fatal) -----------------
|
||||||
|
|
||||||
|
@test "warns but continues when the TCP target is unreachable" {
|
||||||
|
export TARGET_PORT=1
|
||||||
|
run_entrypoint_bg
|
||||||
|
wait_for_log "Socat socket is active|Socat socket not found"
|
||||||
|
grep -q "Cannot connect to $TARGET_HOST:$TARGET_PORT" "$LOG"
|
||||||
|
grep -q "Container is ready and running" "$LOG"
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "reports success when the TCP target is reachable" {
|
||||||
|
( nc -l 127.0.0.1 34599 >/dev/null 2>&1 & )
|
||||||
|
disown 2>/dev/null || true
|
||||||
|
sleep 0.3
|
||||||
|
export TARGET_PORT=34599
|
||||||
|
run_entrypoint_bg
|
||||||
|
wait_for_log "Socat socket is active|Socat socket not found"
|
||||||
|
grep -q "Connection to $TARGET_HOST:$TARGET_PORT is working" "$LOG"
|
||||||
|
}
|
||||||
|
|
||||||
|
# ---- Debug level -> socat flags mapping -----------------------------------
|
||||||
|
|
||||||
|
@test "maps an unset DEBUG_LEVEL default of 1 to a single -d flag" {
|
||||||
|
run_entrypoint_bg
|
||||||
|
wait_for_log "Using debug level"
|
||||||
|
grep -q "Using debug level: 1 (-d)" "$LOG"
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "maps DEBUG_LEVEL=2 to two -d flags" {
|
||||||
|
export DEBUG_LEVEL=2
|
||||||
|
run_entrypoint_bg
|
||||||
|
wait_for_log "Using debug level"
|
||||||
|
grep -q "Using debug level: 2 (-d -d)" "$LOG"
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "maps DEBUG_LEVEL=3 to three -d flags" {
|
||||||
|
export DEBUG_LEVEL=3
|
||||||
|
run_entrypoint_bg
|
||||||
|
wait_for_log "Using debug level"
|
||||||
|
grep -q "Using debug level: 3 (-d -d -d)" "$LOG"
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "maps an unrecognized DEBUG_LEVEL to no debug flags" {
|
||||||
|
export DEBUG_LEVEL=0
|
||||||
|
run_entrypoint_bg
|
||||||
|
wait_for_log "Using debug level"
|
||||||
|
grep -q "Using debug level: 0 ()" "$LOG"
|
||||||
|
}
|
||||||
|
|
||||||
|
# ---- Shutdown behavior ------------------------------------------------------
|
||||||
|
|
||||||
|
@test "shuts down gracefully and stops socat on SIGTERM" {
|
||||||
|
run_entrypoint_bg
|
||||||
|
wait_for_log "Socat socket is active|Socat socket not found"
|
||||||
|
|
||||||
|
ep_pid="$(entrypoint_pid)"
|
||||||
|
sc_pid="$(socat_pid)"
|
||||||
|
[ -n "$ep_pid" ]
|
||||||
|
[ -n "$sc_pid" ]
|
||||||
|
|
||||||
|
kill -TERM "$ep_pid"
|
||||||
|
wait_for_pid_gone "$ep_pid"
|
||||||
|
|
||||||
|
grep -q "Received SIGTERM, shutting down gracefully" "$LOG"
|
||||||
|
grep -q "Cleanup completed, exiting" "$LOG"
|
||||||
|
! kill -0 "$sc_pid" 2>/dev/null
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "exits 1 once socat's process dies unexpectedly" {
|
||||||
|
run_entrypoint_bg
|
||||||
|
wait_for_log "Socat socket is active|Socat socket not found"
|
||||||
|
|
||||||
|
ep_pid="$(entrypoint_pid)"
|
||||||
|
sc_pid="$(socat_pid)"
|
||||||
|
[ -n "$ep_pid" ]
|
||||||
|
[ -n "$sc_pid" ]
|
||||||
|
|
||||||
|
kill -9 "$sc_pid"
|
||||||
|
wait_for_pid_gone "$ep_pid"
|
||||||
|
|
||||||
|
grep -q "Socat process has stopped" "$LOG"
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user