test(wave135): 视频拼接引擎纯逻辑抽离 + 70单测 #1049

Closed
xiaoxia wants to merge 1 commits from test/wave135-concat-engine-pure into develop
Owner

变更内容

新增纯逻辑模块 concat_engine_pure.py

concat_engine.py 中抽离所有纯函数,0 FFmpeg 依赖:

分类 函数 说明
帧率 parse_fps / format_fps_filter 帧率字符串解析(支持分数格式)
参数计算 resolve_output_params / calculate_scaled_size 输出参数解析、等比缩放+黑边
Stream Copy can_use_stream_copy 判断是否可以无损拼接
文件列表 generate_concat_file_list demuxer模式文件列表生成
滤镜构建 build_scale_pad_filter / build_fps_filter / build_concat_filter / build_single_segment_filter_chain 拼接滤镜链组件
配置验证 validate_concat_config / validate_video_path 配置合法性 + 路径安全
工具 estimate_total_duration / count_valid_segments 时长统计、有效段统计

70个单元测试

测试类 数量
TestParseFps 10
TestFormatFpsFilter 3
TestResolveOutputParams 6
TestCalculateScaledSize 6
TestCanUseStreamCopy 9
TestGenerateConcatFileList 5
TestBuildScalePadFilter 4
TestBuildFpsFilter 2
TestBuildConcatFilter 4
TestBuildSingleSegmentFilterChain 3
TestValidateConcatConfig 7
TestValidateVideoPath 5
TestEstimateTotalDuration 4
TestCountValidSegments 3

向后兼容

  • concat_engine.py 未修改,不影响现有功能
  • 后续可逐步迁移到使用 pure 模块

纯函数,无外部依赖,本地70测全绿。

