|
7 | 7 | from procrastinate import testing |
8 | 8 |
|
9 | 9 | from taskbadger import StatusEnum |
10 | | -from taskbadger.procrastinate import TB_TASK_ID_KWARG, _instrument_task |
| 10 | +from taskbadger.procrastinate import TB_TASK_ID_KWARG, _instrument_task, track |
11 | 11 | from tests.utils import task_for_test |
12 | 12 |
|
13 | 13 |
|
@@ -181,3 +181,70 @@ def add6(a, b): |
181 | 181 | create.assert_called_once() |
182 | 182 | statuses = [c.kwargs["status"] for c in update.call_args_list] |
183 | 183 | assert statuses == [StatusEnum.PROCESSING, StatusEnum.SUCCESS] |
| 184 | + |
| 185 | + |
| 186 | +@pytest.mark.usefixtures("_bind_settings") |
| 187 | +def test_track_bare_form(app): |
| 188 | + @track |
| 189 | + @app.task(name="bare") |
| 190 | + def bare(a): |
| 191 | + return a |
| 192 | + |
| 193 | + tb = task_for_test() |
| 194 | + with mock.patch("taskbadger.procrastinate.create_task_safe", return_value=tb): |
| 195 | + bare.defer(a=1) |
| 196 | + |
| 197 | + assert getattr(bare, "_taskbadger_manual") is True |
| 198 | + # Inspect the actual Procrastinate job - jobs is a dict keyed by int, kwargs under "args" |
| 199 | + jobs = list(app.connector.jobs.values()) |
| 200 | + assert jobs[0]["args"][TB_TASK_ID_KWARG] == tb.id |
| 201 | + |
| 202 | + |
| 203 | +@pytest.mark.usefixtures("_bind_settings") |
| 204 | +def test_track_parameterized(app): |
| 205 | + @track(name="custom", value_max=10, tags={"env": "test"}, data={"k": "v"}) |
| 206 | + @app.task(name="raw_name") |
| 207 | + def raw(a): |
| 208 | + return a |
| 209 | + |
| 210 | + tb = task_for_test() |
| 211 | + with mock.patch("taskbadger.procrastinate.create_task_safe", return_value=tb) as create: |
| 212 | + raw.defer(a=1) |
| 213 | + |
| 214 | + create.assert_called_once() |
| 215 | + assert create.call_args.args == ("custom",) |
| 216 | + assert create.call_args.kwargs == { |
| 217 | + "status": StatusEnum.PENDING, |
| 218 | + "value_max": 10, |
| 219 | + "tags": {"env": "test"}, |
| 220 | + "data": {"k": "v"}, |
| 221 | + } |
| 222 | + |
| 223 | + |
| 224 | +@pytest.mark.usefixtures("_bind_settings") |
| 225 | +def test_track_idempotent(app): |
| 226 | + @track |
| 227 | + @track |
| 228 | + @app.task(name="dup") |
| 229 | + def dup(a): |
| 230 | + return a |
| 231 | + |
| 232 | + # Two @track applications must not double-wrap; defer once still creates one |
| 233 | + # PENDING task and injects one id. |
| 234 | + tb = task_for_test() |
| 235 | + with mock.patch("taskbadger.procrastinate.create_task_safe", return_value=tb) as create: |
| 236 | + dup.defer(a=1) |
| 237 | + assert create.call_count == 1 |
| 238 | + jobs = list(app.connector.jobs.values()) |
| 239 | + args = jobs[0]["args"] |
| 240 | + # Reserved key appears exactly once |
| 241 | + assert list(args).count(TB_TASK_ID_KWARG) == 1 |
| 242 | + |
| 243 | + |
| 244 | +def test_track_unknown_opt_raises(app): |
| 245 | + @app.task(name="bad") |
| 246 | + def bad(): |
| 247 | + pass |
| 248 | + |
| 249 | + with pytest.raises(TypeError, match="unexpected keyword"): |
| 250 | + track(name="x", does_not_exist=True)(bad) |
0 commit comments