Skip to content

Commit

Permalink
test: rework unit tests to isolate mocks and add missing cases
Browse files Browse the repository at this point in the history
  • Loading branch information
eko committed Oct 20, 2019
1 parent 9de424d commit 19c7bf8
Show file tree
Hide file tree
Showing 19 changed files with 535 additions and 116 deletions.
10 changes: 4 additions & 6 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,7 @@ mocks:
mockery -case=snake -name=SetterCacheInterface -dir=cache/ -output test/mocks/cache/
mockery -case=snake -name=MetricsInterface -dir=metrics/ -output test/mocks/metrics/
mockery -case=snake -name=StoreInterface -dir=store/ -output test/mocks/store/

# in package store clients mocks
mockery -case=snake -inpkg -name=BigcacheClientInterface -dir=store/ -output store/
mockery -case=snake -inpkg -name=MemcacheClientInterface -dir=store/ -output store/
mockery -case=snake -inpkg -name=RedisClientInterface -dir=store/ -output store/
mockery -case=snake -inpkg -name=RistrettoClientInterface -dir=store/ -output store/
mockery -case=snake -name=BigcacheClientInterface -dir=store/ -output test/mocks/store/clients/
mockery -case=snake -name=MemcacheClientInterface -dir=store/ -output test/mocks/store/clients/
mockery -case=snake -name=RedisClientInterface -dir=store/ -output test/mocks/store/clients/
mockery -case=snake -name=RistrettoClientInterface -dir=store/ -output test/mocks/store/clients/
13 changes: 13 additions & 0 deletions cache/cache.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package cache

