aps-agent/tests/golden/test_optimize_engine.py

76 lines
2.8 KiB
Python
Raw Normal View History

from __future__ import annotations
from server.aps_domain.closed_loop_runtime import run_closed_loop_candidate
from server.engines import get_engine
from server.engines.optimize_engine import normalize_dispatch_rule
from server.engines.pool_engine import PoolEngine
from tests.golden.test_closed_loop_runtime import BUSINESS_DATE, _ready_world
def _next_id_factory():
counters: dict[str, int] = {}
def next_id(kind: str) -> int:
counters[kind] = counters.get(kind, 0) + 1
return counters[kind]
return next_id
def test_optimize_factory_and_rule_catalog_are_available():
assert get_engine("OPTIMIZE").name == "OPTIMIZE"
assert normalize_dispatch_rule("DELIVERY_FIRST") == "EDD"
assert normalize_dispatch_rule("first-in-first-out") == "FIFO"
assert normalize_dispatch_rule("unknown") == "EDD"
def test_dispatch_rules_have_stable_ordering_keys():
routings = [
{"productCode": "SHORT", "stdTimePerUnit": 2},
{"productCode": "LONG", "stdTimePerUnit": 10},
]
ops = {}
short = {"productCode": "SHORT", "quantity": 1, "dueDate": "2026-08-05", "priority": 2, "orderNo": "SO-S"}
long = {"productCode": "LONG", "quantity": 1, "dueDate": "2026-08-04", "priority": 1, "orderNo": "SO-L"}
assert sorted((long, short), key=lambda row: PoolEngine._dispatch_key("SPT", row, routings, ops)) == [short, long]
assert sorted((short, long), key=lambda row: PoolEngine._dispatch_key("LPT", row, routings, ops)) == [long, short]
def test_optimize_runs_through_closed_loop_v2_and_records_provenance():
world = _ready_world()
result = run_closed_loop_candidate(
world,
_next_id_factory(),
business_date=BUSINESS_DATE,
engine_type="OPTIMIZE",
sort_mode="SPT",
)
assert result["solveStatus"] == "FEASIBLE"
assert result["engineType"] == "OPTIMIZE"
version = world["flexScheduleVersions"][-1]
assert version["engineType"] == "OPTIMIZE"
assert version["solverId"] == "optimize-dispatch"
assert version["algorithmId"] == "optimize.spt"
assert version["schedulingSolutionV2"]["assumptions"][0]["code"] == "OPTIMIZE_ENGINE_V1_ADAPTER"
assert version["schedulingSolutionV2"]["provenance"]["solverId"] == "optimize-dispatch"
def test_optimize_blocker_keeps_engine_identity_and_zero_artifacts():
world = _ready_world()
world["materials"][1]["stock"] = 0
world["routings"] = []
result = run_closed_loop_candidate(
world,
_next_id_factory(),
business_date=BUSINESS_DATE,
engine_type="OPTIMIZE",
)
assert result["solveStatus"] == "BLOCKED"
assert result["engineType"] == "OPTIMIZE"
assert result["woCount"] == 0
assert world["flexScheduleVersions"][-1]["engineType"] == "OPTIMIZE"
assert world["flexWorkOrders"] == []