71 lines
3.4 KiB
Python
71 lines
3.4 KiB
Python
# #region Test.Infrastructure.GradioProxy [C:3] [TYPE Module] [SEMANTICS test,nginx,docker,agent,gradio]
|
|
# @BRIEF Verify Gradio agent proxy contracts across nginx, compose, and agent launch config.
|
|
# @RELATION BINDS_TO -> [docker.nginx.conf]
|
|
# @RELATION BINDS_TO -> [docker.nginx.ssl.conf]
|
|
# @RELATION BINDS_TO -> [AgentChat.Config]
|
|
# @TEST_EDGE: docker_dns_name -> Proxy targets compose service name `agent`.
|
|
# @TEST_EDGE: prefix_forwarding -> Proxy preserves `/api/agent/gradio` for Gradio root_path.
|
|
# @TEST_EDGE: auth_forwarding -> Browser Authorization header is forwarded.
|
|
from pathlib import Path
|
|
|
|
|
|
PROJECT_ROOT = Path(__file__).resolve().parents[2]
|
|
|
|
|
|
def _read(relative_path: str) -> str:
|
|
return (PROJECT_ROOT / relative_path).read_text(encoding="utf-8")
|
|
|
|
|
|
def test_nginx_http_gradio_proxy_targets_agent_service_and_preserves_prefix():
|
|
"""HTTP nginx routes Gradio traffic to compose service `agent` without stripping root_path."""
|
|
text = _read("docker/nginx.conf")
|
|
assert "location /api/agent/gradio/" in text
|
|
assert "set $agent_api http://agent:7860;" in text
|
|
assert "superset-tools-agent" not in text
|
|
assert "rewrite ^/api/agent/gradio" not in text
|
|
assert "proxy_set_header Authorization $http_authorization;" in text
|
|
assert "proxy_set_header Connection $connection_upgrade;" in text
|
|
assert "proxy_redirect http://agent:7860/ /api/agent/gradio/;" in text
|
|
|
|
|
|
def test_nginx_ssl_gradio_proxy_matches_http_contract():
|
|
"""SSL nginx keeps the same Gradio proxy invariants as HTTP nginx."""
|
|
text = _read("docker/nginx.ssl.conf")
|
|
assert "map $http_upgrade $connection_upgrade" in text
|
|
assert "location /api/agent/gradio/" in text
|
|
assert "set $agent_api http://agent:7860;" in text
|
|
assert "superset-tools-agent" not in text
|
|
assert "rewrite ^/api/agent/gradio" not in text
|
|
assert "proxy_set_header Authorization $http_authorization;" in text
|
|
assert "proxy_set_header X-Forwarded-Proto https;" in text
|
|
|
|
|
|
def test_compose_frontend_depends_on_agent_and_agent_uses_root_path():
|
|
"""Compose starts agent before frontend and configures Gradio root_path."""
|
|
for compose_path in ("docker-compose.yml", "docker-compose.enterprise-clean.yml"):
|
|
text = _read(compose_path)
|
|
assert " frontend:" in text
|
|
frontend_block = text.split(" frontend:", 1)[1].split("\n\n", 1)[0]
|
|
assert " - backend" in frontend_block
|
|
assert " - agent" in frontend_block
|
|
agent_block = text.split(" agent:", 1)[1]
|
|
assert "GRADIO_ROOT_PATH: /api/agent/gradio" in agent_block
|
|
|
|
|
|
def test_build_script_generated_enterprise_compose_keeps_agent_proxy_contract():
|
|
"""Release bundle compose heredocs preserve frontend->agent dependency and root_path."""
|
|
text = _read("build.sh")
|
|
assert text.count(" - agent") >= 2
|
|
assert text.count("GRADIO_ROOT_PATH: /api/agent/gradio") >= 2
|
|
|
|
|
|
def test_agent_launch_uses_default_gradio_root_path():
|
|
"""Agent runtime exports `/api/agent/gradio` as Gradio root_path for @gradio/client."""
|
|
config_text = _read("agent/src/ss_tools/agent/_config.py")
|
|
run_text = _read("agent/src/ss_tools/agent/run.py")
|
|
app_text = _read("agent/src/ss_tools/agent/app.py")
|
|
assert 'GRADIO_ROOT_PATH: str = os.getenv("GRADIO_ROOT_PATH", "/api/agent/gradio")' in config_text
|
|
assert "root_path=GRADIO_ROOT_PATH" in run_text
|
|
assert "root_path=GRADIO_ROOT_PATH" in app_text
|
|
# #endregion Test.Infrastructure.GradioProxy
|