diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index ffcc374..b3d6061 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -2,7 +2,7 @@ # See https://pre-commit.com/hooks.html for more hooks repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.6.0 + rev: v5.0.0 hooks: - id: check-added-large-files - id: check-merge-conflict @@ -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.7 + rev: v0.6.9 hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] diff --git a/tests/integration/conftest.py b/tests/integration/conftest.py index 61eb2ba..8adf905 100644 --- a/tests/integration/conftest.py +++ b/tests/integration/conftest.py @@ -74,13 +74,13 @@ def event_loop() -> Iterator[asyncio.AbstractEventLoop]: loop.close() -@pytest.fixture() +@pytest.fixture def platform_auth_server(docker_ip: str, docker_services: Services) -> URL: port = docker_services.port_for("platform-auth", 8080) return URL(f"http://{docker_ip}:{port}") -@pytest.fixture() +@pytest.fixture async def platform_api_server( unused_tcp_port_factory: Callable[[], int], platform_api_app: aiohttp.web.Application, @@ -91,7 +91,7 @@ async def platform_api_server( yield URL.build(scheme="http", host=address.host, port=address.port) -@pytest.fixture() +@pytest.fixture async def platform_config_server( unused_tcp_port_factory: Callable[[], int], platform_config_app: aiohttp.web.Application, @@ -102,14 +102,14 @@ async def platform_config_server( yield URL.build(scheme="http", host=address.host, port=address.port) -@pytest.fixture() +@pytest.fixture def platform_auth_config( platform_auth_server: URL, service_token: str ) -> PlatformAuthConfig: return PlatformAuthConfig(url=platform_auth_server, token=service_token) -@pytest.fixture() +@pytest.fixture def platform_api_config( platform_api_server: URL, service_token: str ) -> PlatformServiceConfig: @@ -118,14 +118,14 @@ def platform_api_config( ) -@pytest.fixture() +@pytest.fixture def platform_config_config( platform_config_server: URL, service_token: str ) -> PlatformServiceConfig: return PlatformServiceConfig(url=platform_config_server, token=service_token) -@pytest.fixture() +@pytest.fixture def metrics_exporter_config( unused_tcp_port_factory: Callable[[], int], platform_config_config: PlatformServiceConfig, @@ -143,7 +143,7 @@ def metrics_exporter_config( ) -@pytest.fixture() +@pytest.fixture async def metrics_exporter_server_factory() -> ( Callable[[MetricsExporterConfig], AbstractAsyncContextManager[URL]] ): @@ -160,7 +160,7 @@ async def _create( return _create -@pytest.fixture() +@pytest.fixture async def metrics_exporter_server( metrics_exporter_server_factory: Callable[ [MetricsExporterConfig], AbstractAsyncContextManager[URL] @@ -171,13 +171,13 @@ async def metrics_exporter_server( yield server -@pytest.fixture() +@pytest.fixture def thanos_query_url(docker_ip: str, docker_services: Services) -> URL: port = docker_services.port_for("thanos-query", 9091) return URL(f"http://{docker_ip}:{port}") -@pytest.fixture() +@pytest.fixture def prometheus_proxy_config( unused_tcp_port_factory: Callable[[], int], platform_auth_config: PlatformAuthConfig, @@ -194,7 +194,7 @@ def prometheus_proxy_config( ) -@pytest.fixture() +@pytest.fixture async def prometheus_proxy_server( prometheus_proxy_config: PrometheusProxyConfig, ) -> AsyncIterator[URL]: @@ -205,13 +205,13 @@ async def prometheus_proxy_server( yield URL.build(scheme="http", host=address.host, port=address.port) -@pytest.fixture() +@pytest.fixture def grafana_url(docker_ip: str, docker_services: Services) -> URL: port = docker_services.port_for("grafana", 3000) return URL(f"http://{docker_ip}:{port}") -@pytest.fixture() +@pytest.fixture def grafana_proxy_config( unused_tcp_port_factory: Callable[[], int], platform_auth_config: PlatformAuthConfig, @@ -228,7 +228,7 @@ def grafana_proxy_config( ) -@pytest.fixture() +@pytest.fixture async def grafana_proxy_server( grafana_proxy_config: GrafanaProxyConfig, ) -> AsyncIterator[URL]: @@ -239,13 +239,13 @@ async def grafana_proxy_server( yield URL.build(scheme="http", host=address.host, port=address.port) -@pytest.fixture() +@pytest.fixture async def client() -> AsyncIterator[aiohttp.ClientSession]: async with aiohttp.ClientSession() as session: yield session -@pytest.fixture() +@pytest.fixture def metrics_api_config( unused_tcp_port_factory: Callable[[], int], platform_auth_config: PlatformAuthConfig, @@ -264,7 +264,7 @@ def metrics_api_config( ) -@pytest.fixture() +@pytest.fixture async def metrics_api_server( metrics_api_config: MetricsApiConfig, ) -> AsyncIterator[URL]: @@ -275,7 +275,7 @@ async def metrics_api_server( yield address.http_url -@pytest.fixture() +@pytest.fixture async def exit_stack() -> AsyncIterator[AsyncExitStack]: async with AsyncExitStack() as stack: yield stack diff --git a/tests/integration/conftest_kube.py b/tests/integration/conftest_kube.py index cc7f637..69d5304 100644 --- a/tests/integration/conftest_kube.py +++ b/tests/integration/conftest_kube.py @@ -82,7 +82,7 @@ async def __call__( pass -@pytest.fixture() +@pytest.fixture async def kube_pod_factory(kube_client: KubeClient) -> AsyncIterator[KubePodFactory]: pods = [] diff --git a/tests/integration/conftest_platform_api.py b/tests/integration/conftest_platform_api.py index a60651c..2b6e172 100644 --- a/tests/integration/conftest_platform_api.py +++ b/tests/integration/conftest_platform_api.py @@ -2,7 +2,7 @@ import pytest -@pytest.fixture() +@pytest.fixture def platform_api_app() -> aiohttp.web.Application: async def _get_config(request: aiohttp.web.Request) -> aiohttp.web.Response: return aiohttp.web.json_response( diff --git a/tests/integration/conftest_platform_auth.py b/tests/integration/conftest_platform_auth.py index 0bb3516..43b8176 100644 --- a/tests/integration/conftest_platform_auth.py +++ b/tests/integration/conftest_platform_auth.py @@ -13,7 +13,7 @@ _JWT_SECRET = "secret" -@pytest.fixture() +@pytest.fixture def token_factory() -> Callable[[str], str]: def _create(name: str) -> str: payload = {"https://platform.neuromation.io/user": name} @@ -30,7 +30,7 @@ class User(AuthUser): UserFactory = Callable[[str, Sequence[Permission]], Awaitable[User]] -@pytest.fixture() +@pytest.fixture def user_factory( token_factory: Callable[[str], str], platform_auth_server: URL ) -> UserFactory: @@ -50,7 +50,7 @@ async def _create(name: str, permissions: Sequence[Permission] = ()) -> User: return _create -@pytest.fixture() +@pytest.fixture async def service_token( user_factory: UserFactory, token_factory: Callable[[str], str] ) -> str: @@ -58,7 +58,7 @@ async def service_token( return token_factory("cluster") -@pytest.fixture() +@pytest.fixture async def cluster_admin_token(user_factory: UserFactory) -> str: user = await user_factory( "cluster-admin", @@ -70,7 +70,7 @@ async def cluster_admin_token(user_factory: UserFactory) -> str: return user.token -@pytest.fixture() +@pytest.fixture async def regular_user_token(user_factory: UserFactory) -> str: user = await user_factory( "user", @@ -82,7 +82,7 @@ async def regular_user_token(user_factory: UserFactory) -> str: return user.token -@pytest.fixture() +@pytest.fixture async def other_cluster_user_token(user_factory: UserFactory) -> str: user = await user_factory( "other-user", diff --git a/tests/integration/conftest_platform_config.py b/tests/integration/conftest_platform_config.py index 3f246c3..9617c54 100644 --- a/tests/integration/conftest_platform_config.py +++ b/tests/integration/conftest_platform_config.py @@ -5,7 +5,7 @@ from neuro_config_client.factories import NodeRole -@pytest.fixture() +@pytest.fixture def platform_config_app() -> aiohttp.web.Application: async def _get_cluster(request: aiohttp.web.Request) -> aiohttp.web.Response: name = request.match_info["cluster_name"] diff --git a/tests/integration/test_api.py b/tests/integration/test_api.py index 3e05125..d6b311f 100644 --- a/tests/integration/test_api.py +++ b/tests/integration/test_api.py @@ -333,7 +333,7 @@ async def test_dashboard_forbidden( class TestMetricsApi: - @pytest.fixture() + @pytest.fixture async def user(self, user_factory: UserFactory) -> User: return await user_factory( str(uuid.uuid4()), [Permission("cluster://default", "read")] diff --git a/tests/integration/test_kube_client.py b/tests/integration/test_kube_client.py index 854e791..c631854 100644 --- a/tests/integration/test_kube_client.py +++ b/tests/integration/test_kube_client.py @@ -18,7 +18,7 @@ class TestKubeClientTokenUpdater: - @pytest.fixture() + @pytest.fixture async def kube_app(self) -> aiohttp.web.Application: async def _get_pods(request: aiohttp.web.Request) -> aiohttp.web.Response: auth = request.headers["Authorization"] @@ -33,7 +33,7 @@ async def _get_pods(request: aiohttp.web.Request) -> aiohttp.web.Response: ) return app - @pytest.fixture() + @pytest.fixture async def kube_server( self, kube_app: aiohttp.web.Application, unused_tcp_port_factory: Any ) -> AsyncIterator[str]: @@ -42,14 +42,14 @@ async def kube_server( ) as address: yield f"http://{address.host}:{address.port}" - @pytest.fixture() + @pytest.fixture def kube_token_path(self) -> Iterator[str]: _, path = tempfile.mkstemp() Path(path).write_text("token-1") yield path Path(path).unlink() - @pytest.fixture() + @pytest.fixture async def kube_client( self, kube_server: str, kube_token_path: str ) -> AsyncIterator[KubeClient]: diff --git a/tests/integration/test_metrics.py b/tests/integration/test_metrics.py index ba7e66f..dcb9452 100644 --- a/tests/integration/test_metrics.py +++ b/tests/integration/test_metrics.py @@ -26,7 +26,7 @@ def cluster(self) -> Cluster: return self._cluster -@pytest.fixture() +@pytest.fixture def cluster() -> Cluster: return Cluster( name="default", @@ -50,13 +50,13 @@ def cluster() -> Cluster: ) -@pytest.fixture() +@pytest.fixture def cluster_holder(cluster: Cluster) -> ClusterHolder: return _TestClusterHolder(cluster) class TestPodCreditsCollector: - @pytest.fixture() + @pytest.fixture def collector( self, kube_client: KubeClient, kube_node: Node, cluster_holder: ClusterHolder ) -> PodCreditsCollector: diff --git a/tests/integration/test_metrics_service.py b/tests/integration/test_metrics_service.py index ea3fd43..9970fed 100644 --- a/tests/integration/test_metrics_service.py +++ b/tests/integration/test_metrics_service.py @@ -34,19 +34,19 @@ async def _post_query_range( return aiohttp.web.json_response({}) -@pytest.fixture() +@pytest.fixture def prometheus_handler() -> PrometheusHandler: return PrometheusHandler() -@pytest.fixture() +@pytest.fixture def prometheus_app(prometheus_handler: PrometheusHandler) -> aiohttp.web.Application: app = aiohttp.web.Application() app.router.add_post("/api/v1/query_range", prometheus_handler.do_post_query_range) return app -@pytest.fixture() +@pytest.fixture async def prometheus_test_client( aiohttp_client: Callable[[aiohttp.web.Application], Awaitable[TestClient]], prometheus_app: aiohttp.web.Application, @@ -54,7 +54,7 @@ async def prometheus_test_client( return await aiohttp_client(prometheus_app) -@pytest.fixture() +@pytest.fixture def prometheus_client( prometheus_test_client: TestClient, ) -> PrometheusClient: @@ -73,7 +73,7 @@ def cluster(self) -> Cluster: return self._cluster -@pytest.fixture() +@pytest.fixture def cluster() -> Cluster: return Cluster( name="default", @@ -89,7 +89,7 @@ def cluster() -> Cluster: class TestMetricsService: - @pytest.fixture() + @pytest.fixture def metrics_service( self, prometheus_client: PrometheusClient, cluster: Cluster ) -> MetricsService: diff --git a/tests/unit/test_auth.py b/tests/unit/test_auth.py index 2322ada..3f3555e 100644 --- a/tests/unit/test_auth.py +++ b/tests/unit/test_auth.py @@ -16,7 +16,7 @@ JOB_ID = "job-00000000-0000-0000-0000-000000000000" -@pytest.fixture() +@pytest.fixture def job_factory() -> Callable[[str], Job]: def _factory(id_: str) -> Job: return Job( @@ -36,14 +36,14 @@ def _factory(id_: str) -> Job: return _factory -@pytest.fixture() +@pytest.fixture def auth_client() -> mock.AsyncMock: client = mock.AsyncMock(AuthClient) client.get_missing_permissions = mock.AsyncMock(return_value=[]) return client -@pytest.fixture() +@pytest.fixture def api_client(job_factory: Callable[[str], Job]) -> mock.AsyncMock: async def get_job(id_: str) -> Job: return job_factory(id_) @@ -54,7 +54,7 @@ async def get_job(id_: str) -> Job: class TestDashboards: - @pytest.fixture() + @pytest.fixture def auth_service( self, auth_client: AuthClient, api_client: ApiClient ) -> AuthService: @@ -124,7 +124,7 @@ async def get_missing_permissions( class TestAuthService: - @pytest.fixture() + @pytest.fixture def service(self, auth_client: AuthClient, api_client: ApiClient) -> AuthService: return AuthService(auth_client, api_client, "default") diff --git a/tests/unit/test_metrics.py b/tests/unit/test_metrics.py index 1f26682..3b78d60 100644 --- a/tests/unit/test_metrics.py +++ b/tests/unit/test_metrics.py @@ -65,17 +65,17 @@ def cluster(self) -> Cluster: return self._cluster -@pytest.fixture() +@pytest.fixture def cluster_holder(cluster: Cluster) -> ClusterHolder: return _TestClusterHolder(cluster) class TestCollector: - @pytest.fixture() + @pytest.fixture def collector(self) -> Collector[Price]: return Collector(Price(), interval_s=0.1) - @pytest.fixture() + @pytest.fixture def price_factory(self, collector: Collector[Price]) -> Iterator[mock.Mock]: price = Price(currency="USD", value=Decimal(1)) with mock.patch.object( @@ -100,7 +100,7 @@ async def test_update( class TestConfigPriceCollector: - @pytest.fixture() + @pytest.fixture def cluster(self) -> Cluster: return Cluster( name="default", @@ -124,7 +124,7 @@ def cluster(self) -> Cluster: ), ) - @pytest.fixture() + @pytest.fixture async def collector_factory( self, cluster_holder: ClusterHolder ) -> Callable[..., AbstractAsyncContextManager[ConfigPriceCollector]]: @@ -164,15 +164,15 @@ async def test_get_latest_value_unknown_node_pool( class TestAWSNodePriceCollector: - @pytest.fixture() + @pytest.fixture def pricing_client(self) -> mock.AsyncMock: return mock.AsyncMock() - @pytest.fixture() + @pytest.fixture def ec2_client(self) -> mock.AsyncMock: return mock.AsyncMock() - @pytest.fixture() + @pytest.fixture def collector_factory( self, pricing_client: AioBaseClient, ec2_client: AioBaseClient ) -> Callable[..., AbstractAsyncContextManager[AWSNodePriceCollector]]: @@ -345,7 +345,7 @@ async def test_get_latest_spot_value_no_history( class TestGCPNodePriceCollector: - @pytest.fixture() + @pytest.fixture def cluster(self) -> Cluster: return Cluster( name="default", @@ -380,7 +380,7 @@ def cluster(self) -> Cluster: ), ) - @pytest.fixture() + @pytest.fixture def google_service_skus(self) -> dict[str, Any]: return { "skus": [ @@ -602,7 +602,7 @@ def google_service_skus(self) -> dict[str, Any]: ] } - @pytest.fixture() + @pytest.fixture def collector_factory( self, cluster_holder: ClusterHolder, google_service_skus: dict[str, Any] ) -> Callable[..., AbstractContextManager[GCPNodePriceCollector]]: @@ -648,7 +648,7 @@ async def test_get_latest_value_cpu_instance_preemptible( result = await collector.get_latest_value() assert result == Price(value=Decimal(1), currency="USD") - @pytest.mark.xfail() + @pytest.mark.xfail async def test_get_latest_value_gpu_instance( self, collector_factory: Callable[..., AbstractContextManager[GCPNodePriceCollector]], @@ -657,7 +657,7 @@ async def test_get_latest_value_gpu_instance( result = await collector.get_latest_value() assert result == Price(value=Decimal("22.73"), currency="USD") - @pytest.mark.xfail() + @pytest.mark.xfail async def test_get_latest_value_gpu_instance_preemptible( self, collector_factory: Callable[..., AbstractContextManager[GCPNodePriceCollector]], @@ -680,7 +680,7 @@ async def test_get_latest_value_unknown_instance_type( ): await collector.get_latest_value() - @pytest.mark.xfail() + @pytest.mark.xfail async def test_get_latest_value_unknown_gpu( self, collector_factory: Callable[..., AbstractContextManager[GCPNodePriceCollector]], @@ -695,7 +695,7 @@ async def test_get_latest_value_unknown_gpu( class TestAzureNodePriceCollector: - @pytest.fixture() + @pytest.fixture def prices_client_factory( self, aiohttp_client: Any, @@ -714,7 +714,7 @@ async def get_prices(request: web.Request) -> web.Response: return _create - @pytest.fixture() + @pytest.fixture def collector_factory(self) -> Callable[..., AzureNodePriceCollector]: def _create( prices_client: aiohttp.ClientSession, @@ -853,7 +853,7 @@ async def test_get_latest_spot_value( class TestPodCreditsCollector: - @pytest.fixture() + @pytest.fixture def cluster(self) -> Cluster: return Cluster( name="default", @@ -876,7 +876,7 @@ def cluster(self) -> Cluster: ), ) - @pytest.fixture() + @pytest.fixture def kube_client_factory(self) -> Callable[..., mock.AsyncMock]: def _create(pods: list[Pod]) -> mock.AsyncMock: async def get_pods( @@ -895,7 +895,7 @@ async def get_pods( return _create - @pytest.fixture() + @pytest.fixture def collector_factory( self, cluster_holder: ClusterHolder, @@ -1019,7 +1019,7 @@ async def test_get_latest_value__no_pods( class TestNodeEnergyConsumptionCollector: - @pytest.fixture() + @pytest.fixture def cluster(self) -> Cluster: return Cluster( name="default",