2023-09-23 01:27:30 +01:00
|
|
|
package cache
|
|
|
|
|
|
|
|
import (
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
|
|
"testing"
|
|
|
|
"time"
|
|
|
|
)
|
|
|
|
|
2023-09-24 12:11:49 +01:00
|
|
|
var nextYear = time.Now().Year() + 1
|
|
|
|
|
2023-09-23 01:27:30 +01:00
|
|
|
func TestItem_HasExpired(t *testing.T) {
|
|
|
|
n := time.Now()
|
2023-09-24 12:11:49 +01:00
|
|
|
|
|
|
|
// date before now is expired
|
2023-09-23 01:27:30 +01:00
|
|
|
a := item[string]{expires: n}
|
|
|
|
timeNow = func() time.Time { return n.Add(time.Second) }
|
|
|
|
assert.True(t, a.HasExpired())
|
2023-09-24 12:11:49 +01:00
|
|
|
|
|
|
|
// date after now is valid
|
2023-09-23 01:27:30 +01:00
|
|
|
a = item[string]{expires: n.Add(time.Second * 2)}
|
|
|
|
assert.False(t, a.HasExpired())
|
2023-09-24 12:11:49 +01:00
|
|
|
|
|
|
|
// empty date is always valid
|
|
|
|
a = item[string]{}
|
|
|
|
assert.False(t, a.HasExpired())
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestCache_GetExpires(t *testing.T) {
|
|
|
|
c := New[string, string]()
|
|
|
|
c.items.Store("a", &item[string]{
|
|
|
|
data: "b",
|
|
|
|
expires: time.Date(nextYear, time.January, 1, 0, 0, 0, 0, time.UTC),
|
|
|
|
})
|
|
|
|
v, exp, found := c.GetExpires("a")
|
|
|
|
assert.Equal(t, "b", v)
|
|
|
|
assert.Equal(t, time.Date(nextYear, time.January, 1, 0, 0, 0, 0, time.UTC), exp)
|
|
|
|
assert.True(t, found)
|
|
|
|
|
|
|
|
v, exp, found = c.GetExpires("b")
|
|
|
|
assert.Equal(t, "", v)
|
|
|
|
assert.Equal(t, time.Time{}, exp)
|
|
|
|
assert.False(t, found)
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestCache_Get(t *testing.T) {
|
|
|
|
c := New[string, string]()
|
|
|
|
c.items.Store("a", &item[string]{
|
|
|
|
data: "b",
|
|
|
|
expires: time.Date(nextYear, time.January, 1, 0, 0, 0, 0, time.UTC),
|
|
|
|
})
|
|
|
|
v, found := c.Get("a")
|
|
|
|
assert.Equal(t, "b", v)
|
|
|
|
assert.True(t, found)
|
|
|
|
|
|
|
|
v, found = c.Get("b")
|
|
|
|
assert.Equal(t, "", v)
|
|
|
|
assert.False(t, found)
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestCache_SetPermanent(t *testing.T) {
|
|
|
|
c := New[string, string]()
|
|
|
|
c.SetPermanent("a", "b")
|
|
|
|
|
|
|
|
value, ok := c.items.Load("a")
|
|
|
|
v := value.(*item[string])
|
|
|
|
assert.Equal(t, item[string]{data: "b"}, *v)
|
|
|
|
assert.True(t, ok)
|
|
|
|
|
|
|
|
value, ok = c.items.Load("b")
|
|
|
|
assert.False(t, ok)
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestCache_Set(t *testing.T) {
|
|
|
|
c := New[string, string]()
|
|
|
|
c.Set("a", "b", time.Date(nextYear, time.January, 1, 0, 0, 0, 0, time.UTC))
|
|
|
|
|
|
|
|
value, ok := c.items.Load("a")
|
|
|
|
v := value.(*item[string])
|
|
|
|
assert.Equal(t, item[string]{
|
|
|
|
data: "b",
|
|
|
|
expires: time.Date(nextYear, time.January, 1, 0, 0, 0, 0, time.UTC),
|
|
|
|
}, *v)
|
|
|
|
assert.True(t, ok)
|
|
|
|
|
|
|
|
value, ok = c.items.Load("b")
|
|
|
|
assert.False(t, ok)
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestCache_Delete(t *testing.T) {
|
|
|
|
c := New[string, string]()
|
|
|
|
c.items.Store("a", &item[string]{data: "b", expires: time.Date(nextYear, time.January, 1, 0, 0, 0, 0, time.UTC)})
|
|
|
|
c.chain = &keyed[string]{item: item[string]{data: "a", expires: time.Date(nextYear, time.January, 1, 0, 0, 0, 0, time.UTC)}}
|
|
|
|
c.Delete("a")
|
|
|
|
|
|
|
|
// scheduler should finish after deleting the item
|
2024-12-19 23:23:20 +00:00
|
|
|
time.Sleep(time.Second)
|
2023-09-24 12:11:49 +01:00
|
|
|
assert.Nil(t, c.chain)
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestCache_Range(t *testing.T) {
|
|
|
|
c := New[string, string]()
|
|
|
|
c.items.Store("a", &item[string]{data: "b"})
|
|
|
|
c.items.Store("b", &item[string]{data: "c"})
|
|
|
|
c.items.Store("c", &item[string]{data: "d"})
|
|
|
|
c.items.Store("d", &item[string]{data: "e"})
|
|
|
|
c.Range(func(key string, value string) bool {
|
|
|
|
assert.Equal(t, string([]byte{[]byte(key)[0] + 1}), value)
|
|
|
|
return true
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestCache_Cleaner(t *testing.T) {
|
|
|
|
timeNow = func() time.Time { return time.Now() }
|
|
|
|
|
|
|
|
n := time.Now().Add(2 * time.Second)
|
|
|
|
c := New[string, string]()
|
|
|
|
c.Set("a", "b", n)
|
|
|
|
|
|
|
|
// check before expiry
|
|
|
|
time.Sleep(time.Second)
|
|
|
|
get, b := c.Get("a")
|
|
|
|
assert.True(t, b)
|
|
|
|
assert.Equal(t, "b", get)
|
|
|
|
|
|
|
|
// check after expiry
|
|
|
|
time.Sleep(1001 * time.Millisecond)
|
|
|
|
get, b = c.Get("a")
|
|
|
|
assert.False(t, b)
|
|
|
|
assert.Equal(t, "", get)
|
|
|
|
|
|
|
|
// scheduler should finish after the chain is empty
|
2024-12-19 23:23:20 +00:00
|
|
|
time.Sleep(time.Second)
|
2023-09-24 12:11:49 +01:00
|
|
|
assert.Nil(t, c.chain)
|
2023-09-23 01:27:30 +01:00
|
|
|
}
|
2024-10-20 22:20:45 +01:00
|
|
|
|
|
|
|
func TestCache_UpdateExpiry(t *testing.T) {
|
|
|
|
timeNow = func() time.Time { return time.Now() }
|
|
|
|
|
|
|
|
c := New[string, string]()
|
|
|
|
c.Set("a", "b", time.Now().Add(2*time.Second))
|
|
|
|
|
|
|
|
time.Sleep(time.Second)
|
|
|
|
get, b := c.Get("a")
|
|
|
|
assert.True(t, b)
|
|
|
|
assert.Equal(t, "b", get)
|
|
|
|
|
|
|
|
c.Set("a", "b", time.Now().Add(5*time.Second))
|
|
|
|
|
|
|
|
// after expiry of the first set call
|
|
|
|
time.Sleep(2 * time.Second)
|
|
|
|
get, b = c.Get("a")
|
|
|
|
assert.True(t, b)
|
|
|
|
assert.Equal(t, "b", get)
|
|
|
|
}
|