Files
light-heart-labs--dreamserver/ods/tests/test-perplexica-entrypoint.py
T
wehub-resource-sync 9e8f1bbeed
Dashboard / frontend (push) Failing after 0s
Dashboard / api (push) Failing after 0s
Lint PowerShell / powershell-lint (ubuntu-latest) (push) Failing after 1s
Python Lint / Lint Python with Ruff (push) Failing after 1s
ShellCheck / Lint shell scripts (push) Failing after 1s
Matrix Smoke / linux-smoke (push) Failing after 1s
Matrix Smoke / distro: cachyos (push) Failing after 15s
Matrix Smoke / distro: linux-mint-21.3 (push) Failing after 15s
Matrix Smoke / distro: debian-12 (push) Failing after 5m21s
Matrix Smoke / distro: fedora-41 (push) Failing after 4m56s
Matrix Smoke / distro: ubuntu-24.04 (push) Failing after 2m13s
Matrix Smoke / distro: rocky-9 (push) Failing after 10m39s
Matrix Smoke / distro: manjaro (push) Failing after 12m11s
Matrix Smoke / distro: opensuse-tw (push) Failing after 11m53s
Matrix Smoke / distro: archlinux (push) Failing after 20m3s
Matrix Smoke / distro: ubuntu-22.04 (push) Failing after 13m49s
Validate .env Schema / tier-1-env-validation (push) Successful in 52s
Validate .env Schema / tier-2-env-validation (push) Successful in 44s
Validate .env Schema / tier-3-env-validation (push) Successful in 52s
Validate .env Schema / tier-4-env-validation (push) Successful in 51s
Validate Extensions Catalog / Check catalog is up-to-date (push) Failing after 9m47s
Secret Scan / Scan for secrets (push) Failing after 21m4s
Validate Docker Compose / Validate Docker Compose files (push) Has been cancelled
Python Type Check / Type check with mypy (push) Has been cancelled
Validate .env Schema / tier-0-env-validation (push) Has been cancelled
Test Linux / integration-smoke (push) Has been cancelled
Lint PowerShell / powershell-lint (windows-latest) (push) Has been cancelled
Matrix Smoke / macos-smoke (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:31:33 +08:00

87 lines
3.6 KiB
Python

#!/usr/bin/env python3
"""Static contract tests for Perplexica's ODS entrypoint patch."""
from __future__ import annotations
import json
import re
from pathlib import Path
ROOT = Path(__file__).resolve().parents[1]
ENV_SCHEMA = ROOT / ".env.schema.json"
SERVICE_DIR = ROOT / "extensions" / "services" / "perplexica"
COMPOSE = SERVICE_DIR / "compose.yaml"
ENTRYPOINT = SERVICE_DIR / "docker-entrypoint.sh"
WHISPER_COMPOSE = ROOT / "extensions" / "services" / "whisper" / "compose.yaml"
def test_compose_uses_ods_entrypoint() -> None:
compose = COMPOSE.read_text(encoding="utf-8")
assert "PERPLEXICA_SCRAPE_URL_MAX_CHARS=${PERPLEXICA_SCRAPE_URL_MAX_CHARS:-30000}" in compose
assert "/app/ods-entrypoint.sh" in compose
assert "./extensions/services/perplexica/docker-entrypoint.sh:/app/ods-entrypoint.sh:ro" in compose
assert 'exec /bin/sh /app/ods-entrypoint.sh \\"$@\\"' in compose
def test_bind_mounted_entrypoints_do_not_require_executable_bit() -> None:
service_entrypoints = (
(COMPOSE, "/app/ods-entrypoint.sh", 'exec /bin/sh /app/ods-entrypoint.sh \\"$@\\"'),
(WHISPER_COMPOSE, "/app/docker-entrypoint.sh", "exec /bin/sh /app/docker-entrypoint.sh"),
)
for compose_path, mounted_script, shell_exec in service_entrypoints:
compose = compose_path.read_text(encoding="utf-8")
assert f"until [ -f {mounted_script} ]" in compose
assert f"until [ -x {mounted_script} ]" not in compose
assert shell_exec in compose
assert f"exec {mounted_script}" not in compose
def test_entrypoint_patches_scrape_url_result_content() -> None:
script = ENTRYPOINT.read_text(encoding="utf-8")
assert "name:\"scrape_url\"" in script
assert "PERPLEXICA_SCRAPE_URL_MAX_CHARS" in script
assert "content:k.slice(0,${max})" in script
sample = 'g.push({content:k,metadata:{url:a,title:j}})'
pattern = re.compile(
r"([A-Za-z_$][\w$]*\.push\(\{content:)"
r"([A-Za-z_$][\w$]*)"
r"(,metadata:\{url:[A-Za-z_$][\w$]*,title:[A-Za-z_$][\w$]*\}\}\))"
)
patched = pattern.sub(lambda m: f"{m.group(1)}{m.group(2)}.slice(0,30000){m.group(3)}", sample)
assert patched == 'g.push({content:k.slice(0,30000),metadata:{url:a,title:j}})'
def test_env_schema_allows_scrape_cap_override() -> None:
schema = json.loads(ENV_SCHEMA.read_text(encoding="utf-8"))
property_schema = schema["properties"]["PERPLEXICA_SCRAPE_URL_MAX_CHARS"]
assert property_schema["type"] == "integer"
assert property_schema["default"] == 30000
assert property_schema["minimum"] == 1000
def test_compose_restores_image_command() -> None:
# Setting `entrypoint:` in compose drops the upstream image's CMD
# (`node server.js`). The override must restate it or the patched
# entrypoint exits 0 with no app process, restart-looping.
compose = COMPOSE.read_text(encoding="utf-8")
assert 'command: ["node", "server.js"]' in compose
def test_entrypoint_falls_back_to_node_server_when_no_args() -> None:
# Belt-and-suspenders: even if a future compose change drops `command:`,
# the entrypoint should still launch the app instead of exiting 0.
script = ENTRYPOINT.read_text(encoding="utf-8")
assert 'if [ "$#" -eq 0 ]' in script
assert "set -- node server.js" in script
if __name__ == "__main__":
test_compose_uses_ods_entrypoint()
test_bind_mounted_entrypoints_do_not_require_executable_bit()
test_entrypoint_patches_scrape_url_result_content()
test_env_schema_allows_scrape_cap_override()
test_compose_restores_image_command()
test_entrypoint_falls_back_to_node_server_when_no_args()