dash works !!! good data. billing seems to work
This commit is contained in:
@@ -1,8 +1,9 @@
|
||||
"""US-014 integration test: tracker-as-first-layer-node inference entry point.
|
||||
"""US-014 integration test: head-worker inference entry point.
|
||||
|
||||
Two stub tracker-nodes (shard 0-5, tracker_mode=True) + two mid-shard stub nodes
|
||||
(shard 6-11) for openai-community/gpt2. Ten requests via gateway assert round-robin
|
||||
load distribution across tracker-nodes and valid OpenAI-format responses.
|
||||
Two stub head workers (shard 0-5, tracker_mode=True for legacy wire
|
||||
compatibility) + two mid-shard stub nodes (shard 6-11) for openai-community/gpt2.
|
||||
Ten requests via gateway assert round-robin load distribution across head
|
||||
workers and valid OpenAI-format responses.
|
||||
"""
|
||||
|
||||
import json
|
||||
@@ -51,7 +52,7 @@ def _register_node(
|
||||
|
||||
@pytest.fixture
|
||||
def tracker_node_setup():
|
||||
"""Start tracker, two tracker-nodes (shard 0-5), two mid-shard nodes (shard 6-11),
|
||||
"""Start tracker, two head workers (shard 0-5), two mid-shard nodes (shard 6-11),
|
||||
and a gateway. Yields (gateway_url, tracker_node_a, tracker_node_b)."""
|
||||
|
||||
tracker = TrackerServer(
|
||||
@@ -66,12 +67,12 @@ def tracker_node_setup():
|
||||
tracker_port = tracker.start()
|
||||
tracker_url = f"http://127.0.0.1:{tracker_port}"
|
||||
|
||||
# Two tracker-nodes: serve shard 0-5, expose /v1/chat/completions
|
||||
# Two head workers: serve shard 0-5, expose /v1/chat/completions.
|
||||
tracker_node_a = StubNodeServer(
|
||||
shard_start=0,
|
||||
shard_end=5,
|
||||
is_last_shard=False,
|
||||
response_prefix="tracker-node-A:",
|
||||
response_prefix="head-worker-A:",
|
||||
model=GPT2_MODEL,
|
||||
tracker_mode=True,
|
||||
)
|
||||
@@ -81,7 +82,7 @@ def tracker_node_setup():
|
||||
shard_start=0,
|
||||
shard_end=5,
|
||||
is_last_shard=False,
|
||||
response_prefix="tracker-node-B:",
|
||||
response_prefix="head-worker-B:",
|
||||
model=GPT2_MODEL,
|
||||
tracker_mode=True,
|
||||
)
|
||||
@@ -106,7 +107,7 @@ def tracker_node_setup():
|
||||
)
|
||||
mid_port_b = mid_node_b.start()
|
||||
|
||||
# Register all nodes with tracker (tracker-nodes get tracker_mode=True)
|
||||
# Register all nodes with tracker (head workers keep legacy tracker_mode=True).
|
||||
_register_node(tracker_url, f"http://127.0.0.1:{port_a}", 0, 5, tracker_mode=True)
|
||||
_register_node(tracker_url, f"http://127.0.0.1:{port_b}", 0, 5, tracker_mode=True)
|
||||
_register_node(tracker_url, f"http://127.0.0.1:{mid_port_a}", 6, 11)
|
||||
@@ -155,22 +156,22 @@ def test_all_responses_valid_openai_format(tracker_node_setup):
|
||||
|
||||
|
||||
def test_both_tracker_nodes_receive_load(tracker_node_setup):
|
||||
"""Both tracker-nodes handle at least one request each out of ten."""
|
||||
"""Both head workers handle at least one request each out of ten."""
|
||||
gateway_url, tracker_node_a, tracker_node_b = tracker_node_setup
|
||||
for i in range(10):
|
||||
_send_chat_request(gateway_url, f"message {i}")
|
||||
assert tracker_node_a.chat_completion_count >= 1, (
|
||||
f"tracker-node-A received no requests (count={tracker_node_a.chat_completion_count})"
|
||||
f"head-worker-A received no requests (count={tracker_node_a.chat_completion_count})"
|
||||
)
|
||||
assert tracker_node_b.chat_completion_count >= 1, (
|
||||
f"tracker-node-B received no requests (count={tracker_node_b.chat_completion_count})"
|
||||
f"head-worker-B received no requests (count={tracker_node_b.chat_completion_count})"
|
||||
)
|
||||
total = tracker_node_a.chat_completion_count + tracker_node_b.chat_completion_count
|
||||
assert total == 10, f"total requests handled by tracker-nodes: {total}, expected 10"
|
||||
assert total == 10, f"total requests handled by head workers: {total}, expected 10"
|
||||
|
||||
|
||||
def test_tracker_nodes_endpoint_returns_registered_nodes(tracker_node_setup):
|
||||
"""GET /v1/tracker-nodes/<model> on the tracker returns both registered tracker-nodes."""
|
||||
"""GET /v1/tracker-nodes/<model> remains as a legacy alias for head workers."""
|
||||
_, tracker_node_a, tracker_node_b = tracker_node_setup
|
||||
# Find the tracker URL by inspecting the fixture indirectly
|
||||
# We need the tracker URL — use the gateway's tracker_url
|
||||
@@ -181,13 +182,13 @@ def test_tracker_nodes_endpoint_returns_registered_nodes(tracker_node_setup):
|
||||
|
||||
|
||||
def test_load_is_distributed_evenly(tracker_node_setup):
|
||||
"""With 10 requests and round-robin, each tracker-node gets exactly 5."""
|
||||
"""With 10 requests and round-robin, each head worker gets exactly 5."""
|
||||
gateway_url, tracker_node_a, tracker_node_b = tracker_node_setup
|
||||
for i in range(10):
|
||||
_send_chat_request(gateway_url, f"round-robin test {i}")
|
||||
assert tracker_node_a.chat_completion_count == 5, (
|
||||
f"expected 5 requests on tracker-node-A, got {tracker_node_a.chat_completion_count}"
|
||||
f"expected 5 requests on head-worker-A, got {tracker_node_a.chat_completion_count}"
|
||||
)
|
||||
assert tracker_node_b.chat_completion_count == 5, (
|
||||
f"expected 5 requests on tracker-node-B, got {tracker_node_b.chat_completion_count}"
|
||||
f"expected 5 requests on head-worker-B, got {tracker_node_b.chat_completion_count}"
|
||||
)
|
||||
|
||||
45
tests/test_tracker_control_plane.py
Normal file
45
tests/test_tracker_control_plane.py
Normal file
@@ -0,0 +1,45 @@
|
||||
"""Tracker control-plane boundaries."""
|
||||
|
||||
import subprocess
|
||||
import sys
|
||||
import textwrap
|
||||
|
||||
|
||||
def test_tracker_startup_does_not_import_or_load_model_backends():
|
||||
"""The public tracker is a router/API endpoint, not an inference worker."""
|
||||
code = textwrap.dedent(
|
||||
"""
|
||||
import builtins
|
||||
import sys
|
||||
|
||||
blocked_roots = {"meshnet_node", "torch", "transformers"}
|
||||
real_import = builtins.__import__
|
||||
|
||||
def guarded_import(name, globals=None, locals=None, fromlist=(), level=0):
|
||||
root = name.split(".", 1)[0]
|
||||
if root in blocked_roots:
|
||||
raise AssertionError(f"tracker imported model backend dependency: {name}")
|
||||
return real_import(name, globals, locals, fromlist, level)
|
||||
|
||||
builtins.__import__ = guarded_import
|
||||
|
||||
from meshnet_tracker.server import TrackerServer
|
||||
|
||||
tracker = TrackerServer()
|
||||
port = tracker.start()
|
||||
assert port > 0
|
||||
tracker.stop()
|
||||
|
||||
imported = blocked_roots & set(sys.modules)
|
||||
assert not imported, f"unexpected model modules imported: {sorted(imported)}"
|
||||
"""
|
||||
)
|
||||
|
||||
result = subprocess.run(
|
||||
[sys.executable, "-c", code],
|
||||
check=False,
|
||||
capture_output=True,
|
||||
text=True,
|
||||
)
|
||||
|
||||
assert result.returncode == 0, result.stderr
|
||||
Reference in New Issue
Block a user