diff --git a/internal/stubserver/stubserver.go b/internal/stubserver/stubserver.go index 73c12aed851..012021dc03e 100644 --- a/internal/stubserver/stubserver.go +++ b/internal/stubserver/stubserver.go @@ -24,6 +24,7 @@ import ( "context" "fmt" "net" + "testing" "time" "google.golang.org/grpc" @@ -179,3 +180,21 @@ func parseCfg(r *manual.Resolver, s string) *serviceconfig.ParseResult { } return g } + +// StartTestService spins up a stub server exposing the TestService on a local +// port. If the passed in server is nil, a stub server that implements only the +// EmptyCall and UnaryCall RPCs is started. +func StartTestService(t *testing.T, server *StubServer) *StubServer { + if server == nil { + server = &StubServer{ + EmptyCallF: func(context.Context, *testpb.Empty) (*testpb.Empty, error) { return &testpb.Empty{}, nil }, + UnaryCallF: func(context.Context, *testpb.SimpleRequest) (*testpb.SimpleResponse, error) { + return &testpb.SimpleResponse{}, nil + }, + } + } + server.StartServer() + + t.Logf("Started test service backend at %q", server.Address) + return server +} diff --git a/internal/testutils/parse_port.go b/internal/testutils/parse_port.go new file mode 100644 index 00000000000..c633af06a7d --- /dev/null +++ b/internal/testutils/parse_port.go @@ -0,0 +1,39 @@ +/* + * + * Copyright 2023 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package testutils + +import ( + "net" + "strconv" + "testing" +) + +// ParsePort returns the port from the given address string, as a unit32. +func ParsePort(t *testing.T, addr string) uint32 { + t.Helper() + + _, p, err := net.SplitHostPort(addr) + if err != nil { + t.Fatalf("Invalid serving address: %v", err) + } + port, err := strconv.ParseUint(p, 10, 32) + if err != nil { + t.Fatalf("Invalid serving port: %v", err) + } + return uint32(port) +} diff --git a/test/xds/xds_client_ack_nack_test.go b/test/xds/xds_client_ack_nack_test.go index 793bdc2fa62..87ff0077cd7 100644 --- a/test/xds/xds_client_ack_nack_test.go +++ b/test/xds/xds_client_ack_nack_test.go @@ -27,6 +27,7 @@ import ( "google.golang.org/grpc" "google.golang.org/grpc/credentials/insecure" "google.golang.org/grpc/internal/grpcsync" + "google.golang.org/grpc/internal/stubserver" "google.golang.org/grpc/internal/testutils" "google.golang.org/grpc/internal/testutils/xds/e2e" @@ -123,15 +124,15 @@ func (s) TestClientResourceVersionAfterStreamRestart(t *testing.T) { }) defer cleanup1() - port, cleanup2 := startTestService(t, nil) - defer cleanup2() + server := stubserver.StartTestService(t, nil) + defer server.Stop() const serviceName = "my-service-client-side-xds" resources := e2e.DefaultClientResources(e2e.ResourceParams{ DialTarget: serviceName, NodeID: nodeID, Host: "localhost", - Port: port, + Port: testutils.ParsePort(t, server.Address), SecLevel: e2e.SecurityLevelNone, }) ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout) diff --git a/test/xds/xds_client_affinity_test.go b/test/xds/xds_client_affinity_test.go index 159d295e110..7fff019fa52 100644 --- a/test/xds/xds_client_affinity_test.go +++ b/test/xds/xds_client_affinity_test.go @@ -26,6 +26,8 @@ import ( "google.golang.org/grpc" "google.golang.org/grpc/credentials/insecure" "google.golang.org/grpc/internal/envconfig" + "google.golang.org/grpc/internal/stubserver" + "google.golang.org/grpc/internal/testutils" "google.golang.org/grpc/internal/testutils/xds/e2e" v3clusterpb "github.com/envoyproxy/go-control-plane/envoy/config/cluster/v3" @@ -91,15 +93,15 @@ func (s) TestClientSideAffinitySanityCheck(t *testing.T) { managementServer, nodeID, _, resolver, cleanup1 := e2e.SetupManagementServer(t, e2e.ManagementServerOptions{}) defer cleanup1() - port, cleanup2 := startTestService(t, nil) - defer cleanup2() + server := stubserver.StartTestService(t, nil) + defer server.Stop() const serviceName = "my-service-client-side-xds" resources := e2e.DefaultClientResources(e2e.ResourceParams{ DialTarget: serviceName, NodeID: nodeID, Host: "localhost", - Port: port, + Port: testutils.ParsePort(t, server.Address), SecLevel: e2e.SecurityLevelNone, }) // Replace RDS and CDS resources with ringhash config, but keep the resource diff --git a/test/xds/xds_client_federation_test.go b/test/xds/xds_client_federation_test.go index d94b2f40fa2..1aebcd22610 100644 --- a/test/xds/xds_client_federation_test.go +++ b/test/xds/xds_client_federation_test.go @@ -30,6 +30,8 @@ import ( "google.golang.org/grpc/credentials/insecure" "google.golang.org/grpc/internal" "google.golang.org/grpc/internal/envconfig" + "google.golang.org/grpc/internal/stubserver" + "google.golang.org/grpc/internal/testutils" "google.golang.org/grpc/internal/testutils/xds/bootstrap" "google.golang.org/grpc/internal/testutils/xds/e2e" "google.golang.org/grpc/resolver" @@ -89,8 +91,8 @@ func (s) TestClientSideFederation(t *testing.T) { if err != nil { t.Fatalf("Failed to create xDS resolver for testing: %v", err) } - port, cleanup := startTestService(t, nil) - defer cleanup() + server := stubserver.StartTestService(t, nil) + defer server.Stop() const serviceName = "my-service-client-side-xds" // LDS is old style name. @@ -115,7 +117,7 @@ func (s) TestClientSideFederation(t *testing.T) { NodeID: nodeID, // This has only RDS and EDS. Routes: []*v3routepb.RouteConfiguration{e2e.DefaultRouteConfig(rdsName, ldsName, cdsName)}, - Endpoints: []*v3endpointpb.ClusterLoadAssignment{e2e.DefaultEndpoint(edsName, "localhost", []uint32{port})}, + Endpoints: []*v3endpointpb.ClusterLoadAssignment{e2e.DefaultEndpoint(edsName, "localhost", []uint32{testutils.ParsePort(t, server.Address)})}, SkipValidation: true, } @@ -161,15 +163,15 @@ func (s) TestFederation_UnknownAuthorityInDialTarget(t *testing.T) { managementServer, nodeID, _, resolver, cleanup1 := e2e.SetupManagementServer(t, e2e.ManagementServerOptions{}) defer cleanup1() - port, cleanup2 := startTestService(t, nil) - defer cleanup2() + server := stubserver.StartTestService(t, nil) + defer server.Stop() const serviceName = "my-service-client-side-xds" resources := e2e.DefaultClientResources(e2e.ResourceParams{ DialTarget: serviceName, NodeID: nodeID, Host: "localhost", - Port: port, + Port: testutils.ParsePort(t, server.Address), SecLevel: e2e.SecurityLevelNone, }) ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout) diff --git a/test/xds/xds_client_ignore_resource_deletion_test.go b/test/xds/xds_client_ignore_resource_deletion_test.go index e59a197fd9c..f5df318a943 100644 --- a/test/xds/xds_client_ignore_resource_deletion_test.go +++ b/test/xds/xds_client_ignore_resource_deletion_test.go @@ -31,6 +31,7 @@ import ( "google.golang.org/grpc/connectivity" "google.golang.org/grpc/credentials/insecure" "google.golang.org/grpc/internal" + "google.golang.org/grpc/internal/stubserver" "google.golang.org/grpc/internal/testutils" "google.golang.org/grpc/internal/testutils/xds/bootstrap" "google.golang.org/grpc/internal/testutils/xds/e2e" @@ -89,11 +90,11 @@ var ( // // Resource deletion is only applicable to Listener and Cluster resources. func (s) TestIgnoreResourceDeletionOnClient(t *testing.T) { - port1, cleanup := startTestService(t, nil) - t.Cleanup(cleanup) + server1 := stubserver.StartTestService(t, nil) + t.Cleanup(server1.Stop) - port2, cleanup := startTestService(t, nil) - t.Cleanup(cleanup) + server2 := stubserver.StartTestService(t, nil) + t.Cleanup(server2.Stop) initialResourceOnServer := func(nodeID string) e2e.UpdateOptions { return e2e.UpdateOptions{ @@ -105,8 +106,8 @@ func (s) TestIgnoreResourceDeletionOnClient(t *testing.T) { e2e.DefaultCluster(cdsName2, edsName2, e2e.SecurityLevelNone), }, Endpoints: []*endpointpb.ClusterLoadAssignment{ - e2e.DefaultEndpoint(edsName1, "localhost", []uint32{port1}), - e2e.DefaultEndpoint(edsName2, "localhost", []uint32{port2}), + e2e.DefaultEndpoint(edsName1, "localhost", []uint32{testutils.ParsePort(t, server1.Address)}), + e2e.DefaultEndpoint(edsName2, "localhost", []uint32{testutils.ParsePort(t, server2.Address)}), }, SkipValidation: true, } diff --git a/test/xds/xds_client_integration_test.go b/test/xds/xds_client_integration_test.go index a431ab5f333..e03c937f816 100644 --- a/test/xds/xds_client_integration_test.go +++ b/test/xds/xds_client_integration_test.go @@ -21,8 +21,6 @@ package xds_test import ( "context" "fmt" - "net" - "strconv" "testing" "time" @@ -30,6 +28,7 @@ import ( "google.golang.org/grpc/credentials/insecure" "google.golang.org/grpc/internal/grpctest" "google.golang.org/grpc/internal/stubserver" + "google.golang.org/grpc/internal/testutils" "google.golang.org/grpc/internal/testutils/xds/e2e" testgrpc "google.golang.org/grpc/interop/grpc_testing" @@ -49,47 +48,19 @@ const ( defaultTestShortTimeout = 10 * time.Millisecond // For events expected to *not* happen. ) -// startTestService spins up a server exposing the TestService on a local port. -// -// Returns the following: -// - the port the server is listening on -// - cleanup function to be invoked by the tests when done -func startTestService(t *testing.T, server *stubserver.StubServer) (uint32, func()) { - if server == nil { - server = &stubserver.StubServer{ - EmptyCallF: func(context.Context, *testpb.Empty) (*testpb.Empty, error) { return &testpb.Empty{}, nil }, - UnaryCallF: func(context.Context, *testpb.SimpleRequest) (*testpb.SimpleResponse, error) { - return &testpb.SimpleResponse{}, nil - }, - } - } - server.StartServer() - - _, p, err := net.SplitHostPort(server.Address) - if err != nil { - t.Fatalf("invalid serving address for stub server: %v", err) - } - port, err := strconv.ParseUint(p, 10, 32) - if err != nil { - t.Fatalf("invalid serving port for stub server: %v", err) - } - t.Logf("Started test service backend at %q", server.Address) - return uint32(port), server.Stop -} - func (s) TestClientSideXDS(t *testing.T) { managementServer, nodeID, _, resolver, cleanup1 := e2e.SetupManagementServer(t, e2e.ManagementServerOptions{}) defer cleanup1() - port, cleanup2 := startTestService(t, nil) - defer cleanup2() + server := stubserver.StartTestService(t, nil) + defer server.Stop() const serviceName = "my-service-client-side-xds" resources := e2e.DefaultClientResources(e2e.ResourceParams{ DialTarget: serviceName, NodeID: nodeID, Host: "localhost", - Port: port, + Port: testutils.ParsePort(t, server.Address), SecLevel: e2e.SecurityLevelNone, }) ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout) diff --git a/test/xds/xds_client_outlier_detection_test.go b/test/xds/xds_client_outlier_detection_test.go index d0afcca78ae..fa08e9be9a3 100644 --- a/test/xds/xds_client_outlier_detection_test.go +++ b/test/xds/xds_client_outlier_detection_test.go @@ -33,6 +33,7 @@ import ( "google.golang.org/grpc" "google.golang.org/grpc/credentials/insecure" "google.golang.org/grpc/internal/stubserver" + "google.golang.org/grpc/internal/testutils" "google.golang.org/grpc/internal/testutils/xds/e2e" testgrpc "google.golang.org/grpc/interop/grpc_testing" testpb "google.golang.org/grpc/interop/grpc_testing" @@ -52,15 +53,19 @@ func (s) TestOutlierDetection_NoopConfig(t *testing.T) { managementServer, nodeID, _, resolver, cleanup1 := e2e.SetupManagementServer(t, e2e.ManagementServerOptions{}) defer cleanup1() - port, cleanup2 := startTestService(t, nil) - defer cleanup2() + server := &stubserver.StubServer{ + EmptyCallF: func(context.Context, *testpb.Empty) (*testpb.Empty, error) { return &testpb.Empty{}, nil }, + } + server.StartServer() + t.Logf("Started test service backend at %q", server.Address) + defer server.Stop() const serviceName = "my-service-client-side-xds" resources := e2e.DefaultClientResources(e2e.ResourceParams{ DialTarget: serviceName, NodeID: nodeID, Host: "localhost", - Port: port, + Port: testutils.ParsePort(t, server.Address), SecLevel: e2e.SecurityLevelNone, }) ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout) @@ -170,31 +175,21 @@ func (s) TestOutlierDetectionWithOutlier(t *testing.T) { defer cleanup() // Working backend 1. - backend1 := &stubserver.StubServer{ - EmptyCallF: func(ctx context.Context, in *testpb.Empty) (*testpb.Empty, error) { - return &testpb.Empty{}, nil - }, - } - port1, cleanup1 := startTestService(t, backend1) - defer cleanup1() + backend1 := stubserver.StartTestService(t, nil) + port1 := testutils.ParsePort(t, backend1.Address) + defer backend1.Stop() // Working backend 2. - backend2 := &stubserver.StubServer{ - EmptyCallF: func(ctx context.Context, in *testpb.Empty) (*testpb.Empty, error) { - return &testpb.Empty{}, nil - }, - } - port2, cleanup2 := startTestService(t, backend2) - defer cleanup2() + backend2 := stubserver.StartTestService(t, nil) + port2 := testutils.ParsePort(t, backend2.Address) + defer backend2.Stop() // Backend 3 that will always return an error and eventually ejected. - backend3 := &stubserver.StubServer{ - EmptyCallF: func(ctx context.Context, in *testpb.Empty) (*testpb.Empty, error) { - return nil, errors.New("some error") - }, - } - port3, cleanup3 := startTestService(t, backend3) - defer cleanup3() + backend3 := stubserver.StartTestService(t, &stubserver.StubServer{ + EmptyCallF: func(context.Context, *testpb.Empty) (*testpb.Empty, error) { return nil, errors.New("some error") }, + }) + port3 := testutils.ParsePort(t, backend3.Address) + defer backend3.Stop() const serviceName = "my-service-client-side-xds" resources := clientResourcesMultipleBackendsAndOD(e2e.ResourceParams{ diff --git a/test/xds/xds_client_retry_test.go b/test/xds/xds_client_retry_test.go index 6af0459af7c..d7cb7b4bfb3 100644 --- a/test/xds/xds_client_retry_test.go +++ b/test/xds/xds_client_retry_test.go @@ -27,6 +27,7 @@ import ( "google.golang.org/grpc/codes" "google.golang.org/grpc/credentials/insecure" "google.golang.org/grpc/internal/stubserver" + "google.golang.org/grpc/internal/testutils" "google.golang.org/grpc/internal/testutils/xds/e2e" "google.golang.org/grpc/status" "google.golang.org/protobuf/types/known/wrapperspb" @@ -39,7 +40,11 @@ import ( func (s) TestClientSideRetry(t *testing.T) { ctr := 0 errs := []codes.Code{codes.ResourceExhausted} - ss := &stubserver.StubServer{ + + managementServer, nodeID, _, resolver, cleanup1 := e2e.SetupManagementServer(t, e2e.ManagementServerOptions{}) + defer cleanup1() + + server := stubserver.StartTestService(t, &stubserver.StubServer{ EmptyCallF: func(ctx context.Context, in *testpb.Empty) (*testpb.Empty, error) { defer func() { ctr++ }() if ctr < len(errs) { @@ -47,20 +52,15 @@ func (s) TestClientSideRetry(t *testing.T) { } return &testpb.Empty{}, nil }, - } - - managementServer, nodeID, _, resolver, cleanup1 := e2e.SetupManagementServer(t, e2e.ManagementServerOptions{}) - defer cleanup1() - - port, cleanup2 := startTestService(t, ss) - defer cleanup2() + }) + defer server.Stop() const serviceName = "my-service-client-side-xds" resources := e2e.DefaultClientResources(e2e.ResourceParams{ DialTarget: serviceName, NodeID: nodeID, Host: "localhost", - Port: port, + Port: testutils.ParsePort(t, server.Address), SecLevel: e2e.SecurityLevelNone, }) ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout) diff --git a/test/xds/xds_rls_clusterspecifier_plugin_test.go b/test/xds/xds_rls_clusterspecifier_plugin_test.go index a94e3f2bced..bca198081a7 100644 --- a/test/xds/xds_rls_clusterspecifier_plugin_test.go +++ b/test/xds/xds_rls_clusterspecifier_plugin_test.go @@ -27,6 +27,7 @@ import ( "google.golang.org/grpc/credentials/insecure" "google.golang.org/grpc/internal" "google.golang.org/grpc/internal/envconfig" + "google.golang.org/grpc/internal/stubserver" "google.golang.org/grpc/internal/testutils" "google.golang.org/grpc/internal/testutils/rls" "google.golang.org/grpc/internal/testutils/xds/e2e" @@ -112,8 +113,9 @@ func testRLSinxDS(t *testing.T, lbPolicy e2e.LoadBalancingPolicy) { // RLS Balancer that communicates to this set up fake RLS Server. managementServer, nodeID, _, resolver, cleanup1 := e2e.SetupManagementServer(t, e2e.ManagementServerOptions{}) defer cleanup1() - port, cleanup2 := startTestService(t, nil) - defer cleanup2() + + server := stubserver.StartTestService(t, nil) + defer server.Stop() lis := testutils.NewListenerWrapper(t, nil) rlsServer, rlsRequestCh := rls.SetupFakeRLSServer(t, lis) @@ -129,7 +131,7 @@ func testRLSinxDS(t *testing.T, lbPolicy e2e.LoadBalancingPolicy) { DialTarget: serviceName, NodeID: nodeID, Host: "localhost", - Port: port, + Port: testutils.ParsePort(t, server.Address), SecLevel: e2e.SecurityLevelNone, }, rlsProto) diff --git a/test/xds/xds_security_config_nack_test.go b/test/xds/xds_security_config_nack_test.go index f2974d47c18..1dc3250935b 100644 --- a/test/xds/xds_security_config_nack_test.go +++ b/test/xds/xds_security_config_nack_test.go @@ -26,6 +26,7 @@ import ( "google.golang.org/grpc" "google.golang.org/grpc/credentials/insecure" xdscreds "google.golang.org/grpc/credentials/xds" + "google.golang.org/grpc/internal/stubserver" "google.golang.org/grpc/internal/testutils" "google.golang.org/grpc/internal/testutils/xds/e2e" @@ -323,8 +324,8 @@ func (s) TestUnmarshalCluster_WithUpdateValidatorFunc(t *testing.T) { managementServer, nodeID, _, resolver, cleanup1 := e2e.SetupManagementServer(t, e2e.ManagementServerOptions{}) defer cleanup1() - port, cleanup2 := startTestService(t, nil) - defer cleanup2() + server := stubserver.StartTestService(t, nil) + defer server.Stop() // This creates a `Cluster` resource with a security config which // refers to `e2e.ClientSideCertProviderInstance` for both root and @@ -333,7 +334,7 @@ func (s) TestUnmarshalCluster_WithUpdateValidatorFunc(t *testing.T) { DialTarget: serviceName, NodeID: nodeID, Host: "localhost", - Port: port, + Port: testutils.ParsePort(t, server.Address), SecLevel: e2e.SecurityLevelMTLS, }) resources.Clusters[0].TransportSocket = test.securityConfig diff --git a/xds/internal/balancer/clusterimpl/tests/balancer_test.go b/xds/internal/balancer/clusterimpl/tests/balancer_test.go index 02f2389c7e7..cf0e7b0ce84 100644 --- a/xds/internal/balancer/clusterimpl/tests/balancer_test.go +++ b/xds/internal/balancer/clusterimpl/tests/balancer_test.go @@ -21,8 +21,6 @@ package clusterimpl_test import ( "context" "fmt" - "net" - "strconv" "strings" "testing" "time" @@ -32,6 +30,7 @@ import ( "google.golang.org/grpc/credentials/insecure" "google.golang.org/grpc/internal/grpctest" "google.golang.org/grpc/internal/stubserver" + "google.golang.org/grpc/internal/testutils" "google.golang.org/grpc/internal/testutils/xds/e2e" "google.golang.org/grpc/status" @@ -68,22 +67,8 @@ func (s) TestConfigUpdateWithSameLoadReportingServerConfig(t *testing.T) { defer mgmtServerCleanup() // Start a server backend exposing the test service. - backend := &stubserver.StubServer{ - EmptyCallF: func(context.Context, *testpb.Empty) (*testpb.Empty, error) { return &testpb.Empty{}, nil }, - } - backend.StartServer() - defer backend.Stop() - - // Extract the host and port where the server backend is running. - _, p, err := net.SplitHostPort(backend.Address) - if err != nil { - t.Fatalf("Invalid serving address for server backend: %v", err) - } - port, err := strconv.ParseUint(p, 10, 32) - if err != nil { - t.Fatalf("Invalid serving port for server backend: %v", err) - } - t.Logf("Started server backend at %q", backend.Address) + server := stubserver.StartTestService(t, nil) + defer server.Stop() // Configure the xDS management server with default resources. Override the // default cluster to include an LRS server config pointing to self. @@ -92,7 +77,7 @@ func (s) TestConfigUpdateWithSameLoadReportingServerConfig(t *testing.T) { DialTarget: serviceName, NodeID: nodeID, Host: "localhost", - Port: uint32(port), + Port: testutils.ParsePort(t, server.Address), SecLevel: e2e.SecurityLevelNone, }) resources.Clusters[0].LrsServer = &v3corepb.ConfigSource{ @@ -129,7 +114,7 @@ func (s) TestConfigUpdateWithSameLoadReportingServerConfig(t *testing.T) { e2e.EndpointResourceWithOptions(e2e.EndpointOptions{ ClusterName: "endpoints-" + serviceName, Host: "localhost", - Ports: []uint32{uint32(port)}, + Ports: []uint32{testutils.ParsePort(t, server.Address)}, DropPercents: map[string]int{"test-drop-everything": 100}, }), } diff --git a/xds/internal/balancer/clusterresolver/e2e_test/balancer_test.go b/xds/internal/balancer/clusterresolver/e2e_test/balancer_test.go index 26cc8986bc0..7eaf29e5e1f 100644 --- a/xds/internal/balancer/clusterresolver/e2e_test/balancer_test.go +++ b/xds/internal/balancer/clusterresolver/e2e_test/balancer_test.go @@ -19,8 +19,6 @@ package e2e_test import ( "context" "fmt" - "net" - "strconv" "strings" "testing" "time" @@ -79,25 +77,14 @@ func (s) TestErrorFromParentLB_ConnectionError(t *testing.T) { defer cleanup() // Start a test backend and extract its host and port. - backend := &stubserver.StubServer{ - EmptyCallF: func(context.Context, *testpb.Empty) (*testpb.Empty, error) { return &testpb.Empty{}, nil }, - } - backend.StartServer() - defer backend.Stop() - _, p, err := net.SplitHostPort(backend.Address) - if err != nil { - t.Fatalf("Failed to split test backend address %q: %v", backend.Address, err) - } - port, err := strconv.ParseUint(p, 10, 32) - if err != nil { - t.Fatalf("Failed to parse test backend port %q: %v", backend.Address, err) - } + server := stubserver.StartTestService(t, nil) + defer server.Stop() // Configure cluster and endpoints resources in the management server. resources := e2e.UpdateOptions{ NodeID: nodeID, Clusters: []*v3clusterpb.Cluster{e2e.DefaultCluster(clusterName, edsServiceName, e2e.SecurityLevelNone)}, - Endpoints: []*v3endpointpb.ClusterLoadAssignment{e2e.DefaultEndpoint(edsServiceName, "localhost", []uint32{uint32(port)})}, + Endpoints: []*v3endpointpb.ClusterLoadAssignment{e2e.DefaultEndpoint(edsServiceName, "localhost", []uint32{testutils.ParsePort(t, server.Address)})}, SkipValidation: true, } ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout) @@ -197,25 +184,14 @@ func (s) TestErrorFromParentLB_ResourceNotFound(t *testing.T) { defer cleanup() // Start a test backend and extract its host and port. - backend := &stubserver.StubServer{ - EmptyCallF: func(context.Context, *testpb.Empty) (*testpb.Empty, error) { return &testpb.Empty{}, nil }, - } - backend.StartServer() - defer backend.Stop() - _, p, err := net.SplitHostPort(backend.Address) - if err != nil { - t.Fatalf("Failed to split test backend address %q: %v", backend.Address, err) - } - port, err := strconv.ParseUint(p, 10, 32) - if err != nil { - t.Fatalf("Failed to parse test backend port %q: %v", backend.Address, err) - } + server := stubserver.StartTestService(t, nil) + defer server.Stop() // Configure cluster and endpoints resources in the management server. resources := e2e.UpdateOptions{ NodeID: nodeID, Clusters: []*v3clusterpb.Cluster{e2e.DefaultCluster(clusterName, edsServiceName, e2e.SecurityLevelNone)}, - Endpoints: []*v3endpointpb.ClusterLoadAssignment{e2e.DefaultEndpoint(edsServiceName, "localhost", []uint32{uint32(port)})}, + Endpoints: []*v3endpointpb.ClusterLoadAssignment{e2e.DefaultEndpoint(edsServiceName, "localhost", []uint32{testutils.ParsePort(t, server.Address)})}, SkipValidation: true, } ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout) @@ -303,7 +279,7 @@ func (s) TestErrorFromParentLB_ResourceNotFound(t *testing.T) { resources = e2e.UpdateOptions{ NodeID: nodeID, Clusters: []*v3clusterpb.Cluster{e2e.DefaultCluster(clusterName, edsServiceName, e2e.SecurityLevelNone)}, - Endpoints: []*v3endpointpb.ClusterLoadAssignment{e2e.DefaultEndpoint(edsServiceName, "localhost", []uint32{uint32(port)})}, + Endpoints: []*v3endpointpb.ClusterLoadAssignment{e2e.DefaultEndpoint(edsServiceName, "localhost", []uint32{testutils.ParsePort(t, server.Address)})}, SkipValidation: true, } if err := managementServer.Update(ctx, resources); err != nil { @@ -371,25 +347,14 @@ func (s) TestEDSResourceRemoved(t *testing.T) { defer cleanup() // Start a test backend and extract its host and port. - backend := &stubserver.StubServer{ - EmptyCallF: func(context.Context, *testpb.Empty) (*testpb.Empty, error) { return &testpb.Empty{}, nil }, - } - backend.StartServer() - defer backend.Stop() - _, p, err := net.SplitHostPort(backend.Address) - if err != nil { - t.Fatalf("Failed to split test backend address %q: %v", backend.Address, err) - } - port, err := strconv.ParseUint(p, 10, 32) - if err != nil { - t.Fatalf("Failed to parse test backend port %q: %v", backend.Address, err) - } + server := stubserver.StartTestService(t, nil) + defer server.Stop() // Configure cluster and endpoints resources in the management server. resources := e2e.UpdateOptions{ NodeID: nodeID, Clusters: []*v3clusterpb.Cluster{e2e.DefaultCluster(clusterName, edsServiceName, e2e.SecurityLevelNone)}, - Endpoints: []*v3endpointpb.ClusterLoadAssignment{e2e.DefaultEndpoint(edsServiceName, "localhost", []uint32{uint32(port)})}, + Endpoints: []*v3endpointpb.ClusterLoadAssignment{e2e.DefaultEndpoint(edsServiceName, "localhost", []uint32{testutils.ParsePort(t, server.Address)})}, SkipValidation: true, } ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout) diff --git a/xds/internal/balancer/clusterresolver/e2e_test/eds_impl_test.go b/xds/internal/balancer/clusterresolver/e2e_test/eds_impl_test.go index 75efb758b4f..7aa951bfec5 100644 --- a/xds/internal/balancer/clusterresolver/e2e_test/eds_impl_test.go +++ b/xds/internal/balancer/clusterresolver/e2e_test/eds_impl_test.go @@ -20,8 +20,6 @@ import ( "context" "errors" "fmt" - "net" - "strconv" "strings" "testing" "time" @@ -33,6 +31,7 @@ import ( "google.golang.org/grpc/internal/balancergroup" "google.golang.org/grpc/internal/grpctest" "google.golang.org/grpc/internal/stubserver" + "google.golang.org/grpc/internal/testutils" rrutil "google.golang.org/grpc/internal/testutils/roundrobin" "google.golang.org/grpc/internal/testutils/xds/e2e" "google.golang.org/grpc/resolver" @@ -78,23 +77,11 @@ func backendAddressesAndPorts(t *testing.T, servers []*stubserver.StubServer) ([ ports := make([]uint32, len(servers)) for i := 0; i < len(servers); i++ { addrs[i] = resolver.Address{Addr: servers[i].Address} - ports[i] = extractPortFromAddress(t, servers[i].Address) + ports[i] = testutils.ParsePort(t, servers[i].Address) } return addrs, ports } -func extractPortFromAddress(t *testing.T, address string) uint32 { - _, p, err := net.SplitHostPort(address) - if err != nil { - t.Fatalf("invalid server address %q: %v", address, err) - } - port, err := strconv.ParseUint(p, 10, 32) - if err != nil { - t.Fatalf("invalid server address %q: %v", address, err) - } - return uint32(port) -} - func startTestServiceBackends(t *testing.T, numBackends int) ([]*stubserver.StubServer, func()) { servers := make([]*stubserver.StubServer, numBackends) for i := 0; i < numBackends; i++ {