80 lines
2.5 KiB
Python
80 lines
2.5 KiB
Python
import json
|
|
|
|
from scripts.dynamic_dispatch_optimizer import generate_plan, write_plan
|
|
|
|
|
|
def test_generate_plan_rebalances_offline_host_tasks_to_online_capacity():
|
|
spec = {
|
|
"hosts": [
|
|
{"name": "ezra", "capacity": 2, "lanes": ["research", "general"]},
|
|
{"name": "bezalel", "capacity": 2, "lanes": ["build", "general"]},
|
|
{"name": "local", "capacity": 1, "lanes": ["general"], "always_available": True},
|
|
],
|
|
"tasks": [
|
|
{"id": "ISSUE-1", "lane": "build", "priority": 100},
|
|
{"id": "ISSUE-2", "lane": "general", "priority": 80},
|
|
{"id": "ISSUE-3", "lane": "research", "priority": 60},
|
|
],
|
|
}
|
|
failover_status = {"fleet": {"ezra": "ONLINE", "bezalel": "OFFLINE"}}
|
|
|
|
plan = generate_plan(spec, failover_status)
|
|
|
|
assignments = {item["task_id"]: item["host"] for item in plan["assignments"]}
|
|
assert assignments == {
|
|
"ISSUE-1": "local",
|
|
"ISSUE-2": "ezra",
|
|
"ISSUE-3": "ezra",
|
|
}
|
|
assert plan["offline_hosts"] == ["bezalel"]
|
|
assert plan["unassigned"] == []
|
|
|
|
|
|
def test_generate_plan_prefers_preferred_host_when_online():
|
|
spec = {
|
|
"hosts": [
|
|
{"name": "ezra", "capacity": 2, "lanes": ["general"]},
|
|
{"name": "bezalel", "capacity": 2, "lanes": ["general"]},
|
|
],
|
|
"tasks": [
|
|
{"id": "ISSUE-9", "lane": "general", "priority": 100, "preferred_hosts": ["bezalel", "ezra"]},
|
|
],
|
|
}
|
|
|
|
plan = generate_plan(spec, {"fleet": {"ezra": "ONLINE", "bezalel": "ONLINE"}})
|
|
|
|
assert plan["assignments"] == [
|
|
{"task_id": "ISSUE-9", "host": "bezalel", "lane": "general", "priority": 100}
|
|
]
|
|
|
|
|
|
def test_generate_plan_reports_unassigned_when_no_host_matches_lane():
|
|
spec = {
|
|
"hosts": [
|
|
{"name": "ezra", "capacity": 1, "lanes": ["research"]},
|
|
],
|
|
"tasks": [
|
|
{"id": "ISSUE-5", "lane": "build", "priority": 50},
|
|
],
|
|
}
|
|
|
|
plan = generate_plan(spec, {"fleet": {"ezra": "ONLINE"}})
|
|
|
|
assert plan["assignments"] == []
|
|
assert plan["unassigned"] == [
|
|
{"task_id": "ISSUE-5", "reason": "no_online_host_for_lane:build"}
|
|
]
|
|
|
|
|
|
def test_write_plan_persists_json(tmp_path):
|
|
plan = {
|
|
"assignments": [{"task_id": "ISSUE-1", "host": "ezra", "lane": "general", "priority": 10}],
|
|
"offline_hosts": [],
|
|
"unassigned": [],
|
|
}
|
|
output_path = tmp_path / "dispatch-plan.json"
|
|
|
|
write_plan(plan, output_path)
|
|
|
|
assert json.loads(output_path.read_text()) == plan
|