linkerd2/controller/api/public/grpc_server_test.go

177 lines
4.0 KiB
Go

package public
import (
"context"
"sort"
"testing"
"github.com/golang/protobuf/ptypes/duration"
tap "github.com/linkerd/linkerd2/controller/gen/controller/tap"
pb "github.com/linkerd/linkerd2/controller/gen/public"
"github.com/linkerd/linkerd2/controller/k8s"
"github.com/prometheus/common/model"
)
type listPodsExpected struct {
err error
k8sRes []string
promRes model.Value
res pb.ListPodsResponse
}
// sort Pods in ListPodResponses for easier comparison
type ByPod []*pb.Pod
func (bp ByPod) Len() int { return len(bp) }
func (bp ByPod) Swap(i, j int) { bp[i], bp[j] = bp[j], bp[i] }
func (bp ByPod) Less(i, j int) bool { return bp[i].Name <= bp[j].Name }
func listPodResponsesEqual(a pb.ListPodsResponse, b pb.ListPodsResponse) bool {
if len(a.Pods) != len(b.Pods) {
return false
}
sort.Sort(ByPod(a.Pods))
sort.Sort(ByPod(b.Pods))
for i := 0; i < len(a.Pods); i++ {
aPod := a.Pods[i]
bPod := b.Pods[i]
if (aPod.Name != bPod.Name) ||
(aPod.Added != bPod.Added) ||
(aPod.Status != bPod.Status) ||
(aPod.PodIP != bPod.PodIP) ||
(aPod.GetDeployment() != bPod.GetDeployment()) {
return false
}
if (aPod.SinceLastReport == nil && bPod.SinceLastReport != nil) ||
(aPod.SinceLastReport != nil && bPod.SinceLastReport == nil) {
return false
}
}
return true
}
func TestListPods(t *testing.T) {
t.Run("Successfully performs a query based on resource type", func(t *testing.T) {
expectations := []listPodsExpected{
listPodsExpected{
err: nil,
promRes: model.Vector{
&model.Sample{
Metric: model.Metric{"pod": "emojivoto-meshed"},
Timestamp: 456,
},
},
k8sRes: []string{`
apiVersion: v1
kind: Pod
metadata:
name: emojivoto-meshed
namespace: emojivoto
labels:
pod-template-hash: hash-meshed
ownerReferences:
- apiVersion: extensions/v1beta1
kind: ReplicaSet
name: rs-emojivoto-meshed
status:
phase: Running
podIP: 1.2.3.4
`, `
apiVersion: v1
kind: Pod
metadata:
name: emojivoto-not-meshed
namespace: emojivoto
labels:
pod-template-hash: hash-not-meshed
ownerReferences:
- apiVersion: extensions/v1beta1
kind: ReplicaSet
name: rs-emojivoto-not-meshed
status:
phase: Pending
podIP: 4.3.2.1
`, `
apiVersion: apps/v1beta2
kind: ReplicaSet
metadata:
name: rs-emojivoto-meshed
namespace: emojivoto
ownerReferences:
- apiVersion: extensions/v1beta1
kind: Deployment
name: meshed-deployment
spec:
selector:
matchLabels:
pod-template-hash: hash-meshed
`, `
apiVersion: apps/v1beta2
kind: ReplicaSet
metadata:
name: rs-emojivoto-not-meshed
namespace: emojivoto
ownerReferences:
- apiVersion: extensions/v1beta1
kind: Deployment
name: not-meshed-deployment
spec:
selector:
matchLabels:
pod-template-hash: hash-not-meshed
`,
},
res: pb.ListPodsResponse{
Pods: []*pb.Pod{
&pb.Pod{
Name: "emojivoto/emojivoto-meshed",
Added: true,
SinceLastReport: &duration.Duration{},
Status: "Running",
PodIP: "1.2.3.4",
Owner: &pb.Pod_Deployment{Deployment: "emojivoto/meshed-deployment"},
},
&pb.Pod{
Name: "emojivoto/emojivoto-not-meshed",
Status: "Pending",
PodIP: "4.3.2.1",
Owner: &pb.Pod_Deployment{Deployment: "emojivoto/not-meshed-deployment"},
},
},
},
},
}
for _, exp := range expectations {
k8sAPI, err := k8s.NewFakeAPI("", exp.k8sRes...)
if err != nil {
t.Fatalf("NewFakeAPI returned an error: %s", err)
}
fakeGrpcServer := newGrpcServer(
&MockProm{Res: exp.promRes},
tap.NewTapClient(nil),
k8sAPI,
"linkerd",
[]string{},
)
k8sAPI.Sync(nil)
rsp, err := fakeGrpcServer.ListPods(context.TODO(), &pb.ListPodsRequest{})
if err != exp.err {
t.Fatalf("Expected error: %s, Got: %s", exp.err, err)
}
if !listPodResponsesEqual(exp.res, *rsp) {
t.Fatalf("Expected: %+v, Got: %+v", &exp.res, rsp)
}
}
})
}