lrucache_test.go 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. package lru
  2. import (
  3. "testing"
  4. "time"
  5. "github.com/stretchr/testify/assert"
  6. )
  7. var entries = []struct {
  8. key string
  9. value string
  10. }{
  11. {"1", "one"},
  12. {"2", "two"},
  13. {"3", "three"},
  14. {"4", "four"},
  15. {"5", "five"},
  16. }
  17. func TestLRUCache(t *testing.T) {
  18. c := New[string, string]()
  19. for _, e := range entries {
  20. c.Set(e.key, e.value)
  21. }
  22. c.Delete("missing")
  23. _, ok := c.Get("missing")
  24. assert.False(t, ok)
  25. for _, e := range entries {
  26. value, ok := c.Get(e.key)
  27. if assert.True(t, ok) {
  28. assert.Equal(t, e.value, value)
  29. }
  30. }
  31. for _, e := range entries {
  32. c.Delete(e.key)
  33. _, ok := c.Get(e.key)
  34. assert.False(t, ok)
  35. }
  36. }
  37. func TestLRUMaxAge(t *testing.T) {
  38. c := New[string, string](WithAge[string, string](86400))
  39. now := time.Now().Unix()
  40. expected := now + 86400
  41. // Add one expired entry
  42. c.Set("foo", "bar")
  43. c.lru.Back().Value.expires = now
  44. // Reset
  45. c.Set("foo", "bar")
  46. e := c.lru.Back().Value
  47. assert.True(t, e.expires >= now)
  48. c.lru.Back().Value.expires = now
  49. // Set a few and verify expiration times
  50. for _, s := range entries {
  51. c.Set(s.key, s.value)
  52. e := c.lru.Back().Value
  53. assert.True(t, e.expires >= expected && e.expires <= expected+10)
  54. }
  55. // Make sure we can get them all
  56. for _, s := range entries {
  57. _, ok := c.Get(s.key)
  58. assert.True(t, ok)
  59. }
  60. // Expire all entries
  61. for _, s := range entries {
  62. le, ok := c.cache[s.key]
  63. if assert.True(t, ok) {
  64. le.Value.expires = now
  65. }
  66. }
  67. // Get one expired entry, which should clear all expired entries
  68. _, ok := c.Get("3")
  69. assert.False(t, ok)
  70. assert.Equal(t, c.lru.Len(), 0)
  71. }
  72. func TestLRUpdateOnGet(t *testing.T) {
  73. c := New[string, string](WithAge[string, string](86400), WithUpdateAgeOnGet[string, string]())
  74. now := time.Now().Unix()
  75. expires := now + 86400/2
  76. // Add one expired entry
  77. c.Set("foo", "bar")
  78. c.lru.Back().Value.expires = expires
  79. _, ok := c.Get("foo")
  80. assert.True(t, ok)
  81. assert.True(t, c.lru.Back().Value.expires > expires)
  82. }
  83. func TestMaxSize(t *testing.T) {
  84. c := New[string, string](WithSize[string, string](2))
  85. // Add one expired entry
  86. c.Set("foo", "bar")
  87. _, ok := c.Get("foo")
  88. assert.True(t, ok)
  89. c.Set("bar", "foo")
  90. c.Set("baz", "foo")
  91. _, ok = c.Get("foo")
  92. assert.False(t, ok)
  93. }
  94. func TestExist(t *testing.T) {
  95. c := New[int, int](WithSize[int, int](1))
  96. c.Set(1, 2)
  97. assert.True(t, c.Exist(1))
  98. c.Set(2, 3)
  99. assert.False(t, c.Exist(1))
  100. }
  101. func TestEvict(t *testing.T) {
  102. temp := 0
  103. evict := func(key int, value int) {
  104. temp = key + value
  105. }
  106. c := New[int, int](WithEvict[int, int](evict), WithSize[int, int](1))
  107. c.Set(1, 2)
  108. c.Set(2, 3)
  109. assert.Equal(t, temp, 3)
  110. }
  111. func TestSetWithExpire(t *testing.T) {
  112. c := New[int, *struct{}](WithAge[int, *struct{}](1))
  113. now := time.Now().Unix()
  114. tenSecBefore := time.Unix(now-10, 0)
  115. c.SetWithExpire(1, &struct{}{}, tenSecBefore)
  116. // res is expected not to exist, and expires should be empty time.Time
  117. res, expires, exist := c.GetWithExpire(1)
  118. assert.True(t, nil == res)
  119. assert.Equal(t, time.Time{}, expires)
  120. assert.Equal(t, false, exist)
  121. }
  122. func TestStale(t *testing.T) {
  123. c := New[int, int](WithAge[int, int](1), WithStale[int, int](true))
  124. now := time.Now().Unix()
  125. tenSecBefore := time.Unix(now-10, 0)
  126. c.SetWithExpire(1, 2, tenSecBefore)
  127. res, expires, exist := c.GetWithExpire(1)
  128. assert.Equal(t, 2, res)
  129. assert.Equal(t, tenSecBefore, expires)
  130. assert.Equal(t, true, exist)
  131. }
  132. func TestCloneTo(t *testing.T) {
  133. o := New[string, int](WithSize[string, int](10))
  134. o.Set("1", 1)
  135. o.Set("2", 2)
  136. n := New[string, int](WithSize[string, int](2))
  137. n.Set("3", 3)
  138. n.Set("4", 4)
  139. o.CloneTo(n)
  140. assert.False(t, n.Exist("3"))
  141. assert.True(t, n.Exist("1"))
  142. n.Set("5", 5)
  143. assert.False(t, n.Exist("1"))
  144. }