Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 18 additions & 1 deletion tests/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,19 @@ Which shutdown path the run exercises:
> A green **`abend`** run does **not** establish the `#179` fix — it tests a
> different path. Use **`longpoll`** to gate `#179` (mvslovers/mvsmf#179).

The easiest way to drive this is the bundled runner
(`tests/run-shutdown-longpoll.sh`) — a file, so there is no fragile multi-line
shell command to mis-paste:

```sh
CONSOLE_LOG=/path/to/hardcopy.log sh tests/run-shutdown-longpoll.sh check # setup check, no P HTTPD
CONSOLE_LOG=/path/to/hardcopy.log sh tests/run-shutdown-longpoll.sh # real run, prompts for P HTTPD
```

It reads API credentials from `HTTPD_AUTH` or from `MBT_MVS_USER`/`MBT_MVS_PASS`
in `./.env`, and uses a non-matching `unsol-key` so the workers stay parked; see
the script header for all knobs. To build the poll request by hand instead:

Example `LONGPOLL_CMD` — one synchronous unsolicited-message detection PUT that
blocks up to 60 s (mvsMF console **issue-command** endpoint,
`PUT /zosmf/restconsoles/consoles/{console-name}` — *not* the `/solmsgs` collect
Expand All @@ -56,10 +69,14 @@ sub-resource):
```sh
LONGPOLL_CMD='curl -s -o /dev/null -u USER:PASS -X PUT \
-H "Content-Type: application/json" \
-d "{\"cmd\":\"D T\",\"unsol-key\":\"IEE136I\",\"unsol-detect-sync\":\"Y\",\"unsol-detect-timeout\":\"60\"}" \
-d "{\"cmd\":\"D T\",\"unsol-key\":\"ZZNOMATCHZZ\",\"unsol-detect-sync\":\"Y\",\"unsol-detect-timeout\":\"60\"}" \
http://HOST:PORT/zosmf/restconsoles/consoles/defcn'
```

> `unsol-key` must be a token that will **not** appear during the poll — do
> **not** use one the command's own response emits (`D T` emits `IEE136I`), or
> detection fires immediately and the worker never parks (→ INCONCLUSIVE).

The long poll must **still be running when `P HTTPD` is issued** — that is the
whole point. The in-flight count is measured `LONGPOLL_SETTLE` s after launch,
but the stop lands later. In `STOP_ADAPTER=cmd` mode the stop follows
Expand Down
61 changes: 61 additions & 0 deletions tests/run-shutdown-longpoll.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
#!/bin/sh
# Convenience runner for tests/shutdown-acceptance.sh in longpoll mode
# (mvsmf#179 / httpd#122). It parks concurrent long-polls so a worker is still
# in flight when P HTTPD lands -- the scenario a fast handler fault cannot
# reproduce, and the only one that actually exercises the #179 quiesce fix.
#
# It is a FILE on purpose: no interactive multi-line command whose line
# continuation a stray space after a backslash can silently break.
#
# Usage:
# sh tests/run-shutdown-longpoll.sh real run: prompts for P HTTPD
# sh tests/run-shutdown-longpoll.sh check non-interactive setup check
# (no P HTTPD; confirms polls park)
#
# Configure via environment (all optional except CONSOLE_LOG + credentials):
# CONSOLE_LOG REQUIRED: MVS console/hardcopy log the test asserts over.
# HTTPD_HOST HTTPD listener host (default: localhost)
# HTTPD_PORT HTTPD listener port (default: 8080)
# CONSOLE_NAME z/OSMF console name (default: defcn)
# HTTPD_AUTH API creds "user:pass"; if unset, falls back to
# MBT_MVS_USER / MBT_MVS_PASS from ./.env
# JOBNAME HTTPD STC jobname (default: HTTPD)
# LONGPOLL_N concurrent long-polls (<= MAXTASK-1) (default: 4)
# LONGPOLL_SETTLE seconds to let them park (default: 3)
set -u

HOST="${HTTPD_HOST:-localhost}"
PORT="${HTTPD_PORT:-8080}"
CONSOLE="${CONSOLE_NAME:-defcn}"
: "${CONSOLE_LOG:?set CONSOLE_LOG to the MVS console/hardcopy log path}"

# API auth: HTTPD_AUTH=user:pass, else the deploy creds from ./.env.
if [ -z "${HTTPD_AUTH:-}" ]; then
[ -f ./.env ] && . ./.env # './' so dash reads the CWD, not $PATH
HTTPD_AUTH="${MBT_MVS_USER:?set HTTPD_AUTH, or MBT_MVS_USER in .env}:${MBT_MVS_PASS:?set HTTPD_AUTH, or MBT_MVS_PASS in .env}"
fi

# JSON body via a temp file -> no quoting nightmare in LONGPOLL_CMD. The unsol-key
# must NOT occur during the poll (do not use a key the command itself emits), so
# the worker blocks the full unsol-detect-timeout and is still parked at P HTTPD.
body=$(mktemp)
trap 'rm -f "$body"' EXIT INT TERM
cat > "$body" <<'JSON'
{"cmd":"D T","unsol-key":"ZZNOMATCHZZ","unsol-detect-sync":"Y","unsol-detect-timeout":"60"}
JSON

export ENV_FILE=/dev/null # config resolved above; skip the test's own .env source
export CONSOLE_LOG
export HTTPD_HOST="$HOST" HTTPD_PORT="$PORT"
export JOBNAME="${JOBNAME:-HTTPD}"
export PROVOKE=longpoll
export LONGPOLL_N="${LONGPOLL_N:-4}"
export LONGPOLL_SETTLE="${LONGPOLL_SETTLE:-3}"
export LONGPOLL_CMD="curl -s -o /dev/null -u $HTTPD_AUTH -X PUT -H 'Content-Type: application/json' -d @$body http://$HOST:$PORT/zosmf/restconsoles/consoles/$CONSOLE"

if [ "${1:-}" = check ]; then # non-interactive: prove the polls park, no real stop
export STOP_ADAPTER=cmd STOP_CMD=true WAIT_SECS="${WAIT_SECS:-2}"
fi

dir=$(dirname "$0")
sh "$dir/shutdown-acceptance.sh"
14 changes: 12 additions & 2 deletions tests/shutdown-acceptance.sh
Original file line number Diff line number Diff line change
Expand Up @@ -100,9 +100,19 @@
set -u

# --- load .env if present (for HTTPD_HOST default only) ---------------------
if [ -f "${ENV_FILE:-.env}" ]; then
# The `.` (dot) builtin searches $PATH when its operand has NO slash — so a bare
# ".env" is looked up in $PATH, not the CWD. Under dash a not-found `.` is a
# special-builtin error that ABORTS a non-interactive shell (silent RC 2 once the
# message is hidden). Force a slash so it is read from the given path, and don't
# swallow errors. Set ENV_FILE=/dev/null to skip sourcing entirely.
env_file="${ENV_FILE:-.env}"
case "$env_file" in
*/*) : ;; # already path-qualified
*) env_file="./$env_file" ;;
esac
if [ -f "$env_file" ]; then
# shellcheck disable=SC1090
. "${ENV_FILE:-.env}" 2>/dev/null || true
. "$env_file" || true
fi

HTTPD_HOST=${HTTPD_HOST:-${MBT_MVS_HOST:-127.0.0.1}}
Expand Down