diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 0a96b95e..f7032b5a 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -12,7 +12,7 @@ repos: - id: end-of-file-fixer - id: trailing-whitespace - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.5.5 + rev: v0.6.1 hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] diff --git a/tests/conftest.py b/tests/conftest.py index f4cb58b0..e877af58 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -4,16 +4,17 @@ from pathlib import Path import pytest + from platform_storage_api.fs.local import FileSystem, LocalFileSystem -@pytest.fixture() +@pytest.fixture async def local_fs() -> AsyncIterator[FileSystem]: async with LocalFileSystem() as fs: yield fs -@pytest.fixture() +@pytest.fixture def local_tmp_dir_path() -> Iterator[Path]: with tempfile.TemporaryDirectory() as d: yield Path(os.path.realpath(d)) diff --git a/tests/integration/conftest.py b/tests/integration/conftest.py index a6271310..f0e9479c 100644 --- a/tests/integration/conftest.py +++ b/tests/integration/conftest.py @@ -13,6 +13,8 @@ import pytest_asyncio import uvicorn from neuro_admin_client import AdminClient +from yarl import URL + from platform_storage_api.api import create_app from platform_storage_api.config import ( AWSConfig, @@ -27,7 +29,6 @@ from platform_storage_api.s3_storage import StorageMetricsAsyncS3Storage from platform_storage_api.storage import SingleStoragePathResolver from platform_storage_api.storage_usage import StorageUsageService -from yarl import URL pytest_plugins = [ @@ -67,17 +68,17 @@ def ping_url(self) -> str: return self.endpoint + "/ping" -@pytest.fixture() +@pytest.fixture def server_url(api: ApiConfig) -> str: return api.storage_base_url -@pytest.fixture() +@pytest.fixture def multi_storage_server_url(multi_storage_api: ApiConfig) -> str: return multi_storage_api.storage_base_url -@pytest.fixture() +@pytest.fixture def platform_config( auth_server: URL, admin_token: str, cluster_name: str ) -> PlatformConfig: @@ -89,7 +90,7 @@ def platform_config( ) -@pytest.fixture() +@pytest.fixture def config( platform_config: PlatformConfig, aws_config: AWSConfig, local_tmp_dir_path: Path ) -> Config: @@ -103,12 +104,12 @@ def config( ) -@pytest.fixture() +@pytest.fixture def metrics_config(aws_config: AWSConfig) -> MetricsConfig: return MetricsConfig(aws=aws_config) -@pytest.fixture() +@pytest.fixture def multi_storage_config(config: Config) -> Config: config = replace(config, storage=replace(config.storage, mode=StorageMode.MULTIPLE)) Path(config.storage.fs_local_base_path, config.platform.cluster_name).mkdir( @@ -147,7 +148,7 @@ async def client() -> AsyncIterator[aiohttp.ClientSession]: yield session -@pytest.fixture() +@pytest.fixture def cluster_name() -> str: return "test-cluster" @@ -166,7 +167,7 @@ def get_filestatus_dict(response_json: dict[str, Any]) -> dict[str, Any]: return response_json["FileStatus"] -@pytest.fixture() +@pytest.fixture async def admin_client() -> AsyncIterator[AdminClient]: async with AdminClient( base_url=URL("http://platform-admin/apis/admin/v1") @@ -174,7 +175,7 @@ async def admin_client() -> AsyncIterator[AdminClient]: yield client -@pytest.fixture() +@pytest.fixture def storage_metrics_s3_storage( s3_client: aiobotocore.client.AioBaseClient, aws_config: AWSConfig ) -> StorageMetricsAsyncS3Storage: @@ -183,7 +184,7 @@ def storage_metrics_s3_storage( ) -@pytest.fixture() +@pytest.fixture def storage_usage_service( config: Config, admin_client: AdminClient, diff --git a/tests/integration/conftest_auth.py b/tests/integration/conftest_auth.py index 91d7b446..d355b884 100644 --- a/tests/integration/conftest_auth.py +++ b/tests/integration/conftest_auth.py @@ -31,7 +31,7 @@ def auth_jwt_secret() -> str: _TokenFactory = Callable[[str], str] -@pytest.fixture() +@pytest.fixture def token_factory() -> _TokenFactory: def _factory(name: str) -> str: payload = {"identity": name} @@ -40,23 +40,23 @@ def _factory(name: str) -> str: return _factory -@pytest.fixture() +@pytest.fixture def admin_token(token_factory: Callable[[str], str]) -> str: return token_factory("admin") -@pytest.fixture() +@pytest.fixture def cluster_token(token_factory: Callable[[str], str]) -> str: return token_factory("cluster") -@pytest.fixture() +@pytest.fixture def no_claim_token(auth_jwt_secret: str) -> str: payload: dict[str, Any] = {} return jwt.encode(payload, auth_jwt_secret, algorithm="HS256") -@pytest.fixture() +@pytest.fixture async def auth_client(auth_server: URL, admin_token: str) -> AsyncIterator[AuthClient]: async with AuthClient(url=auth_server, token=admin_token) as client: yield client @@ -71,7 +71,7 @@ class _User: _UserFactory = Callable[..., Awaitable[_User]] -@pytest.fixture() +@pytest.fixture async def granter(auth_client: AuthClient, admin_token: str) -> Any: async def f(whom: Any, what: Any, sourcer: Any) -> None: headers = auth_client._generate_headers(sourcer.token) @@ -83,7 +83,7 @@ async def f(whom: Any, what: Any, sourcer: Any) -> None: return f -@pytest.fixture() +@pytest.fixture async def regular_user_factory( auth_client: AuthClient, token_factory: _TokenFactory, diff --git a/tests/integration/conftest_moto.py b/tests/integration/conftest_moto.py index 00944a17..2c999203 100644 --- a/tests/integration/conftest_moto.py +++ b/tests/integration/conftest_moto.py @@ -7,10 +7,11 @@ import pytest from aiobotocore.client import AioBaseClient from aiobotocore.session import AioSession -from platform_storage_api.config import AWSConfig from pytest_docker.plugin import Services from yarl import URL +from platform_storage_api.config import AWSConfig + @pytest.fixture(scope="session") def _moto_server(docker_ip: str, docker_services: Services) -> URL: @@ -18,7 +19,7 @@ def _moto_server(docker_ip: str, docker_services: Services) -> URL: return URL(f"http://{docker_ip}:{port}") -@pytest.fixture() +@pytest.fixture async def moto_server(_moto_server: URL) -> AsyncIterator[URL]: yield _moto_server await _reset_moto_server(_moto_server) @@ -30,7 +31,7 @@ async def _reset_moto_server(moto_url: URL) -> None: pass -@pytest.fixture() +@pytest.fixture def aws_config(moto_server: URL) -> AWSConfig: return AWSConfig( region="us-east-1", @@ -41,12 +42,12 @@ def aws_config(moto_server: URL) -> AWSConfig: ) -@pytest.fixture() +@pytest.fixture def _session() -> AioSession: return aiobotocore.session.get_session() -@pytest.fixture() +@pytest.fixture async def s3_client( moto_server: URL, aws_config: AWSConfig, _session: AioSession ) -> AsyncIterator[AioBaseClient]: diff --git a/tests/integration/test_api.py b/tests/integration/test_api.py index 367aef7f..9664a24e 100644 --- a/tests/integration/test_api.py +++ b/tests/integration/test_api.py @@ -13,6 +13,7 @@ import aiohttp.web import pytest import pytest_asyncio + from platform_storage_api.config import Config from platform_storage_api.fs.local import FileStatusType diff --git a/tests/integration/test_api_sharing_resources.py b/tests/integration/test_api_sharing_resources.py index 7ed8b1c0..d090caa8 100644 --- a/tests/integration/test_api_sharing_resources.py +++ b/tests/integration/test_api_sharing_resources.py @@ -7,8 +7,8 @@ import aiohttp import yarl -from platform_storage_api.fs.local import FileStatusType +from platform_storage_api.fs.local import FileStatusType from tests.integration.conftest import ApiConfig, status_iter_response_to_list from .conftest_auth import _User, _UserFactory diff --git a/tests/integration/test_api_websocket.py b/tests/integration/test_api_websocket.py index 1b52fd1c..6922e531 100644 --- a/tests/integration/test_api_websocket.py +++ b/tests/integration/test_api_websocket.py @@ -9,9 +9,9 @@ import aiohttp import cbor + from platform_storage_api.api import WSStorageOperation from platform_storage_api.fs.local import FileStatusType - from tests.integration.conftest import ( ApiConfig, get_filestatus_dict, diff --git a/tests/integration/test_metrics.py b/tests/integration/test_metrics.py index e9483426..93486012 100644 --- a/tests/integration/test_metrics.py +++ b/tests/integration/test_metrics.py @@ -9,21 +9,22 @@ from aiobotocore.client import AioBaseClient from aioresponses import aioresponses from fastapi import FastAPI +from yarl import URL + from platform_storage_api.config import MetricsConfig from platform_storage_api.metrics import create_app from platform_storage_api.storage_usage import StorageUsageService -from yarl import URL from .conftest import run_asgi_app -@pytest.fixture() +@pytest.fixture def app(metrics_config: MetricsConfig) -> Iterator[FastAPI]: with create_app(config=metrics_config) as app: yield app -@pytest.fixture() +@pytest.fixture async def metrics_server( app: FastAPI, unused_tcp_port_factory: Callable[[], int] ) -> AsyncIterator[URL]: @@ -33,7 +34,7 @@ async def metrics_server( yield URL(f"http://{host}:{port}") -@pytest.fixture() +@pytest.fixture async def client(metrics_server: URL) -> AsyncIterator[aiohttp.ClientSession]: async with aiohttp.ClientSession(base_url=metrics_server) as client: yield client diff --git a/tests/integration/test_storage_usage_service.py b/tests/integration/test_storage_usage_service.py index bd39224a..34750ed8 100644 --- a/tests/integration/test_storage_usage_service.py +++ b/tests/integration/test_storage_usage_service.py @@ -6,11 +6,12 @@ import pytest from aioresponses import aioresponses + from platform_storage_api.s3_storage import StorageMetricsAsyncS3Storage from platform_storage_api.storage_usage import StorageUsage, StorageUsageService -@pytest.fixture() +@pytest.fixture def aiohttp_mock() -> Iterator[aioresponses]: with aioresponses(passthrough=["http://0.0.0.0", "http://127.0.0.1"]) as mocked: yield mocked diff --git a/tests/integration/test_worker.py b/tests/integration/test_worker.py index baa493d5..558a8b12 100644 --- a/tests/integration/test_worker.py +++ b/tests/integration/test_worker.py @@ -2,6 +2,7 @@ from unittest import mock from aioresponses import aioresponses + from platform_storage_api.config import Config from platform_storage_api.s3_storage import StorageMetricsAsyncS3Storage from platform_storage_api.storage_usage import StorageUsage diff --git a/tests/unit/conftest.py b/tests/unit/conftest.py index dacca1b7..3e0e8e30 100644 --- a/tests/unit/conftest.py +++ b/tests/unit/conftest.py @@ -6,7 +6,7 @@ from aioresponses import aioresponses -@pytest.fixture() +@pytest.fixture def aiohttp_mock() -> Iterator[aioresponses]: with aioresponses() as mocked: yield mocked diff --git a/tests/unit/test_cache.py b/tests/unit/test_cache.py index a3180451..50110192 100644 --- a/tests/unit/test_cache.py +++ b/tests/unit/test_cache.py @@ -9,6 +9,7 @@ from aiohttp_security.api import IDENTITY_KEY from neuro_auth_client.client import ClientAccessSubTreeView from neuro_auth_client.security import IdentityPolicy + from platform_storage_api.cache import ( AbstractPermissionChecker, PermissionsCache, @@ -65,7 +66,7 @@ async def check_user_permissions( raise HTTPNotFound -@pytest.fixture() +@pytest.fixture def permission_tree() -> ClientAccessSubTreeView: return ClientAccessSubTreeView( action="deny", @@ -86,12 +87,12 @@ def permission_tree() -> ClientAccessSubTreeView: ) -@pytest.fixture() +@pytest.fixture def call_log() -> list[Any]: return [] -@pytest.fixture() +@pytest.fixture def mock_time() -> TimeFactory: def mock_time() -> float: return mock_time.time # type: ignore @@ -100,7 +101,7 @@ def mock_time() -> float: return mock_time -@pytest.fixture() +@pytest.fixture def cache( call_log: list[Any], permission_tree: ClientAccessSubTreeView, @@ -114,7 +115,7 @@ def cache( ) -@pytest.fixture() +@pytest.fixture def slow_cache( call_log: list[Any], permission_tree: ClientAccessSubTreeView, @@ -128,7 +129,7 @@ def slow_cache( ) -@pytest.fixture() +@pytest.fixture def webrequest() -> Request: webrequest = make_mocked_request( "GET", "/", headers={"Authorization": "Bearer authorization"} diff --git a/tests/unit/test_config.py b/tests/unit/test_config.py index c67ce5d8..6d1bede0 100644 --- a/tests/unit/test_config.py +++ b/tests/unit/test_config.py @@ -1,13 +1,14 @@ from pathlib import PurePath import pytest +from yarl import URL + from platform_storage_api.config import ( Config, StorageConfig, StorageMode, StorageServerConfig, ) -from yarl import URL class TestServerConfig: diff --git a/tests/unit/test_fs_local.py b/tests/unit/test_fs_local.py index 6143ede9..95af8f34 100644 --- a/tests/unit/test_fs_local.py +++ b/tests/unit/test_fs_local.py @@ -9,6 +9,7 @@ import pytest import pytest_asyncio + from platform_storage_api.fs.local import ( FileStatus, FileStatusType, @@ -68,27 +69,27 @@ async def remove_iter(fs: FileSystem, path: PurePath, recursive: bool) -> None: class TestLocalFileSystem: - @pytest.fixture() + @pytest.fixture def tmp_dir_path(self) -> Iterator[Path]: # although blocking, this is fine for tests with tempfile.TemporaryDirectory() as d: yield Path(os.path.realpath(d)) - @pytest.fixture() + @pytest.fixture def tmp_file_path(self, tmp_dir_path: Path) -> Iterator[Path]: # although blocking, this is fine for tests with tempfile.NamedTemporaryFile(dir=tmp_dir_path) as f: f.flush() yield Path(f.name) - @pytest.fixture() + @pytest.fixture def path_with_symlink(self, tmp_dir_path: Path) -> Path: (tmp_dir_path / "dir").mkdir() (tmp_dir_path / "dir/subdir").mkdir() os.symlink("dir", tmp_dir_path / "link") return tmp_dir_path / "link/subdir" - @pytest.fixture() + @pytest.fixture def symlink_to_dir(self, tmp_dir_path: Path) -> Path: (tmp_dir_path / "dir").mkdir() path = tmp_dir_path / "dirlink" @@ -96,7 +97,7 @@ def symlink_to_dir(self, tmp_dir_path: Path) -> Path: assert path.is_dir() return path - @pytest.fixture() + @pytest.fixture def symlink_to_file(self, tmp_dir_path: Path) -> Path: (tmp_dir_path / "file").write_bytes(b"test") path = tmp_dir_path / "filelink" @@ -104,7 +105,7 @@ def symlink_to_file(self, tmp_dir_path: Path) -> Path: assert path.is_file() return path - @pytest.fixture() + @pytest.fixture def free_symlink(self, tmp_dir_path: Path) -> Path: path = tmp_dir_path / "nonexistentlink" os.symlink("nonexistent", path) diff --git a/tests/unit/test_storage.py b/tests/unit/test_storage.py index 51cfdf85..c365e7c9 100644 --- a/tests/unit/test_storage.py +++ b/tests/unit/test_storage.py @@ -5,6 +5,7 @@ from typing import Any import pytest + from platform_storage_api.fs.local import FileStatusType, FileSystem, LocalFileSystem from platform_storage_api.storage import ( MultipleStoragePathResolver, @@ -44,7 +45,7 @@ async def test_resolve_base_path( class TestStorage: - @pytest.fixture() + @pytest.fixture def storage(self, local_fs: FileSystem, local_tmp_dir_path: Path) -> Storage: return Storage(SingleStoragePathResolver(local_tmp_dir_path), local_fs) diff --git a/tests/unit/test_storage_usage.py b/tests/unit/test_storage_usage.py index 0f4c6c73..7fec0da6 100644 --- a/tests/unit/test_storage_usage.py +++ b/tests/unit/test_storage_usage.py @@ -6,6 +6,8 @@ import pytest from aioresponses import aioresponses from neuro_admin_client import AdminClient +from yarl import URL + from platform_storage_api.config import ( AWSConfig, Config, @@ -16,10 +18,9 @@ from platform_storage_api.fs.local import FileSystem from platform_storage_api.storage import SingleStoragePathResolver from platform_storage_api.storage_usage import StorageUsage, StorageUsageService -from yarl import URL -@pytest.fixture() +@pytest.fixture def config() -> Config: return Config( server=StorageServerConfig(), @@ -40,14 +41,14 @@ def config() -> Config: class TestStorageUsage: - @pytest.fixture() + @pytest.fixture async def admin_client(self) -> AsyncIterator[AdminClient]: async with AdminClient( base_url=URL("http://platform-admin/apis/admin/v1") ) as client: yield client - @pytest.fixture() + @pytest.fixture def storage_usage_service( self, config: Config,