Skip to content

Commit 2f10fdb

Browse files
committed
s3 client mock support for tests
1 parent 3632935 commit 2f10fdb

File tree

4 files changed

+204
-6
lines changed

4 files changed

+204
-6
lines changed

clients/clients.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,10 @@ type S3Client interface {
129129
DeleteObject(ctx context.Context, params *s3.DeleteObjectInput, optFns ...func(*s3.Options)) (*s3.DeleteObjectOutput, error)
130130
PutObject(ctx context.Context, params *s3.PutObjectInput, optFns ...func(*s3.Options)) (*s3.PutObjectOutput, error)
131131
HeadObject(ctx context.Context, params *s3.HeadObjectInput, optFns ...func(*s3.Options)) (*s3.HeadObjectOutput, error)
132+
GetBucketVersioning(ctx context.Context, params *s3.GetBucketVersioningInput, optFns ...func(*s3.Options)) (*s3.GetBucketVersioningOutput, error)
133+
DeleteObjects(ctx context.Context, params *s3.DeleteObjectsInput, optFns ...func(*s3.Options)) (*s3.DeleteObjectsOutput, error)
134+
ListObjectsV2(ctx context.Context, params *s3.ListObjectsV2Input, optFns ...func(*s3.Options)) (*s3.ListObjectsV2Output, error)
135+
ListObjectVersions(ctx context.Context, params *s3.ListObjectVersionsInput, f ...func(*s3.Options)) (*s3.ListObjectVersionsOutput, error)
132136
}
133137

134138
type S3PresignClient interface {

cloud/services/object_storage_objects.go

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212
s3types "github.com/aws/aws-sdk-go-v2/service/s3/types"
1313
"github.com/aws/smithy-go"
1414

15+
"github.com/linode/cluster-api-provider-linode/clients"
1516
"github.com/linode/cluster-api-provider-linode/cloud/scope"
1617
)
1718

