Files
my-daily/ai-daily-main/tests/test_push_loop.py
T

114 lines
3.4 KiB
Python

#!/usr/bin/env python3
"""测试 push_loop 时间逻辑 - 直接调用 main.py"""
import asyncio
import sys
from datetime import datetime, timedelta
from pathlib import Path
from unittest.mock import patch
sys.path.insert(0, str(Path(__file__).parent.parent))
from src.config import get_timezone, load_config
# 记录调用时间
call_times = []
async def mock_run_push_job(config):
"""模拟 push job"""
now = datetime.now(get_timezone(config))
call_times.append(now)
print(f"\n{'='*40}")
print(f"📤 Mock Push Job 被调用 | {now.strftime('%Y-%m-%d %H:%M:%S')}")
print(f"{'='*40}\n")
async def main():
print("🧪 测试 push_loop 时间逻辑")
print("="*50)
# 加载配置
config = load_config()
tz = get_timezone(config)
# 动态设置 cron:约 30 秒后 和 60 秒后触发
# 标准 cron 是5字段(分 时 日 月 周),通过计算实现秒级等待
now = datetime.now(tz)
# 计算等待时间:
# 第一次:约 30 秒后(下一分钟,等待 = 60 - 当前秒数)
# 第二次:约 60 秒后(下两分钟,等待 = 120 - 当前秒数)
sec_to_wait_1 = 60 - now.second # 到下一分钟的剩余秒数
sec_to_wait_2 = sec_to_wait_1 + 60 # 再加一分钟
min_1 = (now.minute + 1) % 60
min_2 = (now.minute + 2) % 60
cron1 = f"{min_1} {now.hour} * * *"
cron2 = f"{min_2} {now.hour} * * *"
config['schedule']['push_cron'] = [cron1, cron2]
print(f"\n当前时间: {now.strftime('%H:%M:%S')}")
print(f"测试配置:")
print(f" - 第1次推送: {cron1} (约 {sec_to_wait_1}s 后)")
print(f" - 第2次推送: {cron2} (约 {sec_to_wait_2}s 后)")
print()
# 使用 patch mock run_push_job,设置超时 3 分钟
from src import main as main_module
test_task = None
push_task = None
async def run_test():
with patch.object(main_module, 'run_push_job', mock_run_push_job):
await main_module.push_loop(config)
async def timeout_guard():
await asyncio.sleep(180) # 3分钟超时
print("\n⏱️ 测试超时")
if push_task:
push_task.cancel()
try:
# 同时运行 push_loop 和超时守卫
push_task = asyncio.create_task(run_test())
timeout_task = asyncio.create_task(timeout_guard())
# 等待 push_task 完成或超时
while push_task and not push_task.done():
if len(call_times) >= 2:
push_task.cancel()
break
await asyncio.sleep(0.1)
timeout_task.cancel()
except asyncio.CancelledError:
pass
# 验证结果
print("\n" + "="*50)
print("📊 测试结果验证")
print("="*50)
if len(call_times) >= 2:
print(f"✅ 成功调用 {len(call_times)} 次")
for i, t in enumerate(call_times, 1):
print(f" 第{i}次: {t.strftime('%H:%M:%S')}")
interval = (call_times[1] - call_times[0]).total_seconds()
print(f"\n实际间隔: {interval:.1f} 秒")
if 55 <= interval <= 65:
print("✅ 间隔正确 (约60秒)")
else:
print(f"⚠️ 间隔异常 (期望 ~60秒)")
else:
print(f"❌ 只调用了 {len(call_times)} 次,期望 2 次")
if __name__ == "__main__":
try:
asyncio.run(main())
except KeyboardInterrupt:
print("\n\n👋 测试已取消")
sys.exit(130)