From a226a36a3f16c0b2fa953616958be5356738424a Mon Sep 17 00:00:00 2001 From: Wenbo han Date: Fri, 9 Jun 2023 22:44:18 +0800 Subject: [PATCH 1/2] Remove redis driver for Cache module --- cache/driver.go | 16 -- cache/driver_test.go | 514 +------------------------------------------ cache/memory_test.go | 377 +++++++++++++++++++++++++++++++ cache/redis.go | 259 ---------------------- 4 files changed, 388 insertions(+), 778 deletions(-) create mode 100644 cache/memory_test.go delete mode 100644 cache/redis.go diff --git a/cache/driver.go b/cache/driver.go index 103418522..a41b8fb71 100644 --- a/cache/driver.go +++ b/cache/driver.go @@ -1,7 +1,6 @@ package cache import ( - "context" "fmt" "github.com/gookit/color" @@ -28,8 +27,6 @@ func NewDriverImpl(config config.Config) *DriverImpl { func (d *DriverImpl) New(store string) cache.Driver { driver := d.config.GetString(fmt.Sprintf("cache.stores.%s.driver", store)) switch driver { - case "redis": - return d.redis(store) case "memory": return d.memory() case "custom": @@ -40,19 +37,6 @@ func (d *DriverImpl) New(store string) cache.Driver { } } -func (d *DriverImpl) redis(store string) cache.Driver { - redis, err := NewRedis(context.Background(), d.config, store) - if err != nil { - color.Redf("[Cache] Init redis driver error: %v\n", err) - return nil - } - if redis == nil { - return nil - } - - return redis -} - func (d *DriverImpl) memory() cache.Driver { memory, err := NewMemory(d.config) if err != nil { diff --git a/cache/driver_test.go b/cache/driver_test.go index 7110b8d0d..39f6fd1ad 100644 --- a/cache/driver_test.go +++ b/cache/driver_test.go @@ -11,7 +11,6 @@ import ( "github.com/goravel/framework/contracts/cache" configmock "github.com/goravel/framework/contracts/config/mocks" - testingdocker "github.com/goravel/framework/testing/docker" ) type DriverTestSuite struct { @@ -23,10 +22,6 @@ type DriverTestSuite struct { } func TestDriverTestSuite(t *testing.T) { - redisPool, redisDocker, redisStore, err := getRedisDocker() - if err != nil { - log.Fatalf("Get redis store error: %s", err) - } memoryStore, err := getMemoryStore() if err != nil { log.Fatalf("Get memory store error: %s", err) @@ -34,15 +29,9 @@ func TestDriverTestSuite(t *testing.T) { suite.Run(t, &DriverTestSuite{ stores: map[string]cache.Driver{ - "redis": redisStore, "memory": memoryStore, }, - redisDocker: redisDocker, }) - - if err := redisPool.Purge(redisDocker); err != nil { - log.Fatalf("Could not purge resource: %s", err) - } } func (s *DriverTestSuite) SetupTest() { @@ -55,43 +44,6 @@ func (s *DriverTestSuite) TestMemory() { s.NotNil(s.driver.memory()) } -func (s *DriverTestSuite) TestRedis() { - tests := []struct { - description string - setup func() - expectErr bool - }{ - { - description: "success", - setup: func() { - s.mockConfig.On("GetString", "cache.stores.redis.connection", "default").Return("default").Once() - s.mockConfig.On("GetString", "database.redis.default.host").Return("localhost").Once() - s.mockConfig.On("GetString", "database.redis.default.port").Return(s.redisDocker.GetPort("6379/tcp")).Once() - s.mockConfig.On("GetString", "database.redis.default.password").Return("").Once() - s.mockConfig.On("GetInt", "database.redis.default.database").Return(0).Once() - s.mockConfig.On("GetString", "cache.prefix").Return("goravel_cache").Once() - }, - }, - { - description: "error", - setup: func() { - s.mockConfig.On("GetString", "cache.stores.redis.connection", "default").Return("default").Once() - s.mockConfig.On("GetString", "database.redis.default.host").Return("").Once() - }, - expectErr: true, - }, - } - - for _, test := range tests { - s.Run(test.description, func() { - test.setup() - redis := s.driver.redis("redis") - s.Equal(test.expectErr, redis == nil) - s.mockConfig.AssertExpectations(s.T()) - }) - } -} - func (s *DriverTestSuite) TestCustom() { s.mockConfig.On("Get", "cache.stores.store.via").Return(&Store{}).Once() @@ -103,470 +55,26 @@ func (s *DriverTestSuite) TestCustom() { } func (s *DriverTestSuite) TestStore() { - mockConfig := &configmock.Config{} - mockConfig.On("GetString", "cache.stores.memory.driver").Return("memory").Once() - mockConfig.On("GetString", "cache.prefix").Return("goravel_cache").Once() + s.mockConfig.On("GetString", "cache.stores.memory.driver").Return("memory").Once() + s.mockConfig.On("GetString", "cache.prefix").Return("goravel_cache").Once() - memory := NewApplication(mockConfig, "memory") + memory := NewApplication(s.mockConfig, "memory") s.NotNil(memory) s.True(memory.Add("hello", "goravel", 5*time.Second)) s.Equal("goravel", memory.GetString("hello")) - mockConfig.On("GetString", "cache.stores.redis.driver").Return("redis").Once() - mockConfig.On("GetString", "cache.stores.redis.connection", "default").Return("default").Once() - mockConfig.On("GetString", "database.redis.default.host").Return("localhost").Once() - mockConfig.On("GetString", "database.redis.default.port").Return(s.redisDocker.GetPort("6379/tcp")).Once() - mockConfig.On("GetString", "database.redis.default.password").Return("").Once() - mockConfig.On("GetInt", "database.redis.default.database").Return(0).Once() - mockConfig.On("GetString", "cache.prefix").Return("goravel_cache").Once() + s.mockConfig.On("GetString", "cache.stores.custom.driver").Return("custom").Once() + s.mockConfig.On("Get", "cache.stores.custom.via").Return(&Store{}).Once() - redis := memory.Store("redis") - s.NotNil(redis) - s.Equal("", redis.GetString("hello")) - s.True(redis.Add("hello", "world", 5*time.Second)) - s.Equal("world", redis.GetString("hello")) + custom := memory.Store("custom") + s.NotNil(custom) + s.Equal("", custom.GetString("hello")) + s.True(custom.Add("hello", "world", 5*time.Second)) + s.Equal("", custom.GetString("hello")) s.Equal("goravel", memory.GetString("hello")) - mockConfig.AssertExpectations(s.T()) -} - -func (s *DriverTestSuite) TestAdd() { - for name, store := range s.stores { - s.Run(name, func() { - s.Nil(store.Put("name", "Goravel", 1*time.Second)) - s.False(store.Add("name", "World", 1*time.Second)) - s.True(store.Add("name1", "World", 1*time.Second)) - s.True(store.Has("name1")) - time.Sleep(2 * time.Second) - s.False(store.Has("name1")) - s.True(store.Flush()) - }) - } -} - -func (s *DriverTestSuite) TestDecrement() { - for name, store := range s.stores { - s.Run(name, func() { - res, err := store.Decrement("decrement") - s.Equal(-1, res) - s.Nil(err) - - s.Equal(-1, store.GetInt("decrement")) - - res, err = store.Decrement("decrement", 2) - s.Equal(-3, res) - s.Nil(err) - - res, err = store.Decrement("decrement1", 2) - s.Equal(-2, res) - s.Nil(err) - - s.Equal(-2, store.GetInt("decrement1")) - - s.True(store.Add("decrement2", 4, 2*time.Second)) - res, err = store.Decrement("decrement2") - s.Equal(3, res) - s.Nil(err) - - res, err = store.Decrement("decrement2", 2) - s.Equal(1, res) - s.Nil(err) - }) - } -} - -func (s *DriverTestSuite) TestForever() { - for name, store := range s.stores { - s.Run(name, func() { - s.True(store.Forever("name", "Goravel")) - s.Equal("Goravel", store.Get("name", "").(string)) - s.True(store.Flush()) - }) - } -} - -func (s *DriverTestSuite) TestForget() { - for name, store := range s.stores { - s.Run(name, func() { - val := store.Forget("test-forget") - s.True(val) - - err := store.Put("test-forget", "goravel", 5*time.Second) - s.Nil(err) - s.True(store.Forget("test-forget")) - }) - } -} - -func (s *DriverTestSuite) TestFlush() { - for name, store := range s.stores { - s.Run(name, func() { - s.Nil(store.Put("test-flush", "goravel", 5*time.Second)) - s.Equal("goravel", store.Get("test-flush", nil).(string)) - - s.True(store.Flush()) - s.False(store.Has("test-flush")) - }) - } -} - -func (s *DriverTestSuite) TestGet() { - for name, store := range s.stores { - s.Run(name, func() { - s.Nil(store.Put("name", "Goravel", 1*time.Second)) - s.Equal("Goravel", store.Get("name", "").(string)) - s.Equal("World", store.Get("name1", "World").(string)) - s.Equal("World1", store.Get("name2", func() any { - return "World1" - }).(string)) - s.True(store.Forget("name")) - s.True(store.Flush()) - }) - } -} - -func (s *DriverTestSuite) TestGetBool() { - for name, store := range s.stores { - s.Run(name, func() { - s.Equal(true, store.GetBool("test-get-bool", true)) - s.Nil(store.Put("test-get-bool", true, 2*time.Second)) - s.Equal(true, store.GetBool("test-get-bool", false)) - }) - } -} - -func (s *DriverTestSuite) TestGetInt() { - for name, store := range s.stores { - s.Run(name, func() { - s.Equal(2, store.GetInt("test-get-int", 2)) - s.Nil(store.Put("test-get-int", 3, 2*time.Second)) - s.Equal(3, store.GetInt("test-get-int", 2)) - }) - } -} - -func (s *DriverTestSuite) TestGetString() { - for name, store := range s.stores { - s.Run(name, func() { - s.Equal("2", store.GetString("test-get-string", "2")) - s.Nil(store.Put("test-get-string", "3", 2*time.Second)) - s.Equal("3", store.GetString("test-get-string", "2")) - }) - } -} - -func (s *DriverTestSuite) TestHas() { - for name, store := range s.stores { - s.Run(name, func() { - s.False(store.Has("test-has")) - s.Nil(store.Put("test-has", "goravel", 5*time.Second)) - s.True(store.Has("test-has")) - }) - } -} - -func (s *DriverTestSuite) TestIncrement() { - for name, store := range s.stores { - s.Run(name, func() { - res, err := store.Increment("Increment") - s.Equal(1, res) - s.Nil(err) - - s.Equal(1, store.GetInt("Increment")) - - res, err = store.Increment("Increment", 2) - s.Equal(3, res) - s.Nil(err) - - res, err = store.Increment("Increment1", 2) - s.Equal(2, res) - s.Nil(err) - - s.Equal(2, store.GetInt("Increment1")) - - s.True(store.Add("Increment2", 1, 2*time.Second)) - res, err = store.Increment("Increment2") - s.Equal(2, res) - s.Nil(err) - - res, err = store.Increment("Increment2", 2) - s.Equal(4, res) - s.Nil(err) - }) - } -} - -func (s *DriverTestSuite) TestLock() { - for _, store := range s.stores { - tests := []struct { - name string - setup func() - }{ - { - name: "once got lock, lock can't be got again", - setup: func() { - lock := store.Lock("lock") - s.True(lock.Get()) - - lock1 := store.Lock("lock") - s.False(lock1.Get()) - - lock.Release() - }, - }, - { - name: "lock can be got again when had been released", - setup: func() { - lock := store.Lock("lock") - s.True(lock.Get()) - - s.True(lock.Release()) - - lock1 := store.Lock("lock") - s.True(lock1.Get()) - - s.True(lock1.Release()) - }, - }, - { - name: "lock cannot be released when had been got", - setup: func() { - lock := store.Lock("lock") - s.True(lock.Get()) - - lock1 := store.Lock("lock") - s.False(lock1.Get()) - s.False(lock1.Release()) - - s.True(lock.Release()) - }, - }, - { - name: "lock can be force released", - setup: func() { - lock := store.Lock("lock") - s.True(lock.Get()) - - lock1 := store.Lock("lock") - s.False(lock1.Get()) - s.False(lock1.Release()) - s.True(lock1.ForceRelease()) - - s.True(lock.Release()) - }, - }, - { - name: "lock can be got again when timeout", - setup: func() { - lock := store.Lock("lock", 1*time.Second) - s.True(lock.Get()) - - time.Sleep(2 * time.Second) - - lock1 := store.Lock("lock") - s.True(lock1.Get()) - s.True(lock1.Release()) - }, - }, - { - name: "lock can be got again when had been released by callback", - setup: func() { - lock := store.Lock("lock") - s.True(lock.Get(func() { - s.True(true) - })) - - lock1 := store.Lock("lock") - s.True(lock1.Get()) - s.True(lock1.Release()) - }, - }, - { - name: "block wait out", - setup: func() { - lock := store.Lock("lock") - s.True(lock.Get()) - - go func() { - lock1 := store.Lock("lock") - s.NotNil(lock1.Block(1 * time.Second)) - }() - - time.Sleep(2 * time.Second) - - lock.Release() - }, - }, - { - name: "get lock by block when just timeout", - setup: func() { - lock := store.Lock("lock") - s.True(lock.Get()) - - go func() { - lock1 := store.Lock("lock") - s.True(lock1.Block(2 * time.Second)) - s.True(lock1.Release()) - }() - - time.Sleep(1 * time.Second) - - lock.Release() - - time.Sleep(2 * time.Second) - }, - }, - { - name: "get lock by block", - setup: func() { - lock := store.Lock("lock") - s.True(lock.Get()) - - go func() { - lock1 := store.Lock("lock") - s.True(lock1.Block(3 * time.Second)) - s.True(lock1.Release()) - }() - - time.Sleep(1 * time.Second) - - lock.Release() - - time.Sleep(3 * time.Second) - }, - }, - { - name: "get lock by block with callback", - setup: func() { - lock := store.Lock("lock") - s.True(lock.Get()) - - go func() { - lock1 := store.Lock("lock") - s.True(lock1.Block(2*time.Second, func() { - s.True(true) - })) - }() - - time.Sleep(1 * time.Second) - - lock.Release() - - time.Sleep(2 * time.Second) - }, - }, - } - - for _, test := range tests { - s.Run(test.name, func() { - test.setup() - }) - } - } -} - -func (s *DriverTestSuite) TestPull() { - for name, store := range s.stores { - s.Run(name, func() { - s.Nil(store.Put("name", "Goravel", 1*time.Second)) - s.True(store.Has("name")) - s.Equal("Goravel", store.Pull("name", "").(string)) - s.False(store.Has("name")) - }) - } -} - -func (s *DriverTestSuite) TestPut() { - for name, store := range s.stores { - s.Run(name, func() { - s.Nil(store.Put("name", "Goravel", 1*time.Second)) - s.True(store.Has("name")) - s.Equal("Goravel", store.Get("name", "").(string)) - time.Sleep(2 * time.Second) - s.False(store.Has("name")) - }) - } -} - -func (s *DriverTestSuite) TestRemember() { - for name, store := range s.stores { - s.Run(name, func() { - s.Nil(store.Put("name", "Goravel", 1*time.Second)) - value, err := store.Remember("name", 1*time.Second, func() any { - return "World" - }) - s.Nil(err) - s.Equal("Goravel", value) - - value, err = store.Remember("name1", 1*time.Second, func() any { - return "World1" - }) - s.Nil(err) - s.Equal("World1", value) - time.Sleep(2 * time.Second) - s.False(store.Has("name1")) - s.True(store.Flush()) - }) - } -} - -func (s *DriverTestSuite) TestRememberForever() { - for name, store := range s.stores { - s.Run(name, func() { - s.Nil(store.Put("name", "Goravel", 1*time.Second)) - value, err := store.RememberForever("name", func() any { - return "World" - }) - s.Nil(err) - s.Equal("Goravel", value) - - value, err = store.RememberForever("name1", func() any { - return "World1" - }) - s.Nil(err) - s.Equal("World1", value) - s.True(store.Flush()) - }) - } -} - -func getRedisDocker() (*dockertest.Pool, *dockertest.Resource, cache.Driver, error) { - mockConfig := &configmock.Config{} - pool, resource, err := testingdocker.Redis() - if err != nil { - return nil, nil, nil, err - } - - var store cache.Driver - if err := pool.Retry(func() error { - var err error - mockConfig.On("GetString", "cache.stores.redis.connection", "default").Return("default").Once() - mockConfig.On("GetString", "database.redis.default.host").Return("localhost").Once() - mockConfig.On("GetString", "database.redis.default.port").Return(resource.GetPort("6379/tcp")).Once() - mockConfig.On("GetString", "database.redis.default.password").Return(resource.GetPort("")).Once() - mockConfig.On("GetInt", "database.redis.default.database").Return(0).Once() - mockConfig.On("GetString", "cache.prefix").Return("goravel_cache").Once() - store, err = NewRedis(context.Background(), mockConfig, "redis") - - return err - }); err != nil { - return nil, nil, nil, err - } - - return pool, resource, store, nil -} - -func getMemoryStore() (*Memory, error) { - mockConfig := &configmock.Config{} - mockConfig.On("GetString", "cache.prefix").Return("goravel_cache").Once() - - memory, err := NewMemory(mockConfig) - if err != nil { - return nil, err - } - - return memory, nil + s.mockConfig.AssertExpectations(s.T()) } type Store struct { diff --git a/cache/memory_test.go b/cache/memory_test.go new file mode 100644 index 000000000..231676a67 --- /dev/null +++ b/cache/memory_test.go @@ -0,0 +1,377 @@ +package cache + +import ( + "testing" + "time" + + "github.com/stretchr/testify/suite" + + configmock "github.com/goravel/framework/contracts/config/mocks" +) + +type MemoryTestSuite struct { + suite.Suite + mockConfig *configmock.Config + memory *Memory +} + +func TestMemoryTestSuite(t *testing.T) { + suite.Run(t, new(MemoryTestSuite)) +} + +func (s *MemoryTestSuite) SetupTest() { + s.mockConfig = &configmock.Config{} + memoryStore, err := getMemoryStore() + s.Nil(err) + s.memory = memoryStore +} + +func (s *MemoryTestSuite) TestAdd() { + s.Nil(s.memory.Put("name", "Goravel", 1*time.Second)) + s.False(s.memory.Add("name", "World", 1*time.Second)) + s.True(s.memory.Add("name1", "World", 1*time.Second)) + s.True(s.memory.Has("name1")) + time.Sleep(2 * time.Second) + s.False(s.memory.Has("name1")) + s.True(s.memory.Flush()) +} + +func (s *MemoryTestSuite) TestDecrement() { + res, err := s.memory.Decrement("decrement") + s.Equal(-1, res) + s.Nil(err) + + s.Equal(-1, s.memory.GetInt("decrement")) + + res, err = s.memory.Decrement("decrement", 2) + s.Equal(-3, res) + s.Nil(err) + + res, err = s.memory.Decrement("decrement1", 2) + s.Equal(-2, res) + s.Nil(err) + + s.Equal(-2, s.memory.GetInt("decrement1")) + + s.True(s.memory.Add("decrement2", 4, 2*time.Second)) + res, err = s.memory.Decrement("decrement2") + s.Equal(3, res) + s.Nil(err) + + res, err = s.memory.Decrement("decrement2", 2) + s.Equal(1, res) + s.Nil(err) +} + +func (s *MemoryTestSuite) TestForever() { + s.True(s.memory.Forever("name", "Goravel")) + s.Equal("Goravel", s.memory.Get("name", "").(string)) + s.True(s.memory.Flush()) +} + +func (s *MemoryTestSuite) TestForget() { + val := s.memory.Forget("test-forget") + s.True(val) + + err := s.memory.Put("test-forget", "goravel", 5*time.Second) + s.Nil(err) + s.True(s.memory.Forget("test-forget")) +} + +func (s *MemoryTestSuite) TestFlush() { + s.Nil(s.memory.Put("test-flush", "goravel", 5*time.Second)) + s.Equal("goravel", s.memory.Get("test-flush", nil).(string)) + + s.True(s.memory.Flush()) + s.False(s.memory.Has("test-flush")) +} + +func (s *MemoryTestSuite) TestGet() { + s.Nil(s.memory.Put("name", "Goravel", 1*time.Second)) + s.Equal("Goravel", s.memory.Get("name", "").(string)) + s.Equal("World", s.memory.Get("name1", "World").(string)) + s.Equal("World1", s.memory.Get("name2", func() any { + return "World1" + }).(string)) + s.True(s.memory.Forget("name")) + s.True(s.memory.Flush()) +} + +func (s *MemoryTestSuite) TestGetBool() { + s.Equal(true, s.memory.GetBool("test-get-bool", true)) + s.Nil(s.memory.Put("test-get-bool", true, 2*time.Second)) + s.Equal(true, s.memory.GetBool("test-get-bool", false)) +} + +func (s *MemoryTestSuite) TestGetInt() { + s.Equal(2, s.memory.GetInt("test-get-int", 2)) + s.Nil(s.memory.Put("test-get-int", 3, 2*time.Second)) + s.Equal(3, s.memory.GetInt("test-get-int", 2)) +} + +func (s *MemoryTestSuite) TestGetString() { + s.Equal("2", s.memory.GetString("test-get-string", "2")) + s.Nil(s.memory.Put("test-get-string", "3", 2*time.Second)) + s.Equal("3", s.memory.GetString("test-get-string", "2")) +} + +func (s *MemoryTestSuite) TestHas() { + s.False(s.memory.Has("test-has")) + s.Nil(s.memory.Put("test-has", "goravel", 5*time.Second)) + s.True(s.memory.Has("test-has")) +} + +func (s *MemoryTestSuite) TestIncrement() { + res, err := s.memory.Increment("Increment") + s.Equal(1, res) + s.Nil(err) + + s.Equal(1, s.memory.GetInt("Increment")) + + res, err = s.memory.Increment("Increment", 2) + s.Equal(3, res) + s.Nil(err) + + res, err = s.memory.Increment("Increment1", 2) + s.Equal(2, res) + s.Nil(err) + + s.Equal(2, s.memory.GetInt("Increment1")) + + s.True(s.memory.Add("Increment2", 1, 2*time.Second)) + res, err = s.memory.Increment("Increment2") + s.Equal(2, res) + s.Nil(err) + + res, err = s.memory.Increment("Increment2", 2) + s.Equal(4, res) + s.Nil(err) +} + +func (s *MemoryTestSuite) TestLock() { + tests := []struct { + name string + setup func() + }{ + { + name: "once got lock, lock can't be got again", + setup: func() { + lock := s.memory.Lock("lock") + s.True(lock.Get()) + + lock1 := s.memory.Lock("lock") + s.False(lock1.Get()) + + lock.Release() + }, + }, + { + name: "lock can be got again when had been released", + setup: func() { + lock := s.memory.Lock("lock") + s.True(lock.Get()) + + s.True(lock.Release()) + + lock1 := s.memory.Lock("lock") + s.True(lock1.Get()) + + s.True(lock1.Release()) + }, + }, + { + name: "lock cannot be released when had been got", + setup: func() { + lock := s.memory.Lock("lock") + s.True(lock.Get()) + + lock1 := s.memory.Lock("lock") + s.False(lock1.Get()) + s.False(lock1.Release()) + + s.True(lock.Release()) + }, + }, + { + name: "lock can be force released", + setup: func() { + lock := s.memory.Lock("lock") + s.True(lock.Get()) + + lock1 := s.memory.Lock("lock") + s.False(lock1.Get()) + s.False(lock1.Release()) + s.True(lock1.ForceRelease()) + + s.True(lock.Release()) + }, + }, + { + name: "lock can be got again when timeout", + setup: func() { + lock := s.memory.Lock("lock", 1*time.Second) + s.True(lock.Get()) + + time.Sleep(2 * time.Second) + + lock1 := s.memory.Lock("lock") + s.True(lock1.Get()) + s.True(lock1.Release()) + }, + }, + { + name: "lock can be got again when had been released by callback", + setup: func() { + lock := s.memory.Lock("lock") + s.True(lock.Get(func() { + s.True(true) + })) + + lock1 := s.memory.Lock("lock") + s.True(lock1.Get()) + s.True(lock1.Release()) + }, + }, + { + name: "block wait out", + setup: func() { + lock := s.memory.Lock("lock") + s.True(lock.Get()) + + go func() { + lock1 := s.memory.Lock("lock") + s.NotNil(lock1.Block(1 * time.Second)) + }() + + time.Sleep(2 * time.Second) + + lock.Release() + }, + }, + { + name: "get lock by block when just timeout", + setup: func() { + lock := s.memory.Lock("lock") + s.True(lock.Get()) + + go func() { + lock1 := s.memory.Lock("lock") + s.True(lock1.Block(2 * time.Second)) + s.True(lock1.Release()) + }() + + time.Sleep(1 * time.Second) + + lock.Release() + + time.Sleep(2 * time.Second) + }, + }, + { + name: "get lock by block", + setup: func() { + lock := s.memory.Lock("lock") + s.True(lock.Get()) + + go func() { + lock1 := s.memory.Lock("lock") + s.True(lock1.Block(3 * time.Second)) + s.True(lock1.Release()) + }() + + time.Sleep(1 * time.Second) + + lock.Release() + + time.Sleep(3 * time.Second) + }, + }, + { + name: "get lock by block with callback", + setup: func() { + lock := s.memory.Lock("lock") + s.True(lock.Get()) + + go func() { + lock1 := s.memory.Lock("lock") + s.True(lock1.Block(2*time.Second, func() { + s.True(true) + })) + }() + + time.Sleep(1 * time.Second) + + lock.Release() + + time.Sleep(2 * time.Second) + }, + }, + } + + for _, test := range tests { + s.Run(test.name, func() { + test.setup() + }) + } +} + +func (s *MemoryTestSuite) TestPull() { + s.Nil(s.memory.Put("name", "Goravel", 1*time.Second)) + s.True(s.memory.Has("name")) + s.Equal("Goravel", s.memory.Pull("name", "").(string)) + s.False(s.memory.Has("name")) +} + +func (s *MemoryTestSuite) TestPut() { + s.Nil(s.memory.Put("name", "Goravel", 1*time.Second)) + s.True(s.memory.Has("name")) + s.Equal("Goravel", s.memory.Get("name", "").(string)) + time.Sleep(2 * time.Second) + s.False(s.memory.Has("name")) +} + +func (s *MemoryTestSuite) TestRemember() { + s.Nil(s.memory.Put("name", "Goravel", 1*time.Second)) + value, err := s.memory.Remember("name", 1*time.Second, func() any { + return "World" + }) + s.Nil(err) + s.Equal("Goravel", value) + + value, err = s.memory.Remember("name1", 1*time.Second, func() any { + return "World1" + }) + s.Nil(err) + s.Equal("World1", value) + time.Sleep(2 * time.Second) + s.False(s.memory.Has("name1")) + s.True(s.memory.Flush()) +} + +func (s *MemoryTestSuite) TestRememberForever() { + s.Nil(s.memory.Put("name", "Goravel", 1*time.Second)) + value, err := s.memory.RememberForever("name", func() any { + return "World" + }) + s.Nil(err) + s.Equal("Goravel", value) + + value, err = s.memory.RememberForever("name1", func() any { + return "World1" + }) + s.Nil(err) + s.Equal("World1", value) + s.True(s.memory.Flush()) +} + +func getMemoryStore() (*Memory, error) { + mockConfig := &configmock.Config{} + mockConfig.On("GetString", "cache.prefix").Return("goravel_cache").Once() + + memory, err := NewMemory(mockConfig) + if err != nil { + return nil, err + } + + return memory, nil +} diff --git a/cache/redis.go b/cache/redis.go deleted file mode 100644 index 9db50f21d..000000000 --- a/cache/redis.go +++ /dev/null @@ -1,259 +0,0 @@ -package cache - -import ( - "context" - "fmt" - "strconv" - "time" - - "github.com/go-redis/redis/v8" - "github.com/pkg/errors" - "github.com/spf13/cast" - - "github.com/goravel/framework/contracts/cache" - "github.com/goravel/framework/contracts/config" -) - -type Redis struct { - ctx context.Context - config config.Config - prefix string - instance *redis.Client - store string -} - -func NewRedis(ctx context.Context, config config.Config, store string) (*Redis, error) { - connection := config.GetString(fmt.Sprintf("cache.stores.%s.connection", store), "default") - host := config.GetString("database.redis." + connection + ".host") - if host == "" { - return nil, nil - } - - client := redis.NewClient(&redis.Options{ - Addr: host + ":" + config.GetString("database.redis."+connection+".port"), - Password: config.GetString("database.redis." + connection + ".password"), - DB: config.GetInt("database.redis." + connection + ".database"), - }) - - if _, err := client.Ping(context.Background()).Result(); err != nil { - return nil, errors.WithMessage(err, "init connection error") - } - - return &Redis{ - ctx: ctx, - prefix: prefix(config), - instance: client, - store: store, - }, nil -} - -//Add Driver an item in the cache if the key does not exist. -func (r *Redis) Add(key string, value any, t time.Duration) bool { - val, err := r.instance.SetNX(r.ctx, r.key(key), value, t).Result() - if err != nil { - return false - } - - return val -} - -func (r *Redis) Decrement(key string, value ...int) (int, error) { - if len(value) == 0 { - value = append(value, 1) - } - - res, err := r.instance.DecrBy(r.ctx, r.key(key), int64(value[0])).Result() - - return int(res), err -} - -//Forever Driver an item in the cache indefinitely. -func (r *Redis) Forever(key string, value any) bool { - if err := r.Put(key, value, 0); err != nil { - return false - } - - return true -} - -//Forget Remove an item from the cache. -func (r *Redis) Forget(key string) bool { - _, err := r.instance.Del(r.ctx, r.key(key)).Result() - - return err == nil -} - -//Flush Remove all items from the cache. -func (r *Redis) Flush() bool { - res, err := r.instance.FlushAll(r.ctx).Result() - - if err != nil || res != "OK" { - return false - } - - return true -} - -//Get Retrieve an item from the cache by key. -func (r *Redis) Get(key string, def ...any) any { - val, err := r.instance.Get(r.ctx, r.key(key)).Result() - if err != nil { - if len(def) == 0 { - return nil - } - - switch s := def[0].(type) { - case func() any: - return s() - default: - return s - } - } - - return val -} - -func (r *Redis) GetBool(key string, def ...bool) bool { - if len(def) == 0 { - def = append(def, false) - } - res := r.Get(key, def[0]) - if val, ok := res.(string); ok { - return val == "1" - } - - return cast.ToBool(res) -} - -func (r *Redis) GetInt(key string, def ...int) int { - if len(def) == 0 { - def = append(def, 1) - } - res := r.Get(key, def[0]) - if val, ok := res.(string); ok { - i, err := strconv.Atoi(val) - if err != nil { - return def[0] - } - - return i - } - - return cast.ToInt(res) -} - -func (r *Redis) GetInt64(key string, def ...int64) int64 { - if len(def) == 0 { - def = append(def, 1) - } - res := r.Get(key, def[0]) - if val, ok := res.(string); ok { - i, err := strconv.ParseInt(val, 10, 64) - if err != nil { - return def[0] - } - - return i - } - - return cast.ToInt64(res) -} - -func (r *Redis) GetString(key string, def ...string) string { - if len(def) == 0 { - def = append(def, "") - } - return cast.ToString(r.Get(key, def[0])) -} - -//Has Check an item exists in the cache. -func (r *Redis) Has(key string) bool { - value, err := r.instance.Exists(r.ctx, r.key(key)).Result() - - if err != nil || value == 0 { - return false - } - - return true -} - -func (r *Redis) Increment(key string, value ...int) (int, error) { - if len(value) == 0 { - value = append(value, 1) - } - - res, err := r.instance.IncrBy(r.ctx, r.key(key), int64(value[0])).Result() - - return int(res), err -} - -func (r *Redis) Lock(key string, t ...time.Duration) cache.Lock { - return NewLock(r, key, t...) -} - -//Put Driver an item in the cache for a given time. -func (r *Redis) Put(key string, value any, t time.Duration) error { - err := r.instance.Set(r.ctx, r.key(key), value, t).Err() - if err != nil { - return err - } - - return nil -} - -//Pull Retrieve an item from the cache and delete it. -func (r *Redis) Pull(key string, def ...any) any { - var res any - if len(def) == 0 { - res = r.Get(key) - } else { - res = r.Get(key, def[0]) - } - r.Forget(key) - - return res -} - -//Remember Get an item from the cache, or execute the given Closure and store the result. -func (r *Redis) Remember(key string, seconds time.Duration, callback func() any) (any, error) { - val := r.Get(key, nil) - - if val != nil { - return val, nil - } - - val = callback() - - if err := r.Put(key, val, seconds); err != nil { - return nil, err - } - - return val, nil -} - -//RememberForever Get an item from the cache, or execute the given Closure and store the result forever. -func (r *Redis) RememberForever(key string, callback func() any) (any, error) { - val := r.Get(key, nil) - - if val != nil { - return val, nil - } - - val = callback() - - if err := r.Put(key, val, 0); err != nil { - return nil, err - } - - return val, nil -} - -func (r *Redis) WithContext(ctx context.Context) cache.Driver { - store, _ := NewRedis(ctx, r.config, r.store) - - return store -} - -func (r *Redis) key(key string) string { - return r.prefix + key -} From dc4f0063af1835b8559a33fc15aae4fad5332136 Mon Sep 17 00:00:00 2001 From: Wenbo han Date: Fri, 9 Jun 2023 23:06:08 +0800 Subject: [PATCH 2/2] Optimize lint --- cache/driver_test.go | 19 +++---------------- 1 file changed, 3 insertions(+), 16 deletions(-) diff --git a/cache/driver_test.go b/cache/driver_test.go index 39f6fd1ad..40de55ca5 100644 --- a/cache/driver_test.go +++ b/cache/driver_test.go @@ -2,11 +2,9 @@ package cache import ( "context" - "log" "testing" "time" - "github.com/ory/dockertest/v3" "github.com/stretchr/testify/suite" "github.com/goravel/framework/contracts/cache" @@ -15,23 +13,12 @@ import ( type DriverTestSuite struct { suite.Suite - driver *DriverImpl - mockConfig *configmock.Config - stores map[string]cache.Driver - redisDocker *dockertest.Resource + driver *DriverImpl + mockConfig *configmock.Config } func TestDriverTestSuite(t *testing.T) { - memoryStore, err := getMemoryStore() - if err != nil { - log.Fatalf("Get memory store error: %s", err) - } - - suite.Run(t, &DriverTestSuite{ - stores: map[string]cache.Driver{ - "memory": memoryStore, - }, - }) + suite.Run(t, new(DriverTestSuite)) } func (s *DriverTestSuite) SetupTest() {