mirror of
https://github.com/halejohn/Cloudreve.git
synced 2026-01-26 09:34:57 +08:00
Fix: failed unit test / Feat: support TTL in redis cache
This commit is contained in:
8
pkg/cache/driver.go
vendored
8
pkg/cache/driver.go
vendored
@@ -12,7 +12,7 @@ var Store Driver = NewMemoStore()
|
||||
func Init() {
|
||||
//Store = NewRedisStore(10, "tcp", "127.0.0.1:6379", "", "0")
|
||||
//return
|
||||
if conf.RedisConfig.Server != "" && gin.Mode() == gin.TestMode {
|
||||
if conf.RedisConfig.Server != "" && gin.Mode() != gin.TestMode {
|
||||
Store = NewRedisStore(
|
||||
10,
|
||||
"tcp",
|
||||
@@ -26,7 +26,7 @@ func Init() {
|
||||
// Driver 键值缓存存储容器
|
||||
type Driver interface {
|
||||
// 设置值
|
||||
Set(key string, value interface{}) error
|
||||
Set(key string, value interface{}, ttl int) error
|
||||
// 取值
|
||||
Get(key string) (interface{}, bool)
|
||||
// 批量取值,返回成功取值的map即不存在的值
|
||||
@@ -38,8 +38,8 @@ type Driver interface {
|
||||
}
|
||||
|
||||
// Set 设置缓存值
|
||||
func Set(key string, value interface{}) error {
|
||||
return Store.Set(key, value)
|
||||
func Set(key string, value interface{}, ttl int) error {
|
||||
return Store.Set(key, value, ttl)
|
||||
}
|
||||
|
||||
// Get 获取缓存值
|
||||
|
||||
6
pkg/cache/driver_test.go
vendored
6
pkg/cache/driver_test.go
vendored
@@ -8,12 +8,12 @@ import (
|
||||
func TestSet(t *testing.T) {
|
||||
asserts := assert.New(t)
|
||||
|
||||
asserts.NoError(Set("123", "321"))
|
||||
asserts.NoError(Set("123", "321", -1))
|
||||
}
|
||||
|
||||
func TestGet(t *testing.T) {
|
||||
asserts := assert.New(t)
|
||||
asserts.NoError(Set("123", "321"))
|
||||
asserts.NoError(Set("123", "321", -1))
|
||||
|
||||
value, ok := Get("123")
|
||||
asserts.True(ok)
|
||||
@@ -25,7 +25,7 @@ func TestGet(t *testing.T) {
|
||||
|
||||
func TestGetSettings(t *testing.T) {
|
||||
asserts := assert.New(t)
|
||||
asserts.NoError(Set("test_1", "1"))
|
||||
asserts.NoError(Set("test_1", "1", -1))
|
||||
|
||||
values, missed := GetSettings([]string{"1", "2"}, "test_")
|
||||
asserts.Equal(map[string]string{"1": "1"}, values)
|
||||
|
||||
2
pkg/cache/memo.go
vendored
2
pkg/cache/memo.go
vendored
@@ -15,7 +15,7 @@ func NewMemoStore() *MemoStore {
|
||||
}
|
||||
|
||||
// Set 存储值
|
||||
func (store *MemoStore) Set(key string, value interface{}) error {
|
||||
func (store *MemoStore) Set(key string, value interface{}, ttl int) error {
|
||||
store.Store.Store(key, value)
|
||||
return nil
|
||||
}
|
||||
|
||||
14
pkg/cache/memo_test.go
vendored
14
pkg/cache/memo_test.go
vendored
@@ -17,7 +17,7 @@ func TestMemoStore_Set(t *testing.T) {
|
||||
asserts := assert.New(t)
|
||||
|
||||
store := NewMemoStore()
|
||||
err := store.Set("KEY", "vAL")
|
||||
err := store.Set("KEY", "vAL", -1)
|
||||
asserts.NoError(err)
|
||||
|
||||
val, ok := store.Store.Load("KEY")
|
||||
@@ -31,7 +31,7 @@ func TestMemoStore_Get(t *testing.T) {
|
||||
|
||||
// 正常情况
|
||||
{
|
||||
_ = store.Set("string", "string_val")
|
||||
_ = store.Set("string", "string_val", -1)
|
||||
val, ok := store.Get("string")
|
||||
asserts.Equal("string_val", val)
|
||||
asserts.True(ok)
|
||||
@@ -50,7 +50,7 @@ func TestMemoStore_Get(t *testing.T) {
|
||||
key int
|
||||
}
|
||||
test := testStruct{key: 233}
|
||||
_ = store.Set("struct", test)
|
||||
_ = store.Set("struct", test, -1)
|
||||
val, ok := store.Get("struct")
|
||||
asserts.True(ok)
|
||||
res, ok := val.(testStruct)
|
||||
@@ -64,10 +64,10 @@ func TestMemoStore_Gets(t *testing.T) {
|
||||
asserts := assert.New(t)
|
||||
store := NewMemoStore()
|
||||
|
||||
err := store.Set("1", "1,val")
|
||||
err = store.Set("2", "2,val")
|
||||
err = store.Set("3", "3,val")
|
||||
err = store.Set("4", "4,val")
|
||||
err := store.Set("1", "1,val", -1)
|
||||
err = store.Set("2", "2,val", -1)
|
||||
err = store.Set("3", "3,val", -1)
|
||||
err = store.Set("4", "4,val", -1)
|
||||
asserts.NoError(err)
|
||||
|
||||
// 全部命中
|
||||
|
||||
9
pkg/cache/redis.go
vendored
9
pkg/cache/redis.go
vendored
@@ -75,7 +75,7 @@ func NewRedisStore(size int, network, address, password, database string) *Redis
|
||||
}
|
||||
|
||||
// Set 存储值
|
||||
func (store *RedisStore) Set(key string, value interface{}) error {
|
||||
func (store *RedisStore) Set(key string, value interface{}, ttl int) error {
|
||||
rc := store.pool.Get()
|
||||
defer rc.Close()
|
||||
|
||||
@@ -88,7 +88,12 @@ func (store *RedisStore) Set(key string, value interface{}) error {
|
||||
return rc.Err()
|
||||
}
|
||||
|
||||
_, err = rc.Do("SET", key, serialized)
|
||||
if ttl > 0 {
|
||||
_, err = rc.Do("SETEX", key, ttl, serialized)
|
||||
} else {
|
||||
_, err = rc.Do("SET", key, serialized)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
20
pkg/cache/redis_test.go
vendored
20
pkg/cache/redis_test.go
vendored
@@ -42,7 +42,19 @@ func TestRedisStore_Set(t *testing.T) {
|
||||
// 正常情况
|
||||
{
|
||||
cmd := conn.Command("SET", "test", redigomock.NewAnyData()).ExpectStringSlice("OK")
|
||||
err := store.Set("test", "test val")
|
||||
err := store.Set("test", "test val", -1)
|
||||
asserts.NoError(err)
|
||||
if conn.Stats(cmd) != 1 {
|
||||
fmt.Println("Command was not used")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// 带有TTL
|
||||
// 正常情况
|
||||
{
|
||||
cmd := conn.Command("SETEX", "test", 10, redigomock.NewAnyData()).ExpectStringSlice("OK")
|
||||
err := store.Set("test", "test val", 10)
|
||||
asserts.NoError(err)
|
||||
if conn.Stats(cmd) != 1 {
|
||||
fmt.Println("Command was not used")
|
||||
@@ -57,7 +69,7 @@ func TestRedisStore_Set(t *testing.T) {
|
||||
}{
|
||||
Key: "123",
|
||||
}
|
||||
err := store.Set("test", value)
|
||||
err := store.Set("test", value, -1)
|
||||
asserts.Error(err)
|
||||
}
|
||||
|
||||
@@ -65,7 +77,7 @@ func TestRedisStore_Set(t *testing.T) {
|
||||
{
|
||||
conn.Clear()
|
||||
cmd := conn.Command("SET", "test", redigomock.NewAnyData()).ExpectError(errors.New("error"))
|
||||
err := store.Set("test", "test val")
|
||||
err := store.Set("test", "test val", -1)
|
||||
asserts.Error(err)
|
||||
if conn.Stats(cmd) != 1 {
|
||||
fmt.Println("Command was not used")
|
||||
@@ -78,7 +90,7 @@ func TestRedisStore_Set(t *testing.T) {
|
||||
Dial: func() (redis.Conn, error) { return nil, errors.New("error") },
|
||||
MaxIdle: 10,
|
||||
}
|
||||
err := store.Set("test", "123")
|
||||
err := store.Set("test", "123", -1)
|
||||
asserts.Error(err)
|
||||
}
|
||||
|
||||
|
||||
@@ -85,7 +85,7 @@ func (fs *FileSystem) doCompress(ctx context.Context, file *model.File, folder *
|
||||
|
||||
// 创建压缩文件头
|
||||
header := &zip.FileHeader{
|
||||
Name: file.Name,
|
||||
Name: filepath.Join(file.Position, file.Name),
|
||||
Modified: file.UpdatedAt,
|
||||
UncompressedSize64: file.Size,
|
||||
}
|
||||
@@ -103,5 +103,22 @@ func (fs *FileSystem) doCompress(ctx context.Context, file *model.File, folder *
|
||||
}
|
||||
|
||||
_, err = io.Copy(writer, fileToZip)
|
||||
} else if folder != nil {
|
||||
// 对象是目录
|
||||
// 获取子文件
|
||||
subFiles, err := folder.GetChildFiles()
|
||||
if err == nil && len(subFiles) > 0 {
|
||||
for i := 0; i < len(subFiles); i++ {
|
||||
fs.doCompress(ctx, &subFiles[i], nil, zipWriter, isArchive)
|
||||
}
|
||||
|
||||
}
|
||||
// 获取子目录,继续递归遍历
|
||||
subFolders, err := folder.GetChildFolder()
|
||||
if err == nil && len(subFolders) > 0 {
|
||||
for i := 0; i < len(subFolders); i++ {
|
||||
fs.doCompress(ctx, nil, &subFolders[i], zipWriter, isArchive)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,6 +52,7 @@ func TestFileSystem_AddFile(t *testing.T) {
|
||||
f, err := fs.AddFile(ctx, &folder)
|
||||
|
||||
asserts.NoError(err)
|
||||
asserts.NoError(mock.ExpectationsWereMet())
|
||||
asserts.Equal("/Uploads/1_sad.txt", f.SourceName)
|
||||
}
|
||||
|
||||
@@ -146,6 +147,7 @@ func TestFileSystem_GetDownloadContent(t *testing.T) {
|
||||
_, err = fs.GetDownloadContent(ctx, "/TestFileSystem_GetDownloadContent.txt")
|
||||
asserts.NoError(err)
|
||||
asserts.NoError(mock.ExpectationsWereMet())
|
||||
fs.CleanTargets()
|
||||
|
||||
// 有限速
|
||||
mock.ExpectQuery("SELECT(.+)").
|
||||
@@ -302,6 +304,7 @@ func TestFileSystem_GetSource(t *testing.T) {
|
||||
asserts.NoError(mock.ExpectationsWereMet())
|
||||
asserts.NoError(err)
|
||||
asserts.NotEmpty(sourceURL)
|
||||
fs.CleanTargets()
|
||||
}
|
||||
|
||||
// 文件不存在
|
||||
@@ -321,6 +324,7 @@ func TestFileSystem_GetSource(t *testing.T) {
|
||||
asserts.Error(err)
|
||||
asserts.Equal(ErrObjectNotExist.Code, err.(serializer.AppError).Code)
|
||||
asserts.Empty(sourceURL)
|
||||
fs.CleanTargets()
|
||||
}
|
||||
|
||||
// 未知上传策略
|
||||
@@ -346,6 +350,7 @@ func TestFileSystem_GetSource(t *testing.T) {
|
||||
asserts.NoError(mock.ExpectationsWereMet())
|
||||
asserts.Error(err)
|
||||
asserts.Empty(sourceURL)
|
||||
fs.CleanTargets()
|
||||
}
|
||||
|
||||
// 不允许获取外链
|
||||
@@ -372,5 +377,6 @@ func TestFileSystem_GetSource(t *testing.T) {
|
||||
asserts.Error(err)
|
||||
asserts.Equal(serializer.CodePolicyNotAllowed, err.(serializer.AppError).Code)
|
||||
asserts.Empty(sourceURL)
|
||||
fs.CleanTargets()
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user