140 lines
5.3 KiB
Python
140 lines
5.3 KiB
Python
# -*- coding: utf-8 -*-
|
||
"""TaskRegistry 单元测试 — 验证 TaskMeta 元数据注册与查询"""
|
||
import pytest
|
||
from orchestration.task_registry import TaskRegistry, TaskMeta
|
||
|
||
|
||
# ── 辅助:用作注册的假任务类 ──────────────────────────────────
|
||
|
||
class _FakeTask:
|
||
"""占位任务类,用于测试注册"""
|
||
def __init__(self, config, db_connection, api_client, logger):
|
||
self.config = config
|
||
|
||
|
||
class _AnotherFakeTask:
|
||
def __init__(self, config, db_connection, api_client, logger):
|
||
pass
|
||
|
||
|
||
# ── fixtures ──────────────────────────────────────────────────
|
||
|
||
@pytest.fixture
|
||
def registry():
|
||
return TaskRegistry()
|
||
|
||
|
||
# ── register + get_metadata ───────────────────────────────────
|
||
|
||
class TestRegisterAndMetadata:
|
||
"""注册与元数据查询"""
|
||
|
||
def test_register_with_defaults(self, registry):
|
||
"""仅传 task_code + task_class 时,元数据使用默认值(向后兼容)"""
|
||
registry.register("MY_TASK", _FakeTask)
|
||
meta = registry.get_metadata("MY_TASK")
|
||
assert meta is not None
|
||
assert meta.task_class is _FakeTask
|
||
assert meta.requires_db_config is True
|
||
assert meta.layer is None
|
||
assert meta.task_type == "etl"
|
||
|
||
def test_register_with_full_metadata(self, registry):
|
||
"""传入完整元数据"""
|
||
registry.register(
|
||
"ODS_ORDERS", _FakeTask,
|
||
requires_db_config=True, layer="ODS", task_type="etl",
|
||
)
|
||
meta = registry.get_metadata("ODS_ORDERS")
|
||
assert meta.layer == "ODS"
|
||
assert meta.task_type == "etl"
|
||
|
||
def test_register_utility_task(self, registry):
|
||
"""工具类任务:requires_db_config=False"""
|
||
registry.register(
|
||
"INIT_SCHEMA", _FakeTask,
|
||
requires_db_config=False, task_type="utility",
|
||
)
|
||
meta = registry.get_metadata("INIT_SCHEMA")
|
||
assert meta.requires_db_config is False
|
||
assert meta.task_type == "utility"
|
||
|
||
def test_case_insensitive_lookup(self, registry):
|
||
"""task_code 大小写不敏感"""
|
||
registry.register("my_task", _FakeTask)
|
||
assert registry.get_metadata("MY_TASK") is not None
|
||
assert registry.get_metadata("my_task") is not None
|
||
|
||
def test_get_metadata_unknown_returns_none(self, registry):
|
||
"""查询未注册的任务返回 None"""
|
||
assert registry.get_metadata("NONEXISTENT") is None
|
||
|
||
|
||
# ── create_task(接口不变)────────────────────────────────────
|
||
|
||
class TestCreateTask:
|
||
|
||
def test_create_task_returns_instance(self, registry):
|
||
registry.register("MY_TASK", _FakeTask)
|
||
task = registry.create_task("MY_TASK", {"k": "v"}, None, None, None)
|
||
assert isinstance(task, _FakeTask)
|
||
assert task.config == {"k": "v"}
|
||
|
||
def test_create_task_unknown_raises(self, registry):
|
||
with pytest.raises(ValueError, match="未知的任务类型"):
|
||
registry.create_task("NOPE", None, None, None, None)
|
||
|
||
|
||
# ── get_tasks_by_layer ────────────────────────────────────────
|
||
|
||
class TestGetTasksByLayer:
|
||
|
||
def test_returns_matching_tasks(self, registry):
|
||
registry.register("A", _FakeTask, layer="ODS")
|
||
registry.register("B", _AnotherFakeTask, layer="ODS")
|
||
registry.register("C", _FakeTask, layer="DWD")
|
||
result = registry.get_tasks_by_layer("ODS")
|
||
assert set(result) == {"A", "B"}
|
||
|
||
def test_case_insensitive_layer(self, registry):
|
||
registry.register("X", _FakeTask, layer="dws")
|
||
assert registry.get_tasks_by_layer("DWS") == ["X"]
|
||
|
||
def test_no_match_returns_empty(self, registry):
|
||
registry.register("A", _FakeTask, layer="ODS")
|
||
assert registry.get_tasks_by_layer("INDEX") == []
|
||
|
||
def test_none_layer_excluded(self, registry):
|
||
"""layer=None 的任务不会被任何层查询返回"""
|
||
registry.register("UTIL", _FakeTask) # layer 默认 None
|
||
assert registry.get_tasks_by_layer("ODS") == []
|
||
|
||
|
||
# ── is_utility_task ───────────────────────────────────────────
|
||
|
||
class TestIsUtilityTask:
|
||
|
||
def test_utility_task(self, registry):
|
||
registry.register("INIT", _FakeTask, requires_db_config=False)
|
||
assert registry.is_utility_task("INIT") is True
|
||
|
||
def test_normal_task(self, registry):
|
||
registry.register("ETL", _FakeTask, requires_db_config=True)
|
||
assert registry.is_utility_task("ETL") is False
|
||
|
||
def test_unknown_task(self, registry):
|
||
assert registry.is_utility_task("NOPE") is False
|
||
|
||
|
||
# ── get_all_task_codes(接口不变)──────────────────────────────
|
||
|
||
class TestGetAllTaskCodes:
|
||
|
||
def test_returns_all_codes(self, registry):
|
||
registry.register("A", _FakeTask)
|
||
registry.register("B", _AnotherFakeTask)
|
||
assert set(registry.get_all_task_codes()) == {"A", "B"}
|
||
|
||
def test_empty_registry(self, registry):
|
||
assert registry.get_all_task_codes() == []
|