[#1636] blobovniczatree: Validate limiter release in rebuild unit tests

Signed-off-by: Dmitrii Stepanov <d.stepanov@yadro.com>
This commit is contained in:
Dmitrii Stepanov 2025-02-28 10:04:24 +03:00
parent 6c6e463b73
commit eb8b9b2b3b
Signed by: dstepanov-yadro
GPG key ID: 237AF1A763293BC0
2 changed files with 47 additions and 11 deletions

View file

@ -161,9 +161,10 @@ func testRebuildFailoverValidate(t *testing.T, dir string, obj *objectSDK.Object
storageIDs: make(map[oid.Address][]byte),
guard: &sync.Mutex{},
}
limiter := &rebuildLimiterStub{}
rRes, err := b.Rebuild(context.Background(), common.RebuildPrm{
MetaStorage: metaStub,
Limiter: &rebuildLimiterStub{},
Limiter: limiter,
FillPercent: 1,
})
require.NoError(t, err)
@ -171,6 +172,7 @@ func testRebuildFailoverValidate(t *testing.T, dir string, obj *objectSDK.Object
require.Equal(t, uint64(0), rRes.FilesRemoved)
require.NoError(t, b.Close(context.Background()))
require.NoError(t, limiter.ValidateReleased())
blz := blobovnicza.New(blobovnicza.WithPath(filepath.Join(dir, "0", "0", "1.db")))
require.NoError(t, blz.Open(context.Background()))

View file

@ -2,7 +2,9 @@ package blobovniczatree
import (
"context"
"fmt"
"sync"
"sync/atomic"
"testing"
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/core/object"
@ -76,9 +78,10 @@ func TestBlobovniczaTreeFillPercentRebuild(t *testing.T) {
storageIDs: storageIDs,
guard: &sync.Mutex{},
}
limiter := &rebuildLimiterStub{}
rRes, err := b.Rebuild(context.Background(), common.RebuildPrm{
MetaStorage: metaStub,
Limiter: &rebuildLimiterStub{},
Limiter: limiter,
FillPercent: 60,
})
require.NoError(t, err)
@ -94,6 +97,7 @@ func TestBlobovniczaTreeFillPercentRebuild(t *testing.T) {
}
require.NoError(t, b.Close(context.Background()))
require.NoError(t, limiter.ValidateReleased())
})
t.Run("no rebuild single db", func(t *testing.T) {
@ -128,9 +132,10 @@ func TestBlobovniczaTreeFillPercentRebuild(t *testing.T) {
storageIDs: storageIDs,
guard: &sync.Mutex{},
}
limiter := &rebuildLimiterStub{}
rRes, err := b.Rebuild(context.Background(), common.RebuildPrm{
MetaStorage: metaStub,
Limiter: &rebuildLimiterStub{},
Limiter: limiter,
FillPercent: 90, // 64KB / 100KB = 64%
})
require.NoError(t, err)
@ -146,6 +151,7 @@ func TestBlobovniczaTreeFillPercentRebuild(t *testing.T) {
}
require.NoError(t, b.Close(context.Background()))
require.NoError(t, limiter.ValidateReleased())
})
t.Run("rebuild by fill percent", func(t *testing.T) {
@ -193,9 +199,10 @@ func TestBlobovniczaTreeFillPercentRebuild(t *testing.T) {
storageIDs: storageIDs,
guard: &sync.Mutex{},
}
limiter := &rebuildLimiterStub{}
rRes, err := b.Rebuild(context.Background(), common.RebuildPrm{
MetaStorage: metaStub,
Limiter: &rebuildLimiterStub{},
Limiter: limiter,
FillPercent: 80,
})
require.NoError(t, err)
@ -215,6 +222,7 @@ func TestBlobovniczaTreeFillPercentRebuild(t *testing.T) {
}
require.NoError(t, b.Close(context.Background()))
require.NoError(t, limiter.ValidateReleased())
})
t.Run("rebuild by overflow", func(t *testing.T) {
@ -266,9 +274,10 @@ func TestBlobovniczaTreeFillPercentRebuild(t *testing.T) {
require.NoError(t, b.Open(mode.ComponentReadWrite))
require.NoError(t, b.Init())
limiter := &rebuildLimiterStub{}
rRes, err := b.Rebuild(context.Background(), common.RebuildPrm{
MetaStorage: metaStub,
Limiter: &rebuildLimiterStub{},
Limiter: limiter,
FillPercent: 80,
})
require.NoError(t, err)
@ -285,6 +294,7 @@ func TestBlobovniczaTreeFillPercentRebuild(t *testing.T) {
}
require.NoError(t, b.Close(context.Background()))
require.NoError(t, limiter.ValidateReleased())
})
}
@ -338,9 +348,10 @@ func TestBlobovniczaTreeRebuildLargeObject(t *testing.T) {
storageIDs: storageIDs,
guard: &sync.Mutex{},
}
limiter := &rebuildLimiterStub{}
var rPrm common.RebuildPrm
rPrm.MetaStorage = metaStub
rPrm.Limiter = &rebuildLimiterStub{}
rPrm.Limiter = limiter
rPrm.FillPercent = 1
rRes, err := b.Rebuild(context.Background(), rPrm)
require.NoError(t, err)
@ -356,6 +367,7 @@ func TestBlobovniczaTreeRebuildLargeObject(t *testing.T) {
}
require.NoError(t, b.Close(context.Background()))
require.NoError(t, limiter.ValidateReleased())
}
func testBlobovniczaTreeRebuildHelper(t *testing.T, sourceDepth, sourceWidth, targetDepth, targetWidth uint64, shouldMigrate bool) {
@ -427,9 +439,10 @@ func testBlobovniczaTreeRebuildHelper(t *testing.T, sourceDepth, sourceWidth, ta
storageIDs: storageIDs,
guard: &sync.Mutex{},
}
limiter := &rebuildLimiterStub{}
var rPrm common.RebuildPrm
rPrm.MetaStorage = metaStub
rPrm.Limiter = &rebuildLimiterStub{}
rPrm.Limiter = limiter
rPrm.FillPercent = 1
rRes, err := b.Rebuild(context.Background(), rPrm)
require.NoError(t, err)
@ -445,6 +458,7 @@ func testBlobovniczaTreeRebuildHelper(t *testing.T, sourceDepth, sourceWidth, ta
}
require.NoError(t, b.Close(context.Background()))
require.NoError(t, limiter.ValidateReleased())
}
type storageIDUpdateStub struct {
@ -462,16 +476,36 @@ func (s *storageIDUpdateStub) UpdateStorageID(ctx context.Context, addr oid.Addr
return nil
}
type rebuildLimiterStub struct{}
type rebuildLimiterStub struct {
slots atomic.Int64
readRequests atomic.Int64
writeRequests atomic.Int64
}
func (s *rebuildLimiterStub) AcquireWorkSlot(context.Context) (common.ReleaseFunc, error) {
return func() {}, nil
s.slots.Add(1)
return func() { s.slots.Add(-1) }, nil
}
func (s *rebuildLimiterStub) ReadRequest(context.Context) (common.ReleaseFunc, error) {
return func() {}, nil
s.readRequests.Add(1)
return func() { s.readRequests.Add(-1) }, nil
}
func (s *rebuildLimiterStub) WriteRequest(context.Context) (common.ReleaseFunc, error) {
return func() {}, nil
s.writeRequests.Add(1)
return func() { s.writeRequests.Add(-1) }, nil
}
func (s *rebuildLimiterStub) ValidateReleased() error {
if v := s.slots.Load(); v != 0 {
return fmt.Errorf("invalid slots value %d", v)
}
if v := s.readRequests.Load(); v != 0 {
return fmt.Errorf("invalid read requests value %d", v)
}
if v := s.writeRequests.Load(); v != 0 {
return fmt.Errorf("invalid write requests value %d", v)
}
return nil
}