可靠性: 完善 R2 备份恢复与对象生命周期
This commit is contained in:
@@ -0,0 +1,95 @@
|
||||
package db
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
func uploadImageCount(t *testing.T, conn *gorm.DB, id uint) int64 {
|
||||
t.Helper()
|
||||
var count int64
|
||||
require.NoError(t, conn.Unscoped().Model(&UploadImage{}).Where("id = ?", id).Count(&count).Error)
|
||||
return count
|
||||
}
|
||||
|
||||
func TestUploadImagesDeleteByQuestionIDOutbox(t *testing.T) {
|
||||
setR2TestConfig(t)
|
||||
conn, _ := newTestDB(t)
|
||||
ctx := context.Background()
|
||||
images := NewUploadImagesStore(conn)
|
||||
tasks := NewR2DeleteTaskStore(conn)
|
||||
|
||||
first, err := images.Create(ctx, CreateUploadImageOptions{QuestionID: 1, Key: "unique.webp"})
|
||||
require.NoError(t, err)
|
||||
duplicate, err := images.Create(ctx, CreateUploadImageOptions{QuestionID: 1, Key: "unique.webp"})
|
||||
require.NoError(t, err)
|
||||
shared, err := images.Create(ctx, CreateUploadImageOptions{QuestionID: 1, Key: "shared.webp"})
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, conn.WithContext(ctx).Create(&UploadImageQuestion{
|
||||
UploadImageID: shared.ID,
|
||||
QuestionID: 2,
|
||||
}).Error)
|
||||
|
||||
require.NoError(t, images.DeleteByQuestionID(ctx, 1))
|
||||
require.Zero(t, uploadImageCount(t, conn, first.ID))
|
||||
require.Zero(t, uploadImageCount(t, conn, duplicate.ID))
|
||||
require.Equal(t, int64(1), uploadImageCount(t, conn, shared.ID))
|
||||
|
||||
due, err := tasks.ListDue(ctx, 10)
|
||||
require.NoError(t, err)
|
||||
require.Len(t, due, 1, "重复 key 必须去重,共享主体不得入队")
|
||||
require.Equal(t, "unique.webp", due[0].Key)
|
||||
|
||||
require.NoError(t, images.DeleteByQuestionID(ctx, 2))
|
||||
require.Zero(t, uploadImageCount(t, conn, shared.ID))
|
||||
due, err = tasks.ListDue(ctx, 10)
|
||||
require.NoError(t, err)
|
||||
require.Len(t, due, 2)
|
||||
require.ElementsMatch(t, []string{"unique.webp", "shared.webp"}, []string{due[0].Key, due[1].Key})
|
||||
}
|
||||
|
||||
func TestUploadImagesReplaceDeletesOnlyOrphanedPrevious(t *testing.T) {
|
||||
setR2TestConfig(t)
|
||||
conn, _ := newTestDB(t)
|
||||
ctx := context.Background()
|
||||
images := NewUploadImagesStore(conn)
|
||||
tasks := NewR2DeleteTaskStore(conn)
|
||||
|
||||
old, err := images.Create(ctx, CreateUploadImageOptions{
|
||||
Type: UploadImageQuestionTypeAnswer,
|
||||
QuestionID: 10,
|
||||
Key: "old.webp",
|
||||
})
|
||||
require.NoError(t, err)
|
||||
shared, err := images.Create(ctx, CreateUploadImageOptions{
|
||||
Type: UploadImageQuestionTypeAnswer,
|
||||
QuestionID: 10,
|
||||
Key: "shared-old.webp",
|
||||
})
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, conn.WithContext(ctx).Create(&UploadImageQuestion{
|
||||
Type: UploadImageQuestionTypeAnswer,
|
||||
UploadImageID: shared.ID,
|
||||
QuestionID: 11,
|
||||
}).Error)
|
||||
|
||||
newImage, err := images.Create(ctx, CreateUploadImageOptions{
|
||||
Type: UploadImageQuestionTypeAnswer,
|
||||
QuestionID: 10,
|
||||
Key: "new.webp",
|
||||
IsDeletingPrevious: true,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
require.Zero(t, uploadImageCount(t, conn, old.ID))
|
||||
require.Equal(t, int64(1), uploadImageCount(t, conn, shared.ID))
|
||||
require.Equal(t, int64(1), uploadImageCount(t, conn, newImage.ID))
|
||||
|
||||
due, err := tasks.ListDue(ctx, 10)
|
||||
require.NoError(t, err)
|
||||
require.Len(t, due, 1)
|
||||
require.Equal(t, "old.webp", due[0].Key)
|
||||
require.NotEqual(t, newImage.Key, due[0].Key)
|
||||
}
|
||||
Reference in New Issue
Block a user