## 变更内容 ### 新增纯逻辑模块 `concat_engine_pure.py` 从 `concat_engine.py` 中抽离所有纯函数,0 FFmpeg 依赖: | 分类 | 函数 | 说明 | |------|------|------| | 帧率 | `parse_fps` / `format_fps_filter` | 帧率字符串解析(支持分数格式) | | 参数计算 | `resolve_output_params` / `calculate_scaled_size` | 输出参数解析、等比缩放+黑边 | | Stream Copy | `can_use_stream_copy` | 判断是否可以无损拼接 | | 文件列表 | `generate_concat_file_list` | demuxer模式文件列表生成 | | 滤镜构建 | `build_scale_pad_filter` / `build_fps_filter` / `build_concat_filter` / `build_single_segment_filter_chain` | 拼接滤镜链组件 | | 配置验证 | `validate_concat_config` / `validate_video_path` | 配置合法性 + 路径安全 | | 工具 | `estimate_total_duration` / `count_valid_segments` | 时长统计、有效段统计 | ### 70个单元测试 | 测试类 | 数量 | |--------|------| | TestParseFps | 10 | | TestFormatFpsFilter | 3 | | TestResolveOutputParams | 6 | | TestCalculateScaledSize | 6 | | TestCanUseStreamCopy | 9 | | TestGenerateConcatFileList | 5 | | TestBuildScalePadFilter | 4 | | TestBuildFpsFilter | 2 | | TestBuildConcatFilter | 4 | | TestBuildSingleSegmentFilterChain | 3 | | TestValidateConcatConfig | 7 | | TestValidateVideoPath | 5 | | TestEstimateTotalDuration | 4 | | TestCountValidSegments | 3 | ### 向后兼容 - 原 `concat_engine.py` 未修改,不影响现有功能 - 后续可逐步迁移到使用 pure 模块 --- 纯函数,无外部依赖,本地70测全绿。
xiaoxia added 1 commit 2026-07-28 09:23:50 +08:00
test(wave135): 视频拼接引擎纯逻辑抽离 + 70单测
PR Automation / Auto Approve on CI Green (pull_request) Successful in 4m36s
PR Automation / Auto Merge on CI Green + Approved (pull_request) Successful in 17m23s
CI/CD Pipeline / Check if frontend-only change (pull_request) Successful in 25s
CI/CD Pipeline / Validate - Type Check (mypy) (pull_request) Successful in 1m9s
CI/CD Pipeline / Frontend Lint (pull_request) Successful in 59s
CI/CD Pipeline / Build Staging API Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging Web Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging Worker Image (pull_request) Has been skipped
CI/CD Pipeline / Validate - Migration (alembic) (pull_request) Successful in 1m15s
CI/CD Pipeline / Validate - Code Quality (pull_request) Failing after 2m50s
Preview Deploy / Deploy Preview Environment (pull_request) Successful in 1m13s
CI/CD Pipeline / PR Build Web Image (pull_request) Successful in 2m16s
CI/CD Pipeline / PR Build Worker Image (pull_request) Successful in 2m0s
CI/CD Pipeline / PR Build API Image (pull_request) Successful in 6m0s
AI Code Review / AI Code Review (pull_request) Failing after 6m56s
CI/CD Pipeline / Frontend Unit Tests (pull_request) Has been skipped
CI/CD Pipeline / Build Production API Image (pull_request) Has been skipped
CI/CD Pipeline / Build Production Web Image (pull_request) Has been skipped
CI/CD Pipeline / Build Production Worker Image (pull_request) Has been skipped
CI/CD Pipeline / Deploy Staging (Watchtower auto-deploy) (pull_request) Has been skipped
CI/CD Pipeline / Integration Tests (pull_request) Successful in 4m48s
CI/CD Pipeline / Unit Tests (pull_request) Successful in 6m9s
CI/CD Pipeline / Deploy Production (pull_request) Has been skipped
CI/CD Pipeline / Staging E2E Tests (pull_request) Has been skipped
CI/CD Pipeline / Staging API Integration Tests (pull_request) Has been skipped
CI/CD Pipeline / ACR Image Cleanup (pull_request) Has been skipped
CI/CD Pipeline / Canary Release to Production (pull_request) Has been cancelled
CI/CD Pipeline / CI Gate (pull_request) Successful in 35s
CI/CD Pipeline / Production Browser E2E (pull_request) Has been skipped
ACR Cleanup / ACR Image Cleanup (pull_request_target) Has been cancelled
Preview Cleanup / Cleanup Preview Environment (pull_request) Successful in 23s
c0df12679d
- 新增 concat_engine_pure.py:帧率解析/输出参数计算/缩放填充/stream copy判断/文件列表生成/滤镜链构建/配置验证/路径验证
- 70个单测覆盖:parse_fps/resolve_output_params/calculate_scaled_size/can_use_stream_copy/generate_file_list/滤镜构建/配置验证/路径验证
- 0 FFmpeg依赖,纯函数可测试

🚀 预览环境已部署

项目 详情
PR号 #1049
预览链接 https://pr-1049.preview.xiaoxiajianji.com
API环境 staging

💡 预览环境使用 staging API 数据,请勿在预览环境中操作重要数据。

🔄 每次提交新代码后预览环境会自动更新。

🗑️ PR 关闭或合并后,预览环境会自动清理。

🚀 **预览环境已部署** | 项目 | 详情 | |------|------| | PR号 | #1049 | | 预览链接 | [https://pr-1049.preview.xiaoxiajianji.com](https://pr-1049.preview.xiaoxiajianji.com) | | API环境 | staging | > 💡 预览环境使用 staging API 数据,请勿在预览环境中操作重要数据。 > > 🔄 每次提交新代码后预览环境会自动更新。 > > 🗑️ PR 关闭或合并后,预览环境会自动清理。
Collaborator

【阻塞级判定】

  • 是否存在阻塞级问题:是
  • 阻塞级问题数量:2 个

📊 审查概览

  • 整体评价:需修改
  • 建议级问题数量:2 个

