github.com/dtm-labs/rockscache@v0.1.1/client_test.go (about)

     1  package rockscache
     2  
     3  import (
     4  	"context"
     5  	"errors"
     6  	"testing"
     7  	"time"
     8  
     9  	"github.com/redis/go-redis/v9"
    10  	"github.com/stretchr/testify/assert"
    11  )
    12  
    13  var rdbKey = "client-test-key"
    14  
    15  var rdb = redis.NewClient(&redis.Options{
    16  	Addr:     "localhost:6379",
    17  	Username: "root",
    18  	Password: "",
    19  })
    20  var ctx = context.Background()
    21  
    22  // var rdb = redis.NewClusterClient(&redis.ClusterOptions{
    23  // 	Addrs:    []string{"43.128.5.63:46381", "43.128.5.63:46382", "43.128.5.63:46380", "43.128.5.63:46383", "43.128.5.63:46384", "43.128.5.63:46385"},
    24  // 	Username: "",
    25  // 	Password: "",
    26  // })
    27  
    28  type iRedisCluster interface {
    29  	ForEachMaster(context.Context, func(context.Context, *redis.Client) error) error
    30  }
    31  
    32  func getCluster() iRedisCluster {
    33  	var rr interface{} = rdb
    34  	v, _ := rr.(iRedisCluster)
    35  	return v
    36  }
    37  
    38  func clearCache() {
    39  	var err error
    40  	if clu := getCluster(); clu != nil {
    41  		err = clu.ForEachMaster(ctx, func(ctx context.Context, master *redis.Client) error {
    42  			return master.FlushAll(ctx).Err()
    43  		})
    44  	} else {
    45  		err = rdb.FlushDB(ctx).Err()
    46  	}
    47  
    48  	if err != nil {
    49  		panic(err)
    50  	}
    51  }
    52  
    53  func genDataFunc(value string, sleepMilli int) func() (string, error) {
    54  	return func() (string, error) {
    55  		time.Sleep(time.Duration(sleepMilli) * time.Millisecond)
    56  		return value, nil
    57  	}
    58  }
    59  
    60  func init() {
    61  	SetVerbose(true)
    62  }
    63  func TestWeakFetch(t *testing.T) {
    64  	rc := NewClient(rdb, NewDefaultOptions())
    65  
    66  	clearCache()
    67  	began := time.Now()
    68  	expected := "value1"
    69  	go func() {
    70  		dc2 := NewClient(rdb, NewDefaultOptions())
    71  		v, err := dc2.Fetch(rdbKey, 60*time.Second, genDataFunc(expected, 200))
    72  		assert.Nil(t, err)
    73  		assert.Equal(t, expected, v)
    74  	}()
    75  	time.Sleep(20 * time.Millisecond)
    76  
    77  	v, err := rc.Fetch(rdbKey, 60*time.Second, genDataFunc(expected, 201))
    78  	assert.Nil(t, err)
    79  	assert.Equal(t, expected, v)
    80  	assert.True(t, time.Since(began) > time.Duration(150)*time.Millisecond)
    81  
    82  	err = rc.TagAsDeleted(rdbKey)
    83  	assert.Nil(t, err)
    84  
    85  	nv := "value2"
    86  	v, err = rc.Fetch(rdbKey, 60*time.Second, genDataFunc(nv, 200))
    87  	assert.Nil(t, err)
    88  	assert.Equal(t, expected, v)
    89  
    90  	time.Sleep(300 * time.Millisecond)
    91  	v, err = rc.Fetch(rdbKey, 60*time.Second, genDataFunc("ignored", 200))
    92  	assert.Nil(t, err)
    93  	assert.Equal(t, nv, v)
    94  }
    95  
    96  func TestStrongFetch(t *testing.T) {
    97  	clearCache()
    98  	rc := NewClient(rdb, NewDefaultOptions())
    99  	rc.Options.StrongConsistency = true
   100  	began := time.Now()
   101  	expected := "value1"
   102  	go func() {
   103  		dc2 := NewClient(rdb, NewDefaultOptions())
   104  		v, err := dc2.Fetch(rdbKey, 60*time.Second, genDataFunc(expected, 200))
   105  		assert.Nil(t, err)
   106  		assert.Equal(t, expected, v)
   107  	}()
   108  	time.Sleep(20 * time.Millisecond)
   109  
   110  	v, err := rc.Fetch(rdbKey, 60*time.Second, genDataFunc(expected, 200))
   111  	assert.Nil(t, err)
   112  	assert.Equal(t, expected, v)
   113  	assert.True(t, time.Since(began) > time.Duration(150)*time.Millisecond)
   114  
   115  	err = rc.TagAsDeleted(rdbKey)
   116  	assert.Nil(t, err)
   117  
   118  	began = time.Now()
   119  	nv := "value2"
   120  	v, err = rc.Fetch(rdbKey, 60*time.Second, genDataFunc(nv, 200))
   121  	assert.Nil(t, err)
   122  	assert.Equal(t, nv, v)
   123  	assert.True(t, time.Since(began) > time.Duration(150)*time.Millisecond)
   124  
   125  	v, err = rc.Fetch(rdbKey, 60*time.Second, genDataFunc("ignored", 200))
   126  	assert.Nil(t, err)
   127  	assert.Equal(t, nv, v)
   128  
   129  }
   130  
   131  func TestStrongErrorFetch(t *testing.T) {
   132  	rc := NewClient(rdb, NewDefaultOptions())
   133  	rc.Options.StrongConsistency = true
   134  
   135  	clearCache()
   136  	began := time.Now()
   137  
   138  	fetchError := errors.New("fetch error")
   139  	getFn := func() (string, error) {
   140  		return "", fetchError
   141  	}
   142  	_, err := rc.Fetch(rdbKey, 60*time.Second, getFn)
   143  	assert.Error(t, err)
   144  	fetchError = nil
   145  	_, err = rc.Fetch(rdbKey, 60*time.Second, getFn)
   146  	assert.Nil(t, err)
   147  	assert.True(t, time.Since(began) < time.Duration(150)*time.Millisecond)
   148  }
   149  
   150  func TestWeakErrorFetch(t *testing.T) {
   151  	rc := NewClient(rdb, NewDefaultOptions())
   152  
   153  	clearCache()
   154  	began := time.Now()
   155  
   156  	fetchError := errors.New("fetch error")
   157  	getFn := func() (string, error) {
   158  		return "", fetchError
   159  	}
   160  	_, err := rc.Fetch(rdbKey, 60*time.Second, getFn)
   161  	assert.Error(t, err)
   162  	fetchError = nil
   163  	_, err = rc.Fetch(rdbKey, 60*time.Second, getFn)
   164  	assert.Nil(t, err)
   165  	assert.True(t, time.Since(began) < time.Duration(150)*time.Millisecond)
   166  }
   167  
   168  func TestRawGet(t *testing.T) {
   169  	rc := NewClient(rdb, NewDefaultOptions())
   170  	_, err := rc.RawGet(ctx, "not-exists")
   171  	assert.Error(t, redis.Nil, err)
   172  }
   173  
   174  func TestRawSet(t *testing.T) {
   175  	rc := NewClient(rdb, NewDefaultOptions())
   176  	err := rc.RawSet(ctx, "eeeee", "value", 60*time.Second)
   177  	assert.Nil(t, err)
   178  }
   179  
   180  func TestLock(t *testing.T) {
   181  	rc := NewClient(rdb, NewDefaultOptions())
   182  	rc.Options.StrongConsistency = true
   183  	owner := "test_owner"
   184  	key := "test_lock"
   185  	err := rc.LockForUpdate(ctx, key, owner)
   186  	assert.Nil(t, err)
   187  	err = rc.LockForUpdate(ctx, key, "other_owner")
   188  	assert.Error(t, err)
   189  	err = rc.UnlockForUpdate(ctx, key, owner)
   190  	assert.Nil(t, err)
   191  }