Skip to content

Commit

Permalink
add test of entry cache behaviour
Browse files Browse the repository at this point in the history
Signed-off-by: Andrew Whitehead <[email protected]>
  • Loading branch information
andrewwhitehead committed Jan 28, 2025
1 parent 3b6f53c commit aa554a1
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 12 deletions.
3 changes: 2 additions & 1 deletion wrappers/python/setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,5 @@ per_file_ignores = */__init__.py:D104
minversion = 5.0
testpaths =
tests
asyncio_mode=strict
asyncio_mode=auto
asyncio_default_fixture_loop_scope=session
65 changes: 54 additions & 11 deletions wrappers/python/tests/test_store.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import asyncio
import gc
import os
from weakref import WeakKeyDictionary

from pytest import mark, raises
import pytest_asyncio
Expand All @@ -10,6 +12,7 @@
Key,
Store,
)
from aries_askar.bindings.lib import entry_cache


TEST_STORE_URI = os.getenv("TEST_STORE_URI", "sqlite://:memory:")
Expand All @@ -26,15 +29,13 @@ def raw_key() -> str:


@pytest_asyncio.fixture
@mark.asyncio
async def store() -> Store:
key = raw_key()
store = await Store.provision(TEST_STORE_URI, "raw", key, recreate=True)
yield store
await store.close(remove=True)


@mark.asyncio
async def test_insert_update(store: Store):
async with store as session:
# Insert a new entry
Expand Down Expand Up @@ -81,7 +82,6 @@ async def test_insert_update(store: Store):
assert found is None


@mark.asyncio
async def test_remove_all(store: Store):
async with store as session:
# Insert a new entry
Expand All @@ -104,7 +104,6 @@ async def test_remove_all(store: Store):
assert found is None


@mark.asyncio
async def test_scan(store: Store):
async with store as session:
await session.insert(
Expand Down Expand Up @@ -133,7 +132,6 @@ async def test_scan(store: Store):
assert len(rows) == 1 and dict(rows[0]) == TEST_ENTRY


@mark.asyncio
async def test_txn_basic(store: Store):
async with store.transaction() as txn:
# Insert a new entry
Expand Down Expand Up @@ -167,7 +165,6 @@ async def test_txn_basic(store: Store):
assert dict(found) == TEST_ENTRY


@mark.asyncio
async def test_txn_autocommit(store: Store):
with raises(Exception):
async with store.transaction(autocommit=True) as txn:
Expand Down Expand Up @@ -203,7 +200,6 @@ async def test_txn_autocommit(store: Store):
assert dict(found) == TEST_ENTRY


@mark.asyncio
async def test_txn_contention(store: Store):
async with store.transaction() as txn:
await txn.insert(
Expand Down Expand Up @@ -240,7 +236,6 @@ async def inc():
assert int(result.value) == INC_COUNT * TASKS


@mark.asyncio
async def test_key_store_ed25519(store: Store):
# test key operations in a new session
async with store as session:
Expand Down Expand Up @@ -279,7 +274,6 @@ async def test_key_store_ed25519(store: Store):
assert await session.fetch_key(key_name) is None


@mark.asyncio
@mark.parametrize(
"key_alg",
[KeyAlg.A128CBC_HS256, KeyAlg.XC20P],
Expand Down Expand Up @@ -318,7 +312,6 @@ async def test_key_store_symmetric(store: Store, key_alg: KeyAlg):
assert await session.fetch_key(key_name) is None


@mark.asyncio
async def test_profile(store: Store):
# New session in the default profile
async with store as session:
Expand Down Expand Up @@ -409,7 +402,6 @@ async def test_profile(store: Store):
assert (await store.get_default_profile()) == profile


@mark.asyncio
async def test_copy(store: Store):
async with store as session:
# Insert a new entry
Expand All @@ -429,3 +421,54 @@ async def test_copy(store: Store):
entries = await session.fetch_all(TEST_ENTRY["category"])
assert len(entries) == 1
assert entries[0].name == TEST_ENTRY["name"]


def test_entry_cache():
instances = WeakKeyDictionary()

class MockList:
def __init__(self, name: str, value: dict):
self._name = name
self._value = value
self._calls = []
instances[self] = True

@entry_cache
def get_name(self, index: int) -> str:
self._calls.append(index)
return self._name + str(index)

@entry_cache
def get_value(self, index: int) -> dict:
self._calls.append(index)
return self._value

NAME = "testname"
VALUE = {"a": "b"}
lst = MockList(NAME, VALUE)
# check instance is registered
assert instances

# check first call goes to method
assert lst.get_name(99) == NAME + "99"
assert lst._calls == [99]
assert lst.get_name(45) == NAME + "45"
assert lst._calls == [99, 45]
val = lst.get_value(11)
assert val == VALUE
assert lst._calls == [99, 45, 11]

# check dict value is copied
val["a"] = "c"
assert val != VALUE

# check second call goes to cache
assert lst.get_name(99) == NAME + "99"
assert lst.get_name(45) == NAME + "45"
assert lst.get_value(11) == VALUE
assert lst._calls == [99, 45, 11]

# ensure no extra references are keeping the instance around
del lst
gc.collect()
assert not instances

0 comments on commit aa554a1

Please sign in to comment.