Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use InMemoryCache in tests #134

Merged
merged 1 commit into from
Dec 12, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion hishel/_async/_storages.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ async def retrieve(self, key: str) -> tp.Optional[StoredResponse]:
return self._serializer.loads(await self._file_manager.read_from(str(response_path)))
return None

async def aclose(self) -> None:
async def aclose(self) -> None: # pragma: no cover
return

async def _remove_expired_caches(self) -> None:
Expand Down Expand Up @@ -364,6 +364,7 @@ async def store(self, key: str, response: Response, request: Request, metadata:
request_clone = clone_model(request)
stored_response: StoredResponse = (deepcopy(response_clone), deepcopy(request_clone), metadata)
self._cache.put(key, (stored_response, time.monotonic()))
await self._remove_expired_caches()

async def retrieve(self, key: str) -> tp.Optional[StoredResponse]:
"""
Expand Down
5 changes: 4 additions & 1 deletion hishel/_sync/_storages.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ def retrieve(self, key: str) -> tp.Optional[StoredResponse]:
return self._serializer.loads(self._file_manager.read_from(str(response_path)))
return None

def close(self) -> None:
def close(self) -> None: # pragma: no cover
return

def _remove_expired_caches(self) -> None:
Expand Down Expand Up @@ -325,6 +325,8 @@ class InMemoryStorage(BaseStorage):
:type serializer: tp.Optional[BaseSerializer], optional
:param ttl: Specifies the maximum number of seconds that the response can be cached, defaults to None
:type ttl: tp.Optional[tp.Union[int, float]], optional
:param capacity: The maximum number of responses that can be cached, defaults to 128
:type capacity: int, optional
"""

def __init__(
Expand Down Expand Up @@ -362,6 +364,7 @@ def store(self, key: str, response: Response, request: Request, metadata: Metada
request_clone = clone_model(request)
stored_response: StoredResponse = (deepcopy(response_clone), deepcopy(request_clone), metadata)
self._cache.put(key, (stored_response, time.monotonic()))
self._remove_expired_caches()

def retrieve(self, key: str) -> tp.Optional[StoredResponse]:
"""
Expand Down
2 changes: 1 addition & 1 deletion tests/_async/test_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
async def test_client_301():
async with hishel.MockAsyncTransport() as transport:
transport.add_responses([httpx.Response(301, headers=[(b"Location", b"https://example.com")])])
async with hishel.AsyncCacheClient(transport=transport) as client:
async with hishel.AsyncCacheClient(transport=transport, storage=hishel.AsyncInMemoryStorage()) as client:
await client.request(
"GET",
"https://www.example.com",
Expand Down
39 changes: 23 additions & 16 deletions tests/_async/test_pool.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,17 @@


@pytest.mark.anyio
async def test_pool_301(use_temp_dir):
async def test_pool_301():
async with hishel.MockAsyncConnectionPool() as pool:
pool.add_responses([httpcore.Response(301, headers=[(b"Location", b"https://example.com")])])
async with hishel.AsyncCacheConnectionPool(pool=pool) as cache_pool:
async with hishel.AsyncCacheConnectionPool(pool=pool, storage=hishel.AsyncInMemoryStorage()) as cache_pool:
await cache_pool.request("GET", "https://www.example.com")
response = await cache_pool.request("GET", "https://www.example.com")
assert response.extensions["from_cache"]


@pytest.mark.anyio
async def test_pool_response_validation(use_temp_dir):
async def test_pool_response_validation():
async with hishel.MockAsyncConnectionPool() as pool:
pool.add_responses(
[
Expand All @@ -39,7 +39,7 @@ async def test_pool_response_validation(use_temp_dir):
),
]
)
async with hishel.AsyncCacheConnectionPool(pool=pool) as cache_pool:
async with hishel.AsyncCacheConnectionPool(pool=pool, storage=hishel.AsyncInMemoryStorage()) as cache_pool:
request = httpcore.Request("GET", "https://www.example.com")

await cache_pool.handle_async_request(request)
Expand All @@ -52,7 +52,7 @@ async def test_pool_response_validation(use_temp_dir):


@pytest.mark.anyio
async def test_pool_stale_response(use_temp_dir):
async def test_pool_stale_response():
controller = hishel.Controller(allow_stale=True)
async with hishel.MockAsyncConnectionPool() as pool:
pool.add_responses(
Expand All @@ -73,14 +73,16 @@ async def test_pool_stale_response(use_temp_dir):
),
]
)
async with hishel.AsyncCacheConnectionPool(pool=pool, controller=controller) as cache_pool:
async with hishel.AsyncCacheConnectionPool(
pool=pool, controller=controller, storage=hishel.AsyncInMemoryStorage()
) as cache_pool:
await cache_pool.request("GET", "https://www.example.com")
response = await cache_pool.request("GET", "https://www.example.com")
assert not response.extensions["from_cache"]


@pytest.mark.anyio
async def test_pool_stale_response_with_connecterror(use_temp_dir):
async def test_pool_stale_response_with_connecterror():
controller = hishel.Controller(allow_stale=True)

class ConnectErrorPool(hishel.MockAsyncConnectionPool):
Expand All @@ -102,18 +104,22 @@ async def handle_async_request(self, request: Request) -> Response:
),
]
)
async with hishel.AsyncCacheConnectionPool(pool=pool, controller=controller) as cache_pool:
async with hishel.AsyncCacheConnectionPool(
pool=pool, controller=controller, storage=hishel.AsyncInMemoryStorage()
) as cache_pool:
await cache_pool.request("GET", "https://www.example.com")
response = await cache_pool.request("GET", "https://www.example.com")
assert response.extensions["from_cache"]


@pytest.mark.anyio
async def test_pool_with_only_if_cached_directive_without_stored_response(use_temp_dir):
async def test_pool_with_only_if_cached_directive_without_stored_response():
controller = hishel.Controller()

async with hishel.MockAsyncConnectionPool() as pool:
async with hishel.AsyncCacheConnectionPool(pool=pool, controller=controller) as cache_pool:
async with hishel.AsyncCacheConnectionPool(
pool=pool, controller=controller, storage=hishel.AsyncInMemoryStorage()
) as cache_pool:
response = await cache_pool.request(
"GET",
"https://www.example.com",
Expand All @@ -123,7 +129,7 @@ async def test_pool_with_only_if_cached_directive_without_stored_response(use_te


@pytest.mark.anyio
async def test_pool_with_only_if_cached_directive_with_stored_response(use_temp_dir):
async def test_pool_with_only_if_cached_directive_with_stored_response():
controller = hishel.Controller()

async with hishel.MockAsyncConnectionPool() as pool:
Expand All @@ -139,7 +145,9 @@ async def test_pool_with_only_if_cached_directive_with_stored_response(use_temp_
),
]
)
async with hishel.AsyncCacheConnectionPool(pool=pool, controller=controller) as cache_pool:
async with hishel.AsyncCacheConnectionPool(
pool=pool, controller=controller, storage=hishel.AsyncInMemoryStorage()
) as cache_pool:
await cache_pool.request("GET", "https://www.example.com")
response = await cache_pool.request(
"GET",
Expand All @@ -150,7 +158,7 @@ async def test_pool_with_only_if_cached_directive_with_stored_response(use_temp_


@pytest.mark.anyio
async def test_pool_with_cache_disabled_extension(use_temp_dir):
async def test_pool_with_cache_disabled_extension():
class MockedClock(BaseClock):
def now(self) -> int:
return 1440504001 # Mon, 25 Aug 2015 12:00:01 GMT
Expand All @@ -166,7 +174,7 @@ def now(self) -> int:
async with hishel.MockAsyncConnectionPool() as pool:
pool.add_responses([cachable_response, httpcore.Response(201)])
async with hishel.AsyncCacheConnectionPool(
pool=pool, controller=hishel.Controller(clock=MockedClock())
pool=pool, controller=hishel.Controller(clock=MockedClock()), storage=hishel.AsyncInMemoryStorage()
) as cache_transport:
request = httpcore.Request("GET", "https://www.example.com")
# This should create a cache entry
Expand All @@ -190,8 +198,7 @@ async def test_transport_with_custom_key_generator():
async with hishel.MockAsyncConnectionPool() as pool:
pool.add_responses([httpcore.Response(301)])
async with hishel.AsyncCacheConnectionPool(
pool=pool,
controller=controller,
pool=pool, controller=controller, storage=hishel.AsyncInMemoryStorage()
) as cache_transport:
request = httpcore.Request("GET", "https://www.example.com")
# This should create a cache entry
Expand Down
2 changes: 1 addition & 1 deletion tests/_async/test_storages.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ async def test_inmemorystorage():


@pytest.mark.asyncio
async def test_filestorage_expired():
async def test_filestorage_expired(use_temp_dir):
storage = AsyncFileStorage(ttl=0.1)
first_request = Request(b"GET", "https://example.com")
second_request = Request(b"GET", "https://anotherexample.com")
Expand Down
47 changes: 29 additions & 18 deletions tests/_async/test_transport.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,12 @@


@pytest.mark.anyio
async def test_transport_301(use_temp_dir):
async def test_transport_301():
async with hishel.MockAsyncTransport() as transport:
transport.add_responses([httpx.Response(301, headers=[(b"Location", b"https://example.com")])])
async with hishel.AsyncCacheTransport(transport=transport) as cache_transport:
async with hishel.AsyncCacheTransport(
transport=transport, storage=hishel.AsyncInMemoryStorage()
) as cache_transport:
request = httpx.Request("GET", "https://www.example.com")

await cache_transport.handle_async_request(request)
Expand All @@ -18,7 +20,7 @@ async def test_transport_301(use_temp_dir):


@pytest.mark.anyio
async def test_transport_response_validation(use_temp_dir):
async def test_transport_response_validation():
async with hishel.MockAsyncTransport() as transport:
transport.add_responses(
[
Expand All @@ -40,7 +42,9 @@ async def test_transport_response_validation(use_temp_dir):
),
]
)
async with hishel.AsyncCacheTransport(transport=transport) as cache_transport:
async with hishel.AsyncCacheTransport(
transport=transport, storage=hishel.AsyncInMemoryStorage()
) as cache_transport:
request = httpx.Request("GET", "https://www.example.com")

await cache_transport.handle_async_request(request)
Expand All @@ -53,7 +57,7 @@ async def test_transport_response_validation(use_temp_dir):


@pytest.mark.anyio
async def test_transport_stale_response(use_temp_dir):
async def test_transport_stale_response():
controller = hishel.Controller(allow_stale=True)

async with hishel.MockAsyncTransport() as transport:
Expand All @@ -75,15 +79,17 @@ async def test_transport_stale_response(use_temp_dir):
),
]
)
async with hishel.AsyncCacheTransport(transport=transport, controller=controller) as cache_transport:
async with hishel.AsyncCacheTransport(
transport=transport, controller=controller, storage=hishel.AsyncInMemoryStorage()
) as cache_transport:
request = httpx.Request("GET", "https://www.example.com")
await cache_transport.handle_async_request(request)
response = await cache_transport.handle_async_request(request)
assert not response.extensions["from_cache"]


@pytest.mark.anyio
async def test_transport_stale_response_with_connecterror(use_temp_dir):
async def test_transport_stale_response_with_connecterror():
controller = hishel.Controller(allow_stale=True)

class ConnectErrorTransport(hishel.MockAsyncTransport):
Expand Down Expand Up @@ -112,21 +118,23 @@ async def handle_async_request(self, request: httpx.Request) -> httpx.Response:
),
]
)
async with hishel.AsyncCacheTransport(transport=transport, controller=controller) as cache_transport:
async with hishel.AsyncCacheTransport(
transport=transport, controller=controller, storage=hishel.AsyncInMemoryStorage()
) as cache_transport:
request = httpx.Request("GET", "https://www.example.com")
await cache_transport.handle_async_request(request)
response = await cache_transport.handle_async_request(request)
assert response.extensions["from_cache"]


@pytest.mark.anyio
async def test_transport_with_only_if_cached_directive_without_stored_response(
use_temp_dir,
):
async def test_transport_with_only_if_cached_directive_without_stored_response():
controller = hishel.Controller()

async with hishel.MockAsyncTransport() as transport:
async with hishel.AsyncCacheTransport(transport=transport, controller=controller) as cache_transport:
async with hishel.AsyncCacheTransport(
transport=transport, controller=controller, storage=hishel.AsyncInMemoryStorage()
) as cache_transport:
response = await cache_transport.handle_async_request(
httpx.Request(
"GET",
Expand All @@ -138,9 +146,7 @@ async def test_transport_with_only_if_cached_directive_without_stored_response(


@pytest.mark.anyio
async def test_transport_with_only_if_cached_directive_with_stored_response(
use_temp_dir,
):
async def test_transport_with_only_if_cached_directive_with_stored_response():
controller = hishel.Controller()

async with hishel.MockAsyncTransport() as transport:
Expand All @@ -156,7 +162,9 @@ async def test_transport_with_only_if_cached_directive_with_stored_response(
),
]
)
async with hishel.AsyncCacheTransport(transport=transport, controller=controller) as cache_transport:
async with hishel.AsyncCacheTransport(
transport=transport, controller=controller, storage=hishel.AsyncInMemoryStorage()
) as cache_transport:
await cache_transport.handle_async_request(httpx.Request("GET", "https://www.example.com"))
response = await cache_transport.handle_async_request(
httpx.Request(
Expand All @@ -169,7 +177,7 @@ async def test_transport_with_only_if_cached_directive_with_stored_response(


@pytest.mark.anyio
async def test_transport_with_cache_disabled_extension(use_temp_dir):
async def test_transport_with_cache_disabled_extension():
class MockedClock(BaseClock):
def now(self) -> int:
return 1440504001 # Mon, 25 Aug 2015 12:00:01 GMT
Expand All @@ -185,7 +193,9 @@ def now(self) -> int:
async with hishel.MockAsyncTransport() as transport:
transport.add_responses([cachable_response, httpx.Response(201)])
async with hishel.AsyncCacheTransport(
transport=transport, controller=hishel.Controller(clock=MockedClock())
transport=transport,
controller=hishel.Controller(clock=MockedClock()),
storage=hishel.AsyncInMemoryStorage(),
) as cache_transport:
request = httpx.Request("GET", "https://www.example.com")
# This should create a cache entry
Expand All @@ -211,6 +221,7 @@ async def test_transport_with_custom_key_generator():
async with hishel.AsyncCacheTransport(
transport=transport,
controller=controller,
storage=hishel.AsyncInMemoryStorage(),
) as cache_transport:
request = httpx.Request("GET", "https://www.example.com")
# This should create a cache entry
Expand Down
2 changes: 1 addition & 1 deletion tests/_sync/test_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
def test_client_301():
with hishel.MockTransport() as transport:
transport.add_responses([httpx.Response(301, headers=[(b"Location", b"https://example.com")])])
with hishel.CacheClient(transport=transport) as client:
with hishel.CacheClient(transport=transport, storage=hishel.InMemoryStorage()) as client:
client.request(
"GET",
"https://www.example.com",
Expand Down
Loading