2021-09-13 13:38:58 +00:00
|
|
|
package shard
|
|
|
|
|
|
|
|
import (
|
|
|
|
"os"
|
2022-02-02 13:28:08 +00:00
|
|
|
"path/filepath"
|
2021-09-13 13:38:58 +00:00
|
|
|
"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"
|
2021-11-10 07:08:33 +00:00
|
|
|
objectSDK "github.com/nspcc-dev/neofs-sdk-go/object"
|
|
|
|
objecttest "github.com/nspcc-dev/neofs-sdk-go/object/test"
|
2021-09-13 13:38:58 +00:00
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
)
|
|
|
|
|
|
|
|
func TestRefillMetabase(t *testing.T) {
|
|
|
|
p := t.Name()
|
|
|
|
|
|
|
|
defer os.RemoveAll(p)
|
|
|
|
|
|
|
|
blobOpts := []blobstor.Option{
|
2022-02-02 13:28:08 +00:00
|
|
|
blobstor.WithRootPath(filepath.Join(p, "blob")),
|
2021-09-13 13:38:58 +00:00
|
|
|
blobstor.WithBlobovniczaShallowWidth(1),
|
|
|
|
blobstor.WithBlobovniczaShallowDepth(1),
|
|
|
|
}
|
|
|
|
|
|
|
|
sh := New(
|
|
|
|
WithBlobStorOptions(blobOpts...),
|
|
|
|
WithMetaBaseOptions(
|
2022-02-02 13:28:08 +00:00
|
|
|
meta.WithPath(filepath.Join(p, "meta")),
|
2021-09-13 13:38:58 +00:00
|
|
|
),
|
|
|
|
)
|
|
|
|
|
|
|
|
// 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(
|
2022-02-02 13:28:08 +00:00
|
|
|
meta.WithPath(filepath.Join(p, "meta_restored")),
|
2021-09-13 13:38:58 +00:00
|
|
|
),
|
|
|
|
)
|
|
|
|
|
|
|
|
// 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)
|
|
|
|
}
|