From 8b756c6d363814c6addfed773e6e8bbd4c42ed41 Mon Sep 17 00:00:00 2001 From: Anurag Mittal Date: Fri, 13 Sep 2024 09:02:37 +0200 Subject: [PATCH] Added Tests for helped not implemented method --- go.mod | 7 ++- go.sum | 3 + pkg/driver/provisioner.go | 4 +- pkg/driver/provisioner_test.go | 108 ++++++++++++++++++++++++++------- 4 files changed, 96 insertions(+), 26 deletions(-) diff --git a/go.mod b/go.mod index 95d9002..4358a8c 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,7 @@ module github.com/scality/cosi go 1.22.6 require ( + github.com/golang/mock v1.6.0 github.com/stretchr/testify v1.9.0 google.golang.org/grpc v1.66.0 k8s.io/client-go v0.31.0 @@ -13,8 +14,8 @@ require ( ) require ( - github.com/golang/mock v1.6.0 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect + gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect ) require ( @@ -52,8 +53,8 @@ require ( gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - k8s.io/api v0.31.0 // indirect - k8s.io/apimachinery v0.31.0 // indirect + k8s.io/api v0.31.0 + k8s.io/apimachinery v0.31.0 k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 // indirect k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 // indirect sigs.k8s.io/controller-runtime v0.12.3 // indirect diff --git a/go.sum b/go.sum index e7917a7..f1c344a 100644 --- a/go.sum +++ b/go.sum @@ -42,6 +42,7 @@ github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= +github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8= github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= @@ -152,6 +153,8 @@ google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWn gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/evanphx/json-patch.v4 v4.12.0 h1:n6jtcsulIzXPJaxegRbvFNNrZDjbij7ny3gmSPG+6V4= +gopkg.in/evanphx/json-patch.v4 v4.12.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= diff --git a/pkg/driver/provisioner.go b/pkg/driver/provisioner.go index ae527e9..24a2f0b 100644 --- a/pkg/driver/provisioner.go +++ b/pkg/driver/provisioner.go @@ -34,7 +34,7 @@ import ( type provisionerServer struct { Provisioner string - Clientset *kubernetes.Clientset + Clientset kubernetes.Interface KubeConfig *rest.Config BucketClientset bucketclientset.Interface } @@ -168,7 +168,7 @@ func (s *provisionerServer) DriverRevokeBucketAccess(ctx context.Context, return nil, status.Error(codes.Unimplemented, "DriverRevokeBucketAccess: not implemented") } -func initializeObjectStorageProviderClients(ctx context.Context, clientset *kubernetes.Clientset, parameters map[string]string) (*s3client.S3Client, error) { +func initializeObjectStorageProviderClients(ctx context.Context, clientset kubernetes.Interface, parameters map[string]string) (*s3client.S3Client, error) { klog.V(3).InfoS("Initializing object storage provider clients", "parameters", parameters) ospSecretName, namespace, err := fetchObjectStorageProviderSecretInfo(parameters) diff --git a/pkg/driver/provisioner_test.go b/pkg/driver/provisioner_test.go index 53efc77..f7f1f96 100644 --- a/pkg/driver/provisioner_test.go +++ b/pkg/driver/provisioner_test.go @@ -9,11 +9,16 @@ import ( "github.com/aws/aws-sdk-go/service/s3" "github.com/golang/mock/gomock" s3client "github.com/scality/cosi/pkg/util/s3client" - mock_s3iface "github.com/scality/cosi/pkg/util/s3client/mock" // Import the generated mock + mock_s3iface "github.com/scality/cosi/pkg/util/s3client/mock" "github.com/stretchr/testify/assert" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" + v1 "k8s.io/api/core/v1" // For Kubernetes Secret and other core types + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" // For metadata such as ObjectMeta + "k8s.io/apimachinery/pkg/runtime" // For runtime.Object "k8s.io/client-go/kubernetes" + "k8s.io/client-go/kubernetes/fake" // For creating the fake Kubernetes client + ktesting "k8s.io/client-go/testing" // Aliased to avoid conflict with testing package cosispec "sigs.k8s.io/container-object-storage-interface-spec" ) @@ -29,7 +34,7 @@ func TestDriverCreateBucket_Success(t *testing.T) { mockS3.EXPECT().CreateBucket(gomock.Any()).Return(nil, nil).Times(1) // Mock the initializeObjectStorageProviderClients function to return the mock S3 client - initializeS3Client = func(ctx context.Context, clientset *kubernetes.Clientset, parameters map[string]string) (*s3client.S3Client, error) { + initializeS3Client = func(ctx context.Context, clientset kubernetes.Interface, parameters map[string]string) (*s3client.S3Client, error) { return &s3client.S3Client{S3Service: mockS3}, nil } defer func() { initializeS3Client = initializeObjectStorageProviderClients }() // Reset after the test @@ -43,19 +48,16 @@ func TestDriverCreateBucket_Success(t *testing.T) { // Call DriverCreateBucket resp, err := server.DriverCreateBucket(context.TODO(), req) - // Assert that no error occurred and the response is as expected assert.NoError(t, err) assert.NotNil(t, resp) assert.Equal(t, "test-bucket", resp.BucketId) } -// Test S3 client initialization failure func TestDriverCreateBucket_InitClientFailure(t *testing.T) { ctrl := gomock.NewController(t) defer ctrl.Finish() - // Mock initializeObjectStorageProviderClients to return an error - initializeS3Client = func(ctx context.Context, clientset *kubernetes.Clientset, parameters map[string]string) (*s3client.S3Client, error) { + initializeS3Client = func(ctx context.Context, clientset kubernetes.Interface, parameters map[string]string) (*s3client.S3Client, error) { return nil, errors.New("failed to initialize S3 client") } defer func() { initializeS3Client = initializeObjectStorageProviderClients }() // Reset after the test @@ -66,29 +68,23 @@ func TestDriverCreateBucket_InitClientFailure(t *testing.T) { Name: "test-bucket", } - // Call DriverCreateBucket resp, err := server.DriverCreateBucket(context.TODO(), req) - // Assert the error is codes.Internal and no response assert.Nil(t, resp) assert.Error(t, err) assert.Equal(t, codes.Internal, status.Code(err)) } -// Test bucket already exists case func TestDriverCreateBucket_BucketAlreadyExists(t *testing.T) { ctrl := gomock.NewController(t) defer ctrl.Finish() - // Create a mock S3 client mockS3 := mock_s3iface.NewMockS3API(ctrl) - // Mock the S3 CreateBucket call to return bucket already exists error awsErr := awserr.New(s3.ErrCodeBucketAlreadyExists, "Bucket already exists", nil) mockS3.EXPECT().CreateBucket(gomock.Any()).Return(nil, awsErr).Times(1) - // Mock the initializeObjectStorageProviderClients function to return the mock S3 client - initializeS3Client = func(ctx context.Context, clientset *kubernetes.Clientset, parameters map[string]string) (*s3client.S3Client, error) { + initializeS3Client = func(ctx context.Context, clientset kubernetes.Interface, parameters map[string]string) (*s3client.S3Client, error) { return &s3client.S3Client{S3Service: mockS3}, nil } defer func() { initializeS3Client = initializeObjectStorageProviderClients }() // Reset after the test @@ -99,29 +95,24 @@ func TestDriverCreateBucket_BucketAlreadyExists(t *testing.T) { Name: "test-bucket", } - // Call DriverCreateBucket resp, err := server.DriverCreateBucket(context.TODO(), req) - // Assert the error is codes.AlreadyExists assert.Nil(t, resp) assert.Error(t, err) assert.Equal(t, codes.AlreadyExists, status.Code(err)) } -// Test bucket already owned by you case func TestDriverCreateBucket_BucketAlreadyOwnedByYou(t *testing.T) { ctrl := gomock.NewController(t) defer ctrl.Finish() - // Create a mock S3 client mockS3 := mock_s3iface.NewMockS3API(ctrl) - // Mock the S3 CreateBucket call to return bucket already owned by you error awsErr := awserr.New(s3.ErrCodeBucketAlreadyOwnedByYou, "Bucket already owned by you", nil) mockS3.EXPECT().CreateBucket(gomock.Any()).Return(nil, awsErr).Times(1) // Mock the initializeObjectStorageProviderClients function to return the mock S3 client - initializeS3Client = func(ctx context.Context, clientset *kubernetes.Clientset, parameters map[string]string) (*s3client.S3Client, error) { + initializeS3Client = func(ctx context.Context, clientset kubernetes.Interface, parameters map[string]string) (*s3client.S3Client, error) { return &s3client.S3Client{S3Service: mockS3}, nil } defer func() { initializeS3Client = initializeObjectStorageProviderClients }() // Reset after the test @@ -132,11 +123,86 @@ func TestDriverCreateBucket_BucketAlreadyOwnedByYou(t *testing.T) { Name: "test-bucket", } - // Call DriverCreateBucket resp, err := server.DriverCreateBucket(context.TODO(), req) - // Assert the error is codes.AlreadyExists assert.Nil(t, resp) assert.Error(t, err) assert.Equal(t, codes.AlreadyExists, status.Code(err)) } + +func TestDriverDeleteBucket_Unimplemented(t *testing.T) { + server := &provisionerServer{} + + req := &cosispec.DriverDeleteBucketRequest{ + BucketId: "test-bucket", + } + + resp, err := server.DriverDeleteBucket(context.TODO(), req) + + assert.Nil(t, resp) + assert.Error(t, err) + assert.Equal(t, codes.Unimplemented, status.Code(err)) +} + +func TestDriverGrantBucketAccess_Unimplemented(t *testing.T) { + server := &provisionerServer{} + + req := &cosispec.DriverGrantBucketAccessRequest{ + BucketId: "test-bucket", + } + + resp, err := server.DriverGrantBucketAccess(context.TODO(), req) + + assert.Nil(t, resp) + assert.Error(t, err) + assert.Equal(t, codes.Unimplemented, status.Code(err)) +} + +func TestDriverRevokeBucketAccess_Unimplemented(t *testing.T) { + server := &provisionerServer{} + + req := &cosispec.DriverRevokeBucketAccessRequest{ + BucketId: "test-bucket", + } + + resp, err := server.DriverRevokeBucketAccess(context.TODO(), req) + + assert.Nil(t, resp) + assert.Error(t, err) + assert.Equal(t, codes.Unimplemented, status.Code(err)) +} + +// Test initializeObjectStorageProviderClients with successful secret fetch +func TestInitializeObjectStorageProviderClients_Success(t *testing.T) { + // Use a fake Kubernetes client instead of NewForConfigOrDie(nil) + fakeClientset := fake.NewSimpleClientset() + + // Add a fake secret to the client + secret := &v1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-secret", + Namespace: "test-namespace", + }, + Data: map[string][]byte{ + "COSI_S3_ACCESS_KEY_ID": []byte("access-key"), + "COSI_S3_ACCESS_SECRET_KEY": []byte("secret-key"), + "COSI_S3_ENDPOINT": []byte("http://localhost"), + "COSI_S3_REGION": []byte("us-west-1"), + }, + } + + // Mock the secret retrieval + fakeClientset.PrependReactor("get", "secrets", func(action ktesting.Action) (handled bool, ret runtime.Object, err error) { + return true, secret, nil + }) + + // Call initializeObjectStorageProviderClients with the fake client + parameters := map[string]string{ + "COSI_OBJECT_STORAGE_PROVIDER_SECRET_NAME": "test-secret", + "COSI_OBJECT_STORAGE_PROVIDER_SECRET_NAMESPACE": "test-namespace", + } + client, err := initializeObjectStorageProviderClients(context.TODO(), fakeClientset, parameters) + + assert.NoError(t, err) + assert.NotNil(t, client) +}