Skip to content

Commit 840462a

Browse files
adding tests to webserver
1 parent 5eea03a commit 840462a

File tree

4 files changed

+194
-14
lines changed

4 files changed

+194
-14
lines changed

packages/models-library/src/models_library/api_schemas_directorv2/comp_runs.py

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
from pydantic import (
55
BaseModel,
66
BeforeValidator,
7+
ConfigDict,
78
PositiveInt,
89
)
910

@@ -21,6 +22,40 @@ class ComputationRunRpcGet(BaseModel):
2122
started_at: datetime | None
2223
ended_at: datetime | None
2324

25+
model_config = ConfigDict(
26+
json_schema_extra={
27+
"examples": [
28+
{
29+
"project_uuid": "beb16d18-d57d-44aa-a638-9727fa4a72ef",
30+
"iteration": 1,
31+
"state": "SUCCESS",
32+
"info": {
33+
"wallet_id": 9866,
34+
"user_email": "[email protected]",
35+
"wallet_name": "test",
36+
"product_name": "osparc",
37+
"project_name": "test",
38+
"project_metadata": {
39+
"parent_node_id": "12e0c8b2-bad6-40fb-9948-8dec4f65d4d9",
40+
"parent_node_name": "UJyfwFVYySnPCaLuQIaz",
41+
"parent_project_id": "beb16d18-d57d-44aa-a638-9727fa4a72ef",
42+
"parent_project_name": "qTjDmYPxeqAWfCKCQCYF",
43+
"root_parent_node_id": "37176e84-d977-4993-bc49-d76fcfc6e625",
44+
"root_parent_node_name": "UEXExIZVPeFzGRmMglPr",
45+
"root_parent_project_id": "beb16d18-d57d-44aa-a638-9727fa4a72ef",
46+
"root_parent_project_name": "FuDpjjFIyeNTWRUWCuKo",
47+
},
48+
"node_id_names_map": {},
49+
"simcore_user_agent": "agent",
50+
},
51+
"submitted_at": "2023-01-11 13:11:47.293595",
52+
"started_at": "2023-01-11 13:11:47.293595",
53+
"ended_at": "2023-01-11 13:11:47.293595",
54+
}
55+
]
56+
}
57+
)
58+
2459

2560
class ComputationRunRpcGetPage(NamedTuple):
2661
items: list[ComputationRunRpcGet]
@@ -42,6 +77,26 @@ class ComputationTaskRpcGet(BaseModel):
4277
started_at: datetime | None
4378
ended_at: datetime | None
4479

80+
model_config = ConfigDict(
81+
json_schema_extra={
82+
"examples": [
83+
{
84+
"project_uuid": "beb16d18-d57d-44aa-a638-9727fa4a72ef",
85+
"node_id": "12e0c8b2-bad6-40fb-9948-8dec4f65d4d9",
86+
"state": "SUCCESS",
87+
"progress": 0.0,
88+
"image": {
89+
"name": "simcore/services/comp/ti-solutions-optimizer",
90+
"tag": "1.0.19",
91+
"node_requirements": {"CPU": 8.0, "RAM": 25769803776},
92+
},
93+
"started_at": "2023-01-11 13:11:47.293595",
94+
"ended_at": "2023-01-11 13:11:47.293595",
95+
}
96+
]
97+
}
98+
)
99+
45100

46101
class ComputationTaskRpcGetPage(NamedTuple):
47102
items: list[ComputationTaskRpcGet]

services/web/server/src/simcore_service_webserver/director_v2/_computations_rest.py

Lines changed: 30 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,24 +3,25 @@
33
from aiohttp import web
44
from models_library.api_schemas_webserver.computations import (
55
ComputationRunRestGet,
6-
ComputationRunRestGetPage,
76
ComputationTaskRestGet,
8-
ComputationTaskRestGetPage,
97
)
108
from models_library.rest_base import RequestParameters
9+
from models_library.rest_pagination import Page
10+
from models_library.rest_pagination_utils import paginate_data
1111
from models_library.users import UserID
1212
from pydantic import Field
1313
from servicelib.aiohttp.requests_validation import (
1414
parse_request_path_parameters_as,
1515
parse_request_query_parameters_as,
1616
)
17+
from servicelib.mimetype_constants import MIMETYPE_APPLICATION_JSON
1718
from servicelib.request_keys import RQT_USERID_KEY
19+
from servicelib.rest_constants import RESPONSE_MODEL_POLICY
1820

