mirror of https://github.com/grpc/grpc-go.git
xds: change the DumpResources API to return proto message containing the resource dump (#7240)
This commit is contained in:
parent
48b6b11b38
commit
a75dfa68c6
|
|
@ -34,10 +34,7 @@ import (
|
|||
internalgrpclog "google.golang.org/grpc/internal/grpclog"
|
||||
"google.golang.org/grpc/status"
|
||||
"google.golang.org/grpc/xds/internal/xdsclient"
|
||||
"google.golang.org/grpc/xds/internal/xdsclient/xdsresource"
|
||||
"google.golang.org/protobuf/types/known/timestamppb"
|
||||
|
||||
v3adminpb "github.com/envoyproxy/go-control-plane/envoy/admin/v3"
|
||||
v3statusgrpc "github.com/envoyproxy/go-control-plane/envoy/service/status/v3"
|
||||
v3statuspb "github.com/envoyproxy/go-control-plane/envoy/service/status/v3"
|
||||
)
|
||||
|
|
@ -77,7 +74,7 @@ func NewClientStatusDiscoveryServer() (*ClientStatusDiscoveryServer, error) {
|
|||
return s, nil
|
||||
}
|
||||
|
||||
// StreamClientStatus implementations interface ClientStatusDiscoveryServiceServer.
|
||||
// StreamClientStatus implements interface ClientStatusDiscoveryServiceServer.
|
||||
func (s *ClientStatusDiscoveryServer) StreamClientStatus(stream v3statusgrpc.ClientStatusDiscoveryService_StreamClientStatusServer) error {
|
||||
for {
|
||||
req, err := stream.Recv()
|
||||
|
|
@ -97,13 +94,13 @@ func (s *ClientStatusDiscoveryServer) StreamClientStatus(stream v3statusgrpc.Cli
|
|||
}
|
||||
}
|
||||
|
||||
// FetchClientStatus implementations interface ClientStatusDiscoveryServiceServer.
|
||||
// FetchClientStatus implements interface ClientStatusDiscoveryServiceServer.
|
||||
func (s *ClientStatusDiscoveryServer) FetchClientStatus(_ context.Context, req *v3statuspb.ClientStatusRequest) (*v3statuspb.ClientStatusResponse, error) {
|
||||
return s.buildClientStatusRespForReq(req)
|
||||
}
|
||||
|
||||
// buildClientStatusRespForReq fetches the status from the client, and returns
|
||||
// the response to be sent back to xdsclient.
|
||||
// buildClientStatusRespForReq fetches the status of xDS resources from the
|
||||
// xdsclient, and returns the response to be sent back to the csds client.
|
||||
//
|
||||
// If it returns an error, the error is a status error.
|
||||
func (s *ClientStatusDiscoveryServer) buildClientStatusRespForReq(req *v3statuspb.ClientStatusRequest) (*v3statuspb.ClientStatusResponse, error) {
|
||||
|
|
@ -119,16 +116,7 @@ func (s *ClientStatusDiscoveryServer) buildClientStatusRespForReq(req *v3statusp
|
|||
return nil, status.Errorf(codes.InvalidArgument, "node_matchers are not supported, request contains node_matchers: %v", req.NodeMatchers)
|
||||
}
|
||||
|
||||
dump := s.xdsClient.DumpResources()
|
||||
ret := &v3statuspb.ClientStatusResponse{
|
||||
Config: []*v3statuspb.ClientConfig{
|
||||
{
|
||||
Node: s.xdsClient.BootstrapConfig().NodeProto,
|
||||
GenericXdsConfigs: dumpToGenericXdsConfig(dump),
|
||||
},
|
||||
},
|
||||
}
|
||||
return ret, nil
|
||||
return s.xdsClient.DumpResources()
|
||||
}
|
||||
|
||||
// Close cleans up the resources.
|
||||
|
|
@ -137,45 +125,3 @@ func (s *ClientStatusDiscoveryServer) Close() {
|
|||
s.xdsClientClose()
|
||||
}
|
||||
}
|
||||
|
||||
func dumpToGenericXdsConfig(dump map[string]map[string]xdsresource.UpdateWithMD) []*v3statuspb.ClientConfig_GenericXdsConfig {
|
||||
var ret []*v3statuspb.ClientConfig_GenericXdsConfig
|
||||
for typeURL, updates := range dump {
|
||||
for name, update := range updates {
|
||||
config := &v3statuspb.ClientConfig_GenericXdsConfig{
|
||||
TypeUrl: typeURL,
|
||||
Name: name,
|
||||
VersionInfo: update.MD.Version,
|
||||
XdsConfig: update.Raw,
|
||||
LastUpdated: timestamppb.New(update.MD.Timestamp),
|
||||
ClientStatus: serviceStatusToProto(update.MD.Status),
|
||||
}
|
||||
if errState := update.MD.ErrState; errState != nil {
|
||||
config.ErrorState = &v3adminpb.UpdateFailureState{
|
||||
LastUpdateAttempt: timestamppb.New(errState.Timestamp),
|
||||
Details: errState.Err.Error(),
|
||||
VersionInfo: errState.Version,
|
||||
}
|
||||
}
|
||||
ret = append(ret, config)
|
||||
}
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func serviceStatusToProto(serviceStatus xdsresource.ServiceStatus) v3adminpb.ClientResourceStatus {
|
||||
switch serviceStatus {
|
||||
case xdsresource.ServiceStatusUnknown:
|
||||
return v3adminpb.ClientResourceStatus_UNKNOWN
|
||||
case xdsresource.ServiceStatusRequested:
|
||||
return v3adminpb.ClientResourceStatus_REQUESTED
|
||||
case xdsresource.ServiceStatusNotExist:
|
||||
return v3adminpb.ClientResourceStatus_DOES_NOT_EXIST
|
||||
case xdsresource.ServiceStatusACKed:
|
||||
return v3adminpb.ClientResourceStatus_ACKED
|
||||
case xdsresource.ServiceStatusNACKed:
|
||||
return v3adminpb.ClientResourceStatus_NACKED
|
||||
default:
|
||||
return v3adminpb.ClientResourceStatus_UNKNOWN
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,6 +32,10 @@ import (
|
|||
"google.golang.org/grpc/xds/internal/xdsclient/transport"
|
||||
"google.golang.org/grpc/xds/internal/xdsclient/xdsresource"
|
||||
"google.golang.org/protobuf/types/known/anypb"
|
||||
"google.golang.org/protobuf/types/known/timestamppb"
|
||||
|
||||
v3adminpb "github.com/envoyproxy/go-control-plane/envoy/admin/v3"
|
||||
v3statuspb "github.com/envoyproxy/go-control-plane/envoy/service/status/v3"
|
||||
)
|
||||
|
||||
type watchState int
|
||||
|
|
@ -586,26 +590,54 @@ func (a *authority) reportLoad() (*load.Store, func()) {
|
|||
return a.transport.ReportLoad()
|
||||
}
|
||||
|
||||
func (a *authority) dumpResources() map[string]map[string]xdsresource.UpdateWithMD {
|
||||
func (a *authority) dumpResources() ([]*v3statuspb.ClientConfig_GenericXdsConfig, error) {
|
||||
a.resourcesMu.Lock()
|
||||
defer a.resourcesMu.Unlock()
|
||||
|
||||
dump := make(map[string]map[string]xdsresource.UpdateWithMD)
|
||||
var ret []*v3statuspb.ClientConfig_GenericXdsConfig
|
||||
for rType, resourceStates := range a.resources {
|
||||
states := make(map[string]xdsresource.UpdateWithMD)
|
||||
typeURL := rType.TypeURL()
|
||||
for name, state := range resourceStates {
|
||||
var raw *anypb.Any
|
||||
if state.cache != nil {
|
||||
raw = state.cache.Raw()
|
||||
}
|
||||
states[name] = xdsresource.UpdateWithMD{
|
||||
MD: state.md,
|
||||
Raw: raw,
|
||||
config := &v3statuspb.ClientConfig_GenericXdsConfig{
|
||||
TypeUrl: typeURL,
|
||||
Name: name,
|
||||
VersionInfo: state.md.Version,
|
||||
XdsConfig: raw,
|
||||
LastUpdated: timestamppb.New(state.md.Timestamp),
|
||||
ClientStatus: serviceStatusToProto(state.md.Status),
|
||||
}
|
||||
if errState := state.md.ErrState; errState != nil {
|
||||
config.ErrorState = &v3adminpb.UpdateFailureState{
|
||||
LastUpdateAttempt: timestamppb.New(errState.Timestamp),
|
||||
Details: errState.Err.Error(),
|
||||
VersionInfo: errState.Version,
|
||||
}
|
||||
}
|
||||
ret = append(ret, config)
|
||||
}
|
||||
dump[rType.TypeURL()] = states
|
||||
}
|
||||
return dump
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func serviceStatusToProto(serviceStatus xdsresource.ServiceStatus) v3adminpb.ClientResourceStatus {
|
||||
switch serviceStatus {
|
||||
case xdsresource.ServiceStatusUnknown:
|
||||
return v3adminpb.ClientResourceStatus_UNKNOWN
|
||||
case xdsresource.ServiceStatusRequested:
|
||||
return v3adminpb.ClientResourceStatus_REQUESTED
|
||||
case xdsresource.ServiceStatusNotExist:
|
||||
return v3adminpb.ClientResourceStatus_DOES_NOT_EXIST
|
||||
case xdsresource.ServiceStatusACKed:
|
||||
return v3adminpb.ClientResourceStatus_ACKED
|
||||
case xdsresource.ServiceStatusNACKed:
|
||||
return v3adminpb.ClientResourceStatus_NACKED
|
||||
default:
|
||||
return v3adminpb.ClientResourceStatus_UNKNOWN
|
||||
}
|
||||
}
|
||||
|
||||
func combineErrors(rType string, topLevelErrors []error, perResourceErrors map[string]error) error {
|
||||
|
|
|
|||
|
|
@ -24,6 +24,8 @@ import (
|
|||
"google.golang.org/grpc/internal/xds/bootstrap"
|
||||
"google.golang.org/grpc/xds/internal/xdsclient/load"
|
||||
"google.golang.org/grpc/xds/internal/xdsclient/xdsresource"
|
||||
|
||||
v3statuspb "github.com/envoyproxy/go-control-plane/envoy/service/status/v3"
|
||||
)
|
||||
|
||||
// XDSClient is a full fledged gRPC client which queries a set of discovery APIs
|
||||
|
|
@ -48,7 +50,7 @@ type XDSClient interface {
|
|||
|
||||
// DumpResources returns the status of the xDS resources. Returns a map of
|
||||
// resource type URLs to a map of resource names to resource state.
|
||||
DumpResources() map[string]map[string]xdsresource.UpdateWithMD
|
||||
DumpResources() (*v3statuspb.ClientStatusResponse, error)
|
||||
|
||||
ReportLoad(*bootstrap.ServerConfig) (*load.Store, func())
|
||||
|
||||
|
|
|
|||
|
|
@ -19,35 +19,30 @@
|
|||
package xdsclient
|
||||
|
||||
import (
|
||||
"google.golang.org/grpc/xds/internal/xdsclient/xdsresource"
|
||||
v3statuspb "github.com/envoyproxy/go-control-plane/envoy/service/status/v3"
|
||||
)
|
||||
|
||||
func appendMaps(dst, src map[string]map[string]xdsresource.UpdateWithMD) {
|
||||
// Iterate through the resource types.
|
||||
for rType, srcResources := range src {
|
||||
// Lookup/create the resource type specific map in the destination.
|
||||
dstResources := dst[rType]
|
||||
if dstResources == nil {
|
||||
dstResources = make(map[string]xdsresource.UpdateWithMD)
|
||||
dst[rType] = dstResources
|
||||
}
|
||||
|
||||
// Iterate through the resources within the resource type in the source,
|
||||
// and copy them over to the destination.
|
||||
for name, update := range srcResources {
|
||||
dstResources[name] = update
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DumpResources returns the status and contents of all xDS resources.
|
||||
func (c *clientImpl) DumpResources() map[string]map[string]xdsresource.UpdateWithMD {
|
||||
func (c *clientImpl) DumpResources() (*v3statuspb.ClientStatusResponse, error) {
|
||||
c.authorityMu.Lock()
|
||||
defer c.authorityMu.Unlock()
|
||||
dumps := make(map[string]map[string]xdsresource.UpdateWithMD)
|
||||
|
||||
var retCfg []*v3statuspb.ClientConfig_GenericXdsConfig
|
||||
for _, a := range c.authorities {
|
||||
dump := a.dumpResources()
|
||||
appendMaps(dumps, dump)
|
||||
cfg, err := a.dumpResources()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
retCfg = append(retCfg, cfg...)
|
||||
}
|
||||
return dumps
|
||||
|
||||
return &v3statuspb.ClientStatusResponse{
|
||||
Config: []*v3statuspb.ClientConfig{
|
||||
{
|
||||
// TODO: Populate ClientScope. Need to update go-control-plane dependency.
|
||||
Node: c.config.NodeProto,
|
||||
GenericXdsConfigs: retCfg,
|
||||
},
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,46 +20,22 @@ package xdsclient_test
|
|||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/google/go-cmp/cmp/cmpopts"
|
||||
"google.golang.org/grpc/internal/testutils"
|
||||
"google.golang.org/grpc/internal/testutils/xds/e2e"
|
||||
"google.golang.org/grpc/xds/internal/xdsclient"
|
||||
"google.golang.org/grpc/xds/internal/xdsclient/xdsresource"
|
||||
"google.golang.org/protobuf/testing/protocmp"
|
||||
"google.golang.org/protobuf/types/known/anypb"
|
||||
|
||||
v3adminpb "github.com/envoyproxy/go-control-plane/envoy/admin/v3"
|
||||
v3clusterpb "github.com/envoyproxy/go-control-plane/envoy/config/cluster/v3"
|
||||
v3endpointpb "github.com/envoyproxy/go-control-plane/envoy/config/endpoint/v3"
|
||||
v3listenerpb "github.com/envoyproxy/go-control-plane/envoy/config/listener/v3"
|
||||
v3routepb "github.com/envoyproxy/go-control-plane/envoy/config/route/v3"
|
||||
v3statuspb "github.com/envoyproxy/go-control-plane/envoy/service/status/v3"
|
||||
)
|
||||
|
||||
func compareDump(ctx context.Context, client xdsclient.XDSClient, want map[string]map[string]xdsresource.UpdateWithMD) error {
|
||||
var lastErr error
|
||||
for {
|
||||
if err := ctx.Err(); err != nil {
|
||||
return fmt.Errorf("Timeout when waiting for expected dump: %v", lastErr)
|
||||
}
|
||||
cmpOpts := cmp.Options{
|
||||
cmpopts.EquateEmpty(),
|
||||
cmp.Comparer(func(a, b time.Time) bool { return true }),
|
||||
cmpopts.EquateErrors(),
|
||||
protocmp.Transform(),
|
||||
}
|
||||
diff := cmp.Diff(want, client.DumpResources(), cmpOpts)
|
||||
if diff == "" {
|
||||
return nil
|
||||
}
|
||||
lastErr = fmt.Errorf("DumpResources() returned unexpected dump, diff (-want +got):\n%s", diff)
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
}
|
||||
}
|
||||
|
||||
func (s) TestDumpResources(t *testing.T) {
|
||||
// Initialize the xDS resources to be used in this test.
|
||||
ldsTargets := []string{"lds.target.good:0000", "lds.target.good:1111"}
|
||||
|
|
@ -107,7 +83,7 @@ func (s) TestDumpResources(t *testing.T) {
|
|||
// Dump resources and expect empty configs.
|
||||
ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout)
|
||||
defer cancel()
|
||||
if err := compareDump(ctx, client, nil); err != nil {
|
||||
if err := compareUpdateMetadata(ctx, client.DumpResources, nil); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
|
|
@ -124,25 +100,49 @@ func (s) TestDumpResources(t *testing.T) {
|
|||
for _, target := range edsTargets {
|
||||
xdsresource.WatchEndpoints(client, target, noopEndpointsWatcher{})
|
||||
}
|
||||
want := map[string]map[string]xdsresource.UpdateWithMD{
|
||||
"type.googleapis.com/envoy.config.listener.v3.Listener": {
|
||||
ldsTargets[0]: {MD: xdsresource.UpdateMetadata{Status: xdsresource.ServiceStatusRequested}},
|
||||
ldsTargets[1]: {MD: xdsresource.UpdateMetadata{Status: xdsresource.ServiceStatusRequested}},
|
||||
want := []*v3statuspb.ClientConfig_GenericXdsConfig{
|
||||
{
|
||||
TypeUrl: "type.googleapis.com/envoy.config.listener.v3.Listener",
|
||||
Name: ldsTargets[0],
|
||||
ClientStatus: v3adminpb.ClientResourceStatus_REQUESTED,
|
||||
},
|
||||
"type.googleapis.com/envoy.config.route.v3.RouteConfiguration": {
|
||||
rdsTargets[0]: {MD: xdsresource.UpdateMetadata{Status: xdsresource.ServiceStatusRequested}},
|
||||
rdsTargets[1]: {MD: xdsresource.UpdateMetadata{Status: xdsresource.ServiceStatusRequested}},
|
||||
{
|
||||
TypeUrl: "type.googleapis.com/envoy.config.listener.v3.Listener",
|
||||
Name: ldsTargets[1],
|
||||
ClientStatus: v3adminpb.ClientResourceStatus_REQUESTED,
|
||||
},
|
||||
"type.googleapis.com/envoy.config.cluster.v3.Cluster": {
|
||||
cdsTargets[0]: {MD: xdsresource.UpdateMetadata{Status: xdsresource.ServiceStatusRequested}},
|
||||
cdsTargets[1]: {MD: xdsresource.UpdateMetadata{Status: xdsresource.ServiceStatusRequested}},
|
||||
{
|
||||
TypeUrl: "type.googleapis.com/envoy.config.route.v3.RouteConfiguration",
|
||||
Name: rdsTargets[0],
|
||||
ClientStatus: v3adminpb.ClientResourceStatus_REQUESTED,
|
||||
},
|
||||
"type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment": {
|
||||
edsTargets[0]: {MD: xdsresource.UpdateMetadata{Status: xdsresource.ServiceStatusRequested}},
|
||||
edsTargets[1]: {MD: xdsresource.UpdateMetadata{Status: xdsresource.ServiceStatusRequested}},
|
||||
{
|
||||
TypeUrl: "type.googleapis.com/envoy.config.route.v3.RouteConfiguration",
|
||||
Name: rdsTargets[1],
|
||||
ClientStatus: v3adminpb.ClientResourceStatus_REQUESTED,
|
||||
},
|
||||
{
|
||||
TypeUrl: "type.googleapis.com/envoy.config.cluster.v3.Cluster",
|
||||
Name: cdsTargets[0],
|
||||
ClientStatus: v3adminpb.ClientResourceStatus_REQUESTED,
|
||||
},
|
||||
{
|
||||
TypeUrl: "type.googleapis.com/envoy.config.cluster.v3.Cluster",
|
||||
Name: cdsTargets[1],
|
||||
ClientStatus: v3adminpb.ClientResourceStatus_REQUESTED,
|
||||
},
|
||||
{
|
||||
TypeUrl: "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment",
|
||||
Name: edsTargets[0],
|
||||
ClientStatus: v3adminpb.ClientResourceStatus_REQUESTED,
|
||||
},
|
||||
{
|
||||
TypeUrl: "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment",
|
||||
Name: edsTargets[1],
|
||||
ClientStatus: v3adminpb.ClientResourceStatus_REQUESTED,
|
||||
},
|
||||
}
|
||||
if err := compareDump(ctx, client, want); err != nil {
|
||||
if err := compareUpdateMetadata(ctx, client.DumpResources, want); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
|
|
@ -158,25 +158,65 @@ func (s) TestDumpResources(t *testing.T) {
|
|||
}
|
||||
|
||||
// Dump resources and expect ACK configs.
|
||||
want = map[string]map[string]xdsresource.UpdateWithMD{
|
||||
"type.googleapis.com/envoy.config.listener.v3.Listener": {
|
||||
ldsTargets[0]: {Raw: listenerAnys[0], MD: xdsresource.UpdateMetadata{Status: xdsresource.ServiceStatusACKed, Version: "1"}},
|
||||
ldsTargets[1]: {Raw: listenerAnys[1], MD: xdsresource.UpdateMetadata{Status: xdsresource.ServiceStatusACKed, Version: "1"}},
|
||||
want = []*v3statuspb.ClientConfig_GenericXdsConfig{
|
||||
{
|
||||
TypeUrl: "type.googleapis.com/envoy.config.listener.v3.Listener",
|
||||
Name: ldsTargets[0],
|
||||
ClientStatus: v3adminpb.ClientResourceStatus_ACKED,
|
||||
VersionInfo: "1",
|
||||
XdsConfig: listenerAnys[0],
|
||||
},
|
||||
"type.googleapis.com/envoy.config.route.v3.RouteConfiguration": {
|
||||
rdsTargets[0]: {Raw: routeAnys[0], MD: xdsresource.UpdateMetadata{Status: xdsresource.ServiceStatusACKed, Version: "1"}},
|
||||
rdsTargets[1]: {Raw: routeAnys[1], MD: xdsresource.UpdateMetadata{Status: xdsresource.ServiceStatusACKed, Version: "1"}},
|
||||
{
|
||||
TypeUrl: "type.googleapis.com/envoy.config.listener.v3.Listener",
|
||||
Name: ldsTargets[1],
|
||||
ClientStatus: v3adminpb.ClientResourceStatus_ACKED,
|
||||
VersionInfo: "1",
|
||||
XdsConfig: listenerAnys[1],
|
||||
},
|
||||
"type.googleapis.com/envoy.config.cluster.v3.Cluster": {
|
||||
cdsTargets[0]: {Raw: clusterAnys[0], MD: xdsresource.UpdateMetadata{Status: xdsresource.ServiceStatusACKed, Version: "1"}},
|
||||
cdsTargets[1]: {Raw: clusterAnys[1], MD: xdsresource.UpdateMetadata{Status: xdsresource.ServiceStatusACKed, Version: "1"}},
|
||||
{
|
||||
TypeUrl: "type.googleapis.com/envoy.config.route.v3.RouteConfiguration",
|
||||
Name: rdsTargets[0],
|
||||
ClientStatus: v3adminpb.ClientResourceStatus_ACKED,
|
||||
VersionInfo: "1",
|
||||
XdsConfig: routeAnys[0],
|
||||
},
|
||||
"type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment": {
|
||||
edsTargets[0]: {Raw: endpointAnys[0], MD: xdsresource.UpdateMetadata{Status: xdsresource.ServiceStatusACKed, Version: "1"}},
|
||||
edsTargets[1]: {Raw: endpointAnys[1], MD: xdsresource.UpdateMetadata{Status: xdsresource.ServiceStatusACKed, Version: "1"}},
|
||||
{
|
||||
TypeUrl: "type.googleapis.com/envoy.config.route.v3.RouteConfiguration",
|
||||
Name: rdsTargets[1],
|
||||
ClientStatus: v3adminpb.ClientResourceStatus_ACKED,
|
||||
VersionInfo: "1",
|
||||
XdsConfig: routeAnys[1],
|
||||
},
|
||||
{
|
||||
TypeUrl: "type.googleapis.com/envoy.config.cluster.v3.Cluster",
|
||||
Name: cdsTargets[0],
|
||||
ClientStatus: v3adminpb.ClientResourceStatus_ACKED,
|
||||
VersionInfo: "1",
|
||||
XdsConfig: clusterAnys[0],
|
||||
},
|
||||
{
|
||||
TypeUrl: "type.googleapis.com/envoy.config.cluster.v3.Cluster",
|
||||
Name: cdsTargets[1],
|
||||
ClientStatus: v3adminpb.ClientResourceStatus_ACKED,
|
||||
VersionInfo: "1",
|
||||
XdsConfig: clusterAnys[1],
|
||||
},
|
||||
{
|
||||
TypeUrl: "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment",
|
||||
Name: edsTargets[0],
|
||||
ClientStatus: v3adminpb.ClientResourceStatus_ACKED,
|
||||
VersionInfo: "1",
|
||||
XdsConfig: endpointAnys[0],
|
||||
},
|
||||
{
|
||||
TypeUrl: "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment",
|
||||
Name: edsTargets[1],
|
||||
ClientStatus: v3adminpb.ClientResourceStatus_ACKED,
|
||||
VersionInfo: "1",
|
||||
XdsConfig: endpointAnys[1],
|
||||
},
|
||||
}
|
||||
if err := compareDump(ctx, client, want); err != nil {
|
||||
if err := compareUpdateMetadata(ctx, client.DumpResources, want); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
|
|
@ -198,58 +238,77 @@ func (s) TestDumpResources(t *testing.T) {
|
|||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// Verify that the xDS client reports the first resource of each type as
|
||||
// being in "NACKed" state, and the second resource of each type to be in
|
||||
// "ACKed" state. The version for the ACKed resource would be "2", while
|
||||
// that for the NACKed resource would be "1". In the NACKed resource, the
|
||||
// version which is NACKed is stored in the ErrorState field.
|
||||
want = map[string]map[string]xdsresource.UpdateWithMD{
|
||||
"type.googleapis.com/envoy.config.listener.v3.Listener": {
|
||||
ldsTargets[0]: {
|
||||
Raw: listenerAnys[0],
|
||||
MD: xdsresource.UpdateMetadata{
|
||||
Status: xdsresource.ServiceStatusNACKed,
|
||||
Version: "1",
|
||||
ErrState: &xdsresource.UpdateErrorMetadata{Version: "2", Err: cmpopts.AnyError},
|
||||
},
|
||||
want = []*v3statuspb.ClientConfig_GenericXdsConfig{
|
||||
{
|
||||
TypeUrl: "type.googleapis.com/envoy.config.listener.v3.Listener",
|
||||
Name: ldsTargets[0],
|
||||
ClientStatus: v3adminpb.ClientResourceStatus_NACKED,
|
||||
VersionInfo: "1",
|
||||
ErrorState: &v3adminpb.UpdateFailureState{
|
||||
VersionInfo: "2",
|
||||
},
|
||||
ldsTargets[1]: {Raw: listenerAnys[1], MD: xdsresource.UpdateMetadata{Status: xdsresource.ServiceStatusACKed, Version: "2"}},
|
||||
XdsConfig: listenerAnys[0],
|
||||
},
|
||||
"type.googleapis.com/envoy.config.route.v3.RouteConfiguration": {
|
||||
rdsTargets[0]: {
|
||||
Raw: routeAnys[0],
|
||||
MD: xdsresource.UpdateMetadata{
|
||||
Status: xdsresource.ServiceStatusNACKed,
|
||||
Version: "1",
|
||||
ErrState: &xdsresource.UpdateErrorMetadata{Version: "2", Err: cmpopts.AnyError},
|
||||
},
|
||||
},
|
||||
rdsTargets[1]: {Raw: routeAnys[1], MD: xdsresource.UpdateMetadata{Status: xdsresource.ServiceStatusACKed, Version: "2"}},
|
||||
{
|
||||
TypeUrl: "type.googleapis.com/envoy.config.listener.v3.Listener",
|
||||
Name: ldsTargets[1],
|
||||
ClientStatus: v3adminpb.ClientResourceStatus_ACKED,
|
||||
VersionInfo: "2",
|
||||
XdsConfig: listenerAnys[1],
|
||||
},
|
||||
"type.googleapis.com/envoy.config.cluster.v3.Cluster": {
|
||||
cdsTargets[0]: {
|
||||
Raw: clusterAnys[0],
|
||||
MD: xdsresource.UpdateMetadata{
|
||||
Status: xdsresource.ServiceStatusNACKed,
|
||||
Version: "1",
|
||||
ErrState: &xdsresource.UpdateErrorMetadata{Version: "2", Err: cmpopts.AnyError},
|
||||
},
|
||||
{
|
||||
TypeUrl: "type.googleapis.com/envoy.config.route.v3.RouteConfiguration",
|
||||
Name: rdsTargets[0],
|
||||
ClientStatus: v3adminpb.ClientResourceStatus_NACKED,
|
||||
VersionInfo: "1",
|
||||
ErrorState: &v3adminpb.UpdateFailureState{
|
||||
VersionInfo: "2",
|
||||
},
|
||||
cdsTargets[1]: {Raw: clusterAnys[1], MD: xdsresource.UpdateMetadata{Status: xdsresource.ServiceStatusACKed, Version: "2"}},
|
||||
XdsConfig: routeAnys[0],
|
||||
},
|
||||
"type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment": {
|
||||
edsTargets[0]: {
|
||||
Raw: endpointAnys[0],
|
||||
MD: xdsresource.UpdateMetadata{
|
||||
Status: xdsresource.ServiceStatusNACKed,
|
||||
Version: "1",
|
||||
ErrState: &xdsresource.UpdateErrorMetadata{Version: "2", Err: cmpopts.AnyError},
|
||||
},
|
||||
{
|
||||
TypeUrl: "type.googleapis.com/envoy.config.route.v3.RouteConfiguration",
|
||||
Name: rdsTargets[1],
|
||||
ClientStatus: v3adminpb.ClientResourceStatus_ACKED,
|
||||
VersionInfo: "2",
|
||||
XdsConfig: routeAnys[1],
|
||||
},
|
||||
{
|
||||
TypeUrl: "type.googleapis.com/envoy.config.cluster.v3.Cluster",
|
||||
Name: cdsTargets[0],
|
||||
ClientStatus: v3adminpb.ClientResourceStatus_NACKED,
|
||||
VersionInfo: "1",
|
||||
ErrorState: &v3adminpb.UpdateFailureState{
|
||||
VersionInfo: "2",
|
||||
},
|
||||
edsTargets[1]: {Raw: endpointAnys[1], MD: xdsresource.UpdateMetadata{Status: xdsresource.ServiceStatusACKed, Version: "2"}},
|
||||
XdsConfig: clusterAnys[0],
|
||||
},
|
||||
{
|
||||
TypeUrl: "type.googleapis.com/envoy.config.cluster.v3.Cluster",
|
||||
Name: cdsTargets[1],
|
||||
ClientStatus: v3adminpb.ClientResourceStatus_ACKED,
|
||||
VersionInfo: "2",
|
||||
XdsConfig: clusterAnys[1],
|
||||
},
|
||||
{
|
||||
TypeUrl: "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment",
|
||||
Name: edsTargets[0],
|
||||
ClientStatus: v3adminpb.ClientResourceStatus_NACKED,
|
||||
VersionInfo: "1",
|
||||
ErrorState: &v3adminpb.UpdateFailureState{
|
||||
VersionInfo: "2",
|
||||
},
|
||||
XdsConfig: endpointAnys[0],
|
||||
},
|
||||
{
|
||||
TypeUrl: "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment",
|
||||
Name: edsTargets[1],
|
||||
ClientStatus: v3adminpb.ClientResourceStatus_ACKED,
|
||||
VersionInfo: "2",
|
||||
XdsConfig: endpointAnys[1],
|
||||
},
|
||||
}
|
||||
if err := compareDump(ctx, client, want); err != nil {
|
||||
if err := compareUpdateMetadata(ctx, client.DumpResources, want); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ package xdsclient_test
|
|||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"sort"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
|
@ -41,6 +42,7 @@ import (
|
|||
"google.golang.org/protobuf/types/known/anypb"
|
||||
"google.golang.org/protobuf/types/known/wrapperspb"
|
||||
|
||||
v3adminpb "github.com/envoyproxy/go-control-plane/envoy/admin/v3"
|
||||
v3clusterpb "github.com/envoyproxy/go-control-plane/envoy/config/cluster/v3"
|
||||
v3corepb "github.com/envoyproxy/go-control-plane/envoy/config/core/v3"
|
||||
v3endpointpb "github.com/envoyproxy/go-control-plane/envoy/config/endpoint/v3"
|
||||
|
|
@ -48,6 +50,7 @@ import (
|
|||
v3routepb "github.com/envoyproxy/go-control-plane/envoy/config/route/v3"
|
||||
v3httppb "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/network/http_connection_manager/v3"
|
||||
v3discoverypb "github.com/envoyproxy/go-control-plane/envoy/service/discovery/v3"
|
||||
v3statuspb "github.com/envoyproxy/go-control-plane/envoy/service/status/v3"
|
||||
|
||||
_ "google.golang.org/grpc/xds/internal/httpfilter/router" // Register the router filter.
|
||||
)
|
||||
|
|
@ -63,21 +66,42 @@ func startFakeManagementServer(t *testing.T) (*fakeserver.Server, func()) {
|
|||
return fs, sCleanup
|
||||
}
|
||||
|
||||
func compareUpdateMetadata(ctx context.Context, dumpFunc func() map[string]xdsresource.UpdateWithMD, want map[string]xdsresource.UpdateWithMD) error {
|
||||
func compareUpdateMetadata(ctx context.Context, dumpFunc func() (*v3statuspb.ClientStatusResponse, error), want []*v3statuspb.ClientConfig_GenericXdsConfig) error {
|
||||
var cmpOpts = cmp.Options{
|
||||
cmp.Transformer("sort", func(in []*v3statuspb.ClientConfig_GenericXdsConfig) []*v3statuspb.ClientConfig_GenericXdsConfig {
|
||||
out := append([]*v3statuspb.ClientConfig_GenericXdsConfig(nil), in...)
|
||||
sort.Slice(out, func(i, j int) bool {
|
||||
a, b := out[i], out[j]
|
||||
if a == nil {
|
||||
return true
|
||||
}
|
||||
if b == nil {
|
||||
return false
|
||||
}
|
||||
if strings.Compare(a.TypeUrl, b.TypeUrl) == 0 {
|
||||
return strings.Compare(a.Name, b.Name) < 0
|
||||
}
|
||||
return strings.Compare(a.TypeUrl, b.TypeUrl) < 0
|
||||
})
|
||||
return out
|
||||
}),
|
||||
protocmp.Transform(),
|
||||
protocmp.IgnoreFields((*v3statuspb.ClientConfig_GenericXdsConfig)(nil), "last_updated"),
|
||||
protocmp.IgnoreFields((*v3adminpb.UpdateFailureState)(nil), "last_update_attempt", "details"),
|
||||
}
|
||||
|
||||
var lastErr error
|
||||
for ; ctx.Err() == nil; <-time.After(100 * time.Millisecond) {
|
||||
cmpOpts := cmp.Options{
|
||||
cmpopts.EquateEmpty(),
|
||||
cmp.Comparer(func(a, b time.Time) bool { return true }),
|
||||
cmpopts.EquateErrors(),
|
||||
protocmp.Transform(),
|
||||
resp, err := dumpFunc()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
gotUpdateMetadata := dumpFunc()
|
||||
diff := cmp.Diff(want, gotUpdateMetadata, cmpOpts)
|
||||
got := resp.GetConfig()[0].GetGenericXdsConfigs()
|
||||
diff := cmp.Diff(want, got, cmpOpts)
|
||||
if diff == "" {
|
||||
return nil
|
||||
}
|
||||
lastErr = fmt.Errorf("unexpected diff in metadata, diff (-want +got):\n%s\n want: %+v\n got: %+v", diff, want, gotUpdateMetadata)
|
||||
lastErr = fmt.Errorf("unexpected diff in metadata, diff (-want +got):\n%s\n want: %+v\n got: %+v", diff, want, got)
|
||||
}
|
||||
return fmt.Errorf("timeout when waiting for expected update metadata: %v", lastErr)
|
||||
}
|
||||
|
|
@ -124,7 +148,7 @@ func (s) TestHandleListenerResponseFromManagementServer(t *testing.T) {
|
|||
managementServerResponse *v3discoverypb.DiscoveryResponse
|
||||
wantUpdate xdsresource.ListenerUpdate
|
||||
wantErr string
|
||||
wantUpdateMetadata map[string]xdsresource.UpdateWithMD
|
||||
wantGenericXDSConfig []*v3statuspb.ClientConfig_GenericXdsConfig
|
||||
}{
|
||||
{
|
||||
desc: "badly-marshaled-response",
|
||||
|
|
@ -138,8 +162,12 @@ func (s) TestHandleListenerResponseFromManagementServer(t *testing.T) {
|
|||
}},
|
||||
},
|
||||
wantErr: "Listener not found in received response",
|
||||
wantUpdateMetadata: map[string]xdsresource.UpdateWithMD{
|
||||
"resource-name-1": {MD: xdsresource.UpdateMetadata{Status: xdsresource.ServiceStatusNotExist}},
|
||||
wantGenericXDSConfig: []*v3statuspb.ClientConfig_GenericXdsConfig{
|
||||
{
|
||||
TypeUrl: "type.googleapis.com/envoy.config.listener.v3.Listener",
|
||||
Name: resourceName1,
|
||||
ClientStatus: v3adminpb.ClientResourceStatus_DOES_NOT_EXIST,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
|
@ -150,8 +178,12 @@ func (s) TestHandleListenerResponseFromManagementServer(t *testing.T) {
|
|||
VersionInfo: "1",
|
||||
},
|
||||
wantErr: "Listener not found in received response",
|
||||
wantUpdateMetadata: map[string]xdsresource.UpdateWithMD{
|
||||
"resource-name-1": {MD: xdsresource.UpdateMetadata{Status: xdsresource.ServiceStatusNotExist}},
|
||||
wantGenericXDSConfig: []*v3statuspb.ClientConfig_GenericXdsConfig{
|
||||
{
|
||||
TypeUrl: "type.googleapis.com/envoy.config.listener.v3.Listener",
|
||||
Name: resourceName1,
|
||||
ClientStatus: v3adminpb.ClientResourceStatus_DOES_NOT_EXIST,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
|
@ -163,8 +195,12 @@ func (s) TestHandleListenerResponseFromManagementServer(t *testing.T) {
|
|||
Resources: []*anypb.Any{testutils.MarshalAny(t, &v3routepb.RouteConfiguration{})},
|
||||
},
|
||||
wantErr: "Listener not found in received response",
|
||||
wantUpdateMetadata: map[string]xdsresource.UpdateWithMD{
|
||||
"resource-name-1": {MD: xdsresource.UpdateMetadata{Status: xdsresource.ServiceStatusNotExist}},
|
||||
wantGenericXDSConfig: []*v3statuspb.ClientConfig_GenericXdsConfig{
|
||||
{
|
||||
TypeUrl: "type.googleapis.com/envoy.config.listener.v3.Listener",
|
||||
Name: resourceName1,
|
||||
ClientStatus: v3adminpb.ClientResourceStatus_DOES_NOT_EXIST,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
|
@ -181,14 +217,15 @@ func (s) TestHandleListenerResponseFromManagementServer(t *testing.T) {
|
|||
},
|
||||
},
|
||||
wantErr: "no RouteSpecifier",
|
||||
wantUpdateMetadata: map[string]xdsresource.UpdateWithMD{
|
||||
"resource-name-1": {MD: xdsresource.UpdateMetadata{
|
||||
Status: xdsresource.ServiceStatusNACKed,
|
||||
ErrState: &xdsresource.UpdateErrorMetadata{
|
||||
Version: "1",
|
||||
Err: cmpopts.AnyError,
|
||||
wantGenericXDSConfig: []*v3statuspb.ClientConfig_GenericXdsConfig{
|
||||
{
|
||||
TypeUrl: "type.googleapis.com/envoy.config.listener.v3.Listener",
|
||||
Name: resourceName1,
|
||||
ClientStatus: v3adminpb.ClientResourceStatus_NACKED,
|
||||
ErrorState: &v3adminpb.UpdateFailureState{
|
||||
VersionInfo: "1",
|
||||
},
|
||||
}},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
|
@ -203,10 +240,13 @@ func (s) TestHandleListenerResponseFromManagementServer(t *testing.T) {
|
|||
RouteConfigName: "route-configuration-name",
|
||||
HTTPFilters: []xdsresource.HTTPFilter{{Name: "router"}},
|
||||
},
|
||||
wantUpdateMetadata: map[string]xdsresource.UpdateWithMD{
|
||||
"resource-name-1": {
|
||||
MD: xdsresource.UpdateMetadata{Status: xdsresource.ServiceStatusACKed, Version: "1"},
|
||||
Raw: testutils.MarshalAny(t, resource1),
|
||||
wantGenericXDSConfig: []*v3statuspb.ClientConfig_GenericXdsConfig{
|
||||
{
|
||||
TypeUrl: "type.googleapis.com/envoy.config.listener.v3.Listener",
|
||||
Name: resourceName1,
|
||||
ClientStatus: v3adminpb.ClientResourceStatus_ACKED,
|
||||
VersionInfo: "1",
|
||||
XdsConfig: testutils.MarshalAny(t, resource1),
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
@ -222,10 +262,13 @@ func (s) TestHandleListenerResponseFromManagementServer(t *testing.T) {
|
|||
RouteConfigName: "route-configuration-name",
|
||||
HTTPFilters: []xdsresource.HTTPFilter{{Name: "router"}},
|
||||
},
|
||||
wantUpdateMetadata: map[string]xdsresource.UpdateWithMD{
|
||||
"resource-name-1": {
|
||||
MD: xdsresource.UpdateMetadata{Status: xdsresource.ServiceStatusACKed, Version: "1"},
|
||||
Raw: testutils.MarshalAny(t, resource1),
|
||||
wantGenericXDSConfig: []*v3statuspb.ClientConfig_GenericXdsConfig{
|
||||
{
|
||||
TypeUrl: "type.googleapis.com/envoy.config.listener.v3.Listener",
|
||||
Name: resourceName1,
|
||||
ClientStatus: v3adminpb.ClientResourceStatus_ACKED,
|
||||
VersionInfo: "1",
|
||||
XdsConfig: testutils.MarshalAny(t, resource1),
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
@ -300,10 +343,7 @@ func (s) TestHandleListenerResponseFromManagementServer(t *testing.T) {
|
|||
if diff := cmp.Diff(test.wantUpdate, gotUpdate, cmpOpts...); diff != "" {
|
||||
t.Fatalf("Unexpected diff in metadata, diff (-want +got):\n%s", diff)
|
||||
}
|
||||
if err := compareUpdateMetadata(ctx, func() map[string]xdsresource.UpdateWithMD {
|
||||
dump := client.DumpResources()
|
||||
return dump["type.googleapis.com/envoy.config.listener.v3.Listener"]
|
||||
}, test.wantUpdateMetadata); err != nil {
|
||||
if err := compareUpdateMetadata(ctx, client.DumpResources, test.wantGenericXDSConfig); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
})
|
||||
|
|
@ -351,7 +391,7 @@ func (s) TestHandleRouteConfigResponseFromManagementServer(t *testing.T) {
|
|||
managementServerResponse *v3discoverypb.DiscoveryResponse
|
||||
wantUpdate xdsresource.RouteConfigUpdate
|
||||
wantErr string
|
||||
wantUpdateMetadata map[string]xdsresource.UpdateWithMD
|
||||
wantGenericXDSConfig []*v3statuspb.ClientConfig_GenericXdsConfig
|
||||
}{
|
||||
// The first three tests involve scenarios where the response fails
|
||||
// protobuf deserialization (because it contains an invalid data or type
|
||||
|
|
@ -373,8 +413,12 @@ func (s) TestHandleRouteConfigResponseFromManagementServer(t *testing.T) {
|
|||
}},
|
||||
},
|
||||
wantErr: "RouteConfiguration not found in received response",
|
||||
wantUpdateMetadata: map[string]xdsresource.UpdateWithMD{
|
||||
"resource-name-1": {MD: xdsresource.UpdateMetadata{Status: xdsresource.ServiceStatusNotExist}},
|
||||
wantGenericXDSConfig: []*v3statuspb.ClientConfig_GenericXdsConfig{
|
||||
{
|
||||
TypeUrl: "type.googleapis.com/envoy.config.route.v3.RouteConfiguration",
|
||||
Name: resourceName1,
|
||||
ClientStatus: v3adminpb.ClientResourceStatus_DOES_NOT_EXIST,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
|
@ -385,8 +429,12 @@ func (s) TestHandleRouteConfigResponseFromManagementServer(t *testing.T) {
|
|||
VersionInfo: "1",
|
||||
},
|
||||
wantErr: "RouteConfiguration not found in received response",
|
||||
wantUpdateMetadata: map[string]xdsresource.UpdateWithMD{
|
||||
"resource-name-1": {MD: xdsresource.UpdateMetadata{Status: xdsresource.ServiceStatusNotExist}},
|
||||
wantGenericXDSConfig: []*v3statuspb.ClientConfig_GenericXdsConfig{
|
||||
{
|
||||
TypeUrl: "type.googleapis.com/envoy.config.route.v3.RouteConfiguration",
|
||||
Name: resourceName1,
|
||||
ClientStatus: v3adminpb.ClientResourceStatus_DOES_NOT_EXIST,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
|
@ -398,8 +446,12 @@ func (s) TestHandleRouteConfigResponseFromManagementServer(t *testing.T) {
|
|||
Resources: []*anypb.Any{testutils.MarshalAny(t, &v3clusterpb.Cluster{})},
|
||||
},
|
||||
wantErr: "RouteConfiguration not found in received response",
|
||||
wantUpdateMetadata: map[string]xdsresource.UpdateWithMD{
|
||||
"resource-name-1": {MD: xdsresource.UpdateMetadata{Status: xdsresource.ServiceStatusNotExist}},
|
||||
wantGenericXDSConfig: []*v3statuspb.ClientConfig_GenericXdsConfig{
|
||||
{
|
||||
TypeUrl: "type.googleapis.com/envoy.config.route.v3.RouteConfiguration",
|
||||
Name: resourceName1,
|
||||
ClientStatus: v3adminpb.ClientResourceStatus_DOES_NOT_EXIST,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
|
@ -424,14 +476,15 @@ func (s) TestHandleRouteConfigResponseFromManagementServer(t *testing.T) {
|
|||
})},
|
||||
},
|
||||
wantErr: "received route is invalid: retry_policy.num_retries = 0; must be >= 1",
|
||||
wantUpdateMetadata: map[string]xdsresource.UpdateWithMD{
|
||||
"resource-name-1": {MD: xdsresource.UpdateMetadata{
|
||||
Status: xdsresource.ServiceStatusNACKed,
|
||||
ErrState: &xdsresource.UpdateErrorMetadata{
|
||||
Version: "1",
|
||||
Err: cmpopts.AnyError,
|
||||
wantGenericXDSConfig: []*v3statuspb.ClientConfig_GenericXdsConfig{
|
||||
{
|
||||
TypeUrl: "type.googleapis.com/envoy.config.route.v3.RouteConfiguration",
|
||||
Name: resourceName1,
|
||||
ClientStatus: v3adminpb.ClientResourceStatus_NACKED,
|
||||
ErrorState: &v3adminpb.UpdateFailureState{
|
||||
VersionInfo: "1",
|
||||
},
|
||||
}},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
|
@ -452,10 +505,13 @@ func (s) TestHandleRouteConfigResponseFromManagementServer(t *testing.T) {
|
|||
},
|
||||
},
|
||||
},
|
||||
wantUpdateMetadata: map[string]xdsresource.UpdateWithMD{
|
||||
"resource-name-1": {
|
||||
MD: xdsresource.UpdateMetadata{Status: xdsresource.ServiceStatusACKed, Version: "1"},
|
||||
Raw: testutils.MarshalAny(t, resource1),
|
||||
wantGenericXDSConfig: []*v3statuspb.ClientConfig_GenericXdsConfig{
|
||||
{
|
||||
TypeUrl: "type.googleapis.com/envoy.config.route.v3.RouteConfiguration",
|
||||
Name: resourceName1,
|
||||
ClientStatus: v3adminpb.ClientResourceStatus_ACKED,
|
||||
VersionInfo: "1",
|
||||
XdsConfig: testutils.MarshalAny(t, resource1),
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
@ -477,10 +533,13 @@ func (s) TestHandleRouteConfigResponseFromManagementServer(t *testing.T) {
|
|||
},
|
||||
},
|
||||
},
|
||||
wantUpdateMetadata: map[string]xdsresource.UpdateWithMD{
|
||||
"resource-name-1": {
|
||||
MD: xdsresource.UpdateMetadata{Status: xdsresource.ServiceStatusACKed, Version: "1"},
|
||||
Raw: testutils.MarshalAny(t, resource1),
|
||||
wantGenericXDSConfig: []*v3statuspb.ClientConfig_GenericXdsConfig{
|
||||
{
|
||||
TypeUrl: "type.googleapis.com/envoy.config.route.v3.RouteConfiguration",
|
||||
Name: resourceName1,
|
||||
ClientStatus: v3adminpb.ClientResourceStatus_ACKED,
|
||||
VersionInfo: "1",
|
||||
XdsConfig: testutils.MarshalAny(t, resource1),
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
@ -553,10 +612,7 @@ func (s) TestHandleRouteConfigResponseFromManagementServer(t *testing.T) {
|
|||
if diff := cmp.Diff(test.wantUpdate, gotUpdate, cmpOpts...); diff != "" {
|
||||
t.Fatalf("Unexpected diff in metadata, diff (-want +got):\n%s", diff)
|
||||
}
|
||||
if err := compareUpdateMetadata(ctx, func() map[string]xdsresource.UpdateWithMD {
|
||||
dump := client.DumpResources()
|
||||
return dump["type.googleapis.com/envoy.config.route.v3.RouteConfiguration"]
|
||||
}, test.wantUpdateMetadata); err != nil {
|
||||
if err := compareUpdateMetadata(ctx, client.DumpResources, test.wantGenericXDSConfig); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
})
|
||||
|
|
@ -586,7 +642,7 @@ func (s) TestHandleClusterResponseFromManagementServer(t *testing.T) {
|
|||
managementServerResponse *v3discoverypb.DiscoveryResponse
|
||||
wantUpdate xdsresource.ClusterUpdate
|
||||
wantErr string
|
||||
wantUpdateMetadata map[string]xdsresource.UpdateWithMD
|
||||
wantGenericXDSConfig []*v3statuspb.ClientConfig_GenericXdsConfig
|
||||
}{
|
||||
{
|
||||
desc: "badly-marshaled-response",
|
||||
|
|
@ -600,8 +656,12 @@ func (s) TestHandleClusterResponseFromManagementServer(t *testing.T) {
|
|||
}},
|
||||
},
|
||||
wantErr: "Cluster not found in received response",
|
||||
wantUpdateMetadata: map[string]xdsresource.UpdateWithMD{
|
||||
"resource-name-1": {MD: xdsresource.UpdateMetadata{Status: xdsresource.ServiceStatusNotExist}},
|
||||
wantGenericXDSConfig: []*v3statuspb.ClientConfig_GenericXdsConfig{
|
||||
{
|
||||
TypeUrl: "type.googleapis.com/envoy.config.cluster.v3.Cluster",
|
||||
Name: resourceName1,
|
||||
ClientStatus: v3adminpb.ClientResourceStatus_DOES_NOT_EXIST,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
|
@ -612,8 +672,12 @@ func (s) TestHandleClusterResponseFromManagementServer(t *testing.T) {
|
|||
VersionInfo: "1",
|
||||
},
|
||||
wantErr: "Cluster not found in received response",
|
||||
wantUpdateMetadata: map[string]xdsresource.UpdateWithMD{
|
||||
"resource-name-1": {MD: xdsresource.UpdateMetadata{Status: xdsresource.ServiceStatusNotExist}},
|
||||
wantGenericXDSConfig: []*v3statuspb.ClientConfig_GenericXdsConfig{
|
||||
{
|
||||
TypeUrl: "type.googleapis.com/envoy.config.cluster.v3.Cluster",
|
||||
Name: resourceName1,
|
||||
ClientStatus: v3adminpb.ClientResourceStatus_DOES_NOT_EXIST,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
|
@ -625,8 +689,12 @@ func (s) TestHandleClusterResponseFromManagementServer(t *testing.T) {
|
|||
Resources: []*anypb.Any{testutils.MarshalAny(t, &v3endpointpb.ClusterLoadAssignment{})},
|
||||
},
|
||||
wantErr: "Cluster not found in received response",
|
||||
wantUpdateMetadata: map[string]xdsresource.UpdateWithMD{
|
||||
"resource-name-1": {MD: xdsresource.UpdateMetadata{Status: xdsresource.ServiceStatusNotExist}},
|
||||
wantGenericXDSConfig: []*v3statuspb.ClientConfig_GenericXdsConfig{
|
||||
{
|
||||
TypeUrl: "type.googleapis.com/envoy.config.cluster.v3.Cluster",
|
||||
Name: resourceName1,
|
||||
ClientStatus: v3adminpb.ClientResourceStatus_DOES_NOT_EXIST,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
|
@ -650,14 +718,15 @@ func (s) TestHandleClusterResponseFromManagementServer(t *testing.T) {
|
|||
})},
|
||||
},
|
||||
wantErr: "unexpected lbPolicy MAGLEV",
|
||||
wantUpdateMetadata: map[string]xdsresource.UpdateWithMD{
|
||||
"resource-name-1": {MD: xdsresource.UpdateMetadata{
|
||||
Status: xdsresource.ServiceStatusNACKed,
|
||||
ErrState: &xdsresource.UpdateErrorMetadata{
|
||||
Version: "1",
|
||||
Err: cmpopts.AnyError,
|
||||
wantGenericXDSConfig: []*v3statuspb.ClientConfig_GenericXdsConfig{
|
||||
{
|
||||
TypeUrl: "type.googleapis.com/envoy.config.cluster.v3.Cluster",
|
||||
Name: resourceName1,
|
||||
ClientStatus: v3adminpb.ClientResourceStatus_NACKED,
|
||||
ErrorState: &v3adminpb.UpdateFailureState{
|
||||
VersionInfo: "1",
|
||||
},
|
||||
}},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
|
@ -672,10 +741,13 @@ func (s) TestHandleClusterResponseFromManagementServer(t *testing.T) {
|
|||
ClusterName: "resource-name-1",
|
||||
EDSServiceName: "eds-service-name",
|
||||
},
|
||||
wantUpdateMetadata: map[string]xdsresource.UpdateWithMD{
|
||||
"resource-name-1": {
|
||||
MD: xdsresource.UpdateMetadata{Status: xdsresource.ServiceStatusACKed, Version: "1"},
|
||||
Raw: testutils.MarshalAny(t, resource1),
|
||||
wantGenericXDSConfig: []*v3statuspb.ClientConfig_GenericXdsConfig{
|
||||
{
|
||||
TypeUrl: "type.googleapis.com/envoy.config.cluster.v3.Cluster",
|
||||
Name: resourceName1,
|
||||
ClientStatus: v3adminpb.ClientResourceStatus_ACKED,
|
||||
VersionInfo: "1",
|
||||
XdsConfig: testutils.MarshalAny(t, resource1),
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
@ -691,10 +763,13 @@ func (s) TestHandleClusterResponseFromManagementServer(t *testing.T) {
|
|||
ClusterName: "resource-name-1",
|
||||
EDSServiceName: "eds-service-name",
|
||||
},
|
||||
wantUpdateMetadata: map[string]xdsresource.UpdateWithMD{
|
||||
"resource-name-1": {
|
||||
MD: xdsresource.UpdateMetadata{Status: xdsresource.ServiceStatusACKed, Version: "1"},
|
||||
Raw: testutils.MarshalAny(t, resource1),
|
||||
wantGenericXDSConfig: []*v3statuspb.ClientConfig_GenericXdsConfig{
|
||||
{
|
||||
TypeUrl: "type.googleapis.com/envoy.config.cluster.v3.Cluster",
|
||||
Name: resourceName1,
|
||||
ClientStatus: v3adminpb.ClientResourceStatus_ACKED,
|
||||
VersionInfo: "1",
|
||||
XdsConfig: testutils.MarshalAny(t, resource1),
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
@ -778,10 +853,7 @@ func (s) TestHandleClusterResponseFromManagementServer(t *testing.T) {
|
|||
if diff := cmp.Diff(test.wantUpdate, gotUpdate, cmpOpts...); diff != "" {
|
||||
t.Fatalf("Unexpected diff in metadata, diff (-want +got):\n%s", diff)
|
||||
}
|
||||
if err := compareUpdateMetadata(ctx, func() map[string]xdsresource.UpdateWithMD {
|
||||
dump := client.DumpResources()
|
||||
return dump["type.googleapis.com/envoy.config.cluster.v3.Cluster"]
|
||||
}, test.wantUpdateMetadata); err != nil {
|
||||
if err := compareUpdateMetadata(ctx, client.DumpResources, test.wantGenericXDSConfig); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
})
|
||||
|
|
@ -859,7 +931,7 @@ func (s) TestHandleEndpointsResponseFromManagementServer(t *testing.T) {
|
|||
managementServerResponse *v3discoverypb.DiscoveryResponse
|
||||
wantUpdate xdsresource.EndpointsUpdate
|
||||
wantErr string
|
||||
wantUpdateMetadata map[string]xdsresource.UpdateWithMD
|
||||
wantGenericXDSConfig []*v3statuspb.ClientConfig_GenericXdsConfig
|
||||
}{
|
||||
// The first three tests involve scenarios where the response fails
|
||||
// protobuf deserialization (because it contains an invalid data or type
|
||||
|
|
@ -881,8 +953,12 @@ func (s) TestHandleEndpointsResponseFromManagementServer(t *testing.T) {
|
|||
}},
|
||||
},
|
||||
wantErr: "Endpoints not found in received response",
|
||||
wantUpdateMetadata: map[string]xdsresource.UpdateWithMD{
|
||||
"resource-name-1": {MD: xdsresource.UpdateMetadata{Status: xdsresource.ServiceStatusNotExist}},
|
||||
wantGenericXDSConfig: []*v3statuspb.ClientConfig_GenericXdsConfig{
|
||||
{
|
||||
TypeUrl: "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment",
|
||||
Name: resourceName1,
|
||||
ClientStatus: v3adminpb.ClientResourceStatus_DOES_NOT_EXIST,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
|
@ -893,8 +969,12 @@ func (s) TestHandleEndpointsResponseFromManagementServer(t *testing.T) {
|
|||
VersionInfo: "1",
|
||||
},
|
||||
wantErr: "Endpoints not found in received response",
|
||||
wantUpdateMetadata: map[string]xdsresource.UpdateWithMD{
|
||||
"resource-name-1": {MD: xdsresource.UpdateMetadata{Status: xdsresource.ServiceStatusNotExist}},
|
||||
wantGenericXDSConfig: []*v3statuspb.ClientConfig_GenericXdsConfig{
|
||||
{
|
||||
TypeUrl: "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment",
|
||||
Name: resourceName1,
|
||||
ClientStatus: v3adminpb.ClientResourceStatus_DOES_NOT_EXIST,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
|
@ -906,8 +986,12 @@ func (s) TestHandleEndpointsResponseFromManagementServer(t *testing.T) {
|
|||
Resources: []*anypb.Any{testutils.MarshalAny(t, &v3listenerpb.Listener{})},
|
||||
},
|
||||
wantErr: "Endpoints not found in received response",
|
||||
wantUpdateMetadata: map[string]xdsresource.UpdateWithMD{
|
||||
"resource-name-1": {MD: xdsresource.UpdateMetadata{Status: xdsresource.ServiceStatusNotExist}},
|
||||
wantGenericXDSConfig: []*v3statuspb.ClientConfig_GenericXdsConfig{
|
||||
{
|
||||
TypeUrl: "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment",
|
||||
Name: resourceName1,
|
||||
ClientStatus: v3adminpb.ClientResourceStatus_DOES_NOT_EXIST,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
|
@ -949,14 +1033,15 @@ func (s) TestHandleEndpointsResponseFromManagementServer(t *testing.T) {
|
|||
},
|
||||
},
|
||||
wantErr: "EDS response contains an endpoint with zero weight",
|
||||
wantUpdateMetadata: map[string]xdsresource.UpdateWithMD{
|
||||
"resource-name-1": {MD: xdsresource.UpdateMetadata{
|
||||
Status: xdsresource.ServiceStatusNACKed,
|
||||
ErrState: &xdsresource.UpdateErrorMetadata{
|
||||
Version: "1",
|
||||
Err: cmpopts.AnyError,
|
||||
wantGenericXDSConfig: []*v3statuspb.ClientConfig_GenericXdsConfig{
|
||||
{
|
||||
TypeUrl: "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment",
|
||||
Name: resourceName1,
|
||||
ClientStatus: v3adminpb.ClientResourceStatus_NACKED,
|
||||
ErrorState: &v3adminpb.UpdateFailureState{
|
||||
VersionInfo: "1",
|
||||
},
|
||||
}},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
|
@ -983,10 +1068,13 @@ func (s) TestHandleEndpointsResponseFromManagementServer(t *testing.T) {
|
|||
},
|
||||
},
|
||||
},
|
||||
wantUpdateMetadata: map[string]xdsresource.UpdateWithMD{
|
||||
"resource-name-1": {
|
||||
MD: xdsresource.UpdateMetadata{Status: xdsresource.ServiceStatusACKed, Version: "1"},
|
||||
Raw: testutils.MarshalAny(t, resource1),
|
||||
wantGenericXDSConfig: []*v3statuspb.ClientConfig_GenericXdsConfig{
|
||||
{
|
||||
TypeUrl: "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment",
|
||||
Name: resourceName1,
|
||||
ClientStatus: v3adminpb.ClientResourceStatus_ACKED,
|
||||
VersionInfo: "1",
|
||||
XdsConfig: testutils.MarshalAny(t, resource1),
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
@ -1014,10 +1102,13 @@ func (s) TestHandleEndpointsResponseFromManagementServer(t *testing.T) {
|
|||
},
|
||||
},
|
||||
},
|
||||
wantUpdateMetadata: map[string]xdsresource.UpdateWithMD{
|
||||
"resource-name-1": {
|
||||
MD: xdsresource.UpdateMetadata{Status: xdsresource.ServiceStatusACKed, Version: "1"},
|
||||
Raw: testutils.MarshalAny(t, resource1),
|
||||
wantGenericXDSConfig: []*v3statuspb.ClientConfig_GenericXdsConfig{
|
||||
{
|
||||
TypeUrl: "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment",
|
||||
Name: resourceName1,
|
||||
ClientStatus: v3adminpb.ClientResourceStatus_ACKED,
|
||||
VersionInfo: "1",
|
||||
XdsConfig: testutils.MarshalAny(t, resource1),
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
@ -1091,10 +1182,7 @@ func (s) TestHandleEndpointsResponseFromManagementServer(t *testing.T) {
|
|||
if diff := cmp.Diff(test.wantUpdate, gotUpdate, cmpOpts...); diff != "" {
|
||||
t.Fatalf("Unexpected diff in metadata, diff (-want +got):\n%s", diff)
|
||||
}
|
||||
if err := compareUpdateMetadata(ctx, func() map[string]xdsresource.UpdateWithMD {
|
||||
dump := client.DumpResources()
|
||||
return dump["type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment"]
|
||||
}, test.wantUpdateMetadata); err != nil {
|
||||
if err := compareUpdateMetadata(ctx, client.DumpResources, test.wantGenericXDSConfig); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
})
|
||||
|
|
|
|||
Loading…
Reference in New Issue