Skip to content

Commit 676aa32

Browse files
committed
do full round trip in test
1 parent 653dbbc commit 676aa32

File tree

2 files changed

+79
-4
lines changed

2 files changed

+79
-4
lines changed

packages/models-library/src/models_library/functions.py

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,37 @@ class ProjectFunction(FunctionBase):
113113

114114

115115
class RegisteredProjectFunction(ProjectFunction, RegisteredFunctionBase):
116-
pass
116+
model_config = ConfigDict(
117+
populate_by_name=True,
118+
json_schema_extra={
119+
"examples": [
120+
{
121+
"function_class": "PROJECT",
122+
"title": "Example Project Function",
123+
"description": "This is an example project function.",
124+
"input_schema": {
125+
"schema_content": {
126+
"type": "object",
127+
"properties": {"input1": {"type": "integer"}},
128+
},
129+
"schema_class": "application/schema+json",
130+
},
131+
"output_schema": {
132+
"schema_content": {
133+
"type": "object",
134+
"properties": {"output1": {"type": "string"}},
135+
},
136+
"schema_class": "application/schema+json",
137+
},
138+
"default_inputs": None,
139+
"project_id": "11111111-1111-1111-1111-111111111111",
140+
"uid": "22222222-2222-2222-2222-222222222222",
141+
"created_at": "2024-01-01T12:00:00",
142+
"modified_at": "2024-01-02T12:00:00",
143+
},
144+
]
145+
},
146+
)
117147

118148

119149
SolverJobID: TypeAlias = UUID

services/api-server/tests/unit/celery/test_functions.py

Lines changed: 48 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,13 @@
66
from celery.contrib.testing.worker import TestWorkController
77
from celery_library.task import register_task
88
from faker import Faker
9-
from fastapi import FastAPI
9+
from fastapi import FastAPI, status
1010
from httpx import AsyncClient, BasicAuth
11+
from models_library.api_schemas_long_running_tasks.tasks import (
12+
TaskGet,
13+
TaskResult,
14+
TaskStatus,
15+
)
1116
from models_library.functions import (
1217
FunctionClass,
1318
FunctionID,
@@ -34,13 +39,45 @@
3439
JobPricingSpecification,
3540
NodeID,
3641
)
42+
from tenacity import (
43+
AsyncRetrying,
44+
retry_if_exception_type,
45+
stop_after_delay,
46+
wait_exponential,
47+
)
3748

3849
pytest_simcore_core_services_selection = ["postgres", "rabbit"]
3950
pytest_simcore_ops_services_selection = ["adminer"]
4051

4152
_faker = Faker()
4253

4354

55+
async def poll_task_until_done(
56+
client: AsyncClient,
57+
auth: BasicAuth,
58+
task_id: str,
59+
timeout: float = 30.0,
60+
) -> TaskResult:
61+
62+
async for attempt in AsyncRetrying(
63+
stop=stop_after_delay(timeout),
64+
wait=wait_exponential(multiplier=0.5, min=0.5, max=2.0),
65+
reraise=True,
66+
retry=retry_if_exception_type(AssertionError),
67+
):
68+
with attempt:
69+
70+
response = await client.get(f"/{API_VTAG}/tasks/{task_id}", auth=auth)
71+
response.raise_for_status()
72+
status = TaskStatus.model_validate(response.json())
73+
assert status.done is True
74+
75+
assert status.done is True
76+
response = await client.get(f"/{API_VTAG}/tasks/{task_id}/result", auth=auth)
77+
response.raise_for_status()
78+
return TaskResult.model_validate(response.json())
79+
80+
4481
def _register_fake_run_function_task() -> Callable[[Celery], None]:
4582

4683
async def run_function(
@@ -87,7 +124,6 @@ async def test_with_fake_run_function(
87124
auth: BasicAuth,
88125
with_storage_celery_worker: TestWorkController,
89126
):
90-
91127
app.dependency_overrides[get_function] = (
92128
lambda: RegisteredProjectFunction.model_validate(
93129
RegisteredProjectFunction.model_config.get("json_schema_extra", {}).get(
@@ -107,4 +143,13 @@ async def test_with_fake_run_function(
107143
headers=headers,
108144
)
109145

110-
assert response.status_code == 200
146+
assert response.status_code == status.HTTP_200_OK
147+
task = TaskGet.model_validate(response.json())
148+
149+
# Poll until task completion and get result
150+
result = await poll_task_until_done(client, auth, task.task_id)
151+
152+
# Verify the result is a RegisteredProjectFunctionJob
153+
assert result is not None
154+
assert isinstance(result, dict)
155+
# Add more specific assertions based on your expected result structure

0 commit comments

Comments
 (0)