# First set BROKER_SOURCE_DIR and BROKER_RUNBOOK_DIR to the values
# printed by the startup terminal.
: "${BROKER_SOURCE_DIR:?Set BROKER_SOURCE_DIR to the printed source directory.}"
: "${BROKER_RUNBOOK_DIR:?Set BROKER_RUNBOOK_DIR to the printed runbook workspace.}"
export BROKER_CLUSTER_DIR="$BROKER_RUNBOOK_DIR/cluster"
export BROKER_DIAG_FILE="$BROKER_RUNBOOK_DIR/diagnostics.json"
test -f "$BROKER_RUNBOOK_DIR/.stornamics-message-broker-runbook"
test -d "$BROKER_CLUSTER_DIR"
export BROKER_ENDPOINT=http://127.0.0.1:9101
export BROKER_STREAM=source record.ops
export BROKER_GROUP=source record-workers
export BROKER_CONSUMER=source record-reader
Expected signal
The printed source and runbook workspace are accepted, and endpoint, stream, consumer, cluster, and diagnostics values are set.
Capture: Source revision, endpoint, stream, consumer group, runbook workspace, cluster path, and diagnostics path.
curl -i -X PUT \
-H 'Content-Type: application/json' \
--data '{}' \
"$BROKER_ENDPOINT/v1/streams/$BROKER_STREAM"
Expected signal
201 Created or 200 OK with stream metadata for the scoped smoke stream.
Capture: Status, stream name, response body, and route.
curl -i -X POST \
-H 'Content-Type: application/json' \
--data '{"message_id":"source record-1","payload":"operator-smoke","durability_mode":"local-append"}' \
"$BROKER_ENDPOINT/v1/streams/$BROKER_STREAM/records"
Expected signal
201 Created with offset, next offset, message id, and payload byte count.
Capture: Status, offset, message id, payload byte count, and stream name.
curl -i "$BROKER_ENDPOINT/health"
Expected signal
200 OK JSON with status, service, node id, storage status, auth mode, and release metadata.
Capture: Status, selected node, auth mode, storage status, and timestamp.
curl -i "$BROKER_ENDPOINT/metrics"
Expected signal
200 OK text when HTTP metrics exposure is enabled; 404 metrics_disabled means this runtime did not expose metrics.
Capture: Status, response body header, startup metrics flag, and exporter configuration.
curl -i "$BROKER_ENDPOINT/v1/audit/events?start_offset=0&max_records=25"
Expected signal
200 OK JSON with parsed audit events and record metadata when auth permits the administrator route.
Capture: Status, page parameters, event count, and redacted route names.
curl -i "$BROKER_ENDPOINT/v1/audit/export?start_offset=0&max_records=25"
Expected signal
200 OK application/x-ndjson with one payload-free audit record per line when auth permits the route.
Capture: Status, content type, record count, and redacted line sample.
mq cli --target "$BROKER_ENDPOINT" diagnostics collect \
--bundle-id source record-local \
--output "$BROKER_DIAG_FILE"
Expected signal
Diagnostics bundle JSON is written without payload contents.
Capture: Bundle path, schema/version field, redaction summary, and command status.
curl -i "$BROKER_ENDPOINT/streams/$BROKER_STREAM/retention/dry-run?max_bytes=1048576"
Expected signal
200 OK with a non-mutating retention plan.
Capture: Stream, policy input, planned action summary, and timestamp.
curl -i "$BROKER_ENDPOINT/streams/$BROKER_STREAM/tiering/readiness?max_age_ms=86400000"
Expected signal
200 OK with payload-free tiering readiness.
Capture: Readiness fields, stream, policy input, and timestamp.
curl -i "$BROKER_ENDPOINT/v1/streams/$BROKER_STREAM/records?start_offset=0&max_records=10&consumer_group=$BROKER_GROUP&consumer_id=$BROKER_CONSUMER"
Expected signal
200 OK with records, diagnostics, next offset, and end-of-stream signal.
Capture: Status, returned record count, consumer group, and redacted message ids.
curl -i "$BROKER_ENDPOINT/v1/replication/status"
Expected signal
200 OK with scheduler, transport, worker, checkpoint, target, or control status fields where configured.
Capture: Status, configured binding source, route body, and operator note.
# This permanently deletes the printed workspace, including cluster data,
# logs, and the diagnostics bundle. Retain it instead if evidence is still needed.
: "${BROKER_SOURCE_DIR:?Set BROKER_SOURCE_DIR to the printed source directory.}"
: "${BROKER_RUNBOOK_DIR:?Set BROKER_RUNBOOK_DIR to the printed runbook workspace.}"
: "${BROKER_CLUSTER_DIR:?Set BROKER_CLUSTER_DIR from BROKER_RUNBOOK_DIR.}"
: "${BROKER_DIAG_FILE:?Set BROKER_DIAG_FILE from BROKER_RUNBOOK_DIR.}"
expected_prefix="${TMPDIR:-/tmp}/message-broker-runbook-"
case "$BROKER_RUNBOOK_DIR" in
"$expected_prefix"*) ;;
*)
printf 'Refusing to remove unexpected Message Broker workspace: %s
' "$BROKER_RUNBOOK_DIR" >&2
exit 1
;;
esac
if [ "$BROKER_CLUSTER_DIR" != "$BROKER_RUNBOOK_DIR/cluster" ] || [ "$BROKER_DIAG_FILE" != "$BROKER_RUNBOOK_DIR/diagnostics.json" ]; then
printf 'Refusing Message Broker cleanup with mismatched runbook paths.
' >&2
exit 1
fi
if [ ! -f "$BROKER_RUNBOOK_DIR/.stornamics-message-broker-runbook" ] || ! grep -qx 'message-broker-operator-runbook-v1' "$BROKER_RUNBOOK_DIR/.stornamics-message-broker-runbook"; then
printf 'Refusing Message Broker cleanup without the runbook ownership marker: %s
' "$BROKER_RUNBOOK_DIR" >&2
exit 1
fi
if [ ! -f "$BROKER_SOURCE_DIR/Support/Stop-LocalCluster.sh" ]; then
printf 'Cannot find the Message Broker stop helper under: %s
' "$BROKER_SOURCE_DIR" >&2
exit 1
fi
if ! STORNAMICS_LOCAL_CLUSTER_DIR="$BROKER_CLUSTER_DIR" bash "$BROKER_SOURCE_DIR/Support/Stop-LocalCluster.sh"; then
printf 'Message Broker shutdown failed; retaining workspace: %s
' "$BROKER_RUNBOOK_DIR" >&2
exit 1
fi
for node_number in 1 2 3; do
node_id="local-$node_number"
port=$((9100 + node_number))
pid_file="$BROKER_CLUSTER_DIR/pids/node-$node_number.pid"
if [ -e "$pid_file" ]; then
printf 'Message Broker shutdown left a PID file; retaining workspace: %s
' "$pid_file" >&2
exit 1
fi
response="$(curl -sS --max-time 1 "http://127.0.0.1:$port/health" 2>&1 || true)"
if [[ "$response" == *'"service":"stornamics-message-broker"'* && "$response" == *""node_id":"$node_id""* ]]; then
printf 'Message Broker node still responds on port %s; retaining workspace.
' "$port" >&2
exit 1
fi
done
rm -rf -- "$BROKER_RUNBOOK_DIR"
Expected signal
The product stop helper stops all three recorded nodes, shutdown verification passes, and only the guarded runbook workspace is removed.
Capture: Stop-helper output and the retained workspace path before cleanup; do not run removal while evidence is still needed.