feat(station): Anzeige ausliefern, Migrationsprofil, display-Befehle
Schritt 8 des Plans: die fertige E-Paper-Anzeige wird endlich ausgeliefert und verdrahtet, dazu zwei liegengebliebene Dinge. - deploy.sh/setup_pi.sh uebertragen display/ (mit Panel-Treibern und HERKUNFT.md) und ninlight-display.service; setup_pi.sh installiert und aktiviert die Unit und zieht python3-pil nach - ohne Pillow beendet sich der Anzeigedienst still mit 0, das faellt sonst nirgends auf. - setup_pi.sh legt auch das Profil fuer den Migrations-Zugangspunkt an (qconnex-firmware, von der alten Klyqa-Firmware fest vorgegeben, gleiche Adresse wie das Rettungsprofil). Ohne das scheiterte "migrate on" auf einem frisch eingerichteten Pi an need_profile. Bestehende Profile bleiben unangetastet. - "ninlight-station display test|clear|off"; der Hilfetext erklaert die Revisionsbestimmung, denn EPD_REVISION laesst sich nur am Testbild bestimmen. - "off" nimmt die Anzeige mit: erst Dienst stoppen, dann Panel leeren (sonst schreibt der Daemon binnen 5 s sein altes Bild zurueck) und beides vor ap_switch, das bei haengendem NetworkManager abbricht. Ein stehengebliebenes "MIGRATION" wuerde einen Betriebszustand behaupten, den es nicht mehr gibt. - test_host.sh sammelt tools/mkimage als Ganzes ein: die 19 Tests in test_nl_mkimage.py liefen in keiner Suite mehr mit, darunter die Wache fuer die Python-3.8-Randbedingung des Build-Containers. Ein neuer Test haelt die Regel fest, dass keine Testdatei mehr herausfallen kann. - Nebenbei: die Temp-Datei mit dem WLAN-Passwort wird wieder zuverlaessig aufgeraeumt, und leere Konfigurationswerte legen kein kaputtes Profil an.
This commit is contained in:
@@ -0,0 +1,86 @@
|
||||
"""Wache dagegen, dass eine Testdatei aus allen Suiten herausfaellt.
|
||||
|
||||
Genau das war schon einmal passiert: tools/test_host.sh rief pytest auf
|
||||
tools/mkimage/tests und tools/station/tests auf - tools/mkimage/test_nl_mkimage.py
|
||||
liegt aber DIREKT in tools/mkimage/ und lief damit in keiner Suite mehr mit. 19 Tests
|
||||
waren still verschwunden, darunter test_stays_python38_compatible, die Wache fuer die
|
||||
bindende 3.8-Randbedingung des Docker-Build-Containers (`str | None` in nl_mkimage.py
|
||||
hatte den Build schon einmal gebrochen).
|
||||
|
||||
Eine stumm ausgefallene Testdatei ist schlimmer als eine fehlende: die Suite bleibt
|
||||
gruen und behauptet damit eine Deckung, die es nicht gibt. Deshalb wird hier nicht ein
|
||||
einzelner Pfad festgenagelt, sondern die Regel selbst - JEDE test_*.py unter tools/
|
||||
muss von einem der Pfade erfasst sein, die tools/test_host.sh an pytest uebergibt.
|
||||
Eine neue Testdatei an einer neuen Stelle faellt damit sofort auf, statt erst dann,
|
||||
wenn jemand sie vermisst.
|
||||
"""
|
||||
import re
|
||||
from pathlib import Path
|
||||
|
||||
TOOLS_DIR = Path(__file__).resolve().parents[2]
|
||||
REPO_ROOT = TOOLS_DIR.parent
|
||||
TEST_HOST = TOOLS_DIR / "test_host.sh"
|
||||
|
||||
# Verzeichnisse, die keine Tests DIESES Projekts enthalten: virtuelle Umgebungen und
|
||||
# installierte Fremdpakete bringen eigene test_*.py mit, die hier nichts zu suchen haben.
|
||||
IGNORED_PARTS = (".venv", "__pycache__", "site-packages", "node_modules", ".git")
|
||||
|
||||
|
||||
def pytest_paths():
|
||||
"""Die Pfade, die tools/test_host.sh an pytest uebergibt, als aufgeloeste Pfade."""
|
||||
text = TEST_HOST.read_text()
|
||||
match = re.search(r"^\s*python3 -m pytest (.+?)(?:\s+-\S+)*\s*$", text, re.M)
|
||||
assert match, "in tools/test_host.sh ist kein 'python3 -m pytest'-Aufruf zu finden"
|
||||
paths = []
|
||||
for raw in match.group(1).split():
|
||||
arg = raw.strip('"')
|
||||
if arg.startswith("-"):
|
||||
continue
|
||||
paths.append(Path(arg.replace("$ROOT", str(REPO_ROOT))).resolve())
|
||||
assert paths, "der pytest-Aufruf in tools/test_host.sh uebergibt keine Pfade"
|
||||
return paths
|
||||
|
||||
|
||||
def own_test_files():
|
||||
return sorted(
|
||||
p.resolve()
|
||||
for p in TOOLS_DIR.rglob("test_*.py")
|
||||
if not any(part in IGNORED_PARTS for part in p.parts)
|
||||
)
|
||||
|
||||
|
||||
def test_every_test_file_is_reached_by_test_host():
|
||||
roots = pytest_paths()
|
||||
orphans = []
|
||||
for test_file in own_test_files():
|
||||
if not any(test_file == r or r in test_file.parents for r in roots):
|
||||
orphans.append(test_file.relative_to(REPO_ROOT))
|
||||
assert not orphans, (
|
||||
"diese Testdateien laufen in keiner Suite mit - tools/test_host.sh sammelt sie "
|
||||
"nicht ein: {}. Entweder den Pfad in test_host.sh erweitern oder die Datei "
|
||||
"dorthin verschieben, wo sie eingesammelt wird.".format(
|
||||
", ".join(str(o) for o in orphans)
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
def test_python38_guard_is_among_them():
|
||||
"""Die konkrete Datei, deren Ausfall den Build-Bruch damals durchgelassen haette."""
|
||||
guard = (TOOLS_DIR / "mkimage" / "test_nl_mkimage.py").resolve()
|
||||
assert guard.exists(), "tools/mkimage/test_nl_mkimage.py fehlt"
|
||||
roots = pytest_paths()
|
||||
assert any(guard == r or r in guard.parents for r in roots), (
|
||||
"tools/mkimage/test_nl_mkimage.py wird von tools/test_host.sh nicht eingesammelt "
|
||||
"- darin steht test_stays_python38_compatible, die einzige Wache gegen erneute "
|
||||
"3.10-Syntax in nl_mkimage.py (der Docker-Build-Container hat Python 3.8.10)"
|
||||
)
|
||||
|
||||
|
||||
def test_vermin_is_installed():
|
||||
"""vermin fehlt -> harter Fehlschlag, kein Skip.
|
||||
|
||||
Eine Wache, die sich beim Fehlen ihres Werkzeugs stillschweigend abschaltet, haette
|
||||
den Build-Bruch von damals genauso durchgelassen wie gar kein Test. Nachinstallieren:
|
||||
pip install vermin (oder pip3 install --user vermin).
|
||||
"""
|
||||
import vermin # noqa: F401
|
||||
Reference in New Issue
Block a user