2018-10-29 14:26:25 +01:00
|
|
|
package zmon
|
|
|
|
|
|
|
|
import (
|
2021-07-26 15:31:10 +02:00
|
|
|
"encoding/json"
|
2018-10-29 14:26:25 +01:00
|
|
|
"fmt"
|
|
|
|
"net/http"
|
|
|
|
"net/http/httptest"
|
|
|
|
"testing"
|
|
|
|
"time"
|
|
|
|
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
|
|
)
|
|
|
|
|
|
|
|
func TestQuery(tt *testing.T) {
|
|
|
|
client := &http.Client{}
|
|
|
|
for _, ti := range []struct {
|
|
|
|
msg string
|
|
|
|
duration time.Duration
|
|
|
|
aggregators []string
|
|
|
|
status int
|
|
|
|
body string
|
|
|
|
err error
|
|
|
|
dataPoints []DataPoint
|
|
|
|
key string
|
|
|
|
}{
|
|
|
|
{
|
|
|
|
msg: "test getting back a single data point",
|
|
|
|
duration: 1 * time.Hour,
|
|
|
|
status: http.StatusOK,
|
|
|
|
body: `{
|
|
|
|
"queries": [
|
|
|
|
{
|
|
|
|
"results": [
|
|
|
|
{
|
|
|
|
"values": [
|
|
|
|
[1539710395000,765952]
|
|
|
|
]
|
|
|
|
}
|
|
|
|
]
|
|
|
|
}
|
|
|
|
]
|
|
|
|
}`,
|
|
|
|
dataPoints: []DataPoint{
|
|
|
|
{
|
|
|
|
Time: time.Unix(1539710395, 0),
|
|
|
|
Value: 765952,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
msg: "test getting back a single datapoint with key",
|
|
|
|
duration: 1 * time.Hour,
|
|
|
|
status: http.StatusOK,
|
|
|
|
key: "my-key",
|
|
|
|
body: `{
|
|
|
|
"queries": [
|
|
|
|
{
|
|
|
|
"results": [
|
|
|
|
{
|
|
|
|
"values": [
|
|
|
|
[1539710395000,765952]
|
|
|
|
]
|
|
|
|
}
|
|
|
|
]
|
|
|
|
}
|
|
|
|
]
|
|
|
|
}`,
|
|
|
|
dataPoints: []DataPoint{
|
|
|
|
{
|
|
|
|
Time: time.Unix(1539710395, 0),
|
|
|
|
Value: 765952,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
msg: "test getting back a single datapoint with aggregators",
|
|
|
|
duration: 1 * time.Hour,
|
|
|
|
status: http.StatusOK,
|
|
|
|
aggregators: []string{"max"},
|
|
|
|
body: `{
|
|
|
|
"queries": [
|
|
|
|
{
|
|
|
|
"results": [
|
|
|
|
{
|
|
|
|
"values": [
|
|
|
|
[1539710395000,765952]
|
|
|
|
]
|
|
|
|
}
|
|
|
|
]
|
|
|
|
}
|
|
|
|
]
|
|
|
|
}`,
|
|
|
|
dataPoints: []DataPoint{
|
|
|
|
{
|
|
|
|
Time: time.Unix(1539710395, 0),
|
|
|
|
Value: 765952,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
msg: "test query with invalid aggregator",
|
|
|
|
aggregators: []string{"invalid"},
|
|
|
|
err: fmt.Errorf("invalid aggregator 'invalid'"),
|
|
|
|
},
|
|
|
|
{
|
|
|
|
msg: "test query with invalid response",
|
|
|
|
status: http.StatusInternalServerError,
|
|
|
|
body: `{"error": 500}`,
|
|
|
|
err: fmt.Errorf("[kariosdb query] unexpected response code: 500"),
|
|
|
|
},
|
|
|
|
{
|
|
|
|
msg: "test getting invalid values response",
|
|
|
|
duration: 1 * time.Hour,
|
|
|
|
status: http.StatusOK,
|
|
|
|
body: `{
|
|
|
|
"queries": [
|
|
|
|
{
|
|
|
|
"results": [
|
|
|
|
{
|
|
|
|
"values": [
|
|
|
|
[1539710395000,765952,1]
|
|
|
|
]
|
|
|
|
}
|
|
|
|
]
|
|
|
|
}
|
|
|
|
]
|
|
|
|
}`,
|
|
|
|
err: fmt.Errorf("[kariosdb query] unexpected response data"),
|
|
|
|
},
|
|
|
|
} {
|
|
|
|
tt.Run(ti.msg, func(t *testing.T) {
|
|
|
|
ts := httptest.NewServer(http.HandlerFunc(
|
|
|
|
func(w http.ResponseWriter, r *http.Request) {
|
2021-07-26 15:31:10 +02:00
|
|
|
if ti.status == http.StatusOK {
|
|
|
|
q := metricQuery{}
|
|
|
|
decoder := json.NewDecoder(r.Body)
|
|
|
|
err := decoder.Decode(&q)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
|
|
|
numberOfMetrics := len(q.Metrics)
|
|
|
|
assert.Equal(t, 1, numberOfMetrics, "expected 1 metrics, got %d", numberOfMetrics)
|
|
|
|
metric := q.Metrics[0]
|
|
|
|
if ti.key != "" {
|
|
|
|
numberOfTags := len(metric.Tags)
|
|
|
|
assert.Equal(t, 1, numberOfTags, "expected 1 metric, got %d", numberOfTags)
|
|
|
|
tag := metric.Tags["key"][0]
|
|
|
|
assert.Equal(t, ti.key, tag, "expected key '%s' as tag, got '%s'", ti.key, tag)
|
|
|
|
|
|
|
|
numberOfTagGroups := len(metric.GroupBy)
|
|
|
|
assert.Equal(t, 1, numberOfTagGroups, "expected 1 GroupBy tag, got %d", numberOfTagGroups)
|
|
|
|
tagGroups := metric.GroupBy[0]
|
|
|
|
|
|
|
|
numberOfTagGroupTags := len(tagGroups.Tags)
|
|
|
|
assert.Equal(t, 1, numberOfTagGroupTags, "expected 1 GroupBy tag, got %d", numberOfTagGroupTags)
|
|
|
|
|
|
|
|
expectedGroupByTag := "key"
|
|
|
|
groupByTag := tagGroups.Tags[0]
|
|
|
|
assert.Equal(t, expectedGroupByTag, groupByTag, "expected GroupBy tag '%s', got '%s'", expectedGroupByTag, groupByTag)
|
|
|
|
} else {
|
|
|
|
_, ok := metric.Tags["key"]
|
|
|
|
assert.Equal(t, false, ok)
|
|
|
|
assert.Equal(t, 0, len(metric.GroupBy))
|
|
|
|
}
|
|
|
|
}
|
2018-10-29 14:26:25 +01:00
|
|
|
w.WriteHeader(ti.status)
|
2019-04-27 15:35:08 +02:00
|
|
|
_, err := w.Write([]byte(ti.body))
|
|
|
|
assert.NoError(t, err)
|
2018-10-29 14:26:25 +01:00
|
|
|
}),
|
|
|
|
)
|
|
|
|
defer ts.Close()
|
|
|
|
|
|
|
|
zmonClient := NewZMONClient(ts.URL, client)
|
|
|
|
dataPoints, err := zmonClient.Query(1, ti.key, nil, ti.aggregators, ti.duration)
|
|
|
|
assert.Equal(t, ti.err, err)
|
|
|
|
assert.Len(t, dataPoints, len(ti.dataPoints))
|
|
|
|
assert.Equal(t, ti.dataPoints, dataPoints)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestDurationToSampling(tt *testing.T) {
|
|
|
|
for _, ti := range []struct {
|
|
|
|
msg string
|
|
|
|
duration time.Duration
|
|
|
|
sampling sampling
|
|
|
|
}{
|
|
|
|
{
|
|
|
|
msg: "1 hour should map to hours sampling",
|
|
|
|
duration: 1 * time.Hour,
|
|
|
|
sampling: sampling{
|
|
|
|
Unit: "hours",
|
|
|
|
Value: 1,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
msg: "2 years should map to years sampling",
|
|
|
|
duration: 2 * day * 365,
|
|
|
|
sampling: sampling{
|
|
|
|
Unit: "years",
|
|
|
|
Value: 2,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
msg: "1 nanosecond should map to 0 milliseconds sampling",
|
|
|
|
duration: 1,
|
|
|
|
sampling: sampling{
|
|
|
|
Unit: "milliseconds",
|
|
|
|
Value: 0,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
} {
|
|
|
|
tt.Run(ti.msg, func(t *testing.T) {
|
|
|
|
assert.Equal(t, durationToSampling(ti.duration), ti.sampling)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|