From fa05a5f8238e9e1417235711656e5062ccc843a7 Mon Sep 17 00:00:00 2001 From: "info@mode42.com" Date: Fri, 7 Aug 2026 18:23:28 +0000 Subject: Initial push --- scripts/test-wizard.sh | 113 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 113 insertions(+) create mode 100755 scripts/test-wizard.sh (limited to 'scripts/test-wizard.sh') diff --git a/scripts/test-wizard.sh b/scripts/test-wizard.sh new file mode 100755 index 0000000..e75a401 --- /dev/null +++ b/scripts/test-wizard.sh @@ -0,0 +1,113 @@ +#!/usr/bin/env bash +# test-wizard.sh — non-interactive smoke test for max25-lite-setup.sh. +# +# Drives the wizard through all three modem paths (serial, baycom, crdop) +# using a mock `whiptail` on PATH that answers canned responses, then checks +# the generated max25d.ini / crdop.ini / max25-bcpr.ini files are well formed. +# No sudo, no hardware, no PTT — local ./local/ destination only. +set -euo pipefail + +ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +WIZARD="${ROOT}/scripts/max25-lite-setup.sh" +WORKDIR="$(mktemp -d)" +ERR=0 + +ok() { echo "PASS: $*"; } +fail() { echo "FAIL: $*" >&2; ERR=1; } + +cleanup() { rm -rf "$WORKDIR"; } +trap cleanup EXIT + +mock_bin="${WORKDIR}/bin" +mkdir -p "$mock_bin" + +# Mock whiptail: reads canned answers from $WHIPTAIL_ANSWERS (newline list, one +# per --menu/--radiolist/--inputbox/--yesno call, in call order). --msgbox is a +# no-op (informational only). Mirrors the 3>&1 1>&2 2>&3 capture convention: +# the "answer" goes to this script's stderr; exit 0 means OK/Yes. +cat >"${mock_bin}/whiptail" <<'MOCK' +#!/usr/bin/env bash +mode="" +for a in "$@"; do + case "$a" in + --msgbox) mode=msgbox ;; + --yesno) mode=yesno ;; + --inputbox) mode=inputbox ;; + --menu) mode=menu ;; + --radiolist) mode=radiolist ;; + esac +done +[[ "$mode" == "msgbox" ]] && exit 0 +answers_file="${WHIPTAIL_ANSWERS:?WHIPTAIL_ANSWERS not set}" +answer="$(head -n1 "$answers_file")" +tail -n +2 "$answers_file" > "${answers_file}.next" +mv "${answers_file}.next" "$answers_file" +if [[ "$mode" == "yesno" ]]; then + [[ "$answer" == "yes" ]] && exit 0 || exit 1 +fi +echo "$answer" >&2 +exit 0 +MOCK +chmod +x "${mock_bin}/whiptail" + +# Mock arecord/aplay: force the "no ALSA cards" branch deterministically, +# independent of the host's actual sound hardware, so the CRDOP path always +# takes the same code path in this smoke test. +for tool in arecord aplay; do + cat >"${mock_bin}/${tool}" <<'MOCK' +#!/usr/bin/env bash +exit 1 +MOCK + chmod +x "${mock_bin}/${tool}" +done + +run_path() { + local label="$1" answers="$2" ini_glob="$3" want_grep="$4" + local answers_file="${WORKDIR}/answers-${label}" + printf '%s\n' "$answers" > "$answers_file" + rm -rf "${ROOT}/local/max25d.ini" "${ROOT}/local/crdop.ini" "${ROOT}/local/max25-bcpr.ini" + if PATH="${mock_bin}:${PATH}" WHIPTAIL_ANSWERS="$answers_file" \ + bash "$WIZARD" "${WORKDIR}/out-${label}.log" 2>&1; then + if [[ -f "${ROOT}/local/max25d.ini" ]] && grep -q "$want_grep" "${ROOT}/local/max25d.ini"; then + ok "wizard ${label} path: max25d.ini written (${want_grep})" + else + fail "wizard ${label} path: max25d.ini missing or unexpected content" + cat "${WORKDIR}/out-${label}.log" >&2 + fi + else + fail "wizard ${label} path: exited non-zero" + cat "${WORKDIR}/out-${label}.log" >&2 + fi + rm -rf "${ROOT}/local/max25d.ini" "${ROOT}/local/crdop.ini" "${ROOT}/local/max25-bcpr.ini" +} + +# serial: menu=serial, radiolist=/dev/ttyUSB0, callerid, callid, save-location=no (local) +run_path "serial" "serial +/dev/ttyUSB0 +CB-0 +QST +no" "local/max25d.ini" "device = tnc2c" + +# baycom: menu=baycom, radiolist=/dev/ttyS0 (or whatever first port is), callerid, callid, no +run_path "baycom" "baycom +$(bash -c ' + shopt -s nullglob + ports=(/dev/ttyUSB* /dev/ttyACM* /dev/ttyS*) + shopt -u nullglob + echo "${ports[0]:-/dev/ttyUSB0}" +') +CB-0 +QST +no" "local/max25d.ini" "device = max25e0" + +# crdop: menu=crdop, [radiolist ALSA device only if arecord/aplay found any — assume +# none in CI so wizard shows an informational msgbox and uses hw:0,0 defaults], callerid, callid, no +run_path "crdop" "crdop +CB-0 +QST +no" "local/max25d.ini" "device = soft-crdop" + +if [[ "$ERR" -eq 0 ]]; then + echo "OK: wizard non-interactive smoke (serial / baycom / crdop)" +fi +exit "$ERR" -- cgit v1.3.1