From 82efafcc22841c158a6c09145cb69830c2d5dd7d Mon Sep 17 00:00:00 2001 From: shabbyrobe Date: Sun, 10 Mar 2019 13:22:41 +1100 Subject: [PATCH] Add pagination test --- gofakes3_test.go | 49 +++++++++++++++++++++++++++ init_test.go | 87 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 136 insertions(+) diff --git a/gofakes3_test.go b/gofakes3_test.go index c38aed0..6dba9b4 100644 --- a/gofakes3_test.go +++ b/gofakes3_test.go @@ -674,6 +674,55 @@ func TestObjectVersions(t *testing.T) { }) } +func TestListBucketPages(t *testing.T) { + createData := func(ts *testServer, prefix string, n int64) []string { + keys := make([]string, n) + for i := int64(0); i < n; i++ { + key := fmt.Sprintf("%s%d", prefix, i) + ts.backendPutString(defaultBucket, key, nil, fmt.Sprintf("body-%d", i)) + keys[i] = key + } + return keys + } + + assertKeys := func(ts *testServer, rs *listBucketResult, keys ...string) { + found := make([]string, len(rs.Contents)) + for i := 0; i < len(rs.Contents); i++ { + found[i] = aws.StringValue(rs.Contents[i].Key) + } + if !reflect.DeepEqual(found, keys) { + t.Fatal("key mismatch:", keys, "!=", found) + } + } + + for idx, tc := range []struct { + keys, pageKeys int64 + }{ + {8, 3}, + {7, 4}, + {6, 5}, + {5, 6}, + } { + t.Run(fmt.Sprintf("list-page-sizes/%d", idx), func(t *testing.T) { + ts := newTestServer(t) + defer ts.Close() + keys := createData(ts, "", tc.keys) + + rs := ts.mustListBucketV1Pages(nil, tc.pageKeys, "") + if len(rs.CommonPrefixes) > 0 { + t.Fatal() + } + assertKeys(ts, rs, keys...) + + rs = ts.mustListBucketV2Pages(nil, tc.pageKeys, "") + if len(rs.CommonPrefixes) > 0 { + t.Fatal() + } + assertKeys(ts, rs, keys...) + }) + } +} + func s3HasErrorCode(err error, code gofakes3.ErrorCode) bool { if err, ok := err.(awserr.Error); ok { return code == gofakes3.ErrorCode(err.Code()) diff --git a/init_test.go b/init_test.go index 4448c18..02116cd 100644 --- a/init_test.go +++ b/init_test.go @@ -616,6 +616,93 @@ func (ts *testServer) assertObject(bucket string, object string, meta map[string } } +type listBucketResult struct { + CommonPrefixes []*s3.CommonPrefix + Contents []*s3.Object +} + +func (ts *testServer) mustListBucketV1Pages(prefix *gofakes3.Prefix, maxKeys int64, marker string) *listBucketResult { + r, err := ts.listBucketV1Pages(prefix, maxKeys, marker) + ts.OK(err) + return r +} + +func (ts *testServer) listBucketV1Pages(prefix *gofakes3.Prefix, maxKeys int64, marker string) (*listBucketResult, error) { + const pageLimit = 20 + + svc := ts.s3Client() + pages := 0 + in := &s3.ListObjectsInput{ + Bucket: aws.String(defaultBucket), + MaxKeys: aws.Int64(maxKeys), + } + if prefix != nil && prefix.HasDelimiter { + in.Delimiter = aws.String(prefix.Delimiter) + } + if prefix != nil && prefix.HasPrefix { + in.Prefix = aws.String(prefix.Prefix) + } + if marker != "" { + in.Marker = aws.String(marker) + } + + var rs listBucketResult + if err := (svc.ListObjectsPages(in, func(out *s3.ListObjectsOutput, lastPage bool) bool { + pages++ + if pages > pageLimit { + panic("stuck in a page loop") + } + rs.CommonPrefixes = append(rs.CommonPrefixes, out.CommonPrefixes...) + rs.Contents = append(rs.Contents, out.Contents...) + return !lastPage + })); err != nil { + return nil, err + } + + return &rs, nil +} + +func (ts *testServer) mustListBucketV2Pages(prefix *gofakes3.Prefix, maxKeys int64, marker string) *listBucketResult { + r, err := ts.listBucketV2Pages(prefix, maxKeys, marker) + ts.OK(err) + return r +} + +func (ts *testServer) listBucketV2Pages(prefix *gofakes3.Prefix, maxKeys int64, startAfter string) (*listBucketResult, error) { + const pageLimit = 20 + + svc := ts.s3Client() + pages := 0 + in := &s3.ListObjectsV2Input{ + Bucket: aws.String(defaultBucket), + MaxKeys: aws.Int64(maxKeys), + } + if prefix != nil && prefix.HasDelimiter { + in.Delimiter = aws.String(prefix.Delimiter) + } + if prefix != nil && prefix.HasPrefix { + in.Prefix = aws.String(prefix.Prefix) + } + if startAfter != "" { + in.StartAfter = aws.String(startAfter) + } + + var rs listBucketResult + if err := (svc.ListObjectsV2Pages(in, func(out *s3.ListObjectsV2Output, lastPage bool) bool { + pages++ + if pages > pageLimit { + panic("stuck in a page loop") + } + rs.CommonPrefixes = append(rs.CommonPrefixes, out.CommonPrefixes...) + rs.Contents = append(rs.Contents, out.Contents...) + return !lastPage + })); err != nil { + return nil, err + } + + return &rs, nil +} + func (ts *testServer) Close() { ts.server.Close() }