1921
from .._meta import API_VTAG as VTAG
2022
from ..constants import RQ_PRODUCT_KEY
2123
from ..login.decorators import login_required
2224
from ..security.decorators import permission_required
23-
from ..utils_aiohttp import envelope_json_response
2425
from . import _computations_service
2526
from ._computations_rest_schema import (
2627
ComputationRunListQueryParams,
@@ -63,12 +64,20 @@ async def list_computations_latest_iteration(request: web.Request) -> web.Respon
6364
# ordering
6465
order_by=query_params.order_by,
6566
)
66-
_output = ComputationRunRestGetPage(
67-
items=[ComputationRunRestGet(**task.dict()) for task in _get.items],
68-
total=_get.total,
69-
)
7067

71-
return envelope_json_response(_output)
68+
page = Page[ComputationRunRestGet].model_validate(
69+
paginate_data(
70+
chunk=[ComputationRunRestGet(**task.dict()) for task in _get.items],
71+
total=_get.total,
72+
limit=query_params.limit,
73+
offset=query_params.offset,
74+
request_url=request.url,
75+
)
76+
)
77+
return web.Response(
78+
text=page.model_dump_json(**RESPONSE_MODEL_POLICY),
79+
content_type=MIMETYPE_APPLICATION_JSON,
80+
)
7281

7382

