Files
neuron-tai/tests/test_dashboard.py
2026-07-09 08:28:32 +03:00

257 lines
8.5 KiB
Python

"""US-035: tracker web dashboard — served from any tracker, embedded asset."""
import json
import time
import urllib.request
from meshnet_contracts import LocalSolanaContracts
from meshnet_tracker.accounts import AccountStore
from meshnet_tracker.billing import BillingLedger
from meshnet_tracker.server import TrackerServer
PANELS = [
"Tracker hive", "Nodes & coverage", "Client balances",
"Node pending payouts", "Settlement history",
"Strikes / bans / forfeitures", "Model usage", "Call wall",
"Usage summary", "Node throughput", "Request history",
"Chat / inference",
"Console output",
]
def test_dashboard_served_with_all_panels():
tracker = TrackerServer(billing=BillingLedger())
port = tracker.start()
try:
html = urllib.request.urlopen(
f"http://127.0.0.1:{port}/dashboard"
).read().decode()
for panel in PANELS:
assert panel in html
assert "<script>" in html # polling client embedded, no build step
assert "resolveModelGroup" in html
assert "buildModelAliasMap" in html
assert "modelAliasKey(raw)" in html
finally:
tracker.stop()
def test_dashboard_chat_uses_streaming_fetch():
tracker = TrackerServer(billing=BillingLedger())
port = tracker.start()
try:
html = urllib.request.urlopen(
f"http://127.0.0.1:{port}/dashboard"
).read().decode()
finally:
tracker.stop()
assert "stream: true" in html
assert ".body.getReader()" in html
assert '=== "[DONE]"' in html
assert 'console.error("chat stream failed", err)' in html
assert "preloadChatModels" in html
assert "renderChatModels(true)" in html
def test_network_map_includes_node_friendly_name():
tracker = TrackerServer()
port = tracker.start()
try:
body = json.dumps({
"endpoint": "http://127.0.0.1:9010",
"model": "stub-model",
"shard_start": 0,
"shard_end": 3,
"hardware_profile": {},
"friendly_name": "Kitchen GPU",
}).encode()
req = urllib.request.Request(
f"http://127.0.0.1:{port}/v1/nodes/register",
data=body,
headers={"Content-Type": "application/json"},
method="POST",
)
urllib.request.urlopen(req).read()
network = json.loads(
urllib.request.urlopen(f"http://127.0.0.1:{port}/v1/network/map").read()
)
finally:
tracker.stop()
assert network["nodes"][0]["friendly_name"] == "Kitchen GPU"
def test_dashboard_chat_model_selector_shows_health_and_speed():
tracker = TrackerServer()
port = tracker.start()
try:
html = urllib.request.urlopen(
f"http://127.0.0.1:{port}/dashboard"
).read().decode()
finally:
tracker.stop()
assert "chatModelHealthHp" in html
assert "modelServedCopiesFromMap" in html
assert "nodeDisplayName" in html
assert "accountDisplayName" in html
assert "saveNickname" in html
assert "chatModelTypicalTps" in html
assert "chatModelOptionLabel" in html
assert "findRoutingForModel" in html
assert "tok/s" in html
assert "toFixed(2)}HP" in html or '${copies(v)}HP' in html
def test_dashboard_chat_sessions_use_delegated_handlers():
tracker = TrackerServer()
port = tracker.start()
try:
html = urllib.request.urlopen(
f"http://127.0.0.1:{port}/dashboard"
).read().decode()
finally:
tracker.stop()
assert "bindChatSessionList" in html
assert "dataset.sessionId" in html
assert "dataset.deleteSession" in html
assert '[data-session-id]' in html
assert 'onclick="selectChatSession(' not in html
assert 'onclick="deleteChatSession(' not in html
def test_dashboard_incremental_refresh_helpers():
tracker = TrackerServer()
port = tracker.start()
try:
html = urllib.request.urlopen(
f"http://127.0.0.1:{port}/dashboard"
).read().decode()
finally:
tracker.stop()
assert "renderIfChanged" in html
assert "syncKeyedList" in html
assert "refreshBlocked" in html
assert "patchAccountPanelView" in html
assert "buildAccountPanelShell" in html
assert "refreshActiveTab" in html
assert "TAB_FETCHERS" in html
assert "loadAccountSummary" in html
assert "loadAccountUsage" in html
assert "fetchOverviewTab" in html
assert "pollCallWallIfIdle" in html
assert "pendingChatModelRefresh" in html
assert 'renderChatHistory(true)' in html
assert "renderChatHistory();" not in html
assert "refreshIfIdle" not in html
assert "refreshAccountIfIdle" not in html
assert "setInterval(refreshIfIdle" not in html
def test_dashboard_served_by_follower():
"""A tracker that is not the leader (unreachable peers → never elected)
still serves the dashboard from its own replicated state."""
tracker = TrackerServer(
billing=BillingLedger(),
cluster_peers=["http://127.0.0.1:1", "http://127.0.0.1:2"],
)
port = tracker.start()
try:
response = urllib.request.urlopen(f"http://127.0.0.1:{port}/dashboard")
assert response.status == 200
assert "meshnet tracker" in response.read().decode()
finally:
tracker.stop()
def test_registry_wallets_endpoint():
contracts = LocalSolanaContracts()
contracts.registry.submit_stake("wallet-a", 100)
contracts.registry.record_strike("wallet-a")
accounts = AccountStore()
admin = accounts.register(email="admin@example.com", password="admin-pass-123")
session = accounts.create_session(admin["account_id"])
tracker = TrackerServer(contracts=contracts, accounts=accounts)
port = tracker.start()
try:
req = urllib.request.Request(
f"http://127.0.0.1:{port}/v1/registry/wallets",
headers={"Authorization": f"Bearer {session}"},
)
data = json.loads(urllib.request.urlopen(req).read())
assert data["wallets"]["wallet-a"]["strike_count"] == 1
assert data["wallets"]["wallet-a"]["banned"] is False
finally:
tracker.stop()
def test_console_endpoint_exposes_tracker_events():
tracker = TrackerServer()
port = tracker.start()
try:
body = json.dumps({
"endpoint": "http://127.0.0.1:9001",
"model": "stub-model",
"shard_start": 0,
"shard_end": 3,
"hardware_profile": {},
}).encode()
req = urllib.request.Request(
f"http://127.0.0.1:{port}/v1/nodes/register",
data=body,
headers={"Content-Type": "application/json"},
method="POST",
)
urllib.request.urlopen(req).read()
data = json.loads(urllib.request.urlopen(f"http://127.0.0.1:{port}/v1/console").read())
finally:
tracker.stop()
assert any(event["message"] == "node registered" for event in data["events"])
def test_console_node_lifecycle_events_include_model_health():
tracker = TrackerServer(heartbeat_timeout=0.05)
port = tracker.start()
try:
body = json.dumps({
"endpoint": "http://127.0.0.1:9002",
"model": "console-health-test",
"hf_repo": "example/console-health-test",
"num_layers": 4,
"shard_start": 0,
"shard_end": 1,
"hardware_profile": {},
}).encode()
req = urllib.request.Request(
f"http://127.0.0.1:{port}/v1/nodes/register",
data=body,
headers={"Content-Type": "application/json"},
method="POST",
)
urllib.request.urlopen(req).read()
registered = json.loads(urllib.request.urlopen(f"http://127.0.0.1:{port}/v1/console").read())
registered_event = next(
event for event in registered["events"]
if event["message"] == "node registered"
)
assert registered_event["fields"]["model_health"]["served_model_copies"] == 0.5
assert registered_event["fields"]["model_health"]["coverage_percentage"] == 50.0
time.sleep(0.06)
urllib.request.urlopen(f"http://127.0.0.1:{port}/v1/network/map").read()
expired = json.loads(urllib.request.urlopen(f"http://127.0.0.1:{port}/v1/console").read())
expired_event = next(
event for event in expired["events"]
if event["message"] == "node expired"
)
assert expired_event["fields"]["model_health"]["served_model_copies"] == 0.0
assert expired_event["fields"]["model_health"]["coverage_percentage"] == 0.0
finally:
tracker.stop()