Skip to content

Commit

Permalink
COSI-25: add-unit-tests
Browse files Browse the repository at this point in the history
  • Loading branch information
anurag4DSB committed Dec 11, 2024
1 parent 4652178 commit 056509d
Show file tree
Hide file tree
Showing 3 changed files with 162 additions and 26 deletions.
27 changes: 27 additions & 0 deletions pkg/clients/s3/s3_client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,4 +128,31 @@ var _ = Describe("S3Client", func() {
Expect(err).NotTo(BeNil())
})
})

Describe("DeleteBucket", func() {
var mockS3 *mock.MockS3Client
var client *s3client.S3Client

BeforeEach(func() {
mockS3 = &mock.MockS3Client{}
client = &s3client.S3Client{
S3Service: mockS3,
}
})

It("should successfully delete a bucket", func(ctx SpecContext) {
err := client.DeleteBucket(ctx, "test-bucket")
Expect(err).To(BeNil())
})

It("should handle errors when deleting a bucket", func(ctx SpecContext) {
mockS3.DeleteBucketFunc = func(ctx context.Context, input *s3.DeleteBucketInput, opts ...func(*s3.Options)) (*s3.DeleteBucketOutput, error) {
return nil, fmt.Errorf("mock delete bucket error")
}

err := client.DeleteBucket(ctx, "test-bucket")
Expect(err).To(HaveOccurred())
Expect(err.Error()).To(ContainSubstring("mock delete bucket error"))
})
})
})
152 changes: 126 additions & 26 deletions pkg/driver/provisioner_server_impl_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -248,32 +248,6 @@ var _ = Describe("ProvisionerServer DriverCreateBucket", Ordered, func() {
})
})

var _ = Describe("ProvisionerServer Unimplemented Methods", Ordered, func() {
var (
provisioner *driver.ProvisionerServer
clientset *fake.Clientset
bucketName string
)

BeforeEach(func() {
clientset = fake.NewSimpleClientset()
provisioner = &driver.ProvisionerServer{
Provisioner: "test-provisioner",
Clientset: clientset,
}
bucketName = "test-bucket"
})

It("DriverDeleteBucket should return Unimplemented error", func(ctx SpecContext) {
request := &cosiapi.DriverDeleteBucketRequest{BucketId: bucketName}
resp, err := provisioner.DriverDeleteBucket(ctx, request)
Expect(resp).To(BeNil())
Expect(err).To(HaveOccurred())
Expect(status.Code(err)).To(Equal(codes.Unimplemented))
Expect(err.Error()).To(ContainSubstring("DriverCreateBucket: not implemented"))
})
})

