Files
Xiaoze Fan 3af9d90ee5 feat: initial open-source release
Co-authored-by: Shuo Yang <andy_yang@berkeley.edu>
2026-08-11 22:53:25 +00:00

273 lines
9.1 KiB
Python

from __future__ import annotations
import queue
from queue import Empty as _Empty
from freetoken.utils import progress
from freetoken.server.supervisor import BackendHandle, LoadProgress, drain_ready, phase_slug
def test_drain_ready_counts_ready_acks_and_applies_progress():
q: "queue.Queue" = queue.Queue()
q.put(("progress", "Loading weights (FTW)", 5, 10))
q.put("Scheduler is ready")
q.put(("progress", "Loading experts (parallel)", 8, 8))
q.put("tokenizer ready")
q.put("detokenizer ready")
handle = BackendHandle(ack_queue=q, processes=[], expected_acks=3)
progress = LoadProgress()
drain_ready(handle, progress)
assert progress.total_bytes == 8
assert progress.done_bytes == 8
assert progress.phase == "expert_banks"
assert q.empty()
def test_drain_ready_forwards_meta_without_counting_it_ready():
"""("meta", payload) is optional backend metadata: forwarded to on_meta, but it must NOT
count toward expected_acks (else a meta-emitting engine would flip ready one ack early)."""
q: "queue.Queue" = queue.Queue()
q.put(("meta", {"kv_bytes_per_token": 42}))
q.put("Scheduler is ready")
q.put("tokenizer ready")
handle = BackendHandle(ack_queue=q, processes=[], expected_acks=2)
seen: dict = {}
drain_ready(handle, LoadProgress(), on_meta=lambda m: seen.update(m))
assert seen == {"kv_bytes_per_token": 42}
assert q.empty() # both real acks consumed; meta did not short-count them
def test_drain_ready_ignores_meta_when_no_callback():
"""An engine that emits meta while the caller passes no on_meta must not stall or error."""
q: "queue.Queue" = queue.Queue()
q.put(("meta", {"kv_bytes_per_token": 7}))
q.put("Scheduler is ready")
handle = BackendHandle(ack_queue=q, processes=[], expected_acks=1)
drain_ready(handle, LoadProgress()) # no on_meta
assert q.empty()
def test_drain_ready_detects_worker_death_during_load():
import queue
import pytest
from freetoken.server.supervisor import WorkerDied
class DeadProc:
name = "freetoken-TP0-scheduler"
def is_alive(self) -> bool:
return False
q: "queue.Queue" = queue.Queue() # never receives a ready ack
handle = BackendHandle(ack_queue=q, processes=[DeadProc()], expected_acks=1)
with pytest.raises(WorkerDied):
drain_ready(handle, LoadProgress(), get=lambda _t: (_ for _ in ()).throw(_Empty()))
def test_drain_ready_raises_the_real_reason_from_an_error_ack():
"""A worker that pushes ("error", reason) just before dying surfaces THAT reason (e.g. a
config ValueError), not the generic "exited during load"."""
import queue
import pytest
from freetoken.server.supervisor import WorkerDied
q: "queue.Queue" = queue.Queue()
q.put(("error", "ValueError: --moe-backend 'hybrid' cannot compute q4_0 experts on the CPU"))
handle = BackendHandle(ack_queue=q, processes=[], expected_acks=1)
with pytest.raises(WorkerDied) as exc:
drain_ready(handle, LoadProgress())
assert "q4_0" in str(exc.value)
def test_supervisor_reports_the_worker_error_reason_via_on_failure():
"""End to end: an ("error", reason) ack from a dying worker reaches on_failure verbatim, so
the desktop failure modal shows the actionable cause instead of "exited during load"."""
import queue
class DeadProc:
name = "freetoken-TP0-scheduler"
def is_alive(self) -> bool:
return False
q: "queue.Queue" = queue.Queue()
q.put(("error", "ValueError: bad checkpoint config"))
handle = BackendHandle(ack_queue=q, processes=[DeadProc()], expected_acks=1)
seen: dict = {}
from freetoken.server.supervisor import run_backend_supervisor
run_backend_supervisor(
handle,
LoadProgress(),
on_ready=lambda: seen.setdefault("ready", True),
on_failure=lambda m: seen.setdefault("failure", m),
poll=0.01,
)
assert "ready" not in seen
assert seen["failure"] == "ValueError: bad checkpoint config"
def test_supervisor_reports_failure_on_startup_death():
import queue
class DeadProc:
name = "freetoken-detokenizer-0"
def is_alive(self) -> bool:
return False
q: "queue.Queue" = queue.Queue()
handle = BackendHandle(ack_queue=q, processes=[DeadProc()], expected_acks=1)
seen: dict = {}
from freetoken.server.supervisor import run_backend_supervisor
run_backend_supervisor(
handle,
LoadProgress(),
on_ready=lambda: seen.setdefault("ready", True),
on_failure=lambda m: seen.setdefault("failure", m),
poll=0.01,
)
assert "ready" not in seen
assert "detokenizer" in seen["failure"]
def test_supervisor_detects_post_ready_death():
import queue
class Proc:
name = "freetoken-TP0-scheduler"
def __init__(self) -> None:
self._alive = True
def is_alive(self) -> bool:
return self._alive
proc = Proc()
q: "queue.Queue" = queue.Queue()
q.put("scheduler ready")
handle = BackendHandle(ack_queue=q, processes=[proc], expected_acks=1)
seen: dict = {}
from freetoken.server.supervisor import run_backend_supervisor
def on_ready() -> None:
seen["ready"] = True
proc._alive = False # die right after readiness
run_backend_supervisor(
handle, LoadProgress(), on_ready=on_ready,
on_failure=lambda m: seen.setdefault("failure", m), poll=0.01,
)
assert seen.get("ready") is True
assert "scheduler" in seen["failure"]
def test_supervisor_silent_on_post_ready_death_during_shutdown():
"""An orderly stop (SIGTERM/^C) sets a shutting-down flag before the workers exit. A
post-ready death observed while that flag is set is EXPECTED — the watchdog must return
silently: no on_failure, so no ERROR log and no "failed" latch during a clean stop."""
import queue
class Proc:
name = "freetoken-TP0-scheduler"
def __init__(self) -> None:
self._alive = True
def is_alive(self) -> bool:
return self._alive
proc = Proc()
q: "queue.Queue" = queue.Queue()
q.put("scheduler ready")
handle = BackendHandle(ack_queue=q, processes=[proc], expected_acks=1)
seen: dict = {}
shutting_down = {"v": False}
from freetoken.server.supervisor import run_backend_supervisor
def on_ready() -> None:
seen["ready"] = True
shutting_down["v"] = True # stop requested…
proc._alive = False # …and the worker exits as part of that stop
run_backend_supervisor(
handle, LoadProgress(), on_ready=on_ready,
on_failure=lambda m: seen.setdefault("failure", m), poll=0.01,
is_shutting_down=lambda: shutting_down["v"],
)
assert seen.get("ready") is True
assert "failure" not in seen # graceful stop: the death was not reported
def test_supervisor_silent_on_startup_death_during_shutdown():
"""A worker dying mid-load while an orderly stop is already in progress must not be
reported as a load failure either."""
import queue
class DeadProc:
name = "freetoken-detokenizer-0"
def is_alive(self) -> bool:
return False
q: "queue.Queue" = queue.Queue() # never receives a ready ack
handle = BackendHandle(ack_queue=q, processes=[DeadProc()], expected_acks=1)
seen: dict = {}
from freetoken.server.supervisor import run_backend_supervisor
run_backend_supervisor(
handle,
LoadProgress(),
on_ready=lambda: seen.setdefault("ready", True),
on_failure=lambda m: seen.setdefault("failure", m),
poll=0.01,
is_shutting_down=lambda: True, # stop already requested before load finished
)
assert "ready" not in seen
assert "failure" not in seen # silenced: expected exit during shutdown
# ---------------------------------------------------------------------------
# progress sink: the byte_bar -> set_progress_sink pipe drain_ready consumes, and the
# phase_slug normalization that labels the three serve bars.
# ---------------------------------------------------------------------------
def test_phase_slug_normalizes_the_three_serve_bars():
assert phase_slug("Loading weights (FTW)") == "weights"
assert phase_slug("Loading experts (parallel)") == "expert_banks"
assert phase_slug("Loading expert banks (FTW)") == "expert_banks"
assert phase_slug("something else") == "other"
assert phase_slug("") == "other"
def test_byte_bar_emits_to_installed_sink_then_stops_after_clear():
seen: list[tuple[str, int, int]] = []
progress.set_progress_sink(lambda desc, done, total: seen.append((desc, done, total)))
try:
bar = progress.byte_bar(total=100, desc="Loading weights (FTW)")
bar.update(100) # full jump always emits
bar.close()
finally:
progress.set_progress_sink(None)
assert seen and seen[-1] == ("Loading weights (FTW)", 100, 100)
# After clearing, a new bar must not emit.
seen.clear()
bar = progress.byte_bar(total=100, desc="Loading weights (FTW)")
bar.update(100)
bar.close()
assert seen == []