forked from TrueCloudLab/frostfs-s3-gw
[#617] api/handler: Simplify tests
Signed-off-by: Denis Kirillov <denis@nspcc.ru>
This commit is contained in:
parent
cb87fc693b
commit
18a6aca4b4
6 changed files with 166 additions and 237 deletions
44
api/handler/attributes_test.go
Normal file
44
api/handler/attributes_test.go
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
package handler
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/nspcc-dev/neofs-s3-gw/api"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestGetObjectPartsAttributes(t *testing.T) {
|
||||||
|
hc := prepareHandlerContext(t)
|
||||||
|
|
||||||
|
bktName := "bucket-get-attributes"
|
||||||
|
objName, objMultipartName := "object", "object-multipart"
|
||||||
|
partSize := 8
|
||||||
|
|
||||||
|
createTestBucket(hc, bktName)
|
||||||
|
|
||||||
|
putObject(t, hc, bktName, objName)
|
||||||
|
result := getObjectAttributes(hc, bktName, objName, objectParts)
|
||||||
|
require.Nil(t, result.ObjectParts)
|
||||||
|
|
||||||
|
multipartUpload := createMultipartUpload(hc, bktName, objMultipartName, map[string]string{})
|
||||||
|
etag, _ := uploadPart(hc, bktName, objMultipartName, multipartUpload.UploadID, 1, partSize)
|
||||||
|
completeMultipartUpload(hc, bktName, objMultipartName, multipartUpload.UploadID, []string{etag})
|
||||||
|
|
||||||
|
result = getObjectAttributes(hc, bktName, objMultipartName, objectParts)
|
||||||
|
require.NotNil(t, result.ObjectParts)
|
||||||
|
require.Len(t, result.ObjectParts.Parts, 1)
|
||||||
|
require.Equal(t, etag, result.ObjectParts.Parts[0].ChecksumSHA256)
|
||||||
|
require.Equal(t, partSize, result.ObjectParts.Parts[0].Size)
|
||||||
|
require.Equal(t, 1, result.ObjectParts.PartsCount)
|
||||||
|
}
|
||||||
|
|
||||||
|
func getObjectAttributes(hc *handlerContext, bktName, objName string, attrs ...string) *GetObjectAttributesResponse {
|
||||||
|
w, r := prepareTestRequest(hc, bktName, objName, nil)
|
||||||
|
r.Header.Set(api.AmzObjectAttributes, strings.Join(attrs, ","))
|
||||||
|
hc.Handler().GetObjectAttributesHandler(w, r)
|
||||||
|
result := &GetObjectAttributesResponse{}
|
||||||
|
parseTestResponse(hc.t, w, result)
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
|
@ -1,72 +0,0 @@
|
||||||
package handler
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"net/http"
|
|
||||||
"net/url"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/nspcc-dev/neofs-s3-gw/api"
|
|
||||||
"github.com/nspcc-dev/neofs-s3-gw/api/layer"
|
|
||||||
"github.com/stretchr/testify/require"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestGetObjectPartsAttributes(t *testing.T) {
|
|
||||||
hc := prepareHandlerContext(t)
|
|
||||||
|
|
||||||
bktName := "bucket-get-attributes"
|
|
||||||
objName, objMultipartName := "object", "object-multipart"
|
|
||||||
|
|
||||||
createTestBucket(hc, bktName)
|
|
||||||
|
|
||||||
body := bytes.NewReader([]byte("content"))
|
|
||||||
w, r := prepareTestPayloadRequest(hc, bktName, objName, body)
|
|
||||||
hc.Handler().PutObjectHandler(w, r)
|
|
||||||
assertStatus(t, w, http.StatusOK)
|
|
||||||
|
|
||||||
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(hc, bktName, objMultipartName, nil)
|
|
||||||
hc.Handler().CreateMultipartUploadHandler(w, r)
|
|
||||||
multipartUpload := &InitiateMultipartUploadResponse{}
|
|
||||||
parseTestResponse(t, w, multipartUpload)
|
|
||||||
|
|
||||||
body2 := bytes.NewReader([]byte("content2"))
|
|
||||||
w, r = prepareTestPayloadRequest(hc, bktName, objMultipartName, body2)
|
|
||||||
query := make(url.Values)
|
|
||||||
query.Add(uploadIDHeaderName, multipartUpload.UploadID)
|
|
||||||
query.Add(partNumberHeaderName, "1")
|
|
||||||
r.URL.RawQuery = query.Encode()
|
|
||||||
hc.Handler().UploadPartHandler(w, r)
|
|
||||||
assertStatus(t, w, http.StatusOK)
|
|
||||||
etag := w.Result().Header.Get(api.ETag)
|
|
||||||
|
|
||||||
completeUpload := &CompleteMultipartUpload{
|
|
||||||
Parts: []*layer.CompletedPart{{
|
|
||||||
ETag: etag,
|
|
||||||
PartNumber: 1,
|
|
||||||
}},
|
|
||||||
}
|
|
||||||
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(hc, bktName, objMultipartName, nil)
|
|
||||||
r.Header.Set(api.AmzObjectAttributes, objectParts)
|
|
||||||
hc.Handler().GetObjectAttributesHandler(w, r)
|
|
||||||
result = &GetObjectAttributesResponse{}
|
|
||||||
parseTestResponse(t, w, result)
|
|
||||||
require.NotNil(t, result.ObjectParts)
|
|
||||||
require.Len(t, result.ObjectParts.Parts, 1)
|
|
||||||
require.Equal(t, etag, result.ObjectParts.Parts[0].ChecksumSHA256)
|
|
||||||
require.Equal(t, 8, result.ObjectParts.Parts[0].Size)
|
|
||||||
require.Equal(t, 1, result.ObjectParts.PartsCount)
|
|
||||||
}
|
|
|
@ -99,7 +99,7 @@ func TestS3EncryptionSSECMultipartUpload(t *testing.T) {
|
||||||
api.ContentType: "text/plain",
|
api.ContentType: "text/plain",
|
||||||
}
|
}
|
||||||
|
|
||||||
data := multipartUploadEncrypted(t, tc, bktName, objName, headers, objLen, partSize)
|
data := multipartUploadEncrypted(tc, bktName, objName, headers, objLen, partSize)
|
||||||
require.Equal(t, objLen, len(data))
|
require.Equal(t, objLen, len(data))
|
||||||
|
|
||||||
resData, resHeader := getEncryptedObject(t, tc, bktName, objName)
|
resData, resHeader := getEncryptedObject(t, tc, bktName, objName)
|
||||||
|
@ -143,8 +143,8 @@ func checkContentUsingRangeEnc(t *testing.T, tc *handlerContext, bktName, objNam
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func multipartUploadEncrypted(t *testing.T, tc *handlerContext, bktName, objName string, headers map[string]string, objLen, partsSize int) (objData []byte) {
|
func multipartUploadEncrypted(hc *handlerContext, bktName, objName string, headers map[string]string, objLen, partsSize int) (objData []byte) {
|
||||||
multipartInfo := createMultipartUpload(t, tc, bktName, objName, headers)
|
multipartInfo := createMultipartUploadEncrypted(hc, bktName, objName, headers)
|
||||||
|
|
||||||
var sum, currentPart int
|
var sum, currentPart int
|
||||||
var etags []string
|
var etags []string
|
||||||
|
@ -158,26 +158,37 @@ func multipartUploadEncrypted(t *testing.T, tc *handlerContext, bktName, objName
|
||||||
adjustedSize = objLen - sum
|
adjustedSize = objLen - sum
|
||||||
}
|
}
|
||||||
|
|
||||||
etag, data := uploadPart(t, tc, bktName, objName, multipartInfo.UploadID, currentPart, adjustedSize)
|
etag, data := uploadPartEncrypted(hc, bktName, objName, multipartInfo.UploadID, currentPart, adjustedSize)
|
||||||
etags = append(etags, etag)
|
etags = append(etags, etag)
|
||||||
objData = append(objData, data...)
|
objData = append(objData, data...)
|
||||||
}
|
}
|
||||||
|
|
||||||
completeMultipartUpload(t, tc, bktName, objName, multipartInfo.UploadID, etags)
|
completeMultipartUpload(hc, bktName, objName, multipartInfo.UploadID, etags)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func createMultipartUpload(t *testing.T, tc *handlerContext, bktName, objName string, headers map[string]string) *InitiateMultipartUploadResponse {
|
func createMultipartUploadEncrypted(hc *handlerContext, bktName, objName string, headers map[string]string) *InitiateMultipartUploadResponse {
|
||||||
w, r := prepareTestRequest(tc, bktName, objName, nil)
|
return createMultipartUploadBase(hc, bktName, objName, true, headers)
|
||||||
setEncryptHeaders(r)
|
}
|
||||||
|
|
||||||
|
func createMultipartUpload(hc *handlerContext, bktName, objName string, headers map[string]string) *InitiateMultipartUploadResponse {
|
||||||
|
return createMultipartUploadBase(hc, bktName, objName, false, headers)
|
||||||
|
}
|
||||||
|
|
||||||
|
func createMultipartUploadBase(hc *handlerContext, bktName, objName string, encrypted bool, headers map[string]string) *InitiateMultipartUploadResponse {
|
||||||
|
w, r := prepareTestRequest(hc, bktName, objName, nil)
|
||||||
|
if encrypted {
|
||||||
|
setEncryptHeaders(r)
|
||||||
|
}
|
||||||
setHeaders(r, headers)
|
setHeaders(r, headers)
|
||||||
tc.Handler().CreateMultipartUploadHandler(w, r)
|
hc.Handler().CreateMultipartUploadHandler(w, r)
|
||||||
multipartInitInfo := &InitiateMultipartUploadResponse{}
|
multipartInitInfo := &InitiateMultipartUploadResponse{}
|
||||||
readResponse(t, w, http.StatusOK, multipartInitInfo)
|
readResponse(hc.t, w, http.StatusOK, multipartInitInfo)
|
||||||
|
|
||||||
return multipartInitInfo
|
return multipartInitInfo
|
||||||
}
|
}
|
||||||
func completeMultipartUpload(t *testing.T, tc *handlerContext, bktName, objName, uploadID string, partsETags []string) {
|
|
||||||
|
func completeMultipartUpload(hc *handlerContext, bktName, objName, uploadID string, partsETags []string) {
|
||||||
query := make(url.Values)
|
query := make(url.Values)
|
||||||
query.Set(uploadIDQuery, uploadID)
|
query.Set(uploadIDQuery, uploadID)
|
||||||
complete := &CompleteMultipartUpload{
|
complete := &CompleteMultipartUpload{
|
||||||
|
@ -190,24 +201,34 @@ func completeMultipartUpload(t *testing.T, tc *handlerContext, bktName, objName,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
w, r := prepareTestFullRequest(tc, bktName, objName, query, complete)
|
w, r := prepareTestFullRequest(hc, bktName, objName, query, complete)
|
||||||
tc.Handler().CompleteMultipartUploadHandler(w, r)
|
hc.Handler().CompleteMultipartUploadHandler(w, r)
|
||||||
assertStatus(t, w, http.StatusOK)
|
assertStatus(hc.t, w, http.StatusOK)
|
||||||
}
|
}
|
||||||
|
|
||||||
func uploadPart(t *testing.T, tc *handlerContext, bktName, objName, uploadID string, num, size int) (string, []byte) {
|
func uploadPartEncrypted(hc *handlerContext, bktName, objName, uploadID string, num, size int) (string, []byte) {
|
||||||
|
return uploadPartBase(hc, bktName, objName, true, uploadID, num, size)
|
||||||
|
}
|
||||||
|
|
||||||
|
func uploadPart(hc *handlerContext, bktName, objName, uploadID string, num, size int) (string, []byte) {
|
||||||
|
return uploadPartBase(hc, bktName, objName, false, uploadID, num, size)
|
||||||
|
}
|
||||||
|
|
||||||
|
func uploadPartBase(hc *handlerContext, bktName, objName string, encrypted bool, uploadID string, num, size int) (string, []byte) {
|
||||||
partBody := make([]byte, size)
|
partBody := make([]byte, size)
|
||||||
_, err := rand.Read(partBody)
|
_, err := rand.Read(partBody)
|
||||||
require.NoError(t, err)
|
require.NoError(hc.t, err)
|
||||||
|
|
||||||
query := make(url.Values)
|
query := make(url.Values)
|
||||||
query.Set(uploadIDQuery, uploadID)
|
query.Set(uploadIDQuery, uploadID)
|
||||||
query.Set(partNumberQuery, strconv.Itoa(num))
|
query.Set(partNumberQuery, strconv.Itoa(num))
|
||||||
|
|
||||||
w, r := prepareTestRequestWithQuery(tc, bktName, objName, query, partBody)
|
w, r := prepareTestRequestWithQuery(hc, bktName, objName, query, partBody)
|
||||||
setEncryptHeaders(r)
|
if encrypted {
|
||||||
tc.Handler().UploadPartHandler(w, r)
|
setEncryptHeaders(r)
|
||||||
assertStatus(t, w, http.StatusOK)
|
}
|
||||||
|
hc.Handler().UploadPartHandler(w, r)
|
||||||
|
assertStatus(hc.t, w, http.StatusOK)
|
||||||
|
|
||||||
return w.Header().Get(api.ETag), partBody
|
return w.Header().Get(api.ETag), partBody
|
||||||
}
|
}
|
||||||
|
@ -215,57 +236,21 @@ func uploadPart(t *testing.T, tc *handlerContext, bktName, objName, uploadID str
|
||||||
func TestMultipartEncrypted(t *testing.T) {
|
func TestMultipartEncrypted(t *testing.T) {
|
||||||
partSize := 5*1048576 + 1<<16 - 5 // 5MB (min part size) + 64kb (cipher block size) - 5 (to check corner range)
|
partSize := 5*1048576 + 1<<16 - 5 // 5MB (min part size) + 64kb (cipher block size) - 5 (to check corner range)
|
||||||
|
|
||||||
tc := prepareHandlerContext(t)
|
hc := prepareHandlerContext(t)
|
||||||
|
|
||||||
bktName, objName := "bucket-for-sse-c-multipart", "object-to-encrypt-multipart"
|
bktName, objName := "bucket-for-sse-c-multipart", "object-to-encrypt-multipart"
|
||||||
createTestBucket(tc, bktName)
|
createTestBucket(hc, bktName)
|
||||||
|
|
||||||
w, r := prepareTestRequest(tc, bktName, objName, nil)
|
multipartInitInfo := createMultipartUploadEncrypted(hc, bktName, objName, map[string]string{})
|
||||||
setEncryptHeaders(r)
|
part1ETag, part1 := uploadPartEncrypted(hc, bktName, objName, multipartInitInfo.UploadID, 1, partSize)
|
||||||
tc.Handler().CreateMultipartUploadHandler(w, r)
|
part2ETag, part2 := uploadPartEncrypted(hc, bktName, objName, multipartInitInfo.UploadID, 2, 5)
|
||||||
multipartInitInfo := &InitiateMultipartUploadResponse{}
|
completeMultipartUpload(hc, bktName, objName, multipartInitInfo.UploadID, []string{part1ETag, part2ETag})
|
||||||
readResponse(t, w, http.StatusOK, multipartInitInfo)
|
|
||||||
|
|
||||||
part1 := make([]byte, partSize)
|
res, _ := getEncryptedObject(t, hc, bktName, objName)
|
||||||
for i := range part1 {
|
|
||||||
part1[i] = 'a'
|
|
||||||
}
|
|
||||||
query := make(url.Values)
|
|
||||||
query.Set(uploadIDQuery, multipartInitInfo.UploadID)
|
|
||||||
query.Set(partNumberQuery, "1")
|
|
||||||
w, r = prepareTestRequestWithQuery(tc, bktName, objName, query, part1)
|
|
||||||
setEncryptHeaders(r)
|
|
||||||
tc.Handler().UploadPartHandler(w, r)
|
|
||||||
assertStatus(t, w, http.StatusOK)
|
|
||||||
part1ETag := w.Header().Get(api.ETag)
|
|
||||||
|
|
||||||
part2 := []byte("part2")
|
|
||||||
query = make(url.Values)
|
|
||||||
query.Set(uploadIDQuery, multipartInitInfo.UploadID)
|
|
||||||
query.Set(partNumberQuery, "2")
|
|
||||||
w, r = prepareTestRequestWithQuery(tc, bktName, objName, query, part2)
|
|
||||||
setEncryptHeaders(r)
|
|
||||||
tc.Handler().UploadPartHandler(w, r)
|
|
||||||
assertStatus(t, w, http.StatusOK)
|
|
||||||
part2ETag := w.Header().Get(api.ETag)
|
|
||||||
|
|
||||||
query = make(url.Values)
|
|
||||||
query.Set(uploadIDQuery, multipartInitInfo.UploadID)
|
|
||||||
complete := &CompleteMultipartUpload{
|
|
||||||
Parts: []*layer.CompletedPart{
|
|
||||||
{ETag: part1ETag, PartNumber: 1},
|
|
||||||
{ETag: part2ETag, PartNumber: 2},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
w, r = prepareTestFullRequest(tc, bktName, objName, query, complete)
|
|
||||||
tc.Handler().CompleteMultipartUploadHandler(w, r)
|
|
||||||
assertStatus(t, w, http.StatusOK)
|
|
||||||
|
|
||||||
res, _ := getEncryptedObject(t, tc, bktName, objName)
|
|
||||||
require.Equal(t, len(part1)+len(part2), len(res))
|
require.Equal(t, len(part1)+len(part2), len(res))
|
||||||
require.Equal(t, append(part1, part2...), res)
|
require.Equal(t, append(part1, part2...), res)
|
||||||
|
|
||||||
part2Range := getEncryptedObjectRange(t, tc, bktName, objName, len(part1), len(part1)+len(part2)-1)
|
part2Range := getEncryptedObjectRange(t, hc, bktName, objName, len(part1), len(part1)+len(part2)-1)
|
||||||
require.Equal(t, part2[0:], part2Range)
|
require.Equal(t, part2[0:], part2Range)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -155,7 +155,7 @@ func TestGetRange(t *testing.T) {
|
||||||
createTestBucket(tc, bktName)
|
createTestBucket(tc, bktName)
|
||||||
|
|
||||||
content := "123456789abcdef"
|
content := "123456789abcdef"
|
||||||
putObjectContent(t, tc, bktName, objName, content)
|
putObjectContent(tc, bktName, objName, content)
|
||||||
|
|
||||||
full := getObjectRange(t, tc, bktName, objName, 0, len(content)-1)
|
full := getObjectRange(t, tc, bktName, objName, 0, len(content)-1)
|
||||||
require.Equal(t, content, string(full))
|
require.Equal(t, content, string(full))
|
||||||
|
@ -170,11 +170,11 @@ func TestGetRange(t *testing.T) {
|
||||||
require.Equal(t, "bcdef", string(end))
|
require.Equal(t, "bcdef", string(end))
|
||||||
}
|
}
|
||||||
|
|
||||||
func putObjectContent(t *testing.T, tc *handlerContext, bktName, objName, content string) {
|
func putObjectContent(hc *handlerContext, bktName, objName, content string) {
|
||||||
body := bytes.NewReader([]byte(content))
|
body := bytes.NewReader([]byte(content))
|
||||||
w, r := prepareTestPayloadRequest(tc, bktName, objName, body)
|
w, r := prepareTestPayloadRequest(hc, bktName, objName, body)
|
||||||
tc.Handler().PutObjectHandler(w, r)
|
hc.Handler().PutObjectHandler(w, r)
|
||||||
assertStatus(t, w, http.StatusOK)
|
assertStatus(hc.t, w, http.StatusOK)
|
||||||
}
|
}
|
||||||
|
|
||||||
func getObjectRange(t *testing.T, tc *handlerContext, bktName, objName string, start, end int) []byte {
|
func getObjectRange(t *testing.T, tc *handlerContext, bktName, objName string, start, end int) []byte {
|
||||||
|
|
|
@ -423,35 +423,31 @@ func TestObjectLegalHold(t *testing.T) {
|
||||||
objName := "obj-for-legal-hold"
|
objName := "obj-for-legal-hold"
|
||||||
createTestObject(hc, bktInfo, objName)
|
createTestObject(hc, bktInfo, objName)
|
||||||
|
|
||||||
|
getObjectLegalHold(hc, bktName, objName, legalHoldOff)
|
||||||
|
|
||||||
|
putObjectLegalHold(hc, bktName, objName, legalHoldOn)
|
||||||
|
getObjectLegalHold(hc, bktName, objName, legalHoldOn)
|
||||||
|
|
||||||
|
// to make sure put hold is an idempotent operation
|
||||||
|
putObjectLegalHold(hc, bktName, objName, legalHoldOn)
|
||||||
|
|
||||||
|
putObjectLegalHold(hc, bktName, objName, legalHoldOff)
|
||||||
|
getObjectLegalHold(hc, bktName, objName, legalHoldOff)
|
||||||
|
|
||||||
|
// to make sure put hold is an idempotent operation
|
||||||
|
putObjectLegalHold(hc, bktName, objName, legalHoldOff)
|
||||||
|
}
|
||||||
|
|
||||||
|
func getObjectLegalHold(hc *handlerContext, bktName, objName, status string) {
|
||||||
w, r := prepareTestRequest(hc, bktName, objName, nil)
|
w, r := prepareTestRequest(hc, bktName, objName, nil)
|
||||||
hc.Handler().GetObjectLegalHoldHandler(w, r)
|
hc.Handler().GetObjectLegalHoldHandler(w, r)
|
||||||
assertLegalHold(t, w, legalHoldOff)
|
assertLegalHold(hc.t, w, status)
|
||||||
|
}
|
||||||
|
|
||||||
w, r = prepareTestRequest(hc, bktName, objName, &data.LegalHold{Status: legalHoldOn})
|
func putObjectLegalHold(hc *handlerContext, bktName, objName, status string) {
|
||||||
|
w, r := prepareTestRequest(hc, bktName, objName, &data.LegalHold{Status: status})
|
||||||
hc.Handler().PutObjectLegalHoldHandler(w, r)
|
hc.Handler().PutObjectLegalHoldHandler(w, r)
|
||||||
assertStatus(t, w, http.StatusOK)
|
assertStatus(hc.t, w, http.StatusOK)
|
||||||
|
|
||||||
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(hc, bktName, objName, &data.LegalHold{Status: legalHoldOn})
|
|
||||||
hc.Handler().PutObjectLegalHoldHandler(w, r)
|
|
||||||
assertStatus(t, w, http.StatusOK)
|
|
||||||
|
|
||||||
w, r = prepareTestRequest(hc, bktName, objName, &data.LegalHold{Status: legalHoldOff})
|
|
||||||
hc.Handler().PutObjectLegalHoldHandler(w, r)
|
|
||||||
assertStatus(t, w, http.StatusOK)
|
|
||||||
|
|
||||||
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(hc, bktName, objName, &data.LegalHold{Status: legalHoldOff})
|
|
||||||
hc.Handler().PutObjectLegalHoldHandler(w, r)
|
|
||||||
assertStatus(t, w, http.StatusOK)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func assertLegalHold(t *testing.T, w *httptest.ResponseRecorder, status string) {
|
func assertLegalHold(t *testing.T, w *httptest.ResponseRecorder, status string) {
|
||||||
|
@ -471,38 +467,43 @@ func TestObjectRetention(t *testing.T) {
|
||||||
objName := "obj-for-retention"
|
objName := "obj-for-retention"
|
||||||
createTestObject(hc, bktInfo, objName)
|
createTestObject(hc, bktInfo, objName)
|
||||||
|
|
||||||
w, r := prepareTestRequest(hc, bktName, objName, nil)
|
getObjectRetention(hc, bktName, objName, nil, apiErrors.ErrNoSuchKey)
|
||||||
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)}
|
retention := &data.Retention{Mode: governanceMode, RetainUntilDate: time.Now().Add(time.Minute).UTC().Format(time.RFC3339)}
|
||||||
w, r = prepareTestRequest(hc, bktName, objName, retention)
|
putObjectRetention(hc, bktName, objName, retention, false, 0)
|
||||||
hc.Handler().PutObjectRetentionHandler(w, r)
|
getObjectRetention(hc, bktName, objName, retention, 0)
|
||||||
assertStatus(t, w, http.StatusOK)
|
|
||||||
|
|
||||||
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)}
|
retention = &data.Retention{Mode: governanceMode, RetainUntilDate: time.Now().UTC().Add(time.Minute).Format(time.RFC3339)}
|
||||||
w, r = prepareTestRequest(hc, bktName, objName, retention)
|
putObjectRetention(hc, bktName, objName, retention, false, apiErrors.ErrInternalError)
|
||||||
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)}
|
retention = &data.Retention{Mode: complianceMode, RetainUntilDate: time.Now().Add(time.Minute).UTC().Format(time.RFC3339)}
|
||||||
w, r = prepareTestRequest(hc, bktName, objName, retention)
|
putObjectRetention(hc, bktName, objName, retention, true, 0)
|
||||||
r.Header.Set(api.AmzBypassGovernanceRetention, strconv.FormatBool(true))
|
getObjectRetention(hc, bktName, objName, retention, 0)
|
||||||
hc.Handler().PutObjectRetentionHandler(w, r)
|
|
||||||
assertStatus(t, w, http.StatusOK)
|
|
||||||
|
|
||||||
w, r = prepareTestRequest(hc, bktName, objName, nil)
|
putObjectRetention(hc, bktName, objName, retention, true, apiErrors.ErrInternalError)
|
||||||
|
}
|
||||||
|
|
||||||
|
func getObjectRetention(hc *handlerContext, bktName, objName string, retention *data.Retention, errCode apiErrors.ErrorCode) {
|
||||||
|
w, r := prepareTestRequest(hc, bktName, objName, nil)
|
||||||
hc.Handler().GetObjectRetentionHandler(w, r)
|
hc.Handler().GetObjectRetentionHandler(w, r)
|
||||||
assertRetention(t, w, retention)
|
if errCode == 0 {
|
||||||
|
assertRetention(hc.t, w, retention)
|
||||||
|
} else {
|
||||||
|
assertS3Error(hc.t, w, apiErrors.GetAPIError(errCode))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
w, r = prepareTestRequest(hc, bktName, objName, retention)
|
func putObjectRetention(hc *handlerContext, bktName, objName string, retention *data.Retention, byPass bool, errCode apiErrors.ErrorCode) {
|
||||||
r.Header.Set(api.AmzBypassGovernanceRetention, strconv.FormatBool(true))
|
w, r := prepareTestRequest(hc, bktName, objName, retention)
|
||||||
|
if byPass {
|
||||||
|
r.Header.Set(api.AmzBypassGovernanceRetention, strconv.FormatBool(true))
|
||||||
|
}
|
||||||
hc.Handler().PutObjectRetentionHandler(w, r)
|
hc.Handler().PutObjectRetentionHandler(w, r)
|
||||||
assertS3Error(t, w, apiErrors.GetAPIError(apiErrors.ErrInternalError))
|
if errCode == 0 {
|
||||||
|
assertStatus(hc.t, w, http.StatusOK)
|
||||||
|
} else {
|
||||||
|
assertS3Error(hc.t, w, apiErrors.GetAPIError(errCode))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func assertRetention(t *testing.T, w *httptest.ResponseRecorder, retention *data.Retention) {
|
func assertRetention(t *testing.T, w *httptest.ResponseRecorder, retention *data.Retention) {
|
||||||
|
@ -530,25 +531,13 @@ func TestPutObjectWithLock(t *testing.T) {
|
||||||
createTestBucketWithLock(hc, bktName, lockConfig)
|
createTestBucketWithLock(hc, bktName, lockConfig)
|
||||||
|
|
||||||
objDefault := "obj-default-retention"
|
objDefault := "obj-default-retention"
|
||||||
|
putObject(t, hc, bktName, objDefault)
|
||||||
|
|
||||||
w, r := prepareTestRequest(hc, bktName, objDefault, nil)
|
getObjectRetentionApproximate(hc, bktName, objDefault, governanceMode, time.Now().Add(24*time.Hour))
|
||||||
hc.Handler().PutObjectHandler(w, r)
|
getObjectLegalHold(hc, bktName, objDefault, legalHoldOff)
|
||||||
assertStatus(t, w, http.StatusOK)
|
|
||||||
|
|
||||||
w, r = prepareTestRequest(hc, bktName, objDefault, nil)
|
|
||||||
hc.Handler().GetObjectRetentionHandler(w, r)
|
|
||||||
expectedRetention := &data.Retention{
|
|
||||||
Mode: governanceMode,
|
|
||||||
RetainUntilDate: time.Now().Add(24 * time.Hour).Format(time.RFC3339),
|
|
||||||
}
|
|
||||||
assertRetentionApproximate(t, w, expectedRetention, 1)
|
|
||||||
|
|
||||||
w, r = prepareTestRequest(hc, bktName, objDefault, nil)
|
|
||||||
hc.Handler().GetObjectLegalHoldHandler(w, r)
|
|
||||||
assertLegalHold(t, w, legalHoldOff)
|
|
||||||
|
|
||||||
objOverride := "obj-override-retention"
|
objOverride := "obj-override-retention"
|
||||||
w, r = prepareTestRequest(hc, bktName, objOverride, nil)
|
w, r := prepareTestRequest(hc, bktName, objOverride, nil)
|
||||||
r.Header.Set(api.AmzObjectLockMode, complianceMode)
|
r.Header.Set(api.AmzObjectLockMode, complianceMode)
|
||||||
r.Header.Set(api.AmzObjectLockLegalHold, legalHoldOn)
|
r.Header.Set(api.AmzObjectLockLegalHold, legalHoldOn)
|
||||||
r.Header.Set(api.AmzBypassGovernanceRetention, "true")
|
r.Header.Set(api.AmzBypassGovernanceRetention, "true")
|
||||||
|
@ -556,17 +545,18 @@ func TestPutObjectWithLock(t *testing.T) {
|
||||||
hc.Handler().PutObjectHandler(w, r)
|
hc.Handler().PutObjectHandler(w, r)
|
||||||
assertStatus(t, w, http.StatusOK)
|
assertStatus(t, w, http.StatusOK)
|
||||||
|
|
||||||
w, r = prepareTestRequest(hc, bktName, objOverride, nil)
|
getObjectRetentionApproximate(hc, bktName, objOverride, complianceMode, time.Now().Add(2*24*time.Hour))
|
||||||
hc.Handler().GetObjectRetentionHandler(w, r)
|
getObjectLegalHold(hc, bktName, objOverride, legalHoldOn)
|
||||||
expectedRetention = &data.Retention{
|
}
|
||||||
Mode: complianceMode,
|
|
||||||
RetainUntilDate: time.Now().Add(2 * 24 * time.Hour).Format(time.RFC3339),
|
|
||||||
}
|
|
||||||
assertRetentionApproximate(t, w, expectedRetention, 1)
|
|
||||||
|
|
||||||
w, r = prepareTestRequest(hc, bktName, objOverride, nil)
|
func getObjectRetentionApproximate(hc *handlerContext, bktName, objName, mode string, untilDate time.Time) {
|
||||||
hc.Handler().GetObjectLegalHoldHandler(w, r)
|
w, r := prepareTestRequest(hc, bktName, objName, nil)
|
||||||
assertLegalHold(t, w, legalHoldOn)
|
hc.Handler().GetObjectRetentionHandler(w, r)
|
||||||
|
expectedRetention := &data.Retention{
|
||||||
|
Mode: mode,
|
||||||
|
RetainUntilDate: untilDate.Format(time.RFC3339),
|
||||||
|
}
|
||||||
|
assertRetentionApproximate(hc.t, w, expectedRetention, 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestPutLockErrors(t *testing.T) {
|
func TestPutLockErrors(t *testing.T) {
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package handler
|
package handler
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
@ -44,31 +43,14 @@ func TestParseContinuationToken(t *testing.T) {
|
||||||
func TestListObjectNullVersions(t *testing.T) {
|
func TestListObjectNullVersions(t *testing.T) {
|
||||||
hc := prepareHandlerContext(t)
|
hc := prepareHandlerContext(t)
|
||||||
|
|
||||||
bktName := "bucket-versioning-enabled"
|
bktName, objName := "bucket-versioning-enabled", "object"
|
||||||
createTestBucket(hc, bktName)
|
createTestBucket(hc, bktName)
|
||||||
|
|
||||||
objName := "object"
|
putObjectContent(hc, bktName, objName, "content")
|
||||||
|
putBucketVersioning(t, hc, bktName, true)
|
||||||
|
putObjectContent(hc, bktName, objName, "content2")
|
||||||
|
|
||||||
body := bytes.NewReader([]byte("content"))
|
result := listVersions(t, hc, bktName)
|
||||||
w, r := prepareTestPayloadRequest(hc, bktName, objName, body)
|
|
||||||
hc.Handler().PutObjectHandler(w, r)
|
|
||||||
assertStatus(t, w, http.StatusOK)
|
|
||||||
|
|
||||||
versioning := &VersioningConfiguration{Status: "Enabled"}
|
|
||||||
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(hc, bktName, objName, body2)
|
|
||||||
hc.Handler().PutObjectHandler(w, r)
|
|
||||||
assertStatus(t, w, http.StatusOK)
|
|
||||||
|
|
||||||
w, r = prepareTestRequest(hc, bktName, objName, nil)
|
|
||||||
hc.Handler().ListBucketObjectVersionsHandler(w, r)
|
|
||||||
|
|
||||||
result := &ListObjectsVersionsResponse{}
|
|
||||||
parseTestResponse(t, w, result)
|
|
||||||
|
|
||||||
require.Len(t, result.Version, 2)
|
require.Len(t, result.Version, 2)
|
||||||
require.Equal(t, data.UnversionedObjectVersionID, result.Version[1].VersionID)
|
require.Equal(t, data.UnversionedObjectVersionID, result.Version[1].VersionID)
|
||||||
|
|
Loading…
Reference in a new issue