github.com/verrazzano/verrazzano@v1.7.0/platform-operator/controllers/configmaps/components/controller_test.go (about) 1 // Copyright (c) 2023, Oracle and/or its affiliates. 2 // Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. 3 4 package components 5 6 import ( 7 "context" 8 "fmt" 9 "github.com/verrazzano/verrazzano/platform-operator/controllers/verrazzano/component/verrazzano" 10 "testing" 11 12 helmcli "github.com/verrazzano/verrazzano/pkg/helm" 13 "github.com/verrazzano/verrazzano/pkg/log/vzlog" 14 "github.com/verrazzano/verrazzano/platform-operator/apis/verrazzano/v1alpha1" 15 vzapi "github.com/verrazzano/verrazzano/platform-operator/apis/verrazzano/v1beta1" 16 "github.com/verrazzano/verrazzano/platform-operator/constants" 17 "github.com/verrazzano/verrazzano/platform-operator/controllers/verrazzano/component/helm" 18 "github.com/verrazzano/verrazzano/platform-operator/internal/config" 19 "helm.sh/helm/v3/pkg/release" 20 21 "github.com/stretchr/testify/assert" 22 corev1 "k8s.io/api/core/v1" 23 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 24 "k8s.io/apimachinery/pkg/runtime" 25 "k8s.io/apimachinery/pkg/types" 26 controllerruntime "sigs.k8s.io/controller-runtime" 27 "sigs.k8s.io/controller-runtime/pkg/client" 28 "sigs.k8s.io/controller-runtime/pkg/client/fake" 29 ) 30 31 const ( 32 testBomFilePath = "../../verrazzano/testdata/test_bom.json" 33 ) 34 35 // TestConfigMapKindHelmReconciler tests the configMap Reconcile function for a correct and incorrect configmap 36 func TestConfigMapKindHelmReconciler(t *testing.T) { 37 asserts := assert.New(t) 38 39 tests := []struct { 40 name string 41 cm corev1.ConfigMap 42 err error 43 returnError bool 44 requeue bool 45 }{ 46 { 47 name: "successful installation", 48 cm: corev1.ConfigMap{ 49 ObjectMeta: metav1.ObjectMeta{ 50 Name: "test-component", 51 Namespace: constants.VerrazzanoInstallNamespace, 52 Labels: map[string]string{ 53 devComponentConfigMapKindLabel: devComponentConfigMapKindHelmComponent, 54 devComponentConfigMapAPIVersionLabel: devComponentConfigMapAPIVersionv1beta2, 55 }, 56 }, 57 Data: map[string]string{ 58 componentNameKey: "test-component", 59 chartPathKey: "test-component", 60 componentNamespaceKey: constants.VerrazzanoSystemNamespace, 61 overridesKey: "overrideKey: overrideVal", 62 }, 63 }, 64 returnError: false, 65 requeue: false, 66 }, 67 { 68 name: "configmap in wrong namespace", 69 cm: corev1.ConfigMap{ 70 ObjectMeta: metav1.ObjectMeta{ 71 Name: "test-component", 72 Namespace: constants.VerrazzanoSystemNamespace, 73 Labels: map[string]string{ 74 devComponentConfigMapKindLabel: devComponentConfigMapKindHelmComponent, 75 devComponentConfigMapAPIVersionLabel: devComponentConfigMapAPIVersionv1beta2, 76 }, 77 }, 78 Data: map[string]string{ 79 componentNameKey: "test-component", 80 chartPathKey: "test-component", 81 componentNamespaceKey: constants.VerrazzanoSystemNamespace, 82 overridesKey: "overrideKey: overrideVal", 83 }, 84 }, 85 returnError: true, 86 requeue: false, 87 }, 88 { 89 name: "no name", 90 cm: corev1.ConfigMap{ 91 ObjectMeta: metav1.ObjectMeta{ 92 Name: "test-component", 93 Namespace: constants.VerrazzanoInstallNamespace, 94 Labels: map[string]string{ 95 devComponentConfigMapKindLabel: devComponentConfigMapKindHelmComponent, 96 devComponentConfigMapAPIVersionLabel: devComponentConfigMapAPIVersionv1beta2, 97 }, 98 }, 99 Data: map[string]string{ 100 chartPathKey: "test-component", 101 componentNamespaceKey: constants.VerrazzanoSystemNamespace, 102 overridesKey: "overrideKey: overrideVal", 103 }, 104 }, 105 returnError: true, 106 requeue: false, 107 }, 108 { 109 name: "no chart path", 110 cm: corev1.ConfigMap{ 111 ObjectMeta: metav1.ObjectMeta{ 112 Name: "test-component", 113 Namespace: constants.VerrazzanoInstallNamespace, 114 Labels: map[string]string{ 115 devComponentConfigMapKindLabel: devComponentConfigMapKindHelmComponent, 116 devComponentConfigMapAPIVersionLabel: devComponentConfigMapAPIVersionv1beta2, 117 }, 118 }, 119 Data: map[string]string{ 120 componentNameKey: "test-component", 121 componentNamespaceKey: constants.VerrazzanoSystemNamespace, 122 overridesKey: "overrideKey: overrideVal", 123 }, 124 }, 125 returnError: true, 126 requeue: false, 127 }, 128 { 129 name: "no namespace", 130 cm: corev1.ConfigMap{ 131 ObjectMeta: metav1.ObjectMeta{ 132 Name: "test-component", 133 Namespace: constants.VerrazzanoInstallNamespace, 134 Labels: map[string]string{ 135 devComponentConfigMapKindLabel: devComponentConfigMapKindHelmComponent, 136 devComponentConfigMapAPIVersionLabel: devComponentConfigMapAPIVersionv1beta2, 137 }, 138 }, 139 Data: map[string]string{ 140 componentNameKey: "test-component", 141 chartPathKey: "test-component", 142 overridesKey: "overrideKey: overrideVal", 143 }, 144 }, 145 returnError: true, 146 requeue: false, 147 }, 148 } 149 150 for _, tt := range tests { 151 t.Run(tt.name, func(t *testing.T) { 152 config.SetDefaultBomFilePath(testBomFilePath) 153 helm.SetUpgradeFunc(fakeUpgrade) 154 defer helm.SetDefaultUpgradeFunc() 155 config.TestProfilesDir = "../../../manifests/profiles" 156 defer func() { config.TestProfilesDir = "" }() 157 158 cli := buildFakeClient(tt.cm) 159 160 req := newRequest(tt.cm.Namespace, tt.cm.Name) 161 reconciler := newConfigMapReconciler(cli) 162 res, err := reconciler.Reconcile(context.TODO(), req) 163 164 if tt.returnError { 165 assert.Error(t, err) 166 } else { 167 assert.Nil(t, err) 168 } 169 170 asserts.Equal(tt.requeue, res.Requeue) 171 172 }) 173 } 174 } 175 176 // TestConfigMapKindShimReconciler tests the configMap Reconcile function for a correct and incorrect configmap 177 func TestConfigMapKindShimReconciler(t *testing.T) { 178 asserts := assert.New(t) 179 180 tests := []struct { 181 name string 182 cm corev1.ConfigMap 183 err error 184 returnError bool 185 requeue bool 186 init bool 187 }{ 188 { 189 name: "successful installation", 190 cm: corev1.ConfigMap{ 191 ObjectMeta: metav1.ObjectMeta{ 192 Name: "test-component", 193 Namespace: constants.VerrazzanoInstallNamespace, 194 Labels: map[string]string{ 195 devComponentConfigMapKindLabel: devComponentConfigMapKindShimComponent, 196 devComponentConfigMapAPIVersionLabel: devComponentConfigMapAPIVersionv1beta2, 197 }, 198 }, 199 Data: map[string]string{ 200 componentNameKey: "verrazzano", 201 }, 202 }, 203 init: true, 204 returnError: false, 205 requeue: false, 206 }, 207 { 208 name: "component not found", 209 cm: corev1.ConfigMap{ 210 ObjectMeta: metav1.ObjectMeta{ 211 Name: "test-component", 212 Namespace: constants.VerrazzanoInstallNamespace, 213 Labels: map[string]string{ 214 devComponentConfigMapKindLabel: devComponentConfigMapKindShimComponent, 215 devComponentConfigMapAPIVersionLabel: devComponentConfigMapAPIVersionv1beta2, 216 }, 217 }, 218 Data: map[string]string{ 219 componentNameKey: "test-component", 220 }, 221 }, 222 init: false, 223 returnError: true, 224 requeue: false, 225 }, 226 { 227 name: "configmap in wrong namespace", 228 cm: corev1.ConfigMap{ 229 ObjectMeta: metav1.ObjectMeta{ 230 Name: "test-component", 231 Namespace: constants.VerrazzanoSystemNamespace, 232 Labels: map[string]string{ 233 devComponentConfigMapKindLabel: devComponentConfigMapKindShimComponent, 234 devComponentConfigMapAPIVersionLabel: devComponentConfigMapAPIVersionv1beta2, 235 }, 236 }, 237 Data: map[string]string{ 238 componentNameKey: "test-component", 239 }, 240 }, 241 init: false, 242 returnError: true, 243 requeue: false, 244 }, 245 { 246 name: "no name", 247 cm: corev1.ConfigMap{ 248 ObjectMeta: metav1.ObjectMeta{ 249 Name: "test-component", 250 Namespace: constants.VerrazzanoInstallNamespace, 251 Labels: map[string]string{ 252 devComponentConfigMapKindLabel: devComponentConfigMapKindShimComponent, 253 devComponentConfigMapAPIVersionLabel: devComponentConfigMapAPIVersionv1beta2, 254 }, 255 }, 256 Data: map[string]string{}, 257 }, 258 init: false, 259 returnError: true, 260 requeue: false, 261 }, 262 { 263 name: "invalid map kind", 264 cm: corev1.ConfigMap{ 265 ObjectMeta: metav1.ObjectMeta{ 266 Name: "test-component", 267 Namespace: constants.VerrazzanoInstallNamespace, 268 Labels: map[string]string{ 269 devComponentConfigMapKindLabel: "invalid-kind", 270 devComponentConfigMapAPIVersionLabel: devComponentConfigMapAPIVersionv1beta2, 271 }, 272 }, 273 Data: map[string]string{ 274 componentNameKey: "test-component", 275 }, 276 }, 277 init: false, 278 returnError: true, 279 requeue: false, 280 }, 281 } 282 283 for _, tt := range tests { 284 t.Run(tt.name, func(t *testing.T) { 285 config.SetDefaultBomFilePath(testBomFilePath) 286 helm.SetUpgradeFunc(fakeUpgrade) 287 defer helm.SetDefaultUpgradeFunc() 288 config.TestProfilesDir = "../../../manifests/profiles" 289 defer func() { config.TestProfilesDir = "" }() 290 291 cli := buildFakeClient(tt.cm) 292 293 if tt.init { 294 shimComponents[verrazzano.ComponentName] = verrazzano.NewComponent() 295 } 296 req := newRequest(tt.cm.Namespace, tt.cm.Name) 297 reconciler := newConfigMapReconciler(cli) 298 res, err := reconciler.Reconcile(context.TODO(), req) 299 300 if tt.returnError { 301 assert.Error(t, err) 302 } else { 303 assert.Nil(t, err) 304 } 305 306 asserts.Equal(tt.requeue, res.Requeue) 307 308 }) 309 } 310 } 311 312 // newScheme creates a new scheme that includes this package's object to use for testing 313 func newScheme() *runtime.Scheme { 314 scheme := runtime.NewScheme() 315 _ = corev1.AddToScheme(scheme) 316 _ = v1alpha1.AddToScheme(scheme) 317 _ = vzapi.AddToScheme(scheme) 318 return scheme 319 } 320 321 // newRequest creates a new reconciler request for testing 322 // namespace - The namespace to use in the request 323 // name - The name to use in the request 324 func newRequest(namespace string, name string) controllerruntime.Request { 325 return controllerruntime.Request{ 326 NamespacedName: types.NamespacedName{ 327 Namespace: namespace, 328 Name: name}} 329 } 330 331 // newConfigMapReconciler creates a new reconciler for testing 332 func newConfigMapReconciler(c client.Client) ComponentConfigMapReconciler { 333 scheme := newScheme() 334 reconciler := ComponentConfigMapReconciler{ 335 Client: c, 336 Scheme: scheme, 337 } 338 return reconciler 339 } 340 341 func buildFakeClient(cm corev1.ConfigMap) client.Client { 342 vz := &v1alpha1.Verrazzano{ 343 ObjectMeta: metav1.ObjectMeta{ 344 Name: "test-vz", 345 Namespace: constants.VerrazzanoInstallNamespace, 346 }, 347 } 348 secret := &corev1.Secret{ 349 ObjectMeta: metav1.ObjectMeta{ 350 Name: constants.GlobalImagePullSecName, 351 Namespace: "default", 352 }, 353 } 354 return fake.NewClientBuilder().WithObjects(vz, &cm, secret).WithScheme(newScheme()).Build() 355 } 356 357 // fakeUpgrade verifies that the correct parameter values are passed to upgrade 358 func fakeUpgrade(_ vzlog.VerrazzanoLogger, releaseName string, namespace string, chartDir string, _ bool, _ bool, overrides []helmcli.HelmOverrides) (*release.Release, error) { 359 if releaseName != "test-component" { 360 return nil, fmt.Errorf("Incorrect releaseName, expecting test-component, got %s", releaseName) 361 } 362 if chartDir != "/verrazzano/platform-operator/thirdparty/charts/test-component" { 363 return nil, fmt.Errorf("Incorrect releaseName, expecting test-component, got %s", chartDir) 364 } 365 if namespace != constants.VerrazzanoSystemNamespace { 366 return nil, fmt.Errorf("Incorrect release namespace, expecting verrazzano-system, got %s", namespace) 367 } 368 if len(overrides) != 2 { 369 return nil, fmt.Errorf("Incorrect number of overrides, expecting 2, got %d", len(overrides)) 370 } 371 return nil, nil 372 }