sigs.k8s.io/cluster-api-provider-azure@v1.14.3/exp/api/v1beta1/azuremachinepool_test.go (about)

     1  /*
     2  Copyright 2021 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 v1beta1_test
    18  
    19  import (
    20  	"testing"
    21  
    22  	"github.com/onsi/gomega"
    23  	utilfeature "k8s.io/component-base/featuregate/testing"
    24  	"k8s.io/utils/ptr"
    25  	infrav1 "sigs.k8s.io/cluster-api-provider-azure/api/v1beta1"
    26  	infrav1exp "sigs.k8s.io/cluster-api-provider-azure/exp/api/v1beta1"
    27  	"sigs.k8s.io/cluster-api-provider-azure/feature"
    28  	capifeature "sigs.k8s.io/cluster-api/feature"
    29  )
    30  
    31  func TestAzureMachinePool_Validate(t *testing.T) {
    32  	cases := []struct {
    33  		Name    string
    34  		Factory func(g *gomega.GomegaWithT) *infrav1exp.AzureMachinePool
    35  		Expect  func(g *gomega.GomegaWithT, actual error)
    36  	}{
    37  		{
    38  			Name: "HasNoImage",
    39  			Factory: func(_ *gomega.GomegaWithT) *infrav1exp.AzureMachinePool {
    40  				return new(infrav1exp.AzureMachinePool)
    41  			},
    42  			Expect: func(g *gomega.GomegaWithT, actual error) {
    43  				g.Expect(actual).NotTo(gomega.HaveOccurred())
    44  			},
    45  		},
    46  		{
    47  			Name: "HasValidImage",
    48  			Factory: func(_ *gomega.GomegaWithT) *infrav1exp.AzureMachinePool {
    49  				return &infrav1exp.AzureMachinePool{
    50  					Spec: infrav1exp.AzureMachinePoolSpec{
    51  						Template: infrav1exp.AzureMachinePoolMachineTemplate{
    52  							Image: &infrav1.Image{
    53  								SharedGallery: &infrav1.AzureSharedGalleryImage{
    54  									SubscriptionID: "foo",
    55  									ResourceGroup:  "blah",
    56  									Name:           "bin",
    57  									Gallery:        "bazz",
    58  									Version:        "1.2.3",
    59  								},
    60  							},
    61  						},
    62  					},
    63  				}
    64  			},
    65  			Expect: func(g *gomega.GomegaWithT, actual error) {
    66  				g.Expect(actual).NotTo(gomega.HaveOccurred())
    67  			},
    68  		},
    69  		{
    70  			Name: "HasInvalidImage",
    71  			Factory: func(_ *gomega.GomegaWithT) *infrav1exp.AzureMachinePool {
    72  				return &infrav1exp.AzureMachinePool{
    73  					Spec: infrav1exp.AzureMachinePoolSpec{
    74  						Template: infrav1exp.AzureMachinePoolMachineTemplate{
    75  							Image: new(infrav1.Image),
    76  						},
    77  					},
    78  				}
    79  			},
    80  			Expect: func(g *gomega.GomegaWithT, actual error) {
    81  				g.Expect(actual).To(gomega.HaveOccurred())
    82  				g.Expect(actual.Error()).To(gomega.ContainSubstring("You must supply an ID, Marketplace or ComputeGallery image details"))
    83  			},
    84  		},
    85  		{
    86  			Name: "HasValidTerminateNotificationTimeout",
    87  			Factory: func(_ *gomega.GomegaWithT) *infrav1exp.AzureMachinePool {
    88  				return &infrav1exp.AzureMachinePool{
    89  					Spec: infrav1exp.AzureMachinePoolSpec{
    90  						Template: infrav1exp.AzureMachinePoolMachineTemplate{
    91  							TerminateNotificationTimeout: ptr.To(7),
    92  						},
    93  					},
    94  				}
    95  			},
    96  			Expect: func(g *gomega.GomegaWithT, actual error) {
    97  				g.Expect(actual).NotTo(gomega.HaveOccurred())
    98  			},
    99  		},
   100  		{
   101  			Name: "HasInvalidMaximumTerminateNotificationTimeout",
   102  			Factory: func(_ *gomega.GomegaWithT) *infrav1exp.AzureMachinePool {
   103  				return &infrav1exp.AzureMachinePool{
   104  					Spec: infrav1exp.AzureMachinePoolSpec{
   105  						Template: infrav1exp.AzureMachinePoolMachineTemplate{
   106  							TerminateNotificationTimeout: ptr.To(20),
   107  						},
   108  					},
   109  				}
   110  			},
   111  			Expect: func(g *gomega.GomegaWithT, actual error) {
   112  				g.Expect(actual).To(gomega.HaveOccurred())
   113  				g.Expect(actual.Error()).To(gomega.ContainSubstring("maximum timeout 15 is allowed for TerminateNotificationTimeout"))
   114  			},
   115  		},
   116  		{
   117  			Name: "HasInvalidMinimumTerminateNotificationTimeout",
   118  			Factory: func(_ *gomega.GomegaWithT) *infrav1exp.AzureMachinePool {
   119  				return &infrav1exp.AzureMachinePool{
   120  					Spec: infrav1exp.AzureMachinePoolSpec{
   121  						Template: infrav1exp.AzureMachinePoolMachineTemplate{
   122  							TerminateNotificationTimeout: ptr.To(3),
   123  						},
   124  					},
   125  				}
   126  			},
   127  			Expect: func(g *gomega.GomegaWithT, actual error) {
   128  				g.Expect(actual).To(gomega.HaveOccurred())
   129  				g.Expect(actual.Error()).To(gomega.ContainSubstring("minimum timeout 5 is allowed for TerminateNotificationTimeout"))
   130  			},
   131  		},
   132  		{
   133  			Name: "HasNoDiagnostics",
   134  			Factory: func(_ *gomega.GomegaWithT) *infrav1exp.AzureMachinePool {
   135  				return &infrav1exp.AzureMachinePool{
   136  					Spec: infrav1exp.AzureMachinePoolSpec{
   137  						Template: infrav1exp.AzureMachinePoolMachineTemplate{
   138  							Diagnostics: nil,
   139  						},
   140  					},
   141  				}
   142  			},
   143  			Expect: func(g *gomega.GomegaWithT, actual error) {
   144  				g.Expect(actual).NotTo(gomega.HaveOccurred())
   145  			},
   146  		},
   147  		{
   148  			Name: "HasValidDiagnostics",
   149  			Factory: func(_ *gomega.GomegaWithT) *infrav1exp.AzureMachinePool {
   150  				return &infrav1exp.AzureMachinePool{
   151  					Spec: infrav1exp.AzureMachinePoolSpec{
   152  						Template: infrav1exp.AzureMachinePoolMachineTemplate{
   153  							Diagnostics: &infrav1.Diagnostics{
   154  								Boot: &infrav1.BootDiagnostics{
   155  									StorageAccountType: infrav1.ManagedDiagnosticsStorage,
   156  								},
   157  							},
   158  						},
   159  					},
   160  				}
   161  			},
   162  			Expect: func(g *gomega.GomegaWithT, actual error) {
   163  				g.Expect(actual).NotTo(gomega.HaveOccurred())
   164  			},
   165  		},
   166  		{
   167  			Name: "HasMismatcingManagedDiagnosticsWithStorageAccountURI",
   168  			Factory: func(_ *gomega.GomegaWithT) *infrav1exp.AzureMachinePool {
   169  				return &infrav1exp.AzureMachinePool{
   170  					Spec: infrav1exp.AzureMachinePoolSpec{
   171  						Template: infrav1exp.AzureMachinePoolMachineTemplate{
   172  							Diagnostics: &infrav1.Diagnostics{
   173  								Boot: &infrav1.BootDiagnostics{
   174  									StorageAccountType: infrav1.ManagedDiagnosticsStorage,
   175  									UserManaged: &infrav1.UserManagedBootDiagnostics{
   176  										StorageAccountURI: "https://fake",
   177  									},
   178  								},
   179  							},
   180  						},
   181  					},
   182  				}
   183  			},
   184  			Expect: func(g *gomega.GomegaWithT, actual error) {
   185  				g.Expect(actual).To(gomega.HaveOccurred())
   186  			},
   187  		},
   188  		{
   189  			Name: "HasMismatcingDisabledDiagnosticsWithStorageAccountURI",
   190  			Factory: func(_ *gomega.GomegaWithT) *infrav1exp.AzureMachinePool {
   191  				return &infrav1exp.AzureMachinePool{
   192  					Spec: infrav1exp.AzureMachinePoolSpec{
   193  						Template: infrav1exp.AzureMachinePoolMachineTemplate{
   194  							Diagnostics: &infrav1.Diagnostics{
   195  								Boot: &infrav1.BootDiagnostics{
   196  									StorageAccountType: infrav1.DisabledDiagnosticsStorage,
   197  									UserManaged: &infrav1.UserManagedBootDiagnostics{
   198  										StorageAccountURI: "https://fake",
   199  									},
   200  								},
   201  							},
   202  						},
   203  					},
   204  				}
   205  			},
   206  			Expect: func(g *gomega.GomegaWithT, actual error) {
   207  				g.Expect(actual).To(gomega.HaveOccurred())
   208  			},
   209  		},
   210  	}
   211  
   212  	for _, c := range cases {
   213  		c := c
   214  		t.Run(c.Name, func(t *testing.T) {
   215  			// Don't add t.Parallel() here or the test will fail.
   216  			// NOTE: AzureMachinePool is behind MachinePool feature gate flag; the webhook
   217  			// must prevent creating new objects in case the feature flag is disabled.
   218  			defer utilfeature.SetFeatureGateDuringTest(t, feature.Gates, capifeature.MachinePool, true)()
   219  			g := gomega.NewGomegaWithT(t)
   220  			amp := c.Factory(g)
   221  			actualErr := amp.Validate(nil, nil)
   222  			c.Expect(g, actualErr)
   223  		})
   224  	}
   225  }