Skip to content

Commit 4090c55

Browse files
authored
🎨Improve testing on DB listener (#8019)
1 parent fbde76d commit 4090c55

19 files changed

+290
-13
lines changed

packages/pytest-simcore/src/pytest_simcore/db_entries_mocks.py

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,15 @@
1010
import pytest
1111
import sqlalchemy as sa
1212
from faker import Faker
13+
from models_library.products import ProductName
1314
from models_library.projects import ProjectAtDB, ProjectID
1415
from models_library.projects_nodes_io import NodeID
16+
from pytest_simcore.helpers.postgres_tools import insert_and_get_row_lifespan
1517
from simcore_postgres_database.models.comp_pipeline import StateType, comp_pipeline
1618
from simcore_postgres_database.models.comp_tasks import comp_tasks
19+
from simcore_postgres_database.models.products import products
1720
from simcore_postgres_database.models.projects import ProjectType, projects
21+
from simcore_postgres_database.models.projects_to_products import projects_to_products
1822
from simcore_postgres_database.models.services import services_access_rights
1923
from simcore_postgres_database.models.users import UserRole, UserStatus, users
2024
from simcore_postgres_database.utils_projects_nodes import (
@@ -63,9 +67,22 @@ def creator(**user_kwargs) -> dict[str, Any]:
6367
print(f"<-- deleted users {created_user_ids=}")
6468

6569

70+
@pytest.fixture
71+
async def product_db(
72+
sqlalchemy_async_engine: AsyncEngine, product: dict[str, Any]
73+
) -> AsyncIterator[dict[str, Any]]:
74+
async with insert_and_get_row_lifespan( # pylint:disable=contextmanager-generator-missing-cleanup
75+
sqlalchemy_async_engine,
76+
table=products,
77+
values=product,
78+
pk_col=products.c.name,
79+
) as created_product:
80+
yield created_product
81+
82+
6683
@pytest.fixture
6784
async def project(
68-
sqlalchemy_async_engine: AsyncEngine, faker: Faker
85+
sqlalchemy_async_engine: AsyncEngine, faker: Faker, product_name: ProductName
6986
) -> AsyncIterator[Callable[..., Awaitable[ProjectAtDB]]]:
7087
created_project_ids: list[str] = []
7188

@@ -113,6 +130,12 @@ async def creator(
113130
for node_id in inserted_project.workbench
114131
],
115132
)
133+
await con.execute(
134+
projects_to_products.insert().values(
135+
project_uuid=f"{inserted_project.uuid}",
136+
product_name=product_name,
137+
)
138+
)
116139
print(f"--> created {inserted_project=}")
117140
created_project_ids.append(f"{inserted_project.uuid}")
118141
return inserted_project

services/director-v2/tests/conftest.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
"pytest_simcore.docker_registry",
4444
"pytest_simcore.docker_swarm",
4545
"pytest_simcore.environment_configs",
46+
"pytest_simcore.faker_products_data",
4647
"pytest_simcore.faker_projects_data",
4748
"pytest_simcore.faker_users_data",
4849
"pytest_simcore.minio_service",
@@ -355,7 +356,6 @@ async def wrapper(*args, **kwargs):
355356

356357
@pytest.fixture
357358
def mock_osparc_variables_api_auth_rpc(mocker: MockerFixture) -> None:
358-
359359
fake_data = ApiKeyGet.model_validate(ApiKeyGet.model_json_schema()["examples"][0])
360360

361361
async def _create(

services/director-v2/tests/integration/01/test_computation_api.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,7 @@ def test_invalid_computation(
192192
async def test_start_empty_computation_is_refused(
193193
async_client: httpx.AsyncClient,
194194
create_registered_user: Callable,
195+
product_db: dict[str, Any],
195196
project: Callable[..., Awaitable[ProjectAtDB]],
196197
osparc_product_name: str,
197198
osparc_product_api_base_url: str,
@@ -397,6 +398,7 @@ async def test_run_partial_computation(
397398
wait_for_catalog_service: Callable[[UserID, str], Awaitable[None]],
398399
async_client: httpx.AsyncClient,
399400
create_registered_user: Callable,
401+
product_db: dict[str, Any],
400402
project: Callable[..., Awaitable[ProjectAtDB]],
401403
update_project_workbench_with_comp_tasks: Callable,
402404
fake_workbench_without_outputs: dict[str, Any],
@@ -549,6 +551,7 @@ async def test_run_computation(
549551
wait_for_catalog_service: Callable[[UserID, str], Awaitable[None]],
550552
async_client: httpx.AsyncClient,
551553
create_registered_user: Callable,
554+
product_db: dict[str, Any],
552555
project: Callable[..., Awaitable[ProjectAtDB]],
553556
fake_workbench_without_outputs: dict[str, Any],
554557
update_project_workbench_with_comp_tasks: Callable,
@@ -667,6 +670,7 @@ async def test_run_computation(
667670
async def test_abort_computation(
668671
async_client: httpx.AsyncClient,
669672
create_registered_user: Callable,
673+
product_db: dict[str, Any],
670674
project: Callable[..., Awaitable[ProjectAtDB]],
671675
fake_workbench_without_outputs: dict[str, Any],
672676
fake_workbench_computational_pipeline_details: PipelineDetails,
@@ -746,6 +750,7 @@ async def test_abort_computation(
746750
async def test_update_and_delete_computation(
747751
async_client: httpx.AsyncClient,
748752
create_registered_user: Callable,
753+
product_db: dict[str, Any],
749754
project: Callable[..., Awaitable[ProjectAtDB]],
750755
fake_workbench_without_outputs: dict[str, Any],
751756
fake_workbench_computational_pipeline_details_not_started: PipelineDetails,
@@ -874,6 +879,7 @@ async def test_update_and_delete_computation(
874879
async def test_pipeline_with_no_computational_services_still_create_correct_comp_tasks_in_db(
875880
async_client: httpx.AsyncClient,
876881
create_registered_user: Callable,
882+
product_db: dict[str, Any],
877883
project: Callable[..., Awaitable[ProjectAtDB]],
878884
jupyter_service: dict[str, Any],
879885
osparc_product_name: str,
@@ -920,6 +926,7 @@ async def test_pipeline_with_no_computational_services_still_create_correct_comp
920926
async def test_pipeline_with_control_loop_made_of_dynamic_services_is_allowed(
921927
client: TestClient,
922928
create_registered_user: Callable,
929+
product_db: dict[str, Any],
923930
project: Callable[..., Awaitable[ProjectAtDB]],
924931
jupyter_service: dict[str, Any],
925932
osparc_product_name: str,
@@ -991,6 +998,7 @@ async def test_pipeline_with_control_loop_made_of_dynamic_services_is_allowed(
991998
async def test_pipeline_with_cycle_containing_a_computational_service_is_forbidden(
992999
client: TestClient,
9931000
create_registered_user: Callable,
1001+
product_db: dict[str, Any],
9941002
project: Callable[..., Awaitable[ProjectAtDB]],
9951003
sleeper_service: dict[str, Any],
9961004
jupyter_service: dict[str, Any],
@@ -1075,6 +1083,7 @@ async def test_pipeline_with_cycle_containing_a_computational_service_is_forbidd
10751083
async def test_burst_create_computations(
10761084
async_client: httpx.AsyncClient,
10771085
create_registered_user: Callable,
1086+
product_db: dict[str, Any],
10781087
project: Callable[..., Awaitable[ProjectAtDB]],
10791088
fake_workbench_without_outputs: dict[str, Any],
10801089
update_project_workbench_with_comp_tasks: Callable,

services/director-v2/tests/integration/02/test_dynamic_services_routes.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,9 @@ def user_id(user_db: dict[str, Any]) -> UserID:
9797

9898
@pytest.fixture
9999
async def project_id(
100-
user_db: dict[str, Any], project: Callable[..., Awaitable[ProjectAtDB]]
100+
user_db: dict[str, Any],
101+
project: Callable[..., Awaitable[ProjectAtDB]],
102+
product_db: dict[str, Any],
101103
) -> str:
102104
prj = await project(user=user_db)
103105
return f"{prj.uuid}"

services/director-v2/tests/integration/02/test_dynamic_sidecar_nodeports_integration.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
)
2929
from models_library.api_schemas_directorv2.computations import ComputationGet
3030
from models_library.clusters import ClusterAuthentication
31+
from models_library.products import ProductName
3132
from models_library.projects import (
3233
Node,
3334
NodesDict,
@@ -164,6 +165,7 @@ async def minimal_configuration(
164165
ensure_swarm_and_networks: None,
165166
minio_s3_settings_envs: EnvVarsDict,
166167
current_user: dict[str, Any],
168+
product_db: dict[str, Any],
167169
osparc_product_name: str,
168170
) -> AsyncIterator[None]:
169171
await wait_for_catalog_service(current_user["id"], osparc_product_name)
@@ -917,6 +919,13 @@ async def _assert_retrieve_completed(
917919
), "TIP: Message missing suggests that the data was never uploaded: look in services/dynamic-sidecar/src/simcore_service_dynamic_sidecar/modules/nodeports.py"
918920

919921

922+
def product_name(osparc_product_name: ProductName) -> ProductName:
923+
"""
924+
override the product name to be used in these tests
925+
"""
926+
return osparc_product_name
927+
928+
920929
@pytest.mark.flaky(max_runs=3)
921930
async def test_nodeports_integration(
922931
cleanup_services_and_networks: None,

services/director-v2/tests/integration/02/test_mixed_dynamic_sidecar_and_legacy_project.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,7 @@ def user_dict(create_registered_user: Callable) -> dict[str, Any]:
139139
async def dy_static_file_server_project(
140140
minimal_configuration: None,
141141
user_dict: dict[str, Any],
142+
product_db: dict[str, Any],
142143
project: Callable[..., Awaitable[ProjectAtDB]],
143144
dy_static_file_server_service: dict,
144145
dy_static_file_server_dynamic_sidecar_service: dict,

services/director-v2/tests/unit/with_dbs/comp_scheduler/test_api_route_computations.py

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ def minimal_configuration(
8888
faker: Faker,
8989
with_disabled_auto_scheduling: mock.Mock,
9090
with_disabled_scheduler_publisher: mock.Mock,
91+
product_db: dict[str, Any],
9192
):
9293
monkeypatch.setenv("DIRECTOR_V2_DYNAMIC_SIDECAR_ENABLED", "false")
9394
monkeypatch.setenv("COMPUTATIONAL_BACKEND_DASK_CLIENT_ENABLED", "1")
@@ -363,11 +364,6 @@ def _mocked_get_pricing_unit(request, pricing_plan_id: int) -> httpx.Response:
363364
yield respx_mock
364365

365366

366-
@pytest.fixture
367-
def product_name(faker: Faker) -> str:
368-
return faker.name()
369-
370-
371367
@pytest.fixture
372368
def product_api_base_url(faker: Faker) -> AnyHttpUrl:
373369
return TypeAdapter(AnyHttpUrl).validate_python(faker.url())
@@ -379,7 +375,7 @@ async def test_computation_create_validators(
379375
fake_workbench_without_outputs: dict[str, Any],
380376
product_name: str,
381377
product_api_base_url: AnyHttpUrl,
382-
faker: Faker,
378+
product_db: dict[str, Any],
383379
):
384380
user = create_registered_user()
385381
proj = await project(user, workbench=fake_workbench_without_outputs)
@@ -911,7 +907,7 @@ async def test_get_computation_from_not_started_computation_task(
911907
node_states={
912908
t.node_id: NodeState(
913909
modified=True,
914-
currentStatus=RunningState.NOT_STARTED,
910+
current_status=RunningState.NOT_STARTED,
915911
progress=None,
916912
dependencies={
917913
NodeID(node)
@@ -983,7 +979,7 @@ async def test_get_computation_from_published_computation_task(
983979
node_states={
984980
t.node_id: NodeState(
985981
modified=True,
986-
currentStatus=RunningState.PUBLISHED,
982+
current_status=RunningState.PUBLISHED,
987983
dependencies={
988984
NodeID(node)
989985
for node, next_nodes in fake_workbench_adjacency.items()

services/director-v2/tests/unit/with_dbs/comp_scheduler/test_api_route_computations_tasks.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,7 @@ async def project_id(
120120
project: Callable[..., Awaitable[ProjectAtDB]],
121121
create_pipeline: Callable[..., Awaitable[CompPipelineAtDB]],
122122
create_tasks: Callable[..., Awaitable[list[CompTaskAtDB]]],
123+
product_db: dict[str, Any],
123124
) -> ProjectID:
124125
"""project uuid of a saved project (w/ tasks up-to-date)"""
125126

@@ -133,6 +134,7 @@ async def project_id(
133134
)
134135
# insert tasks -> comp_tasks
135136
comp_tasks = await create_tasks(user=user, project=proj)
137+
assert comp_tasks
136138

137139
return proj.uuid
138140

@@ -166,7 +168,7 @@ async def test_get_all_tasks_log_files(
166168
assert resp.status_code == status.HTTP_200_OK
167169
log_files = TypeAdapter(list[TaskLogFileGet]).validate_json(resp.text)
168170
assert log_files
169-
assert all(l.download_link for l in log_files)
171+
assert all(file.download_link for file in log_files)
170172

171173

172174
async def test_get_task_logs_file(

services/director-v2/tests/unit/with_dbs/comp_scheduler/test_api_rpc_computations.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ async def test_rpc_list_computation_runs_and_tasks(
4040
create_tasks: Callable[..., Awaitable[list[CompTaskAtDB]]],
4141
create_comp_run: Callable[..., Awaitable[CompRunsAtDB]],
4242
rpc_client: RabbitMQRPCClient,
43+
product_db: dict[str, Any],
4344
):
4445
user = create_registered_user()
4546
proj = await project(user, workbench=fake_workbench_without_outputs)
@@ -119,6 +120,7 @@ async def test_rpc_list_computation_runs_with_filtering(
119120
create_tasks: Callable[..., Awaitable[list[CompTaskAtDB]]],
120121
create_comp_run: Callable[..., Awaitable[CompRunsAtDB]],
121122
rpc_client: RabbitMQRPCClient,
123+
product_db: dict[str, Any],
122124
):
123125
user = create_registered_user()
124126

@@ -175,6 +177,7 @@ async def test_rpc_list_computation_runs_history(
175177
create_tasks: Callable[..., Awaitable[list[CompTaskAtDB]]],
176178
create_comp_run: Callable[..., Awaitable[CompRunsAtDB]],
177179
rpc_client: RabbitMQRPCClient,
180+
product_db: dict[str, Any],
178181
):
179182
user = create_registered_user()
180183

@@ -186,6 +189,7 @@ async def test_rpc_list_computation_runs_history(
186189
comp_tasks = await create_tasks(
187190
user=user, project=proj, state=StateType.PUBLISHED, progress=None
188191
)
192+
assert comp_tasks
189193
comp_runs_1 = await create_comp_run(
190194
user=user,
191195
project=proj,
@@ -195,6 +199,7 @@ async def test_rpc_list_computation_runs_history(
195199
iteration=1,
196200
dag_adjacency_list=fake_workbench_adjacency,
197201
)
202+
assert comp_runs_1
198203
comp_runs_2 = await create_comp_run(
199204
user=user,
200205
project=proj,
@@ -204,6 +209,7 @@ async def test_rpc_list_computation_runs_history(
204209
iteration=2,
205210
dag_adjacency_list=fake_workbench_adjacency,
206211
)
212+
assert comp_runs_2
207213
comp_runs_3 = await create_comp_run(
208214
user=user,
209215
project=proj,
@@ -213,6 +219,7 @@ async def test_rpc_list_computation_runs_history(
213219
iteration=3,
214220
dag_adjacency_list=fake_workbench_adjacency,
215221
)
222+
assert comp_runs_3
216223

217224
output = await rpc_computations.list_computations_iterations_page(
218225
rpc_client, product_name="osparc", user_id=user["id"], project_ids=[proj.uuid]

services/director-v2/tests/unit/with_dbs/comp_scheduler/test_db_repositories_comp_runs.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
import datetime
1010
import random
1111
from collections.abc import Awaitable, Callable
12-
from typing import cast
12+
from typing import Any, cast
1313

1414
import arrow
1515
import pytest
@@ -56,6 +56,7 @@ async def test_get(
5656
fake_project_id: ProjectID,
5757
publish_project: Callable[[], Awaitable[PublishedProject]],
5858
create_comp_run: Callable[..., Awaitable[CompRunsAtDB]],
59+
product_db: dict[str, Any],
5960
):
6061
with pytest.raises(ComputationalRunNotFoundError):
6162
await CompRunsRepository(sqlalchemy_async_engine).get(
@@ -88,6 +89,7 @@ async def test_list(
8889
publish_project: Callable[[], Awaitable[PublishedProject]],
8990
run_metadata: RunMetadataDict,
9091
faker: Faker,
92+
product_db: dict[str, Any],
9193
):
9294
assert await CompRunsRepository(sqlalchemy_async_engine).list_() == []
9395

@@ -269,6 +271,7 @@ async def test_create(
269271
run_metadata: RunMetadataDict,
270272
faker: Faker,
271273
publish_project: Callable[[], Awaitable[PublishedProject]],
274+
product_db: dict[str, Any],
272275
):
273276
with pytest.raises(ProjectNotFoundError):
274277
await CompRunsRepository(sqlalchemy_async_engine).create(
@@ -331,6 +334,7 @@ async def test_update(
331334
run_metadata: RunMetadataDict,
332335
faker: Faker,
333336
publish_project: Callable[[], Awaitable[PublishedProject]],
337+
product_db: dict[str, Any],
334338
):
335339
# this updates nothing but also does not complain
336340
updated = await CompRunsRepository(sqlalchemy_async_engine).update(
@@ -371,6 +375,7 @@ async def test_set_run_result(
371375
run_metadata: RunMetadataDict,
372376
faker: Faker,
373377
publish_project: Callable[[], Awaitable[PublishedProject]],
378+
product_db: dict[str, Any],
374379
):
375380
published_project = await publish_project()
376381
created = await CompRunsRepository(sqlalchemy_async_engine).create(
@@ -419,6 +424,7 @@ async def test_mark_for_cancellation(
419424
run_metadata: RunMetadataDict,
420425
faker: Faker,
421426
publish_project: Callable[[], Awaitable[PublishedProject]],
427+
product_db: dict[str, Any],
422428
):
423429
published_project = await publish_project()
424430
created = await CompRunsRepository(sqlalchemy_async_engine).create(
@@ -451,6 +457,7 @@ async def test_mark_for_scheduling(
451457
run_metadata: RunMetadataDict,
452458
faker: Faker,
453459
publish_project: Callable[[], Awaitable[PublishedProject]],
460+
product_db: dict[str, Any],
454461
):
455462
published_project = await publish_project()
456463
created = await CompRunsRepository(sqlalchemy_async_engine).create(
@@ -485,6 +492,7 @@ async def test_mark_scheduling_done(
485492
run_metadata: RunMetadataDict,
486493
faker: Faker,
487494
publish_project: Callable[[], Awaitable[PublishedProject]],
495+
product_db: dict[str, Any],
488496
):
489497
published_project = await publish_project()
490498
created = await CompRunsRepository(sqlalchemy_async_engine).create(

0 commit comments

Comments
 (0)