diff --git a/scripts/camera_service.py b/scripts/camera_service.py index e272e79..23b5a21 100644 --- a/scripts/camera_service.py +++ b/scripts/camera_service.py @@ -747,6 +747,7 @@ def create_app(folder: Path | str | None = None, raise HTTPException(400, "«orizzontale» e «verticale» devono essere true o false") with lock: prima = orientamenti.get(nome) or {} + prima_voce = orientamenti.get(nome) # #110: voce di prima (None = non c'era), per il ripristino se il salvataggio fallisce cambiato = (bool(prima.get("orizzontale")), bool(prima.get("verticale"))) != (orizz, vert) if orizz or vert: orientamenti[nome] = {"orizzontale": orizz, "verticale": vert} @@ -760,6 +761,10 @@ def create_app(folder: Path | str | None = None, os.replace(tmp, file_orientamento) except OSError as e: _log.warning("orientamento non salvato (%s): %s", file_orientamento, e) + if prima_voce is None: # #110: salvataggio fallito -> in memoria resta l'orientamento di prima + orientamenti.pop(nome, None) + else: + orientamenti[nome] = prima_voce raise HTTPException(500, "salvataggio dell'orientamento non riuscito") # i frame tenuti hanno l'orientamento di prima grezzi.pop(nome, None) diff --git a/scripts/tests/test_camera_orientamento.py b/scripts/tests/test_camera_orientamento.py index 6d10af9..a6dff3a 100644 --- a/scripts/tests/test_camera_orientamento.py +++ b/scripts/tests/test_camera_orientamento.py @@ -166,3 +166,21 @@ def test_avviso_con_mappa_attiva(client_denso): assert "«Densa»" in r.json()["avviso"] and "va rifatta" in r.json()["avviso"] # stesso valore di nuovo: nulla e' cambiato, nessun avviso assert _imposta(client_denso, True, False, source=SORGENTE_DENSA).json()["avviso"] is None + + +def test_scrittura_fallita_500_e_orientamento_di_prima(cartella, config, monkeypatch): + # #110: se orientamento.json non si scrive, in memoria resta l'orientamento di prima + mod = _carica() + with TestClient(mod.create_app(cartella, config)) as c: + assert _imposta(c, True, False).status_code == 200 # stato di partenza: orizzontale + def rotto(*a, **k): + raise OSError("disco pieno") + monkeypatch.setattr(mod.os, "replace", rotto) + assert _imposta(c, False, True).status_code == 500 + j = c.get("/camera/orientamento", params={"source": SORGENTE}).json() + assert (j["orizzontale"], j["verticale"]) == (True, False) + assert _grab(c) == (0, 3) # ancora solo orizzontale + # sorgente che prima non c'era: la voce non resta + assert c.put("/camera/orientamento", json={"source": "altra", "orizzontale": True, "verticale": True}).status_code == 500 + j = c.get("/camera/orientamento", params={"source": "altra"}).json() + assert (j["orizzontale"], j["verticale"]) == (False, False)