@@ -142,7 +143,7 @@ func DeleteObject(ctx context.Context, mscope *scope.MachineScope) error {
142143
func PurgeAllObjects(
143144
ctx context.Context,
144145
bucket string,
145-
s3client *s3.Client,
146+
s3client clients.S3Client,
146147
bypassRetention,
147148
ignoreNotFound bool,
148149
) error {
@@ -172,7 +173,7 @@ func PurgeAllObjects(
172173
// Versioned objects will get a deletion marker instead of being fully purged.
173174
func DeleteAllObjects(
174175
ctx context.Context,
175-
s3client *s3.Client,
176+
s3client clients.S3Client,
176177
bucketName string,
177178
bypassRetention bool,
178179
) error {
@@ -208,7 +209,7 @@ func DeleteAllObjects(
208209
}
209210

210211
// DeleteAllObjectVersionsAndDeleteMarkers deletes all versions of a given object
211-
func DeleteAllObjectVersionsAndDeleteMarkers(ctx context.Context, client *s3.Client, bucket, prefix string, bypassRetention, ignoreNotFound bool) error {
212+
func DeleteAllObjectVersionsAndDeleteMarkers(ctx context.Context, client clients.S3Client, bucket, prefix string, bypassRetention, ignoreNotFound bool) error {
212213
paginator := s3.NewListObjectVersionsPaginator(client, &s3.ListObjectVersionsInput{
213214
Bucket: aws.String(bucket),
214215
Prefix: aws.String(prefix),
@@ -217,14 +218,14 @@ func DeleteAllObjectVersionsAndDeleteMarkers(ctx context.Context, client *s3.Cli
217218
var objectsToDelete []s3types.ObjectIdentifier
218219
for paginator.HasMorePages() {
219220
page, err := paginator.NextPage(ctx)
220-
if page == nil {
221-
continue
222-
}
223221
if err != nil {
224222
if !IsObjNotFoundErr(err) || !ignoreNotFound {
225223
return err
226224
}
227225
}
226+
if page == nil {
227+
continue
228+
}
228229

229230
for _, version := range page.Versions {
230231
objectsToDelete = append(

cloud/services/object_storage_objects_test.go

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,13 @@ import (
88
awssigner "github.com/aws/aws-sdk-go-v2/aws/signer/v4"
99
"github.com/aws/aws-sdk-go-v2/service/s3"
1010
"github.com/aws/aws-sdk-go-v2/service/s3/types"
11+
"github.com/aws/smithy-go/middleware"
1112
"github.com/stretchr/testify/assert"
1213
"github.com/stretchr/testify/require"
1314
"go.uber.org/mock/gomock"
1415
corev1 "k8s.io/api/core/v1"
1516
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
17+
"k8s.io/utils/ptr"
1618
"sigs.k8s.io/controller-runtime/pkg/client"
1719

1820
infrav1alpha2 "github.com/linode/cluster-api-provider-linode/api/v1alpha2"
@@ -413,3 +415,114 @@ func TestDeleteObject(t *testing.T) {
413415
),
414416
)
415417
}
418+
419+
func TestDeleteAllObjects(t *testing.T) {
420+
t.Parallel()
421+
422+
NewSuite(t, mock.MockK8sClient{}, mock.MockS3Client{}).Run(
423+
OneOf(
424+
Path(
425+
Call("fail to list objects", func(ctx context.Context, mck Mock) {
426+
mck.S3Client.EXPECT().ListObjectsV2(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, errors.New("fail"))
427+
}),
428+
Result("error", func(ctx context.Context, mck Mock) {
429+
err := DeleteAllObjects(ctx, mck.S3Client, "test", true)
430+
assert.Error(t, err)
431+
}),
432+
),
433+
Path(
434+
Call("no objects", func(ctx context.Context, mck Mock) {
435+
mck.S3Client.EXPECT().ListObjectsV2(gomock.Any(), gomock.Any(), gomock.Any()).Return(&s3.ListObjectsV2Output{}, nil)
436+
}),
437+
Result("success", func(ctx context.Context, mck Mock) {
438+
err := DeleteAllObjects(ctx, mck.S3Client, "test", true)
439+
assert.NoError(t, err)
440+
}),
441+
),
442+
),
443+
)
444+
}
445+
446+
func TestDeleteAllObjectVersionsAndDeleteMarkers(t *testing.T) {
447+
t.Parallel()
448+
449+
NewSuite(t, mock.MockK8sClient{}, mock.MockS3Client{}).Run(
450+
OneOf(
451+
Path(
452+
Call("fail to list object versions", func(ctx context.Context, mck Mock) {
453+
mck.S3Client.EXPECT().ListObjectVersions(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, errors.New("fail"))
454+
}),
455+
Result("error", func(ctx context.Context, mck Mock) {
456+
err := DeleteAllObjectVersionsAndDeleteMarkers(ctx, mck.S3Client, "test", "", true, false)
457+
assert.Error(t, err)
458+
}),
459+
),
460+
Path(
461+
Call("no objects", func(ctx context.Context, mck Mock) {
462+
mck.S3Client.EXPECT().ListObjectVersions(gomock.Any(), gomock.Any(), gomock.Any()).Return(&s3.ListObjectVersionsOutput{}, nil)
463+
}),
464+
Result("error", func(ctx context.Context, mck Mock) {
465+
err := DeleteAllObjectVersionsAndDeleteMarkers(ctx, mck.S3Client, "test", "", true, false)
466+
assert.NoError(t, err)
467+
}),
468+
),
469+
Path(
470+
Call("with an object", func(ctx context.Context, mck Mock) {
471+
mck.S3Client.EXPECT().ListObjectVersions(gomock.Any(), gomock.Any(), gomock.Any()).Return(&s3.ListObjectVersionsOutput{
472+
Name: ptr.To("test"),
473+
Versions: []types.ObjectVersion{
474+
{
475+
IsLatest: ptr.To(true),
476+
Key: ptr.To("test"),
477+
VersionId: ptr.To("version2"),
478+
},
479+
},
480+
ResultMetadata: middleware.Metadata{},
481+
}, nil)
482+
mck.S3Client.EXPECT().DeleteObjects(gomock.Any(), gomock.Any(), gomock.Any()).Return(&s3.DeleteObjectsOutput{}, nil)
483+
}),
484+
Result("success", func(ctx context.Context, mck Mock) {
485+
err := DeleteAllObjectVersionsAndDeleteMarkers(ctx, mck.S3Client, "test", "", true, false)
486+
assert.NoError(t, err)
487+
}),
488+
),
489+
Path(
490+
Call("with versions and delete markers", func(ctx context.Context, mck Mock) {
491+
mck.S3Client.EXPECT().ListObjectVersions(gomock.Any(), gomock.Any(), gomock.Any()).Return(&s3.ListObjectVersionsOutput{
492+
Name: ptr.To("test"),
493+
Versions: []types.ObjectVersion{
494+
{
495+
IsLatest: ptr.To(false),
496+
Key: ptr.To("test"),
497+
VersionId: ptr.To("version1"),
498+
},
499+
{
500+
IsLatest: ptr.To(true),
501+
Key: ptr.To("test"),
502+
VersionId: ptr.To("version2"),
503+
},
504+
},
505+
ResultMetadata: middleware.Metadata{},
506+
DeleteMarkers: []types.DeleteMarkerEntry{
507+
{
508+
IsLatest: ptr.To(false),
509+
Key: ptr.To("test"),
510+
VersionId: ptr.To("version1"),
511+
},
512+
{
513+
IsLatest: ptr.To(true),
514+
Key: ptr.To("test"),
515+
VersionId: ptr.To("version2"),
516+
},
517+
},
518+
}, nil)
519+
mck.S3Client.EXPECT().DeleteObjects(gomock.Any(), gomock.Any(), gomock.Any()).Return(&s3.DeleteObjectsOutput{}, nil)
520+
}),
521+
Result("success", func(ctx context.Context, mck Mock) {
522+
err := DeleteAllObjectVersionsAndDeleteMarkers(ctx, mck.S3Client, "test", "", true, false)
523+
assert.NoError(t, err)
524+
}),
525+
),
526+
),
527+
)
528+
}

mock/client.go

Lines changed: 80 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)