94 lines
2.1 KiB
Python
94 lines
2.1 KiB
Python
import time
|
|
import pytest
|
|
|
|
from ttl_lru_cache import TTLCache, CacheMiss
|
|
|
|
|
|
def test_basic_get_set():
|
|
c = TTLCache(2)
|
|
c.set("a", 1)
|
|
c.set("b", 2)
|
|
assert c.get("a") == 1
|
|
assert c.get("z", 9) == 9
|
|
assert "a" in c
|
|
|
|
|
|
def test_lru_eviction():
|
|
c = TTLCache(2)
|
|
c.set("a", 1)
|
|
c.set("b", 2)
|
|
c.get("a") # make a recently used
|
|
c.set("c", 3)
|
|
assert "b" not in c
|
|
assert c.get("a") == 1
|
|
assert c.get("c") == 3
|
|
|
|
|
|
def test_ttl_expiry():
|
|
clock = [0.0]
|
|
c = TTLCache(10, default_ttl=5, clock=lambda: clock[0])
|
|
c.set("a", 1)
|
|
assert c.get("a") == 1
|
|
clock[0] = 6
|
|
assert c.get("a") is None
|
|
assert "a" not in c
|
|
assert len(c) == 0
|
|
|
|
|
|
def test_per_entry_ttl_override():
|
|
clock = [0.0]
|
|
c = TTLCache(10, default_ttl=100, clock=lambda: clock[0])
|
|
c.set("short", 1, ttl=2)
|
|
c.set("long", 2)
|
|
clock[0] = 3
|
|
assert "short" not in c
|
|
assert c.get("long") == 2
|
|
|
|
|
|
def test_peek_does_not_update_recency():
|
|
c = TTLCache(2)
|
|
c.set("a", 1)
|
|
c.set("b", 2)
|
|
c.peek("a")
|
|
c.set("c", 3)
|
|
# a was not touched via get, so it should be evicted (b was more recent? actually b inserted last)
|
|
# After set a,b: order a,b. peek a no change. set c evicts LRU = a.
|
|
assert "a" not in c
|
|
|
|
|
|
def test_get_strict_raises():
|
|
c = TTLCache(2)
|
|
with pytest.raises(CacheMiss):
|
|
c.get_strict("nope")
|
|
|
|
|
|
def test_invalid_args():
|
|
with pytest.raises(ValueError):
|
|
TTLCache(0)
|
|
with pytest.raises(ValueError):
|
|
TTLCache(2, default_ttl=0)
|
|
c = TTLCache(2)
|
|
with pytest.raises(ValueError):
|
|
c.set("x", 1, ttl=0)
|
|
|
|
|
|
def test_delete_and_clear():
|
|
c = TTLCache(2)
|
|
c.set("a", 1)
|
|
assert c.delete("a") is True
|
|
assert c.delete("a") is False
|
|
c.set("b", 2)
|
|
c.clear()
|
|
assert len(c) == 0
|
|
|
|
|
|
def test_capacity_eviction_with_expired():
|
|
clock = [0.0]
|
|
c = TTLCache(2, clock=lambda: clock[0])
|
|
c.set("a", 1, ttl=1)
|
|
c.set("b", 2, ttl=1)
|
|
clock[0] = 2 # both expired
|
|
c.set("c", 3) # should not count expired toward capacity
|
|
assert len(c) == 1
|
|
assert c.get("c") == 3
|