🔴 阻塞级问题(必须修复)

  1. [apps/worker/video_processing/concat_engine_pure.py: 440] 路径遍历安全漏洞

    • 问题类型:安全漏洞
    • 问题描述:在 validate_video_path 函数中,使用 str(video_abs).startswith(str(work_abs)) 来判断路径是否在工作目录内。这种前缀匹配方式存在严重安全漏洞,攻击者可以利用目录名包含关系绕过检查。例如,工作目录为 /safe/work,攻击者传入路径 /safe/work_backup/file.mp4,由于 /safe/work_backup/safe/work 开头,检查会错误地通过,导致允许访问工作目录之外的文件。
    • 修改建议:应使用 Path.is_relative_to()(Python 3.9+)或检查 str(video_abs) + os.sep 前缀,确保路径严格在工作目录及其子目录下。
  2. [tests/unit/test_concat_engine_pure.py: 272] 测试代码语法/逻辑错误

    • 问题类型:逻辑bug / 语法错误
    • 问题描述:在 test_path_with_single_quote 测试用例中,断言语句 assert "'\\''" in result or file 存在错误。变量 file 未定义(除非是指内置类型,但在此上下文中显然是拼写错误或残留代码)。这会导致测试运行时抛出 NameError,且由于 or file 的存在,如果解释为内置类型对象,该断言将恒为 True,导致测试失效,无法验证单引号转义逻辑的正确性。
    • 修改建议:删除 or file,修改为 assert "'\\''" in result

💡 改进建议(不阻塞合并)

  1. [apps/worker/video_processing/concat_engine_pure.py: 325] 文件列表生成未处理换行符

    • 具体内容:在 generate_concat_file_list 函数中,仅转义了单引号。如果文件路径中包含换行符(\n),会破坏 concat demuxer 的文件格式,导致解析错误。建议增加对换行符的检查或过滤。
  2. [apps/worker/video_processing/concat_engine_pure.py: 398] 冗余逻辑判断

    • 具体内容:在 validate_concat_config 函数中,先判断了 if not segments 并返回,随后又判断 if len(segments) < 1。这两个条件是等价的,且第一个判断已经处理了空列表情况,第二个判断永远不会执行。建议删除冗余代码。

格式检查通过 | 逻辑审查需修改 | ⚠️ 建议关注性能


🤖 由 AI 代码审查机器人自动生成 | 2026-07-28 01:29:39 | 模型:

### 【阻塞级判定】 - 是否存在阻塞级问题:是 - 阻塞级问题数量:2 个 ### 📊 审查概览 - 整体评价:需修改 - 建议级问题数量:2 个 ### 🔴 阻塞级问题(必须修复) 1. **[apps/worker/video_processing/concat_engine_pure.py: 440] 路径遍历安全漏洞** - 问题类型:安全漏洞 - 问题描述:在 `validate_video_path` 函数中,使用 `str(video_abs).startswith(str(work_abs))` 来判断路径是否在工作目录内。这种前缀匹配方式存在严重安全漏洞,攻击者可以利用目录名包含关系绕过检查。例如,工作目录为 `/safe/work`,攻击者传入路径 `/safe/work_backup/file.mp4`,由于 `/safe/work_backup` 以 `/safe/work` 开头,检查会错误地通过,导致允许访问工作目录之外的文件。 - 修改建议:应使用 `Path.is_relative_to()`(Python 3.9+)或检查 `str(video_abs) + os.sep` 前缀,确保路径严格在工作目录及其子目录下。 2. **[tests/unit/test_concat_engine_pure.py: 272] 测试代码语法/逻辑错误** - 问题类型:逻辑bug / 语法错误 - 问题描述:在 `test_path_with_single_quote` 测试用例中,断言语句 `assert "'\\''" in result or file` 存在错误。变量 `file` 未定义(除非是指内置类型,但在此上下文中显然是拼写错误或残留代码)。这会导致测试运行时抛出 `NameError`,且由于 `or file` 的存在,如果解释为内置类型对象,该断言将恒为 True,导致测试失效,无法验证单引号转义逻辑的正确性。 - 修改建议:删除 `or file`,修改为 `assert "'\\''" in result`。 ### 💡 改进建议(不阻塞合并) 1. **[apps/worker/video_processing/concat_engine_pure.py: 325] 文件列表生成未处理换行符** - 具体内容:在 `generate_concat_file_list` 函数中,仅转义了单引号。如果文件路径中包含换行符(`\n`),会破坏 concat demuxer 的文件格式,导致解析错误。建议增加对换行符的检查或过滤。 2. **[apps/worker/video_processing/concat_engine_pure.py: 398] 冗余逻辑判断** - 具体内容:在 `validate_concat_config` 函数中,先判断了 `if not segments` 并返回,随后又判断 `if len(segments) < 1`。这两个条件是等价的,且第一个判断已经处理了空列表情况,第二个判断永远不会执行。建议删除冗余代码。 --- ✅ 格式检查通过 | ❌ 逻辑审查需修改 | ⚠️ 建议关注性能 --- <sub>🤖 由 AI 代码审查机器人自动生成 | 2026-07-28 01:29:39 | 模型: </sub> <!-- AI_CODE_REVIEW_AUTO_COMMENT -->
xiaoxia closed this pull request 2026-07-28 09:43:26 +08:00

