forked from TrueCloudLab/frostfs-node
[#1491] engine/test: Rework engine test utils
- 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>
This commit is contained in:
parent
7ef36749d0
commit
7fc6101bec
11 changed files with 88 additions and 123 deletions
|
@ -3,7 +3,6 @@ package engine
|
|||
import (
|
||||
"context"
|
||||
"path/filepath"
|
||||
"sync/atomic"
|
||||
"testing"
|
||||
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor"
|
||||
|
@ -26,68 +25,77 @@ func (s epochState) CurrentEpoch() uint64 {
|
|||
|
||||
type testEngineWrapper struct {
|
||||
engine *StorageEngine
|
||||
shards []*shard.Shard
|
||||
shardIDs []*shard.ID
|
||||
}
|
||||
|
||||
func testNewEngine(t testing.TB, opts ...Option) *testEngineWrapper {
|
||||
engine := New(WithLogger(test.NewLogger(t)))
|
||||
for _, opt := range opts {
|
||||
opt(engine.cfg)
|
||||
}
|
||||
return &testEngineWrapper{
|
||||
engine: engine,
|
||||
}
|
||||
}
|
||||
|
||||
func (te *testEngineWrapper) setInitializedShards(t testing.TB, shards ...*shard.Shard) *testEngineWrapper {
|
||||
for _, s := range shards {
|
||||
pool, err := ants.NewPool(10, ants.WithNonblocking(true))
|
||||
require.NoError(t, err)
|
||||
|
||||
te.engine.shards[s.ID().String()] = hashedShard{
|
||||
shardWrapper: shardWrapper{
|
||||
errorCount: new(atomic.Uint32),
|
||||
Shard: s,
|
||||
},
|
||||
hash: hrw.StringHash(s.ID().String()),
|
||||
}
|
||||
te.engine.shardPools[s.ID().String()] = pool
|
||||
te.shardIDs = append(te.shardIDs, s.ID())
|
||||
}
|
||||
return te
|
||||
opts = append(testGetDefaultEngineOptions(t), opts...)
|
||||
return &testEngineWrapper{engine: New(opts...)}
|
||||
}
|
||||
|
||||
func (te *testEngineWrapper) setShardsNum(t testing.TB, num int) *testEngineWrapper {
|
||||
shards := make([]*shard.Shard, 0, num)
|
||||
|
||||
for range num {
|
||||
shards = append(shards, testNewShard(t))
|
||||
}
|
||||
|
||||
return te.setInitializedShards(t, shards...)
|
||||
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 {
|
||||
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 {
|
||||
opts := shardOpts(i)
|
||||
id, err := te.engine.AddShard(context.Background(), opts...)
|
||||
shard, err := te.engine.createShard(context.Background(), shardOpts(i))
|
||||
require.NoError(t, err)
|
||||
te.shardIDs = append(te.shardIDs, id)
|
||||
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 {
|
||||
for i := range num {
|
||||
defaultOpts := testDefaultShardOptions(t)
|
||||
opts := append(defaultOpts, shardOpts(i)...)
|
||||
id, err := te.engine.AddShard(context.Background(), opts...)
|
||||
require.NoError(t, err)
|
||||
te.shardIDs = append(te.shardIDs, id)
|
||||
}
|
||||
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{
|
||||
{
|
||||
|
@ -137,34 +145,3 @@ func newTestStorages(root string, smallSize uint64) ([]blobstor.SubStorage, *tes
|
|||
},
|
||||
}, smallFileStorage, largeFileStorage
|
||||
}
|
||||
|
||||
func testNewShard(t testing.TB, opts ...shard.Option) *shard.Shard {
|
||||
sid, err := generateShardID()
|
||||
require.NoError(t, err)
|
||||
|
||||
shardOpts := append([]shard.Option{shard.WithID(sid)}, testDefaultShardOptions(t)...)
|
||||
s := shard.New(append(shardOpts, opts...)...)
|
||||
|
||||
require.NoError(t, s.Open(context.Background()))
|
||||
require.NoError(t, s.Init(context.Background()))
|
||||
|
||||
return s
|
||||
}
|
||||
|
||||
func testDefaultShardOptions(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)),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue