79 lines
2.3 KiB
Python
79 lines
2.3 KiB
Python
import threading
|
|
import time
|
|
import unittest
|
|
|
|
from lru_ttl_cache import LRUTTLCache
|
|
|
|
|
|
class TestLRUTTLCache(unittest.TestCase):
|
|
def test_basic_put_get(self):
|
|
c = LRUTTLCache(maxsize=2, ttl=10)
|
|
c.put("a", 1)
|
|
self.assertEqual(c.get("a"), 1)
|
|
self.assertEqual(c.get("missing", "d"), "d")
|
|
|
|
def test_lru_eviction(self):
|
|
c = LRUTTLCache(maxsize=2, ttl=10)
|
|
c.put("a", 1); c.put("b", 2)
|
|
c.get("a") # refresh a
|
|
c.put("c", 3) # evicts b
|
|
self.assertEqual(c.get("b", None), None)
|
|
self.assertEqual(c.get("a"), 1)
|
|
self.assertEqual(c.get("c"), 3)
|
|
|
|
def test_ttl_expiry(self):
|
|
clock = {"t": 0.0}
|
|
c = LRUTTLCache(maxsize=4, ttl=5, clock=lambda: clock["t"])
|
|
c.put("a", 1)
|
|
self.assertTrue(c.contains("a"))
|
|
clock["t"] = 6.0
|
|
self.assertFalse(c.contains("a"))
|
|
self.assertEqual(c.get("a", "x"), "x")
|
|
|
|
def test_put_overwrite_resets_ttl(self):
|
|
clock = {"t": 0.0}
|
|
c = LRUTTLCache(maxsize=4, ttl=5, clock=lambda: clock["t"])
|
|
c.put("a", 1)
|
|
clock["t"] = 4.0
|
|
c.put("a", 2) # reset ttl: now expires at 9
|
|
clock["t"] = 8.0
|
|
self.assertEqual(c.get("a"), 2)
|
|
clock["t"] = 10.0
|
|
self.assertEqual(c.get("a", "x"), "x")
|
|
|
|
def test_stats(self):
|
|
c = LRUTTLCache(maxsize=2, ttl=10)
|
|
c.put("a", 1); c.put("b", 2)
|
|
c.get("a"); c.get("zzz")
|
|
s = c.stats
|
|
self.assertEqual(s["hits"], 1)
|
|
self.assertEqual(s["misses"], 1)
|
|
self.assertEqual(s["size"], 2)
|
|
|
|
def test_thread_safety(self):
|
|
c = LRUTTLCache(maxsize=100, ttl=100)
|
|
errs = []
|
|
|
|
def w(i):
|
|
try:
|
|
for j in range(50):
|
|
c.put((i, j), i * j)
|
|
c.get((i, j))
|
|
except Exception as e: # noqa
|
|
errs.append(e)
|
|
|
|
ts = [threading.Thread(target=w, args=(i,)) for i in range(8)]
|
|
for t in ts: t.start()
|
|
for t in ts: t.join()
|
|
self.assertFalse(errs)
|
|
|
|
def test_validation(self):
|
|
with self.assertRaises(ValueError):
|
|
LRUTTLCache(maxsize=0, ttl=1)
|
|
with self.assertRaises(ValueError):
|
|
LRUTTLCache(maxsize=1, ttl=0)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|