api_test.py 4.75 KB
"""
api_test.py - 对 api.py 中 FootballReplayMatch.replay_match_event 的测试

使用伪数据覆盖主要分支:
1. 时间阈值内直接匹配成功
2. 时间匹配失败 + LLM 判定不是进球
3. 时间匹配失败 + LLM 判定是进球 + LLM 匹配成功
4. 时间匹配失败 + LLM 判定是进球 + LLM 匹配失败
5. 无进球事件 / events 为空
6. 边界:缺少 replay 键时抛出异常
"""
import os
import time
import unittest
from types import SimpleNamespace
from unittest.mock import MagicMock, patch

try:
    from api import FootballReplayMatch
except ImportError:
    from .api import FootballReplayMatch
    
from pathlib import Path
def get_video_files_pathlib(folder_path, extensions=None):
    if extensions is None:
        extensions = {'.mp4'}
    else:
        extensions = {ext.lower() for ext in extensions}
    
    folder = Path(folder_path)
    image_files = [f.name for f in folder.iterdir() 
                   if f.is_file() and f.suffix.lower() in extensions]
    return sorted(image_files)

def _fake_settings():
    """构造一个 settings 伪对象,兼容 api.py 中的 value_or_default 读取逻辑。"""
    return SimpleNamespace(
        match_by_time_threshold=30,
        llm=SimpleNamespace(base_url="http://192.168.1.59:11434/v1", 
                            model_name="Qwen3.6-35B-A3B-UD-Q8_K_XL.gguf", 
                            temperature=0.7, 
                            api_key='no_key'
                            ),
        common=SimpleNamespace(cache_dir=f"/root/lzw/tmp_0602_replay_cache/videos_cache", 
                               task_log_dir=f"/root/lzw/tmp_0602_replay_cache/tasks_log"
                               ),
        save_frames_enable=True,
    )


def get_replays_and_events_pair():
    
    videos_dir = rf"/root/lzw/finished"
    
    dir_pairs = []
    for video_name in sorted(os.listdir(videos_dir)):

        live_dir = os.path.join(videos_dir, video_name, 'live')
        live_video_dir = os.path.join(live_dir, 'videos')
        
        replays_dir = os.path.join(videos_dir, video_name, 'replays')
        replay_videos_dir = os.path.join(replays_dir, 'videos')
        
        dir_pairs.append((replay_videos_dir, live_video_dir))
    return dir_pairs



def get_event_list(events_mp4_dir):
    # url = "http://video.mam.miguvideo.com/mnt6/fastclip3/wsc/2026/04/29/df760b8d15394cbc9ed0d0a4a9c4b786_1080PS/29133605/vodtmp/3b3e99cf4ca84c3782503d8817242de2.m3u8"
    # events_mp4_dir = r"/root/lzw/finished/69dd5845dd0412067b8d5587-auto-1776074760653/live/videos"
    
    events_mp4_names = get_video_files_pathlib(events_mp4_dir)
    
    event_lis = []
    for mp4 in events_mp4_names:
        mp4_path = os.path.join(events_mp4_dir, mp4)
        event_lis.append({
            "id": mp4,
            "type": "1",
            "url": mp4_path,
            # "event_utc": None
        })
    return event_lis

def _base_data(i, replay_path, event_lis):

    return {
        "id": f"task_{str(i).zfill(3)}",
        "match_id": f"match_{str(i).zfill(3)}",
        "replay": {
            "id": os.path.basename(replay_path),
            "url": replay_path,
            # "start_utc": None,
            # "end_utc": None
        },
        "events": event_lis,
    }


def test_match_by_time_success():

    replays_and_events_pair = get_replays_and_events_pair()
    for replays_mp4_dir, events_mp4_dir in replays_and_events_pair:
        # replays_mp4_dir = "/root/lzw/finished/69e5102bfd87d43d09bba90d-auto-10154993/replays/videos"
        # events_mp4_dir = r"/root/lzw/finished/69e5102bfd87d43d09bba90d-auto-10154993/live/videos"
        print(100*"=")
        print(f"replays_mp4_dir: {replays_mp4_dir}, events_mp4_dir: {events_mp4_dir}")
        
        settings = _fake_settings()
        frm = FootballReplayMatch(settings)

        relays_mp4_names = get_video_files_pathlib(replays_mp4_dir)
        event_list = get_event_list(events_mp4_dir)
        
        all_time = 0.0
        max_time = 0.0
        for i, replay_name in enumerate(relays_mp4_names):
            print(100*"*")
            replay_path = os.path.join(replays_mp4_dir, replay_name)
            data = _base_data(i+1, replay_path, event_list)
            
            start_time = time.time()
            result = frm.replay_match_event(data)
            end_time = time.time()
            cost_time = end_time - start_time
            all_time += cost_time
            print(f"replay_name: {replay_name}, cost time:{cost_time}")
            if max_time < cost_time:
                max_time = cost_time
            
            print(result)
            print()
            print()
            
        print(100*"#")
        print(f"max_time: {max_time}")
        print(f"all_time: {all_time}")
        # exit()

if __name__ == "__main__":
    test_match_by_time_success()