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 }