From cd3a1d8478ce61b236d3811a956cdefb81a06a8e Mon Sep 17 00:00:00 2001 From: ashokhein Date: Mon, 24 Jan 2022 12:58:57 +0000 Subject: [PATCH] fixed bug when Prometheus returns NaN Signed-off-by: ashokhein --- pkg/metrics/providers/prometheus.go | 3 +- pkg/metrics/providers/prometheus_test.go | 47 +++++++++++++++--------- 2 files changed, 31 insertions(+), 19 deletions(-) diff --git a/pkg/metrics/providers/prometheus.go b/pkg/metrics/providers/prometheus.go index e0660369..bead94a8 100644 --- a/pkg/metrics/providers/prometheus.go +++ b/pkg/metrics/providers/prometheus.go @@ -22,6 +22,7 @@ import ( "encoding/json" "fmt" "io" + "math" "net/http" "net/url" "path" @@ -148,7 +149,7 @@ func (p *PrometheusProvider) RunQuery(query string) (float64, error) { value = &f } } - if value == nil { + if value == nil || math.IsNaN(*value) { return 0, fmt.Errorf("%w", ErrNoValuesFound) } diff --git a/pkg/metrics/providers/prometheus_test.go b/pkg/metrics/providers/prometheus_test.go index a0ad1a65..84ee62c0 100644 --- a/pkg/metrics/providers/prometheus_test.go +++ b/pkg/metrics/providers/prometheus_test.go @@ -134,29 +134,40 @@ func TestPrometheusProvider_RunQueryWithBasicAuth(t *testing.T) { assert.Equal(t, float64(100), val) }) - t.Run("no values", func(t *testing.T) { - ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - json := `{"status":"success","data":{"resultType":"vector","result":[]}}` - w.Write([]byte(json)) - })) - defer ts.Close() + noResultTests := []struct { + name string + queryResult string + }{ + {name: "no values result", queryResult: `{"status":"success","data":{"resultType":"vector","result":[]}}`}, + {name: "NaN result", queryResult: `{"status":"success","data":{"resultType":"vector","result":[{"metric":{},"value":[1643023250.379,"NaN"]}]}}`}, + } - clients := prometheusFake() + for _, tt := range noResultTests { + t.Run(tt.name, func(t *testing.T) { + ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + json := tt.queryResult + w.Write([]byte(json)) + })) + defer ts.Close() - template, err := clients.flaggerClient.FlaggerV1beta1(). - MetricTemplates("default").Get(context.TODO(), "prometheus", metav1.GetOptions{}) - require.NoError(t, err) - template.Spec.Provider.Address = ts.URL + clients := prometheusFake() - secret, err := clients.kubeClient.CoreV1().Secrets("default").Get(context.TODO(), "prometheus", metav1.GetOptions{}) - require.NoError(t, err) + template, err := clients.flaggerClient.FlaggerV1beta1(). + MetricTemplates("default").Get(context.TODO(), "prometheus", metav1.GetOptions{}) + require.NoError(t, err) + template.Spec.Provider.Address = ts.URL - prom, err := NewPrometheusProvider(template.Spec.Provider, secret.Data) - require.NoError(t, err) + secret, err := clients.kubeClient.CoreV1().Secrets("default").Get(context.TODO(), "prometheus", metav1.GetOptions{}) + require.NoError(t, err) + + prom, err := NewPrometheusProvider(template.Spec.Provider, secret.Data) + require.NoError(t, err) + + _, err = prom.RunQuery(template.Spec.Query) + require.True(t, errors.Is(err, ErrNoValuesFound)) + }) + } - _, err = prom.RunQuery(template.Spec.Query) - require.True(t, errors.Is(err, ErrNoValuesFound)) - }) } func TestPrometheusProvider_IsOnline(t *testing.T) {