forked from TrueCloudLab/frostfs-rest-gw
[#36] Add test for storage group management
Signed-off-by: Denis Kirillov <denis@nspcc.ru>
This commit is contained in:
parent
e83cef6d24
commit
6e8b6f8b51
2 changed files with 117 additions and 2 deletions
|
@ -135,6 +135,8 @@ func runTests(ctx context.Context, t *testing.T, key *keys.PrivateKey, version s
|
||||||
t.Run("rest put container eacl "+version, func(t *testing.T) { restContainerEACLPut(ctx, t, clientPool, owner) })
|
t.Run("rest put container eacl "+version, func(t *testing.T) { restContainerEACLPut(ctx, t, clientPool, owner) })
|
||||||
t.Run("rest get container eacl "+version, func(t *testing.T) { restContainerEACLGet(ctx, t, clientPool, cnrID) })
|
t.Run("rest get container eacl "+version, func(t *testing.T) { restContainerEACLGet(ctx, t, clientPool, cnrID) })
|
||||||
t.Run("rest list containers "+version, func(t *testing.T) { restContainerList(ctx, t, clientPool, owner, cnrID) })
|
t.Run("rest list containers "+version, func(t *testing.T) { restContainerList(ctx, t, clientPool, owner, cnrID) })
|
||||||
|
|
||||||
|
t.Run("rest manage storage group "+version, func(t *testing.T) { restManageStorageGroup(ctx, t, clientPool, owner, cnrID) })
|
||||||
}
|
}
|
||||||
|
|
||||||
func createDockerContainer(ctx context.Context, t *testing.T, image string) testcontainers.Container {
|
func createDockerContainer(ctx context.Context, t *testing.T, image string) testcontainers.Container {
|
||||||
|
@ -443,6 +445,117 @@ func checkGWErrorResponse(t *testing.T, httpClient *http.Client, request *http.R
|
||||||
require.Equal(t, models.ErrorTypeGW, *resp.Type)
|
require.Equal(t, models.ErrorTypeGW, *resp.Type)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func restManageStorageGroup(ctx context.Context, t *testing.T, clientPool *pool.Pool, owner user.ID, cnrID cid.ID) {
|
||||||
|
attributes := map[string]string{object.AttributeFileName: "someFile"}
|
||||||
|
content := []byte("content")
|
||||||
|
objID := createObject(ctx, t, clientPool, &owner, cnrID, attributes, content)
|
||||||
|
|
||||||
|
bearer := &models.Bearer{Object: getAllowedRules()}
|
||||||
|
httpClient := defaultHTTPClient()
|
||||||
|
bearerTokens := makeAuthTokenRequest(ctx, t, []*models.Bearer{bearer}, httpClient)
|
||||||
|
bearerToken := bearerTokens[0]
|
||||||
|
|
||||||
|
query := make(url.Values)
|
||||||
|
query.Add(walletConnectQuery, strconv.FormatBool(useWalletConnect))
|
||||||
|
|
||||||
|
var storageGroupAddress models.Address
|
||||||
|
storageGroupName := "my-storage-group"
|
||||||
|
t.Run("put storage group", func(t *testing.T) {
|
||||||
|
req := &models.StorageGroupPutBody{
|
||||||
|
Lifetime: util.NewInteger(10),
|
||||||
|
Members: []string{objID.EncodeToString()},
|
||||||
|
Name: storageGroupName,
|
||||||
|
}
|
||||||
|
|
||||||
|
body, err := json.Marshal(req)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
request, err := http.NewRequest(http.MethodPut, testHost+"/v1/containers/"+cnrID.EncodeToString()+"/storagegroups?"+query.Encode(), bytes.NewReader(body))
|
||||||
|
require.NoError(t, err)
|
||||||
|
prepareCommonHeaders(request.Header, bearerToken)
|
||||||
|
|
||||||
|
doRequest(t, httpClient, request, http.StatusOK, &storageGroupAddress)
|
||||||
|
require.Equal(t, cnrID.EncodeToString(), *storageGroupAddress.ContainerID)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("list storage groups", func(t *testing.T) {
|
||||||
|
request, err := http.NewRequest(http.MethodGet, testHost+"/v1/containers/"+cnrID.EncodeToString()+"/storagegroups?"+query.Encode(), nil)
|
||||||
|
require.NoError(t, err)
|
||||||
|
prepareCommonHeaders(request.Header, bearerToken)
|
||||||
|
|
||||||
|
list := &models.StorageGroupList{}
|
||||||
|
doRequest(t, httpClient, request, http.StatusOK, list)
|
||||||
|
|
||||||
|
require.Equal(t, int64(1), *list.Size)
|
||||||
|
require.Equal(t, storageGroupAddress.ContainerID, list.StorageGroups[0].Address.ContainerID)
|
||||||
|
require.Equal(t, storageGroupAddress.ObjectID, list.StorageGroups[0].Address.ObjectID)
|
||||||
|
require.Equal(t, storageGroupName, list.StorageGroups[0].Name)
|
||||||
|
require.NotEmpty(t, list.StorageGroups[0].ExpirationEpoch)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("get storage group", func(t *testing.T) {
|
||||||
|
request, err := http.NewRequest(http.MethodGet, testHost+"/v1/containers/"+cnrID.EncodeToString()+"/storagegroups/"+*storageGroupAddress.ObjectID+"?"+query.Encode(), nil)
|
||||||
|
require.NoError(t, err)
|
||||||
|
prepareCommonHeaders(request.Header, bearerToken)
|
||||||
|
|
||||||
|
group := &models.StorageGroup{}
|
||||||
|
doRequest(t, httpClient, request, http.StatusOK, group)
|
||||||
|
|
||||||
|
require.Equal(t, strconv.Itoa(len(content)), *group.Size)
|
||||||
|
require.Equal(t, storageGroupName, group.Name)
|
||||||
|
require.Equal(t, storageGroupAddress.ContainerID, group.Address.ContainerID)
|
||||||
|
require.Equal(t, storageGroupAddress.ObjectID, group.Address.ObjectID)
|
||||||
|
require.NotEmpty(t, *group.ExpirationEpoch)
|
||||||
|
require.Equal(t, []string{objID.EncodeToString()}, group.Members)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("delete storage group", func(t *testing.T) {
|
||||||
|
request, err := http.NewRequest(http.MethodDelete, testHost+"/v1/containers/"+cnrID.EncodeToString()+"/storagegroups/"+*storageGroupAddress.ObjectID+"?"+query.Encode(), nil)
|
||||||
|
require.NoError(t, err)
|
||||||
|
prepareCommonHeaders(request.Header, bearerToken)
|
||||||
|
|
||||||
|
resp := &models.SuccessResponse{}
|
||||||
|
doRequest(t, httpClient, request, http.StatusOK, resp)
|
||||||
|
require.True(t, *resp.Success)
|
||||||
|
|
||||||
|
var sgObjID oid.ID
|
||||||
|
err = sgObjID.DecodeString(*storageGroupAddress.ObjectID)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
var addr oid.Address
|
||||||
|
addr.SetContainer(cnrID)
|
||||||
|
addr.SetObject(sgObjID)
|
||||||
|
|
||||||
|
var prm pool.PrmObjectHead
|
||||||
|
prm.SetAddress(addr)
|
||||||
|
|
||||||
|
_, err = clientPool.HeadObject(ctx, prm)
|
||||||
|
require.Error(t, err)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func getAllowedRules() []*models.Record {
|
||||||
|
var result []*models.Record
|
||||||
|
|
||||||
|
ops := []models.Operation{models.OperationGET, models.OperationHEAD, models.OperationPUT,
|
||||||
|
models.OperationDELETE, models.OperationSEARCH, models.OperationRANGE, models.OperationRANGEHASH}
|
||||||
|
|
||||||
|
for _, op := range ops {
|
||||||
|
rec := &models.Record{
|
||||||
|
Operation: models.NewOperation(op),
|
||||||
|
Action: models.NewAction(models.ActionALLOW),
|
||||||
|
Filters: []*models.Filter{},
|
||||||
|
Targets: []*models.Target{{
|
||||||
|
Role: models.NewRole(models.RoleOTHERS),
|
||||||
|
Keys: []string{},
|
||||||
|
}},
|
||||||
|
}
|
||||||
|
result = append(result, rec)
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
func restObjectPut(ctx context.Context, t *testing.T, clientPool *pool.Pool, cnrID cid.ID) {
|
func restObjectPut(ctx context.Context, t *testing.T, clientPool *pool.Pool, cnrID cid.ID) {
|
||||||
bearer := &models.Bearer{
|
bearer := &models.Bearer{
|
||||||
Object: []*models.Record{{
|
Object: []*models.Record{{
|
||||||
|
@ -1282,7 +1395,7 @@ func createContainer(ctx context.Context, t *testing.T, clientPool *pool.Pool, o
|
||||||
|
|
||||||
var waitPrm pool.WaitParams
|
var waitPrm pool.WaitParams
|
||||||
waitPrm.SetPollInterval(3 * time.Second)
|
waitPrm.SetPollInterval(3 * time.Second)
|
||||||
waitPrm.SetTimeout(15 * time.Second)
|
waitPrm.SetTimeout(30 * time.Second)
|
||||||
|
|
||||||
var prm pool.PrmContainerPut
|
var prm pool.PrmContainerPut
|
||||||
prm.SetContainer(cnr)
|
prm.SetContainer(cnr)
|
||||||
|
@ -1335,7 +1448,7 @@ func restrictByEACL(ctx context.Context, t *testing.T, clientPool *pool.Pool, cn
|
||||||
|
|
||||||
var waitPrm pool.WaitParams
|
var waitPrm pool.WaitParams
|
||||||
waitPrm.SetPollInterval(3 * time.Second)
|
waitPrm.SetPollInterval(3 * time.Second)
|
||||||
waitPrm.SetTimeout(15 * time.Second)
|
waitPrm.SetTimeout(30 * time.Second)
|
||||||
|
|
||||||
var prm pool.PrmContainerSetEACL
|
var prm pool.PrmContainerSetEACL
|
||||||
prm.SetTable(*table)
|
prm.SetTable(*table)
|
||||||
|
|
|
@ -130,6 +130,8 @@ func (a *API) Configure(api *operations.FrostfsRestGwAPI) http.Handler {
|
||||||
|
|
||||||
api.PutStorageGroupHandler = operations.PutStorageGroupHandlerFunc(a.PutStorageGroup)
|
api.PutStorageGroupHandler = operations.PutStorageGroupHandlerFunc(a.PutStorageGroup)
|
||||||
api.ListStorageGroupsHandler = operations.ListStorageGroupsHandlerFunc(a.ListStorageGroups)
|
api.ListStorageGroupsHandler = operations.ListStorageGroupsHandlerFunc(a.ListStorageGroups)
|
||||||
|
api.GetStorageGroupHandler = operations.GetStorageGroupHandlerFunc(a.GetStorageGroup)
|
||||||
|
api.DeleteStorageGroupHandler = operations.DeleteStorageGroupHandlerFunc(a.DeleteStorageGroup)
|
||||||
|
|
||||||
api.BearerAuthAuth = func(s string) (*models.Principal, error) {
|
api.BearerAuthAuth = func(s string) (*models.Principal, error) {
|
||||||
if !strings.HasPrefix(s, BearerPrefix) {
|
if !strings.HasPrefix(s, BearerPrefix) {
|
||||||
|
|
Loading…
Reference in a new issue