Skip to content

Commit 628f288

Browse files
committed
Updated tests
1 parent ac94d0f commit 628f288

File tree

6 files changed

+68
-88
lines changed

6 files changed

+68
-88
lines changed

src/hope_country_report/apps/power_query/celery_tasks.py

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -135,14 +135,8 @@ def trap(sig: Any, frame: Any):
135135
except (Ignore, Reject, Retry):
136136
raise
137137
except Exception as e:
138+
# Let the on_failure handler in AbstractPowerQueryTask handle saving error details
138139
logger.exception(f"Unhandled exception in run_background_query for query {query_id}: {e}")
139-
if query:
140-
try:
141-
query.error_message = str(e)
142-
query.sentry_error_id = str(capture_exception(e))
143-
query.save(update_fields=["error_message", "sentry_error_id"])
144-
except Exception as save_e:
145-
logger.error(f"Failed to save error details for query {query_id} on exception: {save_e}")
146140
raise
147141

148142

src/hope_country_report/apps/power_query/models/query.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,9 @@ def execute_matrix(self, persist: bool = True, running_task: "PowerQueryTask|Non
128128
results[f"sentry_{str(a)}"] = str(err)
129129
self.error_message = str(e)
130130
self.sentry_error_id = str(err)
131-
self.save(update_fields=["error_message", "sentry_error_id"])
131+
if self.error_message:
132+
results["error_message"] = self.error_message
133+
results["sentry_error_id"] = self.sentry_error_id
132134
self.update_results(results)
133135
self.datasets.exclude(pk__in=[dpk for dpk in results.values() if isinstance(dpk, int)]).delete()
134136
return results

tests/admin/test_admin.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
from typing import Callable
2+
13
import pytest
24
from unittest import mock
35
from unittest.mock import Mock
@@ -237,17 +239,17 @@ def test_reportconfig_admin_queue(app, report_config):
237239
res_follow = res_post.follow()
238240
assert res_follow.status_code == 200
239241
messages = [m.message for m in res_follow.context["messages"]]
240-
assert "Queued" in messages
242+
assert "Queued" in messages[0]
241243

242244
with mock.patch.object(ReportConfiguration, "is_queued", return_value=True):
243245
change_url = reverse("admin:power_query_reportconfiguration_change", args=[report_config.pk])
244246
res_get_again = app.get(url, headers={"Referer": change_url})
245247
assert res_get_again.status_code == 302
246-
assert res_get_again.location == change_url, "Redirect should go to the change page if already queued"
248+
assert res_get_again.location == change_url
247249
res_follow_again = res_get_again.follow()
248250
assert res_follow_again.status_code == 200
249251
messages = [m.message for m in res_follow_again.context["messages"]]
250-
assert "Task has already been queued." in messages
252+
assert "Task has already been queued." in messages[0]
251253

252254

253255
def test_reportconfig_admin_terminate(app, report_config):
@@ -281,7 +283,7 @@ def test_reportconfig_admin_terminate(app, report_config):
281283
assert len(messages) > 0, "Expected success/info message after terminate"
282284

283285

284-
def test_reportconfig_admin_revoke(app, report_config):
286+
def test_reportconfig_admin_revoke(app: Callable, report_config: ReportConfiguration) -> None:
285287
"""Test the celery revoke action."""
286288
url = reverse("admin:power_query_reportconfiguration_celery_revoke", args=[report_config.pk])
287289

tests/admin/test_admin_pq.py

Lines changed: 21 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -32,18 +32,19 @@ def test_celery_terminate(django_app, admin_user, query):
3232
change_url = reverse("admin:power_query_query_change", args=[query.pk])
3333

3434
with mock.patch.object(Query, "is_queued", return_value=False):
35-
res_get = django_app.get(url, user=admin_user)
36-
assert res_get.status_code == 302, "Expected a redirect when task is not queued"
37-
assert res_get.location == change_url, "Redirect should go to the change page"
38-
res_follow = res_get.follow()
35+
res_get = django_app.get(url, user=admin_user, headers={"Referer": change_url})
36+
assert res_get.status_code == 302
37+
assert res_get.location == change_url
38+
res_follow = res_get.follow(expect_errors=True)
3939
messages = [m.message for m in res_follow.context["messages"]]
4040
assert "Task not queued." in messages
4141

4242
with mock.patch.object(Query, "is_queued", return_value=True):
4343
with mock.patch.object(Query, "terminate") as mock_terminate:
44-
res = django_app.get(url, user=admin_user)
44+
res = django_app.get(url, user=admin_user, headers={"Referer": change_url})
4545
assert res.status_code == 200
46-
assert f"Terminate {query}" in res.text
46+
assert "Confirm termination request" in res.text
47+
assert str(query) in res.text
4748

4849
change_url = reverse("admin:power_query_query_change", args=[query.pk])
4950

@@ -70,7 +71,7 @@ def test_celery_queue(django_app, admin_user, query):
7071
url = reverse("admin:power_query_query_celery_queue", args=[query.pk])
7172

7273
with mock.patch.object(Query, "queue") as mock_queue:
73-
res = django_app.get(url, user=admin_user)
74+
res = django_app.get(url, user=admin_user, headers={"Referer": url})
7475
assert res.status_code == 200
7576
assert f"Confirm queue action for {query}" in res.text
7677

@@ -87,11 +88,11 @@ def test_celery_queue(django_app, admin_user, query):
8788

8889
change_url = reverse("admin:power_query_query_change", args=[query.pk])
8990
with mock.patch.object(Query, "is_queued", return_value=True):
90-
res_get_again = django_app.get(url, user=admin_user)
91-
assert res_get_again.status_code == 302
92-
assert res_get_again.location == change_url, "Redirect should go to the change page if already queued"
93-
res_follow_again = res_get_again.follow()
94-
messages = [m.message for m in res_follow_again.context["messages"]]
91+
res_get_already_queued = django_app.get(url, user=admin_user, headers={"Referer": change_url})
92+
assert res_get_already_queued.status_code == 302
93+
assert res_get_already_queued.location == change_url
94+
res_follow_already_queued = res_get_already_queued.follow(expect_errors=True)
95+
messages = [m.message for m in res_follow_already_queued.context["messages"]]
9596
assert "Task has already been queued." in messages
9697

9798

@@ -102,18 +103,19 @@ def test_celery_revoke(django_app, admin_user, query):
102103
change_url = reverse("admin:power_query_query_change", args=[query.pk])
103104

104105
with mock.patch.object(Query, "is_queued", return_value=False):
105-
res_get = django_app.get(url, user=admin_user)
106-
assert res_get.status_code == 302
107-
assert res_get.location == change_url, "Redirect should go to the change page"
108-
res_follow = res_get.follow()
109-
messages = [m.message for m in res_follow.context["messages"]]
106+
res_get_not_queued = django_app.get(url, user=admin_user, headers={"Referer": change_url})
107+
assert res_get_not_queued.status_code == 302
108+
assert res_get_not_queued.location == change_url
109+
res_follow_not_queued = res_get_not_queued.follow(expect_errors=True)
110+
messages = [m.message for m in res_follow_not_queued.context["messages"]]
110111
assert "Task not queued." in messages
111112

112113
with mock.patch.object(Query, "is_queued", return_value=True):
113114
with mock.patch.object(Query, "revoke") as mock_revoke:
114-
res = django_app.get(url, user=admin_user)
115+
res = django_app.get(url, user=admin_user, headers={"Referer": change_url})
115116
assert res.status_code == 200
116-
assert f"Revoke {query}" in res.text
117+
assert "Confirm revoking action for [ABSTRACT]" in res.text
118+
assert str(query) in res.text
117119

118120
res_post = res.forms[1].submit()
119121
assert res_post.status_code == 302

tests/power_query/test_pq_celery.py

Lines changed: 34 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,13 @@
66

77
from django.conf import settings
88

9+
from celery import states
910
from celery.result import EagerResult
1011
from django_celery_beat.models import PeriodicTask
1112

1213
from hope_country_report.apps.power_query.celery_tasks import refresh_report, reports_refresh, run_background_query
1314
from hope_country_report.apps.power_query.exceptions import QueryRunCanceled, QueryRunTerminated
15+
from hope_country_report.apps.power_query.models import Query, ReportConfiguration
1416
from hope_country_report.config.celery import app
1517
from hope_country_report.state import state
1618

@@ -77,41 +79,45 @@ def query2():
7779

7880

7981
@pytest.fixture()
80-
def report(query1: "Query"):
82+
def report(query1: Query):
8183
from testutils.factories import ReportConfigurationFactory
8284

8385
return ReportConfigurationFactory(name="Celery Report", query=query1, owner=query1.owner)
8486

8587

86-
def test_run_background_query(settings, query1: "Query") -> None:
88+
def test_run_background_query(settings, query1: Query) -> None:
8789
settings.CELERY_TASK_ALWAYS_EAGER = True
8890
run_background_query.delay(query1.pk, query1.version)
8991
assert query1.datasets.exists()
9092

9193

92-
def test_run_background_query_version_mismatch(settings, query1: "Query") -> None:
94+
def test_run_background_query_version_mismatch(settings, query1: Query) -> None:
9395
settings.CELERY_TASK_ALWAYS_EAGER = True
94-
result = run_background_query.delay(query1.pk, -1)
95-
assert result.state == "REJECTED"
96+
result: EagerResult = run_background_query.delay(query1.pk, -1)
97+
assert result.state == states.REJECTED
9698

9799

98-
def test_run_background_query_removed(settings, query1: "Query", monkeypatch) -> None:
99-
from hope_country_report.apps.power_query.models import Query
100+
def test_run_background_query_removed(settings, query1: Query) -> None:
101+
from unittest.mock import PropertyMock
100102

101103
settings.CELERY_TASK_ALWAYS_EAGER = True
102-
with mock.patch("hope_country_report.apps.power_query.models.Query.status", Query.CANCELED):
104+
with mock.patch(
105+
"hope_country_report.apps.power_query.models.Query.task_status",
106+
new_callable=PropertyMock,
107+
return_value=states.REVOKED,
108+
):
103109
result: EagerResult = run_background_query.delay(query1.pk, query1.version)
104-
assert result.state == "IGNORED"
110+
assert result.state == "SUCCESS"
105111

106112

107-
def test_run_background_query_canceled(settings, query1: "Query", monkeypatch) -> None:
113+
def test_run_background_query_canceled(settings, query1: Query, monkeypatch) -> None:
108114
settings.CELERY_TASK_ALWAYS_EAGER = True
109115
with mock.patch("hope_country_report.apps.power_query.models.Query.execute_matrix", side_effect=QueryRunCanceled()):
110116
result: EagerResult = run_background_query.delay(query1.pk, query1.version)
111117
assert result.state == "REJECTED"
112118

113119

114-
def test_run_background_query_terminate(settings, query1: "Query", monkeypatch) -> None:
120+
def test_run_background_query_terminate(settings, query1: Query, monkeypatch) -> None:
115121
settings.CELERY_TASK_ALWAYS_EAGER = True
116122
with mock.patch(
117123
"hope_country_report.apps.power_query.models.Query.execute_matrix", side_effect=QueryRunTerminated()
@@ -125,13 +131,13 @@ def test_refresh_report(report: "ReportConfiguration") -> None:
125131
assert report.documents.exists()
126132

127133

128-
def test_celery_no_worker(db, settings, query2: "Query") -> None:
134+
def test_celery_no_worker(db, settings, query2: Query) -> None:
129135
settings.CELERY_TASK_ALWAYS_EAGER = False
130-
assert query2.status == "Not scheduled"
136+
assert query2.task_status == "Not scheduled"
131137
query2.queue()
132-
assert query2.status == "QUEUED"
138+
assert query2.task_status == "QUEUED"
133139
query2.terminate()
134-
assert query2.status == "CANCELED"
140+
assert query2.task_status == "Not scheduled"
135141

136142

137143
def test_celery_reports_refresh(db, settings, report: "ReportConfiguration") -> None:
@@ -147,45 +153,19 @@ def test_celery_reports_refresh(db, settings, report: "ReportConfiguration") ->
147153
assert result.state == "SUCCESS"
148154

149155

150-
# @pytest.fixture(scope="session")
151-
# def celery_config():
152-
# return {"broker_url": settings.CELERY_BROKER_URL, "result_backend": settings.CELERY_BROKER_URL}
153-
#
154-
#
155-
# @pytest.fixture(scope="session")
156-
# def celery_enable_logging():
157-
# return True
158-
#
159-
#
160-
# @pytest.fixture(scope="session")
161-
# def celery_worker_pool():
162-
# return "prefork"
163-
#
164-
165-
166-
@pytest.mark.django_db(transaction=True)
167-
def test_celery_error(settings, query_exception: "Query") -> None:
156+
@pytest.mark.django_db
157+
def test_celery_error(settings, query_exception: Query) -> None:
168158
settings.CELERY_TASK_ALWAYS_EAGER = True
159+
settings.CELERY_TASK_STORE_EAGER_RESULT = True
169160
query_exception.last_run = None
170-
result = query_exception.queue()
171-
assert result
161+
query_exception.error_message = None
162+
query_exception.sentry_error_id = None
163+
query_exception.save()
164+
165+
query_exception.queue()
166+
172167
query_exception.refresh_from_db()
173-
assert query_exception.last_run
174-
assert query_exception.curr_async_result_id == result
175-
assert query_exception.status == "Not scheduled"
176-
assert query_exception.error_message
177-
178-
179-
#
180-
#
181-
# @pytest.mark.django_db(transaction=True)
182-
# def test_celery_async(settings, celery_worker, query_exception: "Query") -> None:
183-
# settings.CELERY_TASK_ALWAYS_EAGER = True
184-
# query_exception.last_run = None
185-
# result = query_exception.queue()
186-
# assert result
187-
# query_exception.refresh_from_db()
188-
# assert query_exception.last_run
189-
# assert query_exception.curr_async_result_id == result
190-
# assert query_exception.status == "Not scheduled"
191-
# assert query_exception.error_message
168+
169+
assert query_exception.error_message == "internal exc"
170+
assert query_exception.sentry_error_id
171+
assert query_exception.task_status == "MISSING"

tests/power_query/test_pq_report.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -103,11 +103,11 @@ def report(query2: "Query", monkeypatch):
103103

104104
def test_celery_no_worker(db, settings, report: "ReportConfiguration") -> None:
105105
settings.CELERY_TASK_ALWAYS_EAGER = False
106-
assert report.status == "Not scheduled"
106+
assert report.task_status == "Not scheduled"
107107
report.queue()
108-
assert report.status == "QUEUED"
108+
assert report.task_status == "QUEUED"
109109
report.terminate()
110-
assert report.status == "CANCELED"
110+
assert report.task_status == "Not scheduled"
111111

112112

113113
def test_report_refresh(db, settings, report: "ReportConfiguration") -> None:

0 commit comments

Comments
 (0)