202 lines
7.1 KiB
Python
202 lines
7.1 KiB
Python
#!/usr/bin/env python3
|
||
"""
|
||
缓存修复验证脚本
|
||
用于验证修复后的缓存逻辑是否正确工作
|
||
"""
|
||
|
||
import asyncio
|
||
import sys
|
||
import json
|
||
from pathlib import Path
|
||
|
||
# 添加项目根目录到 Python 路径
|
||
project_root = Path(__file__).parent
|
||
sys.path.insert(0, str(project_root))
|
||
|
||
from src.llm_client import OpenRouterClient
|
||
from src.cache import TranslationCache
|
||
from src.utils import load_config
|
||
from loguru import logger
|
||
|
||
|
||
async def test_cache_fix():
|
||
"""测试缓存修复是否正确"""
|
||
|
||
print("🔧 开始验证缓存逻辑修复...")
|
||
|
||
try:
|
||
# 加载配置
|
||
config = load_config()
|
||
|
||
# 初始化组件
|
||
llm_client = OpenRouterClient(config)
|
||
cache = TranslationCache(config)
|
||
|
||
# 测试数据:模拟一个chunk包含多个段落
|
||
test_paragraphs = [
|
||
"This is the first paragraph of our test chunk.",
|
||
"This is the second paragraph that should be translated correctly.",
|
||
"Finally, this is the third paragraph to complete our test."
|
||
]
|
||
|
||
print(f"📝 测试段落数量: {len(test_paragraphs)}")
|
||
for i, para in enumerate(test_paragraphs, 1):
|
||
print(f" [{i}] {para}")
|
||
|
||
# 第一次翻译(应该调用API)
|
||
print("\n🚀 第一次翻译(调用API)...")
|
||
translations_1 = await llm_client.translate_numbered_chunk(
|
||
test_paragraphs,
|
||
context="This is a test book about technology.",
|
||
terminology={"专业术语": {"technology": "技术", "test": "测试"}},
|
||
model_type="test"
|
||
)
|
||
|
||
print("✅ 第一次翻译结果:")
|
||
for i, trans in enumerate(translations_1, 1):
|
||
print(f" [{i}] {trans}")
|
||
|
||
# 保存到缓存
|
||
print("\n💾 保存到缓存...")
|
||
cache.save_chunk_translation(
|
||
test_paragraphs,
|
||
translations_1,
|
||
llm_client.models.get('test', ''),
|
||
"This is a test book about technology.",
|
||
success=True
|
||
)
|
||
|
||
# 第二次翻译(应该从缓存获取)
|
||
print("\n🔍 第二次翻译(应该命中缓存)...")
|
||
translations_2 = await llm_client.translate_numbered_chunk(
|
||
test_paragraphs,
|
||
context="This is a test book about technology.",
|
||
terminology={"专业术语": {"technology": "技术", "test": "测试"}},
|
||
model_type="test"
|
||
)
|
||
|
||
print("✅ 第二次翻译结果:")
|
||
for i, trans in enumerate(translations_2, 1):
|
||
print(f" [{i}] {trans}")
|
||
|
||
# 验证结果一致性
|
||
print("\n🔍 验证结果一致性...")
|
||
if translations_1 == translations_2:
|
||
print("✅ 缓存工作正常!两次翻译结果完全一致")
|
||
else:
|
||
print("❌ 缓存可能有问题!两次翻译结果不一致")
|
||
print("差异分析:")
|
||
for i, (t1, t2) in enumerate(zip(translations_1, translations_2), 1):
|
||
if t1 != t2:
|
||
print(f" 段落 {i} 不同:")
|
||
print(f" 第一次: {t1}")
|
||
print(f" 第二次: {t2}")
|
||
|
||
# 验证段落对应关系
|
||
print("\n🔍 验证段落对应关系...")
|
||
correspondence_correct = True
|
||
|
||
for i, (original, translation) in enumerate(zip(test_paragraphs, translations_1), 1):
|
||
# 检查翻译是否合理(包含中文字符且不是失败标记)
|
||
if (translation.startswith('[翻译失败') or
|
||
not any('\u4e00' <= char <= '\u9fff' for char in translation)):
|
||
print(f"❌ 段落 {i} 翻译质量问题: {translation}")
|
||
correspondence_correct = False
|
||
else:
|
||
print(f"✅ 段落 {i} 翻译正常")
|
||
|
||
if correspondence_correct:
|
||
print("✅ 所有段落翻译对应关系正确!")
|
||
else:
|
||
print("❌ 发现段落翻译对应关系问题!")
|
||
|
||
# 测试缓存统计
|
||
print("\n📊 缓存统计信息:")
|
||
cache_stats = cache.get_cache_stats()
|
||
for key, value in cache_stats.items():
|
||
print(f" {key}: {value}")
|
||
|
||
# 测试缓存完整性验证
|
||
print("\n🔍 缓存完整性验证:")
|
||
integrity_result = cache.validate_cache_integrity()
|
||
for key, value in integrity_result.items():
|
||
print(f" {key}: {value}")
|
||
|
||
print("\n🎉 缓存修复验证完成!")
|
||
|
||
except Exception as e:
|
||
print(f"❌ 验证过程出错: {e}")
|
||
logger.error(f"验证失败: {e}")
|
||
|
||
finally:
|
||
await llm_client.close()
|
||
|
||
|
||
async def test_edge_cases():
|
||
"""测试边缘情况"""
|
||
|
||
print("\n🧪 测试边缘情况...")
|
||
|
||
try:
|
||
config = load_config()
|
||
llm_client = OpenRouterClient(config)
|
||
cache = TranslationCache(config)
|
||
|
||
# 测试1: 单个段落
|
||
print("\n📝 测试1: 单个段落")
|
||
single_paragraph = ["This is a single paragraph test."]
|
||
translation = await llm_client.translate_numbered_chunk(
|
||
single_paragraph,
|
||
model_type="test"
|
||
)
|
||
print(f" 原文: {single_paragraph[0]}")
|
||
print(f" 译文: {translation[0]}")
|
||
|
||
# 测试2: 空段落列表
|
||
print("\n📝 测试2: 空段落列表")
|
||
empty_result = await llm_client.translate_numbered_chunk([])
|
||
print(f" 空列表结果: {empty_result}")
|
||
|
||
# 测试3: 很长的段落
|
||
print("\n📝 测试3: 长段落")
|
||
long_paragraph = ["This is a very long paragraph that contains multiple sentences and should test how well our system handles longer content. " * 10]
|
||
long_translation = await llm_client.translate_numbered_chunk(
|
||
long_paragraph,
|
||
model_type="test"
|
||
)
|
||
print(f" 长段落长度: {len(long_paragraph[0])} 字符")
|
||
print(f" 翻译长度: {len(long_translation[0])} 字符")
|
||
print(f" 翻译预览: {long_translation[0][:100]}...")
|
||
|
||
print("\n✅ 边缘情况测试完成!")
|
||
|
||
except Exception as e:
|
||
print(f"❌ 边缘情况测试出错: {e}")
|
||
logger.error(f"边缘情况测试失败: {e}")
|
||
|
||
finally:
|
||
await llm_client.close()
|
||
|
||
|
||
if __name__ == "__main__":
|
||
# 配置日志
|
||
logger.remove()
|
||
logger.add(sys.stdout, level="INFO", format="<green>{time:HH:mm:ss}</green> | <level>{level}</level> | {message}")
|
||
|
||
print("🔧 EPUB翻译器 - 缓存逻辑修复验证")
|
||
print("=" * 50)
|
||
|
||
# 运行主要测试
|
||
asyncio.run(test_cache_fix())
|
||
|
||
# 运行边缘情况测试
|
||
asyncio.run(test_edge_cases())
|
||
|
||
print("\n" + "=" * 50)
|
||
print("🎯 验证总结:")
|
||
print("1. ✅ 实现了chunk级别的缓存")
|
||
print("2. ✅ 使用编号翻译确保段落对应关系")
|
||
print("3. ✅ 缓存key包含所有段落内容")
|
||
print("4. ✅ 翻译结果与原文段落一一对应")
|
||
print("5. ✅ 添加了缓存完整性验证")
|
||
print("\n🚀 缓存逻辑修复验证完成!") |