server.py bedient jetzt zwei Modi ueber denselben Dienst: --mode/--mode-file/--control legen fest, ob ninlight_<target>_ota.img (Rettung) oder qcx_firmware_<pid>_..._ota_light.img (Migration alter Klyqa-Lampen, via products.parse_request) ausgeliefert wird. Der Modus kommt wahlweise aus einer Datei statt einem Startparameter, damit Task 4 ihn spaeter ohne Dienst-Neustart umschalten kann. Die Steuerdatei control.json (Phase auto/listen/armed) wird bei jeder Anfrage frisch gelesen und atomar mit 0644 geschrieben - eine fehlende oder kaputte Steuerdatei blockiert eine Migration nie, sondern faellt auf "auto" zurueck. Nach einer erfolgreichen Auslieferung in Phase "armed" faellt die Freigabe erst nach dem vollstaendigen Senden auf "listen" zurueck, nie davor, damit ein abgebrochener Transfer die Freigabe fuer den naechsten Bootversuch stehen laesst. status.json bekommt die Migrationsfelder aus Spec 5.2 (mode, phase, armed_target, last_seen). deploy.sh liefert products.py mit aus, sonst startet der Dienst nach dem naechsten Deploy mit ModuleNotFoundError; test_deploy.sh zieht die Sandbox-Dummy-Datei entsprechend nach. Neue Tests in test_server.py verwenden eigene server/migration_server-Fixtures samt Testklient (get/status/set_control/read_control/delete_control/write_raw_control), ohne die bestehende station-Fixture und ihre Tests anzufassen.
367 lines
14 KiB
Bash
Executable File
367 lines
14 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Stub-Tests fuer deploy.sh - ohne Pi ausfuehrbar.
|
|
#
|
|
# ssh/rsync werden im PATH durch Stubs ersetzt: ssh fuehrt das per Heredoc
|
|
# uebergebene Remote-Skript lokal aus (statt es an einen echten Pi zu
|
|
# schicken), rsync uebersetzt "host:pfad"-Ziele auf den blossen lokalen Pfad
|
|
# und ruft dann den echten rsync auf. So laeuft die komplette Logik von
|
|
# deploy.sh - inklusive des Installationsschritts, der normalerweise per SSH
|
|
# auf dem Pi passiert - tatsaechlich, aber vollstaendig gegen ein Sandbox-
|
|
# Verzeichnis (NINLIGHT_STATION_ROOT/…) statt gegen echte Systempfade.
|
|
#
|
|
# Aufruf: tools/station/tests/test_deploy.sh
|
|
set -euo pipefail
|
|
|
|
HERE=$(cd "$(dirname "$0")" && pwd)
|
|
STATION_DIR=$(cd "$HERE/.." && pwd)
|
|
REAL_RSYNC=$(command -v rsync)
|
|
|
|
TMPROOT=$(mktemp -d)
|
|
trap 'rm -rf "$TMPROOT"' EXIT
|
|
|
|
FAILED=0
|
|
pass() { echo "ok - $1"; }
|
|
fail() { echo "FEHLER - $1" >&2; FAILED=1; }
|
|
|
|
# --- Sandbox-Repo aufbauen: tools/station/deploy.sh + tools/mkimage/nl_mkimage.py + build/ ---
|
|
setup_sandbox() {
|
|
local sandbox=$1
|
|
rm -rf "$sandbox"
|
|
mkdir -p "$sandbox/tools/station" "$sandbox/tools/mkimage" "$sandbox/build"
|
|
cp "$STATION_DIR/deploy.sh" "$sandbox/tools/station/deploy.sh"
|
|
chmod +x "$sandbox/tools/station/deploy.sh"
|
|
# Inhalt irrelevant, die Dateien muessen nur existieren (werden "uebertragen").
|
|
echo "# dummy" >"$sandbox/tools/station/server.py"
|
|
echo "# dummy" >"$sandbox/tools/station/products.py"
|
|
echo "# dummy" >"$sandbox/tools/station/ninlight-station"
|
|
echo "# dummy" >"$sandbox/tools/station/ninlight-station.service"
|
|
|
|
# Fake nl_mkimage.py --verify: verhaelt sich wie das echte Tool (eine Zeile
|
|
# "<geraet> <version> <bytes>" auf stdout bei Erfolg, Exit 0; eine Zeile auf
|
|
# stderr bei Fehlschlag, Exit 1), aber steuerbar per Umgebungsvariable
|
|
# MKIMAGE_FAIL_SUBSTR: enthaelt der zu pruefende Dateiname diesen Teilstring,
|
|
# schlaegt die Pruefung fehl.
|
|
cat >"$sandbox/tools/mkimage/nl_mkimage.py" <<'PY'
|
|
import os
|
|
import sys
|
|
|
|
args = sys.argv[1:]
|
|
f = args[args.index("--verify") + 1]
|
|
target = args[args.index("--expect-device") + 1]
|
|
fail_substr = os.environ.get("MKIMAGE_FAIL_SUBSTR", "")
|
|
if fail_substr and fail_substr in f:
|
|
print(f"Fehler: {f} besteht die Trailer-Pruefung nicht (Test-Stub)", file=sys.stderr)
|
|
sys.exit(1)
|
|
size = os.path.getsize(f)
|
|
print(f"{target} 1.0.0 {size}")
|
|
PY
|
|
}
|
|
|
|
# --- Stub-Kommandos fuer ssh/rsync im PATH ---
|
|
setup_stubbin() {
|
|
local bindir=$1 log=$2
|
|
mkdir -p "$bindir"
|
|
|
|
cat >"$bindir/ssh" <<EOF
|
|
#!/usr/bin/env bash
|
|
echo "STUB ssh \$*" >>"$log"
|
|
host=\$1; shift
|
|
"\$@"
|
|
EOF
|
|
|
|
cat >"$bindir/rsync" <<EOF
|
|
#!/usr/bin/env bash
|
|
echo "STUB rsync \$*" >>"$log"
|
|
args=()
|
|
for a in "\$@"; do
|
|
case "\$a" in
|
|
-*) args+=("\$a") ;;
|
|
*:*) args+=("\${a#*:}") ;;
|
|
*) args+=("\$a") ;;
|
|
esac
|
|
done
|
|
exec "$REAL_RSYNC" "\${args[@]}"
|
|
EOF
|
|
|
|
cat >"$bindir/scp" <<EOF
|
|
#!/usr/bin/env bash
|
|
echo "STUB scp \$* - deploy.sh sollte scp nicht aufrufen" >>"$log"
|
|
exit 1
|
|
EOF
|
|
|
|
cat >"$bindir/sudo" <<EOF
|
|
#!/usr/bin/env bash
|
|
echo "STUB sudo \$*" >>"$log"
|
|
exec "\$@"
|
|
EOF
|
|
|
|
cat >"$bindir/systemctl" <<EOF
|
|
#!/usr/bin/env bash
|
|
echo "STUB systemctl \$*" >>"$log"
|
|
case "\$1" in
|
|
is-active) exit "\${FAKE_SYSTEMCTL_ACTIVE_EXIT:-1}" ;;
|
|
restart) exit "\${FAKE_SYSTEMCTL_RESTART_EXIT:-0}" ;;
|
|
*) exit 0 ;;
|
|
esac
|
|
EOF
|
|
|
|
chmod +x "$bindir"/ssh "$bindir"/rsync "$bindir"/scp "$bindir"/sudo "$bindir"/systemctl
|
|
}
|
|
|
|
run_deploy() {
|
|
# Fuehrt deploy.sh mit stubbtem PATH aus; Ausgabe landet in $OUT, Exit-Code in $?.
|
|
local sandbox=$1; shift
|
|
# Auf dem echten Pi existieren /usr/local/bin und /etc/systemd/system schon;
|
|
# in der Sandbox muessen sie fuer "install" eigens angelegt werden.
|
|
mkdir -p "$SANDBOX_STATE/usr/local/bin" "$SANDBOX_STATE/etc/systemd/system"
|
|
PATH="$STUBBIN:$PATH" \
|
|
NINLIGHT_SSH_BIN="$STUBBIN/ssh" \
|
|
NINLIGHT_STATION_ROOT="$SANDBOX_STATE/opt/ninlight-station" \
|
|
NINLIGHT_STATION_BIN="$SANDBOX_STATE/usr/local/bin/ninlight-station" \
|
|
NINLIGHT_STATION_UNIT="$SANDBOX_STATE/etc/systemd/system/ninlight-station.service" \
|
|
"$sandbox/tools/station/deploy.sh" "$@"
|
|
}
|
|
|
|
echo "=== Szenario 1: Image besteht die Trailer-Pruefung nicht -> nichts uebertragen ==="
|
|
SANDBOX="$TMPROOT/s1"; STUBBIN="$TMPROOT/bin1"; LOG="$TMPROOT/s1.log"; SANDBOX_STATE="$TMPROOT/s1-state"
|
|
setup_sandbox "$SANDBOX"
|
|
setup_stubbin "$STUBBIN" "$LOG"
|
|
mkdir -p "$SANDBOX/build/foo"
|
|
echo "dummy" >"$SANDBOX/build/foo/ninlight_foo_ota.img"
|
|
: >"$LOG"
|
|
set +e
|
|
OUT=$(MKIMAGE_FAIL_SUBSTR=foo run_deploy "$SANDBOX" pi-test foo 2>&1)
|
|
RC=$?
|
|
set -e
|
|
if [ "$RC" -ne 0 ]; then pass "Exit-Code != 0 ($RC)"; else fail "Exit-Code war 0"; fi
|
|
if echo "$OUT" | grep -q "besteht die Trailer-Pruefung nicht"; then
|
|
pass "Fehlermeldung zur Trailer-Pruefung vorhanden"
|
|
else
|
|
fail "Fehlermeldung zur Trailer-Pruefung fehlt"
|
|
fi
|
|
if ! grep -q "STUB ssh\|STUB rsync\|STUB scp" "$LOG"; then
|
|
pass "kein ssh/rsync/scp aufgerufen - nichts wurde uebertragen"
|
|
else
|
|
fail "ssh/rsync/scp wurde trotz fehlgeschlagener Pruefung aufgerufen: $(cat "$LOG")"
|
|
fi
|
|
|
|
echo
|
|
echo "=== Szenario 2: keine Images unter build/ gefunden ==="
|
|
SANDBOX="$TMPROOT/s2"; STUBBIN="$TMPROOT/bin2"; LOG="$TMPROOT/s2.log"; SANDBOX_STATE="$TMPROOT/s2-state"
|
|
setup_sandbox "$SANDBOX"
|
|
setup_stubbin "$STUBBIN" "$LOG"
|
|
: >"$LOG"
|
|
set +e
|
|
OUT=$(run_deploy "$SANDBOX" pi-test 2>&1)
|
|
RC=$?
|
|
set -e
|
|
if [ "$RC" -ne 0 ]; then pass "Exit-Code != 0 ($RC)"; else fail "Exit-Code war 0"; fi
|
|
if echo "$OUT" | grep -q "keine Images unter"; then
|
|
pass "Fehlermeldung zu fehlenden Images vorhanden"
|
|
else
|
|
fail "Fehlermeldung zu fehlenden Images fehlt"
|
|
fi
|
|
if ! grep -q "STUB" "$LOG" 2>/dev/null; then
|
|
pass "kein Transfer-Kommando aufgerufen"
|
|
else
|
|
fail "ein Transfer-Kommando wurde trotz fehlender Images aufgerufen: $(cat "$LOG")"
|
|
fi
|
|
|
|
echo
|
|
echo "=== Szenario 3: gezielter Deploy eines Geraetetyps laesst andere Images auf dem Ziel unangetastet (Critical 2) ==="
|
|
SANDBOX="$TMPROOT/s3"; STUBBIN="$TMPROOT/bin3"; LOG="$TMPROOT/s3.log"; SANDBOX_STATE="$TMPROOT/s3-state"
|
|
setup_sandbox "$SANDBOX"
|
|
setup_stubbin "$STUBBIN" "$LOG"
|
|
mkdir -p "$SANDBOX/build/foo" "$SANDBOX/build/bar"
|
|
echo "foo-image-neu" >"$SANDBOX/build/foo/ninlight_foo_ota.img"
|
|
echo "bar-image" >"$SANDBOX/build/bar/ninlight_bar_ota.img"
|
|
# Zielverzeichnis simuliert einen vorherigen Voll-Deploy: Images fuer foo UND bar liegen schon da.
|
|
mkdir -p "$SANDBOX_STATE/opt/ninlight-station/images"
|
|
echo "foo-image-alt" >"$SANDBOX_STATE/opt/ninlight-station/images/ninlight_foo_ota.img"
|
|
echo "bar-image" >"$SANDBOX_STATE/opt/ninlight-station/images/ninlight_bar_ota.img"
|
|
: >"$LOG"
|
|
set +e
|
|
OUT=$(run_deploy "$SANDBOX" pi-test foo 2>&1)
|
|
RC=$?
|
|
set -e
|
|
if [ "$RC" -eq 0 ]; then pass "Exit-Code 0"; else fail "Exit-Code $RC, Ausgabe: $OUT"; fi
|
|
if echo "$OUT" | grep -q "andere Geraetetypen im Zielverzeichnis bleiben erhalten"; then
|
|
pass "Ausgabe kuendigt gezielten Deploy ohne --delete an"
|
|
else
|
|
fail "Ausgabe erwaehnt den gezielten Deploy nicht"
|
|
fi
|
|
if [ -f "$SANDBOX_STATE/opt/ninlight-station/images/ninlight_bar_ota.img" ]; then
|
|
pass "Image des NICHT ausgewaehlten Geraetetyps (bar) blieb erhalten"
|
|
else
|
|
fail "Image des nicht ausgewaehlten Geraetetyps (bar) wurde geloescht - Critical 2 nicht behoben"
|
|
fi
|
|
if [ -f "$SANDBOX_STATE/opt/ninlight-station/images/ninlight_foo_ota.img" ] \
|
|
&& [ "$(cat "$SANDBOX_STATE/opt/ninlight-station/images/ninlight_foo_ota.img")" = "foo-image-neu" ]; then
|
|
pass "Image des ausgewaehlten Geraetetyps (foo) wurde aktualisiert"
|
|
else
|
|
fail "Image des ausgewaehlten Geraetetyps (foo) wurde nicht aktualisiert"
|
|
fi
|
|
|
|
echo
|
|
echo "=== Szenario 4: Voll-Deploy (kein target) entfernt veraltete Images - zur Abgrenzung von Szenario 3 ==="
|
|
SANDBOX="$TMPROOT/s4"; STUBBIN="$TMPROOT/bin4"; LOG="$TMPROOT/s4.log"; SANDBOX_STATE="$TMPROOT/s4-state"
|
|
setup_sandbox "$SANDBOX"
|
|
setup_stubbin "$STUBBIN" "$LOG"
|
|
mkdir -p "$SANDBOX/build/foo"
|
|
echo "foo-image-neu" >"$SANDBOX/build/foo/ninlight_foo_ota.img"
|
|
mkdir -p "$SANDBOX_STATE/opt/ninlight-station/images"
|
|
echo "veraltet" >"$SANDBOX_STATE/opt/ninlight-station/images/ninlight_veraltet_ota.img"
|
|
: >"$LOG"
|
|
set +e
|
|
OUT=$(run_deploy "$SANDBOX" pi-test 2>&1)
|
|
RC=$?
|
|
set -e
|
|
if [ "$RC" -eq 0 ]; then pass "Exit-Code 0"; else fail "Exit-Code $RC, Ausgabe: $OUT"; fi
|
|
if [ ! -f "$SANDBOX_STATE/opt/ninlight-station/images/ninlight_veraltet_ota.img" ]; then
|
|
pass "veraltetes Image wurde beim Voll-Deploy entfernt (--delete wirkt weiterhin, wenn gewollt)"
|
|
else
|
|
fail "veraltetes Image wurde beim Voll-Deploy NICHT entfernt"
|
|
fi
|
|
|
|
echo
|
|
echo "=== Szenario 5: Dienst laeuft, Neustart nach dem Deploy schlaegt fehl -> Exit != 0 (Minor) ==="
|
|
SANDBOX="$TMPROOT/s5"; STUBBIN="$TMPROOT/bin5"; LOG="$TMPROOT/s5.log"; SANDBOX_STATE="$TMPROOT/s5-state"
|
|
setup_sandbox "$SANDBOX"
|
|
setup_stubbin "$STUBBIN" "$LOG"
|
|
mkdir -p "$SANDBOX/build/foo" "$SANDBOX_STATE/usr/local/bin" "$SANDBOX_STATE/etc/systemd/system"
|
|
echo "foo-image" >"$SANDBOX/build/foo/ninlight_foo_ota.img"
|
|
: >"$LOG"
|
|
set +e
|
|
OUT=$(FAKE_SYSTEMCTL_ACTIVE_EXIT=0 FAKE_SYSTEMCTL_RESTART_EXIT=1 \
|
|
PATH="$STUBBIN:$PATH" \
|
|
NINLIGHT_SSH_BIN="$STUBBIN/ssh" \
|
|
NINLIGHT_STATION_ROOT="$SANDBOX_STATE/opt/ninlight-station" \
|
|
NINLIGHT_STATION_BIN="$SANDBOX_STATE/usr/local/bin/ninlight-station" \
|
|
NINLIGHT_STATION_UNIT="$SANDBOX_STATE/etc/systemd/system/ninlight-station.service" \
|
|
"$SANDBOX/tools/station/deploy.sh" pi-test foo 2>&1)
|
|
RC=$?
|
|
set -e
|
|
if [ "$RC" -ne 0 ]; then pass "Exit-Code != 0, wenn der Neustart fehlschlaegt ($RC)"; else fail "Exit-Code war 0, obwohl der Neustart fehlschlug"; fi
|
|
if echo "$OUT" | grep -q "Neustart nach dem Deploy ist aber fehlgeschlagen"; then
|
|
pass "Fehlermeldung unterscheidet Neustart-Fehlschlag von 'Dienst laeuft nicht'"
|
|
else
|
|
fail "Fehlermeldung fehlt oder ist mehrdeutig"
|
|
fi
|
|
if echo "$OUT" | grep -q "Dienst laeuft nicht"; then
|
|
fail "faelschlich 'Dienst laeuft nicht' gemeldet, obwohl der Dienst lief"
|
|
else
|
|
pass "'Dienst laeuft nicht' wird nicht faelschlich gemeldet"
|
|
fi
|
|
|
|
echo
|
|
echo "=== Szenario 6: deploy.sh/setup_pi.sh nutzen ohne Override /usr/bin/ssh (bzw. scp) ==="
|
|
# Die anderen Szenarien laufen mit NINLIGHT_SSH_BIN auf einen Stub umgebogen - das prueft die
|
|
# Logik, aber nicht mehr, WELCHEN ssh das Skript ohne Override tatsaechlich waehlt. Der Nutzer
|
|
# verlangt ausdruecklich /usr/bin/ssh und /usr/bin/scp statt einer Variante im PATH; das hier
|
|
# ist die Absicherung dagegen, dass der Default beim naechsten Umbau stillschweigend zurueck
|
|
# auf ein PATH-"ssh" rutscht.
|
|
if grep -q 'SSH_BIN=\${NINLIGHT_SSH_BIN:-/usr/bin/ssh}' "$STATION_DIR/deploy.sh"; then
|
|
pass "deploy.sh: Default fuer SSH_BIN ist /usr/bin/ssh"
|
|
else
|
|
fail "deploy.sh: Default fuer SSH_BIN ist nicht mehr /usr/bin/ssh"
|
|
fi
|
|
if grep -q 'SSH_BIN=\${NINLIGHT_SSH_BIN:-/usr/bin/ssh}' "$STATION_DIR/setup_pi.sh"; then
|
|
pass "setup_pi.sh: Default fuer SSH_BIN ist /usr/bin/ssh"
|
|
else
|
|
fail "setup_pi.sh: Default fuer SSH_BIN ist nicht mehr /usr/bin/ssh"
|
|
fi
|
|
if grep -q 'SCP_BIN=\${NINLIGHT_SCP_BIN:-/usr/bin/scp}' "$STATION_DIR/setup_pi.sh"; then
|
|
pass "setup_pi.sh: Default fuer SCP_BIN ist /usr/bin/scp"
|
|
else
|
|
fail "setup_pi.sh: Default fuer SCP_BIN ist nicht mehr /usr/bin/scp"
|
|
fi
|
|
|
|
echo
|
|
echo "=== Szenario 7: Voll-Deploy mit zwei Build-Verzeichnissen fuer denselben Dateinamen -> Abbruch (B1) ==="
|
|
SANDBOX="$TMPROOT/s7"; STUBBIN="$TMPROOT/bin7"; LOG="$TMPROOT/s7.log"; SANDBOX_STATE="$TMPROOT/s7-state"
|
|
setup_sandbox "$SANDBOX"
|
|
setup_stubbin "$STUBBIN" "$LOG"
|
|
mkdir -p "$SANDBOX/build/evk" "$SANDBOX/build/evk-onb"
|
|
echo "evk-mit-wlan" >"$SANDBOX/build/evk/ninlight_evk_ota.img"
|
|
echo "evk-ohne-wlan" >"$SANDBOX/build/evk-onb/ninlight_evk_ota.img"
|
|
: >"$LOG"
|
|
set +e
|
|
OUT=$(run_deploy "$SANDBOX" pi-test 2>&1)
|
|
RC=$?
|
|
set -e
|
|
if [ "$RC" -ne 0 ]; then pass "Exit-Code != 0 ($RC)"; else fail "Exit-Code war 0, obwohl zwei Fundorte denselben Dateinamen liefern"; fi
|
|
if echo "$OUT" | grep -q "ninlight_evk_ota.img mehrfach gefunden"; then
|
|
pass "Fehlermeldung nennt den doppelten Dateinamen"
|
|
else
|
|
fail "Fehlermeldung zum doppelten Dateinamen fehlt: $OUT"
|
|
fi
|
|
if echo "$OUT" | grep -q "build/evk/ninlight_evk_ota.img" && echo "$OUT" | grep -q "build/evk-onb/ninlight_evk_ota.img"; then
|
|
pass "Fehlermeldung nennt beide Fundorte"
|
|
else
|
|
fail "Fehlermeldung nennt nicht beide Fundorte: $OUT"
|
|
fi
|
|
if ! grep -q "STUB" "$LOG" 2>/dev/null; then
|
|
pass "kein Transfer-Kommando aufgerufen - nichts wurde stillschweigend uebertragen"
|
|
else
|
|
fail "ein Transfer-Kommando wurde trotz doppeltem Dateinamen aufgerufen: $(cat "$LOG")"
|
|
fi
|
|
|
|
echo
|
|
echo "=== Szenario 8: Voll-Deploy zeigt vor dem Loeschen, welche Images verschwinden (B2) ==="
|
|
SANDBOX="$TMPROOT/s8"; STUBBIN="$TMPROOT/bin8"; LOG="$TMPROOT/s8.log"; SANDBOX_STATE="$TMPROOT/s8-state"
|
|
setup_sandbox "$SANDBOX"
|
|
setup_stubbin "$STUBBIN" "$LOG"
|
|
mkdir -p "$SANDBOX/build/foo"
|
|
echo "foo-image-neu" >"$SANDBOX/build/foo/ninlight_foo_ota.img"
|
|
mkdir -p "$SANDBOX_STATE/opt/ninlight-station/images"
|
|
echo "veraltet" >"$SANDBOX_STATE/opt/ninlight-station/images/ninlight_veraltet_ota.img"
|
|
echo "auch-veraltet" >"$SANDBOX_STATE/opt/ninlight-station/images/ninlight_e14_cw_ota.img"
|
|
: >"$LOG"
|
|
set +e
|
|
OUT=$(run_deploy "$SANDBOX" pi-test 2>&1)
|
|
RC=$?
|
|
set -e
|
|
if [ "$RC" -eq 0 ]; then pass "Exit-Code 0"; else fail "Exit-Code $RC, Ausgabe: $OUT"; fi
|
|
if echo "$OUT" | grep -q "folgende Images werden entfernt"; then
|
|
pass "Ausgabe kuendigt die zu entfernenden Images an, bevor geloescht wird"
|
|
else
|
|
fail "Ausgabe nennt die zu entfernenden Images nicht: $OUT"
|
|
fi
|
|
if echo "$OUT" | grep -q "ninlight_veraltet_ota.img" && echo "$OUT" | grep -q "ninlight_e14_cw_ota.img"; then
|
|
pass "beide zu entfernenden Dateien werden namentlich genannt"
|
|
else
|
|
fail "nicht alle zu entfernenden Dateien werden genannt: $OUT"
|
|
fi
|
|
if [ ! -f "$SANDBOX_STATE/opt/ninlight-station/images/ninlight_veraltet_ota.img" ]; then
|
|
pass "veraltetes Image wurde nach der Ankuendigung tatsaechlich entfernt"
|
|
else
|
|
fail "veraltetes Image wurde trotz Ankuendigung nicht entfernt"
|
|
fi
|
|
|
|
echo
|
|
echo "=== Szenario 9: Voll-Deploy ohne verwaiste Images meldet das statt zu schweigen (B2) ==="
|
|
SANDBOX="$TMPROOT/s9"; STUBBIN="$TMPROOT/bin9"; LOG="$TMPROOT/s9.log"; SANDBOX_STATE="$TMPROOT/s9-state"
|
|
setup_sandbox "$SANDBOX"
|
|
setup_stubbin "$STUBBIN" "$LOG"
|
|
mkdir -p "$SANDBOX/build/foo"
|
|
echo "foo-image" >"$SANDBOX/build/foo/ninlight_foo_ota.img"
|
|
: >"$LOG"
|
|
set +e
|
|
OUT=$(run_deploy "$SANDBOX" pi-test 2>&1)
|
|
RC=$?
|
|
set -e
|
|
if [ "$RC" -eq 0 ]; then pass "Exit-Code 0"; else fail "Exit-Code $RC, Ausgabe: $OUT"; fi
|
|
if echo "$OUT" | grep -q "keine Images werden entfernt"; then
|
|
pass "Ausgabe meldet explizit, dass nichts entfernt wird"
|
|
else
|
|
fail "Ausgabe meldet nicht, dass nichts entfernt wird: $OUT"
|
|
fi
|
|
|
|
echo
|
|
if [ "$FAILED" -eq 0 ]; then
|
|
echo "Alle Tests bestanden."
|
|
else
|
|
echo "Mindestens ein Test ist fehlgeschlagen." >&2
|
|
fi
|
|
exit "$FAILED"
|