refactor: 移除独立 hub/proxy/executor/gateway crate,统一为 gateway tunnel 架构

- 删除 aether-hub、aether-proxy 独立项目及其 Dockerfile/配置
- 删除 crates/aether-executor 和 crates/aether-gateway 全部模块
- 新增 apps/ 目录作为应用入口
- 将 hub 概念重构为 gateway tunnel transport
- 将 executor 重构为 execution runtime
- 新增 tunnel.rs 合约定义和 testkit tunnel/execution_runtime 模块
- 更新 Python 服务层和测试适配新架构命名
This commit is contained in:
fawney19
2026-04-03 14:59:58 +08:00
parent ddf18fed9a
commit 8f26e1a31f
983 changed files with 103098 additions and 105837 deletions

View File

@@ -1,12 +1,12 @@
"""
aether-hub local relay 端到端测试
aether-gateway tunnel runtime harness 端到端测试
测试流程:
1. 启动 aether-hub(绑定随机端口)
2. 用 websockets 库模拟一个 aether-proxy client 连接到 Hub
1. 启动 aether-gateway 的 tunnel runtime harness(绑定随机端口)
2. 用 websockets 库模拟一个 aether-proxy client 连接到 tunnel runtime
3. Mock proxy 在收到请求帧后返回固定响应帧
4. 通过 Hub 的 /local/relay/{node_id} HTTP API 发送请求
5. 验证完整链路: HTTP request -> Hub -> WS frame -> mock proxy -> WS frame -> Hub -> HTTP response
4. 通过 /api/internal/tunnel/relay/{node_id} HTTP API 发送请求
5. 验证完整链路: HTTP request -> tunnel runtime -> WS frame -> mock proxy -> WS frame -> tunnel runtime -> HTTP response
运行: uv run python tests/e2e_hub_relay.py
"""
@@ -26,7 +26,7 @@ import time
import httpx
# ---------------------------------------------------------------------------
# Protocol constants (mirror aether-hub/src/protocol.rs)
# Protocol constants (mirror apps/aether-gateway/src/tunnel/embedded/protocol.rs)
# ---------------------------------------------------------------------------
HEADER_SIZE = 10
@@ -158,20 +158,30 @@ async def run_test() -> bool:
hub_binary = os.path.join(
os.path.dirname(__file__),
"..",
"aether-hub",
"target",
"release",
"aether-hub",
"examples",
"tunnel_runtime_harness",
)
hub_binary = os.path.normpath(hub_binary)
if not os.path.isfile(hub_binary):
print(f"FAIL: hub binary not found at {hub_binary}")
print(" run: cd aether-hub && cargo build --release")
return False
hub_binary = os.path.join(
os.path.dirname(__file__),
"..",
"target",
"debug",
"examples",
"tunnel_runtime_harness",
)
hub_binary = os.path.normpath(hub_binary)
if not os.path.isfile(hub_binary):
print(f"FAIL: tunnel runtime harness binary not found at {hub_binary}")
print(" run: cargo build -p aether-gateway --example tunnel_runtime_harness")
return False
# Start aether-hub (with control plane disabled since we don't have the app running)
print(f"[1/5] Starting aether-hub on {hub_bind} ...")
# Start tunnel runtime harness (with control plane disabled since we don't have the app running)
print(f"[1/5] Starting tunnel runtime harness on {hub_bind} ...")
hub_proc = subprocess.Popen(
[
hub_binary,
@@ -187,19 +197,19 @@ async def run_test() -> bool:
)
try:
# Wait for hub to be ready
# Wait for runtime to be ready
for _ in range(30):
await asyncio.sleep(0.2)
try:
async with httpx.AsyncClient() as client:
resp = await client.get(f"http://{hub_bind}/health", timeout=1.0)
if resp.status_code == 200:
print(" hub is healthy")
print(" tunnel runtime harness is healthy")
break
except Exception:
continue
else:
print("FAIL: hub did not start in time")
print("FAIL: tunnel runtime harness did not start in time")
return False
# Check initial stats
@@ -214,7 +224,9 @@ async def run_test() -> bool:
proxy_ready = asyncio.Event()
print(f"\n[2/5] Connecting mock proxy (node_id={node_id}) ...")
proxy_task = asyncio.create_task(
mock_proxy(f"ws://{hub_bind}/proxy", node_id, proxy_ready)
mock_proxy(
f"ws://{hub_bind}/api/internal/proxy-tunnel", node_id, proxy_ready
)
)
try:
@@ -223,7 +235,7 @@ async def run_test() -> bool:
print("FAIL: mock proxy did not connect in time")
return False
# Give hub a moment to register
# Give runtime a moment to register
await asyncio.sleep(0.3)
async with httpx.AsyncClient() as client:
@@ -249,7 +261,7 @@ async def run_test() -> bool:
)
async with httpx.AsyncClient() as client:
relay_url = f"http://{hub_bind}/local/relay/{node_id}"
relay_url = f"http://{hub_bind}/api/internal/tunnel/relay/{node_id}"
resp = await client.post(
relay_url,
content=envelope,
@@ -281,7 +293,7 @@ async def run_test() -> bool:
print(f"\n[5/5] Testing error cases ...")
async with httpx.AsyncClient() as client:
resp = await client.post(
f"http://{hub_bind}/local/relay/non-existent-node",
f"http://{hub_bind}/api/internal/tunnel/relay/non-existent-node",
content=encode_relay_envelope(
{"method": "GET", "url": "https://example.com", "headers": {}, "timeout": 5},
b"",