🗑️ 预览环境已清理

PR #1049 已关闭或合并,对应的预览环境已被清理。

如有需要,可以重新打开 PR 来重新生成预览环境。

🗑️ **预览环境已清理** PR #1049 已关闭或合并,对应的预览环境已被清理。 > 如有需要,可以重新打开 PR 来重新生成预览环境。
xiaoxia reopened this pull request 2026-07-28 12:18:38 +08:00
xiaoxia closed this pull request 2026-07-28 13:07:43 +08:00

🗑️ 预览环境已清理

PR #1049 已关闭或合并,对应的预览环境已被清理。

如有需要,可以重新打开 PR 来重新生成预览环境。

🗑️ **预览环境已清理** PR #1049 已关闭或合并,对应的预览环境已被清理。 > 如有需要,可以重新打开 PR 来重新生成预览环境。
Some checks are pending
PR Automation / Auto Approve on CI Green (pull_request) Successful in 4m36s
PR Automation / Auto Merge on CI Green + Approved (pull_request) Successful in 17m23s
CI/CD Pipeline / Check if frontend-only change (pull_request) Successful in 25s
CI/CD Pipeline / Validate - Type Check (mypy) (pull_request) Successful in 1m9s
CI/CD Pipeline / Frontend Lint (pull_request) Successful in 59s
CI/CD Pipeline / Build Staging API Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging Web Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging Worker Image (pull_request) Has been skipped
CI/CD Pipeline / Validate - Migration (alembic) (pull_request) Successful in 1m15s
CI/CD Pipeline / Validate - Code Quality (pull_request) Failing after 2m50s
Preview Deploy / Deploy Preview Environment (pull_request) Successful in 1m13s
CI/CD Pipeline / PR Build Web Image (pull_request) Successful in 2m16s
CI/CD Pipeline / PR Build Worker Image (pull_request) Successful in 2m0s
CI/CD Pipeline / PR Build API Image (pull_request) Successful in 6m0s
AI Code Review / AI Code Review (pull_request) Failing after 6m56s
CI/CD Pipeline / Frontend Unit Tests (pull_request) Has been skipped
CI/CD Pipeline / Build Production API Image (pull_request) Has been skipped
CI/CD Pipeline / Build Production Web Image (pull_request) Has been skipped
CI/CD Pipeline / Build Production Worker Image (pull_request) Has been skipped
CI/CD Pipeline / Deploy Staging (Watchtower auto-deploy) (pull_request) Has been skipped
CI/CD Pipeline / Integration Tests (pull_request) Successful in 4m48s
CI/CD Pipeline / Unit Tests (pull_request) Successful in 6m9s
CI/CD Pipeline / Deploy Production (pull_request) Has been skipped
CI/CD Pipeline / Staging E2E Tests (pull_request) Has been skipped
CI/CD Pipeline / Staging API Integration Tests (pull_request) Has been skipped
CI/CD Pipeline / ACR Image Cleanup (pull_request) Has been skipped
CI/CD Pipeline / Canary Release to Production (pull_request) Has been cancelled
CI/CD Pipeline / CI Gate (pull_request) Successful in 35s
CI/CD Pipeline / Production Browser E2E (pull_request) Has been skipped
ACR Cleanup / ACR Image Cleanup (pull_request_target) Has been cancelled
Preview Cleanup / Cleanup Preview Environment (pull_request) Successful in 23s

Pull request closed

Sign in to join this conversation.