Files
TradeBot/tests/test_training_coordination.py
T
2026-06-27 08:56:54 +03:00

62 lines
2.1 KiB
Python

from __future__ import annotations
import base64
import hashlib
from crypto_spot_bot.training_coordination import TrainingCoordinator
def test_training_coordinator_claims_and_completes_job(tmp_path) -> None:
coordinator = TrainingCoordinator(tmp_path)
requested = coordinator.request_retrain({"source": "android"})
job_id = requested["job"]["id"]
heartbeat = coordinator.heartbeat({"worker_id": "win-1", "name": "DESKTOP-TMFDL0H"})
claimed = coordinator.claim({"worker_id": "win-1", "name": "DESKTOP-TMFDL0H"})
assert requested["queued"] is True
assert heartbeat["status"]["agent_online"] is True
assert claimed["claimed"] is True
assert claimed["job"]["id"] == job_id
assert coordinator.status()["active_job"]["status"] == "running"
completed = coordinator.complete(job_id, {"success": True, "message": "ok"})
assert completed["job"]["status"] == "completed"
assert coordinator.status()["active_job"] is None
def test_training_coordinator_accepts_chunked_artifact_upload(tmp_path) -> None:
coordinator = TrainingCoordinator(tmp_path)
job = coordinator.request_retrain({"source": "test"})["job"]
payload = b'{"type":"pytorch_recurrent_forecaster","symbols":{}}\n'
sha256 = hashlib.sha256(payload).hexdigest()
first = payload[:20]
second = payload[20:]
part_1 = coordinator.save_artifact_chunk(
job["id"],
{
"name": "lstm_forecaster.json",
"index": 0,
"total": 2,
"sha256": sha256,
"data_base64": base64.b64encode(first).decode("ascii"),
},
)
part_2 = coordinator.save_artifact_chunk(
job["id"],
{
"name": "lstm_forecaster.json",
"index": 1,
"total": 2,
"sha256": sha256,
"data_base64": base64.b64encode(second).decode("ascii"),
},
)
assert part_1["complete"] is False
assert part_2["complete"] is True
assert (tmp_path / "lstm_forecaster.json").read_bytes() == payload
assert coordinator.status()["latest_job"]["artifacts"][0]["sha256"] == sha256