from __future__ import annotations
import pytest
from modelexpress.runtime_load import RuntimeLoadProvider, _scrape_gauge
_VLLM = """
# HELP vllm:gpu_cache_usage_perc GPU KV-cache usage.
# TYPE vllm:gpu_cache_usage_perc gauge
vllm:gpu_cache_usage_perc{model_name="Qwen"} 0.62
vllm:num_requests_running{model_name="Qwen"} 12.0
"""
_VLLM_017 = """
# vLLM >= 0.17 renamed the KV-cache gauge.
vllm:kv_cache_usage_perc{model="Qwen"} 0.73
"""
_SGLANG = """
sglang:token_usage 0.41
"""
_MULTI = """
vllm:gpu_cache_usage_perc{gpu="0"} 0.3
vllm:gpu_cache_usage_perc{gpu="1"} 0.8
"""
_DYNAMO = """
dynamo_component_gpu_cache_usage_percent{dynamo_component="backend",dp_rank="0"} 0.55
"""
_DYNAMO_AND_VLLM = """
vllm:kv_cache_usage_perc{model="Qwen"} 0.73
dynamo_component_gpu_cache_usage_percent{dp_rank="0"} 0.55
"""
def test_scrape_gauge_with_labels():
assert _scrape_gauge(_VLLM, "vllm:gpu_cache_usage_perc") == 0.62
def test_scrape_gauge_takes_max_across_series():
assert _scrape_gauge(_MULTI, "vllm:gpu_cache_usage_perc") == 0.8
def test_scrape_gauge_missing_returns_none():
assert _scrape_gauge(_VLLM, "does_not_exist") is None
def test_scrape_gauge_skips_comments():
assert _scrape_gauge("# TYPE x gauge\n# HELP x foo", "x") is None
def test_provider_reads_vllm_kv_usage():
p = RuntimeLoadProvider("http://x/metrics", _fetch=lambda u, t: _VLLM)
assert abs(p.sample() - 0.62) < 1e-9
def test_provider_reads_vllm_017_kv_cache_usage():
p = RuntimeLoadProvider("http://x/metrics", _fetch=lambda u, t: _VLLM_017)
assert abs(p.sample() - 0.73) < 1e-9
def test_provider_reads_sglang_when_vllm_absent():
p = RuntimeLoadProvider("http://x/metrics", _fetch=lambda u, t: _SGLANG)
assert abs(p.sample() - 0.41) < 1e-9
def test_provider_reads_dynamo_gauge_when_engine_absent():
p = RuntimeLoadProvider("http://x/metrics", _fetch=lambda u, t: _DYNAMO)
assert abs(p.sample() - 0.55) < 1e-9
def test_engine_gauge_wins_over_dynamo_fallback():
p = RuntimeLoadProvider("http://x/metrics", _fetch=lambda u, t: _DYNAMO_AND_VLLM)
assert abs(p.sample() - 0.73) < 1e-9
def test_provider_unreachable_returns_none():
p = RuntimeLoadProvider("http://x/metrics", _fetch=lambda u, t: None)
assert p.sample() is None
def test_provider_no_known_metric_returns_none():
p = RuntimeLoadProvider("http://x/metrics", _fetch=lambda u, t: "other_metric 5\n")
assert p.sample() is None
def test_provider_clamps():
p = RuntimeLoadProvider(
"http://x/metrics", _fetch=lambda u, t: "vllm:gpu_cache_usage_perc 1.5\n"
)
assert p.sample() == 1.0
def test_make_source_load_provider_blends_when_url_set(monkeypatch):
from modelexpress import runtime_load
from modelexpress.nic_metrics import make_source_load_provider
monkeypatch.setenv("MX_P2P_RUNTIME_METRICS_URL", "http://runtime.invalid/metrics")
monkeypatch.setattr(runtime_load, "_http_get", lambda url, timeout: None)
provider = make_source_load_provider(0)
val = provider()
assert val is None or (isinstance(val, float) and 0.0 <= val <= 1.0)
def test_blend_uses_the_provider_that_has_a_reading(monkeypatch):
from modelexpress import nic_metrics, runtime_load
monkeypatch.setenv("MX_P2P_RUNTIME_METRICS_URL", "http://runtime.invalid/metrics")
monkeypatch.setattr(
runtime_load, "_http_get", lambda url, timeout: "vllm:kv_cache_usage_perc 0.7\n"
)
monkeypatch.setattr(nic_metrics.SourceLoadSampler, "sample", lambda self: None)
provider = nic_metrics.make_source_load_provider(0)
assert provider() == pytest.approx(0.7)
def test_blend_is_none_when_neither_provider_has_a_reading(monkeypatch):
from modelexpress import nic_metrics, runtime_load
monkeypatch.setenv("MX_P2P_RUNTIME_METRICS_URL", "http://runtime.invalid/metrics")
monkeypatch.setattr(runtime_load, "_http_get", lambda url, timeout: None)
monkeypatch.setattr(nic_metrics.SourceLoadSampler, "sample", lambda self: None)
assert nic_metrics.make_source_load_provider(0)() is None