[#XX] Add fallback tests
Signed-off-by: Denis Kirillov <d.kirillov@yadro.com>
This commit is contained in:
parent
626a18f540
commit
99eaae2042
2 changed files with 193 additions and 97 deletions
|
@ -26,6 +26,7 @@ import (
|
|||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/netmap"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object"
|
||||
oid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id"
|
||||
oidtest "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id/test"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/user"
|
||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||
"github.com/panjf2000/ants/v2"
|
||||
|
@ -64,6 +65,7 @@ func (t *treeServiceMock) GetLatestVersion(context.Context, *cid.ID, string) (*d
|
|||
type configMock struct {
|
||||
additionalFilenameSearch bool
|
||||
additionalSlashSearch bool
|
||||
indexEnabled bool
|
||||
cors *data.CORSRule
|
||||
}
|
||||
|
||||
|
@ -76,7 +78,7 @@ func (c *configMock) ArchiveCompression() bool {
|
|||
}
|
||||
|
||||
func (c *configMock) IndexPageEnabled() bool {
|
||||
return false
|
||||
return c.indexEnabled
|
||||
}
|
||||
|
||||
func (c *configMock) IndexPageTemplate() string {
|
||||
|
@ -259,6 +261,7 @@ func TestBasic(t *testing.T) {
|
|||
err = json.Unmarshal(r.Response.Body(), &putRes)
|
||||
require.NoError(t, err)
|
||||
|
||||
hc.cfg.additionalFilenameSearch = true
|
||||
obj := hc.frostfs.objects[putRes.ContainerID+"/"+putRes.ObjectID]
|
||||
fileName := prepareObjectAttributes(object.AttributeFileName, objFileName)
|
||||
filePath := prepareObjectAttributes(object.AttributeFilePath, objFilePath)
|
||||
|
@ -269,6 +272,14 @@ func TestBasic(t *testing.T) {
|
|||
r = prepareGetRequest(ctx, cnrID.EncodeToString(), putRes.ObjectID)
|
||||
hc.Handler().DownloadByAddressOrBucketName(r)
|
||||
require.Equal(t, content, string(r.Response.Body()))
|
||||
|
||||
r = prepareGetRequest(ctx, cnrID.EncodeToString(), objFilePath)
|
||||
hc.Handler().DownloadByAddressOrBucketName(r)
|
||||
require.Equal(t, content, string(r.Response.Body()))
|
||||
|
||||
r = prepareGetRequest(ctx, cnrID.EncodeToString(), objFileName)
|
||||
hc.Handler().DownloadByAddressOrBucketName(r)
|
||||
require.Equal(t, content, string(r.Response.Body()))
|
||||
})
|
||||
|
||||
t.Run("head", func(t *testing.T) {
|
||||
|
@ -276,6 +287,16 @@ func TestBasic(t *testing.T) {
|
|||
hc.Handler().HeadByAddressOrBucketName(r)
|
||||
require.Equal(t, putRes.ObjectID, string(r.Response.Header.Peek(hdrObjectID)))
|
||||
require.Equal(t, putRes.ContainerID, string(r.Response.Header.Peek(hdrContainerID)))
|
||||
|
||||
r = prepareGetRequest(ctx, cnrID.EncodeToString(), objFilePath)
|
||||
hc.Handler().HeadByAddressOrBucketName(r)
|
||||
require.Equal(t, putRes.ObjectID, string(r.Response.Header.Peek(hdrObjectID)))
|
||||
require.Equal(t, putRes.ContainerID, string(r.Response.Header.Peek(hdrContainerID)))
|
||||
|
||||
r = prepareGetRequest(ctx, cnrID.EncodeToString(), objFileName)
|
||||
hc.Handler().HeadByAddressOrBucketName(r)
|
||||
require.Equal(t, putRes.ObjectID, string(r.Response.Header.Peek(hdrObjectID)))
|
||||
require.Equal(t, putRes.ContainerID, string(r.Response.Header.Peek(hdrContainerID)))
|
||||
})
|
||||
|
||||
t.Run("get by attribute", func(t *testing.T) {
|
||||
|
@ -285,11 +306,11 @@ func TestBasic(t *testing.T) {
|
|||
|
||||
r = prepareGetByAttributeRequest(ctx, bktName, attrFileName, objFilePath)
|
||||
hc.Handler().DownloadByAttribute(r)
|
||||
require.Equal(t, content, string(r.Response.Body()))
|
||||
require.Equal(t, fasthttp.StatusNotFound, r.Response.StatusCode())
|
||||
|
||||
r = prepareGetByAttributeRequest(ctx, bktName, attrFilePath, objFileName)
|
||||
hc.Handler().DownloadByAttribute(r)
|
||||
require.Equal(t, content, string(r.Response.Body()))
|
||||
require.Equal(t, fasthttp.StatusNotFound, r.Response.StatusCode())
|
||||
})
|
||||
|
||||
t.Run("head by attribute", func(t *testing.T) {
|
||||
|
@ -300,13 +321,11 @@ func TestBasic(t *testing.T) {
|
|||
|
||||
r = prepareGetByAttributeRequest(ctx, bktName, attrFileName, objFilePath)
|
||||
hc.Handler().HeadByAttribute(r)
|
||||
require.Equal(t, putRes.ObjectID, string(r.Response.Header.Peek(hdrObjectID)))
|
||||
require.Equal(t, putRes.ContainerID, string(r.Response.Header.Peek(hdrContainerID)))
|
||||
require.Equal(t, fasthttp.StatusNotFound, r.Response.StatusCode())
|
||||
|
||||
r = prepareGetByAttributeRequest(ctx, bktName, attrFilePath, objFileName)
|
||||
hc.Handler().HeadByAttribute(r)
|
||||
require.Equal(t, putRes.ObjectID, string(r.Response.Header.Peek(hdrObjectID)))
|
||||
require.Equal(t, putRes.ContainerID, string(r.Response.Header.Peek(hdrContainerID)))
|
||||
require.Equal(t, fasthttp.StatusNotFound, r.Response.StatusCode())
|
||||
})
|
||||
|
||||
t.Run("zip", func(t *testing.T) {
|
||||
|
@ -330,101 +349,187 @@ func TestBasic(t *testing.T) {
|
|||
})
|
||||
}
|
||||
|
||||
func TestFindObjectByAttribute(t *testing.T) {
|
||||
func prepareHandlerAndBucket(t *testing.T) (*handlerContext, cid.ID) {
|
||||
hc := prepareHandlerContext(t)
|
||||
hc.cfg.additionalFilenameSearch = true
|
||||
|
||||
bktName := "bucket"
|
||||
cnrID, cnr, err := hc.prepareContainer(bktName, acl.PublicRWExtended)
|
||||
require.NoError(t, err)
|
||||
hc.frostfs.SetContainer(cnrID, cnr)
|
||||
|
||||
ctx := context.Background()
|
||||
ctx = middleware.SetNamespace(ctx, "")
|
||||
return hc, cnrID
|
||||
}
|
||||
|
||||
content := "hello"
|
||||
r, err := prepareUploadRequest(ctx, cnrID.EncodeToString(), content)
|
||||
require.NoError(t, err)
|
||||
func TestGetObjectWithFallback(t *testing.T) {
|
||||
ctx := middleware.SetNamespace(context.Background(), "")
|
||||
|
||||
hc.Handler().Upload(r)
|
||||
require.Equal(t, r.Response.StatusCode(), http.StatusOK)
|
||||
t.Run("by oid", func(t *testing.T) {
|
||||
hc, cnrID := prepareHandlerAndBucket(t)
|
||||
|
||||
var putRes putResponse
|
||||
err = json.Unmarshal(r.Response.Body(), &putRes)
|
||||
require.NoError(t, err)
|
||||
obj1ID := oidtest.ID()
|
||||
obj1 := object.New()
|
||||
obj1.SetID(obj1ID)
|
||||
obj1.SetPayload([]byte("obj1"))
|
||||
hc.frostfs.objects[cnrID.String()+"/"+obj1ID.String()] = obj1
|
||||
|
||||
testAttrVal1 := "/folder/cat.jpg"
|
||||
testAttrVal2 := "cat.jpg"
|
||||
testAttrVal3 := "test-attr-val3"
|
||||
r := prepareGetRequest(ctx, cnrID.EncodeToString(), obj1ID.String())
|
||||
hc.Handler().DownloadByAddressOrBucketName(r)
|
||||
require.Equal(t, string(obj1.Payload()), string(r.Response.Body()))
|
||||
})
|
||||
|
||||
for _, tc := range []struct {
|
||||
name string
|
||||
firstAttr object.Attribute
|
||||
secondAttr object.Attribute
|
||||
reqAttrKey string
|
||||
reqAttrValue string
|
||||
err string
|
||||
additionalSearch bool
|
||||
}{
|
||||
{
|
||||
name: "success search by FileName",
|
||||
firstAttr: prepareObjectAttributes(attrFilePath, testAttrVal1),
|
||||
secondAttr: prepareObjectAttributes(attrFileName, testAttrVal2),
|
||||
reqAttrKey: attrFileName,
|
||||
reqAttrValue: testAttrVal2,
|
||||
additionalSearch: false,
|
||||
},
|
||||
{
|
||||
name: "failed search by FileName",
|
||||
firstAttr: prepareObjectAttributes(attrFilePath, testAttrVal1),
|
||||
secondAttr: prepareObjectAttributes(attrFileName, testAttrVal2),
|
||||
reqAttrKey: attrFileName,
|
||||
reqAttrValue: testAttrVal3,
|
||||
err: "not found",
|
||||
additionalSearch: false,
|
||||
},
|
||||
{
|
||||
name: "success search by FilePath (with additional search)",
|
||||
firstAttr: prepareObjectAttributes(attrFilePath, testAttrVal1),
|
||||
secondAttr: prepareObjectAttributes(attrFileName, testAttrVal2),
|
||||
reqAttrKey: attrFilePath,
|
||||
reqAttrValue: testAttrVal2,
|
||||
additionalSearch: true,
|
||||
},
|
||||
{
|
||||
name: "failed by FilePath (with additional search)",
|
||||
firstAttr: prepareObjectAttributes(attrFilePath, testAttrVal1),
|
||||
secondAttr: prepareObjectAttributes(attrFileName, testAttrVal2),
|
||||
reqAttrKey: attrFilePath,
|
||||
reqAttrValue: testAttrVal3,
|
||||
err: "not found",
|
||||
additionalSearch: true,
|
||||
},
|
||||
{
|
||||
name: "success search by FilePath with leading slash (with additional search)",
|
||||
firstAttr: prepareObjectAttributes(attrFilePath, testAttrVal1),
|
||||
secondAttr: prepareObjectAttributes(attrFileName, testAttrVal2),
|
||||
reqAttrKey: attrFilePath,
|
||||
reqAttrValue: "/cat.jpg",
|
||||
additionalSearch: true,
|
||||
},
|
||||
} {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
obj := hc.frostfs.objects[putRes.ContainerID+"/"+putRes.ObjectID]
|
||||
obj.SetAttributes(tc.firstAttr, tc.secondAttr)
|
||||
hc.cfg.additionalFilenameSearch = tc.additionalSearch
|
||||
t.Run("by filepath as it is", func(t *testing.T) {
|
||||
hc, cnrID := prepareHandlerAndBucket(t)
|
||||
|
||||
objID, err := hc.Handler().findObjectByAttribute(ctx, cnrID, tc.reqAttrKey, tc.reqAttrValue)
|
||||
if tc.err != "" {
|
||||
require.Error(t, err)
|
||||
require.Contains(t, err.Error(), tc.err)
|
||||
return
|
||||
}
|
||||
obj1ID := oidtest.ID()
|
||||
obj1 := object.New()
|
||||
obj1.SetID(obj1ID)
|
||||
obj1.SetPayload([]byte("obj1"))
|
||||
obj1.SetAttributes(prepareObjectAttributes(object.AttributeFilePath, "filepath/obj1"))
|
||||
hc.frostfs.objects[cnrID.String()+"/"+obj1ID.String()] = obj1
|
||||
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, putRes.ObjectID, objID.EncodeToString())
|
||||
})
|
||||
}
|
||||
obj2ID := oidtest.ID()
|
||||
obj2 := object.New()
|
||||
obj2.SetID(obj2ID)
|
||||
obj2.SetPayload([]byte("obj2"))
|
||||
obj2.SetAttributes(prepareObjectAttributes(object.AttributeFilePath, "/filepath/obj2"))
|
||||
hc.frostfs.objects[cnrID.String()+"/"+obj2ID.String()] = obj2
|
||||
|
||||
r := prepareGetRequest(ctx, cnrID.EncodeToString(), "filepath/obj1")
|
||||
hc.Handler().DownloadByAddressOrBucketName(r)
|
||||
require.Equal(t, string(obj1.Payload()), string(r.Response.Body()))
|
||||
|
||||
r = prepareGetRequest(ctx, cnrID.EncodeToString(), "/filepath/obj2")
|
||||
hc.Handler().DownloadByAddressOrBucketName(r)
|
||||
require.Equal(t, string(obj2.Payload()), string(r.Response.Body()))
|
||||
})
|
||||
|
||||
t.Run("by filepath slash fallback", func(t *testing.T) {
|
||||
hc, cnrID := prepareHandlerAndBucket(t)
|
||||
|
||||
obj1ID := oidtest.ID()
|
||||
obj1 := object.New()
|
||||
obj1.SetID(obj1ID)
|
||||
obj1.SetPayload([]byte("obj1"))
|
||||
obj1.SetAttributes(prepareObjectAttributes(object.AttributeFilePath, "filepath/obj1"))
|
||||
hc.frostfs.objects[cnrID.String()+"/"+obj1ID.String()] = obj1
|
||||
|
||||
r := prepareGetRequest(ctx, cnrID.EncodeToString(), "/filepath/obj1")
|
||||
hc.Handler().DownloadByAddressOrBucketName(r)
|
||||
require.Equal(t, fasthttp.StatusNotFound, r.Response.StatusCode())
|
||||
|
||||
hc.cfg.additionalSlashSearch = true
|
||||
|
||||
r = prepareGetRequest(ctx, cnrID.EncodeToString(), "/filepath/obj1")
|
||||
hc.Handler().DownloadByAddressOrBucketName(r)
|
||||
require.Equal(t, string(obj1.Payload()), string(r.Response.Body()))
|
||||
})
|
||||
|
||||
t.Run("by filename fallback", func(t *testing.T) {
|
||||
hc, cnrID := prepareHandlerAndBucket(t)
|
||||
|
||||
obj1ID := oidtest.ID()
|
||||
obj1 := object.New()
|
||||
obj1.SetID(obj1ID)
|
||||
obj1.SetPayload([]byte("obj1"))
|
||||
obj1.SetAttributes(prepareObjectAttributes(object.AttributeFileName, "filename/obj1"))
|
||||
hc.frostfs.objects[cnrID.String()+"/"+obj1ID.String()] = obj1
|
||||
|
||||
r := prepareGetRequest(ctx, cnrID.EncodeToString(), "filename/obj1")
|
||||
hc.Handler().DownloadByAddressOrBucketName(r)
|
||||
require.Equal(t, fasthttp.StatusNotFound, r.Response.StatusCode())
|
||||
|
||||
hc.cfg.additionalFilenameSearch = true
|
||||
|
||||
r = prepareGetRequest(ctx, cnrID.EncodeToString(), "filename/obj1")
|
||||
hc.Handler().DownloadByAddressOrBucketName(r)
|
||||
require.Equal(t, string(obj1.Payload()), string(r.Response.Body()))
|
||||
})
|
||||
|
||||
t.Run("by filename and slash fallback", func(t *testing.T) {
|
||||
hc, cnrID := prepareHandlerAndBucket(t)
|
||||
|
||||
obj1ID := oidtest.ID()
|
||||
obj1 := object.New()
|
||||
obj1.SetID(obj1ID)
|
||||
obj1.SetPayload([]byte("obj1"))
|
||||
obj1.SetAttributes(prepareObjectAttributes(object.AttributeFileName, "filename/obj1"))
|
||||
hc.frostfs.objects[cnrID.String()+"/"+obj1ID.String()] = obj1
|
||||
|
||||
r := prepareGetRequest(ctx, cnrID.EncodeToString(), "/filename/obj1")
|
||||
hc.Handler().DownloadByAddressOrBucketName(r)
|
||||
require.Equal(t, fasthttp.StatusNotFound, r.Response.StatusCode())
|
||||
|
||||
hc.cfg.additionalFilenameSearch = true
|
||||
|
||||
r = prepareGetRequest(ctx, cnrID.EncodeToString(), "/filename/obj1")
|
||||
hc.Handler().DownloadByAddressOrBucketName(r)
|
||||
require.Equal(t, fasthttp.StatusNotFound, r.Response.StatusCode())
|
||||
|
||||
hc.cfg.additionalSlashSearch = true
|
||||
|
||||
r = prepareGetRequest(ctx, cnrID.EncodeToString(), "/filename/obj1")
|
||||
hc.Handler().DownloadByAddressOrBucketName(r)
|
||||
require.Equal(t, string(obj1.Payload()), string(r.Response.Body()))
|
||||
})
|
||||
|
||||
t.Run("index fallback", func(t *testing.T) {
|
||||
hc, cnrID := prepareHandlerAndBucket(t)
|
||||
|
||||
obj1ID := oidtest.ID()
|
||||
obj1 := object.New()
|
||||
obj1.SetID(obj1ID)
|
||||
obj1.SetPayload([]byte("obj1"))
|
||||
obj1.SetAttributes(prepareObjectAttributes(object.AttributeFilePath, "filepath/index.html"))
|
||||
hc.frostfs.objects[cnrID.String()+"/"+obj1ID.String()] = obj1
|
||||
|
||||
r := prepareGetRequest(ctx, cnrID.EncodeToString(), "filepath/")
|
||||
hc.Handler().DownloadByAddressOrBucketName(r)
|
||||
require.Equal(t, fasthttp.StatusNotFound, r.Response.StatusCode())
|
||||
|
||||
r = prepareGetRequest(ctx, cnrID.EncodeToString(), "filepath")
|
||||
hc.Handler().DownloadByAddressOrBucketName(r)
|
||||
require.Equal(t, fasthttp.StatusNotFound, r.Response.StatusCode())
|
||||
|
||||
hc.cfg.indexEnabled = true
|
||||
|
||||
r = prepareGetRequest(ctx, cnrID.EncodeToString(), "filepath")
|
||||
hc.Handler().DownloadByAddressOrBucketName(r)
|
||||
require.Equal(t, string(obj1.Payload()), string(r.Response.Body()))
|
||||
|
||||
r = prepareGetRequest(ctx, cnrID.EncodeToString(), "filepath/")
|
||||
hc.Handler().DownloadByAddressOrBucketName(r)
|
||||
require.Equal(t, string(obj1.Payload()), string(r.Response.Body()))
|
||||
})
|
||||
|
||||
t.Run("index filename fallback", func(t *testing.T) {
|
||||
hc, cnrID := prepareHandlerAndBucket(t)
|
||||
|
||||
obj1ID := oidtest.ID()
|
||||
obj1 := object.New()
|
||||
obj1.SetID(obj1ID)
|
||||
obj1.SetPayload([]byte("obj1"))
|
||||
obj1.SetAttributes(prepareObjectAttributes(object.AttributeFileName, "filename/index.html"))
|
||||
hc.frostfs.objects[cnrID.String()+"/"+obj1ID.String()] = obj1
|
||||
|
||||
r := prepareGetRequest(ctx, cnrID.EncodeToString(), "filename/")
|
||||
hc.Handler().DownloadByAddressOrBucketName(r)
|
||||
require.Equal(t, fasthttp.StatusNotFound, r.Response.StatusCode())
|
||||
|
||||
r = prepareGetRequest(ctx, cnrID.EncodeToString(), "filename")
|
||||
hc.Handler().DownloadByAddressOrBucketName(r)
|
||||
require.Equal(t, fasthttp.StatusNotFound, r.Response.StatusCode())
|
||||
|
||||
hc.cfg.indexEnabled = true
|
||||
hc.cfg.additionalFilenameSearch = true
|
||||
|
||||
r = prepareGetRequest(ctx, cnrID.EncodeToString(), "filename")
|
||||
hc.Handler().DownloadByAddressOrBucketName(r)
|
||||
require.Equal(t, string(obj1.Payload()), string(r.Response.Body()))
|
||||
|
||||
r = prepareGetRequest(ctx, cnrID.EncodeToString(), "filename/")
|
||||
hc.Handler().DownloadByAddressOrBucketName(r)
|
||||
require.Equal(t, string(obj1.Payload()), string(r.Response.Body()))
|
||||
})
|
||||
}
|
||||
|
||||
func prepareUploadRequest(ctx context.Context, bucket, content string) (*fasthttp.RequestCtx, error) {
|
||||
|
|
|
@ -175,15 +175,6 @@ func (h *Handler) HeadByAddressOrBucketName(req *fasthttp.RequestCtx) {
|
|||
Middleware{Func: h.byAttributeSearchMiddleware(h.headObject, object.AttributeFileName, indexFormer), Enabled: fileNameFallbackEnabled && indexPageEnabled},
|
||||
)
|
||||
}
|
||||
|
||||
var objID oid.ID
|
||||
if checkS3Err == nil {
|
||||
h.byS3Path(ctx, req, bktInfo, oidParam, h.headObject)
|
||||
} else if err = objID.DecodeString(oidParam); err == nil {
|
||||
h.byNativeAddress(ctx, req, bktInfo.CID, objID, h.headObject)
|
||||
} else {
|
||||
h.logAndSendError(ctx, req, logs.InvalidOIDParam, err)
|
||||
}
|
||||
}
|
||||
|
||||
// HeadByAttribute handles attribute-based head requests.
|
||||
|
|
Loading…
Add table
Reference in a new issue