| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129 |
- from __future__ import annotations
- from datetime import timedelta
- from sqlalchemy import create_engine
- from sqlalchemy.orm import Session
- from supply_infra.db.models.pipeline_lock import PipelineLock
- from supply_infra.db.models.pipeline_run import PipelineRun
- from supply_infra.db.models.pipeline_step_run import PipelineStepRun
- from supply_infra.db.repositories.pipeline_step_run_repo import (
- PipelineStepRunRepository,
- )
- from supply_infra.pipeline.dates import china_now
- def _session() -> Session:
- engine = create_engine("sqlite+pysqlite:///:memory:")
- PipelineRun.__table__.create(engine)
- PipelineStepRun.__table__.create(engine)
- PipelineLock.__table__.create(engine)
- return Session(engine, expire_on_commit=False)
- def _run(run_id: str) -> PipelineRun:
- now = china_now()
- return PipelineRun(
- run_id=run_id,
- dedupe_key=f"supply_pipeline:20260727:{run_id}",
- pipeline_key="supply_pipeline",
- biz_dt="20260727",
- trigger_type="test",
- run_mode="full",
- dry_run=True,
- status="queued",
- deadline_at=now + timedelta(days=1),
- config_snapshot_json={},
- date_snapshot_json={},
- )
- def _step(
- *,
- step_run_id: str,
- run_id: str,
- status: str,
- order: int,
- ) -> PipelineStepRun:
- return PipelineStepRun(
- step_run_id=step_run_id,
- run_id=run_id,
- step_key=f"step-{step_run_id}",
- step_order=order,
- attempt=1,
- status=status,
- critical=True,
- dependency_snapshot_json=[],
- input_snapshot_json={},
- timeout_seconds=10,
- max_attempts=1,
- retryable=False,
- )
- def test_claim_respects_global_active_step_cap() -> None:
- with _session() as session:
- session.add_all(
- [
- _run("run-1"),
- _run("run-2"),
- _step(
- step_run_id="running",
- run_id="run-1",
- status="running",
- order=1,
- ),
- _step(
- step_run_id="ready",
- run_id="run-2",
- status="ready",
- order=1,
- ),
- ]
- )
- session.flush()
- claimed = PipelineStepRunRepository(session).claim_next_ready(
- owner="worker-2",
- lease_seconds=120,
- max_active_steps=1,
- now=china_now(),
- )
- assert claimed is None
- ready = session.get(PipelineStepRun, "ready")
- assert ready is not None
- assert ready.status == "ready"
- def test_claim_does_not_overlap_a_different_pipeline_run() -> None:
- with _session() as session:
- session.add_all(
- [
- _run("run-1"),
- _run("run-2"),
- _step(
- step_run_id="running",
- run_id="run-1",
- status="running",
- order=1,
- ),
- _step(
- step_run_id="ready",
- run_id="run-2",
- status="ready",
- order=1,
- ),
- ]
- )
- session.flush()
- claimed = PipelineStepRunRepository(session).claim_next_ready(
- owner="worker-2",
- lease_seconds=120,
- max_active_steps=2,
- now=china_now(),
- )
- assert claimed is None
|