Skip to content

Commit 152c7e3

Browse files
adding final tests
1 parent b0cbcc2 commit 152c7e3

File tree

6 files changed

+212
-12
lines changed

6 files changed

+212
-12
lines changed

packages/models-library/src/models_library/api_schemas_webserver/computations.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,10 @@ class ComputationTaskRestGet(OutputSchema):
164164
class ComputationCollectionRunListQueryParams(
165165
PageQueryParameters,
166166
):
167+
filter_only_running: bool = Field(
168+
default=False,
169+
description="If true, only running collection runs are returned",
170+
)
167171
filter_by_root_project_id: ProjectID | None = Field(
168172
default=None,
169173
)

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

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,10 @@
88

99

1010
class CompRunCollectionDBGet(BaseModel):
11-
collection_id: CollectionRunID
12-
client_generated_id: str
13-
client_generated_display_name: str
11+
collection_run_id: CollectionRunID
12+
client_or_system_generated_id: str
13+
client_or_system_generated_display_name: str
14+
generated_by_system: bool
1415
created: datetime
1516

1617
model_config = ConfigDict(from_attributes=True)

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,10 @@ async def get_comp_run_collection_or_none_by_id(
4242
"""Get a computational run collection by collection_run_id."""
4343
result = await conn.execute(
4444
comp_run_collections.select().where(
45-
comp_run_collections.c.collection_run_id == collection_run_id
45+
comp_run_collections.c.collection_run_id == f"{collection_run_id}"
4646
)
4747
)
48-
row = await result.one_or_none()
48+
row = await result.first()
4949
if row is None:
5050
return None
5151
return CompRunCollectionDBGet.model_validate(row)

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -376,8 +376,8 @@ async def list_computation_collection_runs(
376376
started_at=item.started_at,
377377
ended_at=item.ended_at,
378378
name=(
379-
run_collection.client_generated_display_name
380-
if run_collection
379+
run_collection.client_or_system_generated_display_name
380+
if run_collection and run_collection.generated_by_system is False
381381
else project_root_name
382382
),
383383
)

services/web/server/src/simcore_service_webserver/director_v2/_controller/computations_rest.py

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -205,15 +205,16 @@ async def list_computations_latest_iteration_tasks(
205205
@permission_required("services.pipeline.*")
206206
@permission_required("project.read")
207207
async def list_computation_collection_runs(request: web.Request) -> web.Response:
208-
# Add: Filter by root project ID
209-
210208
req_ctx = ComputationsRequestContext.model_validate(request)
211209
query_params: ComputationCollectionRunListQueryParams = (
212210
parse_request_query_parameters_as(
213211
ComputationCollectionRunListQueryParams, request
214212
)
215213
)
216214

215+
if query_params.filter_only_running is True:
216+
raise NotImplementedError
217+
217218
total, items = await _computations_service.list_computation_collection_runs(
218219
request.app,
219220
product_name=req_ctx.product_name,
@@ -247,15 +248,13 @@ async def list_computation_collection_runs(request: web.Request) -> web.Response
247248

248249

249250
@routes.get(
250-
f"/{VTAG}/computation-collection-runs/{{collection_run_id}}/tasks", #: Who should be the owner of computation_collection_id ?
251+
f"/{VTAG}/computation-collection-runs/{{collection_run_id}}/tasks",
251252
name="list_computation_collection_run_tasks",
252253
)
253254
@login_required
254255
@permission_required("services.pipeline.*")
255256
@permission_required("project.read")
256257
async def list_computation_collection_run_tasks(request: web.Request) -> web.Response:
257-
# Add: Filter by root project ID
258-
259258
req_ctx = ComputationsRequestContext.model_validate(request)
260259
path_params = parse_request_path_parameters_as(
261260
ComputationCollectionRunPathParams, request

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

Lines changed: 196 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,22 @@
44

55

66
import pytest
7+
import sqlalchemy as sa
78
from aiohttp.test_utils import TestClient
89
from faker import Faker
910
from models_library.api_schemas_directorv2.comp_runs import (
11+
ComputationCollectionRunRpcGet,
12+
ComputationCollectionRunRpcGetPage,
13+
ComputationCollectionRunTaskRpcGet,
14+
ComputationCollectionRunTaskRpcGetPage,
1015
ComputationRunRpcGet,
1116
ComputationRunRpcGetPage,
1217
ComputationTaskRpcGet,
1318
ComputationTaskRpcGetPage,
1419
)
1520
from models_library.api_schemas_webserver.computations import (
21+
ComputationCollectionRunRestGet,
22+
ComputationCollectionRunTaskRestGet,
1623
ComputationRunRestGet,
1724
ComputationTaskRestGet,
1825
)
@@ -26,6 +33,8 @@
2633
)
2734
from pytest_simcore.services_api_mocks_for_aiohttp_clients import AioResponsesMock
2835
from servicelib.aiohttp import status
36+
from simcore_postgres_database.models.comp_run_collections import comp_run_collections
37+
from simcore_postgres_database.models.projects_metadata import projects_metadata
2938
from simcore_service_webserver.db.models import UserRole
3039
from simcore_service_webserver.projects.models import ProjectDict
3140

@@ -287,3 +296,190 @@ async def test_list_computations_latest_iteration(
287296
)
288297
if user_role != UserRole.ANONYMOUS:
289298
assert ComputationTaskRestGet.model_validate(data[0])
299+
300+
301+
### NEW:
302+
303+
304+
@pytest.fixture
305+
def mock_rpc_list_computation_collection_runs_page(
306+
mocker: MockerFixture,
307+
user_project: ProjectDict,
308+
) -> ComputationCollectionRunRpcGetPage:
309+
project_uuid = user_project["uuid"]
310+
example = ComputationCollectionRunRpcGet.model_config["json_schema_extra"][
311+
"examples"
312+
][0]
313+
example["project_ids"] = [project_uuid]
314+
example["info"]["project_metadata"]["root_parent_project_id"] = project_uuid
315+
316+
return mocker.patch(
317+
"simcore_service_webserver.director_v2._computations_service.computations.list_computation_collection_runs_page",
318+
spec=True,
319+
return_value=ComputationCollectionRunRpcGetPage(
320+
items=[ComputationCollectionRunRpcGet.model_validate(example)],
321+
total=1,
322+
),
323+
)
324+
325+
326+
@pytest.fixture
327+
def mock_rpc_list_computation_collection_run_tasks_page(
328+
mocker: MockerFixture,
329+
user_project: ProjectDict,
330+
) -> str:
331+
project_uuid = user_project["uuid"]
332+
workbench_ids = list(user_project["workbench"].keys())
333+
example = ComputationCollectionRunTaskRpcGet.model_config["json_schema_extra"][
334+
"examples"
335+
][0]
336+
example["node_id"] = workbench_ids[0]
337+
example["project_uuid"] = project_uuid
338+
339+
mocker.patch(
340+
"simcore_service_webserver.director_v2._computations_service.computations.list_computation_collection_run_tasks_page",
341+
spec=True,
342+
return_value=ComputationCollectionRunTaskRpcGetPage(
343+
items=[ComputationCollectionRunTaskRpcGet.model_validate(example)],
344+
total=1,
345+
),
346+
)
347+
348+
return workbench_ids[0]
349+
350+
351+
@pytest.mark.parametrize(*standard_role_response(), ids=str)
352+
async def test_list_computation_collection_runs_and_tasks(
353+
director_v2_service_mock: AioResponsesMock,
354+
user_project: ProjectDict,
355+
client: TestClient,
356+
logged_user: LoggedUser,
357+
user_role: UserRole,
358+
expected: ExpectedResponse,
359+
mock_rpc_list_computation_collection_runs_page: None,
360+
mock_rpc_list_computation_collection_run_tasks_page: str,
361+
faker: Faker,
362+
):
363+
assert client.app
364+
url = client.app.router["list_computation_collection_runs"].url_for()
365+
resp = await client.get(f"{url}")
366+
data, _ = await assert_status(
367+
resp, status.HTTP_200_OK if user_role == UserRole.GUEST else expected.ok
368+
)
369+
if user_role != UserRole.ANONYMOUS:
370+
assert ComputationCollectionRunRestGet.model_validate(data[0])
371+
assert data[0]["name"] == user_project["name"]
372+
373+
url = client.app.router["list_computation_collection_run_tasks"].url_for(
374+
collection_run_id=faker.uuid4()
375+
)
376+
resp = await client.get(f"{url}")
377+
data, _ = await assert_status(
378+
resp, status.HTTP_200_OK if user_role == UserRole.GUEST else expected.ok
379+
)
380+
if user_role != UserRole.ANONYMOUS:
381+
assert ComputationCollectionRunTaskRestGet.model_validate(data[0])
382+
assert len(data) == 1
383+
assert (
384+
data[0]["name"]
385+
== user_project["workbench"][
386+
mock_rpc_list_computation_collection_run_tasks_page
387+
]["label"]
388+
)
389+
390+
391+
@pytest.fixture
392+
async def populated_comp_run_collection(
393+
client: TestClient,
394+
postgres_db: sa.engine.Engine,
395+
):
396+
assert client.app
397+
example = ComputationCollectionRunRpcGet.model_config["json_schema_extra"][
398+
"examples"
399+
][0]
400+
collection_run_id = example["collection_run_id"]
401+
402+
with postgres_db.connect() as con:
403+
con.execute(
404+
comp_run_collections.insert()
405+
.values(
406+
collection_run_id=collection_run_id,
407+
client_or_system_generated_id=collection_run_id,
408+
client_or_system_generated_display_name="My Collection Run",
409+
generated_by_system=False,
410+
created=sa.func.now(),
411+
modified=sa.func.now(),
412+
)
413+
.returning(comp_run_collections.c.collection_run_id)
414+
)
415+
yield
416+
con.execute(comp_run_collections.delete())
417+
418+
419+
@pytest.mark.parametrize(*standard_role_response(), ids=str)
420+
async def test_list_computation_collection_runs_with_client_defined_name(
421+
director_v2_service_mock: AioResponsesMock,
422+
user_project: ProjectDict,
423+
client: TestClient,
424+
logged_user: LoggedUser,
425+
user_role: UserRole,
426+
expected: ExpectedResponse,
427+
populated_comp_run_collection: None,
428+
mock_rpc_list_computation_collection_runs_page: None,
429+
):
430+
assert client.app
431+
url = client.app.router["list_computation_collection_runs"].url_for()
432+
resp = await client.get(f"{url}")
433+
data, _ = await assert_status(
434+
resp, status.HTTP_200_OK if user_role == UserRole.GUEST else expected.ok
435+
)
436+
if user_role != UserRole.ANONYMOUS:
437+
assert ComputationCollectionRunRestGet.model_validate(data[0])
438+
assert data[0]["name"] == "My Collection Run"
439+
440+
441+
@pytest.fixture
442+
async def populated_project_metadata(
443+
client: TestClient,
444+
logged_user: LoggedUser,
445+
user_project: ProjectDict,
446+
postgres_db: sa.engine.Engine,
447+
):
448+
assert client.app
449+
project_uuid = user_project["uuid"]
450+
with postgres_db.connect() as con:
451+
con.execute(
452+
projects_metadata.insert().values(
453+
**{
454+
"project_uuid": project_uuid,
455+
"custom": {"job_name": "My Job Name"},
456+
}
457+
)
458+
)
459+
yield
460+
con.execute(projects_metadata.delete())
461+
462+
463+
@pytest.mark.parametrize(*standard_role_response(), ids=str)
464+
async def test_list_computation_collection_runs_and_tasks_with_different_names(
465+
director_v2_service_mock: AioResponsesMock,
466+
user_project: ProjectDict,
467+
client: TestClient,
468+
logged_user: LoggedUser,
469+
user_role: UserRole,
470+
expected: ExpectedResponse,
471+
populated_project_metadata: None,
472+
mock_rpc_list_computation_collection_run_tasks_page: str,
473+
faker: Faker,
474+
):
475+
assert client.app
476+
url = client.app.router["list_computation_collection_run_tasks"].url_for(
477+
collection_run_id=faker.uuid4()
478+
)
479+
resp = await client.get(f"{url}")
480+
data, _ = await assert_status(
481+
resp, status.HTTP_200_OK if user_role == UserRole.GUEST else expected.ok
482+
)
483+
if user_role != UserRole.ANONYMOUS:
484+
assert ComputationCollectionRunTaskRestGet.model_validate(data[0])
485+
assert data[0]["name"] == "My Job Name"

0 commit comments

Comments
 (0)