# ========= Copyright 2026 @ Strukto.AI All Rights Reserved. ========= # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # ========= Copyright 2026 @ Strukto.AI All Rights Reserved. ========= import asyncio import pytest from mirage.cache.lock import KeyLockMixin class _Store(KeyLockMixin): pass @pytest.mark.asyncio async def test_different_keys_return_different_locks(): store = _Store() assert store._lock_for("/a") is not store._lock_for("/b") @pytest.mark.asyncio async def test_same_key_returns_same_lock(): store = _Store() assert store._lock_for("/a") is store._lock_for("/a") @pytest.mark.asyncio async def test_discard_lock_removes_key(): store = _Store() store._lock_for("/a") store._discard_lock("/a") assert "/a" not in store._key_locks @pytest.mark.asyncio async def test_discard_lock_missing_key_no_error(): store = _Store() store._discard_lock("/nope") @pytest.mark.asyncio async def test_clear_locks_removes_all(): store = _Store() store._lock_for("/a") store._lock_for("/b") store._clear_locks() assert len(store._key_locks) == 0 @pytest.mark.asyncio async def test_concurrent_different_keys_no_block(): store = _Store() order = [] async def acquire(key, label): async with store._lock_for(key): order.append(f"{label}_start") await asyncio.sleep(0) order.append(f"{label}_end") await asyncio.gather(acquire("/a", "a"), acquire("/b", "b")) assert "a_start" in order assert "b_start" in order @pytest.mark.asyncio async def test_same_key_serialized(): store = _Store() order = [] async def acquire(label): async with store._lock_for("/same"): order.append(f"{label}_start") await asyncio.sleep(0.01) order.append(f"{label}_end") await asyncio.gather(acquire("first"), acquire("second")) assert order[0] == "first_start" assert order[1] == "first_end" assert order[2] == "second_start" assert order[3] == "second_end"