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  }