-
Notifications
You must be signed in to change notification settings - Fork 38
feat: Add placement status metrics #1077
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 2 commits
623f26d
8486603
8a89ce8
0200684
c6a8490
ed646ef
a6026c9
222867e
f337151
e89bb6e
82a9a65
c74a770
4ed96c6
d446d00
fef4bb6
07ffce0
1cec5f4
9bbdf16
d3e408d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -6,6 +6,7 @@ package clusterresourceplacement | |
|
|
||
| import ( | ||
| "fmt" | ||
| "sort" | ||
| "strconv" | ||
| "time" | ||
|
|
||
|
|
@@ -402,13 +403,9 @@ var _ = Describe("Test ClusterResourcePlacement Controller", func() { | |
| checkPlacementCompleteMetric(customRegistry, testCRPName, false, 1) | ||
|
|
||
| By("Ensure placement status metric was emitted") | ||
| status := map[string][]string{ | ||
| string(placementv1beta1.ClusterResourcePlacementScheduledConditionType): { | ||
| string(corev1.ConditionUnknown), | ||
| }, | ||
| string(placementv1beta1.ClusterResourcePlacementRolloutStartedConditionType): { | ||
| "nil", | ||
| }, | ||
| status := map[string]string{ | ||
| string(placementv1beta1.ClusterResourcePlacementScheduledConditionType): string(corev1.ConditionUnknown), | ||
| string(placementv1beta1.ClusterResourcePlacementRolloutStartedConditionType): "nil", | ||
| } | ||
| checkPlacementStatusMetric(customRegistry, crp, status) | ||
| }) | ||
|
|
@@ -461,11 +458,8 @@ var _ = Describe("Test ClusterResourcePlacement Controller", func() { | |
| checkPlacementCompleteMetric(customRegistry, testCRPName, false, 1) | ||
|
|
||
| By("Ensure placement status metric was emitted") | ||
| status := map[string][]string{ | ||
| string(placementv1beta1.ClusterResourcePlacementScheduledConditionType): { | ||
| string(corev1.ConditionUnknown), | ||
| string(corev1.ConditionFalse), | ||
| }, | ||
| status := map[string]string{ | ||
| string(placementv1beta1.ClusterResourcePlacementScheduledConditionType): string(corev1.ConditionFalse), | ||
| } | ||
| checkPlacementStatusMetric(customRegistry, crp, status) | ||
britaniar marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| }) | ||
|
|
@@ -568,13 +562,9 @@ var _ = Describe("Test ClusterResourcePlacement Controller", func() { | |
| checkPlacementCompleteMetric(customRegistry, testCRPName, false, 1) | ||
|
|
||
| By("Ensure placement status metric was emitted") | ||
| status := map[string][]string{ | ||
| string(placementv1beta1.ClusterResourcePlacementScheduledConditionType): { | ||
| string(corev1.ConditionUnknown), | ||
| }, | ||
| string(placementv1beta1.ClusterResourcePlacementRolloutStartedConditionType): { | ||
| string(corev1.ConditionUnknown), | ||
| }, | ||
| status := map[string]string{ | ||
| string(placementv1beta1.ClusterResourcePlacementScheduledConditionType): string(corev1.ConditionUnknown), | ||
| string(placementv1beta1.ClusterResourcePlacementRolloutStartedConditionType): string(corev1.ConditionUnknown), | ||
| } | ||
| checkPlacementStatusMetric(customRegistry, crp, status) | ||
britaniar marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
|
|
@@ -677,19 +667,10 @@ var _ = Describe("Test ClusterResourcePlacement Controller", func() { | |
| checkPlacementCompleteMetric(customRegistry, testCRPName, false, 1) | ||
|
|
||
| By("Ensure placement status metric was emitted") | ||
| status = map[string][]string{ | ||
| string(placementv1beta1.ClusterResourcePlacementScheduledConditionType): { | ||
| string(corev1.ConditionUnknown), | ||
| }, | ||
| string(placementv1beta1.ClusterResourcePlacementRolloutStartedConditionType): { | ||
| string(corev1.ConditionUnknown), | ||
| }, | ||
| string(placementv1beta1.ClusterResourcePlacementOverriddenConditionType): { | ||
| string(corev1.ConditionUnknown), | ||
| }, | ||
| string(placementv1beta1.ClusterResourcePlacementWorkSynchronizedConditionType): { | ||
| string(corev1.ConditionUnknown), | ||
| }, | ||
| status = map[string]string{ | ||
| string(placementv1beta1.ClusterResourcePlacementScheduledConditionType): string(corev1.ConditionUnknown), | ||
| string(placementv1beta1.ClusterResourcePlacementRolloutStartedConditionType): string(corev1.ConditionUnknown), | ||
| string(placementv1beta1.ClusterResourcePlacementWorkSynchronizedConditionType): string(corev1.ConditionUnknown), | ||
| } | ||
| checkPlacementStatusMetric(customRegistry, crp, status) | ||
| }) | ||
|
|
@@ -865,25 +846,11 @@ var _ = Describe("Test ClusterResourcePlacement Controller", func() { | |
| checkPlacementCompleteMetric(customRegistry, testCRPName, true, 2) | ||
|
||
|
|
||
| By("Ensure placement status metric was emitted") | ||
| status := map[string][]string{ | ||
| string(placementv1beta1.ClusterResourcePlacementScheduledConditionType): { | ||
| string(corev1.ConditionUnknown), | ||
| }, | ||
| string(placementv1beta1.ClusterResourcePlacementRolloutStartedConditionType): { | ||
| string(corev1.ConditionUnknown), | ||
| }, | ||
| string(placementv1beta1.ClusterResourcePlacementOverriddenConditionType): { | ||
| string(corev1.ConditionUnknown), | ||
| }, | ||
| string(placementv1beta1.ClusterResourcePlacementWorkSynchronizedConditionType): { | ||
| string(corev1.ConditionUnknown), | ||
| }, | ||
| string(placementv1beta1.ClusterResourcePlacementAppliedConditionType): { | ||
| string(corev1.ConditionUnknown), | ||
| }, | ||
| string(placementv1beta1.ClusterResourcePlacementAvailableConditionType): { | ||
| string(corev1.ConditionUnknown), | ||
| }, | ||
| status := map[string]string{ | ||
| string(placementv1beta1.ClusterResourcePlacementScheduledConditionType): string(corev1.ConditionUnknown), | ||
| string(placementv1beta1.ClusterResourcePlacementRolloutStartedConditionType): string(corev1.ConditionUnknown), | ||
| string(placementv1beta1.ClusterResourcePlacementWorkSynchronizedConditionType): string(corev1.ConditionUnknown), | ||
| string(placementv1beta1.ClusterResourcePlacementAppliedConditionType): string(corev1.ConditionUnknown), | ||
| } | ||
| checkPlacementStatusMetric(customRegistry, crp, status) | ||
| }) | ||
|
|
@@ -1180,22 +1147,10 @@ var _ = Describe("Test ClusterResourcePlacement Controller", func() { | |
| checkPlacementCompleteMetric(customRegistry, testCRPName, true, 2) | ||
|
|
||
| By("Ensure placement status metric was emitted") | ||
| status := map[string][]string{ | ||
| string(placementv1beta1.ClusterResourcePlacementScheduledConditionType): { | ||
| string(corev1.ConditionUnknown), | ||
| }, | ||
| string(placementv1beta1.ClusterResourcePlacementRolloutStartedConditionType): { | ||
| string(corev1.ConditionUnknown), | ||
| }, | ||
| string(placementv1beta1.ClusterResourcePlacementOverriddenConditionType): { | ||
| string(corev1.ConditionUnknown), | ||
| }, | ||
| string(placementv1beta1.ClusterResourcePlacementWorkSynchronizedConditionType): { | ||
| string(corev1.ConditionUnknown), | ||
| }, | ||
| string(placementv1beta1.ClusterResourcePlacementDiffReportedConditionType): { | ||
| string(corev1.ConditionUnknown), | ||
| }, | ||
| status := map[string]string{ | ||
| string(placementv1beta1.ClusterResourcePlacementScheduledConditionType): string(corev1.ConditionUnknown), | ||
| string(placementv1beta1.ClusterResourcePlacementRolloutStartedConditionType): string(corev1.ConditionUnknown), | ||
| string(placementv1beta1.ClusterResourcePlacementDiffReportedConditionType): string(corev1.ConditionUnknown), | ||
| } | ||
| checkPlacementStatusMetric(customRegistry, crp, status) | ||
| }) | ||
|
|
@@ -1229,7 +1184,7 @@ func checkPlacementCompleteMetric(registry *prometheus.Registry, crpName string, | |
| } | ||
| } | ||
|
|
||
| func checkPlacementStatusMetric(registry *prometheus.Registry, crp *placementv1beta1.ClusterResourcePlacement, statuses map[string][]string) { | ||
| func checkPlacementStatusMetric(registry *prometheus.Registry, crp *placementv1beta1.ClusterResourcePlacement, statuses map[string]string) { | ||
britaniar marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| metricFamilies, err := registry.Gather() | ||
| Expect(err).Should(Succeed()) | ||
| var placementStatusMetrics []*prometheusclientmodel.Metric | ||
|
|
@@ -1238,41 +1193,65 @@ func checkPlacementStatusMetric(registry *prometheus.Registry, crp *placementv1b | |
| placementStatusMetrics = mf.GetMetric() | ||
| } | ||
| } | ||
| By(fmt.Sprint("placementStatusMetrics: %w ", placementStatusMetrics)) | ||
| // Iterate over the labels and compare with expected values from statuses map | ||
| for _, emittedMetric := range placementStatusMetrics { | ||
| metricLabels := emittedMetric.GetLabel() | ||
|
|
||
| // Initialize variables for each metric iteration | ||
| var condType string | ||
| var expectedStatuses []string | ||
| var statusExists bool | ||
| // Sorting metrics based on the "condition_type" label | ||
| sortMetricsByConditionType(placementStatusMetrics) | ||
| By(fmt.Sprint("placementStatusMetrics: %w ", placementStatusMetrics)) | ||
| // Check the number of emitted metrics | ||
| Expect(len(placementStatusMetrics)).Should(Equal(len(statuses))) | ||
|
|
||
| // Iterate over the labels and compare with expected values from conditionType | ||
| for _, label := range metricLabels { | ||
| switch label.GetName() { | ||
| case "generation": | ||
| Expect(label.GetValue()).Should(Equal(strconv.FormatInt(crp.Generation, 10))) | ||
| case "name": | ||
| Expect(label.GetValue()).Should(Equal(crp.Name)) | ||
| case "conditionType": | ||
| condType = label.GetValue() | ||
| // Retrieve possible statuses from the map directly | ||
| expectedStatuses, statusExists = statuses[condType] | ||
| // Ensure that the conditionType exists in the map | ||
| Expect(statusExists).Should(BeTrue(), fmt.Sprintf("status for conditionType '%s' is missing in the conditionTypeStatuses map", condType)) | ||
| case "status": | ||
| // Compare the status label with the expected statuses for this conditionType | ||
| statusFound := false | ||
| for _, expectedStatus := range expectedStatuses { | ||
| if label.GetValue() == expectedStatus { | ||
| statusFound = true | ||
| break | ||
| } | ||
| } | ||
| // Ensure the status is one of the expected values | ||
| Expect(statusFound).Should(BeTrue(), fmt.Sprintf("status '%s' for conditionType '%s' does not match any expected value", label.GetValue(), condType)) | ||
| } | ||
| expectedPlacementStatusMetrics := make([]*prometheusclientmodel.Metric, 0, len(statuses)) | ||
| for condType, status := range statuses { | ||
| metric := &prometheusclientmodel.Metric{ | ||
| Label: []*prometheusclientmodel.LabelPair{ | ||
| { | ||
| Name: ptr.To("conditionType"), | ||
| Value: ptr.To(condType), | ||
| }, | ||
| { | ||
| Name: ptr.To("generation"), | ||
| Value: ptr.To(strconv.FormatInt(crp.Generation, 10)), | ||
| }, | ||
| { | ||
| Name: ptr.To("name"), | ||
| Value: ptr.To(crp.Name), | ||
| }, | ||
| { | ||
| Name: ptr.To("status"), | ||
| Value: ptr.To(status), | ||
| }, | ||
| }, | ||
| } | ||
| expectedPlacementStatusMetrics = append(expectedPlacementStatusMetrics, metric) | ||
| } | ||
| sortMetricsByConditionType(expectedPlacementStatusMetrics) | ||
| fmt.Println("\nExpectedMetrics:", expectedPlacementStatusMetrics) | ||
| // Use cmp.Diff to compare the slices of metrics | ||
| var previousTime float64 | ||
| previousTime = 0 | ||
| for i := range placementStatusMetrics { | ||
| diff := cmp.Diff(placementStatusMetrics[i].Label, expectedPlacementStatusMetrics[i].Label, cmpopts.IgnoreUnexported(prometheusclientmodel.LabelPair{})) | ||
| Expect(diff).Should(BeEmpty(), fmt.Sprintf("Metric mismatch: %s", diff)) | ||
| Expect(placementStatusMetrics[i].GetGauge().GetValue()).ShouldNot(Equal(previousTime)) | ||
| Expect(placementStatusMetrics[i].GetGauge().GetValue() > previousTime).Should(BeTrue()) | ||
| previousTime = placementStatusMetrics[i].GetGauge().GetValue() | ||
| } | ||
| } | ||
|
|
||
| func sortMetricsByConditionType(metrics []*prometheusclientmodel.Metric) { | ||
| var conditionTypeOrder = map[string]int{ | ||
| string(placementv1beta1.ClusterResourcePlacementScheduledConditionType): 0, | ||
| string(placementv1beta1.ClusterResourcePlacementRolloutStartedConditionType): 1, | ||
| string(placementv1beta1.ClusterResourcePlacementOverriddenConditionType): 2, | ||
| string(placementv1beta1.ClusterResourcePlacementWorkSynchronizedConditionType): 3, | ||
| string(placementv1beta1.ClusterResourcePlacementAppliedConditionType): 4, | ||
| string(placementv1beta1.ClusterResourcePlacementAvailableConditionType): 5, | ||
| string(placementv1beta1.ClusterResourcePlacementDiffReportedConditionType): 6, | ||
| } | ||
| sort.Slice(metrics, func(i, j int) bool { | ||
| // Get condition type values using the condition label | ||
| conditionTypeI := conditionTypeOrder[metrics[i].GetLabel()[0].GetValue()] | ||
| conditionTypeJ := conditionTypeOrder[metrics[j].GetLabel()[0].GetValue()] | ||
| return conditionTypeI < conditionTypeJ | ||
| }) | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.