"""Tests for triage.py — query classification and node selection.""" import asyncio import json import httpx import cluster import config import triage def _reset(): cluster.CLUSTER_NODES.clear() cluster.CLUSTER_COORDINATOR = None _published = [] async def _fake_publish(exchange, routing_key, payload): _published.append((exchange, routing_key, payload)) class _MockPostResponse: def __init__(self, json_data: dict, status_code: int = 200): self._json_data = json_data self.status_code = status_code def json(self): return self._json_data async def __aenter__(self): return self async def __aexit__(self, exc_type, exc, tb): return False class _MockPostContext: def __init__(self, response: _MockPostResponse): self._response = response async def __aenter__(self): return self._response async def __aexit__(self, exc_type, exc, tb): return False # ---------- 1. classify_query returns valid classification ---------- def test_classify_returns_valid(monkeypatch): async def post_stub(self, url, json=None, timeout=None): return _MockPostResponse({ "choices": [{"message": {"content": "code"}}] }) monkeypatch.setattr(httpx.AsyncClient, "post", post_stub) result = __import__("asyncio").run(triage.classify_query("write a python function")) assert result == "code" # ---------- 2. classify_query on error returns "general" ---------- def test_classify_error_returns_general(monkeypatch): async def post_stub(self, url, json=None, timeout=None): raise httpx.ConnectError("connection refused") monkeypatch.setattr(httpx.AsyncClient, "post", post_stub) result = __import__("asyncio").run(triage.classify_query("any question")) assert result == "general" # ---------- 3. select_node("code") returns coder node ---------- def test_select_node_code_returns_coder(): _reset() cluster.CLUSTER_NODES["coder01"] = { "name": "coder01", "type": "worker", "status": "active", "ip": "192.168.50.210", "active_model": {"name": "qwen2.5-coder-14b", "port": 8082}, } cluster.CLUSTER_NODES["general01"] = { "name": "general01", "type": "worker", "status": "active", "ip": "192.168.50.211", "active_model": {"name": "llama3.1", "port": 8081}, } node = asyncio.run(triage.select_node("code")) assert node is not None assert node["name"] == "coder01" # ---------- 4. select_node("general") with no matching node returns None ---------- def test_select_node_general_no_match_returns_none(): _reset() cluster.CLUSTER_NODES["coder01"] = { "name": "coder01", "type": "worker", "status": "active", "active_model": {"name": "qwen2.5-coder-14b", "port": 8082}, } node = asyncio.run(triage.select_node("general")) assert node is None # ---------- 5. get_inference_url with coder node ---------- def test_get_inference_url_with_coder_node(monkeypatch): _reset() async def fake_classify(query: str) -> str: return "code" monkeypatch.setattr(triage, "classify_query", fake_classify) cluster.CLUSTER_NODES["coder01"] = { "name": "coder01", "type": "worker", "status": "active", "ip": "192.168.50.210", "active_model": {"name": "qwen2.5-coder-14b", "port": 8082}, } url = __import__("asyncio").run(triage.get_inference_url("write a loop in rust")) assert url == "http://192.168.50.210:8082/v1" # ---------- 6. get_inference_url with no nodes returns LLAMA_SERVER_BASE ---------- def test_get_inference_url_no_nodes(monkeypatch): _reset() async def fake_classify(query: str) -> str: return "code" monkeypatch.setattr(triage, "classify_query", fake_classify) url = __import__("asyncio").run(triage.get_inference_url("any question")) assert url == config.LLAMA_SERVER_BASE