feat(station): Tasterdienst per deploy.sh/setup_pi.sh ausliefern
This commit is contained in:
@@ -58,6 +58,7 @@ echo "STUB scp \$*" >>"$log"
|
||||
for a in "\$@"; do
|
||||
case "\$a" in
|
||||
*ninlight-display) [ -n "\${FAKE_SCP_SKIP_DIR:-}" ] && exit 0 ;;
|
||||
*ninlight-button) [ -n "\${FAKE_SCP_SKIP_BUTTON_DIR:-}" ] && exit 0 ;;
|
||||
esac
|
||||
done
|
||||
args=()
|
||||
@@ -141,7 +142,19 @@ EOF
|
||||
#!/usr/bin/env bash
|
||||
echo "STUB systemctl \$*" >>"$log"
|
||||
# Testschalter: laesst "enable"/"restart" scheitern (beides darf setup_pi.sh nur
|
||||
# warnen lassen, nie abbrechen).
|
||||
# warnen lassen, nie abbrechen). Der Taster hat eigene Schalter (FAKE_BUTTON_*), damit
|
||||
# ein Szenario NUR ihn scheitern lassen kann, ohne die Anzeige mitzureissen - sonst
|
||||
# liesse sich nicht zeigen, dass ein fehlgeschlagenes enable/start des Tasters fuer
|
||||
# sich genommen keinen Abbruch ausloest.
|
||||
case "\$*" in
|
||||
*ninlight-button*)
|
||||
case "\$1" in
|
||||
enable) exit "\${FAKE_BUTTON_ENABLE_EXIT:-0}" ;;
|
||||
restart) exit "\${FAKE_BUTTON_RESTART_EXIT:-0}" ;;
|
||||
*) exit 0 ;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
case "\$1" in
|
||||
enable) exit "\${FAKE_SYSTEMCTL_ENABLE_EXIT:-0}" ;;
|
||||
restart) exit "\${FAKE_SYSTEMCTL_RESTART_EXIT:-0}" ;;
|
||||
@@ -202,6 +215,7 @@ run_setup() {
|
||||
NINLIGHT_STATION_BIN="$state/usr/local/bin/ninlight-station" \
|
||||
NINLIGHT_STATION_UNIT="$state/etc/systemd/system/ninlight-station.service" \
|
||||
NINLIGHT_DISPLAY_UNIT="$state/etc/systemd/system/ninlight-display.service" \
|
||||
NINLIGHT_BUTTON_UNIT="$state/etc/systemd/system/ninlight-button.service" \
|
||||
NINLIGHT_NM_DIR="$state/etc/NetworkManager/system-connections" \
|
||||
NINLIGHT_BOOT_CONFIG_NEW="$state/boot/firmware/config.txt" \
|
||||
NINLIGHT_BOOT_CONFIG_OLD="$state/boot/config.txt" \
|
||||
@@ -906,6 +920,133 @@ grep -Fqx "dtparam=spi=on" "$CONFIG27" && pass "die Zeile wurde trotzdem aktivie
|
||||
[ "$(cat "${CONFIG27}.bak-ninlight")" = "urspruenglicher-originalzustand" ] && pass "die bestehende Sicherung blieb unangetastet" || fail "die Sicherung wurde ueberschrieben: $(cat "${CONFIG27}.bak-ninlight")"
|
||||
echo "$OUT" | grep -q "existiert bereits - wird nicht ueberschrieben" && pass "Ausgabe erwaehnt, dass die Sicherung nicht ueberschrieben wurde" || fail "keine entsprechende Meldung: $OUT"
|
||||
|
||||
echo
|
||||
echo "=== Szenario 28 (Task 8b): Taster wird ausgeliefert, installiert und aktiviert ==="
|
||||
STATE="$TMPROOT/s28-state"; STUBBIN="$TMPROOT/bin28"; LOG="$TMPROOT/s28.log"
|
||||
setup_state "$STATE"
|
||||
setup_stubbin "$STUBBIN" "$LOG"
|
||||
: >"$LOG"
|
||||
set +e
|
||||
OUT=$(run_setup "$STATE" "$STUBBIN" 2>&1)
|
||||
RC=$?
|
||||
set -e
|
||||
[ "$RC" -eq 0 ] && pass "Exit-Code 0" || fail "Exit-Code $RC, Ausgabe: $OUT"
|
||||
BTN28="$STATE/opt/ninlight-station/button"
|
||||
[ -f "$BTN28/button.py" ] && pass "button/button.py ausgeliefert" || fail "button/button.py fehlt unter $BTN28"
|
||||
[ -x "$BTN28/button.py" ] && pass "button.py ist ausfuehrbar" || fail "button.py ist nicht ausfuehrbar"
|
||||
[ ! -d "$BTN28/__pycache__" ] && pass "kein __pycache__ auf dem Pi gelandet" || fail "__pycache__ wurde mitkopiert"
|
||||
[ -f "$STATE/etc/systemd/system/ninlight-button.service" ] && pass "ninlight-button.service installiert" || fail "Taster-Unit fehlt - sie waere weiter toter Text im Repo"
|
||||
grep -Fq "systemctl enable ninlight-button.service" "$LOG" && pass "Tasterdienst wurde aktiviert" || fail "kein 'systemctl enable ninlight-button' im Log"
|
||||
grep -Fq "systemctl restart ninlight-button.service" "$LOG" && pass "Tasterdienst wurde gestartet" || fail "kein 'systemctl restart ninlight-button' im Log"
|
||||
# Die Station selbst bleibt weiterhin aus - derselbe Sicherheitsfehler waere hier
|
||||
# genauso schwerwiegend wie in Szenario 5.
|
||||
grep -Fq "systemctl enable ninlight-station" "$LOG" && fail "setup_pi.sh aktiviert den Stationsdienst" || pass "Stationsdienst bleibt deaktiviert"
|
||||
|
||||
echo
|
||||
echo "=== Szenario 29 (Task 8b): Reststand in der Ablage fuehrt beim Taster nicht zu einer stillen Nullinstallation ==="
|
||||
# Dasselbe Muster wie Szenario 11 fuer die Anzeige, hier fuer button/: ein
|
||||
# liegengebliebenes "…/ninlight-button/" laesst ein "scp -r" hineinkopieren statt
|
||||
# darauf, die Installationsschleife faende dann nichts.
|
||||
STATE="$TMPROOT/s29-state"; STUBBIN="$TMPROOT/bin29"; LOG="$TMPROOT/s29.log"
|
||||
setup_state "$STATE"
|
||||
setup_stubbin "$STUBBIN" "$LOG"
|
||||
mkdir -p "$STATE/tmp/ninlight-button"
|
||||
echo "rest" >"$STATE/tmp/ninlight-button/uebrig.py"
|
||||
: >"$LOG"
|
||||
set +e
|
||||
OUT=$(run_setup "$STATE" "$STUBBIN" 2>&1)
|
||||
RC=$?
|
||||
set -e
|
||||
[ "$RC" -eq 0 ] && pass "Exit-Code 0" || fail "Exit-Code $RC, Ausgabe: $OUT"
|
||||
BTN29="$STATE/opt/ninlight-station/button"
|
||||
[ -f "$BTN29/button.py" ] && pass "button.py trotz Reststand installiert" || fail "Nullinstallation: $BTN29 enthaelt $(ls -A "$BTN29" 2>/dev/null | tr '\n' ' ')"
|
||||
[ ! -d "$BTN29/button" ] && pass "kein verschachteltes button/button/ entstanden" || fail "verschachteltes Verzeichnis angelegt"
|
||||
[ ! -f "$BTN29/uebrig.py" ] && pass "der Reststand des Vorlaufs wurde nicht mitinstalliert" || fail "uebrig.py aus dem Reststand landete auf dem Pi"
|
||||
|
||||
echo
|
||||
echo "=== Szenario 30 (Task 8b): scheitert die Uebertragung des Tastercodes, wird laut abgebrochen ==="
|
||||
STATE="$TMPROOT/s30-state"; STUBBIN="$TMPROOT/bin30"; LOG="$TMPROOT/s30.log"
|
||||
setup_state "$STATE"
|
||||
setup_stubbin "$STUBBIN" "$LOG"
|
||||
: >"$LOG"
|
||||
set +e
|
||||
OUT=$(FAKE_SCP_SKIP_BUTTON_DIR=1 run_setup "$STATE" "$STUBBIN" 2>&1)
|
||||
RC=$?
|
||||
set -e
|
||||
[ "$RC" -ne 0 ] && pass "Exit-Code != 0" || fail "Exit-Code 0 trotz fehlgeschlagener Uebertragung: $OUT"
|
||||
echo "$OUT" | grep -q "button.py fehlt" && pass "Fehlermeldung nennt die fehlende Datei" || fail "Fehlermeldung fehlt: $OUT"
|
||||
grep -Fq "systemctl enable ninlight-button" "$LOG" && fail "der Tasterdienst wurde trotz fehlender Dateien aktiviert" || pass "kein aktivierter Tasterdienst ohne Dateien"
|
||||
for F in "$STATE/opt/ninlight-station/server.py" "$STATE/opt/ninlight-station/products.py" \
|
||||
"$STATE/usr/local/bin/ninlight-station" \
|
||||
"$STATE/etc/systemd/system/ninlight-station.service" \
|
||||
"$STATE/etc/systemd/system/ninlight-display.service" \
|
||||
"$STATE/etc/systemd/system/ninlight-button.service"; do
|
||||
[ ! -e "$F" ] && pass "wirklich nicht installiert: $(basename "$F")" || fail "die Meldung luegt - $F liegt auf dem Pi"
|
||||
done
|
||||
REST30=$(find "$STATE/tmp" -mindepth 1 2>/dev/null | head -n5)
|
||||
[ -z "$REST30" ] && pass "die Ablage wurde auch im Fehlerfall aufgeraeumt" || fail "Reststand in der Ablage: $REST30"
|
||||
|
||||
echo
|
||||
echo "=== Szenario 31 (Task 8b): eine im Repo geloeschte Datei verschwindet auch aus button/ auf dem Pi ==="
|
||||
STATE="$TMPROOT/s31-state"; STUBBIN="$TMPROOT/bin31"; LOG="$TMPROOT/s31.log"
|
||||
setup_state "$STATE"
|
||||
setup_stubbin "$STUBBIN" "$LOG"
|
||||
mkdir -p "$STATE/opt/ninlight-station/button"
|
||||
echo "alt" >"$STATE/opt/ninlight-station/button/veraltet.py"
|
||||
: >"$LOG"
|
||||
set +e
|
||||
OUT=$(run_setup "$STATE" "$STUBBIN" 2>&1)
|
||||
RC=$?
|
||||
set -e
|
||||
[ "$RC" -eq 0 ] && pass "Exit-Code 0" || fail "Exit-Code $RC, Ausgabe: $OUT"
|
||||
[ ! -f "$STATE/opt/ninlight-station/button/veraltet.py" ] && pass "veraltete Datei entfernt" || fail "veraltet.py blieb liegen"
|
||||
[ -f "$STATE/opt/ninlight-station/button/button.py" ] && pass "der aktuelle Code ist trotzdem da" || fail "button.py fehlt"
|
||||
|
||||
echo
|
||||
echo "=== Szenario 32 (Task 8b): ein fehlgeschlagenes enable/restart NUR des Tasterdienstes warnt und bricht nicht ab ==="
|
||||
# Eigene Schalter (FAKE_BUTTON_*), damit die Anzeige dabei unbeteiligt bleibt - das
|
||||
# zeigt, dass der Taster fuer sich genommen keine Voraussetzung ist.
|
||||
STATE="$TMPROOT/s32-state"; STUBBIN="$TMPROOT/bin32"; LOG="$TMPROOT/s32.log"
|
||||
setup_state "$STATE"
|
||||
setup_stubbin "$STUBBIN" "$LOG"
|
||||
: >"$LOG"
|
||||
set +e
|
||||
OUT=$(FAKE_BUTTON_ENABLE_EXIT=1 FAKE_BUTTON_RESTART_EXIT=1 run_setup "$STATE" "$STUBBIN" 2>"$TMPROOT/s32.err")
|
||||
RC=$?
|
||||
set -e
|
||||
ERR=$(cat "$TMPROOT/s32.err")
|
||||
[ "$RC" -eq 0 ] && pass "Exit-Code 0 trotz fehlgeschlagenem enable/restart des Tasters" || fail "Exit-Code $RC: $ERR"
|
||||
echo "$ERR" | grep -q "systemctl enable ninlight-button" && pass "Warnung zu 'enable' auf stderr" || fail "keine enable-Warnung: $ERR"
|
||||
echo "$ERR" | grep -q "systemctl restart ninlight-button" && pass "Warnung zu 'restart' auf stderr" || fail "keine restart-Warnung: $ERR"
|
||||
grep -Fq "systemctl enable ninlight-display.service" "$LOG" && pass "die Anzeige wurde trotzdem aktiviert - der Taster reisst sie nicht mit" || fail "die Anzeige-Aktivierung blieb aus"
|
||||
[ -f "$STATE/etc/NetworkManager/system-connections/qconnex-firmware.nmconnection" ] && pass "der Lauf ging danach normal weiter (Profile angelegt)" || fail "der Lauf brach nach der Warnung ab"
|
||||
|
||||
echo
|
||||
echo "=== Szenario 33 (Task 8b): ein zweiter Lauf ist ein echtes No-Op ==="
|
||||
# Idempotenz ist die Kopfzusage von setup_pi.sh (siehe Kommentar am Dateianfang) - hier
|
||||
# konkret fuer den neu hinzugekommenen Taster geprueft: ein zweiter Lauf auf einem
|
||||
# bereits eingerichteten Pi darf button/ und dessen Unit nicht veraendern.
|
||||
STATE="$TMPROOT/s33-state"; STUBBIN="$TMPROOT/bin33"; LOG="$TMPROOT/s33.log"
|
||||
setup_state "$STATE"
|
||||
setup_stubbin "$STUBBIN" "$LOG"
|
||||
: >"$LOG"
|
||||
set +e
|
||||
run_setup "$STATE" "$STUBBIN" >/dev/null 2>&1
|
||||
RC1=$?
|
||||
set -e
|
||||
[ "$RC1" -eq 0 ] || fail "erster Lauf schon fehlgeschlagen (rc=$RC1)"
|
||||
SUM_BEFORE=$(find "$STATE/opt/ninlight-station/button" "$STATE/etc/systemd/system/ninlight-button.service" -type f -exec cksum {} \; | sort)
|
||||
: >"$LOG"
|
||||
set +e
|
||||
OUT=$(run_setup "$STATE" "$STUBBIN" 2>&1)
|
||||
RC2=$?
|
||||
set -e
|
||||
[ "$RC2" -eq 0 ] && pass "zweiter Lauf: Exit-Code 0" || fail "zweiter Lauf: Exit-Code $RC2, Ausgabe: $OUT"
|
||||
SUM_AFTER=$(find "$STATE/opt/ninlight-station/button" "$STATE/etc/systemd/system/ninlight-button.service" -type f -exec cksum {} \; | sort)
|
||||
[ "$SUM_BEFORE" = "$SUM_AFTER" ] && pass "button/ und die Taster-Unit sind nach dem zweiten Lauf byte-identisch" || fail "der zweite Lauf hat etwas an button/ veraendert"
|
||||
grep -Fq "systemctl enable ninlight-button.service" "$LOG" && pass "der zweite Lauf aktiviert den Tasterdienst erneut (idempotent, kein Fehler)" || fail "kein erneutes 'systemctl enable ninlight-button' im zweiten Lauf"
|
||||
echo "$OUT" | grep -q "veraltete Datei entfernt: button/" && fail "der zweite Lauf meldet eine veraltete Datei, obwohl nichts geloescht wurde" || pass "keine falsche 'veraltete Datei entfernt'-Meldung im zweiten Lauf"
|
||||
|
||||
echo
|
||||
if [ "$FAILED" -eq 0 ]; then
|
||||
echo "Alle Tests bestanden."
|
||||
|
||||
Reference in New Issue
Block a user