frostfs-node/pkg/local_object_storage/engine/engine_test.go
2024-12-02 15:37:25 +03:00

149 lines
4.6 KiB
Go

package engine
import (
"context"
"path/filepath"
"testing"
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor"
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/blobovniczatree"
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/fstree"
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/teststore"
meta "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/metabase"
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/pilorama"
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/shard"
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/util/logger/test"
objectSDK "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object"
"github.com/stretchr/testify/require"
)
type epochState struct {
currEpoch uint64
}
func (s epochState) CurrentEpoch() uint64 {
return s.currEpoch
}
type testEngineWrapper struct {
engine *StorageEngine
shards []*shard.Shard
shardIDs []*shard.ID
}
func testNewEngine(t testing.TB, opts ...Option) *testEngineWrapper {
opts = append(testGetDefaultEngineOptions(t), opts...)
return &testEngineWrapper{engine: New(opts...)}
}
func (te *testEngineWrapper) setShardsNum(t testing.TB, num int) *testEngineWrapper {
return te.setShardsNumOpts(t, num, func(_ int) []shard.Option {
return testGetDefaultShardOptions(t)
})
}
func (te *testEngineWrapper) setShardsNumOpts(
t testing.TB, num int, shardOpts func(id int) []shard.Option,
) *testEngineWrapper {
te.shards = make([]*shard.Shard, num)
te.shardIDs = make([]*shard.ID, num)
for i := range num {
shard, err := te.engine.createShard(context.Background(), shardOpts(i))
require.NoError(t, err)
require.NoError(t, te.engine.addShard(shard))
te.shards[i] = shard
te.shardIDs[i] = shard.ID()
}
require.Len(t, te.engine.shards, num)
require.Len(t, te.engine.shardPools, num)
return te
}
func (te *testEngineWrapper) setShardsNumAdditionalOpts(
t testing.TB, num int, shardOpts func(id int) []shard.Option,
) *testEngineWrapper {
return te.setShardsNumOpts(t, num, func(id int) []shard.Option {
return append(testGetDefaultShardOptions(t), shardOpts(id)...)
})
}
// prepare calls Open and Init on the created engine.
func (te *testEngineWrapper) prepare(t testing.TB) *testEngineWrapper {
require.NoError(t, te.engine.Open(context.Background()))
require.NoError(t, te.engine.Init(context.Background()))
return te
}
func testGetDefaultEngineOptions(t testing.TB) []Option {
return []Option{
WithLogger(test.NewLogger(t)),
}
}
func testGetDefaultShardOptions(t testing.TB) []shard.Option {
return []shard.Option{
shard.WithLogger(test.NewLogger(t)),
shard.WithBlobStorOptions(
blobstor.WithStorages(
newStorages(t, t.TempDir(), 1<<20)),
blobstor.WithLogger(test.NewLogger(t)),
),
shard.WithPiloramaOptions(pilorama.WithPath(filepath.Join(t.TempDir(), "pilorama"))),
shard.WithMetaBaseOptions(
meta.WithPath(filepath.Join(t.TempDir(), "metabase")),
meta.WithPermissions(0o700),
meta.WithEpochState(epochState{}),
meta.WithLogger(test.NewLogger(t)),
),
}
}
func newStorages(t testing.TB, root string, smallSize uint64) []blobstor.SubStorage {
return []blobstor.SubStorage{
{
Storage: blobovniczatree.NewBlobovniczaTree(
context.Background(),
blobovniczatree.WithRootPath(filepath.Join(root, "blobovnicza")),
blobovniczatree.WithBlobovniczaShallowDepth(1),
blobovniczatree.WithBlobovniczaShallowWidth(1),
blobovniczatree.WithPermissions(0o700),
blobovniczatree.WithLogger(test.NewLogger(t))),
Policy: func(_ *objectSDK.Object, data []byte) bool {
return uint64(len(data)) < smallSize
},
},
{
Storage: fstree.New(
fstree.WithPath(root),
fstree.WithDepth(1),
fstree.WithLogger(test.NewLogger(t))),
},
}
}
func newTestStorages(root string, smallSize uint64) ([]blobstor.SubStorage, *teststore.TestStore, *teststore.TestStore) {
smallFileStorage := teststore.New(
teststore.WithSubstorage(blobovniczatree.NewBlobovniczaTree(
context.Background(),
blobovniczatree.WithRootPath(filepath.Join(root, "blobovnicza")),
blobovniczatree.WithBlobovniczaShallowDepth(1),
blobovniczatree.WithBlobovniczaShallowWidth(1),
blobovniczatree.WithPermissions(0o700)),
))
largeFileStorage := teststore.New(
teststore.WithSubstorage(fstree.New(
fstree.WithPath(root),
fstree.WithDepth(1)),
))
return []blobstor.SubStorage{
{
Storage: smallFileStorage,
Policy: func(_ *objectSDK.Object, data []byte) bool {
return uint64(len(data)) < smallSize
},
},
{
Storage: largeFileStorage,
},
}, smallFileStorage, largeFileStorage
}