mirror of https://github.com/linkerd/linkerd2.git
Adding unit test for CLI edges command (#2837)
Adds a unit test for the `linkerd edges` command.
This commit is contained in:
parent
b9cc66c6c8
commit
8c496e3d0d
|
@ -112,14 +112,8 @@ func validateEdgesRequestInputs(targets []pb.Resource, options *edgesOptions) er
|
|||
return fmt.Errorf("Edges cannot be returned for a specific resource name; remove %s from query", target.Name)
|
||||
}
|
||||
switch target.Type {
|
||||
case "authority":
|
||||
case "authority", "service", "all":
|
||||
return fmt.Errorf("Resource type is not supported: %s", target.Type)
|
||||
case "service":
|
||||
return fmt.Errorf("Resource type is not supported: %s", target.Type)
|
||||
case "all":
|
||||
return fmt.Errorf("Resource type is not supported: %s", target.Type)
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,153 @@
|
|||
package cmd
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/linkerd/linkerd2/controller/api/public"
|
||||
)
|
||||
|
||||
type edgesParamsExp struct {
|
||||
options *edgesOptions
|
||||
resSrc []string
|
||||
resDst []string
|
||||
resClient []string
|
||||
resServer []string
|
||||
resMsg []string
|
||||
resourceType string
|
||||
file string
|
||||
}
|
||||
|
||||
func TestEdges(t *testing.T) {
|
||||
// response content for SRC, DST, CLIENT, SERVER and MSG
|
||||
var (
|
||||
resSrc = []string{
|
||||
"web-57b7f9db85-297dw",
|
||||
"web-57b7f9db85-297dw",
|
||||
"vote-bot-7466ffc7f7-5rc4l",
|
||||
}
|
||||
resDst = []string{
|
||||
"emoji-646ddcc5f9-zjgs9",
|
||||
"voting-689f845d98-rj6nz",
|
||||
"web-57b7f9db85-297dw",
|
||||
}
|
||||
resClient = []string{
|
||||
"web.emojivoto.serviceaccount.identity.linkerd.cluster.local",
|
||||
"web.emojivoto.serviceaccount.identity.linkerd.cluster.local",
|
||||
"default.emojivoto.serviceaccount.identity.linkerd.cluster.local",
|
||||
}
|
||||
resServer = []string{
|
||||
"emoji.emojivoto.serviceaccount.identity.linkerd.cluster.local",
|
||||
"voting.emojivoto.serviceaccount.identity.linkerd.cluster.local",
|
||||
"web.emojivoto.serviceaccount.identity.linkerd.cluster.local",
|
||||
}
|
||||
resMsg = []string{"", "", ""}
|
||||
)
|
||||
|
||||
options := newEdgesOptions()
|
||||
options.namespace = "emojivoto"
|
||||
options.outputFormat = tableOutput
|
||||
t.Run("Returns edges", func(t *testing.T) {
|
||||
testEdgesCall(edgesParamsExp{
|
||||
options: options,
|
||||
resourceType: "pod",
|
||||
resSrc: resSrc,
|
||||
resDst: resDst,
|
||||
resClient: resClient,
|
||||
resServer: resServer,
|
||||
resMsg: resMsg,
|
||||
file: "edges_one_output.golden",
|
||||
}, t)
|
||||
})
|
||||
|
||||
options.outputFormat = jsonOutput
|
||||
t.Run("Returns edges (json)", func(t *testing.T) {
|
||||
testEdgesCall(edgesParamsExp{
|
||||
options: options,
|
||||
resourceType: "pod",
|
||||
resSrc: resSrc,
|
||||
resDst: resDst,
|
||||
resClient: resClient,
|
||||
resServer: resServer,
|
||||
resMsg: resMsg,
|
||||
file: "edges_one_output_json.golden",
|
||||
}, t)
|
||||
})
|
||||
|
||||
t.Run("Returns an error if outputFormat specified is not table or json", func(t *testing.T) {
|
||||
options.outputFormat = wideOutput
|
||||
args := []string{"pod"}
|
||||
expectedError := "--output currently only supports table and json"
|
||||
|
||||
_, err := buildEdgesRequests(args, options)
|
||||
if err == nil || err.Error() != expectedError {
|
||||
t.Fatalf("Expected error [%s] instead got [%s]", expectedError, err)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("Returns an error if request includes the resource name", func(t *testing.T) {
|
||||
options.outputFormat = tableOutput
|
||||
args := []string{"pod/pod-name"}
|
||||
expectedError := "Edges cannot be returned for a specific resource name; remove pod-name from query"
|
||||
|
||||
_, err := buildEdgesRequests(args, options)
|
||||
if err == nil || err.Error() != expectedError {
|
||||
t.Fatalf("Expected error [%s] instead got [%s]", expectedError, err)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("Returns an error if request is for authority", func(t *testing.T) {
|
||||
options.outputFormat = tableOutput
|
||||
args := []string{"authority"}
|
||||
expectedError := "Resource type is not supported: authority"
|
||||
|
||||
_, err := buildEdgesRequests(args, options)
|
||||
if err == nil || err.Error() != expectedError {
|
||||
t.Fatalf("Expected error [%s] instead got [%s]", expectedError, err)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("Returns an error if request is for service", func(t *testing.T) {
|
||||
options.outputFormat = tableOutput
|
||||
args := []string{"service"}
|
||||
expectedError := "Resource type is not supported: service"
|
||||
|
||||
_, err := buildEdgesRequests(args, options)
|
||||
if err == nil || err.Error() != expectedError {
|
||||
t.Fatalf("Expected error [%s] instead got [%s]", expectedError, err)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("Returns an error if request is for all resource types", func(t *testing.T) {
|
||||
options.outputFormat = tableOutput
|
||||
args := []string{"all"}
|
||||
expectedError := "Resource type is not supported: all"
|
||||
|
||||
_, err := buildEdgesRequests(args, options)
|
||||
if err == nil || err.Error() != expectedError {
|
||||
t.Fatalf("Expected error [%s] instead got [%s]", expectedError, err)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func testEdgesCall(exp edgesParamsExp, t *testing.T) {
|
||||
mockClient := &public.MockAPIClient{}
|
||||
response := public.GenEdgesResponse(exp.resourceType, exp.resSrc, exp.resDst, exp.resClient, exp.resServer, exp.resMsg)
|
||||
|
||||
mockClient.EdgesResponseToReturn = &response
|
||||
|
||||
args := []string{"pod"}
|
||||
reqs, err := buildEdgesRequests(args, exp.options)
|
||||
if err != nil {
|
||||
t.Fatalf("Unexpected error: %v", err)
|
||||
}
|
||||
|
||||
resp, err := requestEdgesFromAPI(mockClient, reqs[0])
|
||||
if err != nil {
|
||||
t.Fatalf("Unexpected error: %v", err)
|
||||
}
|
||||
|
||||
rows := edgesRespToRows(resp)
|
||||
output := renderEdgeStats(rows, exp.options)
|
||||
|
||||
diffTestdata(t, exp.file, output)
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
SRC DST CLIENT SERVER MSG
|
||||
web-57b7f9db85-297dw emoji-646ddcc5f9-zjgs9 web.emojivoto emoji.emojivoto -
|
||||
web-57b7f9db85-297dw voting-689f845d98-rj6nz web.emojivoto voting.emojivoto -
|
||||
vote-bot-7466ffc7f7-5rc4l web-57b7f9db85-297dw default.emojivoto web.emojivoto -
|
|
@ -0,0 +1,23 @@
|
|||
[
|
||||
{
|
||||
"src": "web-57b7f9db85-297dw",
|
||||
"dst": "emoji-646ddcc5f9-zjgs9",
|
||||
"client_id": "web.emojivoto",
|
||||
"server_id": "emoji.emojivoto",
|
||||
"no_tls_reason": "-"
|
||||
},
|
||||
{
|
||||
"src": "web-57b7f9db85-297dw",
|
||||
"dst": "voting-689f845d98-rj6nz",
|
||||
"client_id": "web.emojivoto",
|
||||
"server_id": "voting.emojivoto",
|
||||
"no_tls_reason": "-"
|
||||
},
|
||||
{
|
||||
"src": "vote-bot-7466ffc7f7-5rc4l",
|
||||
"dst": "web-57b7f9db85-297dw",
|
||||
"client_id": "default.emojivoto",
|
||||
"server_id": "web.emojivoto",
|
||||
"no_tls_reason": "-"
|
||||
}
|
||||
]
|
|
@ -228,6 +228,37 @@ func GenStatSummaryResponse(resName, resType string, resNs []string, counts *Pod
|
|||
return resp
|
||||
}
|
||||
|
||||
// GenEdgesResponse generates a mock Public API StatSummaryResponse
|
||||
// object.
|
||||
func GenEdgesResponse(resourceType string, resSrc, resDst, resClient, resServer, msg []string) pb.EdgesResponse {
|
||||
edges := []*pb.Edge{}
|
||||
for i := range resSrc {
|
||||
edge := &pb.Edge{
|
||||
Src: &pb.Resource{
|
||||
Name: resSrc[i],
|
||||
Type: resourceType,
|
||||
},
|
||||
Dst: &pb.Resource{
|
||||
Name: resDst[i],
|
||||
Type: resourceType,
|
||||
},
|
||||
ClientId: resClient[i],
|
||||
ServerId: resServer[i],
|
||||
NoIdentityMsg: msg[i],
|
||||
}
|
||||
edges = append(edges, edge)
|
||||
}
|
||||
|
||||
resp := pb.EdgesResponse{
|
||||
Response: &pb.EdgesResponse_Ok_{
|
||||
Ok: &pb.EdgesResponse_Ok{
|
||||
Edges: edges,
|
||||
},
|
||||
},
|
||||
}
|
||||
return resp
|
||||
}
|
||||
|
||||
// GenTopRoutesResponse generates a mock Public API TopRoutesResponse object.
|
||||
func GenTopRoutesResponse(routes []string, counts []uint64, outbound bool, authority string) pb.TopRoutesResponse {
|
||||
rows := []*pb.RouteTable_Row{}
|
||||
|
|
Loading…
Reference in New Issue