Files
opencloud/services/storage-users/pkg/task/trash_bin_test.go
2025-01-21 11:16:38 +01:00

207 lines
6.8 KiB
Go

package task_test
import (
"context"
"encoding/json"
"errors"
"time"
apiGateway "github.com/cs3org/go-cs3apis/cs3/gateway/v1beta1"
gateway "github.com/cs3org/go-cs3apis/cs3/gateway/v1beta1"
apiUser "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1"
apiRpc "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1"
apiProvider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
apiTypes "github.com/cs3org/go-cs3apis/cs3/types/v1beta1"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
"github.com/opencloud-eu/opencloud/services/storage-users/pkg/task"
"github.com/opencloud-eu/reva/v2/pkg/rgrpc/status"
"github.com/opencloud-eu/reva/v2/pkg/rgrpc/todo/pool"
"github.com/opencloud-eu/reva/v2/pkg/utils"
cs3mocks "github.com/opencloud-eu/reva/v2/tests/cs3mocks/mocks"
"github.com/stretchr/testify/mock"
"google.golang.org/grpc"
)
func MustMarshal(v any) []byte {
b, err := json.Marshal(v)
if err != nil {
panic(err)
}
return b
}
var _ = Describe("trash", func() {
var (
gatewayClient *cs3mocks.GatewayAPIClient
gatewaySelector pool.Selectable[gateway.GatewayAPIClient]
ctx context.Context
now time.Time
genericError error
user *apiUser.User
getUserResponse *apiUser.GetUserResponse
authenticateResponse *apiGateway.AuthenticateResponse
listStorageSpacesResponse *apiProvider.ListStorageSpacesResponse
personalSpace *apiProvider.StorageSpace
projectSpace *apiProvider.StorageSpace
virtualSpace *apiProvider.StorageSpace
)
BeforeEach(func() {
pool.RemoveSelector("GatewaySelector" + "eu.opencloud.api.gateway")
gatewayClient = &cs3mocks.GatewayAPIClient{}
gatewaySelector = pool.GetSelector[gateway.GatewayAPIClient](
"GatewaySelector",
"eu.opencloud.api.gateway",
func(cc grpc.ClientConnInterface) gateway.GatewayAPIClient {
return gatewayClient
},
)
ctx = context.Background()
now = time.Now()
genericError = errors.New("any")
getUserResponse = &apiUser.GetUserResponse{
Status: status.NewOK(ctx),
}
authenticateResponse = &apiGateway.AuthenticateResponse{
Status: status.NewOK(ctx),
Token: "",
}
listStorageSpacesResponse = &apiProvider.ListStorageSpacesResponse{
Status: status.NewOK(ctx),
StorageSpaces: []*apiProvider.StorageSpace{},
}
personalSpace = &apiProvider.StorageSpace{
SpaceType: "personal",
Id: &apiProvider.StorageSpaceId{
OpaqueId: "personal",
},
Root: &apiProvider.ResourceId{
OpaqueId: "personal",
},
}
projectSpace = &apiProvider.StorageSpace{
SpaceType: "project",
Id: &apiProvider.StorageSpaceId{
OpaqueId: "project",
},
Root: &apiProvider.ResourceId{
OpaqueId: "project",
},
Opaque: &apiTypes.Opaque{},
}
// virtual is here as an example,
// the task ignores all space types expect `project` and `personal`.
virtualSpace = &apiProvider.StorageSpace{
SpaceType: "virtual",
Id: &apiProvider.StorageSpaceId{
OpaqueId: "virtual",
},
Root: &apiProvider.ResourceId{
OpaqueId: "virtual",
},
}
user = &apiUser.User{
Id: &apiUser.UserId{
OpaqueId: "user",
},
}
})
Describe("PurgeTrashBin", func() {
It("throws an error if the user cannot authenticate", func() {
gatewayClient.On("GetUser", mock.Anything, mock.Anything).Return(getUserResponse, nil)
gatewayClient.On("Authenticate", mock.Anything, mock.Anything).Return(nil, genericError)
err := task.PurgeTrashBin("service-user-id", now, task.Project, gatewaySelector, "")
Expect(err).To(HaveOccurred())
})
It("throws an error if space listing fails", func() {
gatewayClient.On("GetUser", mock.Anything, mock.Anything).Return(getUserResponse, nil)
gatewayClient.On("Authenticate", mock.Anything, mock.Anything).Return(authenticateResponse, nil)
gatewayClient.On("ListStorageSpaces", mock.Anything, mock.Anything).Return(nil, genericError)
err := task.PurgeTrashBin("service-user-id", now, task.Project, gatewaySelector, "")
Expect(err).To(HaveOccurred())
})
It("only deletes items older than the specified period", func() {
var (
recycleItems = map[string][]*apiProvider.RecycleItem{
"personal": {
{Key: "now", DeletionTime: utils.TimeToTS(now)},
{Key: "after", DeletionTime: utils.TimeToTS(now.Add(1 * time.Second))},
{Key: "before", DeletionTime: utils.TimeToTS(now.Add(-1 * time.Second))},
},
"project": {
{Key: "now", DeletionTime: utils.TimeToTS(now)},
{Key: "after", DeletionTime: utils.TimeToTS(now.Add(1 * time.Minute))},
{Key: "before", DeletionTime: utils.TimeToTS(now.Add(-1 * time.Minute))},
},
"virtual": {
{Key: "now", DeletionTime: utils.TimeToTS(now)},
{Key: "after", DeletionTime: utils.TimeToTS(now.Add(1 * time.Hour))},
{Key: "before", DeletionTime: utils.TimeToTS(now.Add(-1 * time.Hour))},
},
}
)
personalSpace.Owner = user
listStorageSpacesResponse.StorageSpaces = []*apiProvider.StorageSpace{
personalSpace,
projectSpace,
virtualSpace,
}
projectSpace.Opaque.Map = map[string]*apiTypes.OpaqueEntry{
"grants": {
Decoder: "json",
Value: MustMarshal(map[string]*apiProvider.ResourcePermissions{
"admin": {
Delete: true,
},
}),
},
}
gatewayClient.On("GetUser", mock.Anything, mock.Anything).Return(getUserResponse, nil)
gatewayClient.On("Authenticate", mock.Anything, mock.Anything).Return(authenticateResponse, nil)
gatewayClient.On("ListStorageSpaces", mock.Anything, mock.Anything).Return(listStorageSpacesResponse, nil)
gatewayClient.On("ListRecycle", mock.Anything, mock.Anything).Return(
func(_ context.Context, req *apiProvider.ListRecycleRequest, _ ...grpc.CallOption) *apiProvider.ListRecycleResponse {
return &apiProvider.ListRecycleResponse{
RecycleItems: recycleItems[req.Ref.ResourceId.OpaqueId],
}
}, nil,
)
gatewayClient.On("PurgeRecycle", mock.Anything, mock.Anything).Return(
func(_ context.Context, req *apiProvider.PurgeRecycleRequest, _ ...grpc.CallOption) *apiProvider.PurgeRecycleResponse {
var items []*apiProvider.RecycleItem
for _, item := range recycleItems[req.Ref.ResourceId.OpaqueId] {
if req.Key == item.Key {
continue
}
items = append(items, item)
}
recycleItems[req.Ref.ResourceId.OpaqueId] = items
return &apiProvider.PurgeRecycleResponse{
Status: &apiRpc.Status{
Code: apiRpc.Code_CODE_OK,
},
}
}, nil,
)
err := task.PurgeTrashBin("service-user-id", now, task.Project, gatewaySelector, "")
Expect(err).To(BeNil())
Expect(recycleItems["personal"]).To(HaveLen(2))
Expect(recycleItems["project"]).To(HaveLen(2))
// virtual spaces are ignored
Expect(recycleItems["virtual"]).To(HaveLen(3))
})
})
})