[#1636] blobovniczatree: Validate limiter release in rebuild unit tests
Signed-off-by: Dmitrii Stepanov <d.stepanov@yadro.com>
This commit is contained in:
parent
250cd71bf8
commit
f2ea3499cd
2 changed files with 47 additions and 11 deletions
|
@ -161,9 +161,10 @@ func testRebuildFailoverValidate(t *testing.T, dir string, obj *objectSDK.Object
|
||||||
storageIDs: make(map[oid.Address][]byte),
|
storageIDs: make(map[oid.Address][]byte),
|
||||||
guard: &sync.Mutex{},
|
guard: &sync.Mutex{},
|
||||||
}
|
}
|
||||||
|
limiter := &rebuildLimiterStub{}
|
||||||
rRes, err := b.Rebuild(context.Background(), common.RebuildPrm{
|
rRes, err := b.Rebuild(context.Background(), common.RebuildPrm{
|
||||||
MetaStorage: metaStub,
|
MetaStorage: metaStub,
|
||||||
Limiter: &rebuildLimiterStub{},
|
Limiter: limiter,
|
||||||
FillPercent: 1,
|
FillPercent: 1,
|
||||||
})
|
})
|
||||||
require.NoError(t, err)
|
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.Equal(t, uint64(0), rRes.FilesRemoved)
|
||||||
|
|
||||||
require.NoError(t, b.Close(context.Background()))
|
require.NoError(t, b.Close(context.Background()))
|
||||||
|
require.NoError(t, limiter.ValidateReleased())
|
||||||
|
|
||||||
blz := blobovnicza.New(blobovnicza.WithPath(filepath.Join(dir, "0", "0", "1.db")))
|
blz := blobovnicza.New(blobovnicza.WithPath(filepath.Join(dir, "0", "0", "1.db")))
|
||||||
require.NoError(t, blz.Open(context.Background()))
|
require.NoError(t, blz.Open(context.Background()))
|
||||||
|
|
|
@ -2,7 +2,9 @@ package blobovniczatree
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"fmt"
|
||||||
"sync"
|
"sync"
|
||||||
|
"sync/atomic"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/core/object"
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/core/object"
|
||||||
|
@ -76,9 +78,10 @@ func TestBlobovniczaTreeFillPercentRebuild(t *testing.T) {
|
||||||
storageIDs: storageIDs,
|
storageIDs: storageIDs,
|
||||||
guard: &sync.Mutex{},
|
guard: &sync.Mutex{},
|
||||||
}
|
}
|
||||||
|
limiter := &rebuildLimiterStub{}
|
||||||
rRes, err := b.Rebuild(context.Background(), common.RebuildPrm{
|
rRes, err := b.Rebuild(context.Background(), common.RebuildPrm{
|
||||||
MetaStorage: metaStub,
|
MetaStorage: metaStub,
|
||||||
Limiter: &rebuildLimiterStub{},
|
Limiter: limiter,
|
||||||
FillPercent: 60,
|
FillPercent: 60,
|
||||||
})
|
})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
@ -94,6 +97,7 @@ func TestBlobovniczaTreeFillPercentRebuild(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
require.NoError(t, b.Close(context.Background()))
|
require.NoError(t, b.Close(context.Background()))
|
||||||
|
require.NoError(t, limiter.ValidateReleased())
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("no rebuild single db", func(t *testing.T) {
|
t.Run("no rebuild single db", func(t *testing.T) {
|
||||||
|
@ -128,9 +132,10 @@ func TestBlobovniczaTreeFillPercentRebuild(t *testing.T) {
|
||||||
storageIDs: storageIDs,
|
storageIDs: storageIDs,
|
||||||
guard: &sync.Mutex{},
|
guard: &sync.Mutex{},
|
||||||
}
|
}
|
||||||
|
limiter := &rebuildLimiterStub{}
|
||||||
rRes, err := b.Rebuild(context.Background(), common.RebuildPrm{
|
rRes, err := b.Rebuild(context.Background(), common.RebuildPrm{
|
||||||
MetaStorage: metaStub,
|
MetaStorage: metaStub,
|
||||||
Limiter: &rebuildLimiterStub{},
|
Limiter: limiter,
|
||||||
FillPercent: 90, // 64KB / 100KB = 64%
|
FillPercent: 90, // 64KB / 100KB = 64%
|
||||||
})
|
})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
@ -146,6 +151,7 @@ func TestBlobovniczaTreeFillPercentRebuild(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
require.NoError(t, b.Close(context.Background()))
|
require.NoError(t, b.Close(context.Background()))
|
||||||
|
require.NoError(t, limiter.ValidateReleased())
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("rebuild by fill percent", func(t *testing.T) {
|
t.Run("rebuild by fill percent", func(t *testing.T) {
|
||||||
|
@ -193,9 +199,10 @@ func TestBlobovniczaTreeFillPercentRebuild(t *testing.T) {
|
||||||
storageIDs: storageIDs,
|
storageIDs: storageIDs,
|
||||||
guard: &sync.Mutex{},
|
guard: &sync.Mutex{},
|
||||||
}
|
}
|
||||||
|
limiter := &rebuildLimiterStub{}
|
||||||
rRes, err := b.Rebuild(context.Background(), common.RebuildPrm{
|
rRes, err := b.Rebuild(context.Background(), common.RebuildPrm{
|
||||||
MetaStorage: metaStub,
|
MetaStorage: metaStub,
|
||||||
Limiter: &rebuildLimiterStub{},
|
Limiter: limiter,
|
||||||
FillPercent: 80,
|
FillPercent: 80,
|
||||||
})
|
})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
@ -215,6 +222,7 @@ func TestBlobovniczaTreeFillPercentRebuild(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
require.NoError(t, b.Close(context.Background()))
|
require.NoError(t, b.Close(context.Background()))
|
||||||
|
require.NoError(t, limiter.ValidateReleased())
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("rebuild by overflow", func(t *testing.T) {
|
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.Open(mode.ComponentReadWrite))
|
||||||
require.NoError(t, b.Init())
|
require.NoError(t, b.Init())
|
||||||
|
|
||||||
|
limiter := &rebuildLimiterStub{}
|
||||||
rRes, err := b.Rebuild(context.Background(), common.RebuildPrm{
|
rRes, err := b.Rebuild(context.Background(), common.RebuildPrm{
|
||||||
MetaStorage: metaStub,
|
MetaStorage: metaStub,
|
||||||
Limiter: &rebuildLimiterStub{},
|
Limiter: limiter,
|
||||||
FillPercent: 80,
|
FillPercent: 80,
|
||||||
})
|
})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
@ -285,6 +294,7 @@ func TestBlobovniczaTreeFillPercentRebuild(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
require.NoError(t, b.Close(context.Background()))
|
require.NoError(t, b.Close(context.Background()))
|
||||||
|
require.NoError(t, limiter.ValidateReleased())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -338,9 +348,10 @@ func TestBlobovniczaTreeRebuildLargeObject(t *testing.T) {
|
||||||
storageIDs: storageIDs,
|
storageIDs: storageIDs,
|
||||||
guard: &sync.Mutex{},
|
guard: &sync.Mutex{},
|
||||||
}
|
}
|
||||||
|
limiter := &rebuildLimiterStub{}
|
||||||
var rPrm common.RebuildPrm
|
var rPrm common.RebuildPrm
|
||||||
rPrm.MetaStorage = metaStub
|
rPrm.MetaStorage = metaStub
|
||||||
rPrm.Limiter = &rebuildLimiterStub{}
|
rPrm.Limiter = limiter
|
||||||
rPrm.FillPercent = 1
|
rPrm.FillPercent = 1
|
||||||
rRes, err := b.Rebuild(context.Background(), rPrm)
|
rRes, err := b.Rebuild(context.Background(), rPrm)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
@ -356,6 +367,7 @@ func TestBlobovniczaTreeRebuildLargeObject(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
require.NoError(t, b.Close(context.Background()))
|
require.NoError(t, b.Close(context.Background()))
|
||||||
|
require.NoError(t, limiter.ValidateReleased())
|
||||||
}
|
}
|
||||||
|
|
||||||
func testBlobovniczaTreeRebuildHelper(t *testing.T, sourceDepth, sourceWidth, targetDepth, targetWidth uint64, shouldMigrate bool) {
|
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,
|
storageIDs: storageIDs,
|
||||||
guard: &sync.Mutex{},
|
guard: &sync.Mutex{},
|
||||||
}
|
}
|
||||||
|
limiter := &rebuildLimiterStub{}
|
||||||
var rPrm common.RebuildPrm
|
var rPrm common.RebuildPrm
|
||||||
rPrm.MetaStorage = metaStub
|
rPrm.MetaStorage = metaStub
|
||||||
rPrm.Limiter = &rebuildLimiterStub{}
|
rPrm.Limiter = limiter
|
||||||
rPrm.FillPercent = 1
|
rPrm.FillPercent = 1
|
||||||
rRes, err := b.Rebuild(context.Background(), rPrm)
|
rRes, err := b.Rebuild(context.Background(), rPrm)
|
||||||
require.NoError(t, err)
|
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, b.Close(context.Background()))
|
||||||
|
require.NoError(t, limiter.ValidateReleased())
|
||||||
}
|
}
|
||||||
|
|
||||||
type storageIDUpdateStub struct {
|
type storageIDUpdateStub struct {
|
||||||
|
@ -462,16 +476,36 @@ func (s *storageIDUpdateStub) UpdateStorageID(ctx context.Context, addr oid.Addr
|
||||||
return nil
|
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) {
|
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) {
|
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) {
|
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
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue