linkerd2/controller/heartbeat/heartbeat_test.go

218 lines
4.4 KiB
Go

package heartbeat
import (
"context"
"fmt"
"net/http"
"net/http/httptest"
"net/url"
"testing"
"github.com/go-test/deep"
"github.com/linkerd/linkerd2/pkg/k8s"
"github.com/linkerd/linkerd2/pkg/prometheus"
"github.com/prometheus/common/model"
)
func TestK8sValues(t *testing.T) {
testCases := []struct {
namespace string
k8sConfigs []string
expected url.Values
}{
{
"linkerd",
[]string{`
kind: ConfigMap
apiVersion: v1
metadata:
name: linkerd-config
namespace: linkerd
creationTimestamp: 2019-02-15T12:34:56Z
uid: fake-uuid`,
},
url.Values{
"k8s-version": []string{"v0.0.0-master+$Format:%H$"},
"install-time": []string{"1550234096"},
"uuid": []string{"fake-uuid"},
},
},
{
"bad-ns",
[]string{`
kind: ConfigMap
apiVersion: v1
metadata:
name: linkerd-config
namespace: linkerd
uid: fake-uuid`,
},
url.Values{
"k8s-version": []string{"v0.0.0-master+$Format:%H$"},
},
},
{
"linkerd",
[]string{`
kind: ConfigMap
apiVersion: v1
metadata:
name: linkerd-config
namespace: linkerd
creationTimestamp: 2019-02-15T12:34:56Z
uid: fake-uuid
data:
values: |
linkerdVersion: stable-2.10`, `
kind: Namespace
apiVersion: v1
metadata:
name: linkerd-viz
labels:
linkerd.io/extension: viz`,
},
url.Values{
"k8s-version": []string{"v0.0.0-master+$Format:%H$"},
"install-time": []string{"1550234096"},
"uuid": []string{"fake-uuid"},
"ext-viz": []string{"1"},
},
},
}
ctx := context.Background()
for i, tc := range testCases {
tc := tc // pin
t.Run(fmt.Sprintf("%d", i), func(t *testing.T) {
k8sAPI, err := k8s.NewFakeAPI(tc.k8sConfigs...)
if err != nil {
t.Fatalf("NewFakeAPI returned an error: %s", err)
}
v := K8sValues(ctx, k8sAPI, tc.namespace)
if diff := deep.Equal(v, tc.expected); diff != nil {
t.Fatalf("K8sValues %v", diff)
}
})
}
}
func TestPromValues(t *testing.T) {
testCases := []struct {
namespace string
promRes model.Value
expected url.Values
}{
{
"linkerd",
model.Vector{
&model.Sample{
Metric: model.Metric{"pod": "emojivoto-meshed"},
Value: 100.1234,
Timestamp: 456,
},
},
url.Values{
"total-rps": []string{"100"},
"meshed-pods": []string{"100"},
"p99-handle-us": []string{"100"},
"max-mem-linkerd-proxy": []string{"100"},
"max-mem-destination": []string{"100"},
"max-mem-prometheus": []string{"100"},
"p95-cpu-linkerd-proxy": []string{"100.123"},
"p95-cpu-destination": []string{"100.123"},
"p95-cpu-prometheus": []string{"100.123"},
"proxy-injector-injections": []string{"100"},
},
},
{
"bad-ns",
model.Vector{},
url.Values{},
},
}
for i, tc := range testCases {
tc := tc // pin
t.Run(fmt.Sprintf("%d", i), func(t *testing.T) {
v := PromValues(&prometheus.MockProm{Res: tc.promRes}, tc.namespace)
if diff := deep.Equal(v, tc.expected); diff != nil {
t.Fatalf("PromValues %v", diff)
}
})
}
}
func TestMergeValues(t *testing.T) {
testCases := []struct {
v1, v2, expected url.Values
}{
{
url.Values{
"a": []string{"b"},
"c": []string{"d"},
},
url.Values{
"e": []string{"f"},
"g": []string{"h"},
},
url.Values{
"a": []string{"b"},
"c": []string{"d"},
"e": []string{"f"},
"g": []string{"h"},
},
},
{
url.Values{},
url.Values{},
url.Values{},
},
}
for i, tc := range testCases {
tc := tc // pin
t.Run(fmt.Sprintf("%d", i), func(t *testing.T) {
v := MergeValues(tc.v1, tc.v2)
if diff := deep.Equal(v, tc.expected); diff != nil {
t.Fatalf("MergeValues %v", diff)
}
})
}
}
func TestSend(t *testing.T) {
testCases := []struct {
v url.Values
err error
}{
{
url.Values{
"a": []string{"b"},
"c": []string{"d"},
},
nil,
},
}
for i, tc := range testCases {
tc := tc // pin
t.Run(fmt.Sprintf("%d", i), func(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(
func(w http.ResponseWriter, r *http.Request) {
if diff := deep.Equal(r.URL.Query(), tc.v); diff != nil {
t.Fatalf("Send queried for: %+v, expected: %+v", r.URL.Query(), tc.v)
}
w.Write([]byte(`{"stable":"stable-a.b.c","edge":"edge-d.e.f"}`))
}),
)
defer ts.Close()
err := send(ts.Client(), ts.URL, tc.v)
if diff := deep.Equal(err, tc.err); diff != nil {
t.Fatalf("Send: %+v", diff)
}
})
}
}