sigs.k8s.io/cluster-api@v1.7.1/internal/controllers/topology/cluster/patches/external/external_patch_generator_test.go (about)

     1  /*
     2  Copyright 2022 The Kubernetes Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package external
    18  
    19  import (
    20  	"context"
    21  	"testing"
    22  
    23  	. "github.com/onsi/gomega"
    24  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    25  	utilfeature "k8s.io/component-base/featuregate/testing"
    26  	"k8s.io/utils/ptr"
    27  
    28  	clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1"
    29  	runtimev1 "sigs.k8s.io/cluster-api/exp/runtime/api/v1alpha1"
    30  	runtimecatalog "sigs.k8s.io/cluster-api/exp/runtime/catalog"
    31  	runtimehooksv1 "sigs.k8s.io/cluster-api/exp/runtime/hooks/api/v1alpha1"
    32  	"sigs.k8s.io/cluster-api/feature"
    33  	runtimeclient "sigs.k8s.io/cluster-api/internal/runtime/client"
    34  )
    35  
    36  func TestExternalPatchGenerator_Generate(t *testing.T) {
    37  	defer utilfeature.SetFeatureGateDuringTest(t, feature.Gates, feature.RuntimeSDK, true)()
    38  
    39  	ctx := context.Background()
    40  	tests := []struct {
    41  		name          string
    42  		runtimeClient *fakeRuntimeClient
    43  		patch         *clusterv1.ClusterClassPatch
    44  		request       *runtimehooksv1.GeneratePatchesRequest
    45  		assertRequest func(g *WithT, actualRequest runtimehooksv1.RequestObject)
    46  	}{
    47  		{
    48  			name:          "Request should not have any settings if there are no settings in external patch definition",
    49  			runtimeClient: &fakeRuntimeClient{},
    50  			patch: &clusterv1.ClusterClassPatch{
    51  				Name:        "",
    52  				Description: "",
    53  				EnabledIf:   nil,
    54  				Definitions: nil,
    55  				External: &clusterv1.ExternalPatchDefinition{
    56  					GenerateExtension: ptr.To("test-generate-extension"),
    57  					Settings:          nil,
    58  				},
    59  			},
    60  			request: &runtimehooksv1.GeneratePatchesRequest{},
    61  			assertRequest: func(g *WithT, actualRequest runtimehooksv1.RequestObject) {
    62  				actualSettings := actualRequest.GetSettings()
    63  				g.Expect(actualSettings).To(BeNil())
    64  			},
    65  		},
    66  		{
    67  			name:          "Request should have setting if setting are defined in external path definition",
    68  			runtimeClient: &fakeRuntimeClient{},
    69  			patch: &clusterv1.ClusterClassPatch{
    70  				Name:        "",
    71  				Description: "",
    72  				EnabledIf:   nil,
    73  				Definitions: nil,
    74  				External: &clusterv1.ExternalPatchDefinition{
    75  					GenerateExtension: ptr.To("test-generate-extension"),
    76  					Settings: map[string]string{
    77  						"key1": "value1",
    78  					},
    79  				},
    80  			},
    81  			request: &runtimehooksv1.GeneratePatchesRequest{},
    82  			assertRequest: func(g *WithT, actualRequest runtimehooksv1.RequestObject) {
    83  				actualSettings := actualRequest.GetSettings()
    84  				expectedSettings := map[string]string{
    85  					"key1": "value1",
    86  				}
    87  				g.Expect(actualSettings).To(Equal(expectedSettings))
    88  			},
    89  		},
    90  	}
    91  
    92  	for _, tt := range tests {
    93  		t.Run(tt.name, func(t *testing.T) {
    94  			g := NewWithT(t)
    95  			externalPatchGenerator := NewGenerator(tt.runtimeClient, tt.patch)
    96  			_, _ = externalPatchGenerator.Generate(ctx, &clusterv1.Cluster{}, tt.request)
    97  			tt.assertRequest(g, tt.runtimeClient.callExtensionRequest)
    98  		})
    99  	}
   100  }
   101  
   102  var _ runtimeclient.Client = &fakeRuntimeClient{}
   103  
   104  type fakeRuntimeClient struct {
   105  	callExtensionRequest runtimehooksv1.RequestObject
   106  }
   107  
   108  func (f *fakeRuntimeClient) WarmUp(_ *runtimev1.ExtensionConfigList) error {
   109  	panic("implement me")
   110  }
   111  
   112  func (f *fakeRuntimeClient) IsReady() bool {
   113  	panic("implement me")
   114  }
   115  
   116  func (f *fakeRuntimeClient) Discover(_ context.Context, _ *runtimev1.ExtensionConfig) (*runtimev1.ExtensionConfig, error) {
   117  	panic("implement me")
   118  }
   119  
   120  func (f *fakeRuntimeClient) Register(_ *runtimev1.ExtensionConfig) error {
   121  	panic("implement me")
   122  }
   123  
   124  func (f *fakeRuntimeClient) Unregister(_ *runtimev1.ExtensionConfig) error {
   125  	panic("implement me")
   126  }
   127  
   128  func (f *fakeRuntimeClient) CallAllExtensions(_ context.Context, _ runtimecatalog.Hook, _ metav1.Object, _ runtimehooksv1.RequestObject, _ runtimehooksv1.ResponseObject) error {
   129  	panic("implement me")
   130  }
   131  
   132  func (f *fakeRuntimeClient) CallExtension(_ context.Context, _ runtimecatalog.Hook, _ metav1.Object, _ string, request runtimehooksv1.RequestObject, _ runtimehooksv1.ResponseObject) error {
   133  	// Keep a copy of the request object.
   134  	// We keep a copy because the request is modified after the call is made. So we keep a copy to perform assertions.
   135  	f.callExtensionRequest = request.DeepCopyObject().(runtimehooksv1.RequestObject)
   136  	return nil
   137  }