import (
"crypto"
"fmt"
"reflect"
"strings"

"github.com/eko/gocache/codec"
Expand Down Expand Up @@ -62,3 +65,13 @@ func (c *Cache) GetType() string {
func (c *Cache) getCacheKey(key interface{}) string {
return strings.ToLower(checksum(key))
}

// checksum hashes a given object into a string
func checksum(object interface{}) string {
digester := crypto.MD5.New()
fmt.Fprint(digester, reflect.TypeOf(object))
fmt.Fprint(digester, object)
hash := digester.Sum(nil)

return fmt.Sprintf("%x", hash)
}
10 changes: 2 additions & 8 deletions cache/chain.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,20 +76,14 @@ func (c *ChainCache) Invalidate(options store.InvalidateOptions) error {
}

// setUntil sets a value in available caches, eventually until a given cache layer
func (c *ChainCache) setUntil(key, object interface{}, until *string) error {
func (c *ChainCache) setUntil(key, object interface{}, until *string) {
for _, cache := range c.caches {
if until != nil && *until == cache.GetCodec().GetStore().GetType() {
break
}

err := cache.Set(key, object, nil)
if err != nil {
storeType := cache.GetCodec().GetStore().GetType()
return fmt.Errorf("Unable to set item into cache with store '%s': %v", storeType, err)
}
cache.Set(key, object, nil)
}

return nil
}

// GetCaches returns all Chaind caches
Expand Down
120 changes: 120 additions & 0 deletions cache/chain_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package cache

import (
"errors"
"fmt"
"testing"

"github.com/eko/gocache/store"
Expand Down Expand Up @@ -118,6 +119,105 @@ func TestChainGetWhenAvailableInSecondCache(t *testing.T) {
assert.Equal(t, cacheValue, value)
}

func TestChainGetWhenNotAvailableInAnyCache(t *testing.T) {
// Given
// Cache 1
store1 := &mocksStore.StoreInterface{}
store1.On("GetType").Return("store1")

codec1 := &mocksCodec.CodecInterface{}
codec1.On("GetStore").Return(store1)

cache1 := &mocksCache.SetterCacheInterface{}
cache1.On("GetCodec").Return(codec1)
cache1.On("Get", "my-key").Return(nil, errors.New("Unable to find in cache 1"))

// Cache 2
store2 := &mocksStore.StoreInterface{}
store2.On("GetType").Return("store2")

codec2 := &mocksCodec.CodecInterface{}
codec2.On("GetStore").Return(store2)

cache2 := &mocksCache.SetterCacheInterface{}
cache2.On("GetCodec").Return(codec2)
cache2.On("Get", "my-key").Return(nil, errors.New("Unable to find in cache 2"))
cache2.AssertNotCalled(t, "Set")

cache := NewChain(cache1, cache2)

// When
value, err := cache.Get("my-key")

// Then
assert.Equal(t, errors.New("Unable to find in cache 2"), err)
assert.Equal(t, nil, value)
}

func TestChainSet(t *testing.T) {
// Given
cacheValue := &struct {
Hello string
}{
Hello: "world",
}

options := &store.Options{}

// Cache 1
cache1 := &mocksCache.SetterCacheInterface{}
cache1.On("Set", "my-key", cacheValue, options).Return(nil)

// Cache 2
cache2 := &mocksCache.SetterCacheInterface{}
cache2.On("Set", "my-key", cacheValue, options).Return(nil)

cache := NewChain(cache1, cache2)

// When
err := cache.Set("my-key", cacheValue, options)

// Then
assert.Nil(t, err)
}

func TestChainSetWhenErrorOnSetting(t *testing.T) {
// Given
cacheValue := &struct {
Hello string
}{
Hello: "world",
}

options := &store.Options{}

expectedErr := errors.New("An unexpected error occurred while setting data")

// Cache 1
store1 := &mocksStore.StoreInterface{}
store1.On("GetType").Return("store1")

codec1 := &mocksCodec.CodecInterface{}
codec1.On("GetStore").Return(store1)

cache1 := &mocksCache.SetterCacheInterface{}
cache1.On("GetCodec").Return(codec1)
cache1.On("Set", "my-key", cacheValue, options).Return(expectedErr)

// Cache 2
cache2 := &mocksCache.SetterCacheInterface{}
cache2.AssertNotCalled(t, "Set")

cache := NewChain(cache1, cache2)

// When
err := cache.Set("my-key", cacheValue, options)

// Then
assert.Error(t, err)
assert.Equal(t, err.Error(), fmt.Sprintf("Unable to set item into cache with store 'store1': %s", expectedErr.Error()))
}

func TestChainDelete(t *testing.T) {
// Given
// Cache 1
Expand Down Expand Up @@ -211,3 +311,23 @@ func TestChainGetType(t *testing.T) {
// When - Then
assert.Equal(t, ChainType, cache.GetType())
}

func TestCacheChecksum(t *testing.T) {
testCases := []struct {
value interface{}
expectedHash string
}{
{value: 273273623, expectedHash: "a187c153af38575778244cb3796536da"},
{value: "hello-world", expectedHash: "f31215be6928a6f6e0c7c1cf2c68054e"},
{value: []byte(`hello-world`), expectedHash: "f097ebac995e666eb074e019cd39d99b"},
{value: struct{ Label string }{}, expectedHash: "2938da2beee350d6ea988e404109f428"},
{value: struct{ Label string }{Label: "hello-world"}, expectedHash: "4119a1c8530a0420859f1c6ecf2dc0b7"},
{value: struct{ Label string }{Label: "hello-everyone"}, expectedHash: "1d7e7ed4acd56d2635f7cb33aa702bdd"},
}

for _, tc := range testCases {
value := checksum(tc.value)

assert.Equal(t, tc.expectedHash, value)
}
}
17 changes: 0 additions & 17 deletions cache/common.go

This file was deleted.

27 changes: 0 additions & 27 deletions cache/common_test.go

This file was deleted.

25 changes: 25 additions & 0 deletions cache/loadable_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,31 @@ func TestNewLoadable(t *testing.T) {
assert.Equal(t, cache1, cache.cache)
}

func TestLoadableGetWhenAlreadyInCache(t *testing.T) {
// Given
cacheValue := &struct {
Hello string
}{
Hello: "world",
}

cache1 := &mocksCache.SetterCacheInterface{}
cache1.On("Get", "my-key").Return(cacheValue, nil)

loadFunc := func(key interface{}) (interface{}, error) {
return nil, errors.New("Should not be called")
}

cache := NewLoadable(loadFunc, cache1)

// When
value, err := cache.Get("my-key")

// Then
assert.Nil(t, err)
assert.Equal(t, cacheValue, value)
}

func TestLoadableGetWhenNotAvailableInLoadFunc(t *testing.T) {
// Given
// Cache
Expand Down
27 changes: 27 additions & 0 deletions cache/metric_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package cache
import (
"errors"
"testing"
"time"

"github.com/eko/gocache/store"
mocksCache "github.com/eko/gocache/test/mocks/cache"
Expand Down Expand Up @@ -86,6 +87,32 @@ func TestMetricGetWhenChainCache(t *testing.T) {
assert.Equal(t, cacheValue, value)
}

func TestMetricSet(t *testing.T) {
// Given
value := &struct {
Hello string
}{
Hello: "world",
}

options := &store.Options{
Expiration: 5 * time.Second,
}

cache1 := &mocksCache.SetterCacheInterface{}
cache1.On("Set", "my-key", value, options).Return(nil)

metrics := &mocksMetrics.MetricsInterface{}

cache := NewMetric(metrics, cache1)

// When
err := cache.Set("my-key", value, options)

// Then
assert.Nil(t, err)
}

func TestMetricDelete(t *testing.T) {
// Given
cache1 := &mocksCache.SetterCacheInterface{}
Expand Down
3 changes: 3 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@ go 1.13
require (
github.com/allegro/bigcache v1.2.1
github.com/bradfitz/gomemcache v0.0.0-20190913173617-a41fca850d0b
github.com/coreos/etcd v3.3.17+incompatible
github.com/dgraph-io/ristretto v0.0.0-20191010170704-2ba187ef9534
github.com/go-redis/redis/v7 v7.0.0-beta.4
github.com/jonboulle/clockwork v0.1.0 // indirect
github.com/kr/pretty v0.1.0 // indirect
github.com/prometheus/client_golang v1.1.0
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90
Expand Down
7 changes: 7 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,14 @@ github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
github.com/bradfitz/gomemcache v0.0.0-20190913173617-a41fca850d0b h1:L/QXpzIa3pOvUGt1D1lA5KjYhPBAN/3iWdP7xeFS9F0=
github.com/bradfitz/gomemcache v0.0.0-20190913173617-a41fca850d0b/go.mod h1:H0wQNHz2YrLsuXOZozoeDmnHXkNCRmMW0gwFWDfEZDA=
github.com/coreos/etcd v3.3.17+incompatible h1:f/Z3EoDSx1yjaIjLQGo1diYUlQYSBrrAQ5vP8NjwXwo=
github.com/coreos/etcd v3.3.17+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dgraph-io/ristretto v0.0.0-20191010170704-2ba187ef9534 h1:9G6fVccQriMJu4nXwpwLDoy9y31t/KUSLAbPcoBgv+4=
github.com/dgraph-io/ristretto v0.0.0-20191010170704-2ba187ef9534/go.mod h1:edzKIzGvqUCMzhTVWbiTSe75zD9Xxq0GtSBtFmaUTZs=
github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw=
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
Expand All @@ -30,6 +35,8 @@ github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/jonboulle/clockwork v0.1.0 h1:VKV+ZcuP6l3yW9doeqz6ziZGgcynBVQO+obU0+0hcPo=
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
Expand Down
22 changes: 22 additions & 0 deletions marshaler/marshaler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,28 @@ func TestSetWhenString(t *testing.T) {
assert.Nil(t, err)
}

func TestSetWhenError(t *testing.T) {
// Given
cacheValue := "test"

options := &store.Options{
Expiration: 5 * time.Second,
}

expectedErr := errors.New("An unexpected error occurred")

cache := &mocksCache.CacheInterface{}
cache.On("Set", "my-key", []byte{0xa4, 0x74, 0x65, 0x73, 0x74}, options).Return(expectedErr)

marshaler := New(cache)

// When
err := marshaler.Set("my-key", cacheValue, options)

// Then
assert.Equal(t, expectedErr, err)
}

func TestDelete(t *testing.T) {
// Given
cache := &mocksCache.CacheInterface{}
Expand Down
Loading

0 comments on commit 19c7bf8

Please sign in to comment.