first commit

This commit is contained in:
strepsiades
2026-03-09 16:31:42 +08:00
commit 4a9c444b10
486 changed files with 52479 additions and 0 deletions
+1
View File
@@ -0,0 +1 @@
"""Mock components for sync_state_machine tests."""
+113
View File
@@ -0,0 +1,113 @@
from __future__ import annotations
from dataclasses import dataclass, field
from typing import Dict, List, Optional
from pydantic import BaseModel
from sync_state_machine.common.sync_node import SyncNode
from sync_state_machine.datasource.datasource import BaseDataSource
from sync_state_machine.datasource.task_result import TaskResult
class MockSchema(BaseModel):
id: Optional[str] = None
name: str = "mock"
class MockSyncNode(SyncNode[MockSchema]):
node_type = "mock"
schema = MockSchema
@dataclass
class HandlerScript:
create: str = "success" # success | failed | skipped | in_progress
update: str = "success"
delete: str = "success"
poll_sequence: List[str] = field(default_factory=lambda: ["success"]) # success | failed | in_progress
class ScriptedMockHandler:
def __init__(self, script: HandlerScript):
self._script = script
self._collection = None
self._poll_index = 0
@property
def node_type(self) -> str:
return "mock"
@property
def node_class(self):
return MockSyncNode
@property
def schema(self):
return MockSchema
def set_collection(self, collection):
self._collection = collection
async def load(self):
return []
async def create_all(self, nodes):
return [self._build_result(self._script.create, node.node_id, "create") for node in nodes]
async def update_all(self, nodes):
return [
self._build_result(
self._script.update,
node.node_id,
"update",
)
for node in nodes
]
async def delete_all(self, nodes):
return [self._build_result(self._script.delete, node.node_id, "delete") for node in nodes]
async def poll_tasks(self, task_ids: List[str]) -> Dict[str, TaskResult]:
status = self._script.poll_sequence[min(self._poll_index, len(self._script.poll_sequence) - 1)]
self._poll_index += 1
out: Dict[str, TaskResult] = {}
for task_id in task_ids:
out[task_id] = self._build_poll_result(status, task_id)
return out
def _build_result(
self,
mode: str,
node_id: str,
phase: str,
) -> TaskResult:
if mode == "success":
return TaskResult.success(node_id=node_id, data_id=f"{phase}-{node_id}")
if mode == "failed":
return TaskResult.failed(node_id=node_id, error=f"{phase} failed")
if mode == "skipped":
return TaskResult.skipped(
node_id=node_id,
reason=f"{phase} skipped",
)
if mode == "in_progress":
return TaskResult.in_progress(node_id=node_id, task_id=f"task-{phase}-{node_id}")
raise ValueError(f"Unsupported mode: {mode}")
def _build_poll_result(self, mode: str, task_id: str) -> TaskResult:
if mode == "success":
return TaskResult.success(node_id=self._node_id_from_task(task_id), data_id=f"done-{task_id}")
if mode == "failed":
return TaskResult.failed(node_id=self._node_id_from_task(task_id), error="poll failed")
if mode == "in_progress":
return TaskResult.in_progress(node_id=self._node_id_from_task(task_id), task_id=task_id)
raise ValueError(f"Unsupported poll mode: {mode}")
@staticmethod
def _node_id_from_task(task_id: str) -> str:
return task_id.split("-")[-1]
class MockDataSource(BaseDataSource):
pass