2023-07-19 14:18:55 +00:00
|
|
|
package api
|
|
|
|
|
|
|
|
import (
|
|
|
|
"encoding/json"
|
|
|
|
"fmt"
|
|
|
|
"io"
|
|
|
|
"net/http"
|
|
|
|
"net/http/httptest"
|
|
|
|
"net/url"
|
|
|
|
"testing"
|
|
|
|
"time"
|
|
|
|
|
|
|
|
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/metrics"
|
|
|
|
"github.com/go-chi/chi/v5"
|
|
|
|
"github.com/go-chi/chi/v5/middleware"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
"go.uber.org/zap/zaptest"
|
|
|
|
)
|
|
|
|
|
|
|
|
func TestRouterUploadPart(t *testing.T) {
|
|
|
|
chiRouter := prepareRouter(t)
|
|
|
|
|
|
|
|
w := httptest.NewRecorder()
|
|
|
|
r := httptest.NewRequest(http.MethodPut, "/dkirillov/fix-object", nil)
|
|
|
|
query := make(url.Values)
|
|
|
|
query.Set("uploadId", "some-id")
|
|
|
|
query.Set("partNumber", "1")
|
|
|
|
r.URL.RawQuery = query.Encode()
|
|
|
|
|
|
|
|
chiRouter.ServeHTTP(w, r)
|
|
|
|
resp := readResponse(t, w)
|
|
|
|
require.Equal(t, "UploadPart", resp.Method)
|
|
|
|
}
|
|
|
|
|
2023-07-20 09:08:45 +00:00
|
|
|
func TestRouterListMultipartUploads(t *testing.T) {
|
|
|
|
chiRouter := prepareRouter(t)
|
|
|
|
|
|
|
|
w := httptest.NewRecorder()
|
|
|
|
r := httptest.NewRequest(http.MethodGet, "/test-bucket", nil)
|
|
|
|
query := make(url.Values)
|
|
|
|
query.Set("uploads", "")
|
|
|
|
r.URL.RawQuery = query.Encode()
|
|
|
|
|
|
|
|
chiRouter.ServeHTTP(w, r)
|
|
|
|
resp := readResponse(t, w)
|
|
|
|
require.Equal(t, "ListMultipartUploads", resp.Method)
|
|
|
|
}
|
|
|
|
|
2023-07-19 14:18:55 +00:00
|
|
|
func TestRouterObjectWithSlashes(t *testing.T) {
|
|
|
|
chiRouter := prepareRouter(t)
|
|
|
|
|
|
|
|
bktName, objName := "dkirillov", "/fix/object"
|
|
|
|
target := fmt.Sprintf("/%s/%s", bktName, objName)
|
|
|
|
|
|
|
|
w := httptest.NewRecorder()
|
|
|
|
r := httptest.NewRequest(http.MethodPut, target, nil)
|
|
|
|
|
|
|
|
chiRouter.ServeHTTP(w, r)
|
|
|
|
resp := readResponse(t, w)
|
|
|
|
require.Equal(t, "PutObject", resp.Method)
|
|
|
|
require.Equal(t, objName, resp.ReqInfo.ObjectName)
|
|
|
|
}
|
|
|
|
|
2023-08-17 08:54:11 +00:00
|
|
|
func TestRouterObjectEscaping(t *testing.T) {
|
|
|
|
chiRouter := prepareRouter(t)
|
|
|
|
|
|
|
|
bktName := "dkirillov"
|
|
|
|
|
|
|
|
for _, tc := range []struct {
|
|
|
|
name string
|
|
|
|
expectedObjName string
|
|
|
|
objName string
|
|
|
|
}{
|
|
|
|
{
|
|
|
|
name: "simple",
|
|
|
|
expectedObjName: "object",
|
|
|
|
objName: "object",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "with slashes",
|
|
|
|
expectedObjName: "fix/object",
|
|
|
|
objName: "fix/object",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "with percentage",
|
|
|
|
expectedObjName: "fix/object%ac",
|
|
|
|
objName: "fix/object%ac",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "with percentage escaped",
|
|
|
|
expectedObjName: "fix/object%ac",
|
|
|
|
objName: "fix/object%25ac",
|
|
|
|
},
|
|
|
|
} {
|
|
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
|
|
target := fmt.Sprintf("/%s/%s", bktName, tc.objName)
|
|
|
|
|
|
|
|
w := httptest.NewRecorder()
|
|
|
|
r := httptest.NewRequest(http.MethodPut, target, nil)
|
|
|
|
|
|
|
|
chiRouter.ServeHTTP(w, r)
|
|
|
|
resp := readResponse(t, w)
|
|
|
|
require.Equal(t, "PutObject", resp.Method)
|
|
|
|
require.Equal(t, tc.expectedObjName, resp.ReqInfo.ObjectName)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-07-19 14:18:55 +00:00
|
|
|
func prepareRouter(t *testing.T) *chi.Mux {
|
|
|
|
throttleOps := middleware.ThrottleOpts{
|
|
|
|
Limit: 10,
|
|
|
|
BacklogTimeout: 30 * time.Second,
|
|
|
|
}
|
|
|
|
|
|
|
|
handleMock := &handlerMock{t: t}
|
|
|
|
cntrMock := ¢erMock{}
|
|
|
|
log := zaptest.NewLogger(t)
|
|
|
|
metric := &metrics.AppMetrics{}
|
|
|
|
|
|
|
|
chiRouter := chi.NewRouter()
|
|
|
|
AttachChi(chiRouter, nil, throttleOps, handleMock, cntrMock, log, metric)
|
|
|
|
return chiRouter
|
|
|
|
}
|
|
|
|
|
|
|
|
func readResponse(t *testing.T, w *httptest.ResponseRecorder) handlerResult {
|
|
|
|
var res handlerResult
|
|
|
|
|
|
|
|
resData, err := io.ReadAll(w.Result().Body)
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
err = json.Unmarshal(resData, &res)
|
|
|
|
require.NoErrorf(t, err, "actual body: '%s'", string(resData))
|
|
|
|
return res
|
|
|
|
}
|