Skip to content

Commit

Permalink
Test contentcache
Browse files Browse the repository at this point in the history
  • Loading branch information
toshinari123 committed Feb 5, 2024
1 parent 85e9e7a commit 9c1086c
Showing 1 changed file with 90 additions and 37 deletions.
127 changes: 90 additions & 37 deletions internal/cache/contentcache_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,95 +6,148 @@ import (
"sync"
"time"
"fmt"
"io"

"github.com/stretchr/testify/assert"
)

type CacheKeyMock string

func TestGetContent(t *testing.T) {
fmt.Println("testing GetContent...")
cc, err := NewContentCache(8, true)
load := func(r io.ReadSeeker) (*bytes.Buffer, int64, error) {
b, err := io.ReadAll(r)
nb := bytes.NewBuffer(b)
if err != nil {
return nb, 0, err
}
return nb, int64(nb.Len()), nil
}
cc, err := NewContentCache[CacheKeyMock](8, true, load)
assert.Empty(t, err)
assert.Equal(t, uint64(0), cc.cache.Metrics.CostAdded())
assert.Equal(t, uint64(0), cc.cache.Metrics.CostEvicted())
assert.Equal(t, uint64(0), cc.cache.Metrics.KeysAdded())
assert.Equal(t, uint64(0), cc.cache.Metrics.KeysEvicted())
assert.Equal(t, uint64(0), cc.cache.Metrics.KeysUpdated())

ccc, err := cc.GetContent("id1", bytes.NewReader([]byte("a")))
k1 := CacheKeyMock("id1")
k2 := CacheKeyMock("id2")
k3 := CacheKeyMock("id3")

ccc, found := cc.GetContent(k1)
assert.Equal(t, false, found)
assert.Equal(t, "hit: 0 miss: 1 keys-added: 0 keys-updated: 0 keys-evicted: 0 cost-added: 0 cost-evicted: 0 sets-dropped: 0 sets-rejected: 0 gets-dropped: 0 gets-kept: 0 gets-total: 1 hit-ratio: 0.00", cc.cache.Metrics.String())

ccc, err = cc.SetContent(k1, bytes.NewReader([]byte("a")))
time.Sleep(100 * time.Millisecond) //https://github.com/dgraph-io/ristretto/issues/161
assert.Empty(t, err)
assert.Equal(t, ContentCacheCell{id: "id1", Data: bytes.NewBuffer([]byte("a"))}, ccc)
assert.Equal(t, bytes.NewBuffer([]byte("a")), ccc)
assert.Equal(t, "hit: 0 miss: 1 keys-added: 1 keys-updated: 0 keys-evicted: 0 cost-added: 1 cost-evicted: 0 sets-dropped: 0 sets-rejected: 0 gets-dropped: 0 gets-kept: 0 gets-total: 1 hit-ratio: 0.00", cc.cache.Metrics.String())

ccc, err = cc.GetContent("id1", bytes.NewReader([]byte("a")))
time.Sleep(100 * time.Millisecond)
assert.Empty(t, err)
assert.Equal(t, ContentCacheCell{id: "id1", Data: bytes.NewBuffer([]byte("a"))}, ccc)
ccc, found = cc.GetContent(k1)
assert.Equal(t, true, found)
assert.Equal(t, bytes.NewBuffer([]byte("a")), ccc)
assert.Equal(t, "hit: 1 miss: 1 keys-added: 1 keys-updated: 0 keys-evicted: 0 cost-added: 1 cost-evicted: 0 sets-dropped: 0 sets-rejected: 0 gets-dropped: 0 gets-kept: 0 gets-total: 2 hit-ratio: 0.50", cc.cache.Metrics.String())

ccc, err = cc.GetContent("id2", bytes.NewReader([]byte("test")))
ccc, err = cc.SetContent(k1, bytes.NewReader([]byte("test")))
time.Sleep(100 * time.Millisecond)
assert.Empty(t, err)
assert.Equal(t, ContentCacheCell{id: "id2", Data: bytes.NewBuffer([]byte("test"))}, ccc)
assert.Equal(t, "hit: 1 miss: 2 keys-added: 2 keys-updated: 0 keys-evicted: 0 cost-added: 5 cost-evicted: 0 sets-dropped: 0 sets-rejected: 0 gets-dropped: 0 gets-kept: 0 gets-total: 3 hit-ratio: 0.33", cc.cache.Metrics.String())
assert.Equal(t, bytes.NewBuffer([]byte("test")), ccc)
assert.Equal(t, "hit: 1 miss: 1 keys-added: 1 keys-updated: 1 keys-evicted: 0 cost-added: 4 cost-evicted: 0 sets-dropped: 0 sets-rejected: 0 gets-dropped: 0 gets-kept: 0 gets-total: 2 hit-ratio: 0.50", cc.cache.Metrics.String())

//below should not happen as hash is used as id
ccc, err = cc.GetContent("id2", bytes.NewReader([]byte("update")))
time.Sleep(100 * time.Millisecond)
assert.Empty(t, err)
assert.Equal(t, ContentCacheCell{id: "id2", Data: bytes.NewBuffer([]byte("test"))}, ccc)
assert.Equal(t, "hit: 2 miss: 2 keys-added: 2 keys-updated: 0 keys-evicted: 0 cost-added: 5 cost-evicted: 0 sets-dropped: 0 sets-rejected: 0 gets-dropped: 0 gets-kept: 0 gets-total: 4 hit-ratio: 0.50", cc.cache.Metrics.String())
ccc, found = cc.GetContent(k1)
assert.Equal(t, true, found)
assert.Equal(t, bytes.NewBuffer([]byte("test")), ccc)
assert.Equal(t, "hit: 2 miss: 1 keys-added: 1 keys-updated: 1 keys-evicted: 0 cost-added: 4 cost-evicted: 0 sets-dropped: 0 sets-rejected: 0 gets-dropped: 0 gets-kept: 0 gets-total: 3 hit-ratio: 0.67", cc.cache.Metrics.String())

ccc, err = cc.GetContent("id3", bytes.NewReader([]byte("overflow")))
ccc, err = cc.SetContent(k2, bytes.NewReader([]byte("overflow")))
time.Sleep(100 * time.Millisecond)
assert.Empty(t, err)
assert.Equal(t, ContentCacheCell{id: "id3", Data: bytes.NewBuffer([]byte("overflow"))}, ccc)
assert.Equal(t, "hit: 2 miss: 3 keys-added: 3 keys-updated: 0 keys-evicted: 2 cost-added: 13 cost-evicted: 5 sets-dropped: 0 sets-rejected: 0 gets-dropped: 0 gets-kept: 0 gets-total: 5 hit-ratio: 0.40", cc.cache.Metrics.String())
assert.Equal(t, bytes.NewBuffer([]byte("overflow")), ccc)
assert.Equal(t, "hit: 2 miss: 1 keys-added: 2 keys-updated: 1 keys-evicted: 1 cost-added: 12 cost-evicted: 4 sets-dropped: 0 sets-rejected: 0 gets-dropped: 0 gets-kept: 0 gets-total: 3 hit-ratio: 0.67", cc.cache.Metrics.String())

//below should not happen as content size is checked before putting in cache
ccc, err = cc.GetContent("id4", bytes.NewReader([]byte("content too big")))
ccc, found = cc.GetContent(k2)
assert.Equal(t, true, found)
assert.Equal(t, bytes.NewBuffer([]byte("overflow")), ccc)
assert.Equal(t, "hit: 3 miss: 1 keys-added: 2 keys-updated: 1 keys-evicted: 1 cost-added: 12 cost-evicted: 4 sets-dropped: 0 sets-rejected: 0 gets-dropped: 0 gets-kept: 0 gets-total: 4 hit-ratio: 0.75", cc.cache.Metrics.String())

ccc, err = cc.SetContent(k3, bytes.NewReader([]byte("content too big")))
time.Sleep(100 * time.Millisecond)
assert.Empty(t, err)
assert.Equal(t, ContentCacheCell{id: "id4", Data: bytes.NewBuffer([]byte("content too big"))}, ccc)
assert.Equal(t, "hit: 2 miss: 4 keys-added: 3 keys-updated: 0 keys-evicted: 2 cost-added: 13 cost-evicted: 5 sets-dropped: 0 sets-rejected: 0 gets-dropped: 0 gets-kept: 0 gets-total: 6 hit-ratio: 0.33", cc.cache.Metrics.String())
assert.Equal(t, bytes.NewBuffer([]byte("content too big")), ccc)
assert.Equal(t, "hit: 3 miss: 1 keys-added: 2 keys-updated: 1 keys-evicted: 1 cost-added: 12 cost-evicted: 4 sets-dropped: 0 sets-rejected: 0 gets-dropped: 0 gets-kept: 0 gets-total: 4 hit-ratio: 0.75", cc.cache.Metrics.String())

ccc, found = cc.GetContent(k3)
assert.Equal(t, false, found)
assert.Equal(t, "hit: 3 miss: 2 keys-added: 2 keys-updated: 1 keys-evicted: 1 cost-added: 12 cost-evicted: 4 sets-dropped: 0 sets-rejected: 0 gets-dropped: 0 gets-kept: 0 gets-total: 5 hit-ratio: 0.60", cc.cache.Metrics.String())
}

