github.com/ulule/limiter/v3@v3.11.3-0.20230613131926-4cb9c1da4633/drivers/store/memory/cache_test.go (about)

     1  package memory_test
     2  
     3  import (
     4  	"sync"
     5  	"testing"
     6  	"time"
     7  
     8  	"github.com/stretchr/testify/require"
     9  
    10  	"github.com/ulule/limiter/v3/drivers/store/memory"
    11  )
    12  
    13  func TestCacheIncrementSequential(t *testing.T) {
    14  	is := require.New(t)
    15  
    16  	key := "foobar"
    17  	cache := memory.NewCache(10 * time.Nanosecond)
    18  	duration := 50 * time.Millisecond
    19  	deleted := time.Now().Add(duration).UnixNano()
    20  	epsilon := 0.001
    21  
    22  	x, expire := cache.Increment(key, 1, duration)
    23  	is.Equal(int64(1), x)
    24  	is.InEpsilon(deleted, expire.UnixNano(), epsilon)
    25  
    26  	x, expire = cache.Increment(key, 2, duration)
    27  	is.Equal(int64(3), x)
    28  	is.InEpsilon(deleted, expire.UnixNano(), epsilon)
    29  
    30  	time.Sleep(duration)
    31  
    32  	deleted = time.Now().Add(duration).UnixNano()
    33  	x, expire = cache.Increment(key, 1, duration)
    34  	is.Equal(int64(1), x)
    35  	is.InEpsilon(deleted, expire.UnixNano(), epsilon)
    36  }
    37  
    38  func TestCacheIncrementConcurrent(t *testing.T) {
    39  	is := require.New(t)
    40  
    41  	goroutines := 200
    42  	ops := 500
    43  
    44  	expected := int64(0)
    45  	for i := 0; i < goroutines; i++ {
    46  		if (i % 3) == 0 {
    47  			for j := 0; j < ops; j++ {
    48  				expected += int64(i + j)
    49  			}
    50  		}
    51  	}
    52  
    53  	key := "foobar"
    54  	cache := memory.NewCache(10 * time.Nanosecond)
    55  
    56  	wg := &sync.WaitGroup{}
    57  	wg.Add(goroutines)
    58  
    59  	for i := 0; i < goroutines; i++ {
    60  		go func(i int) {
    61  			if (i % 3) == 0 {
    62  				time.Sleep(1 * time.Second)
    63  				for j := 0; j < ops; j++ {
    64  					cache.Increment(key, int64(i+j), (1 * time.Second))
    65  				}
    66  			} else {
    67  				time.Sleep(50 * time.Millisecond)
    68  				stopAt := time.Now().Add(500 * time.Millisecond)
    69  				for time.Now().Before(stopAt) {
    70  					cache.Increment(key, int64(i), (75 * time.Millisecond))
    71  				}
    72  			}
    73  			wg.Done()
    74  		}(i)
    75  	}
    76  	wg.Wait()
    77  
    78  	value, expire := cache.Get(key, (100 * time.Millisecond))
    79  	is.Equal(expected, value)
    80  	is.True(time.Now().Before(expire))
    81  }
    82  
    83  func TestCacheGet(t *testing.T) {
    84  	is := require.New(t)
    85  
    86  	key := "foobar"
    87  	cache := memory.NewCache(10 * time.Nanosecond)
    88  	duration := 50 * time.Millisecond
    89  	deleted := time.Now().Add(duration).UnixNano()
    90  	epsilon := 0.001
    91  
    92  	x, expire := cache.Get(key, duration)
    93  	is.Equal(int64(0), x)
    94  	is.InEpsilon(deleted, expire.UnixNano(), epsilon)
    95  }
    96  
    97  func TestCacheReset(t *testing.T) {
    98  	is := require.New(t)
    99  
   100  	key := "foobar"
   101  	cache := memory.NewCache(10 * time.Nanosecond)
   102  	duration := 50 * time.Millisecond
   103  	deleted := time.Now().Add(duration).UnixNano()
   104  	epsilon := 0.001
   105  
   106  	x, expire := cache.Get(key, duration)
   107  	is.Equal(int64(0), x)
   108  	is.InEpsilon(deleted, expire.UnixNano(), epsilon)
   109  
   110  	x, expire = cache.Increment(key, 1, duration)
   111  	is.Equal(int64(1), x)
   112  	is.InEpsilon(deleted, expire.UnixNano(), epsilon)
   113  
   114  	x, expire = cache.Increment(key, 1, duration)
   115  	is.Equal(int64(2), x)
   116  	is.InEpsilon(deleted, expire.UnixNano(), epsilon)
   117  
   118  	x, expire = cache.Reset(key, duration)
   119  	is.Equal(int64(0), x)
   120  	is.InEpsilon(deleted, expire.UnixNano(), epsilon)
   121  
   122  	x, expire = cache.Increment(key, 1, duration)
   123  	is.Equal(int64(1), x)
   124  	is.InEpsilon(deleted, expire.UnixNano(), epsilon)
   125  
   126  	x, expire = cache.Increment(key, 1, duration)
   127  	is.Equal(int64(2), x)
   128  	is.InEpsilon(deleted, expire.UnixNano(), epsilon)
   129  }