linkerd2/controller/api/public/edges_test.go

170 lines
5.2 KiB
Go

package public
import (
"context"
"testing"
"github.com/golang/protobuf/proto"
pb "github.com/linkerd/linkerd2/controller/gen/public"
pkgK8s "github.com/linkerd/linkerd2/pkg/k8s"
"github.com/prometheus/common/model"
)
const (
clientIDLabel = model.LabelName("client_id")
serverIDLabel = model.LabelName("server_id")
resourceLabel = model.LabelName("deployment")
)
type edgesExpected struct {
expectedStatRPC
req pb.EdgesRequest // the request we would like to test
expectedResponse pb.EdgesResponse // the edges response we expect
}
func genInboundPromSample(resourceNamespace, resourceName, clientID string) *model.Sample {
return &model.Sample{
Metric: model.Metric{
resourceLabel: model.LabelValue(resourceName),
namespaceLabel: model.LabelValue(resourceNamespace),
clientIDLabel: model.LabelValue(clientID),
},
Value: 123,
Timestamp: 456,
}
}
func genOutboundPromSample(resourceNamespace, resourceName, resourceNameDst, resourceNamespaceDst, serverID string) *model.Sample {
dstResourceLabel := "dst_" + resourceLabel
return &model.Sample{
Metric: model.Metric{
resourceLabel: model.LabelValue(resourceName),
namespaceLabel: model.LabelValue(resourceNamespace),
dstNamespaceLabel: model.LabelValue(resourceNamespaceDst),
dstResourceLabel: model.LabelValue(resourceNameDst),
serverIDLabel: model.LabelValue(serverID),
},
Value: 123,
Timestamp: 456,
}
}
func testEdges(t *testing.T, expectations []edgesExpected) {
for _, exp := range expectations {
mockProm, fakeGrpcServer, err := newMockGrpcServer(exp.expectedStatRPC)
if err != nil {
t.Fatalf("Error creating mock grpc server: %s", err)
}
rsp, err := fakeGrpcServer.Edges(context.TODO(), &exp.req)
if err != exp.err {
t.Fatalf("Expected error: %s, Got: %s", exp.err, err)
}
err = exp.verifyPromQueries(mockProm)
if err != nil {
t.Fatal(err)
}
rspEdgeRows := rsp.GetOk().Edges
if len(rspEdgeRows) != len(exp.expectedResponse.GetOk().Edges) {
t.Fatalf(
"Expected [%d] edge rows, got [%d].\nExpected:\n%s\nGot:\n%s",
len(exp.expectedResponse.GetOk().Edges),
len(rspEdgeRows),
exp.expectedResponse.GetOk().Edges,
rspEdgeRows,
)
}
for i, st := range rspEdgeRows {
expected := exp.expectedResponse.GetOk().Edges[i]
if !proto.Equal(st, expected) {
t.Fatalf("Expected: %+v\n Got: %+v\n", expected, st)
}
}
if !proto.Equal(exp.expectedResponse.GetOk(), rsp.GetOk()) {
t.Fatalf("Expected edgesOkResp: %+v\n Got: %+v", &exp.expectedResponse, rsp)
}
}
}
func TestEdges(t *testing.T) {
mockPromResponse := model.Vector{
genInboundPromSample("emojivoto", "emoji", "web.emojivoto.serviceaccount.identity.linkerd.cluster.local"),
genInboundPromSample("emojivoto", "voting", "web.emojivoto.serviceaccount.identity.linkerd.cluster.local"),
genInboundPromSample("emojivoto", "web", "default.emojivoto.serviceaccount.identity.linkerd.cluster.local"),
genInboundPromSample("linkerd", "linkerd-prometheus", "linkerd-controller.linkerd.identity.linkerd.cluster.local"),
genOutboundPromSample("emojivoto", "web", "emoji", "emojivoto", "emoji.emojivoto.serviceaccount.identity.linkerd.cluster.local"),
genOutboundPromSample("emojivoto", "web", "voting", "emojivoto", "voting.emojivoto.serviceaccount.identity.linkerd.cluster.local"),
genOutboundPromSample("emojivoto", "vote-bot", "web", "emojivoto", "web.emojivoto.serviceaccount.identity.linkerd.cluster.local"),
genOutboundPromSample("linkerd", "linkerd-controller", "linkerd-prometheus", "linkerd", "linkerd-prometheus.linkerd.identity.linkerd.cluster.local"),
}
t.Run("Successfully returns edges for resource type Deployment and namespace emojivoto", func(t *testing.T) {
expectations := []edgesExpected{
{
expectedStatRPC: expectedStatRPC{
err: nil,
mockPromResponse: mockPromResponse,
},
req: pb.EdgesRequest{
Selector: &pb.ResourceSelection{
Resource: &pb.Resource{
Namespace: "emojivoto",
Type: pkgK8s.Deployment,
},
},
},
expectedResponse: GenEdgesResponse("deployment", "emojivoto"),
}}
testEdges(t, expectations)
})
t.Run("Successfully returns edges for resource type Deployment and namespace linkerd", func(t *testing.T) {
expectations := []edgesExpected{
{
expectedStatRPC: expectedStatRPC{
err: nil,
mockPromResponse: mockPromResponse,
},
req: pb.EdgesRequest{
Selector: &pb.ResourceSelection{
Resource: &pb.Resource{
Namespace: "linkerd",
Type: pkgK8s.Deployment,
},
},
},
expectedResponse: GenEdgesResponse("deployment", "linkerd"),
}}
testEdges(t, expectations)
})
t.Run("Successfully returns edges for resource type Deployment and all namespaces", func(t *testing.T) {
expectations := []edgesExpected{
{
expectedStatRPC: expectedStatRPC{
err: nil,
mockPromResponse: mockPromResponse,
},
req: pb.EdgesRequest{
Selector: &pb.ResourceSelection{
Resource: &pb.Resource{
Type: pkgK8s.Deployment,
},
},
},
expectedResponse: GenEdgesResponse("deployment", "all"),
}}
testEdges(t, expectations)
})
}