forked from TrueCloudLab/frostfs-node
[#1869] shard: Allow to reload metabase on SIGHUP
Signed-off-by: Evgenii Stratonikov <evgeniy@morphbits.ru>
This commit is contained in:
parent
f769fc83fc
commit
c785e11b20
7 changed files with 252 additions and 13 deletions
143
pkg/local_object_storage/shard/reload_test.go
Normal file
143
pkg/local_object_storage/shard/reload_test.go
Normal file
|
@ -0,0 +1,143 @@
|
|||
package shard
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
objectCore "github.com/nspcc-dev/neofs-node/pkg/core/object"
|
||||
"github.com/nspcc-dev/neofs-node/pkg/local_object_storage/blobstor"
|
||||
"github.com/nspcc-dev/neofs-node/pkg/local_object_storage/blobstor/fstree"
|
||||
meta "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/metabase"
|
||||
"github.com/nspcc-dev/neofs-node/pkg/local_object_storage/pilorama"
|
||||
"github.com/nspcc-dev/neofs-node/pkg/util/logger"
|
||||
checksumtest "github.com/nspcc-dev/neofs-sdk-go/checksum/test"
|
||||
cidtest "github.com/nspcc-dev/neofs-sdk-go/container/id/test"
|
||||
objectSDK "github.com/nspcc-dev/neofs-sdk-go/object"
|
||||
oidtest "github.com/nspcc-dev/neofs-sdk-go/object/id/test"
|
||||
sessiontest "github.com/nspcc-dev/neofs-sdk-go/session/test"
|
||||
usertest "github.com/nspcc-dev/neofs-sdk-go/user/test"
|
||||
"github.com/nspcc-dev/neofs-sdk-go/version"
|
||||
"github.com/stretchr/testify/require"
|
||||
"go.uber.org/zap/zaptest"
|
||||
)
|
||||
|
||||
func TestShardReload(t *testing.T) {
|
||||
p := t.Name()
|
||||
defer os.RemoveAll(p)
|
||||
|
||||
l := &logger.Logger{Logger: zaptest.NewLogger(t)}
|
||||
blobOpts := []blobstor.Option{
|
||||
blobstor.WithLogger(l),
|
||||
blobstor.WithStorages([]blobstor.SubStorage{
|
||||
{
|
||||
Storage: fstree.New(
|
||||
fstree.WithPath(filepath.Join(p, "blob")),
|
||||
fstree.WithDepth(1)),
|
||||
},
|
||||
}),
|
||||
}
|
||||
|
||||
metaOpts := []meta.Option{
|
||||
meta.WithPath(filepath.Join(p, "meta")),
|
||||
meta.WithEpochState(epochState{})}
|
||||
|
||||
opts := []Option{
|
||||
WithLogger(l),
|
||||
WithBlobStorOptions(blobOpts...),
|
||||
WithMetaBaseOptions(metaOpts...),
|
||||
WithPiloramaOptions(
|
||||
pilorama.WithPath(filepath.Join(p, "pilorama")))}
|
||||
|
||||
sh := New(opts...)
|
||||
require.NoError(t, sh.Open())
|
||||
require.NoError(t, sh.Init())
|
||||
|
||||
objects := make([]objAddr, 5)
|
||||
for i := range objects {
|
||||
objects[i].obj = newObject()
|
||||
objects[i].addr = objectCore.AddressOf(objects[i].obj)
|
||||
require.NoError(t, putObject(sh, objects[i].obj))
|
||||
}
|
||||
|
||||
checkHasObjects := func(t *testing.T, exists bool) {
|
||||
for i := range objects {
|
||||
var prm ExistsPrm
|
||||
prm.SetAddress(objects[i].addr)
|
||||
|
||||
res, err := sh.Exists(prm)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, exists, res.Exists(), "object #%d is missing", i)
|
||||
}
|
||||
}
|
||||
|
||||
checkHasObjects(t, true)
|
||||
|
||||
t.Run("same config, no-op", func(t *testing.T) {
|
||||
require.NoError(t, sh.Reload(opts...))
|
||||
checkHasObjects(t, true)
|
||||
})
|
||||
|
||||
t.Run("open meta at new path", func(t *testing.T) {
|
||||
newShardOpts := func(metaPath string, resync bool) []Option {
|
||||
metaOpts := []meta.Option{meta.WithPath(metaPath), meta.WithEpochState(epochState{})}
|
||||
return append(opts, WithMetaBaseOptions(metaOpts...), WithRefillMetabase(resync))
|
||||
}
|
||||
|
||||
newOpts := newShardOpts(filepath.Join(p, "meta1"), false)
|
||||
require.NoError(t, sh.Reload(newOpts...))
|
||||
|
||||
checkHasObjects(t, false) // new path, but no resync
|
||||
|
||||
t.Run("can put objects", func(t *testing.T) {
|
||||
obj := newObject()
|
||||
require.NoError(t, putObject(sh, obj))
|
||||
objects = append(objects, objAddr{obj: obj, addr: objectCore.AddressOf(obj)})
|
||||
})
|
||||
|
||||
newOpts = newShardOpts(filepath.Join(p, "meta2"), true)
|
||||
require.NoError(t, sh.Reload(newOpts...))
|
||||
|
||||
checkHasObjects(t, true) // all objects are restored, including the new one
|
||||
|
||||
t.Run("reload failed", func(t *testing.T) {
|
||||
badPath := filepath.Join(p, "meta3")
|
||||
require.NoError(t, os.WriteFile(badPath, []byte{1}, 0))
|
||||
|
||||
newOpts = newShardOpts(badPath, true)
|
||||
require.Error(t, sh.Reload(newOpts...))
|
||||
|
||||
// Cleanup is done, no panic.
|
||||
obj := newObject()
|
||||
require.ErrorIs(t, putObject(sh, obj), ErrReadOnlyMode)
|
||||
|
||||
// Old objects are still accessible.
|
||||
checkHasObjects(t, true)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func putObject(sh *Shard, obj *objectSDK.Object) error {
|
||||
var prm PutPrm
|
||||
prm.SetObject(obj)
|
||||
|
||||
_, err := sh.Put(prm)
|
||||
return err
|
||||
}
|
||||
|
||||
func newObject() *objectSDK.Object {
|
||||
x := objectSDK.New()
|
||||
ver := version.Current()
|
||||
|
||||
x.SetID(oidtest.ID())
|
||||
x.SetSessionToken(sessiontest.Object())
|
||||
x.SetPayload([]byte{1, 2, 3})
|
||||
x.SetPayloadSize(3)
|
||||
x.SetOwnerID(usertest.ID())
|
||||
x.SetContainerID(cidtest.ID())
|
||||
x.SetType(objectSDK.TypeRegular)
|
||||
x.SetVersion(&ver)
|
||||
x.SetPayloadChecksum(checksumtest.Checksum())
|
||||
x.SetPayloadHomomorphicHash(checksumtest.Checksum())
|
||||
return x
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue