From bb57449f5759869cbee4c5d35cfee49b6ff4cf02 Mon Sep 17 00:00:00 2001 From: Ken Lauer Date: Thu, 31 Aug 2023 10:18:01 -0700 Subject: [PATCH 1/3] BLD: epicsmacrolib is now on conda-forge --- conda-recipe/meta.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/conda-recipe/meta.yaml b/conda-recipe/meta.yaml index 15faefac..38071448 100644 --- a/conda-recipe/meta.yaml +++ b/conda-recipe/meta.yaml @@ -23,6 +23,7 @@ requirements: - python >=3.9 - aiohttp - apischema + - epicsmacrolib - graphviz - jinja2 - lark-parser From 816e2ebe4a5e99d35c33ce0b2e17b2e0aa61cac4 Mon Sep 17 00:00:00 2001 From: Ken Lauer Date: Thu, 31 Aug 2023 10:32:43 -0700 Subject: [PATCH 2/3] BLD: pytest-asyncio --- conda-recipe/meta.yaml | 1 + dev-requirements.txt | 1 + 2 files changed, 2 insertions(+) diff --git a/conda-recipe/meta.yaml b/conda-recipe/meta.yaml index 38071448..69bfa5ce 100644 --- a/conda-recipe/meta.yaml +++ b/conda-recipe/meta.yaml @@ -36,6 +36,7 @@ test: - flake8 - happi - pytest + - pytest-asyncio - pytest-aiohttp - pytest-cov - python-ldap diff --git a/dev-requirements.txt b/dev-requirements.txt index ee038d70..4aa7a3d9 100644 --- a/dev-requirements.txt +++ b/dev-requirements.txt @@ -3,6 +3,7 @@ codecov flake8 pytest +pytest-asyncio pytest-aiohttp pytest-cov From fe01c4e66c30d0309bd1f52820287a978fbdf953 Mon Sep 17 00:00:00 2001 From: Ken Lauer Date: Thu, 31 Aug 2023 11:56:11 -0700 Subject: [PATCH 3/3] TST: absorb fixture from pytest-aiohttp due to conda-forge availability --- conda-recipe/meta.yaml | 1 - dev-requirements.txt | 1 - whatrecord/tests/test_server_handler.py | 46 ++++++++++++++++++++++++- 3 files changed, 45 insertions(+), 3 deletions(-) diff --git a/conda-recipe/meta.yaml b/conda-recipe/meta.yaml index 69bfa5ce..42dfcf47 100644 --- a/conda-recipe/meta.yaml +++ b/conda-recipe/meta.yaml @@ -37,7 +37,6 @@ test: - happi - pytest - pytest-asyncio - - pytest-aiohttp - pytest-cov - python-ldap - pytmc diff --git a/dev-requirements.txt b/dev-requirements.txt index 4aa7a3d9..b967bf2e 100644 --- a/dev-requirements.txt +++ b/dev-requirements.txt @@ -4,7 +4,6 @@ codecov flake8 pytest pytest-asyncio -pytest-aiohttp pytest-cov # plugin dependencies diff --git a/whatrecord/tests/test_server_handler.py b/whatrecord/tests/test_server_handler.py index 7c3dc154..22900875 100644 --- a/whatrecord/tests/test_server_handler.py +++ b/whatrecord/tests/test_server_handler.py @@ -1,7 +1,8 @@ """Requires pytest-aiohttp""" import json import logging -from typing import Any, Dict, Optional, Type, TypeVar +from typing import (Any, Awaitable, Callable, Dict, Generator, Optional, Type, + TypeVar, Union) import aiohttp import aiohttp.test_utils @@ -9,6 +10,8 @@ import apischema import pytest import pytest_asyncio +from aiohttp.test_utils import BaseTestServer, TestClient, TestServer +from aiohttp.web import Application from .. import gateway from ..common import RecordInstance, WhatRecord @@ -22,6 +25,8 @@ from .test_server_state import ready_state, state # noqa +AiohttpClient = Callable[[Union[Application, BaseTestServer]], Awaitable[TestClient]] + @pytest.fixture() def handler(ready_state: ServerState) -> ServerHandler: # noqa: F811 @@ -37,6 +42,45 @@ def server(handler: ServerHandler) -> aiohttp.web.Application: return app +@pytest_asyncio.fixture +async def aiohttp_client() -> Generator[AiohttpClient, None, None]: + """ + Factory to create a TestClient instance. + + Borrowed and modified from pytest-aiohttp, as a recent version is + unavailable on conda-forge for our testing purposes. + + aiohttp_client(app, **kwargs) + aiohttp_client(server, **kwargs) + aiohttp_client(raw_server, **kwargs) + """ + clients = [] + + async def go( + __param: Union[Application, BaseTestServer], + *, + server_kwargs: Optional[Dict[str, Any]] = None, + **kwargs: Any, + ) -> TestClient: + if isinstance(__param, Application): + server_kwargs = server_kwargs or {} + server = TestServer(__param, **server_kwargs) + client = TestClient(server, **kwargs) + elif isinstance(__param, BaseTestServer): + client = TestClient(__param, **kwargs) + else: + raise ValueError(f"Unknown argument type: {type(__param)}") + + await client.start_server() + clients.append(client) + return client + + yield go + + while clients: + await clients.pop().close() + + @pytest_asyncio.fixture() async def client(server: aiohttp.web.Application, aiohttp_client): return await aiohttp_client(server)