|
1 | 1 | import batchtools.prom_metrics as pm |
2 | | -import types |
3 | 2 | from datetime import datetime |
4 | 3 | from unittest import mock |
5 | 4 |
|
6 | 5 |
|
7 | 6 | def test_now_rfc3339_parses_with_timezone(): |
8 | 7 | s = pm.now_rfc3339() |
9 | | - # ISO 8601 parseable and includes timezone info (+00:00) |
10 | 8 | dt = datetime.fromisoformat(s) |
11 | 9 | assert dt.tzinfo is not None |
12 | 10 | assert s.endswith("+00:00") |
13 | 11 |
|
14 | 12 |
|
15 | 13 | 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} |
17 | 15 |
|
18 | 16 |
|
19 | 17 | def _registry_text() -> str: |
@@ -78,61 +76,58 @@ def test_generate_metrics_text_returns_valid_payload_and_ctype(): |
78 | 76 |
|
79 | 77 |
|
80 | 78 | 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", ""): |
83 | 81 | pm.push_registry_text() |
| 82 | + |
84 | 83 | 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 |
87 | 87 |
|
88 | 88 |
|
89 | 89 | def test_push_registry_text_posts_success(capsys): |
90 | 90 | 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, |
95 | 93 | ): |
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"}) |
101 | 95 |
|
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 |
109 | 98 |
|
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"} |
113 | 107 |
|
114 | 108 |
|
115 | 109 | def test_push_registry_text_posts_failure(capsys): |
116 | 110 | 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")), |
121 | 113 | ): |
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 |
123 | 119 |
|
124 | | - pm.push_registry_text() |
125 | | - out = capsys.readouterr().out |
126 | | - assert "curl returned nonzero exit 7" in out |
127 | 120 |
|
| 121 | +def test_push_registry_text_handles_generic_exception(capsys): |
| 122 | + class WeirdError(Exception): |
| 123 | + pass |
128 | 124 |
|
129 | | -def test_push_registry_text_handles_exception(capsys): |
130 | 125 | 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")), |
135 | 128 | ): |
136 | | - pm.push_registry_text() |
| 129 | + pm.push_registry_text(grouping_key={"instance": "test-ns"}) |
| 130 | + |
137 | 131 | 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