Mikkel Oscar Lyderik Larsen 4acdf72ef7 Handle more complex array in json path
Signed-off-by: Mikkel Oscar Lyderik Larsen <mikkel.larsen@zalando.de>
2021-10-14 09:34:15 +02:00

92 lines
2.4 KiB
Go

package httpmetrics
import (
"errors"
"fmt"
"net/http"
"net/http/httptest"
"net/url"
"testing"
"github.com/stretchr/testify/require"
)
func makeTestHTTPServer(t *testing.T, response []byte) *httptest.Server {
h := func(w http.ResponseWriter, r *http.Request) {
require.Equal(t, r.URL.Path, "/metrics")
w.Header().Set("Content-Type", "application/json")
_, err := w.Write(response)
require.NoError(t, err)
}
return httptest.NewServer(http.HandlerFunc(h))
}
func TestJSONPathMetricsGetter(t *testing.T) {
for _, tc := range []struct {
name string
jsonResponse []byte
jsonPath string
result float64
aggregator AggregatorFunc
err error
}{
{
name: "basic single value",
jsonResponse: []byte(`{"value":3}`),
jsonPath: "$.value",
result: 3,
aggregator: Average,
},
{
name: "basic average",
jsonResponse: []byte(`{"value":[3,4,5]}`),
jsonPath: "$.value",
result: 4,
aggregator: Average,
},
{
name: "dotted key",
jsonResponse: []byte(`{"metric.value":5}`),
jsonPath: "$['metric.value']",
result: 5,
aggregator: Average,
},
{
name: "glob array query",
jsonResponse: []byte(`{"worker_status":[{"last_status":{"backlog":3}},{"last_status":{"backlog":7}}]}`),
jsonPath: "$.worker_status.[*].last_status.backlog",
result: 5,
aggregator: Average,
},
{
name: "json path not resulting in array or number should lead to error",
jsonResponse: []byte(`{"metric.value":5}`),
jsonPath: "$['invalid.metric.values']",
err: errors.New("unexpected json: expected single numeric or array value"),
},
{
name: "invalid json should error",
jsonResponse: []byte(`{`),
jsonPath: "$['invalid.metric.values']",
err: errors.New("unexpected end of file"),
},
} {
t.Run(tc.name, func(t *testing.T) {
server := makeTestHTTPServer(t, tc.jsonResponse)
defer server.Close()
getter, err := NewJSONPathMetricsGetter(DefaultMetricsHTTPClient(), tc.aggregator, tc.jsonPath)
require.NoError(t, err)
url, err := url.Parse(fmt.Sprintf("%s/metrics", server.URL))
require.NoError(t, err)
metric, err := getter.GetMetric(*url)
if tc.err != nil {
require.Error(t, err)
require.Equal(t, tc.err.Error(), err.Error())
return
}
require.NoError(t, err)
require.Equal(t, tc.result, metric)
})
}
}