mirror of
https://github.com/MemeMeow-Studio/MemeMeow.git
synced 2026-10-17 04:41:01 +08:00
107 lines
5.1 KiB
Python
107 lines
5.1 KiB
Python
# 使用所属开发 PostgreSQL 验证 Task 提交、保存点和回滚的真实采集行为。
|
|
from __future__ import annotations
|
|
|
|
import argparse
|
|
import json
|
|
import subprocess
|
|
from datetime import timedelta
|
|
from uuid import uuid4
|
|
|
|
from opentelemetry import metrics
|
|
from opentelemetry.sdk.metrics import MeterProvider
|
|
from opentelemetry.sdk.metrics.export import InMemoryMetricReader
|
|
from sqlalchemy import create_engine
|
|
from sqlalchemy.engine import make_url
|
|
from sqlalchemy.orm import sessionmaker
|
|
|
|
from backend.persistence.models import Scope, ScopeContext, Task, utcnow
|
|
from backend.persistence.repositories.tasks import TaskRepository
|
|
from backend.persistence.task_telemetry import instrument_task_sessions
|
|
|
|
|
|
def main() -> None:
|
|
"""创建带验收标识的真实记录,核实提交成功后的计数且保留数据。"""
|
|
parser = argparse.ArgumentParser()
|
|
parser.add_argument("--api-container", required=True)
|
|
parser.add_argument("--database-container", required=True)
|
|
parser.add_argument("--compose-project", required=True)
|
|
parser.add_argument("--workspace", required=True)
|
|
parser.add_argument("--database-port", required=True, type=int)
|
|
arguments = parser.parse_args()
|
|
containers = json.loads(subprocess.check_output(["docker", "inspect", arguments.api_container, arguments.database_container]))
|
|
for container in containers:
|
|
labels = container["Config"]["Labels"]
|
|
assert labels["com.docker.compose.project"] == arguments.compose_project
|
|
assert labels["com.docker.compose.project.working_dir"] == arguments.workspace
|
|
environment = dict(entry.split("=", 1) for entry in containers[0]["Config"]["Env"])
|
|
reader = InMemoryMetricReader()
|
|
provider = MeterProvider(metric_readers=[reader])
|
|
metrics.set_meter_provider(provider)
|
|
engine = create_engine(make_url(environment["MEMEMEOW_DATABASE_URL"]).set(host="127.0.0.1", port=arguments.database_port))
|
|
factory = sessionmaker(engine, expire_on_commit=False)
|
|
instrument_task_sessions(factory)
|
|
identifier = "monitoring-acceptance-" + uuid4().hex
|
|
|
|
def counts() -> dict[tuple[str, str], int]:
|
|
"""读取真实 SDK 聚合,标签来源为已提交 Task 字段。"""
|
|
result = {}
|
|
data = reader.get_metrics_data()
|
|
if data is not None:
|
|
for resource in data.resource_metrics:
|
|
for scope in resource.scope_metrics:
|
|
for metric in scope.metrics:
|
|
if metric.name == "task_terminals":
|
|
for point in metric.data.data_points:
|
|
result[(point.attributes["result"], point.attributes["reason"])] = point.value
|
|
return result
|
|
|
|
with factory() as session:
|
|
session.add(Scope(id=identifier))
|
|
session.commit()
|
|
task = Task(id=identifier, scope_id=identifier, task_type="monitoring_acceptance", status="running", lease_owner="monitoring-acceptance", lease_expires_at=utcnow() + timedelta(minutes=5))
|
|
session.add(task)
|
|
session.commit()
|
|
assert counts() == {}
|
|
task.status = "failed"
|
|
task.error = {"error": "agent_reservation_expired"}
|
|
session.flush()
|
|
assert counts() == {}
|
|
session.rollback()
|
|
assert counts() == {}
|
|
task = session.get(Task, identifier)
|
|
with session.begin_nested():
|
|
task.status = "failed"
|
|
task.error = {"error": "agent_reservation_expired"}
|
|
session.flush()
|
|
assert counts() == {}
|
|
session.rollback()
|
|
assert counts() == {}
|
|
task = session.get(Task, identifier)
|
|
nested = session.begin_nested()
|
|
task.status = "failed"
|
|
task.error = {"error": "discarded_savepoint"}
|
|
session.flush()
|
|
nested.rollback()
|
|
repository = TaskRepository(session, ScopeContext(identifier))
|
|
assert repository.cancel(task.id, error={"error": "task_cancelled"}, message="monitoring-acceptance 取消")
|
|
session.commit()
|
|
assert counts() == {("cancelled", "task_cancelled"): 1}
|
|
task.message = "monitoring-acceptance 提交后的更新"
|
|
session.commit()
|
|
assert counts() == {("cancelled", "task_cancelled"): 1}
|
|
bulk = Task(id=identifier + "-bulk", scope_id=identifier, task_type="monitoring_acceptance", status="running", lease_owner="monitoring-acceptance", lease_expires_at=utcnow() + timedelta(minutes=5))
|
|
session.add(bulk)
|
|
session.commit()
|
|
repository = TaskRepository(session, ScopeContext(identifier))
|
|
assert repository.update_fenced(bulk.id, 0, "monitoring-acceptance", status="failed", error={"error": "agent_reservation_deadline_invalid"})
|
|
assert counts() == {("cancelled", "task_cancelled"): 1}
|
|
session.commit()
|
|
assert counts() == {("cancelled", "task_cancelled"): 1, ("failed", "agent_reservation_deadline_invalid"): 1}
|
|
provider.shutdown()
|
|
engine.dispose()
|
|
print(json.dumps({"scope": identifier, "checks": ["commit", "rollback", "savepoint_commit", "savepoint_rollback", "unchanged_terminal", "fenced_sql_update"]}, ensure_ascii=False))
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|