package blobstortest import ( "context" "errors" "testing" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/common" "github.com/stretchr/testify/require" ) func TestIterate(t *testing.T, cons Constructor, min, max uint64) { s := cons(t) require.NoError(t, s.Open(false)) require.NoError(t, s.Init()) defer func() { require.NoError(t, s.Close()) }() objects := prepare(t, 10, s, min, max) // Delete random object to ensure it is not iterated over. const delID = 2 var delPrm common.DeletePrm delPrm.Address = objects[2].addr delPrm.StorageID = objects[2].storageID _, err := s.Delete(context.Background(), delPrm) require.NoError(t, err) objects = append(objects[:delID], objects[delID+1:]...) runTestNormalHandler(t, s, objects) runTestIgnoreLogicalErrors(t, s, objects) } func runTestNormalHandler(t *testing.T, s common.Storage, objects []objectDesc) { t.Run("normal handler", func(t *testing.T) { seen := make(map[string]objectDesc) var iterPrm common.IteratePrm iterPrm.Handler = func(elem common.IterationElement) error { seen[elem.Address.String()] = objectDesc{ addr: elem.Address, raw: elem.ObjectData, storageID: elem.StorageID, } return nil } _, err := s.Iterate(context.Background(), iterPrm) require.NoError(t, err) require.Equal(t, len(objects), len(seen)) for i := range objects { d, ok := seen[objects[i].addr.String()] require.True(t, ok) require.Equal(t, objects[i].raw, d.raw) require.Equal(t, objects[i].addr, d.addr) require.Equal(t, objects[i].storageID, d.storageID) } }) } func runTestIgnoreLogicalErrors(t *testing.T, s common.Storage, objects []objectDesc) { t.Run("ignore errors doesn't work for logical errors", func(t *testing.T) { seen := make(map[string]objectDesc) var n int logicErr := errors.New("logic error") var iterPrm common.IteratePrm iterPrm.IgnoreErrors = true iterPrm.Handler = func(elem common.IterationElement) error { seen[elem.Address.String()] = objectDesc{ addr: elem.Address, raw: elem.ObjectData, storageID: elem.StorageID, } n++ if n == len(objects)/2 { return logicErr } return nil } _, err := s.Iterate(context.Background(), iterPrm) require.Equal(t, err, logicErr) require.Len(t, seen, len(objects)/2) for i := range objects { d, ok := seen[objects[i].addr.String()] if ok { n-- require.Equal(t, objects[i].raw, d.raw) require.Equal(t, objects[i].addr, d.addr) require.Equal(t, objects[i].storageID, d.storageID) } } require.Equal(t, 0, n) }) }