var _ = Describe("FetchSecretInformation", Ordered, func() {
var (
parameters map[string]string
Expand Down Expand Up @@ -808,3 +782,129 @@ var _ = Describe("ProvisionerServer DriverRevokeBucketAccess", Ordered, func() {
Expect(err.Error()).To(ContainSubstring("unsupported client type for IAM operations"))
})
})

var _ = Describe("ProvisionerServer DriverDeleteBucket", Ordered, func() {
var (
mockS3Client *mock.MockS3Client
provisioner *driver.ProvisionerServer
clientset *fake.Clientset
bucketName string
request *cosiapi.DriverDeleteBucketRequest
originalInitializeClient func(ctx context.Context, clientset kubernetes.Interface, parameters map[string]string, service string) (interface{}, *util.StorageClientParameters, error)
bucketClientset *bucketclientfake.Clientset
secretName, namespace string
s3Params util.StorageClientParameters
)

BeforeEach(func() {
mockS3Client = &mock.MockS3Client{}
clientset = fake.NewSimpleClientset()
bucketClientset = bucketclientfake.NewSimpleClientset()

provisioner = &driver.ProvisionerServer{
Provisioner: "test-provisioner",
Clientset: clientset,
BucketClientset: bucketClientset,
}

s3Params = util.StorageClientParameters{
AccessKeyID: "test-access-key",
SecretAccessKey: "test-secret-key",
Endpoint: "https://test-endpoint",
Region: "us-west-2",
}
secretName = "my-storage-secret"
namespace = "test-namespace"

// Create a fake Bucket object with appropriate parameters
_, err := bucketClientset.ObjectstorageV1alpha1().Buckets().Create(context.TODO(), &bucketv1alpha1.Bucket{
ObjectMeta: metav1.ObjectMeta{
Name: bucketName,
},
Spec: bucketv1alpha1.BucketSpec{
Parameters: map[string]string{
"objectStorageSecretName": secretName,
"objectStorageSecretNamespace": namespace,
},
},
}, metav1.CreateOptions{})
Expect(err).To(BeNil())

request = &cosiapi.DriverDeleteBucketRequest{BucketId: bucketName}
originalInitializeClient = driver.InitializeClient
driver.InitializeClient = func(ctx context.Context, clientset kubernetes.Interface, parameters map[string]string, service string) (interface{}, *util.StorageClientParameters, error) {
// Validate parameters
Expect(parameters["objectStorageSecretName"]).To(Equal(secretName))
Expect(parameters["objectStorageSecretNamespace"]).To(Equal(namespace))

if service == "S3" {
return &s3client.S3Client{S3Service: mockS3Client}, &s3Params, nil
}
return nil, nil, errors.New("unsupported service")
}
})

AfterEach(func() {
mockS3Client = nil
bucketClientset = nil
clientset = nil
provisioner = nil
driver.InitializeClient = originalInitializeClient
})

It("should successfully delete bucket when bucket exists and parameters are valid", func(ctx SpecContext) {
resp, err := provisioner.DriverDeleteBucket(ctx, request)

Expect(err).To(BeNil())
Expect(resp).NotTo(BeNil())
Expect(resp).To(BeAssignableToTypeOf(&cosiapi.DriverDeleteBucketResponse{}))
})

It("should return error if the bucket does not exist", func(ctx SpecContext) {
err := bucketClientset.ObjectstorageV1alpha1().Buckets().Delete(context.TODO(), bucketName, metav1.DeleteOptions{})
Expect(err).To(BeNil())

resp, err := provisioner.DriverDeleteBucket(ctx, request)

Expect(resp).To(BeNil())
Expect(err).To(HaveOccurred())
Expect(status.Code(err)).To(Equal(codes.Internal))
Expect(err.Error()).To(ContainSubstring("failed to get bucket object from kubernetes"))
})

It("should return error if S3 client initialization fails", func(ctx SpecContext) {
driver.InitializeClient = func(ctx context.Context, clientset kubernetes.Interface, parameters map[string]string, service string) (interface{}, *util.StorageClientParameters, error) {
return nil, nil, fmt.Errorf("mock S3 client initialization error")
}

resp, err := provisioner.DriverDeleteBucket(ctx, request)
Expect(resp).To(BeNil())
Expect(err).To(HaveOccurred())
Expect(status.Code(err)).To(Equal(codes.Internal))
Expect(err.Error()).To(ContainSubstring("failed to initialize object storage provider S3 client"))
})

It("should return InvalidArgument error for unsupported client type", func(ctx SpecContext) {
driver.InitializeClient = func(ctx context.Context, clientset kubernetes.Interface, parameters map[string]string, service string) (interface{}, *util.StorageClientParameters, error) {
return &struct{}{}, &s3Params, nil
}

resp, err := provisioner.DriverDeleteBucket(ctx, request)
Expect(resp).To(BeNil())
Expect(err).To(HaveOccurred())
Expect(status.Code(err)).To(Equal(codes.InvalidArgument))
Expect(err.Error()).To(ContainSubstring("unsupported client type for bucket deletion"))
})

It("should return error if unable to delete bucket", func(ctx SpecContext) {
mockS3Client.DeleteBucketFunc = func(ctx context.Context, input *s3.DeleteBucketInput, opts ...func(*s3.Options)) (*s3.DeleteBucketOutput, error) {
return nil, fmt.Errorf("mock failure: unable to delete bucket")
}

resp, err := provisioner.DriverDeleteBucket(ctx, request)
Expect(resp).To(BeNil())
Expect(err).To(HaveOccurred())
Expect(status.Code(err)).To(Equal(codes.Internal))
Expect(err.Error()).To(ContainSubstring("failed to delete bucket"))
})
})
9 changes: 9 additions & 0 deletions pkg/mock/mock_s3.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
// MockS3Client simulates the behavior of an S3 client for testing.
type MockS3Client struct {
CreateBucketFunc func(ctx context.Context, input *s3.CreateBucketInput, opts ...func(*s3.Options)) (*s3.CreateBucketOutput, error)
DeleteBucketFunc func(ctx context.Context, input *s3.DeleteBucketInput, opts ...func(*s3.Options)) (*s3.DeleteBucketOutput, error)
}

// CreateBucket executes the mock CreateBucketFunc if defined, otherwise returns a default response.
Expand All @@ -18,3 +19,11 @@ func (m *MockS3Client) CreateBucket(ctx context.Context, input *s3.CreateBucketI
}
return &s3.CreateBucketOutput{}, nil
}

// DeleteBucket executes the mock DeleteBucketFunc if defined, otherwise returns a default response.
func (m *MockS3Client) DeleteBucket(ctx context.Context, input *s3.DeleteBucketInput, opts ...func(*s3.Options)) (*s3.DeleteBucketOutput, error) {
if m.DeleteBucketFunc != nil {
return m.DeleteBucketFunc(ctx, input, opts...)
}
return &s3.DeleteBucketOutput{}, nil
}

0 comments on commit 056509d

Please sign in to comment.