7483
@routes.get(
@@ -99,9 +108,17 @@ async def list_computations_latest_iteration_tasks(
99108
# ordering
100109
order_by=query_params.order_by,
101110
)
102-
_output = ComputationTaskRestGetPage(
103-
items=[ComputationTaskRestGet(**task.dict()) for task in _get.items],
104-
total=_get.total,
105-
)
106111

107-
return envelope_json_response(_output)
112+
page = Page[ComputationTaskRestGet].model_validate(
113+
paginate_data(
114+
chunk=[ComputationTaskRestGet(**task.dict()) for task in _get.items],
115+
total=_get.total,
116+
limit=query_params.limit,
117+
offset=query_params.offset,
118+
request_url=request.url,
119+
)
120+
)
121+
return web.Response(
122+
text=page.model_dump_json(**RESPONSE_MODEL_POLICY),
123+
content_type=MIMETYPE_APPLICATION_JSON,
124+
)

services/web/server/tests/unit/with_dbs/01/conftest.py

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,14 @@
11
# pylint: disable=redefined-outer-name
22
# pylint: disable=unused-argument
33
# pylint: disable=unused-variable
4-
4+
from collections.abc import AsyncIterator
5+
from pathlib import Path
56

67
import pytest
8+
from aiohttp.test_utils import TestClient
9+
from pytest_simcore.helpers.webserver_login import UserInfoDict
10+
from pytest_simcore.helpers.webserver_projects import NewProject
11+
from simcore_service_webserver.projects.models import ProjectDict
712

813

914
@pytest.fixture
@@ -13,3 +18,23 @@ def app_environment(
1318
# NOTE: overrides app_environment
1419
monkeypatch.setenv("WEBSERVER_GARBAGE_COLLECTOR", "null")
1520
return app_environment | {"WEBSERVER_GARBAGE_COLLECTOR": "null"}
21+
22+
23+
@pytest.fixture
24+
async def user_project(
25+
client: TestClient,
26+
fake_project: ProjectDict,
27+
logged_user: UserInfoDict,
28+
tests_data_dir: Path,
29+
osparc_product_name: str,
30+
) -> AsyncIterator[ProjectDict]:
31+
async with NewProject(
32+
fake_project,
33+
client.app,
34+
user_id=logged_user["id"],
35+
product_name=osparc_product_name,
36+
tests_data_dir=tests_data_dir,
37+
) as project:
38+
print("-----> added project", project["name"])
39+
yield project
40+
print("<----- removed project", project["name"])

services/web/server/tests/unit/with_dbs/01/test_director_v2_handlers.py

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,18 @@
66
import pytest
77
from aiohttp.test_utils import TestClient
88
from faker import Faker
9+
from models_library.api_schemas_directorv2.comp_runs import (
10+
ComputationRunRpcGet,
11+
ComputationRunRpcGetPage,
12+
ComputationTaskRpcGet,
13+
ComputationTaskRpcGetPage,
14+
)
15+
from models_library.api_schemas_webserver.computations import (
16+
ComputationRunRestGet,
17+
ComputationTaskRestGet,
18+
)
919
from models_library.projects import ProjectID
20+
from pytest_mock import MockerFixture
1021
from pytest_simcore.helpers.assert_checks import assert_status
1122
from pytest_simcore.helpers.webserver_login import LoggedUser
1223
from pytest_simcore.helpers.webserver_parametrizations import (
@@ -16,6 +27,7 @@
1627
from pytest_simcore.services_api_mocks_for_aiohttp_clients import AioResponsesMock
1728
from servicelib.aiohttp import status
1829
from simcore_service_webserver.db.models import UserRole
30+
from simcore_service_webserver.projects.models import ProjectDict
1931

2032

2133
@pytest.fixture
@@ -117,3 +129,74 @@ async def test_stop_computation(
117129
else expected.no_content
118130
),
119131
)
132+
133+
134+
@pytest.fixture
135+
def mock_rpc_list_computations_latest_iteration_tasks(
136+
mocker: MockerFixture,
137+
) -> ComputationRunRpcGetPage:
138+
return mocker.patch(
139+
"simcore_service_webserver.director_v2._computations_service.computations.list_computations_latest_iteration_page",
140+
spec=True,
141+
return_value=ComputationRunRpcGetPage(
142+
items=[
143+
ComputationRunRpcGet.model_validate(
144+
ComputationRunRpcGet.model_config["json_schema_extra"]["examples"][
145+
0
146+
]
147+
)
148+
],
149+
total=1,
150+
),
151+
)
152+
153+
154+
@pytest.fixture
155+
def mock_rpc_list_computations_latest_iteration_tasks_page(
156+
mocker: MockerFixture,
157+
) -> ComputationTaskRpcGetPage:
158+
return mocker.patch(
159+
"simcore_service_webserver.director_v2._computations_service.computations.list_computations_latest_iteration_tasks_page",
160+
spec=True,
161+
return_value=ComputationTaskRpcGetPage(
162+
items=[
163+
ComputationTaskRpcGet.model_validate(
164+
ComputationTaskRpcGet.model_config["json_schema_extra"]["examples"][
165+
0
166+
]
167+
)
168+
],
169+
total=1,
170+
),
171+
)
172+
173+
174+
@pytest.mark.parametrize(*standard_role_response(), ids=str)
175+
async def test_list_computations_latest_iteration(
176+
director_v2_service_mock: AioResponsesMock,
177+
user_project: ProjectDict,
178+
client: TestClient,
179+
logged_user: LoggedUser,
180+
user_role: UserRole,
181+
expected: ExpectedResponse,
182+
mock_rpc_list_computations_latest_iteration_tasks: None,
183+
mock_rpc_list_computations_latest_iteration_tasks_page: None,
184+
):
185+
assert client.app
186+
url = client.app.router["list_computations_latest_iteration"].url_for()
187+
resp = await client.get(f"{url}")
188+
data, _ = await assert_status(
189+
resp, status.HTTP_200_OK if user_role == UserRole.GUEST else expected.ok
190+
)
191+
if user_role != UserRole.ANONYMOUS:
192+
assert ComputationRunRestGet.model_validate(data[0])
193+
194+
url = client.app.router["list_computations_latest_iteration_tasks"].url_for(
195+
project_id=f"{user_project['uuid']}"
196+
)
197+
resp = await client.get(f"{url}")
198+
data, _ = await assert_status(
199+
resp, status.HTTP_200_OK if user_role == UserRole.GUEST else expected.ok
200+
)
201+
if user_role != UserRole.ANONYMOUS:
202+
assert ComputationTaskRestGet.model_validate(data[0])

0 commit comments

Comments
 (0)