forked from TrueCloudLab/frostfs-node
Aleksey Savchuk
7fc6101bec
- Remove `testNewShard` and `setInitializedShards` because they violated the default engine workflow. The correct workflow is: first use `New()`, followed by `Open()`, and then `Init()`. As a result, adding new logic to `(*StorageEngine).Init` caused several tests to fail with a panic when attempting to access uninitialized resources. Now, all engines created with the test utils must be initialized manually. The new helper method `prepare` can be used for that purpose. - Additionally, `setInitializedShards` hardcoded the shard worker pool size, which prevented it from being configured in tests and benchmarks. This has been fixed as well. - Ensure engine initialization is done wherever it was missing. - Refactor `setShardsNumOpts`, `setShardsNumAdditionalOpts`, and `setShardsNum`. Make them all depend on `setShardsNumOpts`. Signed-off-by: Aleksey Savchuk <a.savchuk@yadro.com>
147 lines
4.6 KiB
Go
147 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{}
|
|
|
|
func (s epochState) CurrentEpoch() uint64 {
|
|
return 0
|
|
}
|
|
|
|
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
|
|
}
|