feat: consolidate legacy workflows into gyxx-flow
This commit is contained in:
@@ -0,0 +1,86 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from collections import Counter
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
|
||||
from gyxx_flow.catalog import CatalogError, WorkflowCatalog
|
||||
|
||||
PROJECT_ROOT = Path(__file__).resolve().parents[1]
|
||||
|
||||
|
||||
def test_catalog_maps_exactly_21_current_scheduled_tasks() -> None:
|
||||
catalog = WorkflowCatalog.load(PROJECT_ROOT / "config")
|
||||
scheduled = catalog.scheduled_workflows()
|
||||
|
||||
assert len(scheduled) == 21
|
||||
assert len({item.source_task_name for item in scheduled}) == 21
|
||||
assert Counter(item.module for item in scheduled) == {
|
||||
"content_marketing": 9,
|
||||
"product_commerce": 7,
|
||||
"shop_intelligence": 2,
|
||||
"supply_chain": 3,
|
||||
}
|
||||
|
||||
|
||||
def test_catalog_keeps_known_manual_or_unregistered_workflows_unscheduled() -> None:
|
||||
catalog = WorkflowCatalog.load(PROJECT_ROOT / "config")
|
||||
|
||||
assert {
|
||||
"content.mapping.refresh",
|
||||
"content.retry_failed",
|
||||
"product.backfill",
|
||||
"product.market_rank",
|
||||
"product.review_collection",
|
||||
"supply.purchase_order_update",
|
||||
}.issubset({item.workflow_id for item in catalog.manual_workflows()})
|
||||
assert "product.weekly_aggregate.documented_missing" in {
|
||||
item.workflow_id for item in catalog.unavailable_workflows()
|
||||
}
|
||||
|
||||
|
||||
def test_every_scheduled_workflow_has_one_valid_asia_shanghai_schedule() -> None:
|
||||
catalog = WorkflowCatalog.load(PROJECT_ROOT / "config")
|
||||
|
||||
assert catalog.timezone == "Asia/Shanghai"
|
||||
assert len(catalog.schedules) == 21
|
||||
for workflow in catalog.scheduled_workflows():
|
||||
schedule = catalog.schedule_for(workflow.workflow_id)
|
||||
assert schedule.workflow_id == workflow.workflow_id
|
||||
assert schedule.kind in {"daily", "weekly", "monthly", "interval_days"}
|
||||
assert schedule.at.count(":") == 1
|
||||
|
||||
|
||||
def test_catalog_rejects_duplicate_workflow_ids(tmp_path: Path) -> None:
|
||||
(tmp_path / "workflows.json").write_text(
|
||||
'{"schema_version":2,"workflows":['
|
||||
'{"id":"a.one","module":"content_marketing","trigger":"manual",'
|
||||
'"execution":{"entry":"run.py"}},'
|
||||
'{"id":"a.one","module":"content_marketing","trigger":"manual",'
|
||||
'"execution":{"entry":"other.py"}}]}',
|
||||
encoding="utf-8",
|
||||
)
|
||||
(tmp_path / "schedules.json").write_text(
|
||||
'{"schema_version":1,"timezone":"Asia/Shanghai","schedules":[]}',
|
||||
encoding="utf-8",
|
||||
)
|
||||
|
||||
with pytest.raises(CatalogError, match="duplicate workflow id"):
|
||||
WorkflowCatalog.load(tmp_path)
|
||||
|
||||
|
||||
def test_catalog_rejects_absolute_execution_entry(tmp_path: Path) -> None:
|
||||
(tmp_path / "workflows.json").write_text(
|
||||
'{"schema_version":2,"workflows":['
|
||||
'{"id":"a.one","module":"content_marketing","trigger":"manual",'
|
||||
'"execution":{"entry":"D:/old/run.py"}}]}',
|
||||
encoding="utf-8",
|
||||
)
|
||||
(tmp_path / "schedules.json").write_text(
|
||||
'{"schema_version":1,"timezone":"Asia/Shanghai","schedules":[]}',
|
||||
encoding="utf-8",
|
||||
)
|
||||
|
||||
with pytest.raises(CatalogError, match="relative"):
|
||||
WorkflowCatalog.load(tmp_path)
|
||||
Reference in New Issue
Block a user