fix(station): Signiervariante aus Produkt-ID und Version bestimmen
Eine Entwicklungs-G95 meldete sich am 2026-09-15 mit einer Produkt-ID OHNE
"-dev", aber einer Version MIT "-dev". products.py leitete die Variante
ausschliesslich aus der Produkt-ID ab, die Lampe galt als Produktionsgeraet,
bekam das produktionssigniertes Image und lehnte es ab - ihr Bootloader prueft
gegen den Entwicklungsschluessel.
Die Variante ist damit keine Eigenschaft der Produkt-ID, sondern der Anfrage.
PRODUCTS bildet nur noch auf Geraetetyp und Anzeigename ab; beide Schreibweisen
der Produkt-ID fuehren auf denselben Eintrag. classify_variant() in
parse_request() wertet Produkt-ID UND Version aus: "-dev" an einer der beiden
Stellen bedeutet Entwicklungsgeraet, in der Version nur als ganzes Wort
("-devel"/"-dev2" zaehlen nicht).
Damit eine Fehlklassifikation nicht wieder erst an der Lampe auffaellt, fuehren
status.json (last_seen und jeder recent-Eintrag) und das Panel die Quelle der
Einstufung mit: "g95_cw (dev/Ver)", "dev/ID", "dev/ID+Ver" oder "prod".
Tests: die drei am Geraet mitgeschnittenen Anfragen plus die vierte denkbare
Kombination, die Wortgrenze in der Version, zwei Ende-zu-Ende-Tests im Server
(dev-Image statt prod-Image) und die Panel-Beschriftung.
This commit is contained in:
@@ -33,6 +33,26 @@ def test_migration_shows_detected_lamp():
|
||||
assert "13:04" in text
|
||||
|
||||
|
||||
def test_migration_shows_where_the_dev_classification_came_from():
|
||||
"""Der Hardwarebefund vom 2026-09-15: die Station lieferte ein falsch signiertes Image
|
||||
aus, ohne dass am Panel etwas darauf hindeutete. Steht die Quelle der Einstufung
|
||||
daneben, sieht der Bediener VOR der Freigabe, worauf sie beruht."""
|
||||
def variant_line(last_seen):
|
||||
state = {"mode": "migration", "phase": "listen", "served": 0, "recent": [],
|
||||
"ssid": "qconnex-firmware", "last_seen": last_seen}
|
||||
return [l for l in render.lines(state) if l.startswith("g95_cw (")][0]
|
||||
|
||||
base = {"product_name": "Klyqa G95 Vintage CW/WW", "target": "g95_cw",
|
||||
"lamp_version": "V1.1.1.2357-dev"}
|
||||
assert variant_line(dict(base, variant="dev", variant_source="version")) == "g95_cw (dev/Ver)"
|
||||
assert variant_line(dict(base, variant="dev", variant_source="product_id")) == "g95_cw (dev/ID)"
|
||||
assert variant_line(dict(base, variant="dev", variant_source="both")) == "g95_cw (dev/ID+Ver)"
|
||||
# prod hat keine Quelle - da gibt es nirgends ein "-dev", das man anzeigen koennte.
|
||||
assert variant_line(dict(base, variant="prod", variant_source="none")) == "g95_cw (prod)"
|
||||
# Eine aeltere Serverfassung ohne das Feld bleibt darstellbar.
|
||||
assert variant_line(dict(base, variant="dev")) == "g95_cw (dev)"
|
||||
|
||||
|
||||
def test_recovery_mode_without_traffic():
|
||||
lines = render.lines({"mode": "recovery", "ssid": "ninlight-recovery",
|
||||
"served": 0, "recent": []})
|
||||
|
||||
Reference in New Issue
Block a user