Files
headquarter/apps/api/tests/test_traefik.py
T
alex 6aea953734 feat(FN-010): implement code-server spawn service with Docker Compose
- Add SpawnService with container lifecycle (spawn/stop/status)
- Generate Docker Compose services from tool manifests
- Integrate Traefik label generation with subdomain routing
- Mount workspace, config, and SSH key volumes
- Add container status polling and health checks
- Enhance tool instance API with spawn/stop/start/status endpoints
- Add Traefik forwardAuth middleware for auth proxy
- Update code-server manifest with runtime configuration
2026-05-14 17:27:19 +02:00

198 lines
6.8 KiB
Python

from app.services.traefik import TraefikLabelGenerator
class TestTraefikLabelGenerator:
def test_generate_subdomain(self):
gen = TraefikLabelGenerator(domain="hq.example.com")
subdomain = gen.generate_subdomain(
tool_key="code-server",
project_slug="my-project",
user_slug="alice",
)
assert subdomain == "code-server-my-project-alice.hq.example.com"
def test_generate_subdomain_with_different_domain(self):
gen = TraefikLabelGenerator(domain="tools.localhost")
subdomain = gen.generate_subdomain(
tool_key="opencode",
project_slug="test",
user_slug="bob",
)
assert subdomain == "opencode-test-bob.tools.localhost"
def test_generate_labels_basic(self):
gen = TraefikLabelGenerator(domain="hq.example.com")
labels = gen.generate_labels(
instance_id="abc12345-6789-1234-5678-123456789abc",
tool_key="code-server",
project_slug="my-project",
user_slug="alice",
container_port=8443,
)
assert labels["traefik.enable"] == "true"
assert "Host(`code-server-my-project-alice.hq.example.com`)" in labels[
"traefik.http.routers.tool-abc12345.rule"
]
assert labels["traefik.http.routers.tool-abc12345.entrypoints"] == "websecure"
assert labels["traefik.http.routers.tool-abc12345.service"] == "tool-abc12345"
def test_generate_labels_tls(self):
gen = TraefikLabelGenerator(domain="hq.example.com", entrypoint="websecure")
labels = gen.generate_labels(
instance_id="abc12345-6789-1234-5678-123456789abc",
tool_key="code-server",
project_slug="my-project",
user_slug="alice",
container_port=8443,
)
assert labels["traefik.http.routers.tool-abc12345.tls"] == "true"
assert (
labels["traefik.http.routers.tool-abc12345.tls.certresolver"]
== "letsencrypt"
)
def test_generate_labels_no_tls_for_http(self):
gen = TraefikLabelGenerator(domain="hq.example.com", entrypoint="web")
labels = gen.generate_labels(
instance_id="abc12345-6789-1234-5678-123456789abc",
tool_key="code-server",
project_slug="my-project",
user_slug="alice",
container_port=8443,
)
assert "traefik.http.routers.tool-abc12345.tls" not in labels
assert "traefik.http.routers.tool-abc12345.tls.certresolver" not in labels
def test_generate_labels_service_config(self):
gen = TraefikLabelGenerator(domain="hq.example.com")
labels = gen.generate_labels(
instance_id="abc12345-6789-1234-5678-123456789abc",
tool_key="code-server",
project_slug="my-project",
user_slug="alice",
container_port=8443,
)
assert (
labels["traefik.http.services.tool-abc12345.loadbalancer.server.port"]
== "8443"
)
assert (
labels["traefik.http.services.tool-abc12345.loadbalancer.server.scheme"]
== "http"
)
def test_generate_labels_security_headers(self):
gen = TraefikLabelGenerator(domain="hq.example.com")
labels = gen.generate_labels(
instance_id="abc12345-6789-1234-5678-123456789abc",
tool_key="code-server",
project_slug="my-project",
user_slug="alice",
container_port=8443,
)
middleware_name = "tool-abc12345-sec"
assert (
labels[f"traefik.http.middlewares.{middleware_name}.headers.stsSeconds"]
== "31536000"
)
assert (
labels[
f"traefik.http.middlewares.{middleware_name}.headers.stsIncludeSubdomains"
]
== "true"
)
assert (
labels[
f"traefik.http.middlewares.{middleware_name}.headers.forceStsHeader"
]
== "true"
)
assert (
labels[
f"traefik.http.middlewares.{middleware_name}.headers.contentTypeNosniff"
]
== "true"
)
assert (
labels[
f"traefik.http.middlewares.{middleware_name}.headers.browserXssFilter"
]
== "true"
)
assert (
labels[
f"traefik.http.middlewares.{middleware_name}.headers.customFrameOptionsValue"
]
== "SAMEORIGIN"
)
def test_generate_labels_middleware_attached(self):
gen = TraefikLabelGenerator(domain="hq.example.com")
labels = gen.generate_labels(
instance_id="abc12345-6789-1234-5678-123456789abc",
tool_key="code-server",
project_slug="my-project",
user_slug="alice",
container_port=8443,
)
assert labels["traefik.http.routers.tool-abc12345.middlewares"] == "tool-abc12345-sec"
def test_generate_labels_network(self):
gen = TraefikLabelGenerator(domain="hq.example.com")
labels = gen.generate_labels(
instance_id="abc12345-6789-1234-5678-123456789abc",
tool_key="code-server",
project_slug="my-project",
user_slug="alice",
container_port=8443,
network_name="custom-network",
)
assert labels["traefik.docker.network"] == "custom-network"
def test_generate_labels_default_network(self):
gen = TraefikLabelGenerator(domain="hq.example.com")
labels = gen.generate_labels(
instance_id="abc12345-6789-1234-5678-123456789abc",
tool_key="code-server",
project_slug="my-project",
user_slug="alice",
container_port=8443,
)
assert labels["traefik.docker.network"] == "tools"
def test_generate_removal_labels(self):
gen = TraefikLabelGenerator(domain="hq.example.com")
labels = gen.generate_removal_labels(
instance_id="abc12345-6789-1234-5678-123456789abc",
)
assert labels["traefik.enable"] == "false"
assert labels["traefik.http.routers.tool-abc12345.rule"] == ""
def test_generate_labels_with_opencode(self):
gen = TraefikLabelGenerator(domain="hq.example.com")
labels = gen.generate_labels(
instance_id="xyz78901-2345-6789-0123-456789012345",
tool_key="opencode",
project_slug="demo",
user_slug="charlie",
container_port=3000,
)
assert "Host(`opencode-demo-charlie.hq.example.com`)" in labels[
"traefik.http.routers.tool-xyz78901.rule"
]
assert (
labels["traefik.http.services.tool-xyz78901.loadbalancer.server.port"]
== "3000"
)