Download tests/unit/test_graph_scheduler.py from desiree/spi: direct link, hf CLI and curl.
- Browser
- Download file 3.4 kB
-
https://huggingface.co/desiree/spi/resolve/main/tests/unit/test_graph_scheduler.py
- Command line
-
hf download hf://desiree/spi/tests/unit/test_graph_scheduler.py
-
curl -L -o test_graph_scheduler.py https://huggingface.co/desiree/spi/resolve/main/tests/unit/test_graph_scheduler.py
3.4 kB
| import pytest | |
| from spi.compiler.production_graph import CycleError, ProductionGraph | |
| from spi.renderers.base import RendererError, request_hash | |
| from spi.renderers.mock import MockVideoRenderer | |
| from spi.scheduler.scheduler import Scheduler | |
| from spi.schemas.production import GenerationJob | |
| def _job(jid, deps=None, priority=5, kind="video", shot_id="SHOT_0001"): | |
| return GenerationJob(job_id=jid, depends_on=deps or [], priority=priority, | |
| kind=kind, shot_id=shot_id, request={"prompt": jid}) | |
| def test_topo_respects_deps_and_priority(): | |
| g = ProductionGraph([_job("A"), _job("B"), _job("C", deps=["A"], priority=1), | |
| _job("D", deps=["A", "C"])]) | |
| order = g.topo_order() | |
| assert order.index("A") < order.index("C") < order.index("D") | |
| assert order.index("A") < order.index("B") | |
| def test_cycle_detected(): | |
| g = ProductionGraph([_job("A"), _job("B"), _job("C")]) | |
| g.add_edge("A", "B") | |
| g.add_edge("B", "C") | |
| g.add_edge("C", "A") | |
| with pytest.raises(CycleError): | |
| g.topo_order() | |
| assert any("cycle" in p for p in g.validate()) | |
| def test_unknown_dependency_reported(): | |
| # DESIGN NOTE: validate() reports problems (compile_production turns them into BLOCKED); | |
| # topo_order() is the raising entry point. A first draft of this test wrongly expected | |
| # validate() to raise. The test was corrected, not weakened (§44). | |
| g = ProductionGraph([_job("A")]) | |
| g.jobs["A"].depends_on.append("GHOST") | |
| problems = g.validate() | |
| assert any("GHOST" in p for p in problems) | |
| with pytest.raises(ValueError): | |
| g.topo_order() | |
| def test_video_job_without_shot_reported(): | |
| j = _job("A", kind="video", shot_id=None) | |
| g = ProductionGraph([j]) | |
| assert any("shot_id" in p for p in g.validate()) | |
| def test_ready_jobs_ordering(): | |
| g = ProductionGraph([_job("low", priority=9), _job("high", priority=1)]) | |
| assert g.ready_jobs()[0] == "high" | |
| g.mark("high", "done") | |
| assert g.ready_jobs() == ["low"] | |
| def test_request_hash_stable(): | |
| r1 = {"prompt": "x", "seed": 1} | |
| r2 = {"seed": 1, "prompt": "x"} | |
| assert request_hash(r1) == request_hash(r2) | |
| def test_mock_renderer_caches_identical_requests(): | |
| r = MockVideoRenderer() | |
| a1 = r.generate({"prompt": "same", "num_frames": 48, "seed": 7}) | |
| a2 = r.generate({"seed": 7, "prompt": "same", "num_frames": 48}) # same canonical dict | |
| assert a1["request_hash"] == a2["request_hash"] | |
| assert a1["cached"] is False and a2["cached"] is True | |
| def test_scheduler_executes_all_and_records(): | |
| g = ProductionGraph([_job("A"), _job("B", deps=["A"])]) | |
| summary = Scheduler(g, MockVideoRenderer()).run() | |
| assert summary["done"] == 2 and summary["failed"] == 0 | |
| assert all(j.status == "done" for j in g.jobs.values()) | |
| assert all(j.runtime_s is not None for j in g.jobs.values()) | |
| assert g.jobs["A"].artifact_ref.startswith("mock://video/") | |
| def test_scheduler_retries_then_fails(): | |
| class ExplodingRenderer(MockVideoRenderer): | |
| def generate(self, request): | |
| raise RendererError("simulated OOM") | |
| g = ProductionGraph([_job("A")]) | |
| summary = Scheduler(g, ExplodingRenderer(), max_retries=2).run() | |
| assert summary["failed"] == 1 | |
| assert g.jobs["A"].status == "failed" | |
| assert g.jobs["A"].retries == 3 # 2 retries + initial attempt | |
| assert "OOM" in g.jobs["A"].error |