103 lines
4.1 KiB
Python
103 lines
4.1 KiB
Python
from __future__ import annotations
|
|
import hashlib
|
|
import re
|
|
from pathlib import Path
|
|
import yaml
|
|
|
|
ROOT = Path(__file__).parents[1]
|
|
REPOSITORY_URL = "https://git.radixadm.dk/dennis/homeassistant-stelloauth-addon.git"
|
|
|
|
def load_yaml(path: str) -> dict:
|
|
with (ROOT / path).open(encoding="utf-8") as handle:
|
|
value = yaml.safe_load(handle)
|
|
assert isinstance(value, dict)
|
|
return value
|
|
|
|
def test_repository_metadata() -> None:
|
|
metadata = load_yaml("repository.yaml")
|
|
assert metadata["url"] == REPOSITORY_URL
|
|
assert metadata["name"] == "Stelloauth for Home Assistant"
|
|
assert metadata["maintainer"] == "Dennis / Radix ApS"
|
|
|
|
def test_addon_contract() -> None:
|
|
config = load_yaml("stelloauth/config.yaml")
|
|
assert config["slug"] == "stelloauth"
|
|
assert config["version"] == "0.1.0"
|
|
assert config["arch"] == ["amd64", "aarch64"]
|
|
assert config["startup"] == "application"
|
|
assert config["boot"] == "auto"
|
|
assert config["init"] is True
|
|
assert config["watchdog"] == "http://[HOST]:[PORT:8080]/"
|
|
assert config["ports"] == {"8080/tcp": None}
|
|
for key in ("ingress", "host_network", "privileged", "full_access", "docker_api", "devices", "map"):
|
|
assert key not in config
|
|
|
|
def test_defaults_and_schema_are_aligned() -> None:
|
|
config = load_yaml("stelloauth/config.yaml")
|
|
assert config["options"] == {
|
|
"queue_timeout": "60s",
|
|
"rate_limit_count": 5,
|
|
"rate_limit_duration": "1h",
|
|
}
|
|
assert set(config["schema"]) == set(config["options"])
|
|
assert config["schema"]["rate_limit_count"] == "int(1,20)"
|
|
|
|
def test_repository_hostname_derivation() -> None:
|
|
repository_id = hashlib.sha1(REPOSITORY_URL.lower().encode()).hexdigest()[:8]
|
|
assert repository_id == "0031621f"
|
|
assert f"{repository_id}-stelloauth" == "0031621f-stelloauth"
|
|
|
|
def test_translations_cover_every_option() -> None:
|
|
keys = set(load_yaml("stelloauth/config.yaml")["options"])
|
|
for language in ("da", "en"):
|
|
translation = load_yaml(f"stelloauth/translations/{language}.yaml")
|
|
assert set(translation["configuration"]) == keys
|
|
for entry in translation["configuration"].values():
|
|
assert set(entry) == {"name", "description"}
|
|
assert all(isinstance(value, str) and value.strip() for value in entry.values())
|
|
|
|
|
|
def test_dockerfile_uses_approved_pins_and_builds_patched_stelloauth() -> None:
|
|
dockerfile = (ROOT / "stelloauth/Dockerfile").read_text(encoding="utf-8")
|
|
assert (
|
|
"golang:1.27.1-bookworm@sha256:"
|
|
"69a7b9788769bec032d238959b61854e9ae87f57be9029ec04e9885fabf99195"
|
|
) in dockerfile
|
|
assert (
|
|
"cloakhq/cloakbrowser:0.5.10@sha256:"
|
|
"2ed5b2d047cbdde22cde7ef1a796526c716aadaa5bccbe1db5ade49282b64a76"
|
|
) in dockerfile
|
|
assert "367d4f8c02a3b072c59142c49dffc129edc8548b" in dockerfile
|
|
assert "go test ./..." in dockerfile
|
|
assert not re.search(r"^FROM\s+\S+:latest(?:\s|$)", dockerfile, re.MULTILINE)
|
|
|
|
|
|
def test_dockerfile_declares_home_assistant_runtime_contract() -> None:
|
|
dockerfile = (ROOT / "stelloauth/Dockerfile").read_text(encoding="utf-8")
|
|
for label in (
|
|
"io.hass.name",
|
|
"io.hass.description",
|
|
"io.hass.arch",
|
|
"io.hass.type",
|
|
"io.hass.version",
|
|
):
|
|
assert label in dockerfile
|
|
assert re.search(r"^EXPOSE 8080$", dockerfile, re.MULTILINE)
|
|
assert not re.search(r"^EXPOSE .*\b9222\b", dockerfile, re.MULTILINE)
|
|
assert "ENTRYPOINT []" in dockerfile
|
|
assert 'CMD ["/usr/local/bin/addon-supervisor"]' in dockerfile
|
|
|
|
|
|
def test_dockerfile_patches_parent_cloakserve_instead_of_copying_a_binary() -> None:
|
|
dockerfile = (ROOT / "stelloauth/Dockerfile").read_text(encoding="utf-8")
|
|
assert "COPY patches/cloakserve-loopback.patch" in dockerfile
|
|
for line in dockerfile.splitlines():
|
|
if line.lstrip().startswith("COPY "):
|
|
source = line.split()[1]
|
|
assert Path(source).name != "cloakserve"
|
|
|
|
|
|
def test_runtime_accepts_docker_port_unpublished_status() -> None:
|
|
runtime_test = (ROOT / "tests/test_runtime.sh").read_text(encoding="utf-8")
|
|
assert 'docker port "$container" 9222/tcp 2>/dev/null || true' in runtime_test
|