Skip to content

Commit e739aaa

Browse files
authored
🐛 Regression fix: computational services always restarting (ITISFoundation#3176)
1 parent f6060af commit e739aaa

File tree

9 files changed

+184
-85
lines changed

9 files changed

+184
-85
lines changed

ci/github/unit-testing/service-library.bash

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ test_all() {
2727
--durations=10 \
2828
--log-date-format="%Y-%m-%d %H:%M:%S" \
2929
--log-format="%(asctime)s %(levelname)s %(message)s" \
30-
--numprocesses=auto \
3130
--verbose \
3231
-m "not heavy_load" \
3332
packages/service-library/tests

packages/pytest-simcore/src/pytest_simcore/helpers/utils_dict.py

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
""" Utils to operate with dicts """
22

3+
from copy import deepcopy
34
from typing import Any, Mapping, Optional, Union
45

56
ConfigDict = dict[str, Any]
@@ -13,24 +14,37 @@ def get_from_dict(obj: Mapping[str, Any], dotted_key: str, default=None) -> Any:
1314
return value.get(keys[-1], default)
1415

1516

16-
def copy_from_dict(data: dict[str, Any], *, include: Optional[Union[set, dict]] = None):
17+
def copy_from_dict_ex(data: dict[str, Any], exclude: set[str]) -> dict[str, Any]:
18+
# NOTE: to be refactored by someone and merged with the next method
19+
return {k: v for k, v in data.items() if k not in exclude}
20+
21+
22+
def copy_from_dict(
23+
data: dict[str, Any],
24+
*,
25+
include: Optional[Union[set, dict]] = None,
26+
deep: bool = False
27+
):
1728
#
1829
# Analogous to advanced includes from pydantic exports
1930
# https://pydantic-docs.helpmanual.io/usage/exporting_models/#advanced-include-and-exclude
2031
#
2132

2233
if include is None:
23-
return data.copy()
34+
return deepcopy(data) if deep else data.copy()
2435

2536
if include == ...:
26-
return data
37+
return deepcopy(data) if deep else data.copy()
2738

2839
if isinstance(include, set):
2940
return {key: data[key] for key in include}
3041

3142
assert isinstance(include, dict) # nosec
3243

33-
return {key: copy_from_dict(data[key], include=include[key]) for key in include}
44+
return {
45+
key: copy_from_dict(data[key], include=include[key], deep=deep)
46+
for key in include
47+
}
3448

3549

3650
def update_dict(obj: dict, **updates):

packages/service-library/src/servicelib/archiving_utils.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,7 @@ def _add_to_archive(
225225
for file_to_add in _iter_files_to_compress(
226226
dir_to_compress, exclude_patterns
227227
):
228-
progress_bar.set_description(f"{desc}/{file_to_add.name}")
228+
progress_bar.set_description(f"{desc}/{file_to_add.name}\n")
229229
file_name_in_archive = (
230230
_strip_directory_from_path(file_to_add, dir_to_compress)
231231
if store_relative_path

services/director-v2/tests/unit/test_modules_dynamic_sidecar_docker_service_specs.py

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
import pytest
1010
import respx
1111
from fastapi import FastAPI
12-
from fastapi.encoders import jsonable_encoder
1312
from models_library.aiodocker_api import AioDockerServiceSpec
1413
from models_library.service_settings_labels import (
1514
SimcoreServiceLabels,
@@ -317,9 +316,8 @@ def expected_dynamic_sidecar_spec(run_id: UUID) -> dict[str, Any]:
317316
}
318317

319318

320-
# TESTS
321-
322-
319+
# NOTE: this test is flaky because of a set is serialized unsorted
320+
@pytest.mark.flaky(max_runs=3)
323321
def test_get_dynamic_proxy_spec(
324322
mocked_catalog_service_api: respx.MockRouter,
325323
minimal_app: FastAPI,
@@ -336,28 +334,32 @@ def test_get_dynamic_proxy_spec(
336334
dynamic_sidecar_settings.dict()
337335
== minimal_app.state.settings.DYNAMIC_SERVICES.DYNAMIC_SIDECAR.dict()
338336
)
339-
337+
expected_dynamic_sidecar_spec_model = AioDockerServiceSpec.parse_obj(
338+
expected_dynamic_sidecar_spec
339+
)
340+
assert expected_dynamic_sidecar_spec_model.TaskTemplate
341+
assert expected_dynamic_sidecar_spec_model.TaskTemplate.ContainerSpec
342+
assert expected_dynamic_sidecar_spec_model.TaskTemplate.ContainerSpec.Env
340343
for count in range(1, 11): # loop to check it does not repeat copies
341344
print(f"{count:*^50}")
342-
dynamic_sidecar_spec = get_dynamic_sidecar_spec(
345+
dynamic_sidecar_spec: AioDockerServiceSpec = get_dynamic_sidecar_spec(
343346
scheduler_data=scheduler_data,
344347
dynamic_sidecar_settings=dynamic_sidecar_settings,
345348
dynamic_sidecar_network_id=dynamic_sidecar_network_id,
346349
swarm_network_id=swarm_network_id,
347350
settings=cast(SimcoreServiceSettingsLabel, simcore_service_labels.settings),
348351
app_settings=minimal_app.state.settings,
349352
)
350-
assert dynamic_sidecar_spec
351-
assert jsonable_encoder(dynamic_sidecar_spec) == jsonable_encoder(
352-
AioDockerServiceSpec.parse_obj(expected_dynamic_sidecar_spec)
353-
)
353+
354+
assert dynamic_sidecar_spec == expected_dynamic_sidecar_spec_model
354355
dynamic_sidecar_spec_accumulated = dynamic_sidecar_spec
355-
assert jsonable_encoder(dynamic_sidecar_spec_accumulated) == jsonable_encoder(
356-
AioDockerServiceSpec.parse_obj(expected_dynamic_sidecar_spec)
357-
)
356+
assert dynamic_sidecar_spec_accumulated is not None
357+
assert dynamic_sidecar_spec_accumulated == expected_dynamic_sidecar_spec_model
358358
# TODO: finish test when working on https://github.com/ITISFoundation/osparc-simcore/issues/2454
359359

360360

361+
# NOTE: this test is flaky because of a set is serialized unsorted
362+
@pytest.mark.flaky(max_runs=3)
361363
async def test_merge_dynamic_sidecar_specs_with_user_specific_specs(
362364
mocked_catalog_service_api: respx.MockRouter,
363365
minimal_app: FastAPI,
@@ -379,9 +381,8 @@ async def test_merge_dynamic_sidecar_specs_with_user_specific_specs(
379381
app_settings=minimal_app.state.settings,
380382
)
381383
assert dynamic_sidecar_spec
382-
assert (
383-
jsonable_encoder(dynamic_sidecar_spec, by_alias=True, exclude_unset=True)
384-
== expected_dynamic_sidecar_spec
384+
assert dynamic_sidecar_spec == AioDockerServiceSpec.parse_obj(
385+
expected_dynamic_sidecar_spec
385386
)
386387

387388
catalog_client = CatalogClient.instance(minimal_app)

services/storage/tests/unit/test_handlers_simcore_s3.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -362,6 +362,7 @@ def mock_check_project_exists(mocker: MockerFixture):
362362
)
363363

364364

365+
@pytest.mark.flaky(max_runs=3)
365366
@pytest.mark.parametrize(
366367
"project",
367368
[pytest.param(prj, id=prj.name) for prj in _get_project_with_data()],

0 commit comments

Comments
 (0)