forked from TrueCloudLab/frostfs-s3-gw
[#713] Update tests
Add bearer token to test context Signed-off-by: Denis Kirillov <denis@nspcc.ru>
This commit is contained in:
parent
1a21e6e6e8
commit
cb55d36063
13 changed files with 244 additions and 199 deletions
|
@ -1349,7 +1349,7 @@ func createAccessBox(t *testing.T) *accessbox.Box {
|
|||
}
|
||||
|
||||
func createBucket(t *testing.T, tc *handlerContext, bktName string, box *accessbox.Box) *data.BucketInfo {
|
||||
w, r := prepareTestRequest(t, bktName, "", nil)
|
||||
w, r := prepareTestRequest(tc, bktName, "", nil)
|
||||
ctx := context.WithValue(r.Context(), api.BoxData, box)
|
||||
r = r.WithContext(ctx)
|
||||
tc.Handler().CreateBucketHandler(w, r)
|
||||
|
@ -1361,7 +1361,7 @@ func createBucket(t *testing.T, tc *handlerContext, bktName string, box *accessb
|
|||
}
|
||||
|
||||
func putBucketACL(t *testing.T, tc *handlerContext, bktName string, box *accessbox.Box, header map[string]string) {
|
||||
w, r := prepareTestRequest(t, bktName, "", nil)
|
||||
w, r := prepareTestRequest(tc, bktName, "", nil)
|
||||
for key, val := range header {
|
||||
r.Header.Set(key, val)
|
||||
}
|
||||
|
|
|
@ -2,7 +2,6 @@ package handler
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"testing"
|
||||
|
@ -13,33 +12,32 @@ import (
|
|||
)
|
||||
|
||||
func TestGetObjectPartsAttributes(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
hc := prepareHandlerContext(t)
|
||||
|
||||
bktName := "bucket-get-attributes"
|
||||
objName, objMultipartName := "object", "object-multipart"
|
||||
|
||||
createTestBucket(ctx, t, hc, bktName)
|
||||
createTestBucket(hc, bktName)
|
||||
|
||||
body := bytes.NewReader([]byte("content"))
|
||||
w, r := prepareTestPayloadRequest(bktName, objName, body)
|
||||
w, r := prepareTestPayloadRequest(hc, bktName, objName, body)
|
||||
hc.Handler().PutObjectHandler(w, r)
|
||||
assertStatus(t, w, http.StatusOK)
|
||||
|
||||
w, r = prepareTestRequest(t, bktName, objName, nil)
|
||||
w, r = prepareTestRequest(hc, bktName, objName, nil)
|
||||
r.Header.Set(api.AmzObjectAttributes, objectParts)
|
||||
hc.Handler().GetObjectAttributesHandler(w, r)
|
||||
result := &GetObjectAttributesResponse{}
|
||||
parseTestResponse(t, w, result)
|
||||
require.Nil(t, result.ObjectParts)
|
||||
|
||||
w, r = prepareTestRequest(t, bktName, objMultipartName, nil)
|
||||
w, r = prepareTestRequest(hc, bktName, objMultipartName, nil)
|
||||
hc.Handler().CreateMultipartUploadHandler(w, r)
|
||||
multipartUpload := &InitiateMultipartUploadResponse{}
|
||||
parseTestResponse(t, w, multipartUpload)
|
||||
|
||||
body2 := bytes.NewReader([]byte("content2"))
|
||||
w, r = prepareTestPayloadRequest(bktName, objMultipartName, body2)
|
||||
w, r = prepareTestPayloadRequest(hc, bktName, objMultipartName, body2)
|
||||
query := make(url.Values)
|
||||
query.Add(uploadIDHeaderName, multipartUpload.UploadID)
|
||||
query.Add(partNumberHeaderName, "1")
|
||||
|
@ -54,14 +52,14 @@ func TestGetObjectPartsAttributes(t *testing.T) {
|
|||
PartNumber: 1,
|
||||
}},
|
||||
}
|
||||
w, r = prepareTestRequest(t, bktName, objMultipartName, completeUpload)
|
||||
w, r = prepareTestRequest(hc, bktName, objMultipartName, completeUpload)
|
||||
query = make(url.Values)
|
||||
query.Add(uploadIDHeaderName, multipartUpload.UploadID)
|
||||
r.URL.RawQuery = query.Encode()
|
||||
hc.Handler().CompleteMultipartUploadHandler(w, r)
|
||||
assertStatus(t, w, http.StatusOK)
|
||||
|
||||
w, r = prepareTestRequest(t, bktName, objMultipartName, nil)
|
||||
w, r = prepareTestRequest(hc, bktName, objMultipartName, nil)
|
||||
r.Header.Set(api.AmzObjectAttributes, objectParts)
|
||||
hc.Handler().GetObjectAttributesHandler(w, r)
|
||||
result = &GetObjectAttributesResponse{}
|
||||
|
|
|
@ -22,7 +22,7 @@ func TestCopyWithTaggingDirective(t *testing.T) {
|
|||
|
||||
bktName, objName := "bucket-for-copy", "object-from-copy"
|
||||
objToCopy, objToCopy2 := "object-to-copy", "object-to-copy-2"
|
||||
createBucketAndObject(t, tc, bktName, objName)
|
||||
createBucketAndObject(tc, bktName, objName)
|
||||
|
||||
putObjectTagging(t, tc, bktName, objName, map[string]string{"key": "val"})
|
||||
|
||||
|
@ -47,7 +47,7 @@ func TestCopyToItself(t *testing.T) {
|
|||
tc := prepareHandlerContext(t)
|
||||
|
||||
bktName, objName := "bucket-for-copy", "object-for-copy"
|
||||
createBucketAndObject(t, tc, bktName, objName)
|
||||
createBucketAndObject(tc, bktName, objName)
|
||||
|
||||
copyMeta := CopyMeta{MetadataDirective: replaceDirective}
|
||||
|
||||
|
@ -64,7 +64,7 @@ func TestCopyToItself(t *testing.T) {
|
|||
}
|
||||
|
||||
func copyObject(t *testing.T, tc *handlerContext, bktName, fromObject, toObject string, copyMeta CopyMeta, statusCode int) {
|
||||
w, r := prepareTestRequest(t, bktName, toObject, nil)
|
||||
w, r := prepareTestRequest(tc, bktName, toObject, nil)
|
||||
r.Header.Set(api.AmzCopySource, bktName+"/"+fromObject)
|
||||
|
||||
r.Header.Set(api.AmzMetadataDirective, copyMeta.MetadataDirective)
|
||||
|
@ -95,7 +95,7 @@ func putObjectTagging(t *testing.T, tc *handlerContext, bktName, objName string,
|
|||
})
|
||||
}
|
||||
|
||||
w, r := prepareTestRequest(t, bktName, objName, body)
|
||||
w, r := prepareTestRequest(tc, bktName, objName, body)
|
||||
tc.Handler().PutObjectTaggingHandler(w, r)
|
||||
assertStatus(t, w, http.StatusOK)
|
||||
}
|
||||
|
@ -104,7 +104,7 @@ func getObjectTagging(t *testing.T, tc *handlerContext, bktName, objName, versio
|
|||
query := make(url.Values)
|
||||
query.Add(api.QueryVersionID, version)
|
||||
|
||||
w, r := prepareTestFullRequest(t, bktName, objName, query, nil)
|
||||
w, r := prepareTestFullRequest(tc, bktName, objName, query, nil)
|
||||
tc.Handler().GetObjectTaggingHandler(w, r)
|
||||
assertStatus(t, w, http.StatusOK)
|
||||
|
||||
|
|
|
@ -35,7 +35,7 @@ func TestDeleteObject(t *testing.T) {
|
|||
tc := prepareHandlerContext(t)
|
||||
|
||||
bktName, objName := "bucket-for-removal", "object-to-delete"
|
||||
bktInfo, objInfo := createBucketAndObject(t, tc, bktName, objName)
|
||||
bktInfo, objInfo := createBucketAndObject(tc, bktName, objName)
|
||||
|
||||
checkFound(t, tc, bktName, objName, emptyVersion)
|
||||
deleteObject(t, tc, bktName, objName, emptyVersion)
|
||||
|
@ -61,7 +61,7 @@ func TestDeleteDeletedObject(t *testing.T) {
|
|||
|
||||
t.Run("unversioned bucket", func(t *testing.T) {
|
||||
bktName, objName := "bucket-unversioned-removal", "object-to-delete"
|
||||
createBucketAndObject(t, tc, bktName, objName)
|
||||
createBucketAndObject(tc, bktName, objName)
|
||||
|
||||
versionID, isDeleteMarker := deleteObject(t, tc, bktName, objName, emptyVersion)
|
||||
require.Empty(t, versionID)
|
||||
|
@ -116,7 +116,7 @@ func TestDeleteObjectUnversioned(t *testing.T) {
|
|||
tc := prepareHandlerContext(t)
|
||||
|
||||
bktName, objName := "bucket-for-removal-unversioned", "object-to-delete-unversioned"
|
||||
bktInfo, objInfo := createBucketAndObject(t, tc, bktName, objName)
|
||||
bktInfo, objInfo := createBucketAndObject(tc, bktName, objName)
|
||||
|
||||
checkFound(t, tc, bktName, objName, emptyVersion)
|
||||
deleteObject(t, tc, bktName, objName, emptyVersion)
|
||||
|
@ -151,7 +151,7 @@ func TestDeleteObjectCombined(t *testing.T) {
|
|||
tc := prepareHandlerContext(t)
|
||||
|
||||
bktName, objName := "bucket-for-removal", "object-to-delete"
|
||||
bktInfo, objInfo := createBucketAndObject(t, tc, bktName, objName)
|
||||
bktInfo, objInfo := createBucketAndObject(tc, bktName, objName)
|
||||
|
||||
putBucketVersioning(t, tc, bktName, true)
|
||||
|
||||
|
@ -168,7 +168,7 @@ func TestDeleteObjectSuspended(t *testing.T) {
|
|||
tc := prepareHandlerContext(t)
|
||||
|
||||
bktName, objName := "bucket-for-removal", "object-to-delete"
|
||||
bktInfo, objInfo := createBucketAndObject(t, tc, bktName, objName)
|
||||
bktInfo, objInfo := createBucketAndObject(tc, bktName, objName)
|
||||
|
||||
putBucketVersioning(t, tc, bktName, true)
|
||||
|
||||
|
@ -188,7 +188,7 @@ func TestDeleteMarkers(t *testing.T) {
|
|||
tc := prepareHandlerContext(t)
|
||||
|
||||
bktName, objName := "bucket-for-removal", "object-to-delete"
|
||||
createTestBucket(tc.Context(), t, tc, bktName)
|
||||
createTestBucket(tc, bktName)
|
||||
putBucketVersioning(t, tc, bktName, true)
|
||||
|
||||
checkNotFound(t, tc, bktName, objName, emptyVersion)
|
||||
|
@ -243,21 +243,21 @@ func TestDeleteObjectCheckMarkerReturn(t *testing.T) {
|
|||
require.Equal(t, deleteMarkerVersion, deleteMarkerVersion2)
|
||||
}
|
||||
|
||||
func createBucketAndObject(t *testing.T, tc *handlerContext, bktName, objName string) (*data.BucketInfo, *data.ObjectInfo) {
|
||||
bktInfo := createTestBucket(tc.Context(), t, tc, bktName)
|
||||
func createBucketAndObject(tc *handlerContext, bktName, objName string) (*data.BucketInfo, *data.ObjectInfo) {
|
||||
bktInfo := createTestBucket(tc, bktName)
|
||||
|
||||
objInfo := createTestObject(tc.Context(), t, tc, bktInfo, objName)
|
||||
objInfo := createTestObject(tc, bktInfo, objName)
|
||||
|
||||
return bktInfo, objInfo
|
||||
}
|
||||
|
||||
func createVersionedBucketAndObject(t *testing.T, tc *handlerContext, bktName, objName string) (*data.BucketInfo, *data.ObjectInfo) {
|
||||
createTestBucket(tc.Context(), t, tc, bktName)
|
||||
createTestBucket(tc, bktName)
|
||||
bktInfo, err := tc.Layer().GetBucketInfo(tc.Context(), bktName)
|
||||
require.NoError(t, err)
|
||||
putBucketVersioning(t, tc, bktName, true)
|
||||
|
||||
objInfo := createTestObject(tc.Context(), t, tc, bktInfo, objName)
|
||||
objInfo := createTestObject(tc, bktInfo, objName)
|
||||
|
||||
return bktInfo, objInfo
|
||||
}
|
||||
|
@ -267,7 +267,7 @@ func putBucketVersioning(t *testing.T, tc *handlerContext, bktName string, enabl
|
|||
if enabled {
|
||||
cfg.Status = "Enabled"
|
||||
}
|
||||
w, r := prepareTestRequest(t, bktName, "", cfg)
|
||||
w, r := prepareTestRequest(tc, bktName, "", cfg)
|
||||
tc.Handler().PutBucketVersioningHandler(w, r)
|
||||
assertStatus(t, w, http.StatusOK)
|
||||
}
|
||||
|
@ -276,7 +276,7 @@ func deleteObject(t *testing.T, tc *handlerContext, bktName, objName, version st
|
|||
query := make(url.Values)
|
||||
query.Add(api.QueryVersionID, version)
|
||||
|
||||
w, r := prepareTestFullRequest(t, bktName, objName, query, nil)
|
||||
w, r := prepareTestFullRequest(tc, bktName, objName, query, nil)
|
||||
tc.Handler().DeleteObjectHandler(w, r)
|
||||
assertStatus(t, w, http.StatusNoContent)
|
||||
|
||||
|
@ -284,7 +284,7 @@ func deleteObject(t *testing.T, tc *handlerContext, bktName, objName, version st
|
|||
}
|
||||
|
||||
func deleteBucket(t *testing.T, tc *handlerContext, bktName string, code int) {
|
||||
w, r := prepareTestRequest(t, bktName, "", nil)
|
||||
w, r := prepareTestRequest(tc, bktName, "", nil)
|
||||
tc.Handler().DeleteBucketHandler(w, r)
|
||||
assertStatus(t, w, code)
|
||||
}
|
||||
|
@ -293,7 +293,7 @@ func checkNotFound(t *testing.T, tc *handlerContext, bktName, objName, version s
|
|||
query := make(url.Values)
|
||||
query.Add(api.QueryVersionID, version)
|
||||
|
||||
w, r := prepareTestFullRequest(t, bktName, objName, query, nil)
|
||||
w, r := prepareTestFullRequest(tc, bktName, objName, query, nil)
|
||||
tc.Handler().HeadObjectHandler(w, r)
|
||||
assertStatus(t, w, http.StatusNotFound)
|
||||
}
|
||||
|
@ -302,13 +302,13 @@ func checkFound(t *testing.T, tc *handlerContext, bktName, objName, version stri
|
|||
query := make(url.Values)
|
||||
query.Add(api.QueryVersionID, version)
|
||||
|
||||
w, r := prepareTestFullRequest(t, bktName, objName, query, nil)
|
||||
w, r := prepareTestFullRequest(tc, bktName, objName, query, nil)
|
||||
tc.Handler().HeadObjectHandler(w, r)
|
||||
assertStatus(t, w, http.StatusOK)
|
||||
}
|
||||
|
||||
func listVersions(t *testing.T, tc *handlerContext, bktName string) *ListObjectsVersionsResponse {
|
||||
w, r := prepareTestRequest(t, bktName, "", nil)
|
||||
w, r := prepareTestRequest(tc, bktName, "", nil)
|
||||
tc.Handler().ListBucketObjectVersionsHandler(w, r)
|
||||
assertStatus(t, w, http.StatusOK)
|
||||
res := &ListObjectsVersionsResponse{}
|
||||
|
@ -318,13 +318,13 @@ func listVersions(t *testing.T, tc *handlerContext, bktName string) *ListObjects
|
|||
|
||||
func putObject(t *testing.T, tc *handlerContext, bktName, objName string) {
|
||||
body := bytes.NewReader([]byte("content"))
|
||||
w, r := prepareTestPayloadRequest(bktName, objName, body)
|
||||
w, r := prepareTestPayloadRequest(tc, bktName, objName, body)
|
||||
tc.Handler().PutObjectHandler(w, r)
|
||||
assertStatus(t, w, http.StatusOK)
|
||||
}
|
||||
|
||||
func createSuspendedBucket(t *testing.T, tc *handlerContext, bktName string) *data.BucketInfo {
|
||||
createTestBucket(tc.Context(), t, tc, bktName)
|
||||
createTestBucket(tc, bktName)
|
||||
bktInfo, err := tc.Layer().GetBucketInfo(tc.Context(), bktName)
|
||||
require.NoError(t, err)
|
||||
putBucketVersioning(t, tc, bktName, false)
|
||||
|
|
|
@ -27,7 +27,7 @@ func TestSimpleGetEncrypted(t *testing.T) {
|
|||
tc := prepareHandlerContext(t)
|
||||
|
||||
bktName, objName := "bucket-for-sse-c", "object-to-encrypt"
|
||||
bktInfo := createTestBucket(tc.Context(), t, tc, bktName)
|
||||
bktInfo := createTestBucket(tc, bktName)
|
||||
|
||||
content := "content"
|
||||
putEncryptedObject(t, tc, bktName, objName, content)
|
||||
|
@ -48,7 +48,7 @@ func TestGetEncryptedRange(t *testing.T) {
|
|||
tc := prepareHandlerContext(t)
|
||||
|
||||
bktName, objName := "bucket-for-sse-c", "object-to-encrypt"
|
||||
createTestBucket(tc.Context(), t, tc, bktName)
|
||||
createTestBucket(tc, bktName)
|
||||
|
||||
var sb strings.Builder
|
||||
for i := 0; i < 1<<16+11; i++ {
|
||||
|
@ -89,7 +89,7 @@ func TestGetEncryptedRange(t *testing.T) {
|
|||
func TestS3EncryptionSSECMultipartUpload(t *testing.T) {
|
||||
tc := prepareHandlerContext(t)
|
||||
bktName, objName := "bucket-for-sse-c-multipart-s3-tests", "multipart_enc"
|
||||
createTestBucket(tc.Context(), t, tc, bktName)
|
||||
createTestBucket(tc, bktName)
|
||||
|
||||
objLen := 30 * 1024 * 1024
|
||||
partSize := objLen / 6
|
||||
|
@ -168,7 +168,7 @@ func multipartUploadEncrypted(t *testing.T, tc *handlerContext, bktName, objName
|
|||
}
|
||||
|
||||
func createMultipartUpload(t *testing.T, tc *handlerContext, bktName, objName string, headers map[string]string) *InitiateMultipartUploadResponse {
|
||||
w, r := prepareTestRequest(t, bktName, objName, nil)
|
||||
w, r := prepareTestRequest(tc, bktName, objName, nil)
|
||||
setEncryptHeaders(r)
|
||||
setHeaders(r, headers)
|
||||
tc.Handler().CreateMultipartUploadHandler(w, r)
|
||||
|
@ -190,7 +190,7 @@ func completeMultipartUpload(t *testing.T, tc *handlerContext, bktName, objName,
|
|||
})
|
||||
}
|
||||
|
||||
w, r := prepareTestFullRequest(t, bktName, objName, query, complete)
|
||||
w, r := prepareTestFullRequest(tc, bktName, objName, query, complete)
|
||||
tc.Handler().CompleteMultipartUploadHandler(w, r)
|
||||
assertStatus(t, w, http.StatusOK)
|
||||
}
|
||||
|
@ -204,7 +204,7 @@ func uploadPart(t *testing.T, tc *handlerContext, bktName, objName, uploadID str
|
|||
query.Set(uploadIDQuery, uploadID)
|
||||
query.Set(partNumberQuery, strconv.Itoa(num))
|
||||
|
||||
w, r := prepareTestRequestWithQuery(bktName, objName, query, partBody)
|
||||
w, r := prepareTestRequestWithQuery(tc, bktName, objName, query, partBody)
|
||||
setEncryptHeaders(r)
|
||||
tc.Handler().UploadPartHandler(w, r)
|
||||
assertStatus(t, w, http.StatusOK)
|
||||
|
@ -218,9 +218,9 @@ func TestMultipartEncrypted(t *testing.T) {
|
|||
tc := prepareHandlerContext(t)
|
||||
|
||||
bktName, objName := "bucket-for-sse-c-multipart", "object-to-encrypt-multipart"
|
||||
createTestBucket(tc.Context(), t, tc, bktName)
|
||||
createTestBucket(tc, bktName)
|
||||
|
||||
w, r := prepareTestRequest(t, bktName, objName, nil)
|
||||
w, r := prepareTestRequest(tc, bktName, objName, nil)
|
||||
setEncryptHeaders(r)
|
||||
tc.Handler().CreateMultipartUploadHandler(w, r)
|
||||
multipartInitInfo := &InitiateMultipartUploadResponse{}
|
||||
|
@ -233,7 +233,7 @@ func TestMultipartEncrypted(t *testing.T) {
|
|||
query := make(url.Values)
|
||||
query.Set(uploadIDQuery, multipartInitInfo.UploadID)
|
||||
query.Set(partNumberQuery, "1")
|
||||
w, r = prepareTestRequestWithQuery(bktName, objName, query, part1)
|
||||
w, r = prepareTestRequestWithQuery(tc, bktName, objName, query, part1)
|
||||
setEncryptHeaders(r)
|
||||
tc.Handler().UploadPartHandler(w, r)
|
||||
assertStatus(t, w, http.StatusOK)
|
||||
|
@ -243,7 +243,7 @@ func TestMultipartEncrypted(t *testing.T) {
|
|||
query = make(url.Values)
|
||||
query.Set(uploadIDQuery, multipartInitInfo.UploadID)
|
||||
query.Set(partNumberQuery, "2")
|
||||
w, r = prepareTestRequestWithQuery(bktName, objName, query, part2)
|
||||
w, r = prepareTestRequestWithQuery(tc, bktName, objName, query, part2)
|
||||
setEncryptHeaders(r)
|
||||
tc.Handler().UploadPartHandler(w, r)
|
||||
assertStatus(t, w, http.StatusOK)
|
||||
|
@ -257,7 +257,7 @@ func TestMultipartEncrypted(t *testing.T) {
|
|||
{ETag: part2ETag, PartNumber: 2},
|
||||
},
|
||||
}
|
||||
w, r = prepareTestFullRequest(t, bktName, objName, query, complete)
|
||||
w, r = prepareTestFullRequest(tc, bktName, objName, query, complete)
|
||||
tc.Handler().CompleteMultipartUploadHandler(w, r)
|
||||
assertStatus(t, w, http.StatusOK)
|
||||
|
||||
|
@ -271,14 +271,14 @@ func TestMultipartEncrypted(t *testing.T) {
|
|||
|
||||
func putEncryptedObject(t *testing.T, tc *handlerContext, bktName, objName, content string) {
|
||||
body := bytes.NewReader([]byte(content))
|
||||
w, r := prepareTestPayloadRequest(bktName, objName, body)
|
||||
w, r := prepareTestPayloadRequest(tc, bktName, objName, body)
|
||||
setEncryptHeaders(r)
|
||||
tc.Handler().PutObjectHandler(w, r)
|
||||
assertStatus(t, w, http.StatusOK)
|
||||
}
|
||||
|
||||
func getEncryptedObject(t *testing.T, tc *handlerContext, bktName, objName string) ([]byte, http.Header) {
|
||||
w, r := prepareTestRequest(t, bktName, objName, nil)
|
||||
w, r := prepareTestRequest(tc, bktName, objName, nil)
|
||||
setEncryptHeaders(r)
|
||||
tc.Handler().GetObjectHandler(w, r)
|
||||
assertStatus(t, w, http.StatusOK)
|
||||
|
@ -288,7 +288,7 @@ func getEncryptedObject(t *testing.T, tc *handlerContext, bktName, objName strin
|
|||
}
|
||||
|
||||
func getEncryptedObjectRange(t *testing.T, tc *handlerContext, bktName, objName string, start, end int) []byte {
|
||||
w, r := prepareTestRequest(t, bktName, objName, nil)
|
||||
w, r := prepareTestRequest(tc, bktName, objName, nil)
|
||||
setEncryptHeaders(r)
|
||||
r.Header.Set("Range", fmt.Sprintf("bytes=%d-%d", start, end))
|
||||
tc.Handler().GetObjectHandler(w, r)
|
||||
|
|
|
@ -152,7 +152,7 @@ func TestGetRange(t *testing.T) {
|
|||
tc := prepareHandlerContext(t)
|
||||
|
||||
bktName, objName := "bucket-for-range", "object-to-range"
|
||||
createTestBucket(tc.Context(), t, tc, bktName)
|
||||
createTestBucket(tc, bktName)
|
||||
|
||||
content := "123456789abcdef"
|
||||
putObjectContent(t, tc, bktName, objName, content)
|
||||
|
@ -172,13 +172,13 @@ func TestGetRange(t *testing.T) {
|
|||
|
||||
func putObjectContent(t *testing.T, tc *handlerContext, bktName, objName, content string) {
|
||||
body := bytes.NewReader([]byte(content))
|
||||
w, r := prepareTestPayloadRequest(bktName, objName, body)
|
||||
w, r := prepareTestPayloadRequest(tc, bktName, objName, body)
|
||||
tc.Handler().PutObjectHandler(w, r)
|
||||
assertStatus(t, w, http.StatusOK)
|
||||
}
|
||||
|
||||
func getObjectRange(t *testing.T, tc *handlerContext, bktName, objName string, start, end int) []byte {
|
||||
w, r := prepareTestRequest(t, bktName, objName, nil)
|
||||
w, r := prepareTestRequest(tc, bktName, objName, nil)
|
||||
r.Header.Set("Range", fmt.Sprintf("bytes=%d-%d", start, end))
|
||||
tc.Handler().GetObjectHandler(w, r)
|
||||
assertStatus(t, w, http.StatusPartialContent)
|
||||
|
|
|
@ -22,12 +22,13 @@ import (
|
|||
"github.com/nspcc-dev/neofs-sdk-go/object"
|
||||
oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
|
||||
"github.com/nspcc-dev/neofs-sdk-go/user"
|
||||
usertest "github.com/nspcc-dev/neofs-sdk-go/user/test"
|
||||
"github.com/stretchr/testify/require"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
type handlerContext struct {
|
||||
owner user.ID
|
||||
t *testing.T
|
||||
h *handler
|
||||
tp *layer.TestNeoFS
|
||||
context context.Context
|
||||
|
@ -61,6 +62,9 @@ func prepareHandlerContext(t *testing.T) *handlerContext {
|
|||
return tp.ContainerID(name)
|
||||
})
|
||||
|
||||
var owner user.ID
|
||||
user.IDFromKey(&owner, key.PrivateKey.PublicKey)
|
||||
|
||||
layerCfg := &layer.Config{
|
||||
Caches: layer.DefaultCachesConfigs(zap.NewExample()),
|
||||
AnonKey: layer.AnonymousKey{Key: key},
|
||||
|
@ -77,31 +81,33 @@ func prepareHandlerContext(t *testing.T) *handlerContext {
|
|||
}
|
||||
|
||||
return &handlerContext{
|
||||
owner: owner,
|
||||
t: t,
|
||||
h: h,
|
||||
tp: tp,
|
||||
context: context.Background(),
|
||||
context: context.WithValue(context.Background(), api.BoxData, newTestAccessBox(t, key)),
|
||||
}
|
||||
}
|
||||
|
||||
func createTestBucket(ctx context.Context, t *testing.T, h *handlerContext, bktName string) *data.BucketInfo {
|
||||
_, err := h.MockedPool().CreateContainer(ctx, layer.PrmContainerCreate{
|
||||
Creator: *usertest.ID(),
|
||||
func createTestBucket(hc *handlerContext, bktName string) *data.BucketInfo {
|
||||
_, err := hc.MockedPool().CreateContainer(hc.Context(), layer.PrmContainerCreate{
|
||||
Creator: hc.owner,
|
||||
Name: bktName,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
require.NoError(hc.t, err)
|
||||
|
||||
bktInfo, err := h.Layer().GetBucketInfo(ctx, bktName)
|
||||
require.NoError(t, err)
|
||||
bktInfo, err := hc.Layer().GetBucketInfo(hc.Context(), bktName)
|
||||
require.NoError(hc.t, err)
|
||||
return bktInfo
|
||||
}
|
||||
|
||||
func createTestBucketWithLock(ctx context.Context, t *testing.T, h *handlerContext, bktName string, conf *data.ObjectLockConfiguration) *data.BucketInfo {
|
||||
cnrID, err := h.MockedPool().CreateContainer(ctx, layer.PrmContainerCreate{
|
||||
Creator: *usertest.ID(),
|
||||
func createTestBucketWithLock(hc *handlerContext, bktName string, conf *data.ObjectLockConfiguration) *data.BucketInfo {
|
||||
cnrID, err := hc.MockedPool().CreateContainer(hc.Context(), layer.PrmContainerCreate{
|
||||
Creator: hc.owner,
|
||||
Name: bktName,
|
||||
AdditionalAttributes: [][2]string{{layer.AttributeLockEnabled, "true"}},
|
||||
})
|
||||
require.NoError(t, err)
|
||||
require.NoError(hc.t, err)
|
||||
|
||||
var ownerID user.ID
|
||||
|
||||
|
@ -120,61 +126,61 @@ func createTestBucketWithLock(ctx context.Context, t *testing.T, h *handlerConte
|
|||
},
|
||||
}
|
||||
|
||||
err = h.Layer().PutBucketSettings(ctx, sp)
|
||||
require.NoError(t, err)
|
||||
err = hc.Layer().PutBucketSettings(hc.Context(), sp)
|
||||
require.NoError(hc.t, err)
|
||||
|
||||
return bktInfo
|
||||
}
|
||||
|
||||
func createTestObject(ctx context.Context, t *testing.T, h *handlerContext, bktInfo *data.BucketInfo, objName string) *data.ObjectInfo {
|
||||
func createTestObject(hc *handlerContext, bktInfo *data.BucketInfo, objName string) *data.ObjectInfo {
|
||||
content := make([]byte, 1024)
|
||||
_, err := rand.Read(content)
|
||||
require.NoError(t, err)
|
||||
require.NoError(hc.t, err)
|
||||
|
||||
header := map[string]string{
|
||||
object.AttributeTimestamp: strconv.FormatInt(time.Now().UTC().Unix(), 10),
|
||||
}
|
||||
|
||||
objInfo, err := h.Layer().PutObject(ctx, &layer.PutObjectParams{
|
||||
objInfo, err := hc.Layer().PutObject(hc.Context(), &layer.PutObjectParams{
|
||||
BktInfo: bktInfo,
|
||||
Object: objName,
|
||||
Size: int64(len(content)),
|
||||
Reader: bytes.NewReader(content),
|
||||
Header: header,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
require.NoError(hc.t, err)
|
||||
|
||||
return objInfo
|
||||
}
|
||||
|
||||
func prepareTestRequest(t *testing.T, bktName, objName string, body interface{}) (*httptest.ResponseRecorder, *http.Request) {
|
||||
return prepareTestFullRequest(t, bktName, objName, make(url.Values), body)
|
||||
func prepareTestRequest(hc *handlerContext, bktName, objName string, body interface{}) (*httptest.ResponseRecorder, *http.Request) {
|
||||
return prepareTestFullRequest(hc, bktName, objName, make(url.Values), body)
|
||||
}
|
||||
|
||||
func prepareTestFullRequest(t *testing.T, bktName, objName string, query url.Values, body interface{}) (*httptest.ResponseRecorder, *http.Request) {
|
||||
func prepareTestFullRequest(hc *handlerContext, bktName, objName string, query url.Values, body interface{}) (*httptest.ResponseRecorder, *http.Request) {
|
||||
rawBody, err := xml.Marshal(body)
|
||||
require.NoError(t, err)
|
||||
require.NoError(hc.t, err)
|
||||
|
||||
return prepareTestRequestWithQuery(bktName, objName, query, rawBody)
|
||||
return prepareTestRequestWithQuery(hc, bktName, objName, query, rawBody)
|
||||
}
|
||||
|
||||
func prepareTestRequestWithQuery(bktName, objName string, query url.Values, body []byte) (*httptest.ResponseRecorder, *http.Request) {
|
||||
func prepareTestRequestWithQuery(hc *handlerContext, bktName, objName string, query url.Values, body []byte) (*httptest.ResponseRecorder, *http.Request) {
|
||||
w := httptest.NewRecorder()
|
||||
r := httptest.NewRequest(http.MethodPut, defaultURL, bytes.NewReader(body))
|
||||
r.URL.RawQuery = query.Encode()
|
||||
|
||||
reqInfo := api.NewReqInfo(w, r, api.ObjectRequest{Bucket: bktName, Object: objName})
|
||||
r = r.WithContext(api.SetReqInfo(r.Context(), reqInfo))
|
||||
r = r.WithContext(api.SetReqInfo(hc.Context(), reqInfo))
|
||||
|
||||
return w, r
|
||||
}
|
||||
|
||||
func prepareTestPayloadRequest(bktName, objName string, payload io.Reader) (*httptest.ResponseRecorder, *http.Request) {
|
||||
func prepareTestPayloadRequest(hc *handlerContext, bktName, objName string, payload io.Reader) (*httptest.ResponseRecorder, *http.Request) {
|
||||
w := httptest.NewRecorder()
|
||||
r := httptest.NewRequest(http.MethodPut, defaultURL, payload)
|
||||
|
||||
reqInfo := api.NewReqInfo(w, r, api.ObjectRequest{Bucket: bktName, Object: objName})
|
||||
r = r.WithContext(api.SetReqInfo(r.Context(), reqInfo))
|
||||
r = r.WithContext(api.SetReqInfo(hc.Context(), reqInfo))
|
||||
|
||||
return w, r
|
||||
}
|
||||
|
|
|
@ -6,81 +6,101 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||
"github.com/nspcc-dev/neofs-s3-gw/api"
|
||||
"github.com/nspcc-dev/neofs-s3-gw/creds/accessbox"
|
||||
"github.com/nspcc-dev/neofs-sdk-go/bearer"
|
||||
"github.com/nspcc-dev/neofs-sdk-go/eacl"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestConditionalHead(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
tc := prepareHandlerContext(t)
|
||||
|
||||
bktName := "bucket-for-conditional"
|
||||
createTestBucket(ctx, t, tc, bktName)
|
||||
bktInfo, err := tc.Layer().GetBucketInfo(ctx, bktName)
|
||||
require.NoError(t, err)
|
||||
bktName, objName := "bucket-for-conditional", "object"
|
||||
_, objInfo := createBucketAndObject(tc, bktName, objName)
|
||||
|
||||
objName := "object"
|
||||
objInfo := createTestObject(ctx, t, tc, bktInfo, objName)
|
||||
|
||||
w, r := prepareTestRequest(t, bktName, objName, nil)
|
||||
w, r := prepareTestRequest(tc, bktName, objName, nil)
|
||||
tc.Handler().HeadObjectHandler(w, r)
|
||||
assertStatus(t, w, http.StatusOK)
|
||||
|
||||
etag := w.Result().Header.Get(api.ETag)
|
||||
lastModified := w.Result().Header.Get(api.LastModified)
|
||||
_ = lastModified
|
||||
|
||||
w, r = prepareTestRequest(t, bktName, objName, nil)
|
||||
r.Header.Set(api.IfMatch, etag)
|
||||
tc.Handler().HeadObjectHandler(w, r)
|
||||
assertStatus(t, w, http.StatusOK)
|
||||
headers := map[string]string{api.IfMatch: etag}
|
||||
headObject(t, tc, bktName, objName, headers, http.StatusOK)
|
||||
|
||||
w, r = prepareTestRequest(t, bktName, objName, nil)
|
||||
r.Header.Set(api.IfMatch, "etag")
|
||||
tc.Handler().HeadObjectHandler(w, r)
|
||||
assertStatus(t, w, http.StatusPreconditionFailed)
|
||||
headers = map[string]string{api.IfMatch: "etag"}
|
||||
headObject(t, tc, bktName, objName, headers, http.StatusPreconditionFailed)
|
||||
|
||||
w, r = prepareTestRequest(t, bktName, objName, nil)
|
||||
unmodifiedSince := objInfo.Created.Add(time.Minute)
|
||||
r.Header.Set(api.IfUnmodifiedSince, unmodifiedSince.Format(http.TimeFormat))
|
||||
tc.Handler().HeadObjectHandler(w, r)
|
||||
assertStatus(t, w, http.StatusOK)
|
||||
headers = map[string]string{api.IfUnmodifiedSince: objInfo.Created.Add(time.Minute).Format(http.TimeFormat)}
|
||||
headObject(t, tc, bktName, objName, headers, http.StatusOK)
|
||||
|
||||
var zeroTime time.Time
|
||||
w, r = prepareTestRequest(t, bktName, objName, nil)
|
||||
r.Header.Set(api.IfUnmodifiedSince, zeroTime.UTC().Format(http.TimeFormat))
|
||||
tc.Handler().HeadObjectHandler(w, r)
|
||||
assertStatus(t, w, http.StatusPreconditionFailed)
|
||||
headers = map[string]string{api.IfUnmodifiedSince: zeroTime.UTC().Format(http.TimeFormat)}
|
||||
headObject(t, tc, bktName, objName, headers, http.StatusPreconditionFailed)
|
||||
|
||||
w, r = prepareTestRequest(t, bktName, objName, nil)
|
||||
r.Header.Set(api.IfMatch, etag)
|
||||
r.Header.Set(api.IfUnmodifiedSince, zeroTime.UTC().Format(http.TimeFormat))
|
||||
tc.Handler().HeadObjectHandler(w, r)
|
||||
assertStatus(t, w, http.StatusOK)
|
||||
headers = map[string]string{
|
||||
api.IfMatch: etag,
|
||||
api.IfUnmodifiedSince: zeroTime.UTC().Format(http.TimeFormat),
|
||||
}
|
||||
headObject(t, tc, bktName, objName, headers, http.StatusOK)
|
||||
|
||||
w, r = prepareTestRequest(t, bktName, objName, nil)
|
||||
r.Header.Set(api.IfNoneMatch, etag)
|
||||
tc.Handler().HeadObjectHandler(w, r)
|
||||
assertStatus(t, w, http.StatusNotModified)
|
||||
headers = map[string]string{api.IfNoneMatch: etag}
|
||||
headObject(t, tc, bktName, objName, headers, http.StatusNotModified)
|
||||
|
||||
w, r = prepareTestRequest(t, bktName, objName, nil)
|
||||
r.Header.Set(api.IfNoneMatch, "etag")
|
||||
tc.Handler().HeadObjectHandler(w, r)
|
||||
assertStatus(t, w, http.StatusOK)
|
||||
headers = map[string]string{api.IfNoneMatch: "etag"}
|
||||
headObject(t, tc, bktName, objName, headers, http.StatusOK)
|
||||
|
||||
w, r = prepareTestRequest(t, bktName, objName, nil)
|
||||
r.Header.Set(api.IfModifiedSince, zeroTime.UTC().Format(http.TimeFormat))
|
||||
tc.Handler().HeadObjectHandler(w, r)
|
||||
assertStatus(t, w, http.StatusOK)
|
||||
headers = map[string]string{api.IfModifiedSince: zeroTime.UTC().Format(http.TimeFormat)}
|
||||
headObject(t, tc, bktName, objName, headers, http.StatusOK)
|
||||
|
||||
w, r = prepareTestRequest(t, bktName, objName, nil)
|
||||
r.Header.Set(api.IfModifiedSince, time.Now().Add(time.Minute).UTC().Format(http.TimeFormat))
|
||||
tc.Handler().HeadObjectHandler(w, r)
|
||||
assertStatus(t, w, http.StatusNotModified)
|
||||
headers = map[string]string{api.IfModifiedSince: time.Now().Add(time.Minute).UTC().Format(http.TimeFormat)}
|
||||
headObject(t, tc, bktName, objName, headers, http.StatusNotModified)
|
||||
|
||||
w, r = prepareTestRequest(t, bktName, objName, nil)
|
||||
r.Header.Set(api.IfNoneMatch, etag)
|
||||
r.Header.Set(api.IfModifiedSince, zeroTime.UTC().Format(http.TimeFormat))
|
||||
tc.Handler().HeadObjectHandler(w, r)
|
||||
assertStatus(t, w, http.StatusNotModified)
|
||||
headers = map[string]string{
|
||||
api.IfNoneMatch: etag,
|
||||
api.IfModifiedSince: zeroTime.UTC().Format(http.TimeFormat),
|
||||
}
|
||||
headObject(t, tc, bktName, objName, headers, http.StatusNotModified)
|
||||
}
|
||||
|
||||
func headObject(t *testing.T, tc *handlerContext, bktName, objName string, headers map[string]string, status int) {
|
||||
w, r := prepareTestRequest(tc, bktName, objName, nil)
|
||||
|
||||
for key, val := range headers {
|
||||
r.Header.Set(key, val)
|
||||
}
|
||||
|
||||
tc.Handler().HeadObjectHandler(w, r)
|
||||
assertStatus(t, w, status)
|
||||
}
|
||||
|
||||
func TestInvalidAccessThroughCache(t *testing.T) {
|
||||
tc := prepareHandlerContext(t)
|
||||
bktName, objName := "bucket-for-cache", "obj-for-cache"
|
||||
createBucketAndObject(tc, bktName, objName)
|
||||
|
||||
headObject(t, tc, bktName, objName, nil, http.StatusOK)
|
||||
|
||||
w, r := prepareTestRequest(tc, bktName, objName, nil)
|
||||
tc.Handler().HeadObjectHandler(w, r.WithContext(context.WithValue(r.Context(), api.BoxData, newTestAccessBox(t, nil))))
|
||||
assertStatus(t, w, http.StatusForbidden)
|
||||
}
|
||||
|
||||
func newTestAccessBox(t *testing.T, key *keys.PrivateKey) *accessbox.Box {
|
||||
var err error
|
||||
if key == nil {
|
||||
key, err = keys.NewPrivateKey()
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
var btoken bearer.Token
|
||||
btoken.SetEACLTable(*eacl.NewTable())
|
||||
err = btoken.Sign(key.PrivateKey)
|
||||
require.NoError(t, err)
|
||||
|
||||
return &accessbox.Box{
|
||||
Gate: &accessbox.GateData{
|
||||
BearerToken: &btoken,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
|
@ -245,13 +245,13 @@ func TestPutBucketLockConfigurationHandler(t *testing.T) {
|
|||
hc := prepareHandlerContext(t)
|
||||
|
||||
bktLockDisabled := "bucket-lock-disabled"
|
||||
createTestBucket(ctx, t, hc, bktLockDisabled)
|
||||
createTestBucket(hc, bktLockDisabled)
|
||||
|
||||
bktLockEnabled := "bucket-lock-enabled"
|
||||
createTestBucketWithLock(ctx, t, hc, bktLockEnabled, nil)
|
||||
createTestBucketWithLock(hc, bktLockEnabled, nil)
|
||||
|
||||
bktLockEnabledWithOldConfig := "bucket-lock-enabled-old-conf"
|
||||
createTestBucketWithLock(ctx, t, hc, bktLockEnabledWithOldConfig,
|
||||
createTestBucketWithLock(hc, bktLockEnabledWithOldConfig,
|
||||
&data.ObjectLockConfiguration{
|
||||
Rule: &data.ObjectLockRule{
|
||||
DefaultRetention: &data.DefaultRetention{
|
||||
|
@ -331,14 +331,13 @@ func TestPutBucketLockConfigurationHandler(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestGetBucketLockConfigurationHandler(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
hc := prepareHandlerContext(t)
|
||||
|
||||
bktLockDisabled := "bucket-lock-disabled"
|
||||
createTestBucket(ctx, t, hc, bktLockDisabled)
|
||||
createTestBucket(hc, bktLockDisabled)
|
||||
|
||||
bktLockEnabled := "bucket-lock-enabled"
|
||||
createTestBucketWithLock(ctx, t, hc, bktLockEnabled, nil)
|
||||
createTestBucketWithLock(hc, bktLockEnabled, nil)
|
||||
|
||||
oldConfig := &data.ObjectLockConfiguration{
|
||||
Rule: &data.ObjectLockRule{
|
||||
|
@ -349,7 +348,7 @@ func TestGetBucketLockConfigurationHandler(t *testing.T) {
|
|||
},
|
||||
}
|
||||
bktLockEnabledWithOldConfig := "bucket-lock-enabled-old-conf"
|
||||
createTestBucketWithLock(ctx, t, hc, bktLockEnabledWithOldConfig, oldConfig)
|
||||
createTestBucketWithLock(hc, bktLockEnabledWithOldConfig, oldConfig)
|
||||
|
||||
for _, tc := range []struct {
|
||||
name string
|
||||
|
@ -416,44 +415,43 @@ func assertS3Error(t *testing.T, w *httptest.ResponseRecorder, expectedError api
|
|||
}
|
||||
|
||||
func TestObjectLegalHold(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
hc := prepareHandlerContext(t)
|
||||
|
||||
bktName := "bucket-lock-enabled"
|
||||
bktInfo := createTestBucketWithLock(ctx, t, hc, bktName, nil)
|
||||
bktInfo := createTestBucketWithLock(hc, bktName, nil)
|
||||
|
||||
objName := "obj-for-legal-hold"
|
||||
createTestObject(ctx, t, hc, bktInfo, objName)
|
||||
createTestObject(hc, bktInfo, objName)
|
||||
|
||||
w, r := prepareTestRequest(t, bktName, objName, nil)
|
||||
w, r := prepareTestRequest(hc, bktName, objName, nil)
|
||||
hc.Handler().GetObjectLegalHoldHandler(w, r)
|
||||
assertLegalHold(t, w, legalHoldOff)
|
||||
|
||||
w, r = prepareTestRequest(t, bktName, objName, &data.LegalHold{Status: legalHoldOn})
|
||||
w, r = prepareTestRequest(hc, bktName, objName, &data.LegalHold{Status: legalHoldOn})
|
||||
hc.Handler().PutObjectLegalHoldHandler(w, r)
|
||||
require.Equal(t, http.StatusOK, w.Code)
|
||||
assertStatus(t, w, http.StatusOK)
|
||||
|
||||
w, r = prepareTestRequest(t, bktName, objName, nil)
|
||||
w, r = prepareTestRequest(hc, bktName, objName, nil)
|
||||
hc.Handler().GetObjectLegalHoldHandler(w, r)
|
||||
assertLegalHold(t, w, legalHoldOn)
|
||||
|
||||
// to make sure put hold is an idempotent operation
|
||||
w, r = prepareTestRequest(t, bktName, objName, &data.LegalHold{Status: legalHoldOn})
|
||||
w, r = prepareTestRequest(hc, bktName, objName, &data.LegalHold{Status: legalHoldOn})
|
||||
hc.Handler().PutObjectLegalHoldHandler(w, r)
|
||||
require.Equal(t, http.StatusOK, w.Code)
|
||||
assertStatus(t, w, http.StatusOK)
|
||||
|
||||
w, r = prepareTestRequest(t, bktName, objName, &data.LegalHold{Status: legalHoldOff})
|
||||
w, r = prepareTestRequest(hc, bktName, objName, &data.LegalHold{Status: legalHoldOff})
|
||||
hc.Handler().PutObjectLegalHoldHandler(w, r)
|
||||
require.Equal(t, http.StatusOK, w.Code)
|
||||
assertStatus(t, w, http.StatusOK)
|
||||
|
||||
w, r = prepareTestRequest(t, bktName, objName, nil)
|
||||
w, r = prepareTestRequest(hc, bktName, objName, nil)
|
||||
hc.Handler().GetObjectLegalHoldHandler(w, r)
|
||||
assertLegalHold(t, w, legalHoldOff)
|
||||
|
||||
// to make sure put hold is an idempotent operation
|
||||
w, r = prepareTestRequest(t, bktName, objName, &data.LegalHold{Status: legalHoldOff})
|
||||
w, r = prepareTestRequest(hc, bktName, objName, &data.LegalHold{Status: legalHoldOff})
|
||||
hc.Handler().PutObjectLegalHoldHandler(w, r)
|
||||
require.Equal(t, http.StatusOK, w.Code)
|
||||
assertStatus(t, w, http.StatusOK)
|
||||
}
|
||||
|
||||
func assertLegalHold(t *testing.T, w *httptest.ResponseRecorder, status string) {
|
||||
|
@ -465,44 +463,43 @@ func assertLegalHold(t *testing.T, w *httptest.ResponseRecorder, status string)
|
|||
}
|
||||
|
||||
func TestObjectRetention(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
hc := prepareHandlerContext(t)
|
||||
|
||||
bktName := "bucket-lock-enabled"
|
||||
bktInfo := createTestBucketWithLock(ctx, t, hc, bktName, nil)
|
||||
bktInfo := createTestBucketWithLock(hc, bktName, nil)
|
||||
|
||||
objName := "obj-for-retention"
|
||||
createTestObject(ctx, t, hc, bktInfo, objName)
|
||||
createTestObject(hc, bktInfo, objName)
|
||||
|
||||
w, r := prepareTestRequest(t, bktName, objName, nil)
|
||||
w, r := prepareTestRequest(hc, bktName, objName, nil)
|
||||
hc.Handler().GetObjectRetentionHandler(w, r)
|
||||
assertS3Error(t, w, apiErrors.GetAPIError(apiErrors.ErrNoSuchKey))
|
||||
|
||||
retention := &data.Retention{Mode: governanceMode, RetainUntilDate: time.Now().Add(time.Minute).UTC().Format(time.RFC3339)}
|
||||
w, r = prepareTestRequest(t, bktName, objName, retention)
|
||||
w, r = prepareTestRequest(hc, bktName, objName, retention)
|
||||
hc.Handler().PutObjectRetentionHandler(w, r)
|
||||
assertStatus(t, w, http.StatusOK)
|
||||
|
||||
w, r = prepareTestRequest(t, bktName, objName, nil)
|
||||
w, r = prepareTestRequest(hc, bktName, objName, nil)
|
||||
hc.Handler().GetObjectRetentionHandler(w, r)
|
||||
assertRetention(t, w, retention)
|
||||
|
||||
retention = &data.Retention{Mode: governanceMode, RetainUntilDate: time.Now().UTC().Add(time.Minute).Format(time.RFC3339)}
|
||||
w, r = prepareTestRequest(t, bktName, objName, retention)
|
||||
w, r = prepareTestRequest(hc, bktName, objName, retention)
|
||||
hc.Handler().PutObjectRetentionHandler(w, r)
|
||||
assertS3Error(t, w, apiErrors.GetAPIError(apiErrors.ErrInternalError))
|
||||
|
||||
retention = &data.Retention{Mode: complianceMode, RetainUntilDate: time.Now().Add(time.Minute).UTC().Format(time.RFC3339)}
|
||||
w, r = prepareTestRequest(t, bktName, objName, retention)
|
||||
w, r = prepareTestRequest(hc, bktName, objName, retention)
|
||||
r.Header.Set(api.AmzBypassGovernanceRetention, strconv.FormatBool(true))
|
||||
hc.Handler().PutObjectRetentionHandler(w, r)
|
||||
assertStatus(t, w, http.StatusOK)
|
||||
|
||||
w, r = prepareTestRequest(t, bktName, objName, nil)
|
||||
w, r = prepareTestRequest(hc, bktName, objName, nil)
|
||||
hc.Handler().GetObjectRetentionHandler(w, r)
|
||||
assertRetention(t, w, retention)
|
||||
|
||||
w, r = prepareTestRequest(t, bktName, objName, retention)
|
||||
w, r = prepareTestRequest(hc, bktName, objName, retention)
|
||||
r.Header.Set(api.AmzBypassGovernanceRetention, strconv.FormatBool(true))
|
||||
hc.Handler().PutObjectRetentionHandler(w, r)
|
||||
assertS3Error(t, w, apiErrors.GetAPIError(apiErrors.ErrInternalError))
|
||||
|
@ -518,7 +515,6 @@ func assertRetention(t *testing.T, w *httptest.ResponseRecorder, retention *data
|
|||
}
|
||||
|
||||
func TestPutObjectWithLock(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
hc := prepareHandlerContext(t)
|
||||
|
||||
bktName := "bucket-lock-enabled"
|
||||
|
@ -531,15 +527,15 @@ func TestPutObjectWithLock(t *testing.T) {
|
|||
},
|
||||
},
|
||||
}
|
||||
createTestBucketWithLock(ctx, t, hc, bktName, lockConfig)
|
||||
createTestBucketWithLock(hc, bktName, lockConfig)
|
||||
|
||||
objDefault := "obj-default-retention"
|
||||
|
||||
w, r := prepareTestRequest(t, bktName, objDefault, nil)
|
||||
w, r := prepareTestRequest(hc, bktName, objDefault, nil)
|
||||
hc.Handler().PutObjectHandler(w, r)
|
||||
assertStatus(t, w, http.StatusOK)
|
||||
|
||||
w, r = prepareTestRequest(t, bktName, objDefault, nil)
|
||||
w, r = prepareTestRequest(hc, bktName, objDefault, nil)
|
||||
hc.Handler().GetObjectRetentionHandler(w, r)
|
||||
expectedRetention := &data.Retention{
|
||||
Mode: governanceMode,
|
||||
|
@ -547,12 +543,12 @@ func TestPutObjectWithLock(t *testing.T) {
|
|||
}
|
||||
assertRetentionApproximate(t, w, expectedRetention, 1)
|
||||
|
||||
w, r = prepareTestRequest(t, bktName, objDefault, nil)
|
||||
w, r = prepareTestRequest(hc, bktName, objDefault, nil)
|
||||
hc.Handler().GetObjectLegalHoldHandler(w, r)
|
||||
assertLegalHold(t, w, legalHoldOff)
|
||||
|
||||
objOverride := "obj-override-retention"
|
||||
w, r = prepareTestRequest(t, bktName, objOverride, nil)
|
||||
w, r = prepareTestRequest(hc, bktName, objOverride, nil)
|
||||
r.Header.Set(api.AmzObjectLockMode, complianceMode)
|
||||
r.Header.Set(api.AmzObjectLockLegalHold, legalHoldOn)
|
||||
r.Header.Set(api.AmzBypassGovernanceRetention, "true")
|
||||
|
@ -560,7 +556,7 @@ func TestPutObjectWithLock(t *testing.T) {
|
|||
hc.Handler().PutObjectHandler(w, r)
|
||||
assertStatus(t, w, http.StatusOK)
|
||||
|
||||
w, r = prepareTestRequest(t, bktName, objOverride, nil)
|
||||
w, r = prepareTestRequest(hc, bktName, objOverride, nil)
|
||||
hc.Handler().GetObjectRetentionHandler(w, r)
|
||||
expectedRetention = &data.Retention{
|
||||
Mode: complianceMode,
|
||||
|
@ -568,7 +564,7 @@ func TestPutObjectWithLock(t *testing.T) {
|
|||
}
|
||||
assertRetentionApproximate(t, w, expectedRetention, 1)
|
||||
|
||||
w, r = prepareTestRequest(t, bktName, objOverride, nil)
|
||||
w, r = prepareTestRequest(hc, bktName, objOverride, nil)
|
||||
hc.Handler().GetObjectLegalHoldHandler(w, r)
|
||||
assertLegalHold(t, w, legalHoldOn)
|
||||
}
|
||||
|
@ -577,7 +573,7 @@ func TestPutLockErrors(t *testing.T) {
|
|||
hc := prepareHandlerContext(t)
|
||||
|
||||
bktName, objName := "bucket-lock-enabled", "object"
|
||||
createTestBucketWithLock(hc.Context(), t, hc, bktName, nil)
|
||||
createTestBucketWithLock(hc, bktName, nil)
|
||||
|
||||
headers := map[string]string{api.AmzObjectLockMode: complianceMode}
|
||||
putObjectWithLockFailed(t, hc, bktName, objName, headers, apiErrors.ErrObjectLockInvalidHeaders)
|
||||
|
@ -611,7 +607,7 @@ func TestPutLockErrors(t *testing.T) {
|
|||
}
|
||||
|
||||
func putObjectWithLockFailed(t *testing.T, hc *handlerContext, bktName, objName string, headers map[string]string, errCode apiErrors.ErrorCode) {
|
||||
w, r := prepareTestRequest(t, bktName, objName, nil)
|
||||
w, r := prepareTestRequest(hc, bktName, objName, nil)
|
||||
|
||||
for key, val := range headers {
|
||||
r.Header.Set(key, val)
|
||||
|
@ -622,7 +618,7 @@ func putObjectWithLockFailed(t *testing.T, hc *handlerContext, bktName, objName
|
|||
}
|
||||
|
||||
func putObjectRetentionFailed(t *testing.T, hc *handlerContext, bktName, objName string, retention *data.Retention, errCode apiErrors.ErrorCode) {
|
||||
w, r := prepareTestRequest(t, bktName, objName, retention)
|
||||
w, r := prepareTestRequest(hc, bktName, objName, retention)
|
||||
hc.Handler().PutObjectRetentionHandler(w, r)
|
||||
assertS3Error(t, w, apiErrors.GetAPIError(errCode))
|
||||
}
|
||||
|
|
|
@ -2,7 +2,6 @@ package handler
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strconv"
|
||||
|
@ -43,30 +42,29 @@ func TestParseContinuationToken(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestListObjectNullVersions(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
hc := prepareHandlerContext(t)
|
||||
|
||||
bktName := "bucket-versioning-enabled"
|
||||
createTestBucket(ctx, t, hc, bktName)
|
||||
createTestBucket(hc, bktName)
|
||||
|
||||
objName := "object"
|
||||
|
||||
body := bytes.NewReader([]byte("content"))
|
||||
w, r := prepareTestPayloadRequest(bktName, objName, body)
|
||||
w, r := prepareTestPayloadRequest(hc, bktName, objName, body)
|
||||
hc.Handler().PutObjectHandler(w, r)
|
||||
assertStatus(t, w, http.StatusOK)
|
||||
|
||||
versioning := &VersioningConfiguration{Status: "Enabled"}
|
||||
w, r = prepareTestRequest(t, bktName, objName, versioning)
|
||||
w, r = prepareTestRequest(hc, bktName, objName, versioning)
|
||||
hc.Handler().PutBucketVersioningHandler(w, r)
|
||||
assertStatus(t, w, http.StatusOK)
|
||||
|
||||
body2 := bytes.NewReader([]byte("content2"))
|
||||
w, r = prepareTestPayloadRequest(bktName, objName, body2)
|
||||
w, r = prepareTestPayloadRequest(hc, bktName, objName, body2)
|
||||
hc.Handler().PutObjectHandler(w, r)
|
||||
assertStatus(t, w, http.StatusOK)
|
||||
|
||||
w, r = prepareTestRequest(t, bktName, objName, nil)
|
||||
w, r = prepareTestRequest(hc, bktName, objName, nil)
|
||||
hc.Handler().ListBucketObjectVersionsHandler(w, r)
|
||||
|
||||
result := &ListObjectsVersionsResponse{}
|
||||
|
@ -81,10 +79,10 @@ func TestS3CompatibilityBucketListV2BothContinuationTokenStartAfter(t *testing.T
|
|||
|
||||
bktName := "bucket-for-listing"
|
||||
objects := []string{"bar", "baz", "foo", "quxx"}
|
||||
bktInfo, _ := createBucketAndObject(t, tc, bktName, objects[0])
|
||||
bktInfo, _ := createBucketAndObject(tc, bktName, objects[0])
|
||||
|
||||
for _, objName := range objects[1:] {
|
||||
createTestObject(tc.Context(), t, tc, bktInfo, objName)
|
||||
createTestObject(tc, bktInfo, objName)
|
||||
}
|
||||
|
||||
listV2Response1 := listObjectsV2(t, tc, bktName, "", "", "bar", "", 1)
|
||||
|
@ -106,10 +104,10 @@ func TestS3BucketListDelimiterBasic(t *testing.T) {
|
|||
|
||||
bktName := "bucket-for-listing"
|
||||
objects := []string{"foo/bar", "foo/bar/xyzzy", "quux/thud", "asdf"}
|
||||
bktInfo, _ := createBucketAndObject(t, tc, bktName, objects[0])
|
||||
bktInfo, _ := createBucketAndObject(tc, bktName, objects[0])
|
||||
|
||||
for _, objName := range objects[1:] {
|
||||
createTestObject(tc.Context(), t, tc, bktInfo, objName)
|
||||
createTestObject(tc, bktInfo, objName)
|
||||
}
|
||||
|
||||
listV1Response := listObjectsV1(t, tc, bktName, "", "/", "", -1)
|
||||
|
@ -125,10 +123,10 @@ func TestS3BucketListV2DelimiterPrefix(t *testing.T) {
|
|||
|
||||
bktName := "bucket-for-listingv2"
|
||||
objects := []string{"asdf", "boo/bar", "boo/baz/xyzzy", "cquux/thud", "cquux/bla"}
|
||||
bktInfo, _ := createBucketAndObject(t, tc, bktName, objects[0])
|
||||
bktInfo, _ := createBucketAndObject(tc, bktName, objects[0])
|
||||
|
||||
for _, objName := range objects[1:] {
|
||||
createTestObject(tc.Context(), t, tc, bktInfo, objName)
|
||||
createTestObject(tc, bktInfo, objName)
|
||||
}
|
||||
|
||||
var empty []string
|
||||
|
@ -158,7 +156,7 @@ func listObjectsV2(t *testing.T, tc *handlerContext, bktName, prefix, delimiter,
|
|||
query.Add("continuation-token", continuationToken)
|
||||
}
|
||||
|
||||
w, r := prepareTestFullRequest(t, bktName, "", query, nil)
|
||||
w, r := prepareTestFullRequest(tc, bktName, "", query, nil)
|
||||
tc.Handler().ListObjectsV2Handler(w, r)
|
||||
assertStatus(t, w, http.StatusOK)
|
||||
res := &ListObjectsV2Response{}
|
||||
|
@ -208,7 +206,7 @@ func listObjectsV1(t *testing.T, tc *handlerContext, bktName, prefix, delimiter,
|
|||
query.Add("marker", marker)
|
||||
}
|
||||
|
||||
w, r := prepareTestFullRequest(t, bktName, "", query, nil)
|
||||
w, r := prepareTestFullRequest(tc, bktName, "", query, nil)
|
||||
tc.Handler().ListObjectsV1Handler(w, r)
|
||||
assertStatus(t, w, http.StatusOK)
|
||||
res := &ListObjectsV1Response{}
|
||||
|
|
|
@ -111,9 +111,9 @@ func TestPutObjectOverrideCopiesNumber(t *testing.T) {
|
|||
tc := prepareHandlerContext(t)
|
||||
|
||||
bktName, objName := "bucket-for-copies-number", "object-for-copies-number"
|
||||
bktInfo := createTestBucket(tc.Context(), t, tc, bktName)
|
||||
bktInfo := createTestBucket(tc, bktName)
|
||||
|
||||
w, r := prepareTestRequest(t, bktName, objName, nil)
|
||||
w, r := prepareTestRequest(tc, bktName, objName, nil)
|
||||
r.Header.Set(api.MetadataPrefix+strings.ToUpper(layer.AttributeNeofsCopiesNumber), "1")
|
||||
tc.Handler().PutObjectHandler(w, r)
|
||||
|
||||
|
|
|
@ -11,6 +11,9 @@ import (
|
|||
"time"
|
||||
|
||||
objectv2 "github.com/nspcc-dev/neofs-api-go/v2/object"
|
||||
"github.com/nspcc-dev/neofs-s3-gw/api"
|
||||
"github.com/nspcc-dev/neofs-s3-gw/creds/accessbox"
|
||||
"github.com/nspcc-dev/neofs-sdk-go/bearer"
|
||||
"github.com/nspcc-dev/neofs-sdk-go/checksum"
|
||||
"github.com/nspcc-dev/neofs-sdk-go/container"
|
||||
cid "github.com/nspcc-dev/neofs-sdk-go/container/id"
|
||||
|
@ -127,7 +130,7 @@ func (t *TestNeoFS) UserContainers(_ context.Context, _ user.ID) ([]cid.ID, erro
|
|||
return res, nil
|
||||
}
|
||||
|
||||
func (t *TestNeoFS) ReadObject(_ context.Context, prm PrmObjectRead) (*ObjectPart, error) {
|
||||
func (t *TestNeoFS) ReadObject(ctx context.Context, prm PrmObjectRead) (*ObjectPart, error) {
|
||||
var addr oid.Address
|
||||
addr.SetContainer(prm.Container)
|
||||
addr.SetObject(prm.Object)
|
||||
|
@ -135,6 +138,11 @@ func (t *TestNeoFS) ReadObject(_ context.Context, prm PrmObjectRead) (*ObjectPar
|
|||
sAddr := addr.EncodeToString()
|
||||
|
||||
if obj, ok := t.objects[sAddr]; ok {
|
||||
owner := getOwner(ctx)
|
||||
if !obj.OwnerID().Equals(owner) {
|
||||
return nil, ErrAccessDenied
|
||||
}
|
||||
|
||||
payload := obj.Payload()
|
||||
|
||||
if prm.PayloadRange[0]+prm.PayloadRange[1] > 0 {
|
||||
|
@ -151,7 +159,7 @@ func (t *TestNeoFS) ReadObject(_ context.Context, prm PrmObjectRead) (*ObjectPar
|
|||
return nil, fmt.Errorf("object not found %s", addr)
|
||||
}
|
||||
|
||||
func (t *TestNeoFS) CreateObject(_ context.Context, prm PrmObjectCreate) (oid.ID, error) {
|
||||
func (t *TestNeoFS) CreateObject(ctx context.Context, prm PrmObjectCreate) (oid.ID, error) {
|
||||
b := make([]byte, 32)
|
||||
if _, err := io.ReadFull(rand.Reader, b); err != nil {
|
||||
return oid.ID{}, err
|
||||
|
@ -181,6 +189,7 @@ func (t *TestNeoFS) CreateObject(_ context.Context, prm PrmObjectCreate) (oid.ID
|
|||
obj.SetPayloadSize(prm.PayloadSize)
|
||||
obj.SetAttributes(attrs...)
|
||||
obj.SetCreationEpoch(t.currentEpoch)
|
||||
obj.SetOwnerID(&prm.Creator)
|
||||
t.currentEpoch++
|
||||
|
||||
if len(prm.Locks) > 0 {
|
||||
|
@ -209,12 +218,19 @@ func (t *TestNeoFS) CreateObject(_ context.Context, prm PrmObjectCreate) (oid.ID
|
|||
return objID, nil
|
||||
}
|
||||
|
||||
func (t *TestNeoFS) DeleteObject(_ context.Context, prm PrmObjectDelete) error {
|
||||
func (t *TestNeoFS) DeleteObject(ctx context.Context, prm PrmObjectDelete) error {
|
||||
var addr oid.Address
|
||||
addr.SetContainer(prm.Container)
|
||||
addr.SetObject(prm.Object)
|
||||
|
||||
if obj, ok := t.objects[addr.EncodeToString()]; ok {
|
||||
owner := getOwner(ctx)
|
||||
if !obj.OwnerID().Equals(owner) {
|
||||
return ErrAccessDenied
|
||||
}
|
||||
|
||||
delete(t.objects, addr.EncodeToString())
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
@ -260,3 +276,11 @@ func (t *TestNeoFS) ContainerEACL(_ context.Context, cnrID cid.ID) (*eacl.Table,
|
|||
|
||||
return table, nil
|
||||
}
|
||||
|
||||
func getOwner(ctx context.Context) user.ID {
|
||||
if bd, ok := ctx.Value(api.BoxData).(*accessbox.Box); ok && bd != nil && bd.Gate != nil && bd.Gate.BearerToken != nil {
|
||||
return bearer.ResolveIssuer(*bd.Gate.BearerToken)
|
||||
}
|
||||
|
||||
return user.ID{}
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ import (
|
|||
bearertest "github.com/nspcc-dev/neofs-sdk-go/bearer/test"
|
||||
"github.com/nspcc-dev/neofs-sdk-go/object"
|
||||
oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
|
||||
usertest "github.com/nspcc-dev/neofs-sdk-go/user/test"
|
||||
"github.com/nspcc-dev/neofs-sdk-go/user"
|
||||
"github.com/stretchr/testify/require"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
@ -159,6 +159,9 @@ func prepareContext(t *testing.T, cachesConfig ...*CachesConfig) *testContext {
|
|||
config = cachesConfig[0]
|
||||
}
|
||||
|
||||
var owner user.ID
|
||||
user.IDFromKey(&owner, key.PrivateKey.PublicKey)
|
||||
|
||||
layerCfg := &Config{
|
||||
Caches: config,
|
||||
AnonKey: AnonymousKey{Key: key},
|
||||
|
@ -170,7 +173,7 @@ func prepareContext(t *testing.T, cachesConfig ...*CachesConfig) *testContext {
|
|||
layer: NewLayer(logger, tp, layerCfg),
|
||||
bktInfo: &data.BucketInfo{
|
||||
Name: bktName,
|
||||
Owner: *usertest.ID(),
|
||||
Owner: owner,
|
||||
CID: bktID,
|
||||
},
|
||||
obj: "obj1",
|
||||
|
|
Loading…
Reference in a new issue