Browse Source

Fixed tests having incorrect ids. Fixed an inconsistent results for tests which check websocket-scoped teardowns before the teardown actually happened on the server side.

pull/12529/head
Nir Schulman 9 months ago
parent
commit
3b27561d3d
  1. 24
      tests/test_lifespan_scoped_dependencies/test_dependency_overrides.py
  2. 45
      tests/test_lifespan_scoped_dependencies/test_endpoint_usage.py
  3. 4
      tests/test_lifespan_scoped_dependencies/testing_utilities.py

24
tests/test_lifespan_scoped_dependencies/test_dependency_overrides.py

@ -13,6 +13,8 @@ from fastapi import (
Header,
Path,
Query,
Request,
WebSocket,
)
from fastapi.exceptions import DependencyScopeConflict
from fastapi.params import Security
@ -80,7 +82,7 @@ def expect_correct_amount_of_dependency_activations(
)
@pytest.mark.parametrize("is_websocket", [True, False], ids=["Endpoint", "Websocket"])
@pytest.mark.parametrize("is_websocket", [True, False], ids=["Websocket", "Endpoint"])
@pytest.mark.parametrize("use_cache", [True, False])
@pytest.mark.parametrize("dependency_style", list(DependencyStyle))
@pytest.mark.parametrize("routing_style", ["app_endpoint", "router_endpoint"])
@ -128,7 +130,7 @@ def test_endpoint_dependencies(
)
@pytest.mark.parametrize("is_websocket", [True, False], ids=["Endpoint", "Websocket"])
@pytest.mark.parametrize("is_websocket", [True, False], ids=["Websocket", "Endpoint"])
@pytest.mark.parametrize("dependency_duplication", [1, 2])
@pytest.mark.parametrize("use_cache", [True, False])
@pytest.mark.parametrize("dependency_style", list(DependencyStyle))
@ -179,7 +181,7 @@ def test_router_dependencies(
)
@pytest.mark.parametrize("is_websocket", [True, False], ids=["Endpoint", "Websocket"])
@pytest.mark.parametrize("is_websocket", [True, False], ids=["Websocket", "Endpoint"])
@pytest.mark.parametrize("use_cache", [True, False])
@pytest.mark.parametrize("dependency_style", list(DependencyStyle))
@pytest.mark.parametrize("routing_style", ["app", "router"])
@ -261,7 +263,7 @@ def test_dependency_cache_in_same_dependency(
)
@pytest.mark.parametrize("is_websocket", [True, False], ids=["Endpoint", "Websocket"])
@pytest.mark.parametrize("is_websocket", [True, False], ids=["Websocket", "Endpoint"])
@pytest.mark.parametrize("use_cache", [True, False])
@pytest.mark.parametrize("dependency_style", list(DependencyStyle))
@pytest.mark.parametrize("routing_style", ["app", "router"])
@ -330,7 +332,7 @@ def test_dependency_cache_in_same_endpoint(
)
@pytest.mark.parametrize("is_websocket", [True, False], ids=["Endpoint", "Websocket"])
@pytest.mark.parametrize("is_websocket", [True, False], ids=["Websocket", "Endpoint"])
@pytest.mark.parametrize("use_cache", [True, False])
@pytest.mark.parametrize("dependency_style", list(DependencyStyle))
@pytest.mark.parametrize("routing_style", ["app", "router"])
@ -412,7 +414,7 @@ def test_dependency_cache_in_different_endpoints(
)
@pytest.mark.parametrize("is_websocket", [True, False], ids=["Endpoint", "Websocket"])
@pytest.mark.parametrize("is_websocket", [True, False], ids=["Websocket", "Endpoint"])
@pytest.mark.parametrize("dependency_style", list(DependencyStyle))
@pytest.mark.parametrize("routing_style", ["app", "router"])
def test_no_cached_dependency(
@ -459,7 +461,7 @@ def test_no_cached_dependency(
)
@pytest.mark.parametrize("is_websocket", [True, False], ids=["Endpoint", "Websocket"])
@pytest.mark.parametrize("is_websocket", [True, False], ids=["Websocket", "Endpoint"])
@pytest.mark.parametrize(
"annotation",
[
@ -472,6 +474,8 @@ def test_no_cached_dependency(
Annotated[str, Form()],
Annotated[str, File()],
BackgroundTasks,
Request,
WebSocket,
],
)
def test_override_lifespan_scoped_dependency_cannot_use_endpoint_scoped_parameters(
@ -500,7 +504,7 @@ def test_override_lifespan_scoped_dependency_cannot_use_endpoint_scoped_paramete
pass
@pytest.mark.parametrize("is_websocket", [True, False], ids=["Endpoint", "Websocket"])
@pytest.mark.parametrize("is_websocket", [True, False], ids=["Websocket", "Endpoint"])
@pytest.mark.parametrize("dependency_style", list(DependencyStyle))
def test_non_override_lifespan_scoped_dependency_can_use_overridden_lifespan_scoped_dependencies(
dependency_style: DependencyStyle, is_websocket
@ -541,7 +545,7 @@ def test_non_override_lifespan_scoped_dependency_can_use_overridden_lifespan_sco
)
@pytest.mark.parametrize("is_websocket", [True, False], ids=["Endpoint", "Websocket"])
@pytest.mark.parametrize("is_websocket", [True, False], ids=["Websocket", "Endpoint"])
@pytest.mark.parametrize("depends_class", [Depends, Security])
def test_override_lifespan_scoped_dependency_cannot_use_endpoint_scoped_dependencies(
depends_class, is_websocket
@ -575,7 +579,7 @@ def test_override_lifespan_scoped_dependency_cannot_use_endpoint_scoped_dependen
pass
@pytest.mark.parametrize("is_websocket", [True, False], ids=["Endpoint", "Websocket"])
@pytest.mark.parametrize("is_websocket", [True, False], ids=["Websocket", "Endpoint"])
@pytest.mark.parametrize("use_cache", [True, False])
@pytest.mark.parametrize("dependency_style", list(DependencyStyle))
@pytest.mark.parametrize("routing_style", ["app_endpoint", "router_endpoint"])

45
tests/test_lifespan_scoped_dependencies/test_endpoint_usage.py

@ -1,5 +1,6 @@
import warnings
from contextlib import asynccontextmanager
from time import sleep
from typing import Any, AsyncGenerator, Dict, List, Tuple
import pytest
@ -15,6 +16,8 @@ from fastapi import (
Header,
Path,
Query,
Request,
WebSocket,
)
from fastapi.exceptions import (
DependencyScopeConflict,
@ -70,7 +73,7 @@ def expect_correct_amount_of_dependency_activations(
assert dependency_factory.deactivation_times == expected_activation_times
@pytest.mark.parametrize("is_websocket", [True, False], ids=["Endpoint", "Websocket"])
@pytest.mark.parametrize("is_websocket", [True, False], ids=["Websocket", "Endpoint"])
@pytest.mark.parametrize(
"use_cache", [True, False], ids=["With Cache", "Without Cache"]
)
@ -118,7 +121,7 @@ def test_endpoint_dependencies(
)
@pytest.mark.parametrize("is_websocket", [True, False], ids=["Endpoint", "Websocket"])
@pytest.mark.parametrize("is_websocket", [True, False], ids=["Websocket", "Endpoint"])
@pytest.mark.parametrize("dependency_duplication", [1, 2])
@pytest.mark.parametrize("use_cache", [True, False])
@pytest.mark.parametrize("dependency_style", list(DependencyStyle))
@ -163,7 +166,7 @@ def test_router_dependencies(
)
@pytest.mark.parametrize("is_websocket", [True, False], ids=["Endpoint", "Websocket"])
@pytest.mark.parametrize("is_websocket", [True, False], ids=["Websocket", "Endpoint"])
@pytest.mark.parametrize("use_cache", [True, False])
@pytest.mark.parametrize("dependency_style", list(DependencyStyle))
@pytest.mark.parametrize("routing_style", ["app", "router"])
@ -238,7 +241,7 @@ def test_dependency_cache_in_same_dependency(
)
@pytest.mark.parametrize("is_websocket", [True, False], ids=["Endpoint", "Websocket"])
@pytest.mark.parametrize("is_websocket", [True, False], ids=["Websocket", "Endpoint"])
@pytest.mark.parametrize("use_cache", [True, False])
@pytest.mark.parametrize("dependency_style", list(DependencyStyle))
@pytest.mark.parametrize("routing_style", ["app", "router"])
@ -300,7 +303,7 @@ def test_dependency_cache_in_same_endpoint(
)
@pytest.mark.parametrize("is_websocket", [True, False], ids=["Endpoint", "Websocket"])
@pytest.mark.parametrize("is_websocket", [True, False], ids=["Websocket", "Endpoint"])
@pytest.mark.parametrize("use_cache", [True, False])
@pytest.mark.parametrize("dependency_style", list(DependencyStyle))
@pytest.mark.parametrize("routing_style", ["app", "router"])
@ -375,7 +378,7 @@ def test_dependency_cache_in_different_endpoints(
)
@pytest.mark.parametrize("is_websocket", [True, False], ids=["Endpoint", "Websocket"])
@pytest.mark.parametrize("is_websocket", [True, False], ids=["Websocket", "Endpoint"])
@pytest.mark.parametrize("dependency_style", list(DependencyStyle))
@pytest.mark.parametrize("routing_style", ["app", "router"])
def test_no_cached_dependency(
@ -419,7 +422,7 @@ def test_no_cached_dependency(
)
@pytest.mark.parametrize("is_websocket", [True, False], ids=["Endpoint", "Websocket"])
@pytest.mark.parametrize("is_websocket", [True, False], ids=["Websocket", "Endpoint"])
@pytest.mark.parametrize(
"annotation",
[
@ -432,6 +435,8 @@ def test_no_cached_dependency(
Annotated[str, Form()],
Annotated[str, File()],
BackgroundTasks,
Request,
WebSocket
],
)
def test_lifespan_scoped_dependency_cannot_use_endpoint_scoped_parameters(
@ -453,7 +458,7 @@ def test_lifespan_scoped_dependency_cannot_use_endpoint_scoped_parameters(
)
@pytest.mark.parametrize("is_websocket", [True, False], ids=["Endpoint", "Websocket"])
@pytest.mark.parametrize("is_websocket", [True, False], ids=["Websocket", "Endpoint"])
@pytest.mark.parametrize("dependency_style", list(DependencyStyle))
def test_lifespan_scoped_dependency_can_use_other_lifespan_scoped_dependencies(
dependency_style: DependencyStyle, is_websocket
@ -487,7 +492,7 @@ def test_lifespan_scoped_dependency_can_use_other_lifespan_scoped_dependencies(
)
@pytest.mark.parametrize("is_websocket", [True, False], ids=["Endpoint", "Websocket"])
@pytest.mark.parametrize("is_websocket", [True, False], ids=["Websocket", "Endpoint"])
@pytest.mark.parametrize(
["dependency_style", "supports_teardown"],
[
@ -530,6 +535,10 @@ def test_the_same_dependency_can_work_in_different_scopes(
assert get_response(client, "/test") == [2, 1]
assert dependency_factory.activation_times == 2
if supports_teardown:
if is_websocket:
# Websockets teardown might take some time after the test client
# has disconnected
sleep(0.1)
assert dependency_factory.deactivation_times == 1
else:
assert dependency_factory.deactivation_times == 0
@ -537,6 +546,10 @@ def test_the_same_dependency_can_work_in_different_scopes(
assert get_response(client, "/test") == [3, 1]
assert dependency_factory.activation_times == 3
if supports_teardown:
if is_websocket:
# Websockets teardown might take some time after the test client
# has disconnected
sleep(0.1)
assert dependency_factory.deactivation_times == 2
else:
assert dependency_factory.deactivation_times == 0
@ -551,7 +564,7 @@ def test_the_same_dependency_can_work_in_different_scopes(
@pytest.mark.parametrize(
"lifespan_style", ["lifespan_generator", "events_decorator", "events_constructor"]
)
@pytest.mark.parametrize("is_websocket", [True, False], ids=["Endpoint", "Websocket"])
@pytest.mark.parametrize("is_websocket", [True, False], ids=["Websocket", "Endpoint"])
@pytest.mark.parametrize("dependency_style", list(DependencyStyle))
def test_lifespan_scoped_dependency_can_be_used_alongside_custom_lifespans(
dependency_style: DependencyStyle,
@ -622,7 +635,7 @@ def test_lifespan_scoped_dependency_can_be_used_alongside_custom_lifespans(
assert lifespan_started and lifespan_ended
@pytest.mark.parametrize("is_websocket", [True, False], ids=["Endpoint", "Websocket"])
@pytest.mark.parametrize("is_websocket", [True, False], ids=["Websocket", "Endpoint"])
@pytest.mark.parametrize("depends_class", [Depends, Security])
def test_lifespan_scoped_dependency_cannot_use_endpoint_scoped_dependencies(
depends_class, is_websocket
@ -648,7 +661,7 @@ def test_lifespan_scoped_dependency_cannot_use_endpoint_scoped_dependencies(
)
@pytest.mark.parametrize("is_websocket", [True, False], ids=["Endpoint", "Websocket"])
@pytest.mark.parametrize("is_websocket", [True, False], ids=["Websocket", "Endpoint"])
@pytest.mark.parametrize("use_cache", [True, False])
@pytest.mark.parametrize("dependency_style", list(DependencyStyle))
@pytest.mark.parametrize("routing_style", ["app_endpoint", "router_endpoint"])
@ -683,7 +696,7 @@ def test_dependencies_must_provide_correct_dependency_scope(
)
@pytest.mark.parametrize("is_websocket", [True, False], ids=["Endpoint", "Websocket"])
@pytest.mark.parametrize("is_websocket", [True, False], ids=["Websocket", "Endpoint"])
@pytest.mark.parametrize("use_cache", [True, False])
@pytest.mark.parametrize("dependency_style", list(DependencyStyle))
@pytest.mark.parametrize("routing_style", ["app_endpoint", "router_endpoint"])
@ -717,7 +730,7 @@ def test_endpoints_report_incorrect_dependency_scope(
)
@pytest.mark.parametrize("is_websocket", [True, False], ids=["Endpoint", "Websocket"])
@pytest.mark.parametrize("is_websocket", [True, False], ids=["Websocket", "Endpoint"])
@pytest.mark.parametrize("use_cache", [True, False])
@pytest.mark.parametrize("dependency_style", list(DependencyStyle))
@pytest.mark.parametrize("routing_style", ["app_endpoint", "router_endpoint"])
@ -767,7 +780,7 @@ def test_endpoints_report_uninitialized_dependency(
)
@pytest.mark.parametrize("is_websocket", [True, False], ids=["Endpoint", "Websocket"])
@pytest.mark.parametrize("is_websocket", [True, False], ids=["Websocket", "Endpoint"])
@pytest.mark.parametrize("use_cache", [True, False])
@pytest.mark.parametrize("dependency_style", list(DependencyStyle))
@pytest.mark.parametrize("routing_style", ["app_endpoint", "router_endpoint"])
@ -815,7 +828,7 @@ def test_endpoints_report_uninitialized_internal_lifespan(
client.app_state["__fastapi__"] = internal_state
@pytest.mark.parametrize("is_websocket", [True, False], ids=["Endpoint", "Websocket"])
@pytest.mark.parametrize("is_websocket", [True, False], ids=["Websocket", "Endpoint"])
@pytest.mark.parametrize("use_cache", [True, False])
@pytest.mark.parametrize("dependency_style", list(DependencyStyle))
@pytest.mark.parametrize("routing_style", ["app_endpoint", "router_endpoint"])

4
tests/test_lifespan_scoped_dependencies/testing_utilities.py

@ -1,3 +1,4 @@
import threading
from enum import Enum
from typing import Any, AsyncGenerator, Generator, List, TypeVar, Union
@ -33,6 +34,7 @@ class DependencyFactory:
self.dependency_style = dependency_style
self._should_error = should_error
self._value_offset = value_offset
self._event = threading.Event()
def get_dependency(self):
if self.dependency_style == DependencyStyle.SYNC_FUNCTION:
@ -56,6 +58,7 @@ class DependencyFactory:
yield self.activation_times + self._value_offset
self.deactivation_times += 1
self._event.set()
def _synchronous_generator_dependency(self) -> Generator[T, None, None]:
self.activation_times += 1
@ -64,6 +67,7 @@ class DependencyFactory:
yield self.activation_times + self._value_offset
self.deactivation_times += 1
self._event.set()
async def _asynchronous_function_dependency(self) -> T:
self.activation_times += 1

Loading…
Cancel
Save