All checks were successful
Deploy server-up (dev) / deploy (push) Successful in 6m16s
add_shared_network hing elke service van een stack aan het gedeelde netwerk. Eén druk op 'koppelen' maakte daarmee de database van die app bereikbaar voor elke andere gekoppelde app — en niet elk sjabloon zet daar een wachtwoord op. - Standaard gaan alleen services mee die geen database, cache of zoekindex zijn; brokers als mosquitto en rabbitmq blijven wel deelbaar. - Per onderdeel te kiezen in de stap 'Verbinden'; de keuze staat in .serverup.json en geldt ook bij een volgende wijziging. - mongodump/mongorestore sturen geen inloggegevens meer mee bij een database zonder authenticatie; die dump mislukte altijd. - Joblogs worden bewaard in SU_JOBS (standaard /data/jobs) en teruggelezen na een herstart; een afgekapte taak meldt dat in plaats van 'unknown'. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01H9Vcwu7owJZ3nj5dCf4VFT
91 lines
3.1 KiB
Python
91 lines
3.1 KiB
Python
"""Het joblog moet een herstart overleven.
|
|
|
|
Jobs stonden alleen in het geheugen. Juist bij het bijwerken herstart de
|
|
container middenin de taak, en dan gaf `/api/jobs/<id>` alleen nog "unknown":
|
|
de interface bleef pollen zonder ooit te vertellen hoe het afliep.
|
|
"""
|
|
import json
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
WORTEL = Path(__file__).resolve().parent.parent
|
|
sys.path.insert(0, str(WORTEL / "server-up"))
|
|
|
|
|
|
def _job_met_regels(jobs, tag="backup:web", regels=("bezig", "klaar")):
|
|
jid, q = jobs.create(tag)
|
|
for r in regels:
|
|
jobs.log(q, "dim", r)
|
|
jobs.stream(jid) # regels uit de queue in de job trekken
|
|
return jid
|
|
|
|
|
|
def test_afgeronde_job_blijft_op_schijf_staan(env):
|
|
from core import jobs
|
|
jid = _job_met_regels(jobs)
|
|
jobs.finish(jid, "done")
|
|
|
|
bestand = Path(env["data"]) / "jobs" / f"{jid}.json"
|
|
assert bestand.is_file()
|
|
bewaard = json.loads(bestand.read_text())
|
|
assert bewaard["status"] == "done"
|
|
assert [r["text"] for r in bewaard["lines"]] == ["bezig", "klaar"]
|
|
|
|
|
|
def test_log_blijft_leesbaar_nadat_de_job_uit_het_geheugen_is(env):
|
|
"""Na de TTL ruimt Server Up jobs op; het log hoort dan nog te bestaan."""
|
|
from core import jobs
|
|
jid = _job_met_regels(jobs)
|
|
jobs.finish(jid, "done")
|
|
|
|
jobs._jobs.clear() # zoals _cleanup() na een uur doet
|
|
d = jobs.stream(jid)
|
|
assert d["status"] == "done"
|
|
assert [r["text"] for r in d["lines"]] == ["bezig", "klaar"]
|
|
assert jobs.stream(jid, offset=1)["lines"][0]["text"] == "klaar"
|
|
|
|
|
|
def test_onderbroken_job_wordt_als_zodanig_teruggelezen(env):
|
|
"""Een taak die liep toen de container omviel mag niet als 'running'
|
|
terugkomen: dan blijft de interface eeuwig wachten."""
|
|
from core import jobs
|
|
# Geen finish(): de job loopt nog. Het pollen van de interface schrijft
|
|
# tussentijds weg, en dat is precies wat er van hem overblijft.
|
|
jid = _job_met_regels(jobs, regels=("backup wordt gemaakt",))
|
|
assert (Path(env["data"]) / "jobs" / f"{jid}.json").is_file()
|
|
|
|
jobs._jobs.clear() # de herstart
|
|
assert jobs.herstel() >= 1
|
|
|
|
d = jobs.stream(jid)
|
|
assert d["status"] == "error"
|
|
tekst = " ".join(r["text"] for r in d["lines"])
|
|
assert "backup wordt gemaakt" in tekst
|
|
assert "herstart" in tekst
|
|
|
|
|
|
def test_onbekende_job_blijft_onbekend(env):
|
|
from core import jobs
|
|
assert jobs.stream("bestaatniet")["status"] == "unknown"
|
|
|
|
|
|
def test_er_blijven_niet_eindeloos_joblogs_liggen(env):
|
|
from core import jobs
|
|
for i in range(jobs._BEWAAR + 5):
|
|
jobs.finish(_job_met_regels(jobs, tag=f"taak-{i}"), "done")
|
|
bestanden = list((Path(env["data"]) / "jobs").glob("*.json"))
|
|
assert len(bestanden) <= jobs._BEWAAR
|
|
|
|
|
|
def test_joblog_van_de_api_komt_ook_van_schijf(client, env):
|
|
"""De route zelf moet het bewaarde log teruggeven, niet alleen de module."""
|
|
from conftest import login
|
|
from core import jobs
|
|
login(client)
|
|
jid = _job_met_regels(jobs, regels=("stap 1",))
|
|
jobs.finish(jid, "error")
|
|
jobs._jobs.clear()
|
|
|
|
d = client.get(f"/api/jobs/{jid}").get_json()
|
|
assert d["status"] == "error"
|
|
assert d["lines"][0]["text"] == "stap 1"
|