feat(infra): auto-commit con 56 cambios

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-21 14:22:55 +02:00
parent c1071a82b3
commit 32c7336bf6
56 changed files with 5307 additions and 100 deletions
@@ -0,0 +1,140 @@
"""Tests para discover_local_services."""
import os
import socket
import sys
import yaml
# El modulo hoja se importa por su nombre directo; aseguramos que su directorio
# esta en sys.path para poder correr el test desde cualquier cwd.
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
from discover_local_services import discover_local_services
NORMALIZED_KEYS = {
"name", "subdomain", "port", "health_path", "title", "icon", "category",
"rewrite_host", "up",
}
def _write_manifest(tmp_path, services):
manifest = {
"dashboard_subdomain": "home",
"glance_port": 8585,
"services": services,
}
path = tmp_path / "local_services.yaml"
path.write_text(yaml.safe_dump(manifest), encoding="utf-8")
return str(path)
def test_golden_service_up_with_all_keys(tmp_path):
# Abrimos un socket real en un puerto efímero para simular un servicio vivo.
listener = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
listener.bind(("127.0.0.1", 0))
listener.listen(1)
port = listener.getsockname()[1]
try:
manifest = _write_manifest(tmp_path, [
{
"name": "metabase",
"subdomain": "metabase",
"port": port,
"health_path": "/api/health",
"title": "Metabase",
"icon": "si:metabase",
"category": "Datos",
},
])
result = discover_local_services(manifest, include_registry=False)
assert len(result) == 1
svc = result[0]
# Todas las claves normalizadas presentes.
assert set(svc.keys()) == NORMALIZED_KEYS
assert svc["up"] is True
assert svc["name"] == "metabase"
assert svc["port"] == port
assert svc["health_path"] == "/api/health"
finally:
listener.close()
def test_edge_closed_port_is_down(tmp_path):
# Tomamos un puerto efímero y lo cerramos inmediatamente -> debe estar down.
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(("127.0.0.1", 0))
closed_port = s.getsockname()[1]
s.close()
manifest = _write_manifest(tmp_path, [
{
"name": "ghost",
"subdomain": "ghost",
"port": closed_port,
"health_path": "/",
"title": "Ghost",
"icon": "",
"category": "Otros",
},
])
result = discover_local_services(manifest, include_registry=False)
assert len(result) == 1
assert result[0]["up"] is False
def test_defaults_derived_for_missing_fields(tmp_path):
# Servicio mínimo: solo name + port. El resto debe derivarse con defaults.
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(("127.0.0.1", 0))
closed_port = s.getsockname()[1]
s.close()
manifest = _write_manifest(tmp_path, [
{"name": "barebones", "port": closed_port},
])
result = discover_local_services(manifest, include_registry=False)
svc = result[0]
assert set(svc.keys()) == NORMALIZED_KEYS
assert svc["title"] == "barebones" # derivado de name
assert svc["icon"] == "" # default
assert svc["category"] == "Otros" # default
assert svc["health_path"] == "/" # default
assert svc["subdomain"] == "barebones" # derivado de name
assert svc["up"] is False
def test_empty_manifest_returns_empty_list(tmp_path):
manifest = _write_manifest(tmp_path, [])
result = discover_local_services(manifest, include_registry=False)
assert result == []
def test_rewrite_host_passthrough_desde_manifiesto(tmp_path):
# Un servicio con rewrite_host: true en el manifiesto debe propagar
# rewrite_host == True; uno sin la clave debe dar rewrite_host == False.
listener = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
listener.bind(("127.0.0.1", 0))
listener.listen(1)
port = listener.getsockname()[1]
try:
manifest = _write_manifest(tmp_path, [
{
"name": "jupyter",
"subdomain": "jupyter",
"port": port,
"rewrite_host": True,
},
{
"name": "metabase",
"subdomain": "metabase",
"port": port,
# sin clave rewrite_host -> default False
},
])
result = discover_local_services(manifest, include_registry=False)
by_name = {s["name"]: s for s in result}
assert by_name["jupyter"]["rewrite_host"] is True
assert by_name["metabase"]["rewrite_host"] is False
finally:
listener.close()