universal-fast-dubbing / backend /verify_backend_complete.py
cytopa99's picture
Upload 47 files
68e5689 verified
Raw History Blame Contribute Delete
23.6 kB
"""
后端完整性验证脚本
验证所有后端模块是否正常集成工作,包括:
- 核心处理模块
- 错误处理模块
- 日志记录模块
- 并行处理池
- 请求路由器
- API网关
Requirements: 检查点任务 11
"""
import sys
import os
import asyncio
from typing import Dict, List, Tuple
sys.path.insert(0, '.')
def print_header(title: str) -> None:
"""打印标题"""
print("\n" + "=" * 60)
print(f" {title}")
print("=" * 60)
def print_section(title: str) -> None:
"""打印章节标题"""
print(f"\n--- {title} ---")
def check_result(name: str, passed: bool, details: str = "") -> Tuple[str, bool]:
"""打印检查结果"""
status = "✓" if passed else "✗"
detail_str = f" ({details})" if details else ""
print(f" {status} {name}{detail_str}")
return (name, passed)
class BackendVerifier:
"""后端完整性验证器"""
def __init__(self):
self.results: List[Tuple[str, bool]] = []
def verify_imports(self) -> bool:
"""验证所有模块可以正确导入"""
print_section("模块导入检查")
all_passed = True
# 错误处理模块
try:
from modules import (
ErrorCode, ErrorType, ErrorResponse, ErrorFactory,
create_error_response
)
self.results.append(check_result("错误处理模块", True))
except Exception as e:
self.results.append(check_result("错误处理模块", False, str(e)))
all_passed = False
# 日志模块
try:
from modules import (
LogLevel, Component, StructuredLogRecord, ComponentLogger,
setup_logging, get_component_logger, log_performance
)
self.results.append(check_result("日志记录模块", True))
except Exception as e:
self.results.append(check_result("日志记录模块", False, str(e)))
all_passed = False
# Groq客户端
try:
from modules import (
GroqClient, GroqConfig, GroqError, GroqRateLimitError,
GroqTimeoutError, GroqAuthError, GroqConnectionError, RetryStats
)
self.results.append(check_result("Groq客户端模块", True))
except Exception as e:
self.results.append(check_result("Groq客户端模块", False, str(e)))
all_passed = False
# TTS生成器
try:
from modules import (
TTSGenerator, TTSConfig, TTSError, VoiceRole
)
self.results.append(check_result("TTS生成器模块", True))
except Exception as e:
self.results.append(check_result("TTS生成器模块", False, str(e)))
all_passed = False
# 智能分段器
try:
from modules import (
SmartSegmenter, SegmenterConfig, SegmenterError, SegmentInfo
)
self.results.append(check_result("智能分段器模块", True))
except Exception as e:
self.results.append(check_result("智能分段器模块", False, str(e)))
all_passed = False
# 音频同步引擎
try:
from modules import (
AudioSyncEngine, SyncConfig, AudioSyncError
)
self.results.append(check_result("音频同步引擎模块", True))
except Exception as e:
self.results.append(check_result("音频同步引擎模块", False, str(e)))
all_passed = False
# 并行处理池
try:
from modules import (
ParallelProcessingPool, ProcessorConfig, ProcessingError,
SegmentResult
)
self.results.append(check_result("并行处理池模块", True))
except Exception as e:
self.results.append(check_result("并行处理池模块", False, str(e)))
all_passed = False
# 请求路由器
try:
from modules import (
RequestRouter, RouterConfig, RouterError, URLNotSupportedError,
DownloadError, ProcessingMode
)
self.results.append(check_result("请求路由器模块", True))
except Exception as e:
self.results.append(check_result("请求路由器模块", False, str(e)))
all_passed = False
# API网关
try:
from modules import (
GradioAPIGateway, GatewayConfig, GatewayError, CacheEntry
)
self.results.append(check_result("API网关模块", True))
except Exception as e:
self.results.append(check_result("API网关模块", False, str(e)))
all_passed = False
return all_passed
def verify_error_handling(self) -> bool:
"""验证错误处理功能"""
print_section("错误处理功能检查")
all_passed = True
try:
from modules import (
ErrorCode, ErrorType, ErrorResponse, ErrorFactory
)
# 测试错误响应创建
error = ErrorResponse(
error_code=ErrorCode.GROQ_RATE_LIMIT,
error_type=ErrorType.RETRYABLE,
message="测试限流错误",
retry_available=True,
suggested_action="等待30秒后重试"
)
# 验证to_dict
error_dict = error.to_dict()
assert "error_code" in error_dict
assert "message" in error_dict
self.results.append(check_result("ErrorResponse.to_dict()", True))
# 验证to_user_message
user_msg = error.to_user_message()
assert "测试限流错误" in user_msg
self.results.append(check_result("ErrorResponse.to_user_message()", True))
# 测试工厂方法
rate_limit = ErrorFactory.create_groq_rate_limit_error(retry_after=30)
assert rate_limit.error_code == ErrorCode.GROQ_RATE_LIMIT
self.results.append(check_result("ErrorFactory.create_groq_rate_limit_error()", True))
timeout = ErrorFactory.create_groq_timeout_error(timeout=30, operation="语音识别")
assert timeout.error_code == ErrorCode.GROQ_TIMEOUT
self.results.append(check_result("ErrorFactory.create_groq_timeout_error()", True))
url_error = ErrorFactory.create_url_not_supported_error(url="https://test.com")
assert url_error.error_code == ErrorCode.URL_NOT_SUPPORTED
self.results.append(check_result("ErrorFactory.create_url_not_supported_error()", True))
except Exception as e:
self.results.append(check_result("错误处理功能", False, str(e)))
all_passed = False
return all_passed
def verify_logging(self) -> bool:
"""验证日志记录功能"""
print_section("日志记录功能检查")
all_passed = True
try:
from modules import (
Component, StructuredLogRecord, ComponentLogger,
get_component_logger, StructuredFormatter, HumanReadableFormatter
)
# 测试结构化日志记录
record = StructuredLogRecord(
timestamp="2024-01-01T00:00:00",
level="INFO",
component="Test",
message="测试消息",
session_id="test-session",
duration_ms=100.5
)
# 验证to_dict
record_dict = record.to_dict()
assert record_dict["component"] == "Test"
assert record_dict["duration_ms"] == 100.5
self.results.append(check_result("StructuredLogRecord.to_dict()", True))
# 验证to_json
json_str = record.to_json()
assert "Test" in json_str
assert "测试消息" in json_str
self.results.append(check_result("StructuredLogRecord.to_json()", True))
# 测试组件日志记录器
logger = get_component_logger(Component.GROQ_CLIENT)
assert logger.component == "GroqClient"
self.results.append(check_result("get_component_logger()", True))
# 测试格式化器
formatter = StructuredFormatter()
assert formatter is not None
self.results.append(check_result("StructuredFormatter", True))
human_formatter = HumanReadableFormatter(use_colors=False)
assert human_formatter is not None
self.results.append(check_result("HumanReadableFormatter", True))
except Exception as e:
self.results.append(check_result("日志记录功能", False, str(e)))
all_passed = False
return all_passed
def verify_groq_client(self) -> bool:
"""验证Groq客户端功能"""
print_section("Groq客户端功能检查")
all_passed = True
try:
from modules import GroqClient, GroqConfig, RetryStats
# 创建配置
config = GroqConfig(
api_key="test_key",
max_retries=3,
retry_base_delay=1.0,
retry_max_delay=30.0,
retry_jitter=True
)
# 创建客户端
client = GroqClient(config)
# 验证配置
assert client.asr_model == "whisper-large-v3-turbo"
assert client.llm_model == "llama3-8b-8192"
self.results.append(check_result("GroqClient配置", True))
# 验证重试统计
stats = client.get_retry_stats()
assert isinstance(stats, list)
self.results.append(check_result("GroqClient.get_retry_stats()", True))
# 验证退避延迟计算
delay0 = client._calculate_backoff_delay(0)
delay1 = client._calculate_backoff_delay(1)
delay2 = client._calculate_backoff_delay(2)
# 指数退避:delay应该递增
assert delay1 > delay0 * 0.8 # 考虑抖动
assert delay2 > delay1 * 0.8
self.results.append(check_result("指数退避延迟计算", True))
# 验证retry_after优先
delay_with_retry = client._calculate_backoff_delay(0, retry_after=10.0)
assert delay_with_retry == 10.0
self.results.append(check_result("retry_after优先级", True))
except Exception as e:
self.results.append(check_result("Groq客户端功能", False, str(e)))
all_passed = False
return all_passed
def verify_tts_generator(self) -> bool:
"""验证TTS生成器功能"""
print_section("TTS生成器功能检查")
all_passed = True
try:
from modules import TTSGenerator, VoiceRole
# 创建生成器
generator = TTSGenerator()
# 验证语音映射
voices = generator.get_available_voices()
assert "MALE" in voices
assert "FEMALE" in voices
assert "CHILD" in voices
assert "NARRATOR" in voices
self.results.append(check_result("语音角色映射", True))
# 验证语音模型
assert voices["MALE"] == "zh-CN-YunxiNeural"
assert voices["FEMALE"] == "zh-CN-XiaoxiaoNeural"
assert voices["CHILD"] == "zh-CN-YunjianNeural"
assert voices["NARRATOR"] == "zh-CN-YunyangNeural"
self.results.append(check_result("语音模型配置", True))
# 验证VoiceRole枚举
assert VoiceRole.MALE.value == "MALE"
assert VoiceRole.FEMALE.value == "FEMALE"
self.results.append(check_result("VoiceRole枚举", True))
except Exception as e:
self.results.append(check_result("TTS生成器功能", False, str(e)))
all_passed = False
return all_passed
def verify_segmenter(self) -> bool:
"""验证智能分段器功能"""
print_section("智能分段器功能检查")
all_passed = True
try:
from modules import SmartSegmenter, SegmenterConfig, SegmentInfo
# 创建分段器
segmenter = SmartSegmenter()
# 验证配置
assert segmenter.config.max_segment_duration == 480.0 # 8分钟
assert segmenter.config.min_segment_duration == 300.0 # 5分钟
assert segmenter.config.silence_threshold_db == -40.0
self.results.append(check_result("分段器配置", True))
# 验证should_segment方法存在
assert hasattr(segmenter, 'should_segment')
assert hasattr(segmenter, 'segment_audio')
self.results.append(check_result("分段器方法", True))
# 验证SegmentInfo数据类
segment = SegmentInfo(
index=0,
start_time=0.0,
end_time=300.0,
duration=300.0,
audio_path="test.wav"
)
assert segment.duration == 300.0
self.results.append(check_result("SegmentInfo数据类", True))
except Exception as e:
self.results.append(check_result("智能分段器功能", False, str(e)))
all_passed = False
return all_passed
def verify_audio_sync(self) -> bool:
"""验证音频同步引擎功能"""
print_section("音频同步引擎功能检查")
all_passed = True
try:
from modules import AudioSyncEngine, SyncConfig
# 创建同步引擎
engine = AudioSyncEngine()
# 验证配置
assert engine.config.max_speed_ratio == 1.4
assert engine.config.sync_tolerance == 0.3
self.results.append(check_result("同步引擎配置", True))
# 验证方法存在
assert hasattr(engine, 'align')
assert hasattr(engine, 'align_segment')
assert hasattr(engine, 'check_sync_drift')
self.results.append(check_result("同步引擎方法", True))
# 测试同步漂移检查(返回元组: (needs_correction, drift))
needs_correction, drift = engine.check_sync_drift(10.0, 10.2)
assert isinstance(drift, float)
assert drift < 0.3 # 偏差小于容差
assert needs_correction == False # 不需要校正
self.results.append(check_result("同步漂移检查", True))
except Exception as e:
self.results.append(check_result("音频同步引擎功能", False, str(e)))
all_passed = False
return all_passed
def verify_processor(self) -> bool:
"""验证并行处理池功能"""
print_section("并行处理池功能检查")
all_passed = True
try:
from modules import ParallelProcessingPool, ProcessorConfig, SegmentResult
# 创建处理池(不初始化,只检查结构)
config = ProcessorConfig(max_workers=3)
assert config.max_workers == 3
self.results.append(check_result("处理池配置", True))
# 验证SegmentResult数据类
result = SegmentResult(
index=0,
success=True,
audio_path="test.wav",
duration=100.0
)
assert result.success == True
self.results.append(check_result("SegmentResult数据类", True))
except Exception as e:
self.results.append(check_result("并行处理池功能", False, str(e)))
all_passed = False
return all_passed
def verify_router(self) -> bool:
"""验证请求路由器功能"""
print_section("请求路由器功能检查")
all_passed = True
try:
from modules import RequestRouter, ProcessingMode
# 创建路由器
router = RequestRouter()
# 验证处理模式枚举
assert ProcessingMode.URL.value == "url"
assert ProcessingMode.RECORD.value == "record"
self.results.append(check_result("ProcessingMode枚举", True))
# 验证URL检测方法
assert hasattr(router, 'detect_platform')
assert hasattr(router, 'route_request')
self.results.append(check_result("路由器方法", True))
# 测试平台检测(返回元组: (platform, supports_url))
platform, supports_url = router.detect_platform("https://www.youtube.com/watch?v=test")
assert platform == "youtube"
assert supports_url == True
self.results.append(check_result("YouTube平台检测", True))
platform, supports_url = router.detect_platform("https://www.bilibili.com/video/BV123")
assert platform == "bilibili"
assert supports_url == True
self.results.append(check_result("Bilibili平台检测", True))
# 测试仅录制模式平台
platform, supports_url = router.detect_platform("https://www.netflix.com/watch/123")
assert platform == "netflix"
assert supports_url == False
self.results.append(check_result("Netflix录制模式检测", True))
except Exception as e:
self.results.append(check_result("请求路由器功能", False, str(e)))
all_passed = False
return all_passed
def verify_gateway(self) -> bool:
"""验证API网关功能"""
print_section("API网关功能检查")
all_passed = True
try:
from modules import GradioAPIGateway, GatewayConfig, CacheEntry
from datetime import datetime, timedelta
# 验证配置
config = GatewayConfig(
cache_duration=3600,
max_sessions=10
)
assert config.cache_duration == 3600
self.results.append(check_result("网关配置", True))
# 验证CacheEntry
now = datetime.now()
cache = CacheEntry(
result={"test": "data"},
created_at=now,
expires_at=now + timedelta(hours=1)
)
assert not cache.is_expired()
self.results.append(check_result("CacheEntry功能", True))
# 验证过期检测
expired_cache = CacheEntry(
result={"test": "data"},
created_at=now - timedelta(hours=2),
expires_at=now - timedelta(hours=1)
)
assert expired_cache.is_expired()
self.results.append(check_result("缓存过期检测", True))
except Exception as e:
self.results.append(check_result("API网关功能", False, str(e)))
all_passed = False
return all_passed
def verify_error_integration(self) -> bool:
"""验证错误处理集成"""
print_section("错误处理集成检查")
all_passed = True
try:
from modules import (
ErrorFactory, GroqRateLimitError, GroqTimeoutError,
URLNotSupportedError
)
# 测试从异常创建错误响应
rate_limit_exc = GroqRateLimitError(retry_after=30)
error_response = ErrorFactory.from_exception(rate_limit_exc)
assert error_response.retry_available == True
self.results.append(check_result("GroqRateLimitError转换", True))
timeout_exc = GroqTimeoutError(timeout=30, operation="测试")
error_response = ErrorFactory.from_exception(timeout_exc)
assert "超时" in error_response.message
self.results.append(check_result("GroqTimeoutError转换", True))
except Exception as e:
self.results.append(check_result("错误处理集成", False, str(e)))
all_passed = False
return all_passed
def run_all_verifications(self) -> bool:
"""运行所有验证"""
print_header("Universal Fast Dubbing - 后端完整性验证")
# 运行各项验证
self.verify_imports()
self.verify_error_handling()
self.verify_logging()
self.verify_groq_client()
self.verify_tts_generator()
self.verify_segmenter()
self.verify_audio_sync()
self.verify_processor()
self.verify_router()
self.verify_gateway()
self.verify_error_integration()
# 汇总结果
print_header("验证结果汇总")
passed = sum(1 for _, p in self.results if p)
failed = sum(1 for _, p in self.results if not p)
total = len(self.results)
print(f"\n 总计: {total} 项检查")
print(f" 通过: {passed} 项")
print(f" 失败: {failed} 项")
print(f" 通过率: {passed/total*100:.1f}%")
if failed > 0:
print("\n 失败项目:")
for name, p in self.results:
if not p:
print(f" ✗ {name}")
print("\n" + "=" * 60)
if failed == 0:
print(" ✓ 后端完整性验证通过!")
else:
print(" ✗ 后端完整性验证失败,请检查上述问题")
print("=" * 60)
return failed == 0
def main():
"""主函数"""
verifier = BackendVerifier()
success = verifier.run_all_verifications()
return 0 if success else 1
if __name__ == "__main__":
sys.exit(main())