github.com/goravel/framework@v1.13.9/cache/memory_test.go (about)

     1  package cache
     2  
     3  import (
     4  	"errors"
     5  	"testing"
     6  	"time"
     7  
     8  	"github.com/stretchr/testify/suite"
     9  
    10  	configmock "github.com/goravel/framework/contracts/config/mocks"
    11  )
    12  
    13  type MemoryTestSuite struct {
    14  	suite.Suite
    15  	mockConfig *configmock.Config
    16  	memory     *Memory
    17  }
    18  
    19  func TestMemoryTestSuite(t *testing.T) {
    20  	suite.Run(t, new(MemoryTestSuite))
    21  }
    22  
    23  func (s *MemoryTestSuite) SetupTest() {
    24  	s.mockConfig = &configmock.Config{}
    25  	memoryStore, err := getMemoryStore()
    26  	s.Nil(err)
    27  	s.memory = memoryStore
    28  }
    29  
    30  func (s *MemoryTestSuite) TestAdd() {
    31  	s.Nil(s.memory.Put("name", "Goravel", 1*time.Second))
    32  	s.False(s.memory.Add("name", "World", 1*time.Second))
    33  	s.True(s.memory.Add("name1", "World", 1*time.Second))
    34  	s.True(s.memory.Has("name1"))
    35  	time.Sleep(2 * time.Second)
    36  	s.False(s.memory.Has("name1"))
    37  	s.True(s.memory.Flush())
    38  }
    39  
    40  func (s *MemoryTestSuite) TestDecrement() {
    41  	res, err := s.memory.Decrement("decrement")
    42  	s.Equal(-1, res)
    43  	s.Nil(err)
    44  
    45  	s.Equal(-1, s.memory.GetInt("decrement"))
    46  
    47  	res, err = s.memory.Decrement("decrement", 2)
    48  	s.Equal(-3, res)
    49  	s.Nil(err)
    50  
    51  	res, err = s.memory.Decrement("decrement1", 2)
    52  	s.Equal(-2, res)
    53  	s.Nil(err)
    54  
    55  	s.Equal(-2, s.memory.GetInt("decrement1"))
    56  
    57  	s.True(s.memory.Add("decrement2", 4, 2*time.Second))
    58  	res, err = s.memory.Decrement("decrement2")
    59  	s.Equal(3, res)
    60  	s.Nil(err)
    61  
    62  	res, err = s.memory.Decrement("decrement2", 2)
    63  	s.Equal(1, res)
    64  	s.Nil(err)
    65  }
    66  
    67  func (s *MemoryTestSuite) TestForever() {
    68  	s.True(s.memory.Forever("name", "Goravel"))
    69  	s.Equal("Goravel", s.memory.Get("name", "").(string))
    70  	s.True(s.memory.Flush())
    71  }
    72  
    73  func (s *MemoryTestSuite) TestForget() {
    74  	val := s.memory.Forget("test-forget")
    75  	s.True(val)
    76  
    77  	err := s.memory.Put("test-forget", "goravel", 5*time.Second)
    78  	s.Nil(err)
    79  	s.True(s.memory.Forget("test-forget"))
    80  }
    81  
    82  func (s *MemoryTestSuite) TestFlush() {
    83  	s.Nil(s.memory.Put("test-flush", "goravel", 5*time.Second))
    84  	s.Equal("goravel", s.memory.Get("test-flush", nil).(string))
    85  
    86  	s.True(s.memory.Flush())
    87  	s.False(s.memory.Has("test-flush"))
    88  }
    89  
    90  func (s *MemoryTestSuite) TestGet() {
    91  	s.Nil(s.memory.Put("name", "Goravel", 1*time.Second))
    92  	s.Equal("Goravel", s.memory.Get("name", "").(string))
    93  	s.Equal("World", s.memory.Get("name1", "World").(string))
    94  	s.Equal("World1", s.memory.Get("name2", func() any {
    95  		return "World1"
    96  	}).(string))
    97  	s.True(s.memory.Forget("name"))
    98  	s.True(s.memory.Flush())
    99  }
   100  
   101  func (s *MemoryTestSuite) TestGetBool() {
   102  	s.Equal(true, s.memory.GetBool("test-get-bool", true))
   103  	s.Nil(s.memory.Put("test-get-bool", true, 2*time.Second))
   104  	s.Equal(true, s.memory.GetBool("test-get-bool", false))
   105  }
   106  
   107  func (s *MemoryTestSuite) TestGetInt() {
   108  	s.Equal(2, s.memory.GetInt("test-get-int", 2))
   109  	s.Nil(s.memory.Put("test-get-int", 3, 2*time.Second))
   110  	s.Equal(3, s.memory.GetInt("test-get-int", 2))
   111  }
   112  
   113  func (s *MemoryTestSuite) TestGetString() {
   114  	s.Equal("2", s.memory.GetString("test-get-string", "2"))
   115  	s.Nil(s.memory.Put("test-get-string", "3", 2*time.Second))
   116  	s.Equal("3", s.memory.GetString("test-get-string", "2"))
   117  }
   118  
   119  func (s *MemoryTestSuite) TestHas() {
   120  	s.False(s.memory.Has("test-has"))
   121  	s.Nil(s.memory.Put("test-has", "goravel", 5*time.Second))
   122  	s.True(s.memory.Has("test-has"))
   123  }
   124  
   125  func (s *MemoryTestSuite) TestIncrement() {
   126  	res, err := s.memory.Increment("Increment")
   127  	s.Equal(1, res)
   128  	s.Nil(err)
   129  
   130  	s.Equal(1, s.memory.GetInt("Increment"))
   131  
   132  	res, err = s.memory.Increment("Increment", 2)
   133  	s.Equal(3, res)
   134  	s.Nil(err)
   135  
   136  	res, err = s.memory.Increment("Increment1", 2)
   137  	s.Equal(2, res)
   138  	s.Nil(err)
   139  
   140  	s.Equal(2, s.memory.GetInt("Increment1"))
   141  
   142  	s.True(s.memory.Add("Increment2", 1, 2*time.Second))
   143  	res, err = s.memory.Increment("Increment2")
   144  	s.Equal(2, res)
   145  	s.Nil(err)
   146  
   147  	res, err = s.memory.Increment("Increment2", 2)
   148  	s.Equal(4, res)
   149  	s.Nil(err)
   150  }
   151  
   152  func (s *MemoryTestSuite) TestLock() {
   153  	tests := []struct {
   154  		name  string
   155  		setup func()
   156  	}{
   157  		{
   158  			name: "once got lock, lock can't be got again",
   159  			setup: func() {
   160  				lock := s.memory.Lock("lock")
   161  				s.True(lock.Get())
   162  
   163  				lock1 := s.memory.Lock("lock")
   164  				s.False(lock1.Get())
   165  
   166  				lock.Release()
   167  			},
   168  		},
   169  		{
   170  			name: "lock can be got again when had been released",
   171  			setup: func() {
   172  				lock := s.memory.Lock("lock")
   173  				s.True(lock.Get())
   174  
   175  				s.True(lock.Release())
   176  
   177  				lock1 := s.memory.Lock("lock")
   178  				s.True(lock1.Get())
   179  
   180  				s.True(lock1.Release())
   181  			},
   182  		},
   183  		{
   184  			name: "lock cannot be released when had been got",
   185  			setup: func() {
   186  				lock := s.memory.Lock("lock")
   187  				s.True(lock.Get())
   188  
   189  				lock1 := s.memory.Lock("lock")
   190  				s.False(lock1.Get())
   191  				s.False(lock1.Release())
   192  
   193  				s.True(lock.Release())
   194  			},
   195  		},
   196  		{
   197  			name: "lock can be force released",
   198  			setup: func() {
   199  				lock := s.memory.Lock("lock")
   200  				s.True(lock.Get())
   201  
   202  				lock1 := s.memory.Lock("lock")
   203  				s.False(lock1.Get())
   204  				s.False(lock1.Release())
   205  				s.True(lock1.ForceRelease())
   206  
   207  				s.True(lock.Release())
   208  			},
   209  		},
   210  		{
   211  			name: "lock can be got again when timeout",
   212  			setup: func() {
   213  				lock := s.memory.Lock("lock", 1*time.Second)
   214  				s.True(lock.Get())
   215  
   216  				time.Sleep(2 * time.Second)
   217  
   218  				lock1 := s.memory.Lock("lock")
   219  				s.True(lock1.Get())
   220  				s.True(lock1.Release())
   221  			},
   222  		},
   223  		{
   224  			name: "lock can be got again when had been released by callback",
   225  			setup: func() {
   226  				lock := s.memory.Lock("lock")
   227  				s.True(lock.Get(func() {
   228  					s.True(true)
   229  				}))
   230  
   231  				lock1 := s.memory.Lock("lock")
   232  				s.True(lock1.Get())
   233  				s.True(lock1.Release())
   234  			},
   235  		},
   236  		{
   237  			name: "block wait out",
   238  			setup: func() {
   239  				lock := s.memory.Lock("lock")
   240  				s.True(lock.Get())
   241  
   242  				go func() {
   243  					lock1 := s.memory.Lock("lock")
   244  					s.NotNil(lock1.Block(1 * time.Second))
   245  				}()
   246  
   247  				time.Sleep(2 * time.Second)
   248  
   249  				lock.Release()
   250  			},
   251  		},
   252  		{
   253  			name: "get lock by block when just timeout",
   254  			setup: func() {
   255  				lock := s.memory.Lock("lock")
   256  				s.True(lock.Get())
   257  
   258  				go func() {
   259  					lock1 := s.memory.Lock("lock")
   260  					s.True(lock1.Block(2 * time.Second))
   261  					s.True(lock1.Release())
   262  				}()
   263  
   264  				time.Sleep(1 * time.Second)
   265  
   266  				lock.Release()
   267  
   268  				time.Sleep(2 * time.Second)
   269  			},
   270  		},
   271  		{
   272  			name: "get lock by block",
   273  			setup: func() {
   274  				lock := s.memory.Lock("lock")
   275  				s.True(lock.Get())
   276  
   277  				go func() {
   278  					lock1 := s.memory.Lock("lock")
   279  					s.True(lock1.Block(3 * time.Second))
   280  					s.True(lock1.Release())
   281  				}()
   282  
   283  				time.Sleep(1 * time.Second)
   284  
   285  				lock.Release()
   286  
   287  				time.Sleep(3 * time.Second)
   288  			},
   289  		},
   290  		{
   291  			name: "get lock by block with callback",
   292  			setup: func() {
   293  				lock := s.memory.Lock("lock")
   294  				s.True(lock.Get())
   295  
   296  				go func() {
   297  					lock1 := s.memory.Lock("lock")
   298  					s.True(lock1.Block(2*time.Second, func() {
   299  						s.True(true)
   300  					}))
   301  				}()
   302  
   303  				time.Sleep(1 * time.Second)
   304  
   305  				lock.Release()
   306  
   307  				time.Sleep(2 * time.Second)
   308  			},
   309  		},
   310  	}
   311  
   312  	for _, test := range tests {
   313  		s.Run(test.name, func() {
   314  			test.setup()
   315  		})
   316  	}
   317  }
   318  
   319  func (s *MemoryTestSuite) TestPull() {
   320  	s.Nil(s.memory.Put("name", "Goravel", 1*time.Second))
   321  	s.True(s.memory.Has("name"))
   322  	s.Equal("Goravel", s.memory.Pull("name", "").(string))
   323  	s.False(s.memory.Has("name"))
   324  }
   325  
   326  func (s *MemoryTestSuite) TestPut() {
   327  	s.Nil(s.memory.Put("name", "Goravel", 1*time.Second))
   328  	s.True(s.memory.Has("name"))
   329  	s.Equal("Goravel", s.memory.Get("name", "").(string))
   330  	time.Sleep(2 * time.Second)
   331  	s.False(s.memory.Has("name"))
   332  }
   333  
   334  func (s *MemoryTestSuite) TestRemember() {
   335  	s.Nil(s.memory.Put("name", "Goravel", 1*time.Second))
   336  	value, err := s.memory.Remember("name", 1*time.Second, func() (any, error) {
   337  		return "World", nil
   338  	})
   339  	s.Nil(err)
   340  	s.Equal("Goravel", value)
   341  
   342  	value, err = s.memory.Remember("name1", 1*time.Second, func() (any, error) {
   343  		return "World1", nil
   344  	})
   345  	s.Nil(err)
   346  	s.Equal("World1", value)
   347  	time.Sleep(2 * time.Second)
   348  	s.False(s.memory.Has("name1"))
   349  	s.True(s.memory.Flush())
   350  
   351  	value, err = s.memory.Remember("name2", 1*time.Second, func() (any, error) {
   352  		return nil, errors.New("error")
   353  	})
   354  	s.EqualError(err, "error")
   355  	s.Nil(value)
   356  }
   357  
   358  func (s *MemoryTestSuite) TestRememberForever() {
   359  	s.Nil(s.memory.Put("name", "Goravel", 1*time.Second))
   360  	value, err := s.memory.RememberForever("name", func() (any, error) {
   361  		return "World", nil
   362  	})
   363  	s.Nil(err)
   364  	s.Equal("Goravel", value)
   365  
   366  	value, err = s.memory.RememberForever("name1", func() (any, error) {
   367  		return "World1", nil
   368  	})
   369  	s.Nil(err)
   370  	s.Equal("World1", value)
   371  	s.True(s.memory.Flush())
   372  
   373  	value, err = s.memory.RememberForever("name2", func() (any, error) {
   374  		return nil, errors.New("error")
   375  	})
   376  	s.EqualError(err, "error")
   377  	s.Nil(value)
   378  }
   379  
   380  func getMemoryStore() (*Memory, error) {
   381  	mockConfig := &configmock.Config{}
   382  	mockConfig.On("GetString", "cache.prefix").Return("goravel_cache").Once()
   383  
   384  	memory, err := NewMemory(mockConfig)
   385  	if err != nil {
   386  		return nil, err
   387  	}
   388  
   389  	return memory, nil
   390  }