gitee.com/ks-custle/core-gm@v0.0.0-20230922171213-b83bdd97b62c/grpc/xds/server_test.go (about)

     1  /*
     2   *
     3   * Copyright 2020 gRPC authors.
     4   *
     5   * Licensed under the Apache License, Version 2.0 (the "License");
     6   * you may not use this file except in compliance with the License.
     7   * You may obtain a copy of the License at
     8   *
     9   *     http://www.apache.org/licenses/LICENSE-2.0
    10   *
    11   * Unless required by applicable law or agreed to in writing, software
    12   * distributed under the License is distributed on an "AS IS" BASIS,
    13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    14   * See the License for the specific language governing permissions and
    15   * limitations under the License.
    16   *
    17   */
    18  
    19  package xds
    20  
    21  import (
    22  	"context"
    23  	"errors"
    24  	"fmt"
    25  	"net"
    26  	"reflect"
    27  	"strings"
    28  	"testing"
    29  	"time"
    30  
    31  	grpc "gitee.com/ks-custle/core-gm/grpc"
    32  	"gitee.com/ks-custle/core-gm/grpc/connectivity"
    33  	"gitee.com/ks-custle/core-gm/grpc/credentials/insecure"
    34  	"gitee.com/ks-custle/core-gm/grpc/credentials/tls/certprovider"
    35  	"gitee.com/ks-custle/core-gm/grpc/credentials/xds"
    36  	"gitee.com/ks-custle/core-gm/grpc/internal/grpctest"
    37  	"gitee.com/ks-custle/core-gm/grpc/internal/testutils"
    38  	_ "gitee.com/ks-custle/core-gm/grpc/xds/internal/httpfilter/router"
    39  	xdstestutils "gitee.com/ks-custle/core-gm/grpc/xds/internal/testutils"
    40  	"gitee.com/ks-custle/core-gm/grpc/xds/internal/testutils/e2e"
    41  	"gitee.com/ks-custle/core-gm/grpc/xds/internal/testutils/fakeclient"
    42  	"gitee.com/ks-custle/core-gm/grpc/xds/internal/xdsclient"
    43  	"gitee.com/ks-custle/core-gm/grpc/xds/internal/xdsclient/bootstrap"
    44  	"gitee.com/ks-custle/core-gm/grpc/xds/internal/xdsclient/xdsresource"
    45  
    46  	v3corepb "gitee.com/ks-custle/core-gm/go-control-plane/envoy/config/core/v3"
    47  	v3listenerpb "gitee.com/ks-custle/core-gm/go-control-plane/envoy/config/listener/v3"
    48  	v3routepb "gitee.com/ks-custle/core-gm/go-control-plane/envoy/config/route/v3"
    49  	v3httppb "gitee.com/ks-custle/core-gm/go-control-plane/envoy/extensions/filters/network/http_connection_manager/v3"
    50  	v3tlspb "gitee.com/ks-custle/core-gm/go-control-plane/envoy/extensions/transport_sockets/tls/v3"
    51  	wrapperspb "github.com/golang/protobuf/ptypes/wrappers"
    52  )
    53  
    54  const (
    55  	defaultTestTimeout                     = 5 * time.Second
    56  	defaultTestShortTimeout                = 10 * time.Millisecond
    57  	testServerListenerResourceNameTemplate = "/path/to/resource/%s/%s"
    58  )
    59  
    60  var listenerWithFilterChains = &v3listenerpb.Listener{
    61  	FilterChains: []*v3listenerpb.FilterChain{
    62  		{
    63  			FilterChainMatch: &v3listenerpb.FilterChainMatch{
    64  				PrefixRanges: []*v3corepb.CidrRange{
    65  					{
    66  						AddressPrefix: "192.168.0.0",
    67  						PrefixLen: &wrapperspb.UInt32Value{
    68  							Value: uint32(16),
    69  						},
    70  					},
    71  				},
    72  				SourceType: v3listenerpb.FilterChainMatch_SAME_IP_OR_LOOPBACK,
    73  				SourcePrefixRanges: []*v3corepb.CidrRange{
    74  					{
    75  						AddressPrefix: "192.168.0.0",
    76  						PrefixLen: &wrapperspb.UInt32Value{
    77  							Value: uint32(16),
    78  						},
    79  					},
    80  				},
    81  				SourcePorts: []uint32{80},
    82  			},
    83  			TransportSocket: &v3corepb.TransportSocket{
    84  				Name: "envoy.transport_sockets.tls",
    85  				ConfigType: &v3corepb.TransportSocket_TypedConfig{
    86  					TypedConfig: testutils.MarshalAny(&v3tlspb.DownstreamTlsContext{
    87  						CommonTlsContext: &v3tlspb.CommonTlsContext{
    88  							TlsCertificateCertificateProviderInstance: &v3tlspb.CommonTlsContext_CertificateProviderInstance{
    89  								InstanceName:    "identityPluginInstance",
    90  								CertificateName: "identityCertName",
    91  							},
    92  						},
    93  					}),
    94  				},
    95  			},
    96  			Filters: []*v3listenerpb.Filter{
    97  				{
    98  					Name: "filter-1",
    99  					ConfigType: &v3listenerpb.Filter_TypedConfig{
   100  						TypedConfig: testutils.MarshalAny(&v3httppb.HttpConnectionManager{
   101  							RouteSpecifier: &v3httppb.HttpConnectionManager_RouteConfig{
   102  								RouteConfig: &v3routepb.RouteConfiguration{
   103  									Name: "routeName",
   104  									VirtualHosts: []*v3routepb.VirtualHost{{
   105  										Domains: []string{"lds.target.good:3333"},
   106  										Routes: []*v3routepb.Route{{
   107  											Match: &v3routepb.RouteMatch{
   108  												PathSpecifier: &v3routepb.RouteMatch_Prefix{Prefix: "/"},
   109  											},
   110  											Action: &v3routepb.Route_NonForwardingAction{},
   111  										}}}}},
   112  							},
   113  							HttpFilters: []*v3httppb.HttpFilter{e2e.RouterHTTPFilter},
   114  						}),
   115  					},
   116  				},
   117  			},
   118  		},
   119  	},
   120  }
   121  
   122  type s struct {
   123  	grpctest.Tester
   124  }
   125  
   126  func Test(t *testing.T) {
   127  	grpctest.RunSubTests(t, s{})
   128  }
   129  
   130  type fakeGRPCServer struct {
   131  	done              chan struct{}
   132  	registerServiceCh *testutils.Channel
   133  	serveCh           *testutils.Channel
   134  	stopCh            *testutils.Channel
   135  	gracefulStopCh    *testutils.Channel
   136  }
   137  
   138  func (f *fakeGRPCServer) RegisterService(*grpc.ServiceDesc, interface{}) {
   139  	f.registerServiceCh.Send(nil)
   140  }
   141  
   142  func (f *fakeGRPCServer) Serve(lis net.Listener) error {
   143  	f.serveCh.Send(nil)
   144  	<-f.done
   145  	lis.Close()
   146  	return nil
   147  }
   148  
   149  func (f *fakeGRPCServer) Stop() {
   150  	close(f.done)
   151  	f.stopCh.Send(nil)
   152  }
   153  func (f *fakeGRPCServer) GracefulStop() {
   154  	close(f.done)
   155  	f.gracefulStopCh.Send(nil)
   156  }
   157  
   158  func (f *fakeGRPCServer) GetServiceInfo() map[string]grpc.ServiceInfo {
   159  	panic("implement me")
   160  }
   161  
   162  func newFakeGRPCServer() *fakeGRPCServer {
   163  	return &fakeGRPCServer{
   164  		done:              make(chan struct{}),
   165  		registerServiceCh: testutils.NewChannel(),
   166  		serveCh:           testutils.NewChannel(),
   167  		stopCh:            testutils.NewChannel(),
   168  		gracefulStopCh:    testutils.NewChannel(),
   169  	}
   170  }
   171  
   172  func splitHostPort(hostport string) (string, string) {
   173  	addr, port, err := net.SplitHostPort(hostport)
   174  	if err != nil {
   175  		panic(fmt.Sprintf("listener address %q does not parse: %v", hostport, err))
   176  	}
   177  	return addr, port
   178  }
   179  
   180  func (s) TestNewServer(t *testing.T) {
   181  	xdsCreds, err := xds.NewServerCredentials(xds.ServerOptions{FallbackCreds: insecure.NewCredentials()})
   182  	if err != nil {
   183  		t.Fatalf("failed to create xds server credentials: %v", err)
   184  	}
   185  
   186  	tests := []struct {
   187  		desc              string
   188  		serverOpts        []grpc.ServerOption
   189  		wantXDSCredsInUse bool
   190  	}{
   191  		{
   192  			desc:       "without_xds_creds",
   193  			serverOpts: []grpc.ServerOption{grpc.Creds(insecure.NewCredentials())},
   194  		},
   195  		{
   196  			desc:              "with_xds_creds",
   197  			serverOpts:        []grpc.ServerOption{grpc.Creds(xdsCreds)},
   198  			wantXDSCredsInUse: true,
   199  		},
   200  	}
   201  
   202  	for _, test := range tests {
   203  		t.Run(test.desc, func(t *testing.T) {
   204  			// The xds package adds a couple of server options (unary and stream
   205  			// interceptors) to the server options passed in by the user.
   206  			wantServerOpts := len(test.serverOpts) + 2
   207  
   208  			origNewGRPCServer := newGRPCServer
   209  			newGRPCServer = func(opts ...grpc.ServerOption) grpcServer {
   210  				if got := len(opts); got != wantServerOpts {
   211  					t.Fatalf("%d ServerOptions passed to grpc.Server, want %d", got, wantServerOpts)
   212  				}
   213  				// Verify that the user passed ServerOptions are forwarded as is.
   214  				if !reflect.DeepEqual(opts[2:], test.serverOpts) {
   215  					t.Fatalf("got ServerOptions %v, want %v", opts[2:], test.serverOpts)
   216  				}
   217  				return grpc.NewServer(opts...)
   218  			}
   219  			defer func() {
   220  				newGRPCServer = origNewGRPCServer
   221  			}()
   222  
   223  			s := NewGRPCServer(test.serverOpts...)
   224  			defer s.Stop()
   225  
   226  			if s.xdsCredsInUse != test.wantXDSCredsInUse {
   227  				t.Fatalf("xdsCredsInUse is %v, want %v", s.xdsCredsInUse, test.wantXDSCredsInUse)
   228  			}
   229  		})
   230  	}
   231  }
   232  
   233  func (s) TestRegisterService(t *testing.T) {
   234  	fs := newFakeGRPCServer()
   235  
   236  	origNewGRPCServer := newGRPCServer
   237  	newGRPCServer = func(opts ...grpc.ServerOption) grpcServer { return fs }
   238  	defer func() { newGRPCServer = origNewGRPCServer }()
   239  
   240  	s := NewGRPCServer()
   241  	defer s.Stop()
   242  
   243  	s.RegisterService(&grpc.ServiceDesc{}, nil)
   244  	ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout)
   245  	defer cancel()
   246  	if _, err := fs.registerServiceCh.Receive(ctx); err != nil {
   247  		t.Fatalf("timeout when expecting RegisterService() to called on grpc.Server: %v", err)
   248  	}
   249  }
   250  
   251  const (
   252  	fakeProvider1Name = "fake-certificate-provider-1"
   253  	fakeProvider2Name = "fake-certificate-provider-2"
   254  	fakeConfig        = "my fake config"
   255  )
   256  
   257  var (
   258  	fpb1, fpb2          *fakeProviderBuilder
   259  	certProviderConfigs map[string]*certprovider.BuildableConfig
   260  )
   261  
   262  func init() {
   263  	fpb1 = &fakeProviderBuilder{
   264  		name:    fakeProvider1Name,
   265  		buildCh: testutils.NewChannel(),
   266  	}
   267  	fpb2 = &fakeProviderBuilder{
   268  		name:    fakeProvider2Name,
   269  		buildCh: testutils.NewChannel(),
   270  	}
   271  	cfg1, _ := fpb1.ParseConfig(fakeConfig + "1111")
   272  	cfg2, _ := fpb2.ParseConfig(fakeConfig + "2222")
   273  	certProviderConfigs = map[string]*certprovider.BuildableConfig{
   274  		"default1": cfg1,
   275  		"default2": cfg2,
   276  	}
   277  	certprovider.Register(fpb1)
   278  	certprovider.Register(fpb2)
   279  }
   280  
   281  // fakeProviderBuilder builds new instances of fakeProvider and interprets the
   282  // config provided to it as a string.
   283  type fakeProviderBuilder struct {
   284  	name    string
   285  	buildCh *testutils.Channel
   286  }
   287  
   288  func (b *fakeProviderBuilder) ParseConfig(config interface{}) (*certprovider.BuildableConfig, error) {
   289  	s, ok := config.(string)
   290  	if !ok {
   291  		return nil, fmt.Errorf("providerBuilder %s received config of type %T, want string", b.name, config)
   292  	}
   293  	return certprovider.NewBuildableConfig(b.name, []byte(s), func(certprovider.BuildOptions) certprovider.Provider {
   294  		b.buildCh.Send(nil)
   295  		return &fakeProvider{
   296  			Distributor: certprovider.NewDistributor(),
   297  			config:      s,
   298  		}
   299  	}), nil
   300  }
   301  
   302  func (b *fakeProviderBuilder) Name() string {
   303  	return b.name
   304  }
   305  
   306  // fakeProvider is an implementation of the Provider interface which provides a
   307  // method for tests to invoke to push new key materials.
   308  type fakeProvider struct {
   309  	*certprovider.Distributor
   310  	config string
   311  }
   312  
   313  // Close helps implement the Provider interface.
   314  func (p *fakeProvider) Close() {
   315  	p.Distributor.Stop()
   316  }
   317  
   318  // setupOverrides sets up overrides for bootstrap config, new xdsClient creation
   319  // and new gRPC.Server creation.
   320  func setupOverrides() (*fakeGRPCServer, *testutils.Channel, func()) {
   321  	clientCh := testutils.NewChannel()
   322  	origNewXDSClient := newXDSClient
   323  	newXDSClient = func() (xdsclient.XDSClient, error) {
   324  		c := fakeclient.NewClient()
   325  		c.SetBootstrapConfig(&bootstrap.Config{
   326  			XDSServer: &bootstrap.ServerConfig{
   327  				ServerURI: "dummyBalancer",
   328  				Creds:     grpc.WithTransportCredentials(insecure.NewCredentials()),
   329  				NodeProto: xdstestutils.EmptyNodeProtoV3,
   330  			},
   331  			ServerListenerResourceNameTemplate: testServerListenerResourceNameTemplate,
   332  			CertProviderConfigs:                certProviderConfigs,
   333  		})
   334  		clientCh.Send(c)
   335  		return c, nil
   336  	}
   337  
   338  	fs := newFakeGRPCServer()
   339  	origNewGRPCServer := newGRPCServer
   340  	newGRPCServer = func(opts ...grpc.ServerOption) grpcServer { return fs }
   341  
   342  	return fs, clientCh, func() {
   343  		newXDSClient = origNewXDSClient
   344  		newGRPCServer = origNewGRPCServer
   345  	}
   346  }
   347  
   348  // setupOverridesForXDSCreds overrides only the xdsClient creation with a fake
   349  // one. Tests that use xdsCredentials need a real grpc.Server instead of a fake
   350  // one, because the xDS-enabled server needs to read configured creds from the
   351  // underlying grpc.Server to confirm whether xdsCreds were configured.
   352  func setupOverridesForXDSCreds(includeCertProviderCfg bool) (*testutils.Channel, func()) {
   353  	clientCh := testutils.NewChannel()
   354  	origNewXDSClient := newXDSClient
   355  	newXDSClient = func() (xdsclient.XDSClient, error) {
   356  		c := fakeclient.NewClient()
   357  		bc := &bootstrap.Config{
   358  			XDSServer: &bootstrap.ServerConfig{
   359  				ServerURI: "dummyBalancer",
   360  				Creds:     grpc.WithTransportCredentials(insecure.NewCredentials()),
   361  				NodeProto: xdstestutils.EmptyNodeProtoV3,
   362  			},
   363  			ServerListenerResourceNameTemplate: testServerListenerResourceNameTemplate,
   364  		}
   365  		if includeCertProviderCfg {
   366  			bc.CertProviderConfigs = certProviderConfigs
   367  		}
   368  		c.SetBootstrapConfig(bc)
   369  		clientCh.Send(c)
   370  		return c, nil
   371  	}
   372  
   373  	return clientCh, func() { newXDSClient = origNewXDSClient }
   374  }
   375  
   376  // TestServeSuccess tests the successful case of calling Serve().
   377  // The following sequence of events happen:
   378  //  1. Create a new GRPCServer and call Serve() in a goroutine.
   379  //  2. Make sure an xdsClient is created, and an LDS watch is registered.
   380  //  3. Push an error response from the xdsClient, and make sure that Serve() does
   381  //     not exit.
   382  //  4. Push a good response from the xdsClient, and make sure that Serve() on the
   383  //     underlying grpc.Server is called.
   384  func (s) TestServeSuccess(t *testing.T) {
   385  	fs, clientCh, cleanup := setupOverrides()
   386  	defer cleanup()
   387  
   388  	// Create a new xDS-enabled gRPC server and pass it a server option to get
   389  	// notified about serving mode changes.
   390  	modeChangeCh := testutils.NewChannel()
   391  	modeChangeOption := ServingModeCallback(func(addr net.Addr, args ServingModeChangeArgs) {
   392  		t.Logf("server mode change callback invoked for listener %q with mode %q and error %v", addr.String(), args.Mode, args.Err)
   393  		modeChangeCh.Send(args.Mode)
   394  	})
   395  	server := NewGRPCServer(modeChangeOption)
   396  	defer server.Stop()
   397  
   398  	lis, err := testutils.LocalTCPListener()
   399  	if err != nil {
   400  		t.Fatalf("testutils.LocalTCPListener() failed: %v", err)
   401  	}
   402  
   403  	// Call Serve() in a goroutine, and push on a channel when Serve returns.
   404  	serveDone := testutils.NewChannel()
   405  	go func() {
   406  		if err := server.Serve(lis); err != nil {
   407  			t.Error(err)
   408  		}
   409  		serveDone.Send(nil)
   410  	}()
   411  
   412  	// Wait for an xdsClient to be created.
   413  	ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout)
   414  	defer cancel()
   415  	c, err := clientCh.Receive(ctx)
   416  	if err != nil {
   417  		t.Fatalf("error when waiting for new xdsClient to be created: %v", err)
   418  	}
   419  	client := c.(*fakeclient.Client)
   420  
   421  	// Wait for a listener watch to be registered on the xdsClient.
   422  	name, err := client.WaitForWatchListener(ctx)
   423  	if err != nil {
   424  		t.Fatalf("error when waiting for a ListenerWatch: %v", err)
   425  	}
   426  	wantName := strings.Replace(testServerListenerResourceNameTemplate, "%s", lis.Addr().String(), -1)
   427  	if name != wantName {
   428  		t.Fatalf("LDS watch registered for name %q, want %q", name, wantName)
   429  	}
   430  
   431  	// Push an error to the registered listener watch callback and make sure
   432  	// that Serve does not return.
   433  	client.InvokeWatchListenerCallback(xdsresource.ListenerUpdate{}, xdsresource.NewErrorf(xdsresource.ErrorTypeResourceNotFound, "LDS resource not found"))
   434  	sCtx, sCancel := context.WithTimeout(context.Background(), defaultTestShortTimeout)
   435  	defer sCancel()
   436  	if _, err := serveDone.Receive(sCtx); err != context.DeadlineExceeded {
   437  		t.Fatal("Serve() returned after a bad LDS response")
   438  	}
   439  
   440  	// Make sure the serving mode changes appropriately.
   441  	v, err := modeChangeCh.Receive(ctx)
   442  	if err != nil {
   443  		t.Fatalf("error when waiting for serving mode to change: %v", err)
   444  	}
   445  	if mode := v.(connectivity.ServingMode); mode != connectivity.ServingModeNotServing {
   446  		t.Fatalf("server mode is %q, want %q", mode, connectivity.ServingModeNotServing)
   447  	}
   448  
   449  	// Push a good LDS response, and wait for Serve() to be invoked on the
   450  	// underlying grpc.Server.
   451  	fcm, err := xdsresource.NewFilterChainManager(listenerWithFilterChains, nil)
   452  	if err != nil {
   453  		t.Fatalf("xdsclient.NewFilterChainManager() failed with error: %v", err)
   454  	}
   455  	addr, port := splitHostPort(lis.Addr().String())
   456  	client.InvokeWatchListenerCallback(xdsresource.ListenerUpdate{
   457  		RouteConfigName: "routeconfig",
   458  		InboundListenerCfg: &xdsresource.InboundListenerConfig{
   459  			Address:      addr,
   460  			Port:         port,
   461  			FilterChains: fcm,
   462  		},
   463  	}, nil)
   464  	if _, err := fs.serveCh.Receive(ctx); err != nil {
   465  		t.Fatalf("error when waiting for Serve() to be invoked on the grpc.Server")
   466  	}
   467  
   468  	// Make sure the serving mode changes appropriately.
   469  	v, err = modeChangeCh.Receive(ctx)
   470  	if err != nil {
   471  		t.Fatalf("error when waiting for serving mode to change: %v", err)
   472  	}
   473  	if mode := v.(connectivity.ServingMode); mode != connectivity.ServingModeServing {
   474  		t.Fatalf("server mode is %q, want %q", mode, connectivity.ServingModeServing)
   475  	}
   476  
   477  	// Push an update to the registered listener watch callback with a Listener
   478  	// resource whose host:port does not match the actual listening address and
   479  	// port. This will push the listener to "not-serving" mode.
   480  	client.InvokeWatchListenerCallback(xdsresource.ListenerUpdate{
   481  		RouteConfigName: "routeconfig",
   482  		InboundListenerCfg: &xdsresource.InboundListenerConfig{
   483  			Address:      "10.20.30.40",
   484  			Port:         "666",
   485  			FilterChains: fcm,
   486  		},
   487  	}, nil)
   488  	sCtx, sCancel = context.WithTimeout(context.Background(), defaultTestShortTimeout)
   489  	defer sCancel()
   490  	if _, err := serveDone.Receive(sCtx); err != context.DeadlineExceeded {
   491  		t.Fatal("Serve() returned after a bad LDS response")
   492  	}
   493  
   494  	// Make sure the serving mode changes appropriately.
   495  	v, err = modeChangeCh.Receive(ctx)
   496  	if err != nil {
   497  		t.Fatalf("error when waiting for serving mode to change: %v", err)
   498  	}
   499  	if mode := v.(connectivity.ServingMode); mode != connectivity.ServingModeNotServing {
   500  		t.Fatalf("server mode is %q, want %q", mode, connectivity.ServingModeNotServing)
   501  	}
   502  }
   503  
   504  // TestServeWithStop tests the case where Stop() is called before an LDS update
   505  // is received. This should cause Serve() to exit before calling Serve() on the
   506  // underlying grpc.Server.
   507  func (s) TestServeWithStop(t *testing.T) {
   508  	fs, clientCh, cleanup := setupOverrides()
   509  	defer cleanup()
   510  
   511  	// Note that we are not deferring the Stop() here since we explicitly call
   512  	// it after the LDS watch has been registered.
   513  	server := NewGRPCServer()
   514  
   515  	lis, err := testutils.LocalTCPListener()
   516  	if err != nil {
   517  		t.Fatalf("testutils.LocalTCPListener() failed: %v", err)
   518  	}
   519  
   520  	// Call Serve() in a goroutine, and push on a channel when Serve returns.
   521  	serveDone := testutils.NewChannel()
   522  	go func() {
   523  		if err := server.Serve(lis); err != nil {
   524  			t.Error(err)
   525  		}
   526  		serveDone.Send(nil)
   527  	}()
   528  
   529  	// Wait for an xdsClient to be created.
   530  	ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout)
   531  	defer cancel()
   532  	c, err := clientCh.Receive(ctx)
   533  	if err != nil {
   534  		t.Fatalf("error when waiting for new xdsClient to be created: %v", err)
   535  	}
   536  	client := c.(*fakeclient.Client)
   537  
   538  	// Wait for a listener watch to be registered on the xdsClient.
   539  	name, err := client.WaitForWatchListener(ctx)
   540  	if err != nil {
   541  		server.Stop()
   542  		t.Fatalf("error when waiting for a ListenerWatch: %v", err)
   543  	}
   544  	wantName := strings.Replace(testServerListenerResourceNameTemplate, "%s", lis.Addr().String(), -1)
   545  	if name != wantName {
   546  		server.Stop()
   547  		t.Fatalf("LDS watch registered for name %q, wantPrefix %q", name, wantName)
   548  	}
   549  
   550  	// Call Stop() on the server before a listener update is received, and
   551  	// expect Serve() to exit.
   552  	server.Stop()
   553  	if _, err := serveDone.Receive(ctx); err != nil {
   554  		t.Fatalf("error when waiting for Serve() to exit")
   555  	}
   556  
   557  	// Make sure that Serve() on the underlying grpc.Server is not called.
   558  	sCtx, sCancel := context.WithTimeout(context.Background(), defaultTestShortTimeout)
   559  	defer sCancel()
   560  	if _, err := fs.serveCh.Receive(sCtx); err != context.DeadlineExceeded {
   561  		t.Fatal("Serve() called on underlying grpc.Server")
   562  	}
   563  }
   564  
   565  // TestServeBootstrapFailure tests the case where xDS bootstrap fails and
   566  // verifies that Serve() exits with a non-nil error.
   567  func (s) TestServeBootstrapFailure(t *testing.T) {
   568  	// Since we have not setup fakes for anything, this will attempt to do real
   569  	// xDS bootstrap and that will fail because the bootstrap environment
   570  	// variable is not set.
   571  	server := NewGRPCServer()
   572  	defer server.Stop()
   573  
   574  	lis, err := testutils.LocalTCPListener()
   575  	if err != nil {
   576  		t.Fatalf("testutils.LocalTCPListener() failed: %v", err)
   577  	}
   578  
   579  	serveDone := testutils.NewChannel()
   580  	go func() { serveDone.Send(server.Serve(lis)) }()
   581  
   582  	ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout)
   583  	defer cancel()
   584  	v, err := serveDone.Receive(ctx)
   585  	if err != nil {
   586  		t.Fatalf("error when waiting for Serve() to exit: %v", err)
   587  	}
   588  	if err, ok := v.(error); !ok || err == nil {
   589  		t.Fatal("Serve() did not exit with error")
   590  	}
   591  }
   592  
   593  // TestServeBootstrapConfigInvalid tests the cases where the bootstrap config
   594  // does not contain expected fields. Verifies that the call to Serve() fails.
   595  func (s) TestServeBootstrapConfigInvalid(t *testing.T) {
   596  	tests := []struct {
   597  		desc            string
   598  		bootstrapConfig *bootstrap.Config
   599  	}{
   600  		{
   601  			desc:            "bootstrap config is missing",
   602  			bootstrapConfig: nil,
   603  		},
   604  		{
   605  			desc: "certificate provider config is missing",
   606  			bootstrapConfig: &bootstrap.Config{
   607  				XDSServer: &bootstrap.ServerConfig{
   608  					ServerURI: "dummyBalancer",
   609  					Creds:     grpc.WithTransportCredentials(insecure.NewCredentials()),
   610  					NodeProto: xdstestutils.EmptyNodeProtoV3,
   611  				},
   612  				ServerListenerResourceNameTemplate: testServerListenerResourceNameTemplate,
   613  			},
   614  		},
   615  		{
   616  			desc: "server_listener_resource_name_template is missing",
   617  			bootstrapConfig: &bootstrap.Config{
   618  				XDSServer: &bootstrap.ServerConfig{
   619  					ServerURI: "dummyBalancer",
   620  					Creds:     grpc.WithTransportCredentials(insecure.NewCredentials()),
   621  					NodeProto: xdstestutils.EmptyNodeProtoV3,
   622  				},
   623  				CertProviderConfigs: certProviderConfigs,
   624  			},
   625  		},
   626  	}
   627  
   628  	for _, test := range tests {
   629  		t.Run(test.desc, func(t *testing.T) {
   630  			// Override the xdsClient creation with one that returns a fake
   631  			// xdsClient with the specified bootstrap configuration.
   632  			clientCh := testutils.NewChannel()
   633  			origNewXDSClient := newXDSClient
   634  			newXDSClient = func() (xdsclient.XDSClient, error) {
   635  				c := fakeclient.NewClient()
   636  				c.SetBootstrapConfig(test.bootstrapConfig)
   637  				clientCh.Send(c)
   638  				return c, nil
   639  			}
   640  			defer func() { newXDSClient = origNewXDSClient }()
   641  
   642  			xdsCreds, err := xds.NewServerCredentials(xds.ServerOptions{FallbackCreds: insecure.NewCredentials()})
   643  			if err != nil {
   644  				t.Fatalf("failed to create xds server credentials: %v", err)
   645  			}
   646  			server := NewGRPCServer(grpc.Creds(xdsCreds))
   647  			defer server.Stop()
   648  
   649  			lis, err := testutils.LocalTCPListener()
   650  			if err != nil {
   651  				t.Fatalf("testutils.LocalTCPListener() failed: %v", err)
   652  			}
   653  
   654  			serveDone := testutils.NewChannel()
   655  			go func() {
   656  				err := server.Serve(lis)
   657  				serveDone.Send(err)
   658  			}()
   659  
   660  			ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout)
   661  			defer cancel()
   662  			v, err := serveDone.Receive(ctx)
   663  			if err != nil {
   664  				t.Fatalf("error when waiting for Serve() to exit: %v", err)
   665  			}
   666  			if err, ok := v.(error); !ok || err == nil {
   667  				t.Fatal("Serve() did not exit with error")
   668  			}
   669  		})
   670  	}
   671  }
   672  
   673  // TestServeNewClientFailure tests the case where xds client creation fails and
   674  // verifies that Server() exits with a non-nil error.
   675  func (s) TestServeNewClientFailure(t *testing.T) {
   676  	origNewXDSClient := newXDSClient
   677  	newXDSClient = func() (xdsclient.XDSClient, error) {
   678  		return nil, errors.New("xdsClient creation failed")
   679  	}
   680  	defer func() { newXDSClient = origNewXDSClient }()
   681  
   682  	server := NewGRPCServer()
   683  	defer server.Stop()
   684  
   685  	lis, err := testutils.LocalTCPListener()
   686  	if err != nil {
   687  		t.Fatalf("testutils.LocalTCPListener() failed: %v", err)
   688  	}
   689  
   690  	serveDone := testutils.NewChannel()
   691  	go func() {
   692  		err := server.Serve(lis)
   693  		serveDone.Send(err)
   694  	}()
   695  
   696  	ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout)
   697  	defer cancel()
   698  	v, err := serveDone.Receive(ctx)
   699  	if err != nil {
   700  		t.Fatalf("error when waiting for Serve() to exit: %v", err)
   701  	}
   702  	if err, ok := v.(error); !ok || err == nil {
   703  		t.Fatal("Serve() did not exit with error")
   704  	}
   705  }
   706  
   707  // TestHandleListenerUpdate_NoXDSCreds tests the case where an xds-enabled gRPC
   708  // server is not configured with xDS credentials. Verifies that the security
   709  // config received as part of a Listener update is not acted upon.
   710  func (s) TestHandleListenerUpdate_NoXDSCreds(t *testing.T) {
   711  	fs, clientCh, cleanup := setupOverrides()
   712  	defer cleanup()
   713  
   714  	server := NewGRPCServer()
   715  	defer server.Stop()
   716  
   717  	lis, err := testutils.LocalTCPListener()
   718  	if err != nil {
   719  		t.Fatalf("testutils.LocalTCPListener() failed: %v", err)
   720  	}
   721  
   722  	// Call Serve() in a goroutine, and push on a channel when Serve returns.
   723  	serveDone := testutils.NewChannel()
   724  	go func() {
   725  		if err := server.Serve(lis); err != nil {
   726  			t.Error(err)
   727  		}
   728  		serveDone.Send(nil)
   729  	}()
   730  
   731  	// Wait for an xdsClient to be created.
   732  	ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout)
   733  	defer cancel()
   734  	c, err := clientCh.Receive(ctx)
   735  	if err != nil {
   736  		t.Fatalf("error when waiting for new xdsClient to be created: %v", err)
   737  	}
   738  	client := c.(*fakeclient.Client)
   739  
   740  	// Wait for a listener watch to be registered on the xdsClient.
   741  	name, err := client.WaitForWatchListener(ctx)
   742  	if err != nil {
   743  		t.Fatalf("error when waiting for a ListenerWatch: %v", err)
   744  	}
   745  	wantName := strings.Replace(testServerListenerResourceNameTemplate, "%s", lis.Addr().String(), -1)
   746  	if name != wantName {
   747  		t.Fatalf("LDS watch registered for name %q, want %q", name, wantName)
   748  	}
   749  
   750  	// Push a good LDS response with security config, and wait for Serve() to be
   751  	// invoked on the underlying grpc.Server. Also make sure that certificate
   752  	// providers are not created.
   753  	fcm, err := xdsresource.NewFilterChainManager(&v3listenerpb.Listener{
   754  		FilterChains: []*v3listenerpb.FilterChain{
   755  			{
   756  				TransportSocket: &v3corepb.TransportSocket{
   757  					Name: "envoy.transport_sockets.tls",
   758  					ConfigType: &v3corepb.TransportSocket_TypedConfig{
   759  						TypedConfig: testutils.MarshalAny(&v3tlspb.DownstreamTlsContext{
   760  							CommonTlsContext: &v3tlspb.CommonTlsContext{
   761  								TlsCertificateCertificateProviderInstance: &v3tlspb.CommonTlsContext_CertificateProviderInstance{
   762  									InstanceName:    "identityPluginInstance",
   763  									CertificateName: "identityCertName",
   764  								},
   765  							},
   766  						}),
   767  					},
   768  				},
   769  				Filters: []*v3listenerpb.Filter{
   770  					{
   771  						Name: "filter-1",
   772  						ConfigType: &v3listenerpb.Filter_TypedConfig{
   773  							TypedConfig: testutils.MarshalAny(&v3httppb.HttpConnectionManager{
   774  								RouteSpecifier: &v3httppb.HttpConnectionManager_RouteConfig{
   775  									RouteConfig: &v3routepb.RouteConfiguration{
   776  										Name: "routeName",
   777  										VirtualHosts: []*v3routepb.VirtualHost{{
   778  											Domains: []string{"lds.target.good:3333"},
   779  											Routes: []*v3routepb.Route{{
   780  												Match: &v3routepb.RouteMatch{
   781  													PathSpecifier: &v3routepb.RouteMatch_Prefix{Prefix: "/"},
   782  												},
   783  												Action: &v3routepb.Route_NonForwardingAction{},
   784  											}}}}},
   785  								},
   786  								HttpFilters: []*v3httppb.HttpFilter{e2e.RouterHTTPFilter},
   787  							}),
   788  						},
   789  					},
   790  				},
   791  			},
   792  		},
   793  	}, nil)
   794  	if err != nil {
   795  		t.Fatalf("xdsclient.NewFilterChainManager() failed with error: %v", err)
   796  	}
   797  	addr, port := splitHostPort(lis.Addr().String())
   798  	client.InvokeWatchListenerCallback(xdsresource.ListenerUpdate{
   799  		RouteConfigName: "routeconfig",
   800  		InboundListenerCfg: &xdsresource.InboundListenerConfig{
   801  			Address:      addr,
   802  			Port:         port,
   803  			FilterChains: fcm,
   804  		},
   805  	}, nil)
   806  	if _, err := fs.serveCh.Receive(ctx); err != nil {
   807  		t.Fatalf("error when waiting for Serve() to be invoked on the grpc.Server")
   808  	}
   809  
   810  	// Make sure the security configuration is not acted upon.
   811  	if err := verifyCertProviderNotCreated(); err != nil {
   812  		t.Fatal(err)
   813  	}
   814  }
   815  
   816  // TestHandleListenerUpdate_ErrorUpdate tests the case where an xds-enabled gRPC
   817  // server is configured with xDS credentials, but receives a Listener update
   818  // with an error. Verifies that no certificate providers are created.
   819  func (s) TestHandleListenerUpdate_ErrorUpdate(t *testing.T) {
   820  	clientCh, cleanup := setupOverridesForXDSCreds(true)
   821  	defer cleanup()
   822  
   823  	xdsCreds, err := xds.NewServerCredentials(xds.ServerOptions{FallbackCreds: insecure.NewCredentials()})
   824  	if err != nil {
   825  		t.Fatalf("failed to create xds server credentials: %v", err)
   826  	}
   827  
   828  	server := NewGRPCServer(grpc.Creds(xdsCreds))
   829  	defer server.Stop()
   830  
   831  	lis, err := testutils.LocalTCPListener()
   832  	if err != nil {
   833  		t.Fatalf("testutils.LocalTCPListener() failed: %v", err)
   834  	}
   835  
   836  	// Call Serve() in a goroutine, and push on a channel when Serve returns.
   837  	serveDone := testutils.NewChannel()
   838  	go func() {
   839  		if err := server.Serve(lis); err != nil {
   840  			t.Error(err)
   841  		}
   842  		serveDone.Send(nil)
   843  	}()
   844  
   845  	// Wait for an xdsClient to be created.
   846  	ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout)
   847  	defer cancel()
   848  	c, err := clientCh.Receive(ctx)
   849  	if err != nil {
   850  		t.Fatalf("error when waiting for new xdsClient to be created: %v", err)
   851  	}
   852  	client := c.(*fakeclient.Client)
   853  
   854  	// Wait for a listener watch to be registered on the xdsClient.
   855  	name, err := client.WaitForWatchListener(ctx)
   856  	if err != nil {
   857  		t.Fatalf("error when waiting for a ListenerWatch: %v", err)
   858  	}
   859  	wantName := strings.Replace(testServerListenerResourceNameTemplate, "%s", lis.Addr().String(), -1)
   860  	if name != wantName {
   861  		t.Fatalf("LDS watch registered for name %q, want %q", name, wantName)
   862  	}
   863  
   864  	// Push an error to the registered listener watch callback and make sure
   865  	// that Serve does not return.
   866  	client.InvokeWatchListenerCallback(xdsresource.ListenerUpdate{}, errors.New("LDS error"))
   867  	sCtx, sCancel := context.WithTimeout(context.Background(), defaultTestShortTimeout)
   868  	defer sCancel()
   869  	if _, err := serveDone.Receive(sCtx); err != context.DeadlineExceeded {
   870  		t.Fatal("Serve() returned after a bad LDS response")
   871  	}
   872  
   873  	// Also make sure that no certificate providers are created.
   874  	if err := verifyCertProviderNotCreated(); err != nil {
   875  		t.Fatal(err)
   876  	}
   877  }
   878  
   879  func verifyCertProviderNotCreated() error {
   880  	sCtx, sCancel := context.WithTimeout(context.Background(), defaultTestShortTimeout)
   881  	defer sCancel()
   882  	if _, err := fpb1.buildCh.Receive(sCtx); err != context.DeadlineExceeded {
   883  		return errors.New("certificate provider created when no xDS creds were specified")
   884  	}
   885  	sCtx, sCancel = context.WithTimeout(context.Background(), defaultTestShortTimeout)
   886  	defer sCancel()
   887  	if _, err := fpb2.buildCh.Receive(sCtx); err != context.DeadlineExceeded {
   888  		return errors.New("certificate provider created when no xDS creds were specified")
   889  	}
   890  	return nil
   891  }