From 85f47d18416471955dc58d00af0fcb3376143b40 Mon Sep 17 00:00:00 2001 From: Simon Beck Date: Mon, 4 Sep 2023 11:00:13 +0200 Subject: [PATCH] Add unit tests for webhooks --- operator/user/webhook.go | 23 +++-- operator/user/webhook_test.go | 152 ++++++++++++++++++++++++++++++++-- 2 files changed, 164 insertions(+), 11 deletions(-) diff --git a/operator/user/webhook.go b/operator/user/webhook.go index 1254012..0dc826d 100644 --- a/operator/user/webhook.go +++ b/operator/user/webhook.go @@ -2,6 +2,7 @@ package user import ( "context" + "encoding/json" "fmt" "github.com/go-logr/logr" @@ -14,7 +15,15 @@ import ( "sigs.k8s.io/controller-runtime/pkg/webhook/admission" ) -var _ admission.CustomValidator = &Validator{} +var ( + _ admission.CustomValidator = &Validator{} + getProviderConfigFn = getProviderConfig + getMinioAdminFn = getMinioAdmin +) + +type cannedPolicyLister interface { + ListCannedPolicies(context.Context) (map[string]json.RawMessage, error) +} // Validator validates admission requests. type Validator struct { @@ -86,12 +95,12 @@ func (v *Validator) doesPolicyExist(ctx context.Context, user *miniov1.User) err return nil } - config, err := v.getProviderConfig(ctx, user) + config, err := getProviderConfigFn(ctx, user, v.kube) if err != nil { return err } - ma, err := minioutil.NewMinioAdmin(ctx, v.kube, config) + ma, err := getMinioAdminFn(ctx, v.kube, config) if err != nil { return err } @@ -111,9 +120,13 @@ func (v *Validator) doesPolicyExist(ctx context.Context, user *miniov1.User) err return nil } -func (v *Validator) getProviderConfig(ctx context.Context, user *miniov1.User) (*providerv1.ProviderConfig, error) { +func getProviderConfig(ctx context.Context, user *miniov1.User, kube client.Client) (*providerv1.ProviderConfig, error) { configName := user.GetProviderConfigReference().Name config := &providerv1.ProviderConfig{} - err := v.kube.Get(ctx, client.ObjectKey{Name: configName}, config) + err := kube.Get(ctx, client.ObjectKey{Name: configName}, config) return config, err } + +func getMinioAdmin(ctx context.Context, kube client.Client, config *providerv1.ProviderConfig) (cannedPolicyLister, error) { + return minioutil.NewMinioAdmin(ctx, kube, config) +} diff --git a/operator/user/webhook_test.go b/operator/user/webhook_test.go index 2efe2af..a005d4f 100644 --- a/operator/user/webhook_test.go +++ b/operator/user/webhook_test.go @@ -2,18 +2,26 @@ package user import ( "context" + "encoding/json" "testing" xpv1 "github.com/crossplane/crossplane-runtime/apis/common/v1" "github.com/go-logr/logr" miniov1 "github.com/vshn/provider-minio/apis/minio/v1" + providerv1 "github.com/vshn/provider-minio/apis/provider/v1" + "sigs.k8s.io/controller-runtime/pkg/client" ) +type mockAdminClient struct { + policies map[string]json.RawMessage +} + func TestValidator_ValidateCreate(t *testing.T) { tests := []struct { - name string - obj *miniov1.User - wantErr bool + name string + obj *miniov1.User + wantErr bool + wantPolicies map[string]json.RawMessage }{ { name: "GivenValidObject_ThenNoError", @@ -32,8 +40,51 @@ func TestValidator_ValidateCreate(t *testing.T) { wantErr: true, obj: &miniov1.User{}, }, + { + name: "GivenNotExistingPolicies_ThenError", + wantErr: true, + obj: &miniov1.User{ + Spec: miniov1.UserSpec{ + ForProvider: miniov1.UserParameters{ + Policies: []string{ + "foo", + }, + }, + ResourceSpec: xpv1.ResourceSpec{ + ProviderConfigReference: &xpv1.Reference{ + Name: "test", + }, + }, + }, + }, + }, + { + name: "GivenExistingPolicies_ThenNoError", + obj: &miniov1.User{ + Spec: miniov1.UserSpec{ + ForProvider: miniov1.UserParameters{ + Policies: []string{ + "foo", + }, + }, + ResourceSpec: xpv1.ResourceSpec{ + ProviderConfigReference: &xpv1.Reference{ + Name: "test", + }, + }, + }, + }, + wantPolicies: map[string]json.RawMessage{ + "foo": []byte("foo"), + }, + }, } + for _, tt := range tests { + + getMinioAdminFn = getMockMinioAdmin(tt.wantPolicies) + getProviderConfigFn = getMockProviderConfig + t.Run(tt.name, func(t *testing.T) { v := &Validator{ log: logr.Discard(), @@ -44,6 +95,10 @@ func TestValidator_ValidateCreate(t *testing.T) { return } }) + + getMinioAdminFn = getMinioAdmin + getProviderConfigFn = getProviderConfig + } } @@ -53,13 +108,15 @@ func TestValidator_ValidateUpdate(t *testing.T) { newObj *miniov1.User } tests := []struct { - name string - args args - wantErr bool + name string + args args + wantErr bool + wantPolicies map[string]json.RawMessage }{ { name: "GivenSameObject_ThenNoError", args: args{ + oldObj: &miniov1.User{ Spec: miniov1.UserSpec{ ResourceSpec: xpv1.ResourceSpec{ @@ -130,8 +187,72 @@ func TestValidator_ValidateUpdate(t *testing.T) { }, }, }, + { + name: "GivenNotExistingPolicies_ThenError", + wantErr: true, + args: args{ + oldObj: &miniov1.User{ + Spec: miniov1.UserSpec{ + ResourceSpec: xpv1.ResourceSpec{ + ProviderConfigReference: &xpv1.Reference{ + Name: "provider", + }, + }, + }, + }, + newObj: &miniov1.User{ + Spec: miniov1.UserSpec{ + ForProvider: miniov1.UserParameters{ + Policies: []string{ + "foo", + }, + }, + ResourceSpec: xpv1.ResourceSpec{ + ProviderConfigReference: &xpv1.Reference{ + Name: "test", + }, + }, + }, + }, + }, + }, + { + name: "GivenExistingPolicies_ThenNoError", + args: args{ + oldObj: &miniov1.User{ + Spec: miniov1.UserSpec{ + ResourceSpec: xpv1.ResourceSpec{ + ProviderConfigReference: &xpv1.Reference{ + Name: "provider", + }, + }, + }, + }, + newObj: &miniov1.User{ + Spec: miniov1.UserSpec{ + ForProvider: miniov1.UserParameters{ + Policies: []string{ + "foo", + }, + }, + ResourceSpec: xpv1.ResourceSpec{ + ProviderConfigReference: &xpv1.Reference{ + Name: "test", + }, + }, + }, + }, + }, + wantPolicies: map[string]json.RawMessage{ + "foo": []byte("foo"), + }, + }, } for _, tt := range tests { + + getMinioAdminFn = getMockMinioAdmin(tt.wantPolicies) + getProviderConfigFn = getMockProviderConfig + t.Run(tt.name, func(t *testing.T) { v := &Validator{ log: logr.Discard(), @@ -143,5 +264,24 @@ func TestValidator_ValidateUpdate(t *testing.T) { } }) + + getMinioAdminFn = getMinioAdmin + getProviderConfigFn = getProviderConfig + } +} + +func getMockProviderConfig(context.Context, *miniov1.User, client.Client) (*providerv1.ProviderConfig, error) { + return &providerv1.ProviderConfig{}, nil +} + +func getMockMinioAdmin(policies map[string]json.RawMessage) func(context.Context, client.Client, *providerv1.ProviderConfig) (cannedPolicyLister, error) { + return func(context.Context, client.Client, *providerv1.ProviderConfig) (cannedPolicyLister, error) { + return &mockAdminClient{ + policies: policies, + }, nil } } + +func (m *mockAdminClient) ListCannedPolicies(ctx context.Context) (map[string]json.RawMessage, error) { + return m.policies, nil +}