Spaces:
Running
Running
File size: 4,982 Bytes
2322c22 677e796 2322c22 677e796 2322c22 677e796 2322c22 677e796 2322c22 677e796 2322c22 677e796 2322c22 677e796 2322c22 677e796 2322c22 677e796 2322c22 677e796 2322c22 677e796 2322c22 677e796 2322c22 677e796 2322c22 677e796 2322c22 677e796 2322c22 677e796 2322c22 677e796 2322c22 677e796 2322c22 677e796 2322c22 677e796 2322c22 677e796 2322c22 677e796 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 | import asyncio
import logging
import os
import sys
import types
import pytest
from fastapi import APIRouter
from fastapi.testclient import TestClient
root_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))
if root_dir not in sys.path:
sys.path.insert(0, root_dir)
def create_mock_modules():
sem = types.ModuleType("mock_semantic")
sem_router_mod = types.ModuleType("mock_semantic.router")
r = APIRouter()
@r.get("/ping")
def ping():
return {"project": "semantic", "status": "ok"}
@r.post("/echo")
def echo(data: dict):
return {"project": "semantic", "echo": data}
@r.get("/slow")
async def slow():
await asyncio.sleep(0.5)
return {"status": "finished"}
sem_router_mod.router = r
sem.router = sem_router_mod
sys.modules["mock_semantic"] = sem
sys.modules["mock_semantic.router"] = sem_router_mod
def test_host_with_mocks(monkeypatch, caplog):
create_mock_modules()
monkeypatch.setenv("CORS_ALLOWED_ORIGINS", "https://allowed.com,https://example.com")
monkeypatch.setenv("MAX_BODY_SIZE_BYTES", "1024")
monkeypatch.setenv("REQUEST_TIMEOUT_SECONDS", "0.2")
monkeypatch.setenv("DISABLE_PROJECTS", "")
import registry
registry.PROJECT_REGISTRY = {
"/semantic": "mock_semantic.router:router",
"/broken": "nonexistent_module.router:router",
}
if "main" in sys.modules:
del sys.modules["main"]
with caplog.at_level(logging.INFO):
import main
client = TestClient(main.app)
assert "[/semantic] Successfully mounted at /semantic" in caplog.text
assert "[/broken] Failed to mount router" in caplog.text
res_health = client.get("/health")
assert res_health.status_code == 200
health_data = res_health.json()
assert health_data["status"] == "degraded"
assert "/semantic" in health_data["loaded"]
assert "/broken" in health_data["failed"]
# Verify GET / returns same info as /health
res_root = client.get("/")
assert res_root.status_code == 200
assert res_root.json() == health_data
res_sem = client.get("/semantic/ping")
assert res_sem.status_code == 200
assert res_sem.json() == {"project": "semantic", "status": "ok"}
for doc_url in ["/docs", "/redoc", "/openapi.json"]:
assert client.get(doc_url).status_code == 404
cors_allowed = client.get(
"/semantic/ping",
headers={"Origin": "https://allowed.com"}
)
assert cors_allowed.status_code == 200
assert cors_allowed.headers.get("access-control-allow-origin") == "https://allowed.com"
cors_rejected = client.get(
"/semantic/ping",
headers={"Origin": "https://disallowed.com"}
)
assert cors_rejected.headers.get("access-control-allow-origin") is None
oversized_data = {"text": "a" * 2000}
res_oversized = client.post("/semantic/echo", json=oversized_data)
assert res_oversized.status_code == 413
res_slow = client.get("/semantic/slow")
assert res_slow.status_code == 504
def test_kill_switch(monkeypatch):
create_mock_modules()
monkeypatch.setenv("DISABLE_PROJECTS", "semantic")
import registry
registry.PROJECT_REGISTRY = {
"/semantic": "mock_semantic.router:router",
}
if "main" in sys.modules:
del sys.modules["main"]
import main
client = TestClient(main.app)
res_health = client.get("/health")
health_data = res_health.json()
assert "/semantic" not in health_data["loaded"]
assert "/semantic" not in health_data["failed"]
assert client.get("/semantic/ping").status_code == 404
def test_healthy_status_when_all_load(monkeypatch):
create_mock_modules()
monkeypatch.setenv("DISABLE_PROJECTS", "")
import registry
registry.PROJECT_REGISTRY = {
"/semantic": "mock_semantic.router:router",
}
if "main" in sys.modules:
del sys.modules["main"]
import main
client = TestClient(main.app)
res_health = client.get("/health")
assert res_health.status_code == 200
assert res_health.json()["status"] == "healthy"
assert "/semantic" in res_health.json()["loaded"]
res_root = client.get("/")
assert res_root.status_code == 200
assert res_root.json() == res_health.json()
def test_real_registry():
import importlib
import registry
importlib.reload(registry)
assert list(registry.PROJECT_REGISTRY.keys()) == ["/semantic"]
assert registry.PROJECT_REGISTRY["/semantic"] == "semantic_backend.router:router"
if "main" in sys.modules:
del sys.modules["main"]
import main
client = TestClient(main.app)
res = client.get("/health")
assert res.status_code == 200
data = res.json()
assert data["status"] == "healthy"
assert "/semantic" in data["loaded"]
assert not data["failed"]
res_root = client.get("/")
assert res_root.status_code == 200
assert res_root.json() == data
|