func TestDataRace(t *testing.T) {
fmt.Println("testing data race...")
var wg sync.WaitGroup
cc, err := NewContentCache(8, true)
load := func(r io.ReadSeeker) (*bytes.Buffer, int64, error) {
b, err := io.ReadAll(r)
nb := bytes.NewBuffer(b)
if err != nil {
return nb, 0, err
}
return nb, int64(nb.Len()), nil
}
cc, err := NewContentCache[CacheKeyMock](16, true, load)
assert.Empty(t, err)
k1 := CacheKeyMock("id1")
k2 := CacheKeyMock("id2")
wg.Add(1)
go func() {
defer wg.Done()
_, err := cc.GetContent("id1", bytes.NewReader([]byte("data")))
_, err := cc.SetContent(k1, bytes.NewReader([]byte("data")))
time.Sleep(100 * time.Millisecond)
assert.Empty(t, err)
_, err = cc.GetContent("id2", bytes.NewReader([]byte("race")))
_, err = cc.SetContent(k2, bytes.NewReader([]byte("race")))
time.Sleep(100 * time.Millisecond)
assert.Empty(t, err)
_, found := cc.GetContent(k1)
assert.Equal(t, true, found)
_, found = cc.GetContent(k2)
assert.Equal(t, true, found)
}()
wg.Add(1)
go func() {
defer wg.Done()
_, err := cc.GetContent("id1", bytes.NewReader([]byte("race")))
_, err := cc.SetContent(k1, bytes.NewReader([]byte("race")))
time.Sleep(100 * time.Millisecond)
assert.Empty(t, err)
_, err = cc.GetContent("id2", bytes.NewReader([]byte("data")))
_, err = cc.SetContent(k2, bytes.NewReader([]byte("data")))
time.Sleep(100 * time.Millisecond)
assert.Empty(t, err)
_, found := cc.GetContent(k1)
assert.Equal(t, true, found)
_, found = cc.GetContent(k2)
assert.Equal(t, true, found)
}()
wg.Add(1)
go func() {
defer wg.Done()
_, err := cc.GetContent("id2", bytes.NewReader([]byte("data")))
_, err := cc.SetContent(k2, bytes.NewReader([]byte("data")))
time.Sleep(100 * time.Millisecond)
assert.Empty(t, err)
_, err = cc.GetContent("id1", bytes.NewReader([]byte("race")))
_, err = cc.SetContent(k1, bytes.NewReader([]byte("race")))
time.Sleep(100 * time.Millisecond)
assert.Empty(t, err)
_, found := cc.GetContent(k1)
assert.Equal(t, true, found)
_, found = cc.GetContent(k2)
assert.Equal(t, true, found)
}()
wg.Add(1)
go func() {
defer wg.Done()
_, err := cc.GetContent("id2", bytes.NewReader([]byte("race")))
_, err := cc.SetContent(k2, bytes.NewReader([]byte("race")))
time.Sleep(100 * time.Millisecond)
assert.Empty(t, err)
_, err = cc.GetContent("id1", bytes.NewReader([]byte("data")))
_, err = cc.SetContent(k1, bytes.NewReader([]byte("data")))
time.Sleep(100 * time.Millisecond)
assert.Empty(t, err)
_, found := cc.GetContent(k1)
assert.Equal(t, true, found)
_, found = cc.GetContent(k2)
assert.Equal(t, true, found)
}()
wg.Wait()
}

0 comments on commit 9c1086c

Please sign in to comment.