diff --git a/packages/pytest-simcore/src/pytest_simcore/file_extra.py b/packages/pytest-simcore/src/pytest_simcore/file_extra.py index 99ba8cc031cc..d2c85ee3de09 100644 --- a/packages/pytest-simcore/src/pytest_simcore/file_extra.py +++ b/packages/pytest-simcore/src/pytest_simcore/file_extra.py @@ -4,7 +4,7 @@ import pytest from faker import Faker -from pydantic import ByteSize +from pydantic import ByteSize, NonNegativeInt from pytest_simcore.helpers.logging_tools import log_context @@ -26,6 +26,37 @@ def _creator(size: ByteSize, name: str | None = None) -> Path: return _creator +def _create_random_content( + faker: Faker, + *, + base_dir: Path, + file_min_size: ByteSize, + file_max_size: ByteSize, + remaining_size: ByteSize, + depth: NonNegativeInt | None, +) -> ByteSize: + if remaining_size <= 0: + return remaining_size + + file_size = ByteSize( + faker.pyint( + min_value=min(file_min_size, remaining_size), + max_value=min(remaining_size, file_max_size), + ) + ) + if depth is None: + depth = faker.pyint(0, 5) + file_path = base_dir / f"{faker.unique.file_path(depth=depth, absolute=False)}" + file_path.parent.mkdir(parents=True, exist_ok=True) + assert not file_path.exists() + with file_path.open("wb") as fp: + fp.write(f"I am a {file_size.human_readable()} file".encode()) + fp.truncate(file_size) + assert file_path.exists() + + return ByteSize(remaining_size - file_size) + + @pytest.fixture def create_folder_of_size_with_multiple_files( tmp_path: Path, faker: Faker @@ -34,33 +65,12 @@ def _create_folder_of_size_with_multiple_files( directory_size: ByteSize, file_min_size: ByteSize, file_max_size: ByteSize, + depth: NonNegativeInt | None = None, ) -> Path: # Helper function to create random files and directories assert file_min_size > 0 assert file_min_size <= file_max_size - def create_random_content(base_dir: Path, remaining_size: ByteSize) -> ByteSize: - if remaining_size <= 0: - return remaining_size - - # Decide to create a file or a subdirectory - # Create a file - file_size = ByteSize( - faker.pyint( - min_value=min(file_min_size, remaining_size), - max_value=min(remaining_size, file_max_size), - ) - ) # max file size 1MB - file_path = base_dir / f"{faker.file_path(depth=4, absolute=False)}" - file_path.parent.mkdir(parents=True, exist_ok=True) - assert not file_path.exists() - with file_path.open("wb") as fp: - fp.write(f"I am a {file_size.human_readable()} file".encode()) - fp.truncate(file_size) - assert file_path.exists() - - return ByteSize(remaining_size - file_size) - # Recursively create content in the temporary directory remaining_size = directory_size with log_context( @@ -70,7 +80,14 @@ def create_random_content(base_dir: Path, remaining_size: ByteSize) -> ByteSize: ) as ctx: num_files_created = 0 while remaining_size > 0: - remaining_size = create_random_content(tmp_path, remaining_size) + remaining_size = _create_random_content( + faker, + base_dir=tmp_path, + file_min_size=file_min_size, + file_max_size=file_max_size, + remaining_size=remaining_size, + depth=depth, + ) num_files_created += 1 ctx.logger.info("created %s files", num_files_created) return tmp_path diff --git a/packages/pytest-simcore/src/pytest_simcore/helpers/httpx_assert_checks.py b/packages/pytest-simcore/src/pytest_simcore/helpers/httpx_assert_checks.py index f70d511a0bf8..40f174f5f07b 100644 --- a/packages/pytest-simcore/src/pytest_simcore/helpers/httpx_assert_checks.py +++ b/packages/pytest-simcore/src/pytest_simcore/helpers/httpx_assert_checks.py @@ -20,7 +20,7 @@ def assert_status( response_model: type[T] | None, *, expected_msg: str | None = None, - is_enveloped: bool = True, + expect_envelope: bool = True, ) -> tuple[T | None, Any]: """ Asserts for enveloped responses @@ -36,7 +36,7 @@ def assert_status( if expected_status_code == status.HTTP_204_NO_CONTENT: assert response.text == "" return None, None - if is_enveloped: + if expect_envelope: validated_response = TypeAdapter(Envelope[response_model]).validate_json( response.text ) @@ -49,6 +49,8 @@ def assert_status( expected_status_code, expected_msg, ) + else: + assert data is not None return data, error if is_error(expected_status_code): diff --git a/services/storage/tests/helpers/utils.py b/packages/pytest-simcore/src/pytest_simcore/helpers/storage_utils.py similarity index 78% rename from services/storage/tests/helpers/utils.py rename to packages/pytest-simcore/src/pytest_simcore/helpers/storage_utils.py index 399052a0c333..25f3b2b6e495 100644 --- a/services/storage/tests/helpers/utils.py +++ b/packages/pytest-simcore/src/pytest_simcore/helpers/storage_utils.py @@ -1,8 +1,10 @@ import logging import os -from typing import Any +from pathlib import Path +from typing import Any, TypedDict import sqlalchemy as sa +from models_library.basic_types import SHA256Str from simcore_postgres_database.storage_models import projects from sqlalchemy.ext.asyncio import AsyncEngine @@ -24,6 +26,10 @@ async def get_updated_project( result = await conn.execute( sa.select(projects).where(projects.c.uuid == project_id) ) - row = result.fetchone() - assert row + row = result.one() return row._asdict() + + +class FileIDDict(TypedDict): + path: Path + sha256_checksum: SHA256Str diff --git a/services/storage/tests/helpers/utils_file_meta_data.py b/packages/pytest-simcore/src/pytest_simcore/helpers/storage_utils_file_meta_data.py similarity index 100% rename from services/storage/tests/helpers/utils_file_meta_data.py rename to packages/pytest-simcore/src/pytest_simcore/helpers/storage_utils_file_meta_data.py diff --git a/services/storage/tests/helpers/utils_project.py b/packages/pytest-simcore/src/pytest_simcore/helpers/storage_utils_project.py similarity index 100% rename from services/storage/tests/helpers/utils_project.py rename to packages/pytest-simcore/src/pytest_simcore/helpers/storage_utils_project.py diff --git a/services/storage/tests/fixtures/data_models.py b/packages/pytest-simcore/src/pytest_simcore/simcore_storage_data_models.py similarity index 77% rename from services/storage/tests/fixtures/data_models.py rename to packages/pytest-simcore/src/pytest_simcore/simcore_storage_data_models.py index e3ff1787aa96..b172b3b34df5 100644 --- a/services/storage/tests/fixtures/data_models.py +++ b/packages/pytest-simcore/src/pytest_simcore/simcore_storage_data_models.py @@ -7,24 +7,24 @@ from contextlib import asynccontextmanager from pathlib import Path from random import choice, randint -from typing import Any +from typing import Any, cast import pytest import sqlalchemy as sa from faker import Faker from models_library.basic_types import SHA256Str from models_library.projects import ProjectID -from models_library.projects_nodes_io import NodeID, SimcoreS3FileID +from models_library.projects_nodes_io import NodeID, SimcoreS3FileID, StorageFileID from models_library.users import UserID from pydantic import ByteSize, TypeAdapter -from pytest_simcore.helpers.faker_factories import random_project, random_user from servicelib.utils import limited_gather from simcore_postgres_database.models.project_to_groups import project_to_groups from simcore_postgres_database.storage_models import projects, users from sqlalchemy.dialects.postgresql import insert as pg_insert from sqlalchemy.ext.asyncio import AsyncConnection, AsyncEngine -from ..helpers.utils import get_updated_project +from .helpers.faker_factories import random_project, random_user +from .helpers.storage_utils import FileIDDict, get_updated_project @asynccontextmanager @@ -259,6 +259,39 @@ async def _creator( return _creator +async def _upload_file_and_update_project( + project_id: ProjectID, + node_id: NodeID, + *, + file_name: str | None, + file_id: StorageFileID | None, + file_sizes: tuple[ByteSize, ...], + file_checksums: tuple[SHA256Str, ...], + node_to_files_mapping: dict[NodeID, dict[SimcoreS3FileID, FileIDDict]], + upload_file: Callable[..., Awaitable[tuple[Path, SimcoreS3FileID]]], + create_simcore_file_id: Callable[ + [ProjectID, NodeID, str, Path | None], SimcoreS3FileID + ], + faker: Faker, +) -> None: + if file_name is None: + file_name = faker.file_name() + file_id = create_simcore_file_id(project_id, node_id, file_name, None) + checksum: SHA256Str = choice(file_checksums) # noqa: S311 + src_file, _ = await upload_file( + file_size=choice(file_sizes), # noqa: S311 + file_name=file_name, + file_id=file_id, + sha256_checksum=checksum, + ) + assert file_name is not None + assert file_id is not None + node_to_files_mapping[node_id][file_id] = { + "path": src_file, + "sha256_checksum": checksum, + } + + @pytest.fixture async def random_project_with_files( sqlalchemy_async_engine: AsyncEngine, @@ -271,11 +304,7 @@ async def random_project_with_files( faker: Faker, ) -> Callable[ [int, tuple[ByteSize, ...], tuple[SHA256Str, ...]], - Awaitable[ - tuple[ - dict[str, Any], dict[NodeID, dict[SimcoreS3FileID, dict[str, Path | str]]] - ] - ], + Awaitable[tuple[dict[str, Any], dict[NodeID, dict[SimcoreS3FileID, FileIDDict]]]], ]: async def _creator( num_nodes: int = 12, @@ -295,76 +324,67 @@ async def _creator( "488f3b57932803bbf644593bd46d95599b1d4da1d63bc020d7ebe6f1c255f7f3" ), ), - ) -> tuple[ - dict[str, Any], dict[NodeID, dict[SimcoreS3FileID, dict[str, Path | str]]] - ]: + ) -> tuple[dict[str, Any], dict[NodeID, dict[SimcoreS3FileID, FileIDDict]]]: assert len(file_sizes) == len(file_checksums) project = await create_project(name="random-project") - src_projects_list: dict[ - NodeID, dict[SimcoreS3FileID, dict[str, Path | str]] - ] = {} + node_to_files_mapping: dict[NodeID, dict[SimcoreS3FileID, FileIDDict]] = {} upload_tasks: deque[Awaitable] = deque() for _node_index in range(num_nodes): - # NOTE: we put some more outputs in there to simulate a real case better - new_node_id = NodeID(f"{faker.uuid4()}") + # Create a node with outputs (files and others) + project_id = ProjectID(project["uuid"]) + node_id = cast(NodeID, faker.uuid4(cast_to=None)) + output3_file_name = faker.file_name() output3_file_id = create_simcore_file_id( - ProjectID(project["uuid"]), - new_node_id, - faker.file_name(), - Path("outputs/output3"), + project_id, node_id, output3_file_name, Path("outputs/output_3") ) - src_node_id = await create_project_node( + created_node_id = await create_project_node( ProjectID(project["uuid"]), - new_node_id, + node_id, outputs={ "output_1": faker.pyint(), "output_2": faker.pystr(), "output_3": f"{output3_file_id}", }, ) - assert src_node_id == new_node_id - - # upload the output 3 and some random other files at the root of each node - src_projects_list[src_node_id] = {} - checksum: SHA256Str = choice(file_checksums) # noqa: S311 - src_file, _ = await upload_file( - file_size=choice(file_sizes), # noqa: S311 - file_name=Path(output3_file_id).name, - file_id=output3_file_id, - sha256_checksum=checksum, - ) - src_projects_list[src_node_id][output3_file_id] = { - "path": src_file, - "sha256_checksum": checksum, - } - - async def _upload_file_and_update_project(project, src_node_id): - src_file_name = faker.file_name() - src_file_uuid = create_simcore_file_id( - ProjectID(project["uuid"]), src_node_id, src_file_name, None - ) - checksum: SHA256Str = choice(file_checksums) # noqa: S311 - src_file, _ = await upload_file( - file_size=choice(file_sizes), # noqa: S311 - file_name=src_file_name, - file_id=src_file_uuid, - sha256_checksum=checksum, + assert created_node_id == node_id + + node_to_files_mapping[created_node_id] = {} + upload_tasks.append( + _upload_file_and_update_project( + project_id, + node_id, + file_name=output3_file_name, + file_id=output3_file_id, + file_sizes=file_sizes, + file_checksums=file_checksums, + upload_file=upload_file, + create_simcore_file_id=create_simcore_file_id, + faker=faker, + node_to_files_mapping=node_to_files_mapping, ) - src_projects_list[src_node_id][src_file_uuid] = { - "path": src_file, - "sha256_checksum": checksum, - } + ) - # add a few random files in the node storage + # add a few random files in the node workspace upload_tasks.extend( [ - _upload_file_and_update_project(project, src_node_id) + _upload_file_and_update_project( + project_id, + node_id, + file_name=None, + file_id=None, + file_sizes=file_sizes, + file_checksums=file_checksums, + upload_file=upload_file, + create_simcore_file_id=create_simcore_file_id, + faker=faker, + node_to_files_mapping=node_to_files_mapping, + ) for _ in range(randint(0, 3)) # noqa: S311 ] ) await limited_gather(*upload_tasks, limit=10) project = await get_updated_project(sqlalchemy_async_engine, project["uuid"]) - return project, src_projects_list + return project, node_to_files_mapping return _creator diff --git a/services/storage/tests/fixtures/datcore_adapter.py b/packages/pytest-simcore/src/pytest_simcore/simcore_storage_datcore_adapter.py similarity index 100% rename from services/storage/tests/fixtures/datcore_adapter.py rename to packages/pytest-simcore/src/pytest_simcore/simcore_storage_datcore_adapter.py diff --git a/packages/service-library/src/servicelib/fastapi/http_error.py b/packages/service-library/src/servicelib/fastapi/http_error.py index 1fe45692b43b..c35c615969c8 100644 --- a/packages/service-library/src/servicelib/fastapi/http_error.py +++ b/packages/service-library/src/servicelib/fastapi/http_error.py @@ -94,7 +94,7 @@ def set_app_default_http_error_handlers(app: FastAPI) -> None: app.add_exception_handler( ValidationError, make_http_error_handler_for_exception( - status.HTTP_422_UNPROCESSABLE_ENTITY, + status.HTTP_500_INTERNAL_SERVER_ERROR, ValidationError, envelope_error=True, ), diff --git a/services/storage/requirements/_base.in b/services/storage/requirements/_base.in index c457068e1223..0dda4d60e5a5 100644 --- a/services/storage/requirements/_base.in +++ b/services/storage/requirements/_base.in @@ -21,6 +21,7 @@ httpx opentelemetry-instrumentation-botocore packaging fastapi[all] +fastapi-pagination orjson pydantic[dotenv] tenacity diff --git a/services/storage/requirements/_base.txt b/services/storage/requirements/_base.txt index 26dccf1c4772..3b6a798add8e 100644 --- a/services/storage/requirements/_base.txt +++ b/services/storage/requirements/_base.txt @@ -130,7 +130,7 @@ botocore==1.35.81 # aiobotocore # boto3 # s3transfer -botocore-stubs==1.36.16 +botocore-stubs==1.36.17 # via types-aiobotocore certifi==2025.1.31 # via @@ -195,6 +195,8 @@ fastapi-cli==0.0.7 # via fastapi fastapi-lifespan-manager==0.1.4 # via -r requirements/../../../packages/service-library/requirements/_fastapi.in +fastapi-pagination==0.12.34 + # via -r requirements/_base.in faststream==0.5.34 # via # -r requirements/../../../packages/aws-library/requirements/../../../packages/service-library/requirements/_base.in @@ -566,6 +568,7 @@ pydantic==2.10.6 # -r requirements/_base.in # fast-depends # fastapi + # fastapi-pagination # pydantic-extra-types # pydantic-settings pydantic-core==2.27.2 @@ -826,7 +829,7 @@ types-aiobotocore-s3==2.19.0.post1 # via types-aiobotocore types-aiobotocore-ssm==2.19.0 # via types-aiobotocore -types-awscrt==0.23.9 +types-awscrt==0.23.10 # via botocore-stubs types-python-dateutil==2.9.0.20241206 # via arrow @@ -836,6 +839,7 @@ typing-extensions==4.12.2 # alembic # anyio # fastapi + # fastapi-pagination # faststream # opentelemetry-sdk # pydantic diff --git a/services/storage/requirements/_test.txt b/services/storage/requirements/_test.txt index 4e5563e7fd17..916256340be3 100644 --- a/services/storage/requirements/_test.txt +++ b/services/storage/requirements/_test.txt @@ -87,7 +87,7 @@ docker==7.1.0 # via # -r requirements/_test.in # moto -faker==35.2.0 +faker==36.1.0 # via -r requirements/_test.in fakeredis==2.26.2 # via -r requirements/_test.in @@ -268,7 +268,6 @@ python-dateutil==2.9.0.post0 # via # -c requirements/_base.txt # botocore - # faker # moto # pandas # simcore-service-storage-sdk @@ -360,13 +359,14 @@ typing-extensions==4.12.2 # asyncpg-stubs # aws-sam-translator # cfn-lint - # faker # mypy # pydantic # pydantic-core # sqlalchemy2-stubs tzdata==2025.1 - # via pandas + # via + # faker + # pandas urllib3==2.3.0 # via # -c requirements/../../../requirements/constraints.txt diff --git a/services/storage/requirements/_tools.txt b/services/storage/requirements/_tools.txt index 3288e82ddab0..9f8dc86ff674 100644 --- a/services/storage/requirements/_tools.txt +++ b/services/storage/requirements/_tools.txt @@ -71,7 +71,7 @@ pyyaml==6.0.2 # -c requirements/_test.txt # pre-commit # watchdog -ruff==0.9.5 +ruff==0.9.6 # via -r requirements/../../../requirements/devenv.txt setuptools==75.8.0 # via @@ -84,7 +84,7 @@ typing-extensions==4.12.2 # -c requirements/_base.txt # -c requirements/_test.txt # mypy -virtualenv==20.29.1 +virtualenv==20.29.2 # via pre-commit watchdog==6.0.0 # via -r requirements/_tools.in diff --git a/services/storage/tests/conftest.py b/services/storage/tests/conftest.py index b51a34e81657..fefbaa157eea 100644 --- a/services/storage/tests/conftest.py +++ b/services/storage/tests/conftest.py @@ -12,7 +12,7 @@ from collections.abc import AsyncIterator, Awaitable, Callable from contextlib import AbstractAsyncContextManager, asynccontextmanager from pathlib import Path -from typing import Final, cast +from typing import Any, Final, cast import httpx import pytest @@ -46,6 +46,10 @@ from pytest_simcore.helpers.logging_tools import log_context from pytest_simcore.helpers.monkeypatch_envs import delenvs_from_dict, setenvs_from_dict from pytest_simcore.helpers.s3 import upload_file_to_presigned_link +from pytest_simcore.helpers.storage_utils import FileIDDict +from pytest_simcore.helpers.storage_utils_file_meta_data import ( + assert_file_meta_data_in_db, +) from pytest_simcore.helpers.typing_env import EnvVarsDict from servicelib.aiohttp import status from simcore_postgres_database.storage_models import file_meta_data, projects, users @@ -63,7 +67,6 @@ from tenacity.retry import retry_if_exception_type from tenacity.stop import stop_after_delay from tenacity.wait import wait_fixed -from tests.helpers.utils_file_meta_data import assert_file_meta_data_in_db from types_aiobotocore_s3 import S3Client from yarl import URL @@ -81,8 +84,8 @@ "pytest_simcore.postgres_service", "pytest_simcore.pytest_global_environs", "pytest_simcore.repository_paths", - "tests.fixtures.data_models", - "tests.fixtures.datcore_adapter", + "pytest_simcore.simcore_storage_data_models", + "pytest_simcore.simcore_storage_datcore_adapter", ] CURRENT_DIR = Path(sys.argv[0] if __name__ == "__main__" else __file__).resolve().parent @@ -631,3 +634,24 @@ async def _create_context( await delete_directory(directory_file_upload=directory_file_upload) return _create_context + + +@pytest.fixture +async def with_random_project_with_files( + random_project_with_files: Callable[ + ..., + Awaitable[ + tuple[ + dict[str, Any], + dict[NodeID, dict[SimcoreS3FileID, FileIDDict]], + ] + ], + ], +) -> tuple[dict[str, Any], dict[NodeID, dict[SimcoreS3FileID, FileIDDict]],]: + return await random_project_with_files( + file_sizes=( + TypeAdapter(ByteSize).validate_python("1Mib"), + TypeAdapter(ByteSize).validate_python("2Mib"), + TypeAdapter(ByteSize).validate_python("5Mib"), + ) + ) diff --git a/services/storage/tests/fixtures/__init__.py b/services/storage/tests/fixtures/__init__.py deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/services/storage/tests/helpers/__init__.py b/services/storage/tests/helpers/__init__.py deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/services/storage/tests/unit/test_handlers_files.py b/services/storage/tests/unit/test_handlers_files.py index 6aa70c19d7e2..550d1e6e62b8 100644 --- a/services/storage/tests/unit/test_handlers_files.py +++ b/services/storage/tests/unit/test_handlers_files.py @@ -50,6 +50,10 @@ from pytest_simcore.helpers.logging_tools import log_context from pytest_simcore.helpers.parametrizations import byte_size_ids from pytest_simcore.helpers.s3 import upload_file_part, upload_file_to_presigned_link +from pytest_simcore.helpers.storage_utils import FileIDDict +from pytest_simcore.helpers.storage_utils_file_meta_data import ( + assert_file_meta_data_in_db, +) from servicelib.aiohttp import status from simcore_service_storage.constants import S3_UNDEFINED_OR_EXTERNAL_MULTIPART_ID from simcore_service_storage.models import FileDownloadResponse, S3BucketName, UploadID @@ -61,7 +65,6 @@ from tenacity.retry import retry_if_exception_type from tenacity.stop import stop_after_delay from tenacity.wait import wait_fixed -from tests.helpers.utils_file_meta_data import assert_file_meta_data_in_db from types_aiobotocore_s3 import S3Client from yarl import URL @@ -1482,13 +1485,13 @@ async def test_listing_with_project_id_filter( Awaitable[ tuple[ dict[str, Any], - dict[NodeID, dict[SimcoreS3FileID, dict[str, Path | str]]], + dict[NodeID, dict[SimcoreS3FileID, FileIDDict]], ] ], ], uuid_filter: bool, ): - project, src_projects_list = await random_project_with_files( + src_project, src_projects_list = await random_project_with_files( num_nodes=1, file_sizes=(ByteSize(1),), file_checksums=(TypeAdapter(SHA256Str).validate_python(faker.sha256()),), @@ -1502,12 +1505,12 @@ async def test_listing_with_project_id_filter( node_id = next(iter(src_projects_list.keys())) project_files_in_db = set(src_projects_list[node_id]) assert len(project_files_in_db) > 0 - project_id = project["uuid"] + project_id = src_project["uuid"] project_file_name = Path(choice(list(project_files_in_db))).name # noqa: S311 query = { "user_id": user_id, - "project_id": project_id, + "project_id": f"{project_id}", "uuid_filter": project_file_name if uuid_filter else None, } diff --git a/services/storage/tests/unit/test_handlers_locations.py b/services/storage/tests/unit/test_handlers_locations.py index 9aee89ecc4a4..04eed7b85ebf 100644 --- a/services/storage/tests/unit/test_handlers_locations.py +++ b/services/storage/tests/unit/test_handlers_locations.py @@ -9,7 +9,7 @@ from fastapi import FastAPI, status from models_library.users import UserID from pytest_simcore.helpers.fastapi import url_from_operation_id -from tests.helpers.utils import has_datcore_tokens +from pytest_simcore.helpers.storage_utils import has_datcore_tokens pytest_simcore_core_services_selection = ["postgres"] pytest_simcore_ops_services_selection = ["adminer"] diff --git a/services/storage/tests/unit/test_handlers_simcore_s3.py b/services/storage/tests/unit/test_handlers_simcore_s3.py index f3003ddd122b..f5ff87df5d01 100644 --- a/services/storage/tests/unit/test_handlers_simcore_s3.py +++ b/services/storage/tests/unit/test_handlers_simcore_s3.py @@ -29,6 +29,11 @@ from pytest_simcore.helpers.fastapi import url_from_operation_id from pytest_simcore.helpers.httpx_assert_checks import assert_status from pytest_simcore.helpers.logging_tools import log_context +from pytest_simcore.helpers.storage_utils import FileIDDict, get_updated_project +from pytest_simcore.helpers.storage_utils_file_meta_data import ( + assert_file_meta_data_in_db, +) +from pytest_simcore.helpers.storage_utils_project import clone_project_data from pytest_simcore.helpers.typing_env import EnvVarsDict from servicelib.aiohttp import status from servicelib.fastapi.long_running_tasks.client import long_running_task_request @@ -37,12 +42,8 @@ from simcore_service_storage.models import SearchFilesQueryParams from simcore_service_storage.simcore_s3_dsm import SimcoreS3DataManager from sqlalchemy.ext.asyncio import AsyncEngine -from tests.helpers.utils_file_meta_data import assert_file_meta_data_in_db -from tests.helpers.utils_project import clone_project_data from yarl import URL -from ..helpers.utils import get_updated_project - pytest_simcore_core_services_selection = ["postgres"] pytest_simcore_ops_services_selection = ["adminer", "minio"] @@ -213,7 +214,7 @@ async def test_copy_folders_from_valid_project_with_one_large_file( Awaitable[ tuple[ dict[str, Any], - dict[NodeID, dict[SimcoreS3FileID, dict[str, Path | str]]], + dict[NodeID, dict[SimcoreS3FileID, FileIDDict]], ] ], ], @@ -257,7 +258,7 @@ async def test_copy_folders_from_valid_project_with_one_large_file( sqlalchemy_async_engine, file_id=TypeAdapter(SimcoreS3FileID).validate_python( f"{src_file_id}".replace( - src_project["uuid"], dst_project["uuid"] + f"{src_project['uuid']}", dst_project["uuid"] ).replace(f"{src_node_id}", f"{dst_node_id}") ), expected_entry_exists=True, @@ -283,7 +284,7 @@ async def test_copy_folders_from_valid_project( Awaitable[ tuple[ dict[str, Any], - dict[NodeID, dict[SimcoreS3FileID, dict[str, Path | SHA256Str]]], + dict[NodeID, dict[SimcoreS3FileID, FileIDDict]], ] ], ], @@ -321,7 +322,7 @@ async def test_copy_folders_from_valid_project( sqlalchemy_async_engine, file_id=TypeAdapter(SimcoreS3FileID).validate_python( f"{src_file_id}".replace( - src_project["uuid"], dst_project["uuid"] + f"{src_project['uuid']}", dst_project["uuid"] ).replace(f"{src_node_id}", f"{dst_node_id}") ), expected_entry_exists=True, @@ -404,27 +405,6 @@ def set_log_levels_for_noisy_libraries() -> None: logging.getLogger("werkzeug").setLevel(logging.WARNING) -@pytest.fixture -async def with_random_project_with_files( - random_project_with_files: Callable[ - ..., - Awaitable[ - tuple[ - dict[str, Any], - dict[NodeID, dict[SimcoreS3FileID, dict[str, Path | str]]], - ] - ], - ], -) -> tuple[dict[str, Any], dict[NodeID, dict[SimcoreS3FileID, dict[str, Path | str]]],]: - return await random_project_with_files( - file_sizes=( - TypeAdapter(ByteSize).validate_python("1Mib"), - TypeAdapter(ByteSize).validate_python("2Mib"), - TypeAdapter(ByteSize).validate_python("5Mib"), - ) - ) - - async def test_connect_to_external( set_log_levels_for_noisy_libraries: None, initialized_app: FastAPI, diff --git a/services/storage/tests/unit/test_utils_handlers.py b/services/storage/tests/unit/test_utils_handlers.py index f60528f209bf..c91b34cb9a8f 100644 --- a/services/storage/tests/unit/test_utils_handlers.py +++ b/services/storage/tests/unit/test_utils_handlers.py @@ -160,7 +160,7 @@ async def test_endpoint(): response = await client.get("/test") assert_status( response, - status.HTTP_422_UNPROCESSABLE_ENTITY, + status.HTTP_500_INTERNAL_SERVER_ERROR, None, expected_msg=f"0 validation errors for {_error_msg}", )