Files
ninlight-w600/tools/mkimage/tests/test_suite_coverage.py
T
Michael Sauer cc398ef57a 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.
2026-09-13 23:19:14 +02:00

87 lines
3.7 KiB
Python

"""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