From 066d5dd2bb5c02a8236c92e508622a7308cc343a Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Tue, 24 Oct 2023 12:33:00 -0700 Subject: [PATCH] [xDS e2e tests] move xDS bootstrap and resource helpers into their own library (#34773) This paves the way for reusing these helpers in a standalone xDS server for memory usage tests. --- CMakeLists.txt | 13 + build_autogenerated.yaml | 26 ++ test/cpp/end2end/xds/BUILD | 19 + .../end2end/xds/xds_cluster_end2end_test.cc | 2 +- test/cpp/end2end/xds/xds_core_end2end_test.cc | 26 +- test/cpp/end2end/xds/xds_csds_end2end_test.cc | 2 +- test/cpp/end2end/xds/xds_end2end_test.cc | 8 +- test/cpp/end2end/xds/xds_end2end_test_lib.cc | 298 +------------- test/cpp/end2end/xds/xds_end2end_test_lib.h | 191 +-------- .../end2end/xds/xds_routing_end2end_test.cc | 2 +- test/cpp/end2end/xds/xds_utils.cc | 375 ++++++++++++++++++ test/cpp/end2end/xds/xds_utils.h | 248 ++++++++++++ 12 files changed, 723 insertions(+), 487 deletions(-) create mode 100644 test/cpp/end2end/xds/xds_utils.cc create mode 100644 test/cpp/end2end/xds/xds_utils.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 2bf75b9cdb2..c7ca8122e2d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -26818,6 +26818,7 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) test/cpp/end2end/xds/xds_cluster_end2end_test.cc test/cpp/end2end/xds/xds_end2end_test_lib.cc test/cpp/end2end/xds/xds_server.cc + test/cpp/end2end/xds/xds_utils.cc test/cpp/util/tls_test_utils.cc ) target_compile_features(xds_cluster_end2end_test PUBLIC cxx_std_14) @@ -27085,6 +27086,7 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) test/cpp/end2end/xds/xds_cluster_type_end2end_test.cc test/cpp/end2end/xds/xds_end2end_test_lib.cc test/cpp/end2end/xds/xds_server.cc + test/cpp/end2end/xds/xds_utils.cc test/cpp/util/tls_test_utils.cc ) target_compile_features(xds_cluster_type_end2end_test PUBLIC cxx_std_14) @@ -27324,6 +27326,7 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) test/cpp/end2end/xds/xds_core_end2end_test.cc test/cpp/end2end/xds/xds_end2end_test_lib.cc test/cpp/end2end/xds/xds_server.cc + test/cpp/end2end/xds/xds_utils.cc test/cpp/util/tls_test_utils.cc ) target_compile_features(xds_core_end2end_test PUBLIC cxx_std_14) @@ -27589,6 +27592,7 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) test/cpp/end2end/xds/xds_csds_end2end_test.cc test/cpp/end2end/xds/xds_end2end_test_lib.cc test/cpp/end2end/xds/xds_server.cc + test/cpp/end2end/xds/xds_utils.cc test/cpp/util/tls_test_utils.cc ) target_compile_features(xds_csds_end2end_test PUBLIC cxx_std_14) @@ -27773,6 +27777,7 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) test/cpp/end2end/xds/xds_end2end_test.cc test/cpp/end2end/xds/xds_end2end_test_lib.cc test/cpp/end2end/xds/xds_server.cc + test/cpp/end2end/xds/xds_utils.cc test/cpp/util/tls_test_utils.cc ) target_compile_features(xds_end2end_test PUBLIC cxx_std_14) @@ -28000,6 +28005,7 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) test/cpp/end2end/xds/xds_end2end_test_lib.cc test/cpp/end2end/xds/xds_fault_injection_end2end_test.cc test/cpp/end2end/xds/xds_server.cc + test/cpp/end2end/xds/xds_utils.cc test/cpp/util/tls_test_utils.cc ) target_compile_features(xds_fault_injection_end2end_test PUBLIC cxx_std_14) @@ -28743,6 +28749,7 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) test/cpp/end2end/xds/xds_end2end_test_lib.cc test/cpp/end2end/xds/xds_outlier_detection_end2end_test.cc test/cpp/end2end/xds/xds_server.cc + test/cpp/end2end/xds/xds_utils.cc test/cpp/util/tls_test_utils.cc ) target_compile_features(xds_outlier_detection_end2end_test PUBLIC cxx_std_14) @@ -28918,6 +28925,7 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) test/cpp/end2end/xds/xds_end2end_test_lib.cc test/cpp/end2end/xds/xds_override_host_end2end_test.cc test/cpp/end2end/xds/xds_server.cc + test/cpp/end2end/xds/xds_utils.cc test/cpp/util/tls_test_utils.cc ) target_compile_features(xds_override_host_end2end_test PUBLIC cxx_std_14) @@ -29163,6 +29171,7 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) test/cpp/end2end/xds/xds_end2end_test_lib.cc test/cpp/end2end/xds/xds_pick_first_end2end_test.cc test/cpp/end2end/xds/xds_server.cc + test/cpp/end2end/xds/xds_utils.cc test/cpp/util/tls_test_utils.cc ) target_compile_features(xds_pick_first_end2end_test PUBLIC cxx_std_14) @@ -29331,6 +29340,7 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) test/cpp/end2end/xds/xds_end2end_test_lib.cc test/cpp/end2end/xds/xds_ring_hash_end2end_test.cc test/cpp/end2end/xds/xds_server.cc + test/cpp/end2end/xds/xds_utils.cc test/cpp/util/tls_test_utils.cc ) target_compile_features(xds_ring_hash_end2end_test PUBLIC cxx_std_14) @@ -29503,6 +29513,7 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) test/cpp/end2end/xds/xds_end2end_test_lib.cc test/cpp/end2end/xds/xds_rls_end2end_test.cc test/cpp/end2end/xds/xds_server.cc + test/cpp/end2end/xds/xds_utils.cc test/cpp/util/tls_test_utils.cc ) target_compile_features(xds_rls_end2end_test PUBLIC cxx_std_14) @@ -29786,6 +29797,7 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) test/cpp/end2end/xds/xds_end2end_test_lib.cc test/cpp/end2end/xds/xds_routing_end2end_test.cc test/cpp/end2end/xds/xds_server.cc + test/cpp/end2end/xds/xds_utils.cc test/cpp/util/tls_test_utils.cc ) target_compile_features(xds_routing_end2end_test PUBLIC cxx_std_14) @@ -30024,6 +30036,7 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) test/cpp/end2end/test_service_impl.cc test/cpp/end2end/xds/xds_end2end_test_lib.cc test/cpp/end2end/xds/xds_server.cc + test/cpp/end2end/xds/xds_utils.cc test/cpp/end2end/xds/xds_wrr_end2end_test.cc test/cpp/util/tls_test_utils.cc ) diff --git a/build_autogenerated.yaml b/build_autogenerated.yaml index 750debd3f6b..41d37ec8ee3 100644 --- a/build_autogenerated.yaml +++ b/build_autogenerated.yaml @@ -17560,6 +17560,7 @@ targets: - test/cpp/end2end/test_service_impl.h - test/cpp/end2end/xds/xds_end2end_test_lib.h - test/cpp/end2end/xds/xds_server.h + - test/cpp/end2end/xds/xds_utils.h - test/cpp/util/tls_test_utils.h src: - src/proto/grpc/testing/duplicate/echo_duplicate.proto @@ -17598,6 +17599,7 @@ targets: - test/cpp/end2end/xds/xds_cluster_end2end_test.cc - test/cpp/end2end/xds/xds_end2end_test_lib.cc - test/cpp/end2end/xds/xds_server.cc + - test/cpp/end2end/xds/xds_utils.cc - test/cpp/util/tls_test_utils.cc deps: - gtest @@ -17646,6 +17648,7 @@ targets: - test/cpp/end2end/test_service_impl.h - test/cpp/end2end/xds/xds_end2end_test_lib.h - test/cpp/end2end/xds/xds_server.h + - test/cpp/end2end/xds/xds_utils.h - test/cpp/util/tls_test_utils.h src: - src/proto/grpc/testing/duplicate/echo_duplicate.proto @@ -17685,6 +17688,7 @@ targets: - test/cpp/end2end/xds/xds_cluster_type_end2end_test.cc - test/cpp/end2end/xds/xds_end2end_test_lib.cc - test/cpp/end2end/xds/xds_server.cc + - test/cpp/end2end/xds/xds_utils.cc - test/cpp/util/tls_test_utils.cc deps: - gtest @@ -17737,6 +17741,7 @@ targets: - test/cpp/end2end/test_service_impl.h - test/cpp/end2end/xds/xds_end2end_test_lib.h - test/cpp/end2end/xds/xds_server.h + - test/cpp/end2end/xds/xds_utils.h - test/cpp/util/tls_test_utils.h src: - src/proto/grpc/testing/duplicate/echo_duplicate.proto @@ -17774,6 +17779,7 @@ targets: - test/cpp/end2end/xds/xds_core_end2end_test.cc - test/cpp/end2end/xds/xds_end2end_test_lib.cc - test/cpp/end2end/xds/xds_server.cc + - test/cpp/end2end/xds/xds_utils.cc - test/cpp/util/tls_test_utils.cc deps: - gtest @@ -17840,6 +17846,7 @@ targets: - test/cpp/end2end/test_service_impl.h - test/cpp/end2end/xds/xds_end2end_test_lib.h - test/cpp/end2end/xds/xds_server.h + - test/cpp/end2end/xds/xds_utils.h - test/cpp/util/tls_test_utils.h src: - src/proto/grpc/testing/duplicate/echo_duplicate.proto @@ -17880,6 +17887,7 @@ targets: - test/cpp/end2end/xds/xds_csds_end2end_test.cc - test/cpp/end2end/xds/xds_end2end_test_lib.cc - test/cpp/end2end/xds/xds_server.cc + - test/cpp/end2end/xds/xds_utils.cc - test/cpp/util/tls_test_utils.cc deps: - gtest @@ -17900,6 +17908,7 @@ targets: - test/cpp/end2end/test_service_impl.h - test/cpp/end2end/xds/xds_end2end_test_lib.h - test/cpp/end2end/xds/xds_server.h + - test/cpp/end2end/xds/xds_utils.h - test/cpp/util/tls_test_utils.h src: - src/proto/grpc/testing/duplicate/echo_duplicate.proto @@ -17943,6 +17952,7 @@ targets: - test/cpp/end2end/xds/xds_end2end_test.cc - test/cpp/end2end/xds/xds_end2end_test_lib.cc - test/cpp/end2end/xds/xds_server.cc + - test/cpp/end2end/xds/xds_utils.cc - test/cpp/util/tls_test_utils.cc deps: - gtest @@ -17981,6 +17991,7 @@ targets: - test/cpp/end2end/test_service_impl.h - test/cpp/end2end/xds/xds_end2end_test_lib.h - test/cpp/end2end/xds/xds_server.h + - test/cpp/end2end/xds/xds_utils.h - test/cpp/util/tls_test_utils.h src: - src/proto/grpc/testing/duplicate/echo_duplicate.proto @@ -18020,6 +18031,7 @@ targets: - test/cpp/end2end/xds/xds_end2end_test_lib.cc - test/cpp/end2end/xds/xds_fault_injection_end2end_test.cc - test/cpp/end2end/xds/xds_server.cc + - test/cpp/end2end/xds/xds_utils.cc - test/cpp/util/tls_test_utils.cc deps: - gtest @@ -18259,6 +18271,7 @@ targets: - test/cpp/end2end/test_service_impl.h - test/cpp/end2end/xds/xds_end2end_test_lib.h - test/cpp/end2end/xds/xds_server.h + - test/cpp/end2end/xds/xds_utils.h - test/cpp/util/tls_test_utils.h src: - src/proto/grpc/testing/duplicate/echo_duplicate.proto @@ -18298,6 +18311,7 @@ targets: - test/cpp/end2end/xds/xds_end2end_test_lib.cc - test/cpp/end2end/xds/xds_outlier_detection_end2end_test.cc - test/cpp/end2end/xds/xds_server.cc + - test/cpp/end2end/xds/xds_utils.cc - test/cpp/util/tls_test_utils.cc deps: - gtest @@ -18316,6 +18330,7 @@ targets: - test/cpp/end2end/test_service_impl.h - test/cpp/end2end/xds/xds_end2end_test_lib.h - test/cpp/end2end/xds/xds_server.h + - test/cpp/end2end/xds/xds_utils.h - test/cpp/util/tls_test_utils.h src: - src/proto/grpc/testing/duplicate/echo_duplicate.proto @@ -18356,6 +18371,7 @@ targets: - test/cpp/end2end/xds/xds_end2end_test_lib.cc - test/cpp/end2end/xds/xds_override_host_end2end_test.cc - test/cpp/end2end/xds/xds_server.cc + - test/cpp/end2end/xds/xds_utils.cc - test/cpp/util/tls_test_utils.cc deps: - gtest @@ -18404,6 +18420,7 @@ targets: - test/cpp/end2end/test_service_impl.h - test/cpp/end2end/xds/xds_end2end_test_lib.h - test/cpp/end2end/xds/xds_server.h + - test/cpp/end2end/xds/xds_utils.h - test/cpp/util/tls_test_utils.h src: - src/proto/grpc/testing/duplicate/echo_duplicate.proto @@ -18444,6 +18461,7 @@ targets: - test/cpp/end2end/xds/xds_end2end_test_lib.cc - test/cpp/end2end/xds/xds_pick_first_end2end_test.cc - test/cpp/end2end/xds/xds_server.cc + - test/cpp/end2end/xds/xds_utils.cc - test/cpp/util/tls_test_utils.cc deps: - gtest @@ -18463,6 +18481,7 @@ targets: - test/cpp/end2end/test_service_impl.h - test/cpp/end2end/xds/xds_end2end_test_lib.h - test/cpp/end2end/xds/xds_server.h + - test/cpp/end2end/xds/xds_utils.h - test/cpp/util/tls_test_utils.h src: - src/proto/grpc/testing/duplicate/echo_duplicate.proto @@ -18502,6 +18521,7 @@ targets: - test/cpp/end2end/xds/xds_end2end_test_lib.cc - test/cpp/end2end/xds/xds_ring_hash_end2end_test.cc - test/cpp/end2end/xds/xds_server.cc + - test/cpp/end2end/xds/xds_utils.cc - test/cpp/util/tls_test_utils.cc deps: - gtest @@ -18521,6 +18541,7 @@ targets: - test/cpp/end2end/test_service_impl.h - test/cpp/end2end/xds/xds_end2end_test_lib.h - test/cpp/end2end/xds/xds_server.h + - test/cpp/end2end/xds/xds_utils.h - test/cpp/util/tls_test_utils.h src: - src/proto/grpc/lookup/v1/rls.proto @@ -18561,6 +18582,7 @@ targets: - test/cpp/end2end/xds/xds_end2end_test_lib.cc - test/cpp/end2end/xds/xds_rls_end2end_test.cc - test/cpp/end2end/xds/xds_server.cc + - test/cpp/end2end/xds/xds_utils.cc - test/cpp/util/tls_test_utils.cc deps: - gtest @@ -18622,6 +18644,7 @@ targets: - test/cpp/end2end/test_service_impl.h - test/cpp/end2end/xds/xds_end2end_test_lib.h - test/cpp/end2end/xds/xds_server.h + - test/cpp/end2end/xds/xds_utils.h - test/cpp/util/tls_test_utils.h src: - src/proto/grpc/testing/duplicate/echo_duplicate.proto @@ -18661,6 +18684,7 @@ targets: - test/cpp/end2end/xds/xds_end2end_test_lib.cc - test/cpp/end2end/xds/xds_routing_end2end_test.cc - test/cpp/end2end/xds/xds_server.cc + - test/cpp/end2end/xds/xds_utils.cc - test/cpp/util/tls_test_utils.cc deps: - gtest @@ -18706,6 +18730,7 @@ targets: - test/cpp/end2end/test_service_impl.h - test/cpp/end2end/xds/xds_end2end_test_lib.h - test/cpp/end2end/xds/xds_server.h + - test/cpp/end2end/xds/xds_utils.h - test/cpp/util/tls_test_utils.h src: - src/proto/grpc/testing/duplicate/echo_duplicate.proto @@ -18744,6 +18769,7 @@ targets: - test/cpp/end2end/test_service_impl.cc - test/cpp/end2end/xds/xds_end2end_test_lib.cc - test/cpp/end2end/xds/xds_server.cc + - test/cpp/end2end/xds/xds_utils.cc - test/cpp/end2end/xds/xds_wrr_end2end_test.cc - test/cpp/util/tls_test_utils.cc deps: diff --git a/test/cpp/end2end/xds/BUILD b/test/cpp/end2end/xds/BUILD index a1feea3a974..8cc655b9f69 100644 --- a/test/cpp/end2end/xds/BUILD +++ b/test/cpp/end2end/xds/BUILD @@ -45,6 +45,24 @@ grpc_cc_library( ], ) +grpc_cc_library( + name = "xds_utils", + testonly = True, + srcs = ["xds_utils.cc"], + hdrs = ["xds_utils.h"], + deps = [ + ":xds_server", + "//src/proto/grpc/testing/xds/v3:cluster_proto", + "//src/proto/grpc/testing/xds/v3:discovery_proto", + "//src/proto/grpc/testing/xds/v3:endpoint_proto", + "//src/proto/grpc/testing/xds/v3:http_connection_manager_proto", + "//src/proto/grpc/testing/xds/v3:listener_proto", + "//src/proto/grpc/testing/xds/v3:route_proto", + "//src/proto/grpc/testing/xds/v3:router_proto", + "//test/core/util:grpc_test_util_base", + ], +) + grpc_cc_library( name = "xds_end2end_test_lib", testonly = True, @@ -55,6 +73,7 @@ grpc_cc_library( ], deps = [ ":xds_server", + ":xds_utils", "//:gpr", "//:grpc", "//:grpc++", diff --git a/test/cpp/end2end/xds/xds_cluster_end2end_test.cc b/test/cpp/end2end/xds/xds_cluster_end2end_test.cc index a658f319819..c43d8fbc2a0 100644 --- a/test/cpp/end2end/xds/xds_cluster_end2end_test.cc +++ b/test/cpp/end2end/xds/xds_cluster_end2end_test.cc @@ -343,7 +343,7 @@ TEST_P(CdsDeletionTest, ClusterDeleted) { // Tests that we ignore Cluster deletions if configured to do so. TEST_P(CdsDeletionTest, ClusterDeletionIgnored) { - InitClient(BootstrapBuilder().SetIgnoreResourceDeletion()); + InitClient(XdsBootstrapBuilder().SetIgnoreResourceDeletion()); CreateAndStartBackends(2); // Bring up client pointing to backend 0 and wait for it to connect. EdsResourceArgs args({{"locality0", CreateEndpointsForBackends(0, 1)}}); diff --git a/test/cpp/end2end/xds/xds_core_end2end_test.cc b/test/cpp/end2end/xds/xds_core_end2end_test.cc index 1142b2f0216..a6a9896752e 100644 --- a/test/cpp/end2end/xds/xds_core_end2end_test.cc +++ b/test/cpp/end2end/xds/xds_core_end2end_test.cc @@ -308,7 +308,7 @@ TEST_P(GlobalXdsClientTest, InvalidListenerStillExistsIfPreviouslyCached) { class TimeoutTest : public XdsEnd2endTest { protected: void SetUp() override { - InitClient(BootstrapBuilder(), /*lb_expected_authority=*/"", + InitClient(XdsBootstrapBuilder(), /*lb_expected_authority=*/"", /*xds_resource_does_not_exist_timeout_ms=*/2000); } }; @@ -628,7 +628,7 @@ TEST_P(XdsFederationTest, FederationTargetNoAuthorityWithResourceTemplate) { const char* kNewClusterName = "xdstp://xds.example.com/envoy.config.cluster.v3.Cluster/" "new_cluster_name"; - BootstrapBuilder builder = BootstrapBuilder(); + XdsBootstrapBuilder builder; builder.SetClientDefaultListenerResourceNameTemplate(kNewListenerTemplate); builder.AddAuthority( kAuthority, absl::StrCat("localhost:", authority_balancer_->port()), @@ -682,7 +682,7 @@ TEST_P(XdsFederationTest, FederationTargetAuthorityDefaultResourceTemplate) { const char* kNewClusterName = "xdstp://xds.example.com/envoy.config.cluster.v3.Cluster/" "cluster_name"; - BootstrapBuilder builder = BootstrapBuilder(); + XdsBootstrapBuilder builder; builder.AddAuthority(kAuthority, absl::StrCat("localhost:", authority_balancer_->port())); InitClient(builder); @@ -751,7 +751,7 @@ TEST_P(XdsFederationTest, FederationTargetAuthorityWithResourceTemplate) { const char* kNewClusterName = "xdstp://xds.example.com/envoy.config.cluster.v3.Cluster/" "cluster_name"; - BootstrapBuilder builder = BootstrapBuilder(); + XdsBootstrapBuilder builder; builder.AddAuthority(kAuthority, absl::StrCat("localhost:", authority_balancer_->port()), kNewListenerTemplate); @@ -807,7 +807,7 @@ TEST_P(XdsFederationTest, TargetUriAuthorityUnknown) { const char* kNewListenerTemplate = "xdstp://xds.example.com/envoy.config.listener.v3.Listener/" "client/%s?psm_project_id=1234"; - BootstrapBuilder builder = BootstrapBuilder(); + XdsBootstrapBuilder builder; builder.AddAuthority( kAuthority, absl::StrCat("localhost:", grpc_pick_unused_port_or_die()), kNewListenerTemplate); @@ -838,7 +838,7 @@ TEST_P(XdsFederationTest, RdsResourceNameAuthorityUnknown) { const char* kNewRouteConfigName = "xdstp://xds.unknown.com/envoy.config.route.v3.RouteConfiguration/" "new_route_config_name"; - BootstrapBuilder builder = BootstrapBuilder(); + XdsBootstrapBuilder builder; builder.AddAuthority(kAuthority, absl::StrCat("localhost:", authority_balancer_->port()), kNewListenerTemplate); @@ -884,7 +884,7 @@ TEST_P(XdsFederationTest, CdsResourceNameAuthorityUnknown) { const char* kNewClusterName = "xdstp://xds.unknown.com/envoy.config.cluster.v3.Cluster/" "cluster_name"; - BootstrapBuilder builder = BootstrapBuilder(); + XdsBootstrapBuilder builder; builder.AddAuthority(kAuthority, absl::StrCat("localhost:", authority_balancer_->port()), kNewListenerTemplate); @@ -937,7 +937,7 @@ TEST_P(XdsFederationTest, EdsResourceNameAuthorityUnknown) { const char* kNewClusterName = "xdstp://xds.example.com/envoy.config.cluster.v3.Cluster/" "cluster_name"; - BootstrapBuilder builder = BootstrapBuilder(); + XdsBootstrapBuilder builder; builder.AddAuthority(kAuthority, absl::StrCat("localhost:", authority_balancer_->port()), kNewListenerTemplate); @@ -1004,7 +1004,7 @@ TEST_P(XdsFederationTest, FederationServer) { const char* kNewClusterName = "xdstp://xds.example.com/envoy.config.cluster.v3.Cluster/" "new_cluster_name"; - BootstrapBuilder builder = BootstrapBuilder(); + XdsBootstrapBuilder builder; builder.SetClientDefaultListenerResourceNameTemplate(kNewListenerTemplate); builder.SetServerListenerResourceNameTemplate(kNewServerListenerTemplate); builder.AddAuthority( @@ -1150,7 +1150,7 @@ TEST_P(XdsFederationLoadReportingTest, FederationMultipleLoadReportingTest) { "cluster_name"; const size_t kNumRpcsToDefaultBalancer = 5; const size_t kNumRpcsToAuthorityBalancer = 10; - BootstrapBuilder builder = BootstrapBuilder(); + XdsBootstrapBuilder builder; builder.AddAuthority(kAuthority, absl::StrCat("localhost:", authority_balancer_->port()), kNewListenerTemplate); @@ -1261,7 +1261,7 @@ TEST_P(XdsFederationLoadReportingTest, SameServerInAuthorityAndTopLevel) { const char* kNewEdsServiceName = "xdstp://xds.example.com/envoy.config.endpoint.v3.ClusterLoadAssignment/" "edsservice_name"; - BootstrapBuilder builder = BootstrapBuilder(); + XdsBootstrapBuilder builder; std::string xds_server = absl::StrCat("localhost:", authority_balancer_->port()); builder.AddAuthority(kAuthority, xds_server); @@ -1334,7 +1334,7 @@ INSTANTIATE_TEST_SUITE_P(XdsTest, SecureNamingTest, // Tests that secure naming check passes if target name is expected. TEST_P(SecureNamingTest, TargetNameIsExpected) { - InitClient(BootstrapBuilder(), /*lb_expected_authority=*/"localhost:%d"); + InitClient(XdsBootstrapBuilder(), /*lb_expected_authority=*/"localhost:%d"); CreateAndStartBackends(4); EdsResourceArgs args({ {"locality0", CreateEndpointsForBackends()}, @@ -1346,7 +1346,7 @@ TEST_P(SecureNamingTest, TargetNameIsExpected) { // Tests that secure naming check fails if target name is unexpected. TEST_P(SecureNamingTest, TargetNameIsUnexpected) { GTEST_FLAG_SET(death_test_style, "threadsafe"); - InitClient(BootstrapBuilder(), + InitClient(XdsBootstrapBuilder(), /*lb_expected_authority=*/"incorrect_server_name"); CreateAndStartBackends(4); EdsResourceArgs args({ diff --git a/test/cpp/end2end/xds/xds_csds_end2end_test.cc b/test/cpp/end2end/xds/xds_csds_end2end_test.cc index c616dfcc4d1..c99bf4bfcac 100644 --- a/test/cpp/end2end/xds/xds_csds_end2end_test.cc +++ b/test/cpp/end2end/xds/xds_csds_end2end_test.cc @@ -619,7 +619,7 @@ class CsdsShortAdsTimeoutTest : public ClientStatusDiscoveryServiceTest { protected: void SetUp() override { // Shorten the ADS subscription timeout to speed up the test run. - InitClient(BootstrapBuilder(), /*lb_expected_authority=*/"", + InitClient(XdsBootstrapBuilder(), /*lb_expected_authority=*/"", /*xds_resource_does_not_exist_timeout_ms=*/2000); } }; diff --git a/test/cpp/end2end/xds/xds_end2end_test.cc b/test/cpp/end2end/xds/xds_end2end_test.cc index 9eb8380fcfa..f4e6e1cdbf8 100644 --- a/test/cpp/end2end/xds/xds_end2end_test.cc +++ b/test/cpp/end2end/xds/xds_end2end_test.cc @@ -282,7 +282,7 @@ FakeCertificateProvider::CertDataMapWrapper* g_fake2_cert_data_map = nullptr; class XdsSecurityTest : public XdsEnd2endTest { protected: void SetUp() override { - BootstrapBuilder builder = BootstrapBuilder(); + XdsBootstrapBuilder builder; builder.AddCertificateProviderPlugin("fake_plugin1", "fake1"); builder.AddCertificateProviderPlugin("fake_plugin2", "fake2"); std::vector fields; @@ -734,7 +734,7 @@ class XdsEnabledServerTest : public XdsEnd2endTest { protected: void SetUp() override {} // No-op -- individual tests do this themselves. - void DoSetUp(BootstrapBuilder builder = BootstrapBuilder()) { + void DoSetUp(XdsBootstrapBuilder builder = XdsBootstrapBuilder()) { InitClient(builder); CreateBackends(1, /*xds_enabled=*/true); EdsResourceArgs args({{"locality0", CreateEndpointsForBackends(0, 1)}}); @@ -749,7 +749,7 @@ TEST_P(XdsEnabledServerTest, Basic) { } TEST_P(XdsEnabledServerTest, ListenerDeletionIgnored) { - DoSetUp(BootstrapBuilder().SetIgnoreResourceDeletion()); + DoSetUp(XdsBootstrapBuilder().SetIgnoreResourceDeletion()); backends_[0]->Start(); WaitForBackend(DEBUG_LOCATION, 0); // Check that we ACKed. @@ -843,7 +843,7 @@ TEST_P(XdsEnabledServerTest, ListenerAddressMismatch) { class XdsServerSecurityTest : public XdsEnd2endTest { protected: void SetUp() override { - BootstrapBuilder builder = BootstrapBuilder(); + XdsBootstrapBuilder builder; builder.AddCertificateProviderPlugin("fake_plugin1", "fake1"); builder.AddCertificateProviderPlugin("fake_plugin2", "fake2"); std::vector fields; diff --git a/test/cpp/end2end/xds/xds_end2end_test_lib.cc b/test/cpp/end2end/xds/xds_end2end_test_lib.cc index b24a813c566..b2c893b93a6 100644 --- a/test/cpp/end2end/xds/xds_end2end_test_lib.cc +++ b/test/cpp/end2end/xds/xds_end2end_test_lib.cc @@ -52,10 +52,6 @@ namespace grpc { namespace testing { using ::envoy::config::core::v3::HealthStatus; -using ::envoy::config::endpoint::v3::ClusterLoadAssignment; -using ::envoy::config::listener::v3::Listener; -using ::envoy::extensions::filters::network::http_connection_manager::v3:: - HttpConnectionManager; using ::grpc::experimental::ExternalCertificateVerifier; using ::grpc::experimental::IdentityKeyCertPair; @@ -300,112 +296,6 @@ void XdsEnd2endTest::BalancerServerThread::ShutdownAllServices() { lrs_service_->Shutdown(); } -// -// XdsEnd2endTest::BootstrapBuilder -// - -std::string XdsEnd2endTest::BootstrapBuilder::Build() { - std::vector fields; - fields.push_back(MakeXdsServersText(top_server_)); - if (!client_default_listener_resource_name_template_.empty()) { - fields.push_back( - absl::StrCat(" \"client_default_listener_resource_name_template\": \"", - client_default_listener_resource_name_template_, "\"")); - } - fields.push_back(MakeNodeText()); - if (!server_listener_resource_name_template_.empty()) { - fields.push_back( - absl::StrCat(" \"server_listener_resource_name_template\": \"", - server_listener_resource_name_template_, "\"")); - } - fields.push_back(MakeCertificateProviderText()); - fields.push_back(MakeAuthorityText()); - return absl::StrCat("{", absl::StrJoin(fields, ",\n"), "}"); -} - -std::string XdsEnd2endTest::BootstrapBuilder::MakeXdsServersText( - absl::string_view server_uri) { - constexpr char kXdsServerTemplate[] = - " \"xds_servers\": [\n" - " {\n" - " \"server_uri\": \"\",\n" - " \"channel_creds\": [\n" - " {\n" - " \"type\": \"fake\"\n" - " }\n" - " ],\n" - " \"server_features\": []\n" - " }\n" - " ]"; - std::vector server_features; - if (ignore_resource_deletion_) { - server_features.push_back("\"ignore_resource_deletion\""); - } - return absl::StrReplaceAll( - kXdsServerTemplate, - {{"", server_uri}, - {"", absl::StrJoin(server_features, ", ")}}); -} - -std::string XdsEnd2endTest::BootstrapBuilder::MakeNodeText() { - constexpr char kXdsNode[] = - " \"node\": {\n" - " \"id\": \"xds_end2end_test\",\n" - " \"cluster\": \"test\",\n" - " \"metadata\": {\n" - " \"foo\": \"bar\"\n" - " },\n" - " \"locality\": {\n" - " \"region\": \"corp\",\n" - " \"zone\": \"svl\",\n" - " \"sub_zone\": \"mp3\"\n" - " }\n" - " }"; - return kXdsNode; -} - -std::string XdsEnd2endTest::BootstrapBuilder::MakeCertificateProviderText() { - std::vector entries; - for (const auto& p : plugins_) { - const std::string& key = p.first; - const PluginInfo& plugin_info = p.second; - std::vector fields; - fields.push_back(absl::StrFormat(" \"%s\": {", key)); - if (!plugin_info.plugin_config.empty()) { - fields.push_back( - absl::StrFormat(" \"plugin_name\": \"%s\",", plugin_info.name)); - fields.push_back(absl::StrCat(" \"config\": {\n", - plugin_info.plugin_config, "\n }")); - } else { - fields.push_back( - absl::StrFormat(" \"plugin_name\": \"%s\"", plugin_info.name)); - } - fields.push_back(" }"); - entries.push_back(absl::StrJoin(fields, "\n")); - } - return absl::StrCat(" \"certificate_providers\": {\n", - absl::StrJoin(entries, ",\n"), " \n}"); -} - -std::string XdsEnd2endTest::BootstrapBuilder::MakeAuthorityText() { - std::vector entries; - for (const auto& p : authorities_) { - const std::string& name = p.first; - const AuthorityInfo& authority_info = p.second; - std::vector fields = { - MakeXdsServersText(authority_info.server)}; - if (!authority_info.client_listener_resource_name_template.empty()) { - fields.push_back(absl::StrCat( - "\"client_listener_resource_name_template\": \"", - authority_info.client_listener_resource_name_template, "\"")); - } - entries.push_back(absl::StrCat(absl::StrFormat("\"%s\": {\n ", name), - absl::StrJoin(fields, ",\n"), "\n}")); - } - return absl::StrCat("\"authorities\": {\n", absl::StrJoin(entries, ",\n"), - "\n}"); -} - // // XdsEnd2endTest::RpcOptions // @@ -443,18 +333,6 @@ void XdsEnd2endTest::RpcOptions::SetupRpc(ClientContext* context, // XdsEnd2endTest // -const char XdsEnd2endTest::kDefaultLocalityRegion[] = - "xds_default_locality_region"; -const char XdsEnd2endTest::kDefaultLocalityZone[] = "xds_default_locality_zone"; - -const char XdsEnd2endTest::kServerName[] = "server.example.com"; -const char XdsEnd2endTest::kDefaultRouteConfigurationName[] = - "route_config_name"; -const char XdsEnd2endTest::kDefaultClusterName[] = "cluster_name"; -const char XdsEnd2endTest::kDefaultEdsServiceName[] = "eds_service_name"; -const char XdsEnd2endTest::kDefaultServerRouteConfigurationName[] = - "default_server_route_config_name"; - const char XdsEnd2endTest::kCaCertPath[] = "src/core/tsi/test_creds/ca.pem"; const char XdsEnd2endTest::kServerCertPath[] = "src/core/tsi/test_creds/server1.pem"; @@ -464,30 +342,10 @@ const char XdsEnd2endTest::kServerKeyPath[] = const char XdsEnd2endTest::kRequestMessage[] = "Live long and prosper."; XdsEnd2endTest::XdsEnd2endTest() : balancer_(CreateAndStartBalancer()) { - // Initialize default xDS resources. - // Construct LDS resource. - default_listener_.set_name(kServerName); - HttpConnectionManager http_connection_manager; - auto* filter = http_connection_manager.add_http_filters(); - filter->set_name("router"); - filter->mutable_typed_config()->PackFrom( - envoy::extensions::filters::http::router::v3::Router()); - default_listener_.mutable_api_listener()->mutable_api_listener()->PackFrom( - http_connection_manager); - // Construct RDS resource. - default_route_config_.set_name(kDefaultRouteConfigurationName); - auto* virtual_host = default_route_config_.add_virtual_hosts(); - virtual_host->add_domains("*"); - auto* route = virtual_host->add_routes(); - route->mutable_match()->set_prefix(""); - route->mutable_route()->set_cluster(kDefaultClusterName); - // Construct CDS resource. - default_cluster_.set_name(kDefaultClusterName); - default_cluster_.set_type(Cluster::EDS); - auto* eds_config = default_cluster_.mutable_eds_cluster_config(); - eds_config->mutable_eds_config()->mutable_self(); - eds_config->set_service_name(kDefaultEdsServiceName); - default_cluster_.set_lb_policy(Cluster::ROUND_ROBIN); + // Initialize default client-side xDS resources. + default_listener_ = XdsResourceUtils::DefaultListener(); + default_route_config_ = XdsResourceUtils::DefaultRouteConfig(); + default_cluster_ = XdsResourceUtils::DefaultCluster(); if (GetParam().enable_load_reporting()) { default_cluster_.mutable_lrs_server()->mutable_self(); } @@ -495,21 +353,9 @@ XdsEnd2endTest::XdsEnd2endTest() : balancer_(CreateAndStartBalancer()) { SetListenerAndRouteConfiguration(balancer_.get(), default_listener_, default_route_config_); balancer_->ads_service()->SetCdsResource(default_cluster_); - // Construct a default server-side RDS resource for tests to use. - default_server_route_config_.set_name(kDefaultServerRouteConfigurationName); - virtual_host = default_server_route_config_.add_virtual_hosts(); - virtual_host->add_domains("*"); - route = virtual_host->add_routes(); - route->mutable_match()->set_prefix(""); - route->mutable_non_forwarding_action(); - // Construct a default server-side Listener resource - default_server_listener_.mutable_address() - ->mutable_socket_address() - ->set_address(grpc_core::LocalIp()); - default_server_listener_.mutable_default_filter_chain() - ->add_filters() - ->mutable_typed_config() - ->PackFrom(http_connection_manager); + // Initialize default server-side xDS resources. + default_server_route_config_ = XdsResourceUtils::DefaultServerRouteConfig(); + default_server_listener_ = XdsResourceUtils::DefaultServerListener(); } void XdsEnd2endTest::TearDown() { @@ -534,83 +380,6 @@ XdsEnd2endTest::CreateAndStartBalancer() { return balancer; } -std::string XdsEnd2endTest::GetServerListenerName(int port) { - return absl::StrCat("grpc/server?xds.resource.listening_address=", - grpc_core::LocalIp(), ":", port); -} - -Listener XdsEnd2endTest::PopulateServerListenerNameAndPort( - const Listener& listener_template, int port) { - Listener listener = listener_template; - listener.set_name(GetServerListenerName(port)); - listener.mutable_address()->mutable_socket_address()->set_port_value(port); - return listener; -} - -HttpConnectionManager XdsEnd2endTest::ClientHcmAccessor::Unpack( - const Listener& listener) const { - HttpConnectionManager http_connection_manager; - listener.api_listener().api_listener().UnpackTo(&http_connection_manager); - return http_connection_manager; -} - -void XdsEnd2endTest::ClientHcmAccessor::Pack(const HttpConnectionManager& hcm, - Listener* listener) const { - auto* api_listener = listener->mutable_api_listener()->mutable_api_listener(); - api_listener->PackFrom(hcm); -} - -HttpConnectionManager XdsEnd2endTest::ServerHcmAccessor::Unpack( - const Listener& listener) const { - HttpConnectionManager http_connection_manager; - listener.default_filter_chain().filters().at(0).typed_config().UnpackTo( - &http_connection_manager); - return http_connection_manager; -} - -void XdsEnd2endTest::ServerHcmAccessor::Pack(const HttpConnectionManager& hcm, - Listener* listener) const { - listener->mutable_default_filter_chain() - ->mutable_filters() - ->at(0) - .mutable_typed_config() - ->PackFrom(hcm); -} - -void XdsEnd2endTest::SetListenerAndRouteConfiguration( - BalancerServerThread* balancer, Listener listener, - const RouteConfiguration& route_config, const HcmAccessor& hcm_accessor) { - HttpConnectionManager http_connection_manager = hcm_accessor.Unpack(listener); - if (GetParam().enable_rds_testing()) { - auto* rds = http_connection_manager.mutable_rds(); - rds->set_route_config_name(route_config.name()); - rds->mutable_config_source()->mutable_self(); - balancer->ads_service()->SetRdsResource(route_config); - } else { - *http_connection_manager.mutable_route_config() = route_config; - } - hcm_accessor.Pack(http_connection_manager, &listener); - balancer->ads_service()->SetLdsResource(listener); -} - -void XdsEnd2endTest::SetRouteConfiguration( - BalancerServerThread* balancer, const RouteConfiguration& route_config, - const Listener* listener_to_copy) { - if (GetParam().enable_rds_testing()) { - balancer->ads_service()->SetRdsResource(route_config); - } else { - Listener listener(listener_to_copy == nullptr ? default_listener_ - : *listener_to_copy); - HttpConnectionManager http_connection_manager; - listener.mutable_api_listener()->mutable_api_listener()->UnpackTo( - &http_connection_manager); - *(http_connection_manager.mutable_route_config()) = route_config; - listener.mutable_api_listener()->mutable_api_listener()->PackFrom( - http_connection_manager); - balancer->ads_service()->SetLdsResource(listener); - } -} - std::vector XdsEnd2endTest::CreateEndpointsForBackends(size_t start_index, size_t stop_index, @@ -624,57 +393,6 @@ XdsEnd2endTest::CreateEndpointsForBackends(size_t start_index, return endpoints; } -ClusterLoadAssignment XdsEnd2endTest::BuildEdsResource( - const EdsResourceArgs& args, absl::string_view eds_service_name) { - ClusterLoadAssignment assignment; - assignment.set_cluster_name(eds_service_name); - for (const auto& locality : args.locality_list) { - auto* endpoints = assignment.add_endpoints(); - endpoints->mutable_load_balancing_weight()->set_value(locality.lb_weight); - endpoints->set_priority(locality.priority); - endpoints->mutable_locality()->set_region(kDefaultLocalityRegion); - endpoints->mutable_locality()->set_zone(kDefaultLocalityZone); - endpoints->mutable_locality()->set_sub_zone(locality.sub_zone); - for (size_t i = 0; i < locality.endpoints.size(); ++i) { - const auto& endpoint = locality.endpoints[i]; - auto* lb_endpoints = endpoints->add_lb_endpoints(); - if (locality.endpoints.size() > i && - locality.endpoints[i].health_status != HealthStatus::UNKNOWN) { - lb_endpoints->set_health_status(endpoint.health_status); - } - if (locality.endpoints.size() > i && endpoint.lb_weight >= 1) { - lb_endpoints->mutable_load_balancing_weight()->set_value( - endpoint.lb_weight); - } - auto* endpoint_proto = lb_endpoints->mutable_endpoint(); - auto* socket_address = - endpoint_proto->mutable_address()->mutable_socket_address(); - socket_address->set_address(grpc_core::LocalIp()); - socket_address->set_port_value(endpoint.port); - for (int port : endpoint.additional_ports) { - socket_address = endpoint_proto->add_additional_addresses() - ->mutable_address() - ->mutable_socket_address(); - socket_address->set_address(grpc_core::LocalIp()); - socket_address->set_port_value(port); - } - } - } - if (!args.drop_categories.empty()) { - auto* policy = assignment.mutable_policy(); - for (const auto& p : args.drop_categories) { - const std::string& name = p.first; - const uint32_t parts_per_million = p.second; - auto* drop_overload = policy->add_drop_overloads(); - drop_overload->set_category(name); - auto* drop_percentage = drop_overload->mutable_drop_percentage(); - drop_percentage->set_numerator(parts_per_million); - drop_percentage->set_denominator(args.drop_denominator); - } - } - return assignment; -} - void XdsEnd2endTest::ResetBackendCounters(size_t start_index, size_t stop_index) { if (stop_index == 0) stop_index = backends_.size(); @@ -728,7 +446,7 @@ std::vector XdsEnd2endTest::GetBackendPorts(size_t start_index, return backend_ports; } -void XdsEnd2endTest::InitClient(BootstrapBuilder builder, +void XdsEnd2endTest::InitClient(XdsBootstrapBuilder builder, std::string lb_expected_authority, int xds_resource_does_not_exist_timeout_ms) { if (xds_resource_does_not_exist_timeout_ms > 0) { diff --git a/test/cpp/end2end/xds/xds_end2end_test_lib.h b/test/cpp/end2end/xds/xds_end2end_test_lib.h index 34dec7d8821..fb83b901803 100644 --- a/test/cpp/end2end/xds/xds_end2end_test_lib.h +++ b/test/cpp/end2end/xds/xds_end2end_test_lib.h @@ -50,6 +50,7 @@ #include "test/cpp/end2end/counted_service.h" #include "test/cpp/end2end/test_service_impl.h" #include "test/cpp/end2end/xds/xds_server.h" +#include "test/cpp/end2end/xds/xds_utils.h" namespace grpc { namespace testing { @@ -201,29 +202,9 @@ class XdsTestType { // the indexes in the range [start_index, stop_index). If stop_index // is 0, backends_.size() is used. Backends may or may not be // xDS-enabled, at the discretion of the test. -class XdsEnd2endTest : public ::testing::TestWithParam { +class XdsEnd2endTest : public ::testing::TestWithParam, + public XdsResourceUtils { protected: - using Cluster = ::envoy::config::cluster::v3::Cluster; - using ClusterLoadAssignment = - ::envoy::config::endpoint::v3::ClusterLoadAssignment; - using Listener = ::envoy::config::listener::v3::Listener; - using RouteConfiguration = ::envoy::config::route::v3::RouteConfiguration; - using HttpConnectionManager = ::envoy::extensions::filters::network:: - http_connection_manager::v3::HttpConnectionManager; - - // Default values for locality fields. - static const char kDefaultLocalityRegion[]; - static const char kDefaultLocalityZone[]; - static const uint32_t kDefaultLocalityWeight = 3; - static const int kDefaultLocalityPriority = 0; - - // Default resource names. - static const char kServerName[]; - static const char kDefaultRouteConfigurationName[]; - static const char kDefaultClusterName[]; - static const char kDefaultEdsServiceName[]; - static const char kDefaultServerRouteConfigurationName[]; - // TLS certificate paths. static const char kCaCertPath[]; static const char kServerCertPath[]; @@ -430,73 +411,6 @@ class XdsEnd2endTest : public ::testing::TestWithParam { std::shared_ptr lrs_service_; }; - // A builder for the xDS bootstrap config. - class BootstrapBuilder { - public: - BootstrapBuilder() {} - BootstrapBuilder& SetIgnoreResourceDeletion() { - ignore_resource_deletion_ = true; - return *this; - } - // If ignore_if_set is true, sets the default server only if it has - // not already been set. - BootstrapBuilder& SetDefaultServer(const std::string& server, - bool ignore_if_set = false) { - if (!ignore_if_set || top_server_.empty()) top_server_ = server; - return *this; - } - BootstrapBuilder& SetClientDefaultListenerResourceNameTemplate( - const std::string& client_default_listener_resource_name_template) { - client_default_listener_resource_name_template_ = - client_default_listener_resource_name_template; - return *this; - } - BootstrapBuilder& AddCertificateProviderPlugin( - const std::string& key, const std::string& name, - const std::string& plugin_config = "") { - plugins_[key] = {name, plugin_config}; - return *this; - } - BootstrapBuilder& AddAuthority( - const std::string& authority, const std::string& server = "", - const std::string& client_listener_resource_name_template = "") { - authorities_[authority] = {server, - client_listener_resource_name_template}; - return *this; - } - BootstrapBuilder& SetServerListenerResourceNameTemplate( - const std::string& server_listener_resource_name_template = "") { - server_listener_resource_name_template_ = - server_listener_resource_name_template; - return *this; - } - - std::string Build(); - - private: - struct PluginInfo { - std::string name; - std::string plugin_config; - }; - struct AuthorityInfo { - std::string server; - std::string client_listener_resource_name_template; - }; - - std::string MakeXdsServersText(absl::string_view server_uri); - std::string MakeNodeText(); - std::string MakeCertificateProviderText(); - std::string MakeAuthorityText(); - - bool ignore_resource_deletion_ = false; - std::string top_server_; - std::string client_default_listener_resource_name_template_; - std::map plugins_; - std::map authorities_; - std::string server_listener_resource_name_template_ = - "grpc/server?xds.resource.listening_address=%s"; - }; - // RPC services used to talk to the backends. enum RpcService { SERVICE_ECHO, @@ -525,47 +439,17 @@ class XdsEnd2endTest : public ::testing::TestWithParam { // balancer_, which is already populated with default resources. std::unique_ptr CreateAndStartBalancer(); - // Returns the name of the server-side xDS Listener resource for a - // backend on the specified port. - std::string GetServerListenerName(int port); - - // Returns a copy of listener_template with the server-side resource - // name and the port in the socket address populated. - Listener PopulateServerListenerNameAndPort(const Listener& listener_template, - int port); - - // Interface for accessing HttpConnectionManager config in Listener. - class HcmAccessor { - public: - virtual ~HcmAccessor() = default; - virtual HttpConnectionManager Unpack(const Listener& listener) const = 0; - virtual void Pack(const HttpConnectionManager& hcm, - Listener* listener) const = 0; - }; - - // Client-side impl. - class ClientHcmAccessor : public HcmAccessor { - public: - HttpConnectionManager Unpack(const Listener& listener) const override; - void Pack(const HttpConnectionManager& hcm, - Listener* listener) const override; - }; - - // Server-side impl. - class ServerHcmAccessor : public HcmAccessor { - public: - HttpConnectionManager Unpack(const Listener& listener) const override; - void Pack(const HttpConnectionManager& hcm, - Listener* listener) const override; - }; - // Sets the Listener and RouteConfiguration resource on the specified // balancer. If RDS is in use, they will be set as separate resources; // otherwise, the RouteConfig will be inlined into the Listener. void SetListenerAndRouteConfiguration( BalancerServerThread* balancer, Listener listener, const RouteConfiguration& route_config, - const HcmAccessor& hcm_accessor = ClientHcmAccessor()); + const HcmAccessor& hcm_accessor = ClientHcmAccessor()) { + XdsResourceUtils::SetListenerAndRouteConfiguration( + balancer->ads_service(), std::move(listener), route_config, + GetParam().enable_rds_testing(), hcm_accessor); + } // A convenient wrapper for setting the Listener and // RouteConfiguration resources on the server side. @@ -583,53 +467,11 @@ class XdsEnd2endTest : public ::testing::TestWithParam { // (either listener_to_copy, or if that is null, default_listener_). void SetRouteConfiguration(BalancerServerThread* balancer, const RouteConfiguration& route_config, - const Listener* listener_to_copy = nullptr); - - // Arguments for constructing an EDS resource. - struct EdsResourceArgs { - // An individual endpoint for a backend running on a specified port. - struct Endpoint { - explicit Endpoint(int port, - ::envoy::config::core::v3::HealthStatus health_status = - ::envoy::config::core::v3::HealthStatus::UNKNOWN, - int lb_weight = 1, - std::vector additional_ports = {}) - : port(port), - health_status(health_status), - lb_weight(lb_weight), - additional_ports(std::move(additional_ports)) {} - - int port; - ::envoy::config::core::v3::HealthStatus health_status; - int lb_weight; - std::vector additional_ports; - }; - - // A locality. - struct Locality { - Locality(std::string sub_zone, std::vector endpoints, - uint32_t lb_weight = kDefaultLocalityWeight, - int priority = kDefaultLocalityPriority) - : sub_zone(std::move(sub_zone)), - endpoints(std::move(endpoints)), - lb_weight(lb_weight), - priority(priority) {} - - const std::string sub_zone; - std::vector endpoints; - uint32_t lb_weight; - int priority; - }; - - EdsResourceArgs() = default; - explicit EdsResourceArgs(std::vector locality_list) - : locality_list(std::move(locality_list)) {} - - std::vector locality_list; - std::map drop_categories; - ::envoy::type::v3::FractionalPercent::DenominatorType drop_denominator = - ::envoy::type::v3::FractionalPercent::MILLION; - }; + const Listener* listener_to_copy = nullptr) { + XdsResourceUtils::SetRouteConfiguration( + balancer->ads_service(), route_config, GetParam().enable_rds_testing(), + listener_to_copy); + } // Helper method for generating an endpoint for a backend, for use in // constructing an EDS resource. @@ -662,11 +504,6 @@ class XdsEnd2endTest : public ::testing::TestWithParam { return EdsResourceArgs::Endpoint(grpc_pick_unused_port_or_die()); } - // Constructs an EDS resource. - ClusterLoadAssignment BuildEdsResource( - const EdsResourceArgs& args, - absl::string_view eds_service_name = kDefaultEdsServiceName); - // // Backend management // @@ -727,7 +564,7 @@ class XdsEnd2endTest : public ::testing::TestWithParam { // Initializes global state for the client, such as the bootstrap file // and channel args for the XdsClient. Then calls ResetStub(). // All tests must call this exactly once at the start of the test. - void InitClient(BootstrapBuilder builder = BootstrapBuilder(), + void InitClient(XdsBootstrapBuilder builder = XdsBootstrapBuilder(), std::string lb_expected_authority = "", int xds_resource_does_not_exist_timeout_ms = 0); diff --git a/test/cpp/end2end/xds/xds_routing_end2end_test.cc b/test/cpp/end2end/xds/xds_routing_end2end_test.cc index a4012732404..bb42c8cbcd7 100644 --- a/test/cpp/end2end/xds/xds_routing_end2end_test.cc +++ b/test/cpp/end2end/xds/xds_routing_end2end_test.cc @@ -115,7 +115,7 @@ TEST_P(LdsDeletionTest, ListenerDeleted) { // Tests that we ignore Listener deletions if configured to do so. TEST_P(LdsDeletionTest, ListenerDeletionIgnored) { - InitClient(BootstrapBuilder().SetIgnoreResourceDeletion()); + InitClient(XdsBootstrapBuilder().SetIgnoreResourceDeletion()); CreateAndStartBackends(2); // Bring up client pointing to backend 0 and wait for it to connect. EdsResourceArgs args({{"locality0", CreateEndpointsForBackends(0, 1)}}); diff --git a/test/cpp/end2end/xds/xds_utils.cc b/test/cpp/end2end/xds/xds_utils.cc new file mode 100644 index 00000000000..8ad0cea3c82 --- /dev/null +++ b/test/cpp/end2end/xds/xds_utils.cc @@ -0,0 +1,375 @@ +// Copyright 2017 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. +// + +#include "test/cpp/end2end/xds/xds_utils.h" + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "absl/memory/memory.h" +#include "absl/strings/str_cat.h" +#include "absl/strings/str_format.h" +#include "absl/strings/str_join.h" +#include "absl/strings/str_replace.h" +#include "absl/strings/string_view.h" +#include "absl/types/optional.h" + +#include + +#include "src/core/ext/filters/http/server/http_server_filter.h" +#include "src/core/ext/xds/xds_channel_args.h" +#include "src/core/ext/xds/xds_client_grpc.h" +#include "src/core/lib/gpr/tmpfile.h" +#include "src/core/lib/gprpp/env.h" +#include "src/core/lib/iomgr/load_file.h" +#include "src/core/lib/surface/server.h" +#include "src/cpp/client/secure_credentials.h" +#include "src/proto/grpc/testing/xds/v3/router.grpc.pb.h" +#include "test/core/util/resolve_localhost_ip46.h" + +namespace grpc { +namespace testing { + +using ::envoy::config::cluster::v3::Cluster; +using ::envoy::config::core::v3::HealthStatus; +using ::envoy::config::endpoint::v3::ClusterLoadAssignment; +using ::envoy::config::listener::v3::Listener; +using ::envoy::config::route::v3::RouteConfiguration; +using ::envoy::extensions::filters::network::http_connection_manager::v3:: + HttpConnectionManager; + +// +// XdsBootstrapBuilder +// + +std::string XdsBootstrapBuilder::Build() { + std::vector fields; + fields.push_back(MakeXdsServersText(top_server_)); + if (!client_default_listener_resource_name_template_.empty()) { + fields.push_back( + absl::StrCat(" \"client_default_listener_resource_name_template\": \"", + client_default_listener_resource_name_template_, "\"")); + } + fields.push_back(MakeNodeText()); + if (!server_listener_resource_name_template_.empty()) { + fields.push_back( + absl::StrCat(" \"server_listener_resource_name_template\": \"", + server_listener_resource_name_template_, "\"")); + } + fields.push_back(MakeCertificateProviderText()); + fields.push_back(MakeAuthorityText()); + return absl::StrCat("{", absl::StrJoin(fields, ",\n"), "}"); +} + +std::string XdsBootstrapBuilder::MakeXdsServersText( + absl::string_view server_uri) { + constexpr char kXdsServerTemplate[] = + " \"xds_servers\": [\n" + " {\n" + " \"server_uri\": \"\",\n" + " \"channel_creds\": [\n" + " {\n" + " \"type\": \"fake\"\n" + " }\n" + " ],\n" + " \"server_features\": []\n" + " }\n" + " ]"; + std::vector server_features; + if (ignore_resource_deletion_) { + server_features.push_back("\"ignore_resource_deletion\""); + } + return absl::StrReplaceAll( + kXdsServerTemplate, + {{"", server_uri}, + {"", absl::StrJoin(server_features, ", ")}}); +} + +std::string XdsBootstrapBuilder::MakeNodeText() { + constexpr char kXdsNode[] = + " \"node\": {\n" + " \"id\": \"xds_end2end_test\",\n" + " \"cluster\": \"test\",\n" + " \"metadata\": {\n" + " \"foo\": \"bar\"\n" + " },\n" + " \"locality\": {\n" + " \"region\": \"corp\",\n" + " \"zone\": \"svl\",\n" + " \"sub_zone\": \"mp3\"\n" + " }\n" + " }"; + return kXdsNode; +} + +std::string XdsBootstrapBuilder::MakeCertificateProviderText() { + std::vector entries; + for (const auto& p : plugins_) { + const std::string& key = p.first; + const PluginInfo& plugin_info = p.second; + std::vector fields; + fields.push_back(absl::StrFormat(" \"%s\": {", key)); + if (!plugin_info.plugin_config.empty()) { + fields.push_back( + absl::StrFormat(" \"plugin_name\": \"%s\",", plugin_info.name)); + fields.push_back(absl::StrCat(" \"config\": {\n", + plugin_info.plugin_config, "\n }")); + } else { + fields.push_back( + absl::StrFormat(" \"plugin_name\": \"%s\"", plugin_info.name)); + } + fields.push_back(" }"); + entries.push_back(absl::StrJoin(fields, "\n")); + } + return absl::StrCat(" \"certificate_providers\": {\n", + absl::StrJoin(entries, ",\n"), " \n}"); +} + +std::string XdsBootstrapBuilder::MakeAuthorityText() { + std::vector entries; + for (const auto& p : authorities_) { + const std::string& name = p.first; + const AuthorityInfo& authority_info = p.second; + std::vector fields = { + MakeXdsServersText(authority_info.server)}; + if (!authority_info.client_listener_resource_name_template.empty()) { + fields.push_back(absl::StrCat( + "\"client_listener_resource_name_template\": \"", + authority_info.client_listener_resource_name_template, "\"")); + } + entries.push_back(absl::StrCat(absl::StrFormat("\"%s\": {\n ", name), + absl::StrJoin(fields, ",\n"), "\n}")); + } + return absl::StrCat("\"authorities\": {\n", absl::StrJoin(entries, ",\n"), + "\n}"); +} + +// +// XdsResourceUtils::ClientHcmAccessor +// + +HttpConnectionManager XdsResourceUtils::ClientHcmAccessor::Unpack( + const Listener& listener) const { + HttpConnectionManager http_connection_manager; + listener.api_listener().api_listener().UnpackTo(&http_connection_manager); + return http_connection_manager; +} + +void XdsResourceUtils::ClientHcmAccessor::Pack(const HttpConnectionManager& hcm, + Listener* listener) const { + auto* api_listener = listener->mutable_api_listener()->mutable_api_listener(); + api_listener->PackFrom(hcm); +} + +// +// XdsResourceUtils::ServerHcmAccessor +// + +HttpConnectionManager XdsResourceUtils::ServerHcmAccessor::Unpack( + const Listener& listener) const { + HttpConnectionManager http_connection_manager; + listener.default_filter_chain().filters().at(0).typed_config().UnpackTo( + &http_connection_manager); + return http_connection_manager; +} + +void XdsResourceUtils::ServerHcmAccessor::Pack(const HttpConnectionManager& hcm, + Listener* listener) const { + auto* filters = listener->mutable_default_filter_chain()->mutable_filters(); + if (filters->empty()) filters->Add(); + filters->at(0).mutable_typed_config()->PackFrom(hcm); +} + +// +// XdsResourceUtils +// + +const char XdsResourceUtils::kDefaultLocalityRegion[] = + "xds_default_locality_region"; +const char XdsResourceUtils::kDefaultLocalityZone[] = + "xds_default_locality_zone"; + +const char XdsResourceUtils::kServerName[] = "server.example.com"; +const char XdsResourceUtils::kDefaultRouteConfigurationName[] = + "route_config_name"; +const char XdsResourceUtils::kDefaultClusterName[] = "cluster_name"; +const char XdsResourceUtils::kDefaultEdsServiceName[] = "eds_service_name"; +const char XdsResourceUtils::kDefaultServerRouteConfigurationName[] = + "default_server_route_config_name"; + +Listener XdsResourceUtils::DefaultListener() { + Listener listener; + listener.set_name(kServerName); + ClientHcmAccessor().Pack(DefaultHcm(), &listener); + return listener; +} + +RouteConfiguration XdsResourceUtils::DefaultRouteConfig() { + RouteConfiguration route_config; + route_config.set_name(kDefaultRouteConfigurationName); + auto* virtual_host = route_config.add_virtual_hosts(); + virtual_host->add_domains("*"); + auto* route = virtual_host->add_routes(); + route->mutable_match()->set_prefix(""); + route->mutable_route()->set_cluster(kDefaultClusterName); + return route_config; +} + +Cluster XdsResourceUtils::DefaultCluster() { + Cluster cluster; + cluster.set_name(kDefaultClusterName); + cluster.set_type(Cluster::EDS); + auto* eds_config = cluster.mutable_eds_cluster_config(); + eds_config->mutable_eds_config()->mutable_self(); + eds_config->set_service_name(kDefaultEdsServiceName); + cluster.set_lb_policy(Cluster::ROUND_ROBIN); + return cluster; +} + +Listener XdsResourceUtils::DefaultServerListener() { + Listener listener; + listener.mutable_address()->mutable_socket_address()->set_address( + grpc_core::LocalIp()); + ServerHcmAccessor().Pack(DefaultHcm(), &listener); + return listener; +} + +RouteConfiguration XdsResourceUtils::DefaultServerRouteConfig() { + RouteConfiguration route_config; + route_config.set_name(kDefaultServerRouteConfigurationName); + auto* virtual_host = route_config.add_virtual_hosts(); + virtual_host->add_domains("*"); + auto* route = virtual_host->add_routes(); + route->mutable_match()->set_prefix(""); + route->mutable_non_forwarding_action(); + return route_config; +} + +HttpConnectionManager XdsResourceUtils::DefaultHcm() { + HttpConnectionManager http_connection_manager; + auto* filter = http_connection_manager.add_http_filters(); + filter->set_name("router"); + filter->mutable_typed_config()->PackFrom( + envoy::extensions::filters::http::router::v3::Router()); + return http_connection_manager; +} + +std::string XdsResourceUtils::GetServerListenerName(int port) { + return absl::StrCat("grpc/server?xds.resource.listening_address=", + grpc_core::LocalIp(), ":", port); +} + +Listener XdsResourceUtils::PopulateServerListenerNameAndPort( + const Listener& listener_template, int port) { + Listener listener = listener_template; + listener.set_name(GetServerListenerName(port)); + listener.mutable_address()->mutable_socket_address()->set_port_value(port); + return listener; +} + +void XdsResourceUtils::SetListenerAndRouteConfiguration( + AdsServiceImpl* ads_service, Listener listener, + const RouteConfiguration& route_config, bool use_rds, + const HcmAccessor& hcm_accessor) { + HttpConnectionManager http_connection_manager = hcm_accessor.Unpack(listener); + if (use_rds) { + auto* rds = http_connection_manager.mutable_rds(); + rds->set_route_config_name(route_config.name()); + rds->mutable_config_source()->mutable_self(); + ads_service->SetRdsResource(route_config); + } else { + *http_connection_manager.mutable_route_config() = route_config; + } + hcm_accessor.Pack(http_connection_manager, &listener); + ads_service->SetLdsResource(listener); +} + +void XdsResourceUtils::SetRouteConfiguration( + AdsServiceImpl* ads_service, const RouteConfiguration& route_config, + bool use_rds, const Listener* listener_to_copy) { + if (use_rds) { + ads_service->SetRdsResource(route_config); + } else { + Listener listener(listener_to_copy == nullptr ? DefaultListener() + : *listener_to_copy); + HttpConnectionManager http_connection_manager = + ClientHcmAccessor().Unpack(listener); + *(http_connection_manager.mutable_route_config()) = route_config; + ClientHcmAccessor().Pack(http_connection_manager, &listener); + ads_service->SetLdsResource(listener); + } +} + +ClusterLoadAssignment XdsResourceUtils::BuildEdsResource( + const EdsResourceArgs& args, absl::string_view eds_service_name) { + ClusterLoadAssignment assignment; + assignment.set_cluster_name(eds_service_name); + for (const auto& locality : args.locality_list) { + auto* endpoints = assignment.add_endpoints(); + endpoints->mutable_load_balancing_weight()->set_value(locality.lb_weight); + endpoints->set_priority(locality.priority); + endpoints->mutable_locality()->set_region(kDefaultLocalityRegion); + endpoints->mutable_locality()->set_zone(kDefaultLocalityZone); + endpoints->mutable_locality()->set_sub_zone(locality.sub_zone); + for (size_t i = 0; i < locality.endpoints.size(); ++i) { + const auto& endpoint = locality.endpoints[i]; + auto* lb_endpoints = endpoints->add_lb_endpoints(); + if (locality.endpoints.size() > i && + locality.endpoints[i].health_status != HealthStatus::UNKNOWN) { + lb_endpoints->set_health_status(endpoint.health_status); + } + if (locality.endpoints.size() > i && endpoint.lb_weight >= 1) { + lb_endpoints->mutable_load_balancing_weight()->set_value( + endpoint.lb_weight); + } + auto* endpoint_proto = lb_endpoints->mutable_endpoint(); + auto* socket_address = + endpoint_proto->mutable_address()->mutable_socket_address(); + socket_address->set_address(grpc_core::LocalIp()); + socket_address->set_port_value(endpoint.port); + for (int port : endpoint.additional_ports) { + socket_address = endpoint_proto->add_additional_addresses() + ->mutable_address() + ->mutable_socket_address(); + socket_address->set_address(grpc_core::LocalIp()); + socket_address->set_port_value(port); + } + } + } + if (!args.drop_categories.empty()) { + auto* policy = assignment.mutable_policy(); + for (const auto& p : args.drop_categories) { + const std::string& name = p.first; + const uint32_t parts_per_million = p.second; + auto* drop_overload = policy->add_drop_overloads(); + drop_overload->set_category(name); + auto* drop_percentage = drop_overload->mutable_drop_percentage(); + drop_percentage->set_numerator(parts_per_million); + drop_percentage->set_denominator(args.drop_denominator); + } + } + return assignment; +} + +} // namespace testing +} // namespace grpc diff --git a/test/cpp/end2end/xds/xds_utils.h b/test/cpp/end2end/xds/xds_utils.h new file mode 100644 index 00000000000..5797d9c4835 --- /dev/null +++ b/test/cpp/end2end/xds/xds_utils.h @@ -0,0 +1,248 @@ +// Copyright 2017 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. +// + +#ifndef GRPC_TEST_CPP_END2END_XDS_XDS_UTILS_H +#define GRPC_TEST_CPP_END2END_XDS_XDS_UTILS_H + +#include +#include + +#include "absl/strings/string_view.h" + +#include "src/proto/grpc/testing/xds/v3/cluster.pb.h" +#include "src/proto/grpc/testing/xds/v3/endpoint.pb.h" +#include "src/proto/grpc/testing/xds/v3/http_connection_manager.pb.h" +#include "src/proto/grpc/testing/xds/v3/listener.pb.h" +#include "src/proto/grpc/testing/xds/v3/route.pb.h" +#include "test/cpp/end2end/xds/xds_server.h" + +namespace grpc { +namespace testing { + +// A builder for the xDS bootstrap config. +class XdsBootstrapBuilder { + public: + XdsBootstrapBuilder() {} + XdsBootstrapBuilder& SetIgnoreResourceDeletion() { + ignore_resource_deletion_ = true; + return *this; + } + // If ignore_if_set is true, sets the default server only if it has + // not already been set. + XdsBootstrapBuilder& SetDefaultServer(const std::string& server, + bool ignore_if_set = false) { + if (!ignore_if_set || top_server_.empty()) top_server_ = server; + return *this; + } + XdsBootstrapBuilder& SetClientDefaultListenerResourceNameTemplate( + const std::string& client_default_listener_resource_name_template) { + client_default_listener_resource_name_template_ = + client_default_listener_resource_name_template; + return *this; + } + XdsBootstrapBuilder& AddCertificateProviderPlugin( + const std::string& key, const std::string& name, + const std::string& plugin_config = "") { + plugins_[key] = {name, plugin_config}; + return *this; + } + XdsBootstrapBuilder& AddAuthority( + const std::string& authority, const std::string& server = "", + const std::string& client_listener_resource_name_template = "") { + authorities_[authority] = {server, client_listener_resource_name_template}; + return *this; + } + XdsBootstrapBuilder& SetServerListenerResourceNameTemplate( + const std::string& server_listener_resource_name_template = "") { + server_listener_resource_name_template_ = + server_listener_resource_name_template; + return *this; + } + + std::string Build(); + + private: + struct PluginInfo { + std::string name; + std::string plugin_config; + }; + struct AuthorityInfo { + std::string server; + std::string client_listener_resource_name_template; + }; + + std::string MakeXdsServersText(absl::string_view server_uri); + std::string MakeNodeText(); + std::string MakeCertificateProviderText(); + std::string MakeAuthorityText(); + + bool ignore_resource_deletion_ = false; + std::string top_server_; + std::string client_default_listener_resource_name_template_; + std::map plugins_; + std::map authorities_; + std::string server_listener_resource_name_template_ = + "grpc/server?xds.resource.listening_address=%s"; +}; + +// Utilities for constructing xDS resources. +class XdsResourceUtils { + public: + using HttpConnectionManager = envoy::extensions::filters::network:: + http_connection_manager::v3::HttpConnectionManager; + using Listener = envoy::config::listener::v3::Listener; + using RouteConfiguration = envoy::config::route::v3::RouteConfiguration; + using Cluster = envoy::config::cluster::v3::Cluster; + using ClusterLoadAssignment = + envoy::config::endpoint::v3::ClusterLoadAssignment; + + // Interface for accessing HttpConnectionManager config in Listener. + class HcmAccessor { + public: + virtual ~HcmAccessor() = default; + virtual HttpConnectionManager Unpack(const Listener& listener) const = 0; + virtual void Pack(const HttpConnectionManager& hcm, + Listener* listener) const = 0; + }; + + // Client-side impl. + class ClientHcmAccessor : public HcmAccessor { + public: + HttpConnectionManager Unpack(const Listener& listener) const override; + void Pack(const HttpConnectionManager& hcm, + Listener* listener) const override; + }; + + // Server-side impl. + class ServerHcmAccessor : public HcmAccessor { + public: + HttpConnectionManager Unpack(const Listener& listener) const override; + void Pack(const HttpConnectionManager& hcm, + Listener* listener) const override; + }; + + // Default values for locality fields. + static const char kDefaultLocalityRegion[]; + static const char kDefaultLocalityZone[]; + static const uint32_t kDefaultLocalityWeight = 3; + static const int kDefaultLocalityPriority = 0; + + // Default resource names. + static const char kServerName[]; + static const char kDefaultRouteConfigurationName[]; + static const char kDefaultClusterName[]; + static const char kDefaultEdsServiceName[]; + static const char kDefaultServerRouteConfigurationName[]; + + // Returns default xDS resources. + static Listener DefaultListener(); + static RouteConfiguration DefaultRouteConfig(); + static Cluster DefaultCluster(); + static Listener DefaultServerListener(); + static RouteConfiguration DefaultServerRouteConfig(); + static HttpConnectionManager DefaultHcm(); + + // Returns the name of the server-side xDS Listener resource for a + // backend on the specified port. + static std::string GetServerListenerName(int port); + + // Returns a copy of listener_template with the server-side resource + // name and the port in the socket address populated. + static Listener PopulateServerListenerNameAndPort( + const Listener& listener_template, int port); + + // Sets the Listener and RouteConfiguration resource on the specified + // balancer. If RDS is in use, they will be set as separate resources; + // otherwise, the RouteConfig will be inlined into the Listener. + static void SetListenerAndRouteConfiguration( + AdsServiceImpl* ads_service, Listener listener, + const RouteConfiguration& route_config, bool use_rds = false, + const HcmAccessor& hcm_accessor = ClientHcmAccessor()); + + // A convenient wrapper for setting the Listener and + // RouteConfiguration resources on the server side. + static void SetServerListenerNameAndRouteConfiguration( + AdsServiceImpl* ads_service, Listener listener, int port, + const RouteConfiguration& route_config, bool use_rds = false) { + SetListenerAndRouteConfiguration( + ads_service, PopulateServerListenerNameAndPort(listener, port), + route_config, use_rds, ServerHcmAccessor()); + } + + // Sets the RouteConfiguration resource on the specified balancer. + // If RDS is in use, it will be set directly as an independent + // resource; otherwise, it will be inlined into a Listener resource + // (either listener_to_copy, or if that is null, default_listener_). + static void SetRouteConfiguration(AdsServiceImpl* ads_service, + const RouteConfiguration& route_config, + bool use_rds = false, + const Listener* listener_to_copy = nullptr); + + // Arguments for constructing an EDS resource. + struct EdsResourceArgs { + // An individual endpoint for a backend running on a specified port. + struct Endpoint { + explicit Endpoint(int port, + ::envoy::config::core::v3::HealthStatus health_status = + ::envoy::config::core::v3::HealthStatus::UNKNOWN, + int lb_weight = 1, + std::vector additional_ports = {}) + : port(port), + health_status(health_status), + lb_weight(lb_weight), + additional_ports(std::move(additional_ports)) {} + + int port; + ::envoy::config::core::v3::HealthStatus health_status; + int lb_weight; + std::vector additional_ports; + }; + + // A locality. + struct Locality { + Locality(std::string sub_zone, std::vector endpoints, + uint32_t lb_weight = kDefaultLocalityWeight, + int priority = kDefaultLocalityPriority) + : sub_zone(std::move(sub_zone)), + endpoints(std::move(endpoints)), + lb_weight(lb_weight), + priority(priority) {} + + const std::string sub_zone; + std::vector endpoints; + uint32_t lb_weight; + int priority; + }; + + EdsResourceArgs() = default; + explicit EdsResourceArgs(std::vector locality_list) + : locality_list(std::move(locality_list)) {} + + std::vector locality_list; + std::map drop_categories; + ::envoy::type::v3::FractionalPercent::DenominatorType drop_denominator = + ::envoy::type::v3::FractionalPercent::MILLION; + }; + + // Constructs an EDS resource. + static ClusterLoadAssignment BuildEdsResource( + const EdsResourceArgs& args, + absl::string_view eds_service_name = kDefaultEdsServiceName); +}; + +} // namespace testing +} // namespace grpc + +#endif // GRPC_TEST_CPP_END2END_XDS_XDS_UTILS_H