great-ai/tests/external/test_basic.py

187 lines
4.3 KiB
Python

import asyncio
from functools import partial
import pytest
from great_ai.external.async_lru import alru_cache
alru_cache_attrs = [
"hits",
"misses",
"tasks",
"closed",
"cache_info",
"cache_clear",
"invalidate",
"close",
"open",
]
alru_cache_calable_attrs = alru_cache_attrs.copy()
for attr in ["hits", "misses", "tasks", "closed"]:
alru_cache_calable_attrs.remove(attr)
def test_alru_cache_not_callable(loop):
with pytest.raises(NotImplementedError):
alru_cache("foo")
def test_alru_cache_not_coroutine(loop):
with pytest.raises(RuntimeError):
@alru_cache
def not_coro(val):
return val
def test_alru_cache_deco(loop, check_lru):
asyncio.set_event_loop(loop)
@alru_cache
async def coro():
pass
assert asyncio.iscoroutinefunction(coro)
for attr in alru_cache_attrs:
assert hasattr(coro, attr)
for attr in alru_cache_calable_attrs:
assert callable(getattr(coro, attr))
assert isinstance(coro._cache, dict)
assert isinstance(coro.tasks, set)
check_lru(coro, hits=0, misses=0, cache=0, tasks=0)
awaitable = coro()
assert asyncio.iscoroutine(awaitable)
loop.run_until_complete(awaitable)
def test_alru_cache_deco_called(check_lru, loop):
asyncio.set_event_loop(loop)
@alru_cache()
async def coro():
pass
assert asyncio.iscoroutinefunction(coro)
for attr in alru_cache_attrs:
assert hasattr(coro, attr)
for attr in alru_cache_calable_attrs:
assert callable(getattr(coro, attr))
assert isinstance(coro._cache, dict)
assert isinstance(coro.tasks, set)
check_lru(coro, hits=0, misses=0, cache=0, tasks=0)
awaitable = coro()
assert asyncio.iscoroutine(awaitable)
loop.run_until_complete(awaitable)
def test_alru_cache_fn_called(check_lru, loop):
asyncio.set_event_loop(loop)
async def coro():
pass
coro_wrapped = alru_cache(coro)
assert asyncio.iscoroutinefunction(coro_wrapped)
for attr in alru_cache_attrs:
assert hasattr(coro_wrapped, attr)
for attr in alru_cache_calable_attrs:
assert callable(getattr(coro_wrapped, attr))
assert isinstance(coro_wrapped._cache, dict)
assert isinstance(coro_wrapped.tasks, set)
check_lru(coro_wrapped, hits=0, misses=0, cache=0, tasks=0)
awaitable = coro_wrapped()
assert asyncio.iscoroutine(awaitable)
loop.run_until_complete(awaitable)
def test_alru_cache_origin(loop):
asyncio.set_event_loop(loop)
async def coro():
pass
coro_wrapped = alru_cache(coro)
assert coro_wrapped._origin is coro
coro_wrapped = alru_cache(partial(coro))
assert coro_wrapped._origin is coro
@pytest.mark.asyncio
async def test_alru_cache_await_same_result_async(check_lru, loop):
calls = 0
val = object()
@alru_cache()
async def coro():
nonlocal calls
calls += 1
return val
coros = [coro() for _ in range(100)]
ret = await asyncio.gather(*coros)
expected = [val] * 100
assert ret == expected
check_lru(coro, hits=99, misses=1, cache=1, tasks=0)
assert calls == 1
assert await coro() is val
check_lru(coro, hits=100, misses=1, cache=1, tasks=0)
@pytest.mark.asyncio
async def test_alru_cache_await_same_result_coroutine(check_lru, loop):
calls = 0
val = object()
@alru_cache()
async def coro():
nonlocal calls
calls += 1
return val
coros = [coro() for _ in range(100)]
ret = await asyncio.gather(*coros)
expected = [val] * 100
assert ret == expected
check_lru(coro, hits=99, misses=1, cache=1, tasks=0)
assert calls == 1
assert await coro() is val
check_lru(coro, hits=100, misses=1, cache=1, tasks=0)
@pytest.mark.asyncio
async def test_alru_cache_dict_not_shared(check_lru, loop):
async def coro(val):
return val
coro1 = alru_cache()(coro)
coro2 = alru_cache()(coro)
ret1 = await coro1(1)
check_lru(coro1, hits=0, misses=1, cache=1, tasks=0)
ret2 = await coro2(1)
check_lru(coro2, hits=0, misses=1, cache=1, tasks=0)
assert ret1 == ret2
assert coro1._cache[1].result() == coro2._cache[1].result()
assert coro1._cache != coro2._cache
assert coro1._cache.keys() == coro2._cache.keys()
assert coro1._cache is not coro2._cache