108 lines
4.0 KiB
Python
108 lines
4.0 KiB
Python
"""应用级 API 冒烟测试。
|
|
|
|
使用 FastAPI TestClient 验证健康检查、静态页面、节点注册校验以及
|
|
节点生命周期与手动调用等真实链路。
|
|
"""
|
|
|
|
import json
|
|
from pathlib import Path
|
|
|
|
from fastapi.testclient import TestClient
|
|
|
|
from app.main import app
|
|
|
|
WORKSPACE = Path(__file__).resolve().parent.parent.parent
|
|
# 直接读取 Echo 节点 manifest 作为注册测试的真实数据。
|
|
ECHO_MANIFEST = json.loads(
|
|
(WORKSPACE / "wov-node-echo" / "node.manifest.json").read_text(encoding="utf-8")
|
|
)
|
|
|
|
|
|
def test_health() -> None:
|
|
"""验证静态首页、OpenAPI 文档与健康探针均可访问。"""
|
|
with TestClient(app) as client:
|
|
root = client.get("/", follow_redirects=False)
|
|
assert root.status_code == 200
|
|
assert "WOV 应用中心" in root.text
|
|
|
|
docs = client.get("/docs")
|
|
assert docs.status_code == 200
|
|
|
|
response = client.get("/health")
|
|
assert response.status_code == 200
|
|
assert response.json()["service"] == "wov-api"
|
|
|
|
|
|
def test_register_validation_errors() -> None:
|
|
"""验证非法节点注册请求会被 Pydantic 或协议校验拒绝。"""
|
|
with TestClient(app) as client:
|
|
assert client.post("/api/admin/nodes", json={}).status_code == 422
|
|
invalid = dict(ECHO_MANIFEST, id="")
|
|
assert client.post("/api/admin/nodes", json=invalid).status_code == 422
|
|
invalid = dict(ECHO_MANIFEST, repo_dir="")
|
|
assert client.post("/api/admin/nodes", json=invalid).status_code == 422
|
|
invalid = dict(ECHO_MANIFEST, max_concurrency=0)
|
|
assert client.post("/api/admin/nodes", json=invalid).status_code == 422
|
|
|
|
|
|
def test_node_lifecycle_and_invoke() -> None:
|
|
"""验证注册、查询、调用、停止与删除节点的完整生命周期。"""
|
|
with TestClient(app) as client:
|
|
registered = client.post("/api/admin/nodes", json=ECHO_MANIFEST)
|
|
assert registered.status_code == 200
|
|
assert registered.json()["id"] == "echo"
|
|
|
|
nodes = client.get("/api/admin/nodes")
|
|
assert nodes.status_code == 200
|
|
assert [node["id"] for node in nodes.json()] == ["echo"]
|
|
|
|
node = client.get("/api/admin/nodes/echo")
|
|
assert node.status_code == 200
|
|
assert node.json()["capability"] == "echo"
|
|
|
|
assert client.get("/api/admin/nodes/missing").status_code == 404
|
|
|
|
invoked = client.post(
|
|
"/api/admin/nodes/echo/invoke",
|
|
json={
|
|
"run_id": "run_api",
|
|
"inputs": {"text": "api test"},
|
|
"params": {},
|
|
},
|
|
)
|
|
assert invoked.status_code == 200
|
|
assert invoked.json()["status"] == "completed"
|
|
assert invoked.json()["outputs"]["text"] == "api test"
|
|
|
|
invoked_default = client.post(
|
|
"/api/admin/nodes/echo/invoke",
|
|
json={"inputs": {}},
|
|
)
|
|
assert invoked_default.status_code == 200
|
|
assert invoked_default.json()["status"] == "completed"
|
|
assert invoked_default.json()["outputs"]["text"] == "echo"
|
|
|
|
instances = client.get("/api/admin/node-instances")
|
|
assert instances.status_code == 200
|
|
assert len(instances.json()) >= 1
|
|
instance_id = instances.json()[0]["id"]
|
|
|
|
node_instances = client.get("/api/admin/nodes/echo/instances")
|
|
assert node_instances.status_code == 200
|
|
assert node_instances.json()[0]["id"] == instance_id
|
|
|
|
assert client.get("/api/admin/nodes/missing/instances").status_code == 404
|
|
|
|
stopped = client.post(f"/api/admin/node-instances/{instance_id}/stop")
|
|
assert stopped.status_code == 200
|
|
assert stopped.json()["stopped"] == instance_id
|
|
|
|
assert client.post("/api/admin/node-instances/missing/stop").status_code == 404
|
|
|
|
deleted = client.delete("/api/admin/nodes/echo")
|
|
assert deleted.status_code == 200
|
|
assert deleted.json()["deleted"] == "echo"
|
|
|
|
assert client.get("/api/admin/nodes/echo").status_code == 404
|
|
assert client.delete("/api/admin/nodes/echo").status_code == 404
|