Arrêt de génération et reclassification optionnelle depuis l'interface
- POST /api/stop : SIGTERM au pipeline (groupe isolé via start_new_session), SIGKILL du groupe après 15 s ; forwardé au worker en mode deux machines - « Régénérer » n'implique plus la reclassification : le DTM en cache est réutilisé tant que la méthode ne change pas ; nouvelle case « Reclasser le sol » (--force-classification) et rappel de la classification existante - Tâche marquée « Interrompu » (returncode négatif ou nul) au lieu d'Échec
This commit is contained in:
@ -222,10 +222,13 @@ def test_generate_all_missing_empty(tmp_path, monkeypatch):
|
||||
|
||||
|
||||
def test_build_command_regenerate():
|
||||
"""regenerate=True ajoute --force --force-classification à la commande."""
|
||||
"""regenerate --force seul (classification conservée) ; reclassify ajoute --force-classification."""
|
||||
from lidar_pipeline.webapp import _build_command
|
||||
cmd = " ".join(_build_command([(1054, 6882)], regenerate=True))
|
||||
assert "--force" in cmd
|
||||
assert "--force-classification" not in cmd
|
||||
cmd = " ".join(_build_command([(1054, 6882)], regenerate=True, reclassify=True))
|
||||
assert "--force" in cmd
|
||||
assert "--force-classification" in cmd
|
||||
cmd = " ".join(_build_command([(1054, 6882)]))
|
||||
assert "--force" not in cmd
|
||||
@ -239,14 +242,56 @@ def test_build_command_ground_classification():
|
||||
cmd = _build_command([(1054, 6882)])
|
||||
i = cmd.index("--ground-classification")
|
||||
assert cmd[i + 1] == "ign"
|
||||
# Chaque méthode valide est transmise telle quelle, avec ou sans régénération
|
||||
# Chaque méthode valide est transmise telle quelle ; --force suit
|
||||
# regenerate, --force-classification suit reclassify (indépendants)
|
||||
for method in GROUND_CLASS_METHODS:
|
||||
for regenerate in (False, True):
|
||||
cmd = _build_command([(1054, 6882)], regenerate=regenerate, ground_class=method)
|
||||
i = cmd.index("--ground-classification")
|
||||
assert cmd[i + 1] == method
|
||||
assert ("--force" in cmd) == regenerate
|
||||
assert ("--force-classification" in cmd) == regenerate
|
||||
for reclassify in (False, True):
|
||||
cmd = _build_command([(1054, 6882)], regenerate=regenerate,
|
||||
ground_class=method, reclassify=reclassify)
|
||||
i = cmd.index("--ground-classification")
|
||||
assert cmd[i + 1] == method
|
||||
assert ("--force" in cmd) == regenerate
|
||||
assert ("--force-classification" in cmd) == reclassify
|
||||
|
||||
|
||||
def test_stop_generation(monkeypatch):
|
||||
"""/api/stop termine le processus en cours (SIGTERM) ou refuse (409)."""
|
||||
import time
|
||||
from fastapi import HTTPException
|
||||
import lidar_pipeline.webapp as webapp
|
||||
terminated = []
|
||||
|
||||
class FakeProc:
|
||||
pid = 4242
|
||||
def poll(self):
|
||||
return None # en cours
|
||||
def terminate(self):
|
||||
terminated.append("SIGTERM")
|
||||
def wait(self, timeout=None):
|
||||
terminated.append("wait")
|
||||
|
||||
saved = {k: webapp._job.get(k) for k in ("proc", "started", "returncode", "cmd", "finished")}
|
||||
try:
|
||||
webapp._job.update({"proc": FakeProc(), "started": time.time(),
|
||||
"returncode": None, "cmd": ["x"], "finished": None})
|
||||
assert webapp.stop_generation() == {"arrêt": "demandé"}
|
||||
assert "SIGTERM" in terminated
|
||||
# Le fil d'escalade peut mettre un instant avant son wait : laisser
|
||||
# la file de threads vider avant de restaurer l'état du job.
|
||||
for _ in range(50):
|
||||
if "wait" in terminated:
|
||||
break
|
||||
time.sleep(0.02)
|
||||
# Sans job en cours : refus propre
|
||||
webapp._job.update({"proc": None})
|
||||
try:
|
||||
webapp.stop_generation()
|
||||
assert False, "une HTTPException était attendue"
|
||||
except HTTPException as e:
|
||||
assert e.status_code == 409
|
||||
finally:
|
||||
webapp._job.update(saved)
|
||||
|
||||
|
||||
def test_build_command_default_viz_aspect():
|
||||
@ -574,6 +619,7 @@ def test_generate_forwards_to_remote(monkeypatch):
|
||||
assert result["demarré"] is True and result["distant"] is True
|
||||
assert calls == [("POST", "/api/generate",
|
||||
{"tiles": [[1054, 6882]], "regenerate": False,
|
||||
"reclassify": False,
|
||||
"ground_class": "ign", "ign_classes": "sol",
|
||||
"bare_earth": False, "viz": ["aspect"],
|
||||
"all_missing": False})]
|
||||
|
||||
Reference in New Issue
Block a user