linkerd2/viz/cmd/profile_test.go

135 lines
3.3 KiB
Go

package cmd
import (
"context"
"net/http"
"net/http/httptest"
"testing"
"time"
sp "github.com/linkerd/linkerd2/controller/gen/apis/serviceprofile/v1alpha2"
"github.com/linkerd/linkerd2/pkg/k8s"
"github.com/linkerd/linkerd2/pkg/profiles"
"github.com/linkerd/linkerd2/pkg/protohttp"
metricsPb "github.com/linkerd/linkerd2/viz/metrics-api/gen/viz"
tapPb "github.com/linkerd/linkerd2/viz/tap/gen/tap"
"github.com/linkerd/linkerd2/viz/tap/pkg"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
func TestTapToServiceProfile(t *testing.T) {
name := "service-name"
namespace := "service-namespace"
clusterDomain := "service-cluster.local"
tapDuration := 5 * time.Second
routeLimit := 20
params := pkg.TapRequestParams{
Resource: "deploy/" + name,
Namespace: namespace,
}
tapReq, err := pkg.BuildTapByResourceRequest(params)
if err != nil {
t.Fatalf("Unexpected error: %v", err)
}
event1 := pkg.CreateTapEvent(
&tapPb.TapEvent_Http{
Event: &tapPb.TapEvent_Http_RequestInit_{
RequestInit: &tapPb.TapEvent_Http_RequestInit{
Id: &tapPb.TapEvent_Http_StreamId{
Base: 1,
},
Authority: "",
Path: "/emojivoto.v1.VotingService/VoteFire",
Method: &metricsPb.HttpMethod{
Type: &metricsPb.HttpMethod_Registered_{
Registered: metricsPb.HttpMethod_POST,
},
},
},
},
},
map[string]string{},
tapPb.TapEvent_INBOUND,
)
event2 := pkg.CreateTapEvent(
&tapPb.TapEvent_Http{
Event: &tapPb.TapEvent_Http_RequestInit_{
RequestInit: &tapPb.TapEvent_Http_RequestInit{
Id: &tapPb.TapEvent_Http_StreamId{
Base: 2,
},
Authority: "",
Path: "/my/path/hi",
Method: &metricsPb.HttpMethod{
Type: &metricsPb.HttpMethod_Registered_{
Registered: metricsPb.HttpMethod_GET,
},
},
},
},
},
map[string]string{},
tapPb.TapEvent_INBOUND,
)
kubeAPI, err := k8s.NewFakeAPI()
if err != nil {
t.Fatalf("Unexpected error: %v", err)
}
ts := httptest.NewServer(http.HandlerFunc(
func(w http.ResponseWriter, r *http.Request) {
for _, event := range []*tapPb.TapEvent{event1, event2} {
event := event // pin
err = protohttp.WriteProtoToHTTPResponse(w, event)
if err != nil {
t.Fatalf("Unexpected error: %v", err)
}
}
}),
)
defer ts.Close()
kubeAPI.Config.Host = ts.URL
expectedServiceProfile := sp.ServiceProfile{
TypeMeta: profiles.ServiceProfileMeta,
ObjectMeta: metav1.ObjectMeta{
Name: name + "." + namespace + ".svc." + clusterDomain,
Namespace: namespace,
},
Spec: sp.ServiceProfileSpec{
Routes: []*sp.RouteSpec{
{
Name: "GET /my/path/hi",
Condition: &sp.RequestMatch{
PathRegex: `/my/path/hi`,
Method: "GET",
},
},
{
Name: "POST /emojivoto.v1.VotingService/VoteFire",
Condition: &sp.RequestMatch{
PathRegex: `/emojivoto\.v1\.VotingService/VoteFire`,
Method: "POST",
},
},
},
},
}
actualServiceProfile, err := tapToServiceProfile(context.Background(), kubeAPI, tapReq, namespace, name, clusterDomain, tapDuration, routeLimit)
if err != nil {
t.Fatalf("Failed to create ServiceProfile: %v", err)
}
err = profiles.ServiceProfileYamlEquals(actualServiceProfile, expectedServiceProfile)
if err != nil {
t.Fatalf("ServiceProfiles are not equal: %v", err)
}
}