server-up/tests/test_update_adres.py
Ramon 14515143fc
All checks were successful
Deploy server-up (dev) / deploy (push) Successful in 4m51s
perf(build): image bouwt niet meer alles opnieuw bij elke uitgave
ARG SU_VERSION stond bovenaan met een LABEL erachter. Die waarde verandert
per release, dus alle lagen erna vervielen: apt-get, de Docker-CLI van 70 MB
en de front-end-bestanden. Versie en label staan nu onderaan, en de assets
vóór de broncode zodat ze niet bij elke commit opnieuw van het CDN komen.

Ook: een mislukte pull noemt nu de waarschijnlijke oorzaak (geen gepusht
image) in plaats van alleen naar toegangsrechten te wijzen.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01H9Vcwu7owJZ3nj5dCf4VFT
2026-08-07 16:05:46 +02:00

155 lines
6.7 KiB
Python

"""Het adres van de releases-API en van het image, zoals mensen ze invullen.
Wie in Forgejo naar zijn releases kijkt en dat adres uit de adresbalk plakt,
geeft het adres van een webpagina op. De enige melding die daarop volgde was
`JSONDecodeError: Expecting value: line 1 column 1 (char 0)`, en daar leidt
niemand uit af dat er `/api/v1/repos/` in had moeten staan.
"""
import sys
from pathlib import Path
import pytest
WORTEL = Path(__file__).resolve().parent.parent
sys.path.insert(0, str(WORTEL / "server-up"))
# ── Het releases-adres ───────────────────────────────────────────────────────
@pytest.mark.parametrize("ingevuld,verwacht", [
# Wat je uit de adresbalk van Forgejo plakt.
("https://git.voorbeeld.nl/bes-r/server-up/releases",
"https://git.voorbeeld.nl/api/v1/repos/bes-r/server-up/releases"),
# Zonder /releases erachter.
("https://git.voorbeeld.nl/bes-r/server-up",
"https://git.voorbeeld.nl/api/v1/repos/bes-r/server-up/releases"),
# Met poort, en http.
("http://10.0.20.22:3000/bes-r/server-up/releases",
"http://10.0.20.22:3000/api/v1/repos/bes-r/server-up/releases"),
# De kloon-URL.
("https://git.voorbeeld.nl/bes-r/server-up.git",
"https://git.voorbeeld.nl/api/v1/repos/bes-r/server-up/releases"),
# GitHub heeft zijn API op een eigen host.
("https://github.com/bes-r/server-up/releases",
"https://api.github.com/repos/bes-r/server-up/releases"),
])
def test_webadres_wordt_een_apiadres(env, ingevuld, verwacht):
from core import updater
assert updater.api_url(ingevuld) == verwacht
@pytest.mark.parametrize("al_goed", [
"https://git.voorbeeld.nl/api/v1/repos/bes-r/server-up/releases",
"https://api.github.com/repos/bes-r/server-up/releases",
])
def test_een_apiadres_blijft_ongemoeid(env, al_goed):
from core import updater
assert updater.api_url(al_goed) == al_goed
def test_leeg_blijft_leeg(env):
from core import updater
assert updater.api_url("") == ""
assert updater.api_url(" ") == ""
def test_onherkenbaar_adres_blijft_staan(env):
"""Niet slimmer doen dan we zijn: wat we niet herkennen laten we met rust,
zodat een eigen proxy-adres blijft werken."""
from core import updater
raar = "https://voorbeeld.nl/een/diep/pad/met/releases.json"
assert updater.api_url(raar) == raar
def test_html_geeft_een_begrijpelijke_fout(env, monkeypatch):
"""De melding moet zeggen wát er mis is, niet dat JSON niet parseert."""
from core import updater
class _Antwoord:
def read(self):
return b"<!DOCTYPE html>\n<html lang=\"en-US\">"
def __enter__(self):
return self
def __exit__(self, *a):
return False
monkeypatch.setattr(updater.urllib.request, "urlopen",
lambda *a, **k: _Antwoord())
with pytest.raises(ValueError) as fout:
updater._releases("https://git.voorbeeld.nl/bes-r/server-up/releases")
melding = str(fout.value)
assert "webpagina" in melding
assert "/api/v1/repos/" in melding
assert "JSONDecode" not in melding
def test_check_gebruikt_het_omgerekende_adres(env, monkeypatch):
from core import updater
env["core"].patch({"UPDATE_API_URL":
"https://git.voorbeeld.nl/bes-r/server-up/releases"})
gebruikt = []
monkeypatch.setattr(updater, "_releases",
lambda u: gebruikt.append(u) or [
{"tag_name": "v9.9.99", "prerelease": False}])
res = updater.check("0.8.28", force=True)
assert gebruikt == [
"https://git.voorbeeld.nl/api/v1/repos/bes-r/server-up/releases"]
assert res["update_available"] is True
# ── Het imageadres ───────────────────────────────────────────────────────────
def test_schema_voor_het_image_wordt_weggehaald(env):
"""`docker pull https://…` bestaat niet, maar in het veld ziet het er goed
uit. Er is geen geldig image dat met een schema begint, dus weghalen kan."""
from core import selfupdate
env["core"].patch({"UPDATE_IMAGE": "https://git.voorbeeld.nl/bes-r/server-up"})
assert selfupdate.image_repo({}) == "git.voorbeeld.nl/bes-r/server-up"
env["core"].patch({"UPDATE_IMAGE": "http://10.0.20.22:3000/bes-r/server-up/"})
assert selfupdate.image_repo({}) == "10.0.20.22:3000/bes-r/server-up"
def test_image_zonder_schema_blijft_gelijk(env):
from core import selfupdate
env["core"].patch({"UPDATE_IMAGE": "git.voorbeeld.nl/bes-r/server-up"})
assert selfupdate.image_repo({}) == "git.voorbeeld.nl/bes-r/server-up"
# Een tag hoort er niet in; die komt van de release.
env["core"].patch({"UPDATE_IMAGE": "git.voorbeeld.nl/bes-r/server-up:0.8.28"})
assert selfupdate.image_repo({}) == "git.voorbeeld.nl/bes-r/server-up"
# ── Als het image er niet is ─────────────────────────────────────────────────
def test_mislukte_pull_noemt_de_waarschijnlijke_oorzaak(env, monkeypatch):
"""Een Forgejo-release ontstaat bij de git-tag, maar het image komt uit de
build — en die pusht alleen als de deploy weet naar welke registry. Dan zie
je een release die je niet kunt installeren, en 'geen toegang' is dan een
misleidend antwoord."""
from core import selfupdate, docker
env["core"].patch({"UPDATE_IMAGE": "git.voorbeeld.nl/bes-r/server-up"})
monkeypatch.setattr(selfupdate, "_login", lambda log_fn=None: (True, ""))
monkeypatch.setattr(selfupdate, "inspect_self",
lambda: {"image": "git.voorbeeld.nl/bes-r/server-up:0.8.29"})
monkeypatch.setattr(docker, "_stream", lambda *a, **k: 1)
ok, msg = selfupdate.pull("v0.8.30")
assert ok is False
assert "geen image met deze tag" in msg
assert "SU_IMAGE" in msg
def test_lokaal_gebouwd_image_wordt_als_zodanig_gemeld(env, monkeypatch):
"""Wie zijn image zelf bouwt kan met deze knop nooit iets ophalen; dat hoort
de melding te zeggen in plaats van naar de registry te wijzen."""
from core import selfupdate, docker
env["core"].patch({"UPDATE_IMAGE": "git.voorbeeld.nl/bes-r/server-up"})
monkeypatch.setattr(selfupdate, "_login", lambda log_fn=None: (True, ""))
monkeypatch.setattr(selfupdate, "inspect_self",
lambda: {"image": "server-up:latest"})
monkeypatch.setattr(docker, "_stream", lambda *a, **k: 1)
ok, msg = selfupdate.pull("v0.8.30")
assert ok is False
assert "lokaal gebouwd image" in msg
assert "install.sh" in msg