本次同步 09-12 至 09-28 的代码变更,主要内容: 新增功能 - 修改密码:后端新增 ChangePasswordRequest DTO 与UserController/UserService 对应接口,前端新增 ChangePasswordDialog 并在 Header 接入入口 - 文件预览组件重构:file-preview 目录拆分出 VideoPreview(支持 blobUrl 直传)、 ImagePreview、AudioPreview,index.tsx 统一调度各类型预览器 - 新增 my_ops 算子模块:markitdown_parser、mineru_pdf_parser、text_quality_evaluator - 新增 tools/minio-file-server MinIO 文件服务 功能增强 - 数据清洗:cleaning_task_service/scheduler/routes 重构, data_juicer_executor 与 wrapper 增强,OperatorTable/LogsTable/TaskDetail 同步调整 - 数据标注:annotation sync.py、project.py 接口与schema 更新 - 数据采集、算子市场、首页与菜单路由相关页面调整 - DataJuicer 算子接入(useOperatorOperations、dj_ops_schema) 结构调整 - deepflow/ 更名为 deep-flow/(419 个文件重命名) - 新增 helm 部署编排、GitHub Actions 之外的自建镜像构建脚本 未纳入本次提交 - scripts-backup/、runtime/python-executor-backup/、components_backup/(备份目录) - *.backup*、__pycache__ 产物 - zh_core_web_sm-3.8.0-py3-none-any.whl(46MB 构建产物) - DataX/(内嵌独立仓库,远程亦未收录其源码)
100 lines
3.2 KiB
Python
100 lines
3.2 KiB
Python
import pytest
|
|
|
|
from app.core.exception import BusinessError
|
|
from app.module.cleaning.schema.cleaning import OperatorInstanceDto
|
|
from app.module.cleaning.service.cleaning_task_validator import CleaningTaskValidator
|
|
from app.module.operator.constants import CATEGORY_DEEPDATA_ID, CATEGORY_DATA_JUICER_ID
|
|
|
|
|
|
def _op(op_id: str, inputs: str | None, outputs: str | None, categories: list[str] | None = None) -> OperatorInstanceDto:
|
|
return OperatorInstanceDto(id=op_id, inputs=inputs, outputs=outputs, categories=categories)
|
|
|
|
|
|
def test_check_input_and_output_passes_with_multimodal() -> None:
|
|
instances = [
|
|
_op("a", "text", "multimodal"),
|
|
_op("b", "image", "text"),
|
|
]
|
|
|
|
CleaningTaskValidator.check_input_and_output(instances)
|
|
|
|
|
|
def test_check_input_and_output_raises_on_type_mismatch() -> None:
|
|
instances = [
|
|
_op("a", "text", "image"),
|
|
_op("b", "text", "text"),
|
|
]
|
|
|
|
with pytest.raises(BusinessError):
|
|
CleaningTaskValidator.check_input_and_output(instances)
|
|
|
|
|
|
def test_check_and_get_executor_type_raises_when_mixed_categories() -> None:
|
|
instances = [
|
|
_op("a", None, None, [CATEGORY_DEEPDATA_ID]),
|
|
_op("b", None, None, [CATEGORY_DATA_JUICER_ID]),
|
|
]
|
|
|
|
with pytest.raises(BusinessError):
|
|
CleaningTaskValidator.check_and_get_executor_type(instances)
|
|
|
|
|
|
def test_check_and_get_executor_type_defaults_to_DeepData() -> None:
|
|
instances = [_op("a", None, None, None)]
|
|
|
|
executor = CleaningTaskValidator.check_and_get_executor_type(instances)
|
|
|
|
assert executor == "deepdata"
|
|
|
|
|
|
def test_check_task_id_raises_when_empty() -> None:
|
|
with pytest.raises(BusinessError):
|
|
CleaningTaskValidator.check_task_id("")
|
|
|
|
|
|
def test_check_task_id_accepts_normal_value() -> None:
|
|
CleaningTaskValidator.check_task_id("task-1")
|
|
|
|
|
|
def test_check_input_and_output_returns_for_empty_instances() -> None:
|
|
CleaningTaskValidator.check_input_and_output([])
|
|
|
|
|
|
def test_check_input_and_output_raises_when_current_has_no_outputs() -> None:
|
|
instances = [
|
|
_op("a", "text", None),
|
|
_op("b", "text", "text"),
|
|
]
|
|
with pytest.raises(BusinessError):
|
|
CleaningTaskValidator.check_input_and_output(instances)
|
|
|
|
|
|
def test_check_input_and_output_raises_when_next_has_no_inputs() -> None:
|
|
instances = [
|
|
_op("a", "text", "text"),
|
|
_op("b", None, "text"),
|
|
]
|
|
with pytest.raises(BusinessError):
|
|
CleaningTaskValidator.check_input_and_output(instances)
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"out_type,in_type",
|
|
[
|
|
("text", "text"),
|
|
(" image ", "image"),
|
|
("AUDIO", "audio"),
|
|
],
|
|
)
|
|
def test_check_input_and_output_allows_exact_match_with_normalization(out_type: str, in_type: str) -> None:
|
|
instances = [
|
|
_op("a", "x", out_type),
|
|
_op("b", in_type, "y"),
|
|
]
|
|
CleaningTaskValidator.check_input_and_output(instances)
|
|
|
|
|
|
def test_check_and_get_executor_type_prefers_datajuicer_when_only_datajuicer() -> None:
|
|
instances = [_op("a", None, None, [CATEGORY_DATA_JUICER_ID])]
|
|
assert CleaningTaskValidator.check_and_get_executor_type(instances) == "default"
|