github.com/mdaxf/iac@v0.0.0-20240519030858-58a061660378/framework/cache/cache_test.go (about)

     1  // The package is migrated from beego, you can get from following link:
     2  // import(
     3  //   "github.com/beego/beego/v2/client/cache"
     4  // )
     5  // Copyright 2023. All Rights Reserved.
     6  //
     7  // Licensed under the Apache License, Version 2.0 (the "License");
     8  // you may not use this file except in compliance with the License.
     9  // You may obtain a copy of the License at
    10  //
    11  //      http://www.apache.org/licenses/LICENSE-2.0
    12  //
    13  // Unless required by applicable law or agreed to in writing, software
    14  // distributed under the License is distributed on an "AS IS" BASIS,
    15  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    16  // See the License for the specific language governing permissions and
    17  // limitations under the License.
    18  
    19  package cache
    20  
    21  import (
    22  	"context"
    23  	"math"
    24  	"os"
    25  	"strings"
    26  	"sync"
    27  	"testing"
    28  	"time"
    29  
    30  	"github.com/stretchr/testify/assert"
    31  )
    32  
    33  func TestCacheIncr(t *testing.T) {
    34  	bm, err := NewCache("memory", `{"interval":20}`)
    35  	assert.Nil(t, err)
    36  	// timeoutDuration := 10 * time.Second
    37  
    38  	err = bm.Put(context.Background(), "edwardhey", 0, time.Second*20)
    39  	assert.Nil(t, err)
    40  	wg := sync.WaitGroup{}
    41  	wg.Add(10)
    42  	for i := 0; i < 10; i++ {
    43  		go func() {
    44  			defer wg.Done()
    45  			_ = bm.Incr(context.Background(), "edwardhey")
    46  		}()
    47  	}
    48  	wg.Wait()
    49  	val, _ := bm.Get(context.Background(), "edwardhey")
    50  	if val.(int) != 10 {
    51  		t.Error("Incr err")
    52  	}
    53  }
    54  
    55  func TestCache(t *testing.T) {
    56  	bm, err := NewCache("memory", `{"interval":1}`)
    57  	assert.Nil(t, err)
    58  	timeoutDuration := 5 * time.Second
    59  	if err = bm.Put(context.Background(), "astaxie", 1, timeoutDuration); err != nil {
    60  		t.Error("set Error", err)
    61  	}
    62  	if res, _ := bm.IsExist(context.Background(), "astaxie"); !res {
    63  		t.Error("check err")
    64  	}
    65  
    66  	if v, _ := bm.Get(context.Background(), "astaxie"); v.(int) != 1 {
    67  		t.Error("get err")
    68  	}
    69  
    70  	time.Sleep(7 * time.Second)
    71  
    72  	if res, _ := bm.IsExist(context.Background(), "astaxie"); res {
    73  		t.Error("check err")
    74  	}
    75  
    76  	if err = bm.Put(context.Background(), "astaxie", 1, timeoutDuration); err != nil {
    77  		t.Error("set Error", err)
    78  	}
    79  
    80  	// test different integer type for incr & decr
    81  	testMultiTypeIncrDecr(t, bm, timeoutDuration)
    82  
    83  	// test overflow of incr&decr
    84  	testIncrOverFlow(t, bm, timeoutDuration)
    85  	testDecrOverFlow(t, bm, timeoutDuration)
    86  
    87  	assert.Nil(t, bm.Delete(context.Background(), "astaxie"))
    88  	res, _ := bm.IsExist(context.Background(), "astaxie")
    89  	assert.False(t, res)
    90  
    91  	assert.Nil(t, bm.Put(context.Background(), "astaxie", "author", timeoutDuration))
    92  
    93  	res, _ = bm.IsExist(context.Background(), "astaxie")
    94  	assert.True(t, res)
    95  
    96  	v, _ := bm.Get(context.Background(), "astaxie")
    97  	assert.Equal(t, "author", v)
    98  
    99  	assert.Nil(t, bm.Put(context.Background(), "astaxie1", "author1", timeoutDuration))
   100  
   101  	res, _ = bm.IsExist(context.Background(), "astaxie1")
   102  	assert.True(t, res)
   103  
   104  	vv, _ := bm.GetMulti(context.Background(), []string{"astaxie", "astaxie1"})
   105  	assert.Equal(t, 2, len(vv))
   106  	assert.Equal(t, "author", vv[0])
   107  	assert.Equal(t, "author1", vv[1])
   108  
   109  	vv, err = bm.GetMulti(context.Background(), []string{"astaxie0", "astaxie1"})
   110  	assert.Equal(t, 2, len(vv))
   111  	assert.Nil(t, vv[0])
   112  	assert.Equal(t, "author1", vv[1])
   113  
   114  	assert.NotNil(t, err)
   115  	assert.True(t, strings.Contains(err.Error(), "key isn't exist"))
   116  }
   117  
   118  func TestFileCache(t *testing.T) {
   119  	bm, err := NewCache("file", `{"CachePath":"cache","FileSuffix":".bin","DirectoryLevel":"2","EmbedExpiry":"0"}`)
   120  	assert.Nil(t, err)
   121  	timeoutDuration := 10 * time.Second
   122  	assert.Nil(t, bm.Put(context.Background(), "astaxie", 1, timeoutDuration))
   123  
   124  	res, _ := bm.IsExist(context.Background(), "astaxie")
   125  	assert.True(t, res)
   126  	v, _ := bm.Get(context.Background(), "astaxie")
   127  	assert.Equal(t, 1, v)
   128  
   129  	// test different integer type for incr & decr
   130  	testMultiTypeIncrDecr(t, bm, timeoutDuration)
   131  
   132  	// test overflow of incr&decr
   133  	testIncrOverFlow(t, bm, timeoutDuration)
   134  	testDecrOverFlow(t, bm, timeoutDuration)
   135  
   136  	assert.Nil(t, bm.Delete(context.Background(), "astaxie"))
   137  	res, _ = bm.IsExist(context.Background(), "astaxie")
   138  	assert.False(t, res)
   139  
   140  	// test string
   141  	assert.Nil(t, bm.Put(context.Background(), "astaxie", "author", timeoutDuration))
   142  	res, _ = bm.IsExist(context.Background(), "astaxie")
   143  	assert.True(t, res)
   144  
   145  	v, _ = bm.Get(context.Background(), "astaxie")
   146  	assert.Equal(t, "author", v)
   147  
   148  	// test GetMulti
   149  	assert.Nil(t, bm.Put(context.Background(), "astaxie1", "author1", timeoutDuration))
   150  
   151  	res, _ = bm.IsExist(context.Background(), "astaxie1")
   152  	assert.True(t, res)
   153  
   154  	vv, _ := bm.GetMulti(context.Background(), []string{"astaxie", "astaxie1"})
   155  	assert.Equal(t, 2, len(vv))
   156  	assert.Equal(t, "author", vv[0])
   157  	assert.Equal(t, "author1", vv[1])
   158  
   159  	vv, err = bm.GetMulti(context.Background(), []string{"astaxie0", "astaxie1"})
   160  	assert.Equal(t, 2, len(vv))
   161  
   162  	assert.Nil(t, vv[0])
   163  
   164  	assert.Equal(t, "author1", vv[1])
   165  	assert.NotNil(t, err)
   166  	assert.Nil(t, os.RemoveAll("cache"))
   167  }
   168  
   169  func testMultiTypeIncrDecr(t *testing.T, c Cache, timeout time.Duration) {
   170  	testIncrDecr(t, c, 1, 2, timeout)
   171  	testIncrDecr(t, c, int32(1), int32(2), timeout)
   172  	testIncrDecr(t, c, int64(1), int64(2), timeout)
   173  	testIncrDecr(t, c, uint(1), uint(2), timeout)
   174  	testIncrDecr(t, c, uint32(1), uint32(2), timeout)
   175  	testIncrDecr(t, c, uint64(1), uint64(2), timeout)
   176  }
   177  
   178  func testIncrDecr(t *testing.T, c Cache, beforeIncr interface{}, afterIncr interface{}, timeout time.Duration) {
   179  	ctx := context.Background()
   180  	key := "incDecKey"
   181  
   182  	assert.Nil(t, c.Put(ctx, key, beforeIncr, timeout))
   183  	assert.Nil(t, c.Incr(ctx, key))
   184  
   185  	v, _ := c.Get(ctx, key)
   186  	assert.Equal(t, afterIncr, v)
   187  
   188  	assert.Nil(t, c.Decr(ctx, key))
   189  
   190  	v, _ = c.Get(ctx, key)
   191  	assert.Equal(t, v, beforeIncr)
   192  	assert.Nil(t, c.Delete(ctx, key))
   193  }
   194  
   195  func testIncrOverFlow(t *testing.T, c Cache, timeout time.Duration) {
   196  	ctx := context.Background()
   197  	key := "incKey"
   198  
   199  	assert.Nil(t, c.Put(ctx, key, int64(math.MaxInt64), timeout))
   200  	// int64
   201  	defer func() {
   202  		assert.Nil(t, c.Delete(ctx, key))
   203  	}()
   204  	assert.NotNil(t, c.Incr(ctx, key))
   205  }
   206  
   207  func testDecrOverFlow(t *testing.T, c Cache, timeout time.Duration) {
   208  	var err error
   209  	ctx := context.Background()
   210  	key := "decKey"
   211  
   212  	// int64
   213  	if err = c.Put(ctx, key, int64(math.MinInt64), timeout); err != nil {
   214  		t.Error("Put Error: ", err.Error())
   215  		return
   216  	}
   217  	defer func() {
   218  		if err = c.Delete(ctx, key); err != nil {
   219  			t.Errorf("Delete error: %s", err.Error())
   220  		}
   221  	}()
   222  	if err = c.Decr(ctx, key); err == nil {
   223  		t.Error("Decr error")
   224  		return
   225  	}
   226  }