Skip to content

Commit

Permalink
tests - changes for updated requirements (#276)
Browse files Browse the repository at this point in the history
changes for
    pytest 8.3.3
    pytest-asyncio 0.24
    pytest-httpx 0.32.0
  • Loading branch information
commonism authored Oct 4, 2024
1 parent a2eaba6 commit ce2b235
Show file tree
Hide file tree
Showing 13 changed files with 185 additions and 142 deletions.
6 changes: 4 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -85,9 +85,11 @@ filterwarnings = [
"ignore:unclosed <ssl.SSLSocket:ResourceWarning",
"ignore:unclosed <socket.socket fd=:ResourceWarning",
"ignore:Ignoring Schema with additionalProperties and named properties:UserWarning",
"ignore:'flask.Markup' is deprecated and will be removed in Flask 2.4. Import 'markupsafe.Markup' instead.:DeprecationWarning"
"ignore:'flask.Markup' is deprecated and will be removed in Flask 2.4. Import 'markupsafe.Markup' instead.:DeprecationWarning",
"ignore:unclosed resource <TCPTransport:ResourceWarning"
]
asyncio_mode = "strict"
asyncio_default_fixture_loop_scope = "session"

log_cli = "yes"
log_cli_level = "DEBUG"
Expand All @@ -99,7 +101,7 @@ addopts = "--ignore-glob 'tests/my_*.py'"
[tool.pdm.dev-dependencies]
tests = [
"pytest",
"pytest-asyncio==0.21.1",
"pytest-asyncio>=0.24.0",
"pytest-httpx",
"pytest-cov",
"fastapi",
Expand Down
38 changes: 18 additions & 20 deletions tests/apiv1_test.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import asyncio
import uuid
import sys

import pytest
import pytest_asyncio
Expand All @@ -23,22 +22,25 @@ def config(unused_tcp_port_factory):
return c


@pytest_asyncio.fixture(scope="session")
async def server(event_loop, config):
policy = asyncio.get_event_loop_policy()
asyncio.set_event_loop_policy(uvloop.EventLoopPolicy())
@pytest_asyncio.fixture(loop_scope="session")
async def server(config):
event_loop = asyncio.get_running_loop()
try:
sd = asyncio.Event()
task = event_loop.create_task(serve(app, config, shutdown_trigger=sd.wait))
yield config
finally:
sd.set()
await task
asyncio.set_event_loop_policy(policy)


@pytest_asyncio.fixture(scope="session")
async def client(event_loop, server):
@pytest.fixture(scope="session")
def event_loop_policy():
return uvloop.EventLoopPolicy()


@pytest_asyncio.fixture(loop_scope="session")
async def client(server):
api = await asyncio.to_thread(aiopenapi3.OpenAPI.load_sync, f"http://{server.bind[0]}/v1/openapi.json")
return api

Expand All @@ -47,9 +49,8 @@ def randomPet(name=None):
return {"data": {"pet": {"name": str(name or uuid.uuid4()), "pet_type": "dog"}}, "return_headers": True}


@pytest.mark.asyncio
@pytest.mark.skipif(sys.version_info < (3, 9), reason="requires asyncio.to_thread")
async def test_createPet(event_loop, server, client):
@pytest.mark.asyncio(loop_scope="session")
async def test_createPet(server, client):
h, r = await asyncio.to_thread(client._.createPet, **randomPet())
assert type(r).model_json_schema() == client.components.schemas["Pet"].get_type().model_json_schema()
assert h["X-Limit-Remain"] == 5
Expand All @@ -58,17 +59,15 @@ async def test_createPet(event_loop, server, client):
assert type(r).model_json_schema() == client.components.schemas["Error"].get_type().model_json_schema()


@pytest.mark.asyncio
@pytest.mark.skipif(sys.version_info < (3, 9), reason="requires asyncio.to_thread")
async def test_listPet(event_loop, server, client):
@pytest.mark.asyncio(loop_scope="session")
async def test_listPet(server, client):
h, r = await asyncio.to_thread(client._.createPet, **randomPet(uuid.uuid4()))
l = await asyncio.to_thread(client._.listPet)
assert len(l) > 0


@pytest.mark.asyncio
@pytest.mark.skipif(sys.version_info < (3, 9), reason="requires asyncio.to_thread")
async def test_getPet(event_loop, server, client):
@pytest.mark.asyncio(loop_scope="session")
async def test_getPet(server, client):
h, pet = await asyncio.to_thread(client._.createPet, **randomPet(uuid.uuid4()))
r = await asyncio.to_thread(client._.getPet, parameters={"petId": pet.id})
# FastAPI 0.101 Serialization changes
Expand All @@ -79,9 +78,8 @@ async def test_getPet(event_loop, server, client):
assert type(r).model_json_schema() == client.components.schemas["Error"].get_type().model_json_schema()


@pytest.mark.asyncio
@pytest.mark.skipif(sys.version_info < (3, 9), reason="requires asyncio.to_thread")
async def test_deletePet(event_loop, server, client):
@pytest.mark.asyncio(loop_scope="session")
async def test_deletePet(server, client):
r = await asyncio.to_thread(client._.deletePet, parameters={"petId": -1})
print(r)
assert type(r).model_json_schema() == client.components.schemas["Error"].get_type().model_json_schema()
Expand Down
56 changes: 29 additions & 27 deletions tests/apiv2_test.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import datetime
import random
import sys
import asyncio
import uuid
from typing import ForwardRef
Expand Down Expand Up @@ -41,18 +40,21 @@ def config(unused_tcp_port_factory):
return c


@pytest_asyncio.fixture(scope="session")
async def server(event_loop, config):
policy = asyncio.get_event_loop_policy()
asyncio.set_event_loop_policy(uvloop.EventLoopPolicy())
@pytest.fixture(scope="session")
def event_loop_policy():
return uvloop.EventLoopPolicy()


@pytest_asyncio.fixture(loop_scope="session")
async def server(config):
event_loop = asyncio.get_running_loop()
try:
sd = asyncio.Event()
task = event_loop.create_task(serve(app, config, shutdown_trigger=sd.wait))
yield config
finally:
sd.set()
await task
asyncio.set_event_loop_policy(policy)


@pytest.fixture(scope="session", params=[2])
Expand All @@ -63,14 +65,15 @@ def version(request):
from aiopenapi3.debug import DescriptionDocumentDumper


@pytest_asyncio.fixture(scope="session")
async def client(event_loop, server, version):
@pytest_asyncio.fixture(loop_scope="session")
async def client(server, version):
url = f"http://{server.bind[0]}/{version}/openapi.json"

api = await aiopenapi3.OpenAPI.load_async(url, plugins=[DescriptionDocumentDumper("/tmp/schema.yaml")])
return api


@pytest.mark.asyncio(loop_scope="session")
@pytest.mark.xfail()
def test_Pet():
import json
Expand All @@ -84,24 +87,23 @@ def test_Pet():
assert t.model_json_schema() == data


@pytest.mark.asyncio
@pytest.mark.skipif(sys.version_info < (3, 9), reason="requires asyncio.to_thread")
async def test_sync(event_loop, server, version):
@pytest.mark.asyncio(loop_scope="session")
async def test_sync(server, version):
url = f"http://{server.bind[0]}/{version}/openapi.json"
api = await asyncio.to_thread(aiopenapi3.OpenAPI.load_sync, url)
return api


@pytest.mark.asyncio
async def test_description_document(event_loop, server, version):
@pytest.mark.asyncio(loop_scope="session")
async def test_description_document(server, version):
url = f"http://{server.bind[0]}/{version}/openapi.json"
api = await aiopenapi3.OpenAPI.load_async(url)
return api


@pytest.mark.xfail()
@pytest.mark.asyncio
async def test_model(event_loop, server, client):
@pytest.mark.asyncio(loop_scope="session")
async def test_model(server, client):
orig = client.components.schemas["WhiteCat"].model_dump(exclude_unset=True)
crea = client.components.schemas["WhiteCat"].get_type().model_json_schema()
assert orig == crea
Expand Down Expand Up @@ -150,16 +152,16 @@ def randomPet(client, name=None, cat=False):
}


@pytest.mark.asyncio
async def test_Request(event_loop, server, client):
@pytest.mark.asyncio(loop_scope="session")
async def test_Request(server, client):
client._.createPet.data
client._.createPet.parameters
client._.createPet.args()
client._.createPet.return_value()


@pytest.mark.asyncio
async def test_createPet(event_loop, server, client):
@pytest.mark.asyncio(loop_scope="session")
async def test_createPet(server, client):
data = {
"pet": client.components.schemas["WhiteCat"]
.model(
Expand Down Expand Up @@ -188,8 +190,8 @@ async def test_createPet(event_loop, server, client):
cls()


@pytest.mark.asyncio
async def test_listPet(event_loop, server, client):
@pytest.mark.asyncio(loop_scope="session")
async def test_listPet(server, client):
r = await client._.createPet(data=randomPet(client, str(uuid.uuid4())))
l = await client._.listPet(parameters={"limit": 1})
assert len(l) > 0
Expand All @@ -198,8 +200,8 @@ async def test_listPet(event_loop, server, client):
assert isinstance(l, client.components.schemas["HTTPValidationError"].get_type())


@pytest.mark.asyncio
async def test_getPet(event_loop, server, client):
@pytest.mark.asyncio(loop_scope="session")
async def test_getPet(server, client):
pet = await client._.createPet(data=randomPet(client, str(uuid.uuid4())))
r = await client._.getPet(parameters={"petId": pet.identifier})

Expand All @@ -211,8 +213,8 @@ async def test_getPet(event_loop, server, client):
assert type(r).model_json_schema() == client.components.schemas["Error"].get_type().model_json_schema()


@pytest.mark.asyncio
async def test_deletePet(event_loop, server, client):
@pytest.mark.asyncio(loop_scope="session")
async def test_deletePet(server, client):
r = await client._.deletePet(parameters={"petId": uuid.uuid4(), "x-raise-nonexist": False})
assert type(r).model_json_schema() == client.components.schemas["Error"].get_type().model_json_schema()

Expand All @@ -224,8 +226,8 @@ async def test_deletePet(event_loop, server, client):
await client._.deletePet(parameters={"petId": pet.identifier, "x-raise-nonexist": None})


@pytest.mark.asyncio
async def test_patchPet(event_loop, server, client):
@pytest.mark.asyncio(loop_scope="session")
async def test_patchPet(server, client):
Pet = client.components.schemas["Pet-Input"].get_type()
Dog = typing.get_args(typing.get_args(Pet.model_fields["root"].annotation)[0])[1]
pets = [
Expand Down
8 changes: 0 additions & 8 deletions tests/conftest.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import asyncio
import os
import dataclasses

Expand All @@ -13,13 +12,6 @@
URLBASE = "/"


@pytest.fixture(scope="session")
def event_loop(request):
loop = asyncio.get_event_loop_policy().new_event_loop()
yield loop
loop.close()


@pytest.fixture(autouse=True)
def skip_env(request):
if request.node.get_closest_marker("skip_env"):
Expand Down
27 changes: 14 additions & 13 deletions tests/content_length_test.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import asyncio
import random
import sys

import uvloop
from hypercorn.asyncio import serve
Expand All @@ -26,22 +25,25 @@ def config(unused_tcp_port_factory):
return c


@pytest_asyncio.fixture(scope="session")
async def server(event_loop, config):
policy = asyncio.get_event_loop_policy()
asyncio.set_event_loop_policy(uvloop.EventLoopPolicy())
@pytest_asyncio.fixture(loop_scope="session")
async def server(config):
event_loop = asyncio.get_event_loop()
try:
sd = asyncio.Event()
task = event_loop.create_task(serve(app, config, shutdown_trigger=sd.wait))
yield config
finally:
sd.set()
await task
asyncio.set_event_loop_policy(policy)


@pytest_asyncio.fixture(scope="session")
async def client(event_loop, server):
@pytest.fixture(scope="session")
def event_loop_policy():
return uvloop.EventLoopPolicy()


@pytest_asyncio.fixture(loop_scope="session")
async def client(server):
api = await aiopenapi3.OpenAPI.load_async(f"http://{server.bind[0]}/openapi.json")

return api
Expand All @@ -52,8 +54,8 @@ def content_length(request: Request, response: Response, content_length: int = Q
return PlainTextResponse(content=b" " * content_length)


@pytest.mark.asyncio
async def test_content_length_exceeded(event_loop, server, client):
@pytest.mark.asyncio(loop_scope="session")
async def test_content_length_exceeded(server, client):
cl = random.randint(1, client._max_response_content_length)
r = await client._.content_length(parameters=dict(content_length=cl))
assert len(r) == cl
Expand All @@ -67,9 +69,8 @@ async def test_content_length_exceeded(event_loop, server, client):
await client._.content_length(parameters=dict(content_length=cl))


@pytest.mark.asyncio
@pytest.mark.skipif(sys.version_info < (3, 9), reason="requires asyncio.to_thread")
async def test_sync_content_length_exceeded(event_loop, server):
@pytest.mark.asyncio(loop_scope="session")
async def test_sync_content_length_exceeded(server):
client = await asyncio.to_thread(
aiopenapi3.OpenAPI.load_sync,
f"http://{server.bind[0]}/openapi.json",
Expand Down
2 changes: 1 addition & 1 deletion tests/debug_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ def debug_session_factory(*args, **kwargs) -> httpx.Client:
p = api._.find_pet_by_id(data={}, parameters={"id": 1})


@pytest.mark.asyncio
@pytest.mark.asyncio(loop_scope="session")
async def test_debug_log_async(httpx_mock, petstore_expanded):
httpx_mock.add_response(headers={"Content-Type": "application/json"}, json={"foo": 1})

Expand Down
5 changes: 3 additions & 2 deletions tests/fixtures/schema-discriminated-union-warning.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ components:
properties:
object_type:
type: string
enum: ["a"]
a:
type: string

Expand All @@ -22,7 +23,7 @@ components:
properties:
object_type:
type: string
enum: ["f"]
enum: ["b"]
b:
type: string

Expand All @@ -33,7 +34,7 @@ components:
properties:
object_type:
type: string
# const: "f"
enum: ["c"]
c:
type: string

Expand Down
Loading

0 comments on commit ce2b235

Please sign in to comment.