frostfs-node/pkg/local_object_storage/blobstor/iterate_test.go

153 lines
3.9 KiB
Go
Raw Normal View History

package blobstor
import (
"context"
"encoding/binary"
"errors"
"os"
"testing"
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/common"
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/memstore"
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/teststore"
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/shard/mode"
oid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id"
oidtest "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id/test"
"github.com/stretchr/testify/require"
)
func TestIterateObjects(t *testing.T) {
p := t.Name()
const smalSz = 50
// create BlobStor instance
blobStor := New(
WithStorages(defaultStorages(p, smalSz)),
WithCompressObjects(true),
)
defer os.RemoveAll(p)
// open Blobstor
require.NoError(t, blobStor.Open(context.Background(), mode.ReadWrite))
// initialize Blobstor
require.NoError(t, blobStor.Init())
defer blobStor.Close()
const objNum = 5
type addrData struct {
big bool
addr oid.Address
data []byte
}
mObjs := make(map[string]addrData)
for i := uint64(0); i < objNum; i++ {
sz := smalSz
big := i < objNum/2
if big {
sz++
}
data := make([]byte, sz)
binary.BigEndian.PutUint64(data, i)
addr := oidtest.Address()
mObjs[string(data)] = addrData{
big: big,
addr: addr,
data: data,
}
}
for _, v := range mObjs {
_, err := blobStor.Put(context.Background(), common.PutPrm{Address: v.addr, RawData: v.data})
require.NoError(t, err)
}
err := IterateBinaryObjects(context.Background(), blobStor, func(addr oid.Address, data []byte, descriptor []byte) error {
v, ok := mObjs[string(data)]
require.True(t, ok)
require.Equal(t, v.data, data)
if v.big {
require.True(t, descriptor != nil && len(descriptor) == 0)
} else {
require.NotEmpty(t, descriptor)
}
delete(mObjs, string(data))
return nil
})
require.NoError(t, err)
require.Empty(t, mObjs)
}
func TestIterate_IgnoreErrors(t *testing.T) {
ctx := context.Background()
myErr := errors.New("unique error")
nopIter := func(common.IteratePrm) (common.IterateRes, error) { return common.IterateRes{}, nil }
panicIter := func(common.IteratePrm) (common.IterateRes, error) { panic("unreachable") }
errIter := func(common.IteratePrm) (common.IterateRes, error) { return common.IterateRes{}, myErr }
var s1iter, s2iter func(common.IteratePrm) (common.IterateRes, error)
st1 := teststore.New(
teststore.WithSubstorage(memstore.New()),
teststore.WithIterate(func(prm common.IteratePrm) (common.IterateRes, error) {
return s1iter(prm)
}))
st2 := teststore.New(
teststore.WithSubstorage(memstore.New()),
teststore.WithIterate(func(prm common.IteratePrm) (common.IterateRes, error) {
return s2iter(prm)
}))
bsOpts := []Option{WithStorages([]SubStorage{
{Storage: st1},
{Storage: st2},
})}
bs := New(bsOpts...)
require.NoError(t, bs.Open(ctx, mode.ReadWrite))
require.NoError(t, bs.Init())
nopHandler := func(e common.IterationElement) error {
return nil
}
t.Run("no errors", func(t *testing.T) {
s1iter = nopIter
s2iter = nopIter
_, err := bs.Iterate(ctx, common.IteratePrm{Handler: nopHandler})
require.NoError(t, err)
})
t.Run("error in the first sub storage, the second one is not iterated over", func(t *testing.T) {
s1iter = errIter
s2iter = panicIter
_, err := bs.Iterate(ctx, common.IteratePrm{Handler: nopHandler})
require.ErrorIs(t, err, myErr)
})
t.Run("ignore errors, storage 1", func(t *testing.T) {
s1iter = errIter
s2iter = nopIter
_, err := bs.Iterate(ctx, common.IteratePrm{IgnoreErrors: true, Handler: nopHandler})
require.NoError(t, err)
})
t.Run("ignore errors, storage 2", func(t *testing.T) {
s1iter = nopIter
s2iter = errIter
_, err := bs.Iterate(ctx, common.IteratePrm{IgnoreErrors: true, Handler: nopHandler})
require.NoError(t, err)
})
}