github.com/shuguocloud/go-zero@v1.3.0/core/stores/cache/cachenode_test.go (about)

     1  package cache
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"math/rand"
     7  	"strconv"
     8  	"sync"
     9  	"testing"
    10  	"time"
    11  
    12  	"github.com/alicebob/miniredis/v2"
    13  	"github.com/stretchr/testify/assert"
    14  	"github.com/shuguocloud/go-zero/core/logx"
    15  	"github.com/shuguocloud/go-zero/core/mathx"
    16  	"github.com/shuguocloud/go-zero/core/stat"
    17  	"github.com/shuguocloud/go-zero/core/stores/redis"
    18  	"github.com/shuguocloud/go-zero/core/stores/redis/redistest"
    19  	"github.com/shuguocloud/go-zero/core/syncx"
    20  )
    21  
    22  var errTestNotFound = errors.New("not found")
    23  
    24  func init() {
    25  	logx.Disable()
    26  	stat.SetReporter(nil)
    27  }
    28  
    29  func TestCacheNode_DelCache(t *testing.T) {
    30  	store, clean, err := redistest.CreateRedis()
    31  	assert.Nil(t, err)
    32  	store.Type = redis.ClusterType
    33  	defer clean()
    34  
    35  	cn := cacheNode{
    36  		rds:            store,
    37  		r:              rand.New(rand.NewSource(time.Now().UnixNano())),
    38  		lock:           new(sync.Mutex),
    39  		unstableExpiry: mathx.NewUnstable(expiryDeviation),
    40  		stat:           NewStat("any"),
    41  		errNotFound:    errTestNotFound,
    42  	}
    43  	assert.Nil(t, cn.Del())
    44  	assert.Nil(t, cn.Del([]string{}...))
    45  	assert.Nil(t, cn.Del(make([]string, 0)...))
    46  	cn.Set("first", "one")
    47  	assert.Nil(t, cn.Del("first"))
    48  	cn.Set("first", "one")
    49  	cn.Set("second", "two")
    50  	assert.Nil(t, cn.Del("first", "second"))
    51  }
    52  
    53  func TestCacheNode_DelCacheWithErrors(t *testing.T) {
    54  	store, clean, err := redistest.CreateRedis()
    55  	assert.Nil(t, err)
    56  	defer clean()
    57  	store.Type = redis.ClusterType
    58  
    59  	cn := cacheNode{
    60  		rds:            store,
    61  		r:              rand.New(rand.NewSource(time.Now().UnixNano())),
    62  		lock:           new(sync.Mutex),
    63  		unstableExpiry: mathx.NewUnstable(expiryDeviation),
    64  		stat:           NewStat("any"),
    65  		errNotFound:    errTestNotFound,
    66  	}
    67  	assert.Nil(t, cn.Del("third", "fourth"))
    68  }
    69  
    70  func TestCacheNode_InvalidCache(t *testing.T) {
    71  	s, err := miniredis.Run()
    72  	assert.Nil(t, err)
    73  	defer s.Close()
    74  
    75  	cn := cacheNode{
    76  		rds:            redis.New(s.Addr()),
    77  		r:              rand.New(rand.NewSource(time.Now().UnixNano())),
    78  		lock:           new(sync.Mutex),
    79  		unstableExpiry: mathx.NewUnstable(expiryDeviation),
    80  		stat:           NewStat("any"),
    81  		errNotFound:    errTestNotFound,
    82  	}
    83  	s.Set("any", "value")
    84  	var str string
    85  	assert.NotNil(t, cn.Get("any", &str))
    86  	assert.Equal(t, "", str)
    87  	_, err = s.Get("any")
    88  	assert.Equal(t, miniredis.ErrKeyNotFound, err)
    89  }
    90  
    91  func TestCacheNode_Take(t *testing.T) {
    92  	store, clean, err := redistest.CreateRedis()
    93  	assert.Nil(t, err)
    94  	defer clean()
    95  
    96  	cn := cacheNode{
    97  		rds:            store,
    98  		r:              rand.New(rand.NewSource(time.Now().UnixNano())),
    99  		barrier:        syncx.NewSingleFlight(),
   100  		lock:           new(sync.Mutex),
   101  		unstableExpiry: mathx.NewUnstable(expiryDeviation),
   102  		stat:           NewStat("any"),
   103  		errNotFound:    errTestNotFound,
   104  	}
   105  	var str string
   106  	err = cn.Take(&str, "any", func(v interface{}) error {
   107  		*v.(*string) = "value"
   108  		return nil
   109  	})
   110  	assert.Nil(t, err)
   111  	assert.Equal(t, "value", str)
   112  	assert.Nil(t, cn.Get("any", &str))
   113  	val, err := store.Get("any")
   114  	assert.Nil(t, err)
   115  	assert.Equal(t, `"value"`, val)
   116  }
   117  
   118  func TestCacheNode_TakeNotFound(t *testing.T) {
   119  	store, clean, err := redistest.CreateRedis()
   120  	assert.Nil(t, err)
   121  	defer clean()
   122  
   123  	cn := cacheNode{
   124  		rds:            store,
   125  		r:              rand.New(rand.NewSource(time.Now().UnixNano())),
   126  		barrier:        syncx.NewSingleFlight(),
   127  		lock:           new(sync.Mutex),
   128  		unstableExpiry: mathx.NewUnstable(expiryDeviation),
   129  		stat:           NewStat("any"),
   130  		errNotFound:    errTestNotFound,
   131  	}
   132  	var str string
   133  	err = cn.Take(&str, "any", func(v interface{}) error {
   134  		return errTestNotFound
   135  	})
   136  	assert.True(t, cn.IsNotFound(err))
   137  	assert.True(t, cn.IsNotFound(cn.Get("any", &str)))
   138  	val, err := store.Get("any")
   139  	assert.Nil(t, err)
   140  	assert.Equal(t, `*`, val)
   141  
   142  	store.Set("any", "*")
   143  	err = cn.Take(&str, "any", func(v interface{}) error {
   144  		return nil
   145  	})
   146  	assert.True(t, cn.IsNotFound(err))
   147  	assert.True(t, cn.IsNotFound(cn.Get("any", &str)))
   148  
   149  	store.Del("any")
   150  	errDummy := errors.New("dummy")
   151  	err = cn.Take(&str, "any", func(v interface{}) error {
   152  		return errDummy
   153  	})
   154  	assert.Equal(t, errDummy, err)
   155  }
   156  
   157  func TestCacheNode_TakeWithExpire(t *testing.T) {
   158  	store, clean, err := redistest.CreateRedis()
   159  	assert.Nil(t, err)
   160  	defer clean()
   161  
   162  	cn := cacheNode{
   163  		rds:            store,
   164  		r:              rand.New(rand.NewSource(time.Now().UnixNano())),
   165  		barrier:        syncx.NewSingleFlight(),
   166  		lock:           new(sync.Mutex),
   167  		unstableExpiry: mathx.NewUnstable(expiryDeviation),
   168  		stat:           NewStat("any"),
   169  		errNotFound:    errors.New("any"),
   170  	}
   171  	var str string
   172  	err = cn.TakeWithExpire(&str, "any", func(v interface{}, expire time.Duration) error {
   173  		*v.(*string) = "value"
   174  		return nil
   175  	})
   176  	assert.Nil(t, err)
   177  	assert.Equal(t, "value", str)
   178  	assert.Nil(t, cn.Get("any", &str))
   179  	val, err := store.Get("any")
   180  	assert.Nil(t, err)
   181  	assert.Equal(t, `"value"`, val)
   182  }
   183  
   184  func TestCacheNode_String(t *testing.T) {
   185  	store, clean, err := redistest.CreateRedis()
   186  	assert.Nil(t, err)
   187  	defer clean()
   188  
   189  	cn := cacheNode{
   190  		rds:            store,
   191  		r:              rand.New(rand.NewSource(time.Now().UnixNano())),
   192  		barrier:        syncx.NewSingleFlight(),
   193  		lock:           new(sync.Mutex),
   194  		unstableExpiry: mathx.NewUnstable(expiryDeviation),
   195  		stat:           NewStat("any"),
   196  		errNotFound:    errors.New("any"),
   197  	}
   198  	assert.Equal(t, store.Addr, cn.String())
   199  }
   200  
   201  func TestCacheValueWithBigInt(t *testing.T) {
   202  	store, clean, err := redistest.CreateRedis()
   203  	assert.Nil(t, err)
   204  	defer clean()
   205  
   206  	cn := cacheNode{
   207  		rds:            store,
   208  		r:              rand.New(rand.NewSource(time.Now().UnixNano())),
   209  		barrier:        syncx.NewSingleFlight(),
   210  		lock:           new(sync.Mutex),
   211  		unstableExpiry: mathx.NewUnstable(expiryDeviation),
   212  		stat:           NewStat("any"),
   213  		errNotFound:    errors.New("any"),
   214  	}
   215  
   216  	const (
   217  		key         = "key"
   218  		value int64 = 323427211229009810
   219  	)
   220  
   221  	assert.Nil(t, cn.Set(key, value))
   222  	var val interface{}
   223  	assert.Nil(t, cn.Get(key, &val))
   224  	assert.Equal(t, strconv.FormatInt(value, 10), fmt.Sprintf("%v", val))
   225  }