github.com/verrazzano/verrazzano@v1.7.1/application-operator/controllers/metricsbinding/metricsbinding_controller_test.go (about) 1 // Copyright (c) 2021, 2022, 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 metricsbinding 5 6 import ( 7 "context" 8 "fmt" 9 "testing" 10 "time" 11 12 promoperapi "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1" 13 asserts "github.com/stretchr/testify/assert" 14 vzapi "github.com/verrazzano/verrazzano/application-operator/apis/app/v1alpha1" 15 "github.com/verrazzano/verrazzano/application-operator/constants" 16 vzconst "github.com/verrazzano/verrazzano/pkg/constants" 17 k8sapps "k8s.io/api/apps/v1" 18 k8score "k8s.io/api/core/v1" 19 k8smeta "k8s.io/apimachinery/pkg/apis/meta/v1" 20 "k8s.io/apimachinery/pkg/runtime" 21 "k8s.io/apimachinery/pkg/types" 22 "sigs.k8s.io/controller-runtime/pkg/client/fake" 23 "sigs.k8s.io/controller-runtime/pkg/reconcile" 24 ) 25 26 var metricsTemplate = &vzapi.MetricsTemplate{ 27 TypeMeta: k8smeta.TypeMeta{ 28 Kind: vzconst.MetricsTemplateKind, 29 APIVersion: vzconst.MetricsTemplateAPIVersion, 30 }, 31 ObjectMeta: k8smeta.ObjectMeta{ 32 Namespace: testMetricsTemplateNamespace, 33 Name: testMetricsTemplateName, 34 }, 35 } 36 37 var trueValue = true 38 var metricsBinding = &vzapi.MetricsBinding{ 39 ObjectMeta: k8smeta.ObjectMeta{ 40 Namespace: testMetricsBindingNamespace, 41 Name: testMetricsBindingName, 42 OwnerReferences: []k8smeta.OwnerReference{ 43 { 44 APIVersion: fmt.Sprintf("%s/%s", deploymentGroup, deploymentVersion), 45 BlockOwnerDeletion: &trueValue, 46 Controller: &trueValue, 47 Kind: deploymentKind, 48 Name: testDeploymentName, 49 }, 50 }, 51 }, 52 Spec: vzapi.MetricsBindingSpec{ 53 MetricsTemplate: vzapi.NamespaceName{ 54 Namespace: testMetricsTemplateNamespace, 55 Name: testMetricsTemplateName, 56 }, 57 PrometheusConfigMap: vzapi.NamespaceName{ 58 Namespace: constants.VerrazzanoSystemNamespace, 59 Name: testConfigMapName, 60 }, 61 Workload: vzapi.Workload{ 62 Name: testDeploymentName, 63 TypeMeta: k8smeta.TypeMeta{ 64 Kind: vzconst.DeploymentWorkloadKind, 65 APIVersion: deploymentGroup + "/" + deploymentVersion, 66 }, 67 }, 68 }, 69 } 70 71 var plainWorkload = &k8sapps.Deployment{ 72 ObjectMeta: k8smeta.ObjectMeta{ 73 Namespace: testMetricsBindingNamespace, 74 Name: testDeploymentName, 75 UID: types.UID(testDeploymentUID), 76 }, 77 } 78 79 // The namespace has to contain labels for the template 80 var plainNs = &k8score.Namespace{ 81 ObjectMeta: k8smeta.ObjectMeta{ 82 Name: testMetricsBindingNamespace, 83 Labels: map[string]string{ 84 "test": "test", 85 }, 86 }, 87 } 88 89 // TestReconcile tests the reconcile process of the Metrics Binding 90 // GIVEN a metrics binding 91 // WHEN the function receives the binding 92 // THEN the reconcile process occurs for updating or deleting the Metrics Binding 93 func TestReconcile(t *testing.T) { 94 assert := asserts.New(t) 95 96 scheme := runtime.NewScheme() 97 _ = vzapi.AddToScheme(scheme) 98 _ = k8score.AddToScheme(scheme) 99 _ = k8sapps.AddToScheme(scheme) 100 _ = promoperapi.AddToScheme(scheme) 101 102 labeledNs := plainNs.DeepCopy() 103 labeledNs.Labels = map[string]string{constants.LabelIstioInjection: "enabled"} 104 105 labeledWorkload := plainWorkload.DeepCopy() 106 labeledWorkload.Labels = map[string]string{constants.MetricsWorkloadLabel: testDeploymentName} 107 108 populatedTemplate, err := getTemplateTestFile() 109 assert.NoError(err) 110 testFileCM, err := getConfigMapFromTestFile(true) 111 assert.NoError(err) 112 testFileSec, err := getSecretFromTestFile(true) 113 assert.NoError(err) 114 115 CMMetricsBinding := metricsBinding.DeepCopy() 116 secMetricsBinding := metricsBinding.DeepCopy() 117 secMetricsBinding.Spec.PrometheusConfigMap = vzapi.NamespaceName{} 118 secMetricsBinding.Spec.PrometheusConfigSecret = vzapi.SecretKey{ 119 Namespace: vzconst.PrometheusOperatorNamespace, 120 Name: vzconst.PromAdditionalScrapeConfigsSecretName, 121 Key: prometheusConfigKey, 122 } 123 legacyBinding := metricsBinding.DeepCopy() 124 legacyBinding.Spec.MetricsTemplate.Namespace = constants.LegacyDefaultMetricsTemplateNamespace 125 legacyBinding.Spec.MetricsTemplate.Name = constants.LegacyDefaultMetricsTemplateName 126 legacyBinding.Spec.PrometheusConfigMap.Namespace = vzconst.VerrazzanoSystemNamespace 127 legacyBinding.Spec.PrometheusConfigMap.Name = vzconst.VmiPromConfigName 128 deleteBinding := metricsBinding.DeepCopy() 129 deleteBinding.DeletionTimestamp = &k8smeta.Time{Time: time.Now()} 130 131 tests := []struct { 132 name string 133 metricsBinding *vzapi.MetricsBinding 134 workload *k8sapps.Deployment 135 namespace *k8score.Namespace 136 configMap *k8score.ConfigMap 137 secret *k8score.Secret 138 request *reconcile.Request 139 requeue bool 140 expectError bool 141 }{ 142 { 143 name: "test kube-system request", 144 metricsBinding: CMMetricsBinding, 145 workload: labeledWorkload, 146 namespace: labeledNs, 147 request: &reconcile.Request{NamespacedName: types.NamespacedName{Namespace: vzconst.KubeSystem}}, 148 requeue: false, 149 }, 150 { 151 name: "test configmap", 152 metricsBinding: CMMetricsBinding, 153 workload: labeledWorkload, 154 namespace: labeledNs, 155 configMap: testFileCM, 156 requeue: true, 157 expectError: false, 158 }, 159 { 160 name: "test secret", 161 metricsBinding: secMetricsBinding, 162 workload: labeledWorkload, 163 namespace: labeledNs, 164 secret: testFileSec, 165 requeue: true, 166 expectError: false, 167 }, 168 { 169 name: "test delete", 170 metricsBinding: deleteBinding, 171 workload: labeledWorkload, 172 namespace: labeledNs, 173 configMap: testFileCM, 174 requeue: false, 175 expectError: false, 176 }, 177 } 178 for _, tt := range tests { 179 t.Run(tt.name, func(t *testing.T) { 180 c := fake.NewClientBuilder().WithScheme(scheme).WithRuntimeObjects([]runtime.Object{ 181 populatedTemplate, 182 tt.workload, 183 tt.namespace, 184 tt.metricsBinding, 185 }...) 186 187 if tt.configMap != nil { 188 c = c.WithRuntimeObjects(tt.configMap) 189 } 190 if tt.secret != nil { 191 c = c.WithRuntimeObjects(tt.secret) 192 } 193 194 client := c.Build() 195 r := newReconciler(client) 196 if tt.request == nil { 197 tt.request = &reconcile.Request{NamespacedName: types.NamespacedName{Namespace: tt.metricsBinding.Namespace, Name: tt.metricsBinding.Name}} 198 } 199 result, err := r.Reconcile(context.TODO(), *tt.request) 200 if tt.expectError { 201 assert.Error(err, "Expected error Reconciling the Metrics Binding") 202 return 203 } 204 assert.NoError(err, "Expected no error Reconciling the Metrics Binding") 205 assert.Equal(tt.requeue, result.Requeue) 206 }) 207 } 208 }