Skip to content

Commit 9b13125

Browse files
committed
[V1][Metrics] Add unit test for metrics reading API
Signed-off-by: Mark McLoughlin <[email protected]>
1 parent 9bdf080 commit 9b13125

File tree

2 files changed

+113
-0
lines changed

2 files changed

+113
-0
lines changed

.buildkite/test-pipeline.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,7 @@ steps:
219219
- pytest -v -s v1/test_stats.py
220220
- pytest -v -s v1/test_utils.py
221221
- pytest -v -s v1/test_oracle.py
222+
- pytest -v -s v1/test_metrics_reader.py
222223
# TODO: accuracy does not match, whether setting
223224
# VLLM_USE_FLASHINFER_SAMPLER or not on H100.
224225
- pytest -v -s v1/e2e

tests/v1/test_metrics_reader.py

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
# SPDX-License-Identifier: Apache-2.0
2+
3+
import prometheus_client
4+
import pytest
5+
6+
from vllm.v1.metrics.reader import (Counter, Gauge, Histogram, Vector,
7+
get_metrics_snapshot)
8+
9+
10+
@pytest.fixture(autouse=True)
11+
def test_registry(monkeypatch):
12+
# Use a custom registry for tests
13+
test_registry = prometheus_client.CollectorRegistry(auto_describe=True)
14+
monkeypatch.setattr("vllm.v1.metrics.reader.REGISTRY", test_registry)
15+
return test_registry
16+
17+
18+
@pytest.mark.parametrize("num_engines", [1, 4])
19+
def test_gauge_metric(test_registry, num_engines):
20+
g = prometheus_client.Gauge("vllm:test_gauge",
21+
"Test gauge metric",
22+
labelnames=["model", "engine_index"],
23+
registry=test_registry)
24+
for i in range(num_engines):
25+
g.labels(model="foo", engine_index=str(i)).set(98.5)
26+
27+
metrics = get_metrics_snapshot()
28+
assert len(metrics) == num_engines
29+
engine_labels = [str(i) for i in range(num_engines)]
30+
for m in metrics:
31+
assert isinstance(m, Gauge)
32+
assert m.name == "vllm:test_gauge"
33+
assert m.value == 98.5
34+
assert m.labels["model"] == "foo"
35+
assert m.labels["engine_index"] in engine_labels
36+
engine_labels.remove(m.labels["engine_index"])
37+
38+
39+
@pytest.mark.parametrize("num_engines", [1, 4])
40+
def test_counter_metric(test_registry, num_engines):
41+
c = prometheus_client.Counter("vllm:test_counter",
42+
"Test counter metric",
43+
labelnames=["model", "engine_index"],
44+
registry=test_registry)
45+
for i in range(num_engines):
46+
c.labels(model="bar", engine_index=str(i)).inc(19)
47+
48+
metrics = get_metrics_snapshot()
49+
assert len(metrics) == num_engines
50+
engine_labels = [str(i) for i in range(num_engines)]
51+
for m in metrics:
52+
assert isinstance(m, Counter)
53+
assert m.name == "vllm:test_counter"
54+
assert m.value == 19
55+
assert m.labels["model"] == "bar"
56+
assert m.labels["engine_index"] in engine_labels
57+
engine_labels.remove(m.labels["engine_index"])
58+
59+
60+
@pytest.mark.parametrize("num_engines", [1, 4])
61+
def test_histogram_metric(test_registry, num_engines):
62+
h = prometheus_client.Histogram("vllm:test_histogram",
63+
"Test histogram metric",
64+
labelnames=["model", "engine_index"],
65+
buckets=[10, 20, 30, 40, 50],
66+
registry=test_registry)
67+
for i in range(num_engines):
68+
hist = h.labels(model="blaa", engine_index=str(i))
69+
hist.observe(42)
70+
hist.observe(21)
71+
hist.observe(7)
72+
73+
metrics = get_metrics_snapshot()
74+
assert len(metrics) == num_engines
75+
engine_labels = [str(i) for i in range(num_engines)]
76+
for m in metrics:
77+
assert isinstance(m, Histogram)
78+
assert m.name == "vllm:test_histogram"
79+
assert m.count == 3
80+
assert m.sum == 70
81+
assert m.buckets["10.0"] == 1
82+
assert m.buckets["20.0"] == 1
83+
assert m.buckets["30.0"] == 2
84+
assert m.buckets["40.0"] == 2
85+
assert m.buckets["50.0"] == 3
86+
assert m.labels["model"] == "blaa"
87+
assert m.labels["engine_index"] in engine_labels
88+
engine_labels.remove(m.labels["engine_index"])
89+
90+
91+
@pytest.mark.parametrize("num_engines", [1, 4])
92+
def test_vector_metric(test_registry, num_engines):
93+
c = prometheus_client.Counter(
94+
"vllm:spec_decode_num_accepted_tokens_per_pos",
95+
"Vector-like counter metric",
96+
labelnames=["position", "model", "engine_index"],
97+
registry=test_registry)
98+
for i in range(num_engines):
99+
c.labels(position="0", model="llama", engine_index=str(i)).inc(10)
100+
c.labels(position="1", model="llama", engine_index=str(i)).inc(5)
101+
c.labels(position="2", model="llama", engine_index=str(i)).inc(1)
102+
103+
metrics = get_metrics_snapshot()
104+
assert len(metrics) == num_engines
105+
engine_labels = [str(i) for i in range(num_engines)]
106+
for m in metrics:
107+
assert isinstance(m, Vector)
108+
assert m.name == "vllm:spec_decode_num_accepted_tokens_per_pos"
109+
assert m.values == [10, 5, 1]
110+
assert m.labels["model"] == "llama"
111+
assert m.labels["engine_index"] in engine_labels
112+
engine_labels.remove(m.labels["engine_index"])

0 commit comments

Comments
 (0)