|
|
@@ -11,14 +11,34 @@ STOP="$SCRIPT_DIR/../../skills/brainstorming/scripts/stop-server.sh"
|
|
|
SERVER="$SCRIPT_DIR/../../skills/brainstorming/scripts/server.cjs"
|
|
|
|
|
|
PASS=0; FAIL=0
|
|
|
+PIDS=()
|
|
|
+DIRS=()
|
|
|
+
|
|
|
+cleanup() {
|
|
|
+ for pid in "${PIDS[@]}"; do
|
|
|
+ kill -9 "$pid" 2>/dev/null || true
|
|
|
+ wait "$pid" 2>/dev/null || true
|
|
|
+ done
|
|
|
+ for dir in "${DIRS[@]}"; do
|
|
|
+ rm -rf "$dir"
|
|
|
+ done
|
|
|
+}
|
|
|
+trap cleanup EXIT
|
|
|
+
|
|
|
+track_dir() { DIRS+=("$1"); }
|
|
|
+track_pid() { PIDS+=("$1"); }
|
|
|
+new_server_id() {
|
|
|
+ printf 'testid%026d\n' "$RANDOM"
|
|
|
+}
|
|
|
+
|
|
|
ok() { echo " PASS: $1"; PASS=$((PASS + 1)); }
|
|
|
bad() { echo " FAIL: $1"; echo " $2"; FAIL=$((FAIL + 1)); }
|
|
|
-reap_job() { wait "$1" 2>/dev/null || true; }
|
|
|
|
|
|
# --- Test 1: an unrelated, reused PID must NOT be killed ---
|
|
|
-SESS="$(mktemp -d)"; mkdir -p "$SESS/state"
|
|
|
+SESS="$(mktemp -d)"; track_dir "$SESS"; mkdir -p "$SESS/state"
|
|
|
sleep 600 &
|
|
|
UNRELATED=$!
|
|
|
+track_pid "$UNRELATED"
|
|
|
disown "$UNRELATED" 2>/dev/null || true
|
|
|
echo "$UNRELATED" > "$SESS/state/server.pid"
|
|
|
OUT="$("$STOP" "$SESS")"
|
|
|
@@ -30,14 +50,14 @@ if kill -0 "$UNRELATED" 2>/dev/null; then
|
|
|
else
|
|
|
bad "unrelated reused PID was KILLED" "$OUT"
|
|
|
fi
|
|
|
-kill -9 "$UNRELATED" 2>/dev/null
|
|
|
-reap_job "$UNRELATED"
|
|
|
-rm -rf "$SESS"
|
|
|
|
|
|
-# --- Test 2: a real brainstorm server IS stopped ---
|
|
|
-SESS="$(mktemp -d)"; mkdir -p "$SESS/content" "$SESS/state"
|
|
|
-BRAINSTORM_DIR="$SESS" BRAINSTORM_PORT=3399 node "$SERVER" > /dev/null 2>&1 &
|
|
|
+# --- Test 2: a real brainstorm server with matching instance id IS stopped ---
|
|
|
+SESS="$(mktemp -d)"; track_dir "$SESS"; mkdir -p "$SESS/content" "$SESS/state"
|
|
|
+SERVER_ID="$(new_server_id)"
|
|
|
+printf '%s\n' "$SERVER_ID" > "$SESS/state/server-instance-id"
|
|
|
+BRAINSTORM_DIR="$SESS" BRAINSTORM_PORT=3399 node "$SERVER" "--brainstorm-server-id=$SERVER_ID" > /dev/null 2>&1 &
|
|
|
SRV=$!
|
|
|
+track_pid "$SRV"
|
|
|
disown "$SRV" 2>/dev/null || true
|
|
|
for _ in $(seq 1 40); do kill -0 "$SRV" 2>/dev/null && break; sleep 0.1; done
|
|
|
sleep 0.4
|
|
|
@@ -46,48 +66,74 @@ OUT="$("$STOP" "$SESS")"
|
|
|
sleep 0.3
|
|
|
if kill -0 "$SRV" 2>/dev/null; then
|
|
|
bad "real brainstorm server still running after stop" "$OUT"
|
|
|
- kill -9 "$SRV" 2>/dev/null
|
|
|
- reap_job "$SRV"
|
|
|
else
|
|
|
- reap_job "$SRV"
|
|
|
case "$OUT" in
|
|
|
- *stopped*) ok "real brainstorm server is stopped" ;;
|
|
|
+ *stopped*) ok "real brainstorm server with matching instance id is stopped" ;;
|
|
|
*) bad "server stopped but status was not 'stopped'" "$OUT" ;;
|
|
|
esac
|
|
|
fi
|
|
|
-rm -rf "$SESS"
|
|
|
|
|
|
# --- Test 3: no pid file ---
|
|
|
-SESS="$(mktemp -d)"; mkdir -p "$SESS/state"
|
|
|
+SESS="$(mktemp -d)"; track_dir "$SESS"; mkdir -p "$SESS/state"
|
|
|
OUT="$("$STOP" "$SESS")"
|
|
|
case "$OUT" in
|
|
|
*not_running*) ok "missing pid file reports not_running" ;;
|
|
|
*) bad "missing pid file: unexpected status" "$OUT" ;;
|
|
|
esac
|
|
|
-rm -rf "$SESS"
|
|
|
|
|
|
-# --- Test 4: a `node server.cjs` impostor NOT listening on our port is spared ---
|
|
|
-if command -v lsof > /dev/null 2>&1; then
|
|
|
- SESS="$(mktemp -d)"; mkdir -p "$SESS/state"
|
|
|
- echo '{"type":"server-started","port":3499}' > "$SESS/state/server-info" # nothing listens on 3499
|
|
|
- ( exec -a "node server.cjs" sleep 600 ) &
|
|
|
- IMPOSTOR=$!
|
|
|
- disown "$IMPOSTOR" 2>/dev/null || true
|
|
|
- echo "$IMPOSTOR" > "$SESS/state/server.pid"
|
|
|
- OUT="$("$STOP" "$SESS")"
|
|
|
- if kill -0 "$IMPOSTOR" 2>/dev/null; then
|
|
|
- case "$OUT" in
|
|
|
- *stale_pid*) ok "a node server.cjs not listening on our port is left alone" ;;
|
|
|
- *) bad "impostor survived but status was not stale_pid" "$OUT" ;;
|
|
|
- esac
|
|
|
- else
|
|
|
- bad "killed a node server.cjs that was NOT on our recorded port" "$OUT"
|
|
|
- fi
|
|
|
- kill -9 "$IMPOSTOR" 2>/dev/null
|
|
|
- reap_job "$IMPOSTOR"
|
|
|
- rm -rf "$SESS"
|
|
|
+# --- Test 4: a node server.cjs impostor with missing instance id is spared ---
|
|
|
+SESS="$(mktemp -d)"; track_dir "$SESS"; mkdir -p "$SESS/state"
|
|
|
+( exec -a "node server.cjs" sleep 600 ) &
|
|
|
+IMPOSTOR=$!
|
|
|
+track_pid "$IMPOSTOR"
|
|
|
+disown "$IMPOSTOR" 2>/dev/null || true
|
|
|
+echo "$IMPOSTOR" > "$SESS/state/server.pid"
|
|
|
+OUT="$("$STOP" "$SESS")"
|
|
|
+if kill -0 "$IMPOSTOR" 2>/dev/null; then
|
|
|
+ case "$OUT" in
|
|
|
+ *stale_pid*) ok "missing instance id leaves node server.cjs impostor alone" ;;
|
|
|
+ *) bad "impostor survived but status was not stale_pid" "$OUT" ;;
|
|
|
+ esac
|
|
|
+else
|
|
|
+ bad "killed a node server.cjs impostor with missing instance id" "$OUT"
|
|
|
+fi
|
|
|
+
|
|
|
+# --- Test 5: a node server.cjs impostor with wrong instance id is spared ---
|
|
|
+SESS="$(mktemp -d)"; track_dir "$SESS"; mkdir -p "$SESS/state"
|
|
|
+EXPECTED_ID="$(new_server_id)"
|
|
|
+WRONG_ID="$(new_server_id)"
|
|
|
+printf '%s\n' "$EXPECTED_ID" > "$SESS/state/server-instance-id"
|
|
|
+( exec -a "node server.cjs --brainstorm-server-id=$WRONG_ID" sleep 600 ) &
|
|
|
+IMPOSTOR=$!
|
|
|
+track_pid "$IMPOSTOR"
|
|
|
+disown "$IMPOSTOR" 2>/dev/null || true
|
|
|
+echo "$IMPOSTOR" > "$SESS/state/server.pid"
|
|
|
+OUT="$("$STOP" "$SESS")"
|
|
|
+if kill -0 "$IMPOSTOR" 2>/dev/null; then
|
|
|
+ case "$OUT" in
|
|
|
+ *stale_pid*) ok "wrong instance id leaves node server.cjs impostor alone" ;;
|
|
|
+ *) bad "wrong-id impostor survived but status was not stale_pid" "$OUT" ;;
|
|
|
+ esac
|
|
|
+else
|
|
|
+ bad "killed a node server.cjs impostor with wrong instance id" "$OUT"
|
|
|
+fi
|
|
|
+
|
|
|
+# --- Test 6: malformed instance id is fail-closed ---
|
|
|
+SESS="$(mktemp -d)"; track_dir "$SESS"; mkdir -p "$SESS/state"
|
|
|
+printf '%s\n' 'bad id with spaces' > "$SESS/state/server-instance-id"
|
|
|
+( exec -a "node server.cjs --brainstorm-server-id=bad-id-with-spaces" sleep 600 ) &
|
|
|
+IMPOSTOR=$!
|
|
|
+track_pid "$IMPOSTOR"
|
|
|
+disown "$IMPOSTOR" 2>/dev/null || true
|
|
|
+echo "$IMPOSTOR" > "$SESS/state/server.pid"
|
|
|
+OUT="$("$STOP" "$SESS")"
|
|
|
+if kill -0 "$IMPOSTOR" 2>/dev/null; then
|
|
|
+ case "$OUT" in
|
|
|
+ *stale_pid*) ok "malformed instance id is fail-closed" ;;
|
|
|
+ *) bad "malformed-id impostor survived but status was not stale_pid" "$OUT" ;;
|
|
|
+ esac
|
|
|
else
|
|
|
- echo " SKIP: lsof unavailable — port cross-check test"
|
|
|
+ bad "killed process despite malformed instance id" "$OUT"
|
|
|
fi
|
|
|
|
|
|
echo "--- Results: $PASS passed, $FAIL failed ---"
|