3 changed files with 209 additions and 113 deletions
@ -1,125 +1,167 @@ |
|||||
|
#!/usr/bin/env python3 |
||||
""" |
""" |
||||
测试心跳功能 |
测试WebSocket心跳任务启动功能 |
||||
|
验证心跳任务是否正确启动并发送心跳消息 |
||||
""" |
""" |
||||
import asyncio |
import asyncio |
||||
|
import sys |
||||
|
import os |
||||
import json |
import json |
||||
|
from datetime import datetime |
||||
|
|
||||
|
# 添加项目路径 |
||||
|
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) |
||||
|
|
||||
from app.core.websocket.manager import websocket_manager |
from app.core.websocket.manager import websocket_manager |
||||
|
from app.schemas.websocket import CreateWebSocketClientRequest |
||||
from app.utils.structured_log import get_structured_logger, LogLevel |
from app.utils.structured_log import get_structured_logger, LogLevel |
||||
|
|
||||
logger = get_structured_logger(__name__, LogLevel.INFO) |
logger = get_structured_logger(__name__, LogLevel.DEBUG) |
||||
|
|
||||
async def test_heartbeat_function(): |
async def test_heartbeat_task_startup(): |
||||
"""测试心跳功能""" |
"""测试心跳任务启动""" |
||||
logger.info("开始测试心跳功能") |
print("=== 测试心跳任务启动 ===") |
||||
|
|
||||
try: |
try: |
||||
# 1. 创建客户端(使用较短的心跳间隔进行测试) |
# 测试创建客户端(不实际连接) |
||||
logger.info("1. 创建客户端") |
client_name = "test_heartbeat_client" |
||||
client = await websocket_manager.create_client("test_heartbeat", "ws://localhost:8080", heartbeat_interval=5) |
client_url = "wss://localhost:8080" |
||||
logger.info(f"客户端创建成功: {client.name}") |
heartbeat_interval = 10 # 10秒心跳间隔,便于测试 |
||||
|
|
||||
# 2. 检查初始状态 |
print(f"创建客户端: {client_name} -> {client_url}") |
||||
logger.info("2. 检查初始状态") |
print(f"心跳间隔: {heartbeat_interval}秒") |
||||
stats = websocket_manager.get_stats() |
|
||||
logger.info(f"客户端数量: {stats['client_count']}") |
# 创建客户端 |
||||
logger.info(f"Channel数量: {stats['channel_count']}") |
client = await websocket_manager.create_client(client_name, client_url, heartbeat_interval) |
||||
logger.info(f"适配器数量: {stats['adapter_count']}") |
|
||||
logger.info(f"心跳任务数量: {stats['heartbeat_task_count']}") |
if client: |
||||
|
print(f"✅ 客户端创建成功: {client.name}") |
||||
# 3. 连接客户端 |
print(f" 状态: {client.state.value}") |
||||
logger.info("3. 连接客户端") |
print(f" 连接状态: {client.is_connected}") |
||||
success = await websocket_manager.connect_client("test_heartbeat") |
else: |
||||
logger.info(f"客户端连接成功: {success}") |
print("❌ 客户端创建失败") |
||||
|
return False |
||||
# 4. 等待心跳发送(等待10秒,应该能看到2次心跳) |
|
||||
logger.info("4. 等待心跳发送(10秒)") |
# 检查心跳任务是否存在 |
||||
for i in range(10): |
if client_name in websocket_manager._heartbeat_tasks: |
||||
await asyncio.sleep(1) |
heartbeat_task = websocket_manager._heartbeat_tasks[client_name] |
||||
logger.info(f"等待中... {i+1}/10") |
print(f"✅ 心跳任务存在: {heartbeat_task}") |
||||
|
print(f" 任务状态: {heartbeat_task.done()}") |
||||
# 检查心跳Channel的状态 |
print(f" 任务取消状态: {heartbeat_task.cancelled()}") |
||||
heartbeat_channel = websocket_manager.get_channel("test_heartbeat_heartbeat") |
else: |
||||
if heartbeat_channel: |
print("❌ 心跳任务不存在") |
||||
stats = heartbeat_channel.get_stats() |
return False |
||||
logger.info(f"心跳Channel状态: 队列大小={stats['total_queue_size']}, 消息数={stats['message_count']}") |
|
||||
|
# 检查心跳Channel是否存在 |
||||
# 5. 手动发送一次心跳 |
heartbeat_channel_name = f"{client_name}_heartbeat" |
||||
logger.info("5. 手动发送心跳") |
heartbeat_channel = websocket_manager.get_channel(heartbeat_channel_name) |
||||
success = await websocket_manager.send_heartbeat("test_heartbeat") |
|
||||
logger.info(f"手动心跳发送成功: {success}") |
|
||||
|
|
||||
# 6. 检查心跳Channel状态 |
|
||||
logger.info("6. 检查心跳Channel状态") |
|
||||
heartbeat_channel = websocket_manager.get_channel("test_heartbeat_heartbeat") |
|
||||
if heartbeat_channel: |
if heartbeat_channel: |
||||
stats = heartbeat_channel.get_stats() |
print(f"✅ 心跳Channel存在: {heartbeat_channel.name}") |
||||
logger.info(f"心跳Channel最终状态: {stats}") |
print(f" 连接状态: {heartbeat_channel.is_connected}") |
||||
|
else: |
||||
# 7. 移除客户端 |
print(f"❌ 心跳Channel不存在: {heartbeat_channel_name}") |
||||
logger.info("7. 移除客户端") |
return False |
||||
success = await websocket_manager.remove_client("test_heartbeat") |
|
||||
logger.info(f"客户端移除成功: {success}") |
# 等待一段时间,观察心跳消息 |
||||
|
print(f"等待 {heartbeat_interval + 2} 秒观察心跳消息...") |
||||
# 8. 检查最终状态 |
await asyncio.sleep(heartbeat_interval + 2) |
||||
logger.info("8. 检查最终状态") |
|
||||
stats = websocket_manager.get_stats() |
# 检查心跳任务是否仍在运行 |
||||
logger.info(f"最终状态: 客户端={stats['client_count']}, Channel={stats['channel_count']}, 适配器={stats['adapter_count']}, 心跳任务={stats['heartbeat_task_count']}") |
if client_name in websocket_manager._heartbeat_tasks: |
||||
|
heartbeat_task = websocket_manager._heartbeat_tasks[client_name] |
||||
logger.info("✅ 心跳功能测试完成") |
if not heartbeat_task.done(): |
||||
|
print("✅ 心跳任务仍在运行") |
||||
|
else: |
||||
|
print("❌ 心跳任务已结束") |
||||
|
if heartbeat_task.exception(): |
||||
|
print(f" 异常: {heartbeat_task.exception()}") |
||||
|
else: |
||||
|
print("❌ 心跳任务不存在") |
||||
|
|
||||
|
# 清理资源 |
||||
|
print("清理资源...") |
||||
|
await websocket_manager.remove_client(client_name) |
||||
|
print("✅ 资源清理完成") |
||||
|
|
||||
|
return True |
||||
|
|
||||
except Exception as e: |
except Exception as e: |
||||
logger.error(f"❌ 心跳功能测试失败: {e}") |
print(f"❌ 测试失败: {e}") |
||||
raise |
import traceback |
||||
|
traceback.print_exc() |
||||
|
return False |
||||
|
|
||||
async def test_heartbeat_without_connection(): |
async def test_heartbeat_with_connection(): |
||||
"""测试未连接状态下的心跳""" |
"""测试带连接的心跳功能""" |
||||
logger.info("开始测试未连接状态下的心跳") |
print("\n=== 测试带连接的心跳功能 ===") |
||||
|
|
||||
try: |
try: |
||||
# 1. 创建客户端但不连接 |
# 测试创建并连接客户端 |
||||
logger.info("1. 创建客户端但不连接") |
client_name = "test_heartbeat_connected" |
||||
client = await websocket_manager.create_client("test_heartbeat_no_conn", "ws://localhost:8080", heartbeat_interval=3) |
client_url = "wss://192.168.13.15:7268/ws" # 使用实际的WebSocket服务器 |
||||
logger.info(f"客户端创建成功: {client.name}") |
heartbeat_interval = 15 # 15秒心跳间隔 |
||||
|
|
||||
# 2. 等待一段时间,看心跳任务是否运行 |
print(f"创建并连接客户端: {client_name} -> {client_url}") |
||||
logger.info("2. 等待心跳任务运行(6秒)") |
print(f"心跳间隔: {heartbeat_interval}秒") |
||||
for i in range(6): |
|
||||
await asyncio.sleep(1) |
# 创建客户端 |
||||
logger.info(f"等待中... {i+1}/6") |
client = await websocket_manager.create_client(client_name, client_url, heartbeat_interval) |
||||
|
if not client: |
||||
# 检查心跳Channel的状态 |
print("❌ 客户端创建失败") |
||||
heartbeat_channel = websocket_manager.get_channel("test_heartbeat_no_conn_heartbeat") |
return False |
||||
if heartbeat_channel: |
|
||||
stats = heartbeat_channel.get_stats() |
# 连接客户端 |
||||
logger.info(f"心跳Channel状态: 队列大小={stats['total_queue_size']}, 消息数={stats['message_count']}") |
success = await websocket_manager.connect_client(client_name) |
||||
|
if not success: |
||||
# 3. 移除客户端 |
print("❌ 客户端连接失败") |
||||
logger.info("3. 移除客户端") |
return False |
||||
success = await websocket_manager.remove_client("test_heartbeat_no_conn") |
|
||||
logger.info(f"客户端移除成功: {success}") |
print("✅ 客户端连接成功") |
||||
|
|
||||
logger.info("✅ 未连接状态心跳测试完成") |
# 等待一段时间观察心跳 |
||||
|
print(f"等待 {heartbeat_interval + 5} 秒观察心跳...") |
||||
|
await asyncio.sleep(heartbeat_interval + 5) |
||||
|
|
||||
|
# 检查客户端状态 |
||||
|
client = websocket_manager.get_client(client_name) |
||||
|
if client and client.is_connected: |
||||
|
print("✅ 客户端仍保持连接") |
||||
|
else: |
||||
|
print("❌ 客户端连接已断开") |
||||
|
|
||||
|
# 清理资源 |
||||
|
print("清理资源...") |
||||
|
await websocket_manager.remove_client(client_name) |
||||
|
print("✅ 资源清理完成") |
||||
|
|
||||
|
return True |
||||
|
|
||||
except Exception as e: |
except Exception as e: |
||||
logger.error(f"❌ 未连接状态心跳测试失败: {e}") |
print(f"❌ 测试失败: {e}") |
||||
raise |
import traceback |
||||
|
traceback.print_exc() |
||||
|
return False |
||||
|
|
||||
async def main(): |
async def main(): |
||||
"""主测试函数""" |
"""主测试函数""" |
||||
logger.info("开始心跳功能测试") |
print("开始测试WebSocket心跳任务启动功能") |
||||
|
print("=" * 50) |
||||
|
|
||||
try: |
# 测试1:心跳任务启动 |
||||
# 测试正常心跳功能 |
success1 = await test_heartbeat_task_startup() |
||||
await test_heartbeat_function() |
|
||||
|
# 测试2:带连接的心跳功能 |
||||
# 测试未连接状态下的心跳 |
success2 = await test_heartbeat_with_connection() |
||||
await test_heartbeat_without_connection() |
|
||||
|
print("\n" + "=" * 50) |
||||
logger.info("🎉 所有心跳测试完成") |
print("测试结果汇总:") |
||||
|
print(f"心跳任务启动测试: {'✅ 通过' if success1 else '❌ 失败'}") |
||||
except Exception as e: |
print(f"带连接的心跳测试: {'✅ 通过' if success2 else '❌ 失败'}") |
||||
logger.error(f"❌ 测试失败: {e}") |
|
||||
raise |
if success1 and success2: |
||||
|
print("🎉 所有测试通过!") |
||||
|
else: |
||||
|
print("⚠️ 部分测试失败,请检查日志") |
||||
|
|
||||
if __name__ == "__main__": |
if __name__ == "__main__": |
||||
asyncio.run(main()) |
asyncio.run(main()) |
||||
Loading…
Reference in new issue