package shard import ( "os" "path" "testing" "github.com/nspcc-dev/neofs-node/pkg/core/object" "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/blobstor" meta "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/metabase" objectSDK "github.com/nspcc-dev/neofs-sdk-go/object" objecttest "github.com/nspcc-dev/neofs-sdk-go/object/test" "github.com/stretchr/testify/require" ) func TestRefillMetabase(t *testing.T) { p := t.Name() defer os.RemoveAll(p) blobOpts := []blobstor.Option{ blobstor.WithRootPath(path.Join(p, "blob")), blobstor.WithBlobovniczaShallowWidth(1), blobstor.WithBlobovniczaShallowDepth(1), } sh := New( WithBlobStorOptions(blobOpts...), WithMetaBaseOptions( meta.WithPath(path.Join(p, "meta")), ), ) // open Blobstor require.NoError(t, sh.Open()) // initialize Blobstor require.NoError(t, sh.Init()) const objNum = 5 type objAddr struct { obj *object.Object addr *objectSDK.Address } mObjs := make(map[string]objAddr) for i := uint64(0); i < objNum; i++ { rawObj := objecttest.Raw() rawObj.SetType(objectSDK.TypeRegular) obj := object.NewFromSDK(rawObj.Object()) addr := obj.Address() mObjs[addr.String()] = objAddr{ obj: obj, addr: addr, } } tombObjRaw := object.NewRawFrom(objecttest.Raw()) tombObjRaw.SetType(objectSDK.TypeTombstone) tombstone := objecttest.Tombstone() tombData, err := tombstone.Marshal() require.NoError(t, err) tombObjRaw.SetPayload(tombData) tombObj := tombObjRaw.Object() tombMembers := make([]*objectSDK.Address, 0, len(tombstone.Members())) for _, member := range tombstone.Members() { a := objectSDK.NewAddress() a.SetObjectID(member) a.SetContainerID(tombObj.ContainerID()) tombMembers = append(tombMembers, a) } var putPrm PutPrm for _, v := range mObjs { _, err := sh.Put(putPrm.WithObject(v.obj)) require.NoError(t, err) } _, err = sh.Put(putPrm.WithObject(tombObj)) require.NoError(t, err) _, err = sh.Inhume(new(InhumePrm).WithTarget(tombObj.Address(), tombMembers...)) require.NoError(t, err) var headPrm HeadPrm checkObj := func(addr *objectSDK.Address, expObj *object.Object) { res, err := sh.Head(headPrm.WithAddress(addr)) if expObj == nil { require.ErrorIs(t, err, object.ErrNotFound) return } require.NoError(t, err) require.Equal(t, object.NewRawFromObject(expObj).CutPayload().Object(), res.Object()) } checkAllObjs := func(exists bool) { for _, v := range mObjs { if exists { checkObj(v.addr, v.obj) } else { checkObj(v.addr, nil) } } } checkTombMembers := func(exists bool) { for _, member := range tombMembers { _, err := sh.Head(headPrm.WithAddress(member)) if exists { require.ErrorIs(t, err, object.ErrAlreadyRemoved) } else { require.ErrorIs(t, err, object.ErrNotFound) } } } checkAllObjs(true) checkObj(tombObj.Address(), tombObj) checkTombMembers(true) err = sh.Close() require.NoError(t, err) sh = New( WithBlobStorOptions(blobOpts...), WithMetaBaseOptions( meta.WithPath(path.Join(p, "meta_restored")), ), ) // open Blobstor require.NoError(t, sh.Open()) // initialize Blobstor require.NoError(t, sh.Init()) defer sh.Close() checkAllObjs(false) checkObj(tombObj.Address(), nil) checkTombMembers(false) err = sh.refillMetabase() require.NoError(t, err) checkAllObjs(true) checkObj(tombObj.Address(), tombObj) checkTombMembers(true) }