22# pylint: disable=unused-argument
33
44
5- from collections .abc import Callable
65from typing import Literal
76
87import pytest
1110from fastapi import status
1211from httpx import AsyncClient , BasicAuth
1312from models_library .api_schemas_long_running_tasks .tasks import TaskGet , TaskStatus
14- from models_library .api_schemas_rpc_async_jobs .exceptions import (
15- JobAbortedError ,
16- JobError ,
17- JobNotDoneError ,
18- JobSchedulerError ,
19- )
2013from pytest_mock import MockerFixture , MockType , mocker
2114from simcore_service_api_server .api .routes import tasks as task_routes
2215from simcore_service_api_server .models .schemas .base import ApiServerEnvelope
@@ -41,31 +34,14 @@ def _get_task_manager(app):
4134 return mock_task_manager_object
4235
4336
44- @pytest .fixture
45- def mock_task_manager_raising_factory (
46- mocker : MockerFixture ,
47- mock_task_manager_object_raising_factory : Callable [[Exception ], MockType ],
48- ) -> Callable [[Exception ], MockType ]:
49-
50- def _ (task_manager_exception : Exception ):
51- mock = mock_task_manager_object_raising_factory (task_manager_exception )
52-
53- def _get_task_manager (app ):
54- return mock
55-
56- mocker .patch .object (task_routes , "get_task_manager" , _get_task_manager )
57- return mock
58-
59- return _
60-
61-
6237async def test_list_celery_tasks (
6338 mock_task_manager : MockType ,
6439 client : AsyncClient ,
6540 auth : BasicAuth ,
6641):
6742
6843 response = await client .get ("/v0/tasks" , auth = auth )
44+ assert mock_task_manager .list_tasks .called
6945 assert response .status_code == status .HTTP_200_OK
7046
7147 result = ApiServerEnvelope [list [TaskGet ]].model_validate_json (response .text )
@@ -77,136 +53,119 @@ async def test_list_celery_tasks(
7753 assert task .status_href == f"/v0/tasks/{ task .task_id } "
7854
7955
80- @pytest .mark .parametrize (
81- "method, url, celery_exception, expected_status_code" ,
82- [
83- ("GET" , "/v0/tasks" , CeleryError (), status .HTTP_500_INTERNAL_SERVER_ERROR ),
84- (
85- "GET" ,
86- f"/v0/tasks/{ _faker .uuid4 ()} " ,
87- CeleryError (),
88- status .HTTP_500_INTERNAL_SERVER_ERROR ,
89- ),
90- (
91- "POST" ,
92- f"/v0/tasks/{ _faker .uuid4 ()} :cancel" ,
93- CeleryError (),
94- status .HTTP_500_INTERNAL_SERVER_ERROR ,
95- ),
96- (
97- "GET" ,
98- f"/v0/tasks/{ _faker .uuid4 ()} /result" ,
99- CeleryError (),
100- status .HTTP_500_INTERNAL_SERVER_ERROR ,
101- ),
102- ],
103- )
104- async def test_celery_tasks_error_propagation (
105- mock_task_manager_raising_factory : Callable [[Exception ], None ],
56+ async def test_get_async_jobs_status (
57+ mock_task_manager : MockType ,
10658 client : AsyncClient ,
10759 auth : BasicAuth ,
108- method : Literal ["GET" , "POST" ],
109- url : str ,
110- celery_exception : Exception ,
111- expected_status_code : int ,
11260):
113- mock_task_manager_raising_factory (celery_exception )
114-
115- response = await client .request (method = method , url = url , auth = auth )
116- assert response .status_code == expected_status_code
61+ task_id = f"{ _faker .uuid4 ()} "
62+ response = await client .get (f"/v0/tasks/{ task_id } " , auth = auth )
63+ assert mock_task_manager .get_task_status .called
64+ assert response .status_code == status .HTTP_200_OK
65+ TaskStatus .model_validate_json (response .text )
11766
11867
119- @pytest .mark .parametrize (
120- "async_job_error, expected_status_code" ,
121- [
122- (None , status .HTTP_200_OK ),
123- (
124- JobSchedulerError (
125- exc = Exception ("A very rare exception raised by the scheduler" )
126- ),
127- status .HTTP_500_INTERNAL_SERVER_ERROR ,
128- ),
129- ],
130- )
131- async def test_get_async_jobs_status (
68+ async def test_cancel_async_job (
69+ mock_task_manager : MockType ,
13270 client : AsyncClient ,
133- mocked_async_jobs_rpc_api : dict [str , MockType ],
134- async_job_error : Exception | None ,
13571 auth : BasicAuth ,
136- expected_status_code : int ,
13772):
13873 task_id = f"{ _faker .uuid4 ()} "
139- response = await client .get (f"/v0/tasks/{ task_id } " , auth = auth )
140- assert mocked_async_jobs_rpc_api ["status" ].called
141- assert f"{ mocked_async_jobs_rpc_api ['status' ].call_args [1 ]['job_id' ]} " == task_id
142- assert response .status_code == expected_status_code
143- if response .status_code == status .HTTP_200_OK :
144- TaskStatus .model_validate_json (response .text )
74+ response = await client .post (f"/v0/tasks/{ task_id } :cancel" , auth = auth )
75+ assert mock_task_manager .cancel_task .called
76+ assert response .status_code == status .HTTP_204_NO_CONTENT
14577
14678
147- @pytest .mark .parametrize (
148- "async_job_error, expected_status_code" ,
149- [
150- (None , status .HTTP_204_NO_CONTENT ),
151- (
152- JobSchedulerError (
153- exc = Exception ("A very rare exception raised by the scheduler" )
154- ),
155- status .HTTP_500_INTERNAL_SERVER_ERROR ,
156- ),
157- ],
158- )
159- async def test_cancel_async_job (
79+ async def test_get_result (
80+ mock_task_manager : MockType ,
16081 client : AsyncClient ,
161- mocked_async_jobs_rpc_api : dict [str , MockType ],
162- async_job_error : Exception | None ,
16382 auth : BasicAuth ,
164- expected_status_code : int ,
16583):
16684 task_id = f"{ _faker .uuid4 ()} "
167- response = await client .post (f"/v0/tasks/{ task_id } :cancel " , auth = auth )
168- assert mocked_async_jobs_rpc_api [ "cancel" ]. called
169- assert f" { mocked_async_jobs_rpc_api [ 'cancel' ]. call_args [ 1 ][ 'job_id' ] } " == task_id
170- assert response . status_code == expected_status_code
85+ response = await client .get (f"/v0/tasks/{ task_id } /result " , auth = auth )
86+ assert response . status_code == status . HTTP_200_OK
87+ assert mock_task_manager . get_task_result . called
88+ assert f" { mock_task_manager . get_task_result . call_args [ 1 ][ 'task_uuid' ] } " == task_id
17189
17290
17391@pytest .mark .parametrize (
174- "async_job_error , expected_status_code" ,
92+ "method, url, list_tasks_return_value, get_task_status_return_value, cancel_task_return_value , expected_status_code" ,
17593 [
176- (None , status .HTTP_200_OK ),
17794 (
178- JobError (
179- job_id = _faker . uuid4 () ,
180- exc_type = Exception ,
181- exc_message = "An exception from inside the async job" ,
182- ) ,
95+ "GET" ,
96+ "/v0/tasks" ,
97+ CeleryError () ,
98+ None ,
99+ None ,
183100 status .HTTP_500_INTERNAL_SERVER_ERROR ,
184101 ),
185102 (
186- JobNotDoneError ( job_id = _faker . uuid4 ()) ,
187- status . HTTP_404_NOT_FOUND ,
188- ) ,
189- (
190- JobAbortedError ( job_id = _faker . uuid4 ()) ,
191- status .HTTP_409_CONFLICT ,
103+ "GET" ,
104+ f"/v0/tasks/ { _faker . uuid4 () } " ,
105+ None ,
106+ CeleryError (),
107+ None ,
108+ status .HTTP_500_INTERNAL_SERVER_ERROR ,
192109 ),
193110 (
194- JobSchedulerError (
195- exc = Exception ("A very rare exception raised by the scheduler" )
196- ),
111+ "POST" ,
112+ f"/v0/tasks/{ _faker .uuid4 ()} :cancel" ,
113+ None ,
114+ None ,
115+ CeleryError (),
197116 status .HTTP_500_INTERNAL_SERVER_ERROR ,
198117 ),
199118 ],
200119)
201- async def test_get_async_job_result (
120+ async def test_celery_error_propagation (
121+ mock_task_manager : MockType ,
202122 client : AsyncClient ,
203- mocked_async_jobs_rpc_api : dict [str , MockType ],
204- async_job_error : Exception | None ,
205123 auth : BasicAuth ,
124+ method : Literal ["GET" , "POST" ],
125+ url : str ,
206126 expected_status_code : int ,
207127):
208- task_id = f"{ _faker .uuid4 ()} "
209- response = await client .get (f"/v0/tasks/{ task_id } /result" , auth = auth )
128+ response = await client .request (method = method , url = url , auth = auth )
210129 assert response .status_code == expected_status_code
211- assert mocked_async_jobs_rpc_api ["result" ].called
212- assert f"{ mocked_async_jobs_rpc_api ['result' ].call_args [1 ]['job_id' ]} " == task_id
130+
131+
132+ # @pytest.mark.parametrize(
133+ # "async_job_error, expected_status_code",
134+ # [
135+ # (None, status.HTTP_200_OK),
136+ # (
137+ # JobError(
138+ # job_id=_faker.uuid4(),
139+ # exc_type=Exception,
140+ # exc_message="An exception from inside the async job",
141+ # ),
142+ # status.HTTP_500_INTERNAL_SERVER_ERROR,
143+ # ),
144+ # (
145+ # JobNotDoneError(job_id=_faker.uuid4()),
146+ # status.HTTP_404_NOT_FOUND,
147+ # ),
148+ # (
149+ # JobAbortedError(job_id=_faker.uuid4()),
150+ # status.HTTP_409_CONFLICT,
151+ # ),
152+ # (
153+ # JobSchedulerError(
154+ # exc=Exception("A very rare exception raised by the scheduler")
155+ # ),
156+ # status.HTTP_500_INTERNAL_SERVER_ERROR,
157+ # ),
158+ # ],
159+ # )
160+ # async def test_get_async_job_result(
161+ # client: AsyncClient,
162+ # mocked_async_jobs_rpc_api: dict[str, MockType],
163+ # async_job_error: Exception | None,
164+ # auth: BasicAuth,
165+ # expected_status_code: int,
166+ # ):
167+ # task_id = f"{_faker.uuid4()}"
168+ # response = await client.get(f"/v0/tasks/{task_id}/result", auth=auth)
169+ # assert response.status_code == expected_status_code
170+ # assert mocked_async_jobs_rpc_api["result"].called
171+ # assert f"{mocked_async_jobs_rpc_api['result'].call_args[1]['job_id']}" == task_id
0 commit comments