diff --git a/pkg/local_object_storage/shard/head.go b/pkg/local_object_storage/shard/head.go index 3e504b749..12a90322f 100644 --- a/pkg/local_object_storage/shard/head.go +++ b/pkg/local_object_storage/shard/head.go @@ -9,6 +9,7 @@ import ( // HeadPrm groups the parameters of Head operation. type HeadPrm struct { addr *objectSDK.Address + raw bool } // HeadRes groups resulting values of Head operation. @@ -27,6 +28,17 @@ func (p *HeadPrm) WithAddress(addr *objectSDK.Address) *HeadPrm { return p } +// WithRaw is a Head option to set raw flag value. If flag is unset, then Head +// returns header of virtual object, otherwise it returns SplitInfo of virtual +// object. +func (p *HeadPrm) WithRaw(raw bool) *HeadPrm { + if p != nil { + p.raw = raw + } + + return p +} + // Object returns the requested object header. func (r *HeadRes) Object() *object.Object { return r.obj @@ -36,9 +48,13 @@ func (r *HeadRes) Object() *object.Object { // // Returns any error encountered. func (s *Shard) Head(prm *HeadPrm) (*HeadRes, error) { - head, err := meta.Get(s.metaBase, prm.addr) + headParams := new(meta.GetPrm). + WithAddress(prm.addr). + WithRaw(prm.raw) + + head, err := s.metaBase.Get(headParams) return &HeadRes{ - obj: head, + obj: head.Header(), }, err } diff --git a/pkg/local_object_storage/shard/head_test.go b/pkg/local_object_storage/shard/head_test.go index 7ec0108f0..9af4f60aa 100644 --- a/pkg/local_object_storage/shard/head_test.go +++ b/pkg/local_object_storage/shard/head_test.go @@ -1,8 +1,10 @@ package shard_test import ( + "errors" "testing" + objectSDK "github.com/nspcc-dev/neofs-api-go/pkg/object" "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/shard" "github.com/stretchr/testify/require" ) @@ -26,19 +28,55 @@ func TestShard_Head(t *testing.T) { } func testShardHead(t *testing.T, sh *shard.Shard) { - obj := generateRawObject(t) - addAttribute(obj, "foo", "bar") - putPrm := new(shard.PutPrm) - putPrm.WithObject(obj.Object()) - - _, err := sh.Put(putPrm) - require.NoError(t, err) - headPrm := new(shard.HeadPrm) - headPrm.WithAddress(obj.Object().Address()) - res, err := sh.Head(headPrm) - require.NoError(t, err) - require.Equal(t, obj.Object(), res.Object()) + t.Run("regular object", func(t *testing.T) { + obj := generateRawObject(t) + addAttribute(obj, "foo", "bar") + + putPrm.WithObject(obj.Object()) + + _, err := sh.Put(putPrm) + require.NoError(t, err) + + headPrm.WithAddress(obj.Object().Address()) + + res, err := sh.Head(headPrm) + require.NoError(t, err) + require.Equal(t, obj.Object(), res.Object()) + }) + + t.Run("virtual object", func(t *testing.T) { + cid := generateCID() + splitID := objectSDK.NewSplitID() + + parent := generateRawObjectWithCID(t, cid) + addAttribute(parent, "foo", "bar") + + child := generateRawObjectWithCID(t, cid) + child.SetParent(parent.Object().SDK()) + child.SetParentID(parent.ID()) + child.SetSplitID(splitID) + + putPrm.WithObject(child.Object()) + + _, err := sh.Put(putPrm) + require.NoError(t, err) + + headPrm.WithAddress(parent.Object().Address()) + headPrm.WithRaw(true) + + var siErr *objectSDK.SplitInfoError + + _, err = sh.Head(headPrm) + require.True(t, errors.As(err, &siErr)) + + headPrm.WithAddress(parent.Object().Address()) + headPrm.WithRaw(false) + + head, err := sh.Head(headPrm) + require.NoError(t, err) + require.Equal(t, parent.Object(), head.Object()) + }) }