Skip to content

Commit c73d115

Browse files
committed
tests for prom_metrics that use prometheus rather than local server
1 parent 1373862 commit c73d115

File tree

4 files changed

+43
-50
lines changed

4 files changed

+43
-50
lines changed

batchtools/br.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
from .prom_metrics import (
2222
PROMETHEUS_INSTANCE,
2323
IN_PROGRESS,
24-
# record helpers (emit both histogram + counter)
2524
record_batch_observation,
2625
record_queue_observation,
2726
record_wall_observation,
@@ -191,7 +190,6 @@ def run(args: argparse.Namespace):
191190
job_name=job_name, wait=True, timeout=args.timeout
192191
)
193192

194-
# Emit metrics if we captured any timing
195193
if (
196194
run_elapsed is not None
197195
or queue_wait is not None
@@ -222,8 +220,8 @@ def run(args: argparse.Namespace):
222220
IN_PROGRESS.labels(**labels, result=result_phase).dec()
223221

224222
group = {
225-
"instance": PROMETHEUS_INSTANCE, # e.g. "ope-test"
226-
"job_name": job_name # e.g. "job-none-b799d46a6f995a9d8d58b6aff76abefc"
223+
"instance": PROMETHEUS_INSTANCE, # oc project
224+
"job_name": job_name, # unique name
227225
}
228226

229227
push_registry_text(grouping_key=group)

batchtools/prom_metrics.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import subprocess
21
from datetime import datetime, timezone
32
from .helpers import is_on_project
43

@@ -18,9 +17,8 @@
1817

1918
LONG_JOB_BUCKETS = (1, 2, 5, 10, 20, 30, 60, 120, 180, 300, 600, 900, float("inf"))
2019

21-
PUSHGATEWAY_ADDR = os.getenv(
22-
"PUSHGATEWAY_ADDR", "pushgateway.ope-test.svc:9091"
23-
)
20+
PUSHGATEWAY_ADDR = os.getenv("PUSHGATEWAY_ADDR", "pushgateway.ope-test.svc:9091")
21+
2422

2523
def detect_instance() -> str:
2624
if shutil.which("oc") is None:
@@ -94,6 +92,7 @@ def detect_instance() -> str:
9492
registry=registry,
9593
)
9694

95+
9796
def now_rfc3339() -> str:
9897
return datetime.now(timezone.utc).isoformat()
9998

@@ -141,6 +140,7 @@ def generate_metrics_text() -> tuple[str, str]:
141140
payload = generate_latest(registry)
142141
return payload.decode("utf-8"), CONTENT_TYPE_LATEST
143142

143+
144144
def push_registry_text(grouping_key: dict[str, str] | None = None) -> None:
145145
if not PUSHGATEWAY_ADDR:
146146
body, _ = generate_metrics_text()

pushgateway/prom.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,4 +48,4 @@ spec:
4848
- name: http
4949
port: 9091
5050
targetPort: 9091
51-
type: ClusterIP
51+
type: ClusterIP

tests/test_prom_metrics.py

Lines changed: 36 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,17 @@
11
import batchtools.prom_metrics as pm
2-
import types
32
from datetime import datetime
43
from unittest import mock
54

65

76
def test_now_rfc3339_parses_with_timezone():
87
s = pm.now_rfc3339()
9-
# ISO 8601 parseable and includes timezone info (+00:00)
108
dt = datetime.fromisoformat(s)
119
assert dt.tzinfo is not None
1210
assert s.endswith("+00:00")
1311

1412

1513
def _labels(job="job-x", gpu="none", queue="dummy-localqueue", instance="ns"):
16-
return {"job": job, "gpu": gpu, "queue": queue, "instance": instance}
14+
return {"job_name": job, "gpu": gpu, "queue": queue, "instance": instance}
1715

1816

1917
def _registry_text() -> str:
@@ -78,61 +76,58 @@ def test_generate_metrics_text_returns_valid_payload_and_ctype():
7876

7977

