package engine import ( "context" "fmt" "os" "path/filepath" "sort" "testing" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/core/object" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/internal/testutil" meta "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/metabase" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/pilorama" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/shard" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/util/logger" cidtest "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id/test" objectSDK "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object" "github.com/stretchr/testify/require" "go.uber.org/zap" ) func sortAddresses(addrWithType []object.AddressWithType) []object.AddressWithType { sort.Slice(addrWithType, func(i, j int) bool { return addrWithType[i].Address.EncodeToString() < addrWithType[j].Address.EncodeToString() }) return addrWithType } func TestListWithCursor(t *testing.T) { t.Parallel() tests := []struct { name string shardNum int objectNum int batchSize uint32 }{ { name: "one shard, few objects, small batch size", shardNum: 1, objectNum: 2, batchSize: 1, }, { name: "one shard, many objects, big batch size", shardNum: 1, objectNum: 53, batchSize: 100, }, { name: "many shards, many objects, small batch size", shardNum: 6, objectNum: 66, batchSize: 1, }, { name: "many shards, many objects, big batch size", shardNum: 6, objectNum: 99, batchSize: 100, }, } for i := range tests { tt := tests[i] t.Run(tt.name, func(t *testing.T) { t.Parallel() e := testNewEngine(t).setShardsNumOpts(t, tt.shardNum, func(id int) []shard.Option { return []shard.Option{ shard.WithLogger(&logger.Logger{Logger: zap.L()}), shard.WithBlobStorOptions( blobstor.WithStorages( newStorages(filepath.Join(t.Name(), tt.name, fmt.Sprintf("%d.blobstor", id)), 1<<20))), shard.WithPiloramaOptions(pilorama.WithPath(filepath.Join(t.Name(), tt.name, fmt.Sprintf("%d.pilorama", id)))), shard.WithMetaBaseOptions( meta.WithPath(filepath.Join(t.Name(), tt.name, fmt.Sprintf("%d.metabase", id))), meta.WithPermissions(0700), meta.WithEpochState(epochState{}), )} }).engine require.NoError(t, e.Open()) require.NoError(t, e.Init(context.Background())) t.Cleanup(func() { e.Close() os.RemoveAll(t.Name()) }) expected := make([]object.AddressWithType, 0, tt.objectNum) got := make([]object.AddressWithType, 0, tt.objectNum) for i := 0; i < tt.objectNum; i++ { containerID := cidtest.ID() obj := testutil.GenerateObjectWithCIDWithPayload(containerID, []byte{'a'}) var prm PutPrm prm.WithObject(obj) err := e.Put(context.Background(), prm) require.NoError(t, err) expected = append(expected, object.AddressWithType{Type: objectSDK.TypeRegular, Address: object.AddressOf(obj)}) } expected = sortAddresses(expected) var prm ListWithCursorPrm prm.count = tt.batchSize for { res, err := e.ListWithCursor(context.Background(), prm) if err == ErrEndOfListing { require.Empty(t, res.AddressList()) break } require.NotEmpty(t, res.AddressList()) got = append(got, res.AddressList()...) prm.cursor = res.Cursor() } got = sortAddresses(got) require.Equal(t, expected, got) }) } }