# -*- 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() == []