8078
def test_push_registry_text_no_url_prints_payload(capsys):
81-
# Temporarily clear the push URL so it prints instead of POSTing
82-
with mock.patch.object(pm, "PROMETHEUS_PUSH_URL", "", create=True):
79+
# check "no PUSHGATEWAY_ADDR" branch
80+
with mock.patch.object(pm, "PUSHGATEWAY_ADDR", ""):
8381
pm.push_registry_text()
82+
8483
out = capsys.readouterr().out
85-
assert "PROMETHEUS_PUSH_URL not set" in out
86-
assert "# HELP" in out # the metrics text is printed
84+
assert "PROM: PUSHGATEWAY_ADDR not set" in out
85+
assert "# HELP" in out
86+
assert "# TYPE" in out
8787

8888

8989
def test_push_registry_text_posts_success(capsys):
9090
with (
91-
mock.patch.object(
92-
pm, "PROMETHEUS_PUSH_URL", "http://example/metrics", create=True
93-
),
94-
mock.patch.object(pm.subprocess, "run") as mock_run,
91+
mock.patch.object(pm, "PUSHGATEWAY_ADDR", "pushgateway.example:9091"),
92+
mock.patch.object(pm, "pushadd_to_gateway") as mock_push,
9593
):
96-
mock_run.return_value = types.SimpleNamespace(returncode=0)
97-
98-
pm.push_registry_text()
99-
out = capsys.readouterr().out
100-
assert "metrics successfully pushed" in out
94+
pm.push_registry_text(grouping_key={"instance": "test-ns"})
10195

102-
# Verify we invoked curl with POST and sent our payload
103-
assert mock_run.called
104-
args, kwargs = mock_run.call_args
105-
argv = args[0]
106-
assert "curl" in argv[0]
107-
assert "-X" in argv and "POST" in argv
108-
assert "http://example/metrics" in argv
96+
out = capsys.readouterr().out
97+
assert "PROM: metrics pushed to pushgateway=pushgateway.example:9091" in out
10998

110-
payload = kwargs.get("input", b"").decode("utf-8")
111-
assert "# HELP" in payload
112-
assert "# TYPE" in payload
99+
# verify pushadd_to_gateway was called with expected args
100+
mock_push.assert_called_once()
101+
args, kwargs = mock_push.call_args
102+
assert args[0] == "pushgateway.example:9091"
103+
# job and registry are passed as keyword args
104+
assert kwargs.get("job") == "batchtools"
105+
assert kwargs.get("registry") is pm.registry
106+
assert kwargs.get("grouping_key") == {"instance": "test-ns"}
113107

114108

115109
def test_push_registry_text_posts_failure(capsys):
116110
with (
117-
mock.patch.object(
118-
pm, "PROMETHEUS_PUSH_URL", "http://example/metrics", create=True
119-
),
120-
mock.patch.object(pm.subprocess, "run") as mock_run,
111+
mock.patch.object(pm, "PUSHGATEWAY_ADDR", "pushgateway.example:9091"),
112+
mock.patch.object(pm, "pushadd_to_gateway", side_effect=RuntimeError("boom")),
121113
):
122-
mock_run.return_value = types.SimpleNamespace(returncode=7)
114+
pm.push_registry_text(grouping_key={"instance": "test-ns"})
115+
116+
out = capsys.readouterr().out
117+
assert "PROM: failed to push metrics to pushgateway pushgateway.example:9091" in out
118+
assert "boom" in out
123119

124-
pm.push_registry_text()
125-
out = capsys.readouterr().out
126-
assert "curl returned nonzero exit 7" in out
127120

121+
def test_push_registry_text_handles_generic_exception(capsys):
122+
class WeirdError(Exception):
123+
pass
128124

129-
def test_push_registry_text_handles_exception(capsys):
130125
with (
131-
mock.patch.object(
132-
pm, "PROMETHEUS_PUSH_URL", "http://example/metrics", create=True
133-
),
134-
mock.patch.object(pm.subprocess, "run", side_effect=RuntimeError("boom")),
126+
mock.patch.object(pm, "PUSHGATEWAY_ADDR", "pushgateway.example:9091"),
127+
mock.patch.object(pm, "pushadd_to_gateway", side_effect=WeirdError("weird")),
135128
):
136-
pm.push_registry_text()
129+
pm.push_registry_text(grouping_key={"instance": "test-ns"})
130+
137131
out = capsys.readouterr().out
138-
assert "failed to push metrics via curl" in out
132+
assert "PROM: failed to push metrics to pushgateway pushgateway.example:9091" in out
133+
assert "weird" in out

0 commit comments

Comments
 (0)