from __future__ import annotations from pathlib import Path import pytest from pydantic import BaseModel from sync_state_machine.common.registry import DomainRegistry from sync_state_machine.common.sync_node import SyncNode from sync_state_machine.config import DbDataSourceConfig, LoggingConfig, PersistConfig, PipelineRunConfig from sync_state_machine.datasource.db import BaseDbHandler, DbDataSource from sync_state_machine.pipeline.factory import create_pipeline_from_config from sync_state_machine.sync_system.strategy import DefaultSyncStrategy class EndpointInitSchema(BaseModel): __test__ = False id: str name: str | None = None class EndpointInitNode(SyncNode[EndpointInitSchema]): __test__ = False node_type = "factory_endpoint_demo" schema = EndpointInitSchema class EndpointInitStrategy(DefaultSyncStrategy[EndpointInitSchema]): __test__ = False schema = EndpointInitSchema class EndpointInitDbHandler(BaseDbHandler[EndpointInitSchema]): __test__ = False def __init__(self, datasource: DbDataSource): super().__init__(datasource, "factory_endpoint_demo", EndpointInitNode, EndpointInitSchema) def extract_id(self, data: dict[str, str]) -> str: return str(data.get("id", "")) async def load(self): return [] async def create_all(self, nodes): return [] async def update_all(self, nodes): return [] def _ensure_registered() -> None: node_type = "factory_endpoint_demo" if DomainRegistry.is_registered(node_type): reg = DomainRegistry.get_registration(node_type) reg.schema = EndpointInitSchema reg.node_class = EndpointInitNode reg.strategy_class = EndpointInitStrategy reg.db_handler_class = EndpointInitDbHandler return DomainRegistry.register( node_type=node_type, schema=EndpointInitSchema, node_class=EndpointInitNode, strategy_class=EndpointInitStrategy, db_handler_class=EndpointInitDbHandler, ) @pytest.mark.asyncio async def test_factory_initializes_same_datasource_type_with_distinct_handler_configs( tmp_path: Path, monkeypatch: pytest.MonkeyPatch, ) -> None: _ensure_registered() config = PipelineRunConfig( node_types=["factory_endpoint_demo"], local_datasource=DbDataSourceConfig( type="db", handler_configs={"factory_endpoint_demo": {"side": "local", "batch_size": 10}}, target_project_ids=["project_local"], ), remote_datasource=DbDataSourceConfig( type="db", handler_configs={"factory_endpoint_demo": {"side": "remote", "batch_size": 20}}, target_project_ids=["project_remote"], ), strategies=[], persist=PersistConfig(db_path=str(tmp_path / "factory-init.db")), logging=LoggingConfig(initialize=False), ) pipeline = await create_pipeline_from_config(config) try: local_handler = pipeline.local_datasource.get_handler("factory_endpoint_demo") remote_handler = pipeline.remote_datasource.get_handler("factory_endpoint_demo") assert isinstance(local_handler, EndpointInitDbHandler) assert isinstance(remote_handler, EndpointInitDbHandler) assert local_handler.handler_config == {"side": "local", "batch_size": 10} assert remote_handler.handler_config == {"side": "remote", "batch_size": 20} finally: await pipeline.close()