rats

RAdix iniT Suite
git clone https://git.daat.foo/repos/rats.git
Log | Files | Refs | README | LICENSE

run.sh (5691B)


      1 #!/bin/sh
      2 # tests/run.sh: integration test for serva + svc
      3 #
      4 # Copies ./ssv into a sandbox and drives serva with svc-test.
      5 # No root needed: everything lives under tests/.
      6 
      7 set -u
      8 cd "$(dirname "$0")"
      9 
     10 SANDBOX="$PWD/sandbox/$$"
     11 SOCK="$SANDBOX/serva.sock"
     12 SERVA="$SANDBOX/serva-test"
     13 SVC="$SANDBOX/svc-test"
     14 LOG="$SANDBOX/serva.log"
     15 CONTROL_PROBE="$SANDBOX/control-test"
     16 export CONTROL_PROBE
     17 PASS=0
     18 FAIL=0
     19 
     20 say()  { printf '%s\n' "$*"; }
     21 ok()   { PASS=$((PASS + 1)); say "ok   - $1"; }
     22 bad()  { FAIL=$((FAIL + 1)); say "FAIL - $1"; }
     23 
     24 cleanup() {
     25 	if [ -n "${SERVA_PID:-}" ]; then
     26 		kill "$SERVA_PID" 2>/dev/null
     27 		wait "$SERVA_PID" 2>/dev/null
     28 	fi
     29 	rm -f "$SOCK"
     30 }
     31 trap cleanup 0
     32 trap 'exit 1' HUP INT TERM
     33 
     34 # --- setup sandbox -----------------------------------------------------------
     35 umask 077
     36 mkdir -p "$PWD/sandbox" || exit 1
     37 mkdir "$SANDBOX" || exit 1
     38 cp -R ssv "$SANDBOX/ssv" || exit 1
     39 
     40 for i in 1 2 3 4 5 6 7 8; do
     41 	service="$SANDBOX/ssv/default/status$i"
     42 	mkdir -p "$service/need" "$service/after" || exit 1
     43 	cp ssv/default/oneshot/run "$service/run" || exit 1
     44 	touch "$service/down"
     45 	for j in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16; do
     46 		dep=$(printf 'dep%02d_%057d' "$j" 0)
     47 		touch "$service/need/$dep" "$service/after/$dep"
     48 	done
     49 done
     50 
     51 mkdir "$SANDBOX/ssv/default/fdprobe" || exit 1
     52 cat > "$SANDBOX/ssv/default/fdprobe/run" <<'EOF'
     53 #!/bin/sh
     54 "$CONTROL_PROBE" >probe.out
     55 exec sleep 30
     56 EOF
     57 cat > "$SANDBOX/ssv/default/fdprobe/log" <<'EOF'
     58 #!/bin/sh
     59 "$CONTROL_PROBE" >logger.out
     60 exec cat >/dev/null
     61 EOF
     62 touch "$SANDBOX/ssv/default/fdprobe/down" "$SANDBOX/ssv/default/fdprobe/once"
     63 chmod +x "$SANDBOX/ssv/default/fdprobe/run" "$SANDBOX/ssv/default/fdprobe/log"
     64 
     65 # --- build + launch ----------------------------------------------------------
     66 "${MAKE:-make}" -s TEST_DIR="$SANDBOX" all || { say "build failed"; exit 1; }
     67 
     68 (umask 000; exec "$SERVA") >"$LOG" 2>&1 &
     69 SERVA_PID=$!
     70 
     71 for i in 1 2 3 4 5 6 7 8 9 10; do
     72 	[ -S "$SOCK" ] && break
     73 	sleep 1
     74 done
     75 [ -S "$SOCK" ] || { bad "serva socket never appeared"; exit 1; }
     76 sleep 2   # let services start and crashme restart
     77 
     78 # --- tests -------------------------------------------------------------------
     79 out=$("$SVC" -s)
     80 case $out in
     81 *default/sleeper*RUN*) ok "svc -s lists sleeper as RUN" ;;
     82 *) bad "svc -s should show sleeper RUN, got: $out" ;;
     83 esac
     84 
     85 out=$("$SVC" -s sleeper)
     86 case $out in
     87 *sleeper*RUN*runs=1*) ok "svc -s <name> shows single service with runs=1" ;;
     88 *) bad "svc -s sleeper unexpected: $out" ;;
     89 esac
     90 
     91 out=$("$SVC" -s crashme)
     92 case $out in
     93 *exit=42*) ok "svc -s crashme records exit code 42" ;;
     94 *) bad "svc -s crashme missing exit=42: $out" ;;
     95 esac
     96 
     97 out=$("$SVC" -s crashme)
     98 runs=$(printf '%s' "$out" | sed -n 's/.*runs=\([0-9]*\).*/\1/p')
     99 [ "${runs:-0}" -ge 2 ] && ok "crashme restarted with backoff (runs=$runs)" \
    100 	|| bad "crashme should have restarted, runs=${runs:-?}"
    101 
    102 out=$("$SVC" -s depender)
    103 case $out in
    104 *RUN*) ok "depender started once sleeper was running" ;;
    105 *) bad "depender should be RUN after dep met: $out" ;;
    106 esac
    107 
    108 out=$("$SVC" -s oneshot)
    109 case $out in
    110 *DONE*) ok "oneshot reports DONE after exit" ;;
    111 *) bad "oneshot should be DONE: $out" ;;
    112 esac
    113 
    114 out=$("$SVC" -d sleeper 2>&1) && sleep 1 && out=$("$SVC" -s sleeper)
    115 case $out in
    116 *DOWN*) ok "svc -d brings sleeper down" ;;
    117 *) bad "sleeper should be DOWN after svc -d: $out" ;;
    118 esac
    119 
    120 out=$("$SVC" -s depender)
    121 case $out in
    122 *WAIT*) ok "depender cascades to WAIT when sleeper stops" ;;
    123 *) bad "depender should be WAIT after sleeper down: $out" ;;
    124 esac
    125 
    126 "$SVC" -u sleeper >/dev/null && sleep 1
    127 out=$("$SVC" -s depender)
    128 case $out in
    129 *RUN*) ok "depender restarts when dep comes back" ;;
    130 *) bad "depender should be RUN again: $out" ;;
    131 esac
    132 
    133 out=$("$SVC" -s nosuchsvc 2>&1)
    134 case $out in
    135 *ERR*) ok "svc -s on unknown service returns ERR" ;;
    136 *) bad "expected ERR for unknown service: $out" ;;
    137 esac
    138 
    139 out=$("$SVC" -r sleeper 2>&1) && sleep 1
    140 runs=$("$SVC" -s sleeper | sed -n 's/.*runs=\([0-9]*\).*/\1/p')
    141 [ "${runs:-0}" -ge 2 ] && ok "svc -r restarts sleeper (runs=$runs)" \
    142 	|| bad "svc -r did not restart sleeper: runs=${runs:-?}"
    143 
    144 out=$("$SVC" -s)
    145 rows=$(printf '%s\n' "$out" | sed -n '/default\/status[1-8]/p' | wc -l)
    146 [ "$rows" -eq 8 ] && ok "large status response includes every service" \
    147 	|| bad "large status response lost services: rows=$rows"
    148 
    149 longname=$(printf '%05000d' 0)
    150 if out=$("$SVC" -u "$longname" 2>&1); then
    151 	bad "oversized service name should fail"
    152 else
    153 	case $out in
    154 	*'command too long'*) ok "oversized service name is rejected safely" ;;
    155 	*) bad "unexpected error for oversized service name: $out" ;;
    156 	esac
    157 fi
    158 
    159 out=$("$SVC" -s sleeper depender)
    160 case $out in
    161 *default/sleeper*RUN*default/depender*RUN*) ok "svc handles multiple service names" ;;
    162 *) bad "svc did not return both services: $out" ;;
    163 esac
    164 
    165 if "$SVC" -s nosuchsvc >/dev/null; then
    166 	bad "unknown service should return failure"
    167 else
    168 	ok "unknown service returns failure"
    169 fi
    170 
    171 "$CONTROL_PROBE" -mode && ok "control socket has mode 0600 under umask 000" \
    172 	|| bad "control socket permissions are too broad"
    173 
    174 "$SVC" -u fdprobe >/dev/null
    175 sleep 1
    176 for file in probe.out logger.out; do
    177 	out=$(cat "$SANDBOX/ssv/default/fdprobe/$file" 2>/dev/null)
    178 	case $out in
    179 	'OK: no supervisor descriptors inherited') ok "$file: supervisor descriptors closed and SIGPIPE restored" ;;
    180 	*) bad "$file: unexpected inherited state: $out" ;;
    181 	esac
    182 done
    183 
    184 if "$CONTROL_PROBE" -disconnect && "$SVC" -s sleeper >/dev/null; then
    185 	ok "serva survives a client disconnect during its response"
    186 else
    187 	bad "serva died after a client disconnected"
    188 fi
    189 
    190 # --- summary -----------------------------------------------------------------
    191 say ""
    192 say "passed: $PASS  failed: $FAIL"
    193 say "test files: $SANDBOX"
    194 [ "$FAIL" -eq 0 ]