github.com/verrazzano/verrazzano@v1.7.0/platform-operator/metricsexporter/metricsexporter_test.go (about) 1 // Copyright (c) 2022, 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 metricsexporter 5 6 import ( 7 "testing" 8 9 "github.com/prometheus/client_golang/prometheus/testutil" 10 asserts "github.com/stretchr/testify/assert" 11 "github.com/verrazzano/verrazzano/pkg/log/vzlog" 12 installv1alpha1 "github.com/verrazzano/verrazzano/platform-operator/apis/verrazzano/v1alpha1" 13 "github.com/verrazzano/verrazzano/platform-operator/controllers/verrazzano/component/grafana" 14 ) 15 16 // Constants that hold the times that are used to test various cases of component timestamps being passed 17 // into the TestAnalyzeVerrazzanoResourceMetrics function 18 const ( 19 componentFirstTime string = "2022-07-06T13:54:59Z" 20 componentSecondTime string = "2022-07-06T13:55:45Z" 21 componentThirdTime string = "2022-07-06T13:58:59Z" 22 componentFourthTime string = "2022-07-06T13:59:00Z" 23 unregisteredTestComponent string = "unregistered test component" 24 ) 25 26 func init() { 27 Init() 28 } 29 30 // TestReconcileCounterIncrement tests the Inc fn of the reconcile counter and the reconcile error counter metrics objects 31 // GIVEN a call to Inc 32 // THEN the function should update that internal metric by one 33 func TestReconcileCounterAndErrorIncrement(t *testing.T) { 34 assert := asserts.New(t) 35 test := struct { 36 name string 37 expectedIncrementValueForCounter float64 38 expectedIncrementValueForError float64 39 }{ 40 name: "Test that reoncile counter is incremented by one when function is called", 41 expectedIncrementValueForCounter: float64(1), 42 expectedIncrementValueForError: float64(1), 43 } 44 t.Run(test.name, func(t *testing.T) { 45 reconcileCounterObject, err := GetSimpleCounterMetric(ReconcileCounter) 46 assert.NoError(err) 47 reconcileCounterBefore := testutil.ToFloat64(reconcileCounterObject.Get()) 48 reconcileCounterObject.Inc() 49 reconcileCounterAfter := testutil.ToFloat64(reconcileCounterObject.Get()) 50 assert.Equal(test.expectedIncrementValueForCounter, reconcileCounterAfter-reconcileCounterBefore) 51 reconcileErrorCounterObject, err := GetSimpleCounterMetric(ReconcileError) 52 assert.NoError(err) 53 reconcileErrorCounterBefore := testutil.ToFloat64(reconcileErrorCounterObject.Get()) 54 reconcileErrorCounterObject.Inc() 55 reconcileErrorCounterAfter := testutil.ToFloat64(reconcileErrorCounterObject.Get()) 56 assert.Equal(test.expectedIncrementValueForError, reconcileErrorCounterAfter-reconcileErrorCounterBefore) 57 }) 58 } 59 60 // TestAnalyzeVerrazzanoResourceMetrics tests the AnalyzeVerrazzanoResourceMetrics fn 61 // GIVEN a call to AnalyzeVerrazzanoResourceMetrics 62 // WHEN a VZ CR with or without timestamps is passed to the fn 63 // THEN the function properly updates or does nothing to the component's metric 64 func TestAnalyzeVerrazzanoResourceMetrics(t *testing.T) { 65 assert := asserts.New(t) 66 emptyVZCR := installv1alpha1.Verrazzano{} 67 disabledComponentVZCR := installv1alpha1.Verrazzano{ 68 Status: installv1alpha1.VerrazzanoStatus{ 69 Components: installv1alpha1.ComponentStatusMap{ 70 "grafana": &installv1alpha1.ComponentStatusDetails{ 71 State: installv1alpha1.CompStateDisabled, 72 }, 73 }, 74 }, 75 } 76 conditionsNotFullyMetVZCR := installv1alpha1.Verrazzano{ 77 Status: installv1alpha1.VerrazzanoStatus{ 78 Components: installv1alpha1.ComponentStatusMap{ 79 "grafana": &installv1alpha1.ComponentStatusDetails{ 80 Conditions: []installv1alpha1.Condition{ 81 { 82 Type: installv1alpha1.CondInstallStarted, 83 LastTransitionTime: componentFirstTime, 84 }, 85 }, 86 }, 87 }, 88 }, 89 } 90 installPopulatedVZCR := installv1alpha1.Verrazzano{ 91 Status: installv1alpha1.VerrazzanoStatus{ 92 Components: installv1alpha1.ComponentStatusMap{ 93 "grafana": &installv1alpha1.ComponentStatusDetails{ 94 Conditions: []installv1alpha1.Condition{ 95 { 96 Type: installv1alpha1.CondInstallStarted, 97 LastTransitionTime: componentFirstTime, 98 }, 99 { 100 Type: installv1alpha1.CondInstallComplete, 101 LastTransitionTime: componentSecondTime, 102 }, 103 { 104 Type: installv1alpha1.CondUpgradeStarted, 105 LastTransitionTime: componentThirdTime, 106 }, 107 }, 108 }, 109 }, 110 }, 111 } 112 upgradeStartTimeisAfterUpgradeCompletedTimeVZCR := installv1alpha1.Verrazzano{ 113 Status: installv1alpha1.VerrazzanoStatus{ 114 Components: installv1alpha1.ComponentStatusMap{ 115 unregisteredTestComponent: &installv1alpha1.ComponentStatusDetails{ 116 Conditions: []installv1alpha1.Condition{ 117 { 118 Type: installv1alpha1.CondUpgradeStarted, 119 LastTransitionTime: componentSecondTime, 120 }, 121 { 122 Type: installv1alpha1.CondUpgradeComplete, 123 LastTransitionTime: componentFirstTime, 124 }, 125 }, 126 }, 127 }, 128 }, 129 } 130 upgradeAndInstallPopulatedVZCR := installv1alpha1.Verrazzano{ 131 Status: installv1alpha1.VerrazzanoStatus{ 132 Components: installv1alpha1.ComponentStatusMap{ 133 "grafana": &installv1alpha1.ComponentStatusDetails{ 134 Conditions: []installv1alpha1.Condition{ 135 { 136 Type: installv1alpha1.CondInstallStarted, 137 LastTransitionTime: componentFirstTime, 138 }, 139 { 140 Type: installv1alpha1.CondInstallComplete, 141 LastTransitionTime: componentSecondTime, 142 }, 143 { 144 Type: installv1alpha1.CondUpgradeStarted, 145 LastTransitionTime: componentThirdTime, 146 }, 147 { 148 Type: installv1alpha1.CondUpgradeComplete, 149 LastTransitionTime: componentFourthTime, 150 }, 151 }, 152 }, 153 }, 154 }, 155 } 156 componentNameNotInDictionaryVZCR := installv1alpha1.Verrazzano{ 157 Status: installv1alpha1.VerrazzanoStatus{ 158 Components: installv1alpha1.ComponentStatusMap{ 159 unregisteredTestComponent: &installv1alpha1.ComponentStatusDetails{ 160 Conditions: []installv1alpha1.Condition{ 161 { 162 Type: installv1alpha1.CondInstallStarted, 163 LastTransitionTime: componentFirstTime, 164 }, 165 { 166 Type: installv1alpha1.CondInstallComplete, 167 LastTransitionTime: componentSecondTime, 168 }, 169 { 170 Type: installv1alpha1.CondUpgradeStarted, 171 LastTransitionTime: componentThirdTime, 172 }, 173 { 174 Type: installv1alpha1.CondUpgradeComplete, 175 LastTransitionTime: componentFourthTime, 176 }, 177 }, 178 }, 179 }, 180 }, 181 } 182 installStartTimeisAfterInstallCompletedTimeVZCR := installv1alpha1.Verrazzano{ 183 Status: installv1alpha1.VerrazzanoStatus{ 184 Components: installv1alpha1.ComponentStatusMap{ 185 unregisteredTestComponent: &installv1alpha1.ComponentStatusDetails{ 186 Conditions: []installv1alpha1.Condition{ 187 { 188 Type: installv1alpha1.CondInstallStarted, 189 LastTransitionTime: componentSecondTime, 190 }, 191 { 192 Type: installv1alpha1.CondInstallComplete, 193 LastTransitionTime: componentFirstTime, 194 }, 195 }, 196 }, 197 }, 198 }, 199 } 200 201 tests := []struct { 202 name string 203 vzcr installv1alpha1.Verrazzano 204 expectedValueForInstallMetric float64 205 expectedValueForUpdateMetric float64 206 }{ 207 { 208 name: "test empty Verrazzano", 209 vzcr: emptyVZCR, 210 expectedValueForInstallMetric: float64(0), 211 expectedValueForUpdateMetric: float64(0), 212 }, 213 { 214 name: "test that a diabled component does not have an install or upgrade time", 215 vzcr: disabledComponentVZCR, 216 expectedValueForInstallMetric: float64(0), 217 expectedValueForUpdateMetric: float64(0), 218 }, 219 { 220 name: "Verrazzano where install has started, but not yet completed", 221 vzcr: conditionsNotFullyMetVZCR, 222 expectedValueForInstallMetric: float64(0), 223 expectedValueForUpdateMetric: float64(0), 224 }, 225 { 226 name: "test populated Verrazzano where install has started and completed, but upgrade has not yet completed", 227 vzcr: installPopulatedVZCR, 228 expectedValueForInstallMetric: float64(46), 229 expectedValueForUpdateMetric: float64(0), 230 }, 231 { 232 name: "test that a VZ CR with an upgrade start time after its upgrade completion time does not update the update duration metric for that component", 233 vzcr: upgradeStartTimeisAfterUpgradeCompletedTimeVZCR, 234 expectedValueForInstallMetric: float64(46), 235 expectedValueForUpdateMetric: float64(0), 236 }, 237 { 238 name: "test populated Verrazzano where both install and upgrade have started and completed", 239 vzcr: upgradeAndInstallPopulatedVZCR, 240 expectedValueForInstallMetric: float64(46), 241 expectedValueForUpdateMetric: float64(1), 242 }, 243 { 244 name: "test that an unrecognized component does not cause a seg fault, the analyze VZCR function keeps going on", 245 vzcr: componentNameNotInDictionaryVZCR, 246 expectedValueForInstallMetric: float64(46), 247 expectedValueForUpdateMetric: float64(1), 248 }, 249 { 250 name: "test that a VZ CR with an install start time after its install completion time does not update the install duration metric for that component", 251 vzcr: installStartTimeisAfterInstallCompletedTimeVZCR, 252 expectedValueForInstallMetric: float64(46), 253 expectedValueForUpdateMetric: float64(1), 254 }, 255 } 256 testLog, _ := vzlog.EnsureResourceLogger(&vzlog.ResourceConfig{ 257 Name: "Test", 258 Namespace: "Test namespace", 259 ID: "Test ID", 260 Generation: int64(1), 261 ControllerName: "test controller", 262 }) 263 264 for _, tt := range tests { 265 t.Run(tt.name, func(t *testing.T) { 266 AnalyzeVerrazzanoResourceMetrics(testLog, tt.vzcr) 267 grafanaInstallMetric, err := MetricsExp.internalData.componentInstallDuration.installDuration.GetMetricWithLabelValues(grafana.ComponentJSONName) 268 assert.NoError(err) 269 assert.Equal(tt.expectedValueForInstallMetric, testutil.ToFloat64(grafanaInstallMetric)) 270 grafanaUpgradeMetric, err := MetricsExp.internalData.componentUpgradeDuration.upgradeDuration.GetMetricWithLabelValues(grafana.ComponentJSONName) 271 assert.NoError(err) 272 assert.Equal(tt.expectedValueForUpdateMetric, testutil.ToFloat64(grafanaUpgradeMetric)) 273 }) 274 } 275 }