2022-03-01 15:07:15 +00:00
|
|
|
package handler
|
|
|
|
|
|
|
|
import (
|
|
|
|
"bytes"
|
|
|
|
"context"
|
|
|
|
"encoding/xml"
|
2022-06-01 14:50:30 +00:00
|
|
|
"io"
|
2022-03-01 15:07:15 +00:00
|
|
|
"math/rand"
|
|
|
|
"net/http"
|
|
|
|
"net/http/httptest"
|
2022-06-01 14:50:30 +00:00
|
|
|
"strconv"
|
2022-03-01 15:07:15 +00:00
|
|
|
"testing"
|
2022-06-01 14:50:30 +00:00
|
|
|
"time"
|
2022-03-01 15:07:15 +00:00
|
|
|
|
2022-03-04 13:07:27 +00:00
|
|
|
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
2022-03-01 15:07:15 +00:00
|
|
|
"github.com/nspcc-dev/neofs-s3-gw/api"
|
|
|
|
"github.com/nspcc-dev/neofs-s3-gw/api/data"
|
2022-03-04 13:07:27 +00:00
|
|
|
"github.com/nspcc-dev/neofs-s3-gw/api/layer"
|
2022-03-01 15:07:15 +00:00
|
|
|
"github.com/nspcc-dev/neofs-s3-gw/api/resolver"
|
|
|
|
cid "github.com/nspcc-dev/neofs-sdk-go/container/id"
|
2022-06-01 14:50:30 +00:00
|
|
|
"github.com/nspcc-dev/neofs-sdk-go/object"
|
2022-04-25 09:57:58 +00:00
|
|
|
"github.com/nspcc-dev/neofs-sdk-go/user"
|
2022-06-29 14:43:52 +00:00
|
|
|
usertest "github.com/nspcc-dev/neofs-sdk-go/user/test"
|
2022-03-01 15:07:15 +00:00
|
|
|
"github.com/stretchr/testify/require"
|
2022-04-07 14:36:44 +00:00
|
|
|
"go.uber.org/zap"
|
2022-03-01 15:07:15 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
type handlerContext struct {
|
|
|
|
h *handler
|
2022-06-06 11:09:09 +00:00
|
|
|
tp *layer.TestNeoFS
|
2022-03-01 15:07:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (hc *handlerContext) Handler() *handler {
|
|
|
|
return hc.h
|
|
|
|
}
|
|
|
|
|
2022-06-06 11:09:09 +00:00
|
|
|
func (hc *handlerContext) MockedPool() *layer.TestNeoFS {
|
2022-03-01 15:07:15 +00:00
|
|
|
return hc.tp
|
|
|
|
}
|
|
|
|
|
|
|
|
func (hc *handlerContext) Layer() layer.Client {
|
|
|
|
return hc.h.obj
|
|
|
|
}
|
|
|
|
|
|
|
|
func prepareHandlerContext(t *testing.T) *handlerContext {
|
|
|
|
key, err := keys.NewPrivateKey()
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
2022-04-07 14:36:44 +00:00
|
|
|
l := zap.NewNop()
|
2022-06-06 11:09:09 +00:00
|
|
|
tp := layer.NewTestNeoFS()
|
2022-03-01 15:07:15 +00:00
|
|
|
|
|
|
|
testResolver := &resolver.BucketResolver{Name: "test_resolver"}
|
2022-03-04 13:07:27 +00:00
|
|
|
testResolver.SetResolveFunc(func(_ context.Context, name string) (*cid.ID, error) {
|
|
|
|
return tp.ContainerID(name)
|
2022-03-01 15:07:15 +00:00
|
|
|
})
|
|
|
|
|
|
|
|
layerCfg := &layer.Config{
|
2022-05-20 08:26:35 +00:00
|
|
|
Caches: layer.DefaultCachesConfigs(zap.NewExample()),
|
|
|
|
AnonKey: layer.AnonymousKey{Key: key},
|
|
|
|
Resolver: testResolver,
|
2022-05-31 08:12:53 +00:00
|
|
|
TreeService: layer.NewTreeService(),
|
2022-03-01 15:07:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
h := &handler{
|
|
|
|
log: l,
|
|
|
|
obj: layer.NewLayer(l, tp, layerCfg),
|
|
|
|
cfg: &Config{},
|
|
|
|
}
|
|
|
|
|
|
|
|
return &handlerContext{
|
|
|
|
h: h,
|
|
|
|
tp: tp,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func createTestBucket(ctx context.Context, t *testing.T, h *handlerContext, bktName string) {
|
2022-06-06 11:09:09 +00:00
|
|
|
_, err := h.MockedPool().CreateContainer(ctx, layer.PrmContainerCreate{
|
2022-06-29 14:43:52 +00:00
|
|
|
Creator: *usertest.ID(),
|
|
|
|
Name: bktName,
|
2022-03-04 13:07:27 +00:00
|
|
|
})
|
2022-03-01 15:07:15 +00:00
|
|
|
require.NoError(t, err)
|
|
|
|
}
|
|
|
|
|
2022-03-18 13:04:09 +00:00
|
|
|
func createTestBucketWithLock(ctx context.Context, t *testing.T, h *handlerContext, bktName string, conf *data.ObjectLockConfiguration) *data.BucketInfo {
|
2022-06-06 11:09:09 +00:00
|
|
|
cnrID, err := h.MockedPool().CreateContainer(ctx, layer.PrmContainerCreate{
|
2022-06-29 14:43:52 +00:00
|
|
|
Creator: *usertest.ID(),
|
2022-03-04 13:07:27 +00:00
|
|
|
Name: bktName,
|
|
|
|
AdditionalAttributes: [][2]string{{layer.AttributeLockEnabled, "true"}},
|
|
|
|
})
|
2022-03-01 15:07:15 +00:00
|
|
|
require.NoError(t, err)
|
|
|
|
|
2022-04-25 09:57:58 +00:00
|
|
|
var ownerID user.ID
|
|
|
|
|
2022-03-18 13:04:09 +00:00
|
|
|
bktInfo := &data.BucketInfo{
|
2022-05-25 17:25:43 +00:00
|
|
|
CID: *cnrID,
|
2022-03-18 13:04:09 +00:00
|
|
|
Name: bktName,
|
|
|
|
ObjectLockEnabled: true,
|
2022-05-25 17:25:43 +00:00
|
|
|
Owner: ownerID,
|
2022-03-18 13:04:09 +00:00
|
|
|
}
|
|
|
|
|
2022-03-01 15:07:15 +00:00
|
|
|
sp := &layer.PutSettingsParams{
|
2022-03-18 13:04:09 +00:00
|
|
|
BktInfo: bktInfo,
|
2022-03-01 15:07:15 +00:00
|
|
|
Settings: &data.BucketSettings{
|
|
|
|
VersioningEnabled: true,
|
|
|
|
LockConfiguration: conf,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
err = h.Layer().PutBucketSettings(ctx, sp)
|
|
|
|
require.NoError(t, err)
|
2022-03-18 13:04:09 +00:00
|
|
|
|
|
|
|
return bktInfo
|
2022-03-01 15:07:15 +00:00
|
|
|
}
|
|
|
|
|
2022-03-18 13:04:09 +00:00
|
|
|
func createTestObject(ctx context.Context, t *testing.T, h *handlerContext, bktInfo *data.BucketInfo, objName string) {
|
2022-03-01 15:07:15 +00:00
|
|
|
content := make([]byte, 1024)
|
|
|
|
_, err := rand.Read(content)
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
2022-06-01 14:50:30 +00:00
|
|
|
header := map[string]string{
|
|
|
|
object.AttributeTimestamp: strconv.FormatInt(time.Now().UTC().Unix(), 10),
|
|
|
|
}
|
|
|
|
|
2022-03-01 15:07:15 +00:00
|
|
|
_, err = h.Layer().PutObject(ctx, &layer.PutObjectParams{
|
2022-03-18 13:04:09 +00:00
|
|
|
BktInfo: bktInfo,
|
|
|
|
Object: objName,
|
|
|
|
Size: int64(len(content)),
|
|
|
|
Reader: bytes.NewReader(content),
|
2022-06-01 14:50:30 +00:00
|
|
|
Header: header,
|
2022-03-01 15:07:15 +00:00
|
|
|
})
|
|
|
|
require.NoError(t, err)
|
|
|
|
}
|
|
|
|
|
|
|
|
func prepareTestRequest(t *testing.T, bktName, objName string, body interface{}) (*httptest.ResponseRecorder, *http.Request) {
|
|
|
|
rawBody, err := xml.Marshal(body)
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
w := httptest.NewRecorder()
|
2022-03-02 06:19:01 +00:00
|
|
|
r := httptest.NewRequest(http.MethodPut, defaultURL, bytes.NewReader(rawBody))
|
2022-03-01 15:07:15 +00:00
|
|
|
|
|
|
|
reqInfo := api.NewReqInfo(w, r, api.ObjectRequest{Bucket: bktName, Object: objName})
|
|
|
|
r = r.WithContext(api.SetReqInfo(r.Context(), reqInfo))
|
|
|
|
|
|
|
|
return w, r
|
|
|
|
}
|
2022-06-01 14:50:30 +00:00
|
|
|
|
|
|
|
func assertStatus(t *testing.T, w *httptest.ResponseRecorder, status int) {
|
|
|
|
if w.Code != status {
|
|
|
|
resp, err := io.ReadAll(w.Result().Body)
|
|
|
|
require.NoError(t, err)
|
|
|
|
require.Failf(t, string(resp), "assert status fail, expected: %d, actual: %d", status, w.Code)
|
|
|
|
}
|